idnits 2.17.1 draft-montenegro-hybi-upgrade-hello-handshake-00.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- == It seems as if not all pages are separated by form feeds - found 25 form feeds but 40 pages Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** There are 34 instances of too long lines in the document, the longest one being 10 characters in excess of 72. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year == The document doesn't use any RFC 2119 keywords, yet seems to have RFC 2119 boilerplate text. -- The document date (December 15, 2010) is 4875 days in the past. Is this intentional? Checking references for intended status: Informational ---------------------------------------------------------------------------- == Missing Reference: 'RFC1321' is mentioned on line 916, but not defined == Unused Reference: 'RFC2616' is defined on line 1005, but no explicit reference was found in the text == Unused Reference: 'I-D.ietf-hybi-design-space' is defined on line 1027, but no explicit reference was found in the text ** Obsolete normative reference: RFC 2616 (Obsoleted by RFC 7230, RFC 7231, RFC 7232, RFC 7233, RFC 7234, RFC 7235) == Outdated reference: A later version (-02) exists of draft-ietf-hybi-websocket-requirements-01 == Outdated reference: A later version (-17) exists of draft-ietf-hybi-thewebsocketprotocol-03 -- No information found for draft-ietf-hybi-design-space - is the name correct? Summary: 2 errors (**), 0 flaws (~~), 8 warnings (==), 2 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 HYBI Working Group G. Wilkins 3 Internet-Draft WebTide 4 Intended status: Informational G. Montenegro 5 Expires: June 18, 2011 Microsoft Corporation 6 December 15, 2010 8 WebSocket Upgrade+Hello Handshake 9 draft-montenegro-hybi-upgrade-hello-handshake-00 11 Abstract 13 This document defines the 'Upgrade+Hello' handshake for the Websocket 14 protocol. 16 Requirements Language 18 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 19 "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this 20 document are to be interpreted as described in RFC 2119 [RFC2119]. 22 Status of This Memo 24 This Internet-Draft is submitted in full conformance with the 25 provisions of BCP 78 and BCP 79. 27 Internet-Drafts are working documents of the Internet Engineering 28 Task Force (IETF). Note that other groups may also distribute 29 working documents as Internet-Drafts. The list of current Internet- 30 Drafts is at http://datatracker.ietf.org/drafts/current/. 32 Internet-Drafts are draft documents valid for a maximum of six months 33 and may be updated, replaced, or obsoleted by other documents at any 34 time. It is inappropriate to use Internet-Drafts as reference 35 material or to cite them other than as "work in progress." 37 This Internet-Draft will expire on June 18, 2011. 39 Copyright Notice 41 Copyright (c) 2010 IETF Trust and the persons identified as the 42 document authors. All rights reserved. 44 This document is subject to BCP 78 and the IETF Trust's Legal 45 Provisions Relating to IETF Documents 46 (http://trustee.ietf.org/license-info) in effect on the date of 47 publication of this document. Please review these documents 48 carefully, as they describe your rights and restrictions with respect 49 to this document. Code Components extracted from this document must 50 include Simplified BSD License text as described in Section 4.e of 51 the Trust Legal Provisions and are provided without warranty as 52 described in the Simplified BSD License. 54 Table of Contents 56 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . ancho 57 2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . ancho 58 3. Upgrade+Hello Handshake . . . . . . . . . . . . . . . . . . ancho 59 4. Changes to 1.2. Protocol overview . . . . . . . . . . . . ancho 60 5. Changes to 1.3. Opening handshake . . . . . . . . . . . . ancho 61 6. Changes to 1.9 Subprotocols using the WebSocket protocol . ancho 62 7. Changes to 3.1. Parsing WebSocket URLs . . . . . . . . . . ancho 63 8. Changes to 4.2. Base Framing Protocol . . . . . . . . . . ancho 64 9. Changes to 4.3. Fragmentation . . . . . . . . . . . . . . ancho 65 10. Changes to 4.4. Control Frames . . . . . . . . . . . . . . ancho 66 11. Changes to 4.6. Examples . . . . . . . . . . . . . . . . . ancho 67 12. Changes to 5.1. Client Requirements . . . . . . . . . . . ancho 68 13. Changes to 5.2.1. Reading the client's opening handshake . ancho 69 14. Security Considerations . . . . . . . . . . . . . . . . . . ancho 70 15. IANA Considerations . . . . . . . . . . . . . . . . . . . . ancho 71 16. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . ancho 72 17. References . . . . . . . . . . . . . . . . . . . . . . . . ancho 73 17.1. Normative References . . . . . . . . . . . . . . . . . ancho 74 17.2. Informative References . . . . . . . . . . . . . . . . ancho 76 1. Introduction 78 As of version 3 of the websocket (WS) protocol 79 [I-D.ietf-hybi-thewebsocketprotocol], the handshake used to 80 transition from HTTP to Websocket protocol is deficient with respect 81 to HTTP compatibility and security. Accordingly, much discussion has 82 ensued to try to define the replacement handshake for adoption by the 83 WG. 85 The handshake defined in this document maintains compatibility with 86 HTTP in accordance with [I-D.ietf-hybi-websocket-requirements] while 87 protecting against currently known vulnerabilities. It leverages the 88 'GET+Upgrade' approach in the current handshake, in addition to 89 several other mechanisms, as detailed below. 91 An initial version of this handshake has been previously shared with 92 the working group 93 (http://www.ietf.org/mail-archive/web/hybi/current/msg04534.html). 95 2. Terminology 97 This document uses HyBi-related terms as defined in 98 [I-D.ietf-hybi-websocket-requirements]. 100 3. Upgrade+Hello Handshake 102 The Upgrade+Hello handshake implements the following mechanisms: 104 a. Use Websocket Hello from the server and a Websocket Hello from 105 the client, using Websocket frames to transport hashed nonces 106 (rather than unframed bytes). This fixes the issue with 107 intermediaries not forwarding the unframed bytes on the wire and 108 makes the handshake comply with the requirement to be HTTP/1.1 109 compliant up through the 101 response from the server. 111 b. Include a server nonce in the server-sent Hello, that the client 112 must hash and return in its Hello. 114 c. Use a Hello frame type instead of ping/pong. This does not 115 require an extra round trip. It just ensures that the first 116 frame in each direction is something that is entirely not HTTP 117 and uses the Websocket binary framing instead. 119 d. Replace the char/space encoding of the client nonce with simple 120 hex encoding. 122 e. Define tight restrictions on the punctuation that can be sent in 123 ws URLs and subprotocols (e.g., prohibit use of ':' ) so that 124 they cannot be used to inject HTTP headers. While not as robust 125 as encrypting the handshakes, these restrictions will provide 126 substantial protection against user provided data being used as 127 part of an attack. 129 f. Invert the framing MORE bit to be a FIN bit, so that WS control 130 frames will start with a non-ascii character. This mitigates the 131 attack vector affecting some intermediaries (transparent proxies, 132 load balancers, etc) that have been known to continue parsing the 133 traffic (incorrectly assuming it is still HTTP) even after the 134 handshake. 136 g. TODO: Change use of MD5 to SHA1. Note the use in a "Challenge- 137 Response" manner is not considered susceptible to recent attacks 138 against these hash families per RFC4270, but still makes sense to 139 migrate away from MD5 if nothing else for easier deployment. 141 The above summarizes the changes. The following sections show the 142 text changes that implement the above mechanisms, in traditional 143 "OLD" and "NEW" IETF notation. 145 4. Changes to 1.2. Protocol overview 147 OLD: 149 GET /demo HTTP/1.1 150 Host: example.com 151 Connection: Upgrade 152 Sec-WebSocket-Key2: 12998 5 Y3 1 .P00 153 Sec-WebSocket-Protocol: sample 154 Upgrade: WebSocket 155 Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5 156 Origin: http://example.com 158 ^n:ds[4U 160 The handshake from the server looks as follows: 162 HTTP/1.1 101 WebSocket Protocol Handshake 163 Upgrade: WebSocket 164 Connection: Upgrade 165 Sec-WebSocket-Origin: http://example.com 166 Sec-WebSocket-Location: ws://example.com/demo 167 Sec-WebSocket-Protocol: sample 169 8jKS'y:G*Co,Wxa- 171 NEW: 173 GET /demo HTTP/1.1 174 Host: example.com 175 Connection: Upgrade 176 Sec-WebSocket-Nonce: A23F2BCA452DDE01 177 Sec-WebSocket-Protocol: sample 178 Upgrade: WebSocket 179 Origin: http://example.com 180 Sec-WebSocket-Draft: 3 182 The handshake from the server looks as follows: 184 HTTP/1.1 101 Switching Protocols 185 Upgrade: WebSocket 186 Connection: Upgrade 187 Sec-WebSocket-Origin: http://example.com 188 Sec-WebSocket-Location: ws://example.com/demo 189 Sec-WebSocket-Protocol: sample 191 OLD: 193 Finally, after the last field, the client sends 10 bytes starting 194 with 0x0D 0x0A and followed by 8 random bytes, part of a challenge, 195 and the server sends 18 bytes starting with 0x0D 0x0A and followed by 196 16 bytes consisting of a challenge response. The details of this 197 challenge and other parts of the handshake are described in the next 198 section. 200 Once the client and server have both sent their handshakes, and if 201 the handshake was successful, then the data transfer part starts. 202 This is a two-way communication channel where each side can, 203 independently from the other, send data at will. 205 NEW: 207 Once the client and server have both sent their handshakes, and if 208 the handshake was successful, then the data transfer part starts. 209 This is a two-way communication channel where each side can, 210 independently from the other, send data at will. 212 The first frame sent in both directions must be a Hello frame 213 containing digests to prove the handshakes have been processed. 215 5. Changes to 1.3. Opening handshake 217 OLD: 219 The opening handshake is intended to be compatible with HTTP-based 220 server-side software, so that a single port can be used by both HTTP 221 clients talking to that server and WebSocket clients talking to that 222 server. To this end, the WebSocket client's handshake appears to 223 HTTP servers to be a regular GET request with an Upgrade offer: 225 GET / HTTP/1.1 226 Upgrade: WebSocket 227 Connection: Upgrade 229 Fields in the handshake are sent by the client in a random order; the 230 order is not meaningful. 232 NEW: 234 The opening handshake is intended to be compatible with HTTP-based 235 server-side software, so that a single port can be used by both HTTP 236 clients talking to that server and WebSocket clients talking to that 237 server. To this end, the WebSocket client's handshake appears to 238 HTTP servers to be a regular HTTP request with an Upgrade offer: 240 GET / HTTP/1.1 241 Upgrade: WebSocket 242 Connection: Upgrade 244 Any valid URI may be passed, except that the client must not send a 245 handshake with a URI path that contain the character ':' or any 246 control or whitspace characters in explicit or encoded form. This 247 limits the possibility of using a websocket client to attack a 248 vulnerable non WebSocket servers. 250 Fields in the handshake are sent by the client in an unspecified 251 order; the order is not meaningful. 253 OLD: 255 To prove that the handshake was received, the server has to take 256 three pieces of information and combine them to form a response. The 257 first two pieces of information come from the |Sec-WebSocket-Key1| 258 and |Sec-WebSocket-Key2| fields in the client handshake: 260 Sec-WebSocket-Key1: 18x 6]8vM;54 *(5: { U1]8 z [ 8 261 Sec-WebSocket-Key2: 1_ tx7X d < nw 334J702) 7]o}` 0 263 For each of these fields, the server has to take the digits from the 264 value to obtain a number (in this case 1868545188 and 1733470270 265 respectively), then divide that number by the number of spaces 266 characters in the value (in this case 12 and 10) to obtain a 32-bit 267 number (155712099 and 173347027). These two resulting numbers are 268 then used in the server handshake, as described below. 270 The counting of spaces is intended to make it impossible to smuggle 271 this field into the resource name; making this even harder is the 272 presence of _two_ such fields, and the use of a newline as the only 273 reliable indicator that the end of the key has been reached. The use 274 of random characters interspersed with the spaces and the numbers 275 ensures that the implementor actually looks for spaces and newlines, 276 instead of being treating any character like a space, which would 277 make it again easy to smuggle the fields into the path and trick the 278 server. Finally, _dividing_ by this number of spaces is intended to 279 make sure that even the most naive of implementations will check for 280 spaces, since if ther server does not verify that there are some 281 spaces, the server will try to divide by zero, which is usually fatal 282 (a correct handshake will always have at least one space). 284 The third piece of information is given after the fields, in the last 285 eight bytes of the handshake, expressed here as they would be seen if 286 interpreted as UTF-8: 288 Tm[K T2u 290 The concatenation of the number obtained from processing the |Sec- 291 WebSocket-Key1| field, expressed as a big-endian 32 bit number, the 292 number obtained from processing the |Sec-WebSocket-Key2| field, again 293 expressed as a big-endian 32 bit number, and finally the eight bytes 294 at the end of the handshake, form a 128 bit string whose MD5 sum is 295 then used by the server to prove that it read the handshake. 297 NEW: 299 To prove that the handshake was received, the server has to initiate 300 websocket communication with a Hello frame containing the MD5 hash of 301 a random 64 bit client nonce generated by the client and sent as a 302 hex encoded string in the Sec-WebSocket-Nonce field of the client 303 handshake: 305 Sec-WebSocket-Nonce: A23F2BCA452DDE01 307 The server has to take 8 octets of the client nonce, append the 308 octets of the ASCII string "WebSocket" and then append 8 octets of a 309 randomly generated server nonce (eg 15F0D2278BCD457F). The server 310 nonce and the 16 octet MD5 hash (eg Ee7eBe0c369cBf255a4451Fc58D7Cc4f) 311 of the combined octets must be sent in a Hello frame as the first 312 websocket frame from the server to the client: 314 8F18 15F0D2278BCD457F Ee7eBe0c369cBf255a4451Fc58D7Cc4f 316 OLD: 318 After the fields, the server sends the aforementioned MD5 sum, a 16 319 byte (128 bit) value, shown here as if interpreted as UTF-8: 321 fQJ,fN/4F4!~K~MH 323 This value depends on what the client sends, as described above. If 324 it doesn't match what the client is expecting, the client would 325 disconnect. 327 Having part of the handshake appear after the fields ensures that 328 both the server and the client verify that the connection is not 329 being interrupted by an HTTP intermediary such as a man-in-the-middle 330 cache or proxy. 332 NEW: 334 After the fields, the server sends the aforementioned Hello frame 335 containing the 8 octets of the server nonce followed by the 16 octets 336 of the MD5 digest. 338 After receiving the server handshake, the client must wait for the 339 following Hello frame and verify that the contents. The digest value 340 depends on both the client and server nonces, as described above. If 341 it doesn't match what the client is expecting, the client must 342 disconnect. Only after verifying the contents of the Hello frame may 343 the client application be notified of an open connection. 345 The first websocket frame sent by the client to the server must be a 346 Hello frame containing the 128 bit MD5 digest of the 8 octets of the 347 server nonce followed by the octets of the ASCII string "WebSocket" 348 followed by the 8 octets of the client nonce: 350 8F10 33122035D11258Fd7c764314580e539c 352 6. Changes to 1.9 Subprotocols using the WebSocket protocol 354 OLD: 356 The client can request that the server use a specific subprotocol by 357 including the |Sec-Websocket-Protocol| field in its handshake. If it 358 is specified, the server needs to include the same field and one of 359 the selected subprotocol values in its response for the connection to 360 be established. 362 These subprotocol names do not need to be registered, but if a 364 NEW: 366 The client can request that the server use a specific subprotocol by 367 including the |Sec-Websocket-Protocol| field in its handshake. If it 368 is specified, the server needs to include the same field and one of 369 the selected subprotocol values in its response for the connection to 370 be established. 372 Subprotocol names are restricted to use the ASCII characters A-Z, 373 a-z, 0-9, '/', '_' and '-'. 375 These subprotocol names do not need to be registered, but if a 377 7. Changes to 3.1. Parsing WebSocket URLs 379 OLD: 381 11. If /url/ has a component, then append a single U+003F 382 QUESTION MARK character (?) to /resource name/, followed by the 383 value of the component. 385 12. Return /host/, /port/, /resource name/, and /secure/. 387 NEW: 389 11. If /resource name/ contains the character ':' or any white 390 space sharacters or any characters with codes <= U+0020, 391 then the URL is invalid. 393 12. If /url/ has a component, then append a single U+003F 394 QUESTION MARK character (?) to /resource name/, followed by the 395 value of the component. 397 13. Return /host/, /port/, /resource name/, and /secure/. 399 8. Changes to 4.2. Base Framing Protocol 401 OLD: 403 0 1 2 3 404 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 405 +-+-+-+-+-------+-+-------------+-------------------------------+ 406 |M|R|R|R| opcode|R| Payload len | Extended payload length | 407 |O|S|S|S| (4) |S| (7) | (16/63) | 408 |R|V|V|V| |V| | (if payload len==126/127) | 409 |E|1|2|3| |4| | | 410 +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - + 411 | Extended payload length continued, if payload len == 127 | 412 + - - - - - - - - - - - - - - - +-------------------------------+ 413 | | Extension data | 414 +-------------------------------+ - - - - - - - - - - - - - - - + 415 : : 416 +---------------------------------------------------------------+ 417 : Application data : 418 +---------------------------------------------------------------+ 420 MORE: 1 bit 422 Indicates more fragments follow in the current message 424 NEW: 426 0 1 2 3 427 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 428 +-+-+-+-+-------+-+-------------+-------------------------------+ 429 |F|R|R|R| opcode|R| Payload len | Extended payload length | 430 |I|S|S|S| (4) |S| (7) | (16/63) | 431 |N|V|V|V| |V| | (if payload len==126/127) | 432 | |1|2|3| |4| | | 433 +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - + 434 | Extended payload length continued, if payload len == 127 | 435 + - - - - - - - - - - - - - - - +-------------------------------+ 436 | | Extension data | 437 +-------------------------------+ - - - - - - - - - - - - - - - + 438 : : 439 +---------------------------------------------------------------+ 440 : Application data : 441 +---------------------------------------------------------------+ 443 FIN: 1 bit 445 Indicates no more fragments follow in the current message 447 OLD: 449 ws-frame = frame-more 450 frame-rsv1 451 frame-rsv2 452 frame-rsv3 453 frame-opcode 454 frame-rsv4 455 frame-length 456 frame-extension 457 application-data; 459 frame-more = %x0 ; final frame of message 460 / %x1 ; more frames of this message follow 462 frame-rsv1 = %x0 ; 1 bit, must be 0 464 frame-rsv2 = %x0 ; 1 bit, must be 0 466 frame-rsv3 = %x0 ; 1 bit, must be 0 468 frame-opcode = %x0 ; continuation frame 469 / %x1 ; connection close 470 / %x2 ; ping 471 / %x3 ; pong 472 / %x4 ; text frame 473 / %x5 ; binary frame 474 / %x6-F ; reserved 476 NEW: 478 ws-frame = frame-fin 479 frame-rsv1 480 frame-rsv2 481 frame-rsv3 482 frame-opcode 483 frame-rsv4 484 frame-length 485 frame-extension 486 application-data; 488 frame-fin = %x1 ; final frame of message 489 / %x0 ; more frames of this message follow 491 frame-rsv1 = %x0 ; 1 bit, must be 0 493 frame-rsv2 = %x0 ; 1 bit, must be 0 495 frame-rsv3 = %x0 ; 1 bit, must be 0 497 frame-opcode = %x0 ; continuation frame 498 / %x1 ; connection close 499 / %x2 ; ping 500 / %x3 ; pong 501 / %x4 ; text frame 502 / %x5 ; binary frame 503 / %x6-E ; reserved 504 / %xF ; Hello frame 506 9. Changes to 4.3. Fragmentation 508 OLD: 510 o An unfragmented message consists of a single frame with the MORE 511 bit clear and an opcode other than 0. 513 o A fragmented message consists of a single frame with the MORE bit 514 set and an opcode other than 0, followed by zero or more frames 515 with the MORE bit set and the opcode set to 0, and terminated by a 516 single frame with the MORE bit clear and an opcode of 0. Its 517 content is the concatenation of the application data from each of 518 those frames in order. 520 NEW: 522 o An unfragmented message consists of a single frame with the FIN 523 bit set and an opcode other than 0. 525 o A fragmented message consists of a single frame with the FIN bit 526 clear and an opcode other than 0, followed by zero or more frames 527 with the FIN bit clear and the opcode set to 0, and terminated 528 by asingle frame with the FIN bit set and an opcode of 0. Its 529 content is the concatenation of the application data from each of 530 those frames in order. 532 10. Changes to 4.4. Control Frames 534 OLD: 536 Control frames have opcodes of 0x01 (Close), 0x02 (Ping), or 0x03 537 (Pong). Control frames are used to communicate state about the 538 websocket. 540 NEW: 542 Control frames have opcodes of 0x01 (Close), 0x02 (Ping), 0x03 543 (Pong) or 0x0f (Hello). Control frames are used to communicate 544 state about the websocket. 546 Add a NEW section 4.4.4. after 4.4.3 for the new "Hello" command: 548 4.4.4. Hello 550 The Hello message contains an opcode of 0x0F and must be the first 551 frame sent on any WebSocket connection. 553 A Hello message sent from the server to the client must contain 24 554 octets of data, comprising of the 8 octets of the server nonce and 555 the 16 octets of the MD5 digest of the 41 octets of the client 556 nonce, plus the ASCII string "WebSocket", plus the server nonce. 558 A Hello message sent from the client to the server must contain 16 559 octets of data, comprising the MD5 digest of the 41 octets of the 560 server nonce, plus the ASCII string "WebSocket", plus the client 561 nonce. 563 11. Changes to 4.6. Examples 565 OLD: 567 o A single-frame text message 569 * 0x04 0x05 "Hello" 571 o A fragmented text message 573 * 0x84 0x03 "Hel" 575 * 0x00 0x02 "lo" 577 o Ping request and response 579 * 0x02 0x05 "Hello" 581 * 0x03 0x05 "Hello" 583 o 256 bytes binary message in a single frame 585 * 0x05 0x7E 0x0100 [256 bytes of binary data] 587 o 64KiB binary message in a single frame 589 * 0x05 0x7F 0x0000000000010000 [65536 bytes of binary data] 591 NEW: 593 o A single-frame text message 595 * 0x84 0x05 "Hello" 597 o A fragmented text message 599 * 0x04 0x03 "Hel" 601 * 0x80 0x02 "lo" 603 o Ping request and response 605 * 0x82 0x05 "Hello" 607 * 0x83 0x05 "Hello" 609 o 256 bytes binary message in a single frame 611 * 0x85 0x7E 0x0100 [256 bytes of binary data] 613 o 64KiB binary message in a single frame 614 * 0x85 0x7F 0x0000000000010000 [65536 bytes of binary data] 616 12. Changes to 5.1. Client Requirements 618 OLD: 620 15. Add the string "Sec-WebSocket-Draft: 2" to /fields/. 622 NEW: 624 15. Add the string "Sec-WebSocket-Draft: 3" to /fields/. 626 Note: In the following changes, renumbering is not shown. That 627 should be taken care of by the diff patch to the specification source 628 file. 630 OLD: 632 19. Let /spaces_1/ be a random integer from 1 to 12 inclusive. 634 Let /spaces_2/ be a random integer from 1 to 12 inclusive. 636 EXAMPLE: For example, 5 and 9. 638 20. Let /max_1/ be the largest integer not greater than 639 4,294,967,295 divided by /spaces_1/. 641 Let /max_2/ be the largest integer not greater than 642 4,294,967,295 divided by /spaces_2/. 644 EXAMPLE: Continuing the example, 858,993,459 and 477,218,588. 646 21. Let /number_1/ be a random integer from 0 to /max_1/ inclusive. 648 Let /number_2/ be a random integer from 0 to /max_2/ inclusive. 650 EXAMPLE: For example, 777,007,543 and 114,997,259. 652 22. Let /product_1/ be the result of multiplying /number_1/ and 653 /spaces_1/ together. 655 Let /product_2/ be the result of multiplying /number_2/ and 656 /spaces_2/ together. 658 EXAMPLE: Continuing the example, 3,885,037,715 and 659 1,034,975,331. 661 23. Let /key_1/ be a string consisting of /product_1/, expressed in 662 base ten using the numerals in the range U+0030 DIGIT ZERO (0) 663 to U+0039 DIGIT NINE (9). 665 Let /key_2/ be a string consisting of /product_2/, expressed in 666 base ten using the numerals in the range U+0030 DIGIT ZERO (0) 667 to U+0039 DIGIT NINE (9). 669 EXAMPLE: Continuing the example, "3885037715" and "1034975331". 671 24. Insert between one and twelve random characters from the ranges 672 U+0021 to U+002F and U+003A to U+007E into /key_1/ at random 673 positions. 675 Insert between one and twelve random characters from the ranges 676 U+0021 to U+002F and U+003A to U+007E into /key_2/ at random 677 positions. 679 NOTE: This corresponds to random printable ASCII characters 680 other than the digits and the U+0020 SPACE character. 682 EXAMPLE: Continuing the example, this could lead to "P388O503D& 683 ul7{K%gX(%715" and "1N?|kUT0or3o4I97N5-S3O31". 685 25. Insert /spaces_1/ U+0020 SPACE characters into /key_1/ at random 686 positions other than the start or end of the string. 688 Insert /spaces_2/ U+0020 SPACE characters into /key_2/ at random 689 positions other than the start or end of the string. 691 EXAMPLE: Continuing the example, this could lead to "P388 O503D& 692 ul7 {K%gX( %7 15" and "1 N ?|k UT0or 3o 4 I97N 5-S3O 31". 694 26. Add the string consisting of the concatenation of the string 695 "Sec-WebSocket-Key1:", a U+0020 SPACE character, and the /key_1/ 696 value, to /fields/. 698 Add the string consisting of the concatenation of the string 699 "Sec-WebSocket-Key2:", a U+0020 SPACE character, and the /key_2/ 700 value, to /fields/. 702 NEW: 704 19. Let /client nonce/ be a random 64 bit integer. 706 EXAMPLE expressed as a hexadecimal number : 708 A23F2BCA452DDE01 710 26. Add the string consisting of the concatenation of the string 711 "Sec-WebSocket-Nonce:", a U+0020 SPACE character, and the 712 /client nonce/ value expressed as a base 16 using numerals 713 in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9) 714 and letters in the range U+0041 LATIN CAPITAL LETTER A to 715 U+0046 LATIN CAPITAL LETTER F, to /fields/. 717 Delete these OLD items: 719 29. Let /key_3/ be a string consisting of eight random bytes (or 720 equivalently, a random 64 bit unsigned integer encoded in big- 721 endian order). 723 EXAMPLE: For example, 0x47 0x30 0x22 0x2D 0x5A 0x3F 0x47 0x58. 725 30. Send /key_3/ to the server. 727 OLD: 729 45. Let /challenge/ be the concatenation of /number_1/, expressed as 730 a big-endian 32 bit integer, /number_2/, expressed as a big- 731 endian 32 bit integer, and the eight bytes of /key_3/ in the 732 order they were sent on the wire. 734 EXAMPLE: Using the examples given earlier, this leads to the 16 735 bytes 0x2E 0x50 0x31 0xB7 0x06 0xDA 0xB8 0x0B 0x47 0x30 0x22 736 0x2D 0x5A 0x3F 0x47 0x58. 738 46. Let /expected/ be the MD5 fingerprint of /challenge/ as a big- 739 endian 128 bit string. [RFC1321] 741 EXAMPLE: Using the examples given earlier, this leads to the 16 742 bytes 0x30 0x73 0x74 0x33 0x52 0x6C 0x26 0x71 0x2D 0x32 0x5A 743 0x55 0x5E 0x77 0x65 0x75. In UTF-8, these bytes correspond to 744 the string "0st3Rl&q-2ZU^weu". 746 47. Read sixteen bytes from the server. Let /reply/ be those bytes. 748 If the connection closes before these bytes are received, then 749 fail the WebSocket connection and abort these steps. 751 48. If /reply/ does not exactly equal /expected/, then fail the 752 WebSocket connection and abort these steps. 754 NEW: 756 47. Read twenty six bytes from the server. Let /server hello/ be those bytes. 758 If the connection closes before these bytes are received, then 759 fail the WebSocket connection and abort these steps. 761 48. If the first octet of /server hello/ is not 0x8f then fail the WebSocket 762 connection and abort these steps. 764 If the second octet of /server hello/ is not 0x18 then fail the WebSocket 765 connection and abort these steps. 767 49. Let /server nonce/ be the 8 octets starting from the third octet of 768 /server hello/ 770 EXAMPLE expressed as a hexadecimal number: 772 15F0D2278BCD457F 774 Let /server digest/ be the 16 octets starting from the eleventh 775 octet of /server hello/ 777 50. Let /server expected/ be the 16 octets of MD5 digest of the 778 concatenation of /client nonce/, the ASCII string "WebSocket" and 779 /server nonce/ 781 EXAMPLE expressed as a hexadecimal number: 783 Ee7eBe0c369cBf255a4451Fc58D7Cc4f 785 51. If /server digest/ does not equal /server expected/ then fail 786 the WebSocket connection and abort these steps. 788 52. Let /client digest/ be the 16 octets of MD5 digest of the 789 concatenation of /server nonce/, the ASCII string "WebSocket" and 790 /client nonce/. 792 53. Send the octets 0x8f, 0x10 and /client digest/ 794 13. Changes to 5.2.1. Reading the client's opening handshake 796 OLD: 798 1. The three-character UTF-8 string "GET". 800 2. A UTF-8-encoded U+0020 SPACE character (0x20 byte). 802 3. A string consisting of all the bytes up to the next UTF-8-encoded 803 U+0020 SPACE character (0x20 byte). The result of decoding this 804 string as a UTF-8 string is the name of the resource requested by 805 the server. If the server only supports one resource, then this 806 can safely be ignored; the client verifies that the right 808 NEW: 810 1. The three-character UTF-8 string "GET". 812 2. A UTF-8-encoded U+0020 SPACE character (0x20 byte). 814 3. A string consisting of all the bytes up to the next UTF-8-encoded 815 U+0020 SPACE character (0x20 byte). The result of decoding this 816 string as a UTF-8 string is the name of the resource requested by 817 the server and must be a valid resource name according to Section 3.3. 819 If the server only supports one resource, then this 820 can safely be ignored; the client verifies that the right 822 OLD: 824 |Sec-WebSocket-Key1| 826 |Sec-WebSocket-Key2| 828 NEW: 830 |Sec-WebSocket-Nonce| 832 OLD: 834 /key_1/ 835 The value of the "Sec-WebSocket-Key1" field in the client's 836 handshake. 838 � 839 /key_2/ 840 The value of the "Sec-WebSocket-Key2" field in the client's 841 handshake. 843 /key_3/ 844 The eight random bytes sent after the first 0x0D 0x0A 0x0D 845 0x0A sequence in the client's handshake. 847 3. Let /location/ be the string that results from constructing a 848 WebSocket URL from /host/, /port/, /resource name/, and /secure 849 flag/. 851 4. Let /key-number_1/ be the digits (characters in the range U+0030 852 DIGIT ZERO (0) to U+0039 DIGIT NINE (9)) in /key_1/, interpreted 853 as a base ten integer, ignoring all other characters in /key_1/. 855 Let /key-number_2/ be the digits (characters in the range U+0030 856 DIGIT ZERO (0) to U+0039 DIGIT NINE (9)) in /key_2/, interpreted 857 as a base ten integer, ignoring all other characters in /key_2/. 859 EXAMPLE: For example, assume that the client handshake was: 861 GET / HTTP/1.1 862 Connection: Upgrade 863 Host: example.com 864 Upgrade: WebSocket 865 Sec-WebSocket-Key1: 3e6b263 4 17 80 866 Origin: http://example.com 867 Sec-WebSocket-Key2: 17 9 G`ZD9 2 2b 7X 3 /r90 869 WjN}|M(6 871 The /key-number_1/ would be the number 3,626,341,780, and the 872 /key-number_2/ would be the number 1,799,227,390. 874 In this example, incidentally, /key_3/ is "WjN}|M(6", or 0x57 875 0x6A 0x4E 0x7D 0x7C 0x4D 0x28 0x36. 877 5. Let /spaces_1/ be the number of U+0020 SPACE characters in 878 /key_1/. 880 Let /spaces_2/ be the number of U+0020 SPACE characters in 881 /key_2/. 883 If either /spaces_1/ or /spaces_2/ is zero, then abort the 884 WebSocket connection. This is a symptom of a cross-protocol 885 attack. 887 EXAMPLE: In the example above, /spaces_1/ would be 4 and 888 /spaces_2/ would be 10. 890 6. If /key-number_1/ is not an integral multiple of /spaces_1/, 891 then abort the WebSocket connection. 893 If /key-number_2/ is not an integral multiple of /spaces_2/, 894 then abort the WebSocket connection. 896 NOTE: This can only happen if the client is not a conforming 897 WebSocket client. 899 7. Let /part_1/ be /key-number_1/ divided by /spaces_1/. 901 Let /part_2/ be /key-number_2/ divided by /spaces_2/. 903 EXAMPLE: In the example above, /part_1/ would be 906,585,445 and 904 /part_2/ would be 179,922,739. 906 8. Let /challenge/ be the concatenation of /part_1/, expressed as a 907 big-endian 32 bit integer, /part_2/, expressed as a big-endian 908 32 bit integer, and the eight bytes of /key_3/ in the order they 909 were sent on the wire. 911 EXAMPLE: In the example above, this would be the 16 bytes 0x36 912 0x09 0x65 0x65 0x0A 0xB9 0x67 0x33 0x57 0x6A 0x4E 0x7D 0x7C 0x4D 913 0x28 0x36. 915 9. Let /response/ be the MD5 fingerprint of /challenge/ as a big- 916 endian 128 bit string. [RFC1321] 918 EXAMPLE: In the example above, this would be the 16 bytes 0x6E 919 0x60 0x39 0x65 0x42 0x6B 0x39 0x7A 0x24 0x52 0x38 0x70 0x4F 0x74 920 0x56 0x62, or "n`9eBk9z$R8pOtVb" in UTF-8. 922 NEW: 924 /client nonce/ 925 The value of the "Sec-WebSocket-Nonce" field in the client's 926 handshake. 928 /server nonce/ 929 An 64 bit random integer generated by the server. 931 EXAMPLE expressed in hexadecimal: 933 15F0D2278BCD457F 935 3. Let /location/ be the string that results from constructing a 936 WebSocket URL from /host/, /port/, /resource name/, and /secure 937 flag/. 939 4. Let /server digest/ be the 16 octets of MD5 digest of the 940 concatenation of /client nonce/, the ASCII string "WebSocket" and 941 /server nonce/ 943 EXAMPLE expressed in hexadecimal: 945 Ee7eBe0c369cBf255a4451Fc58D7Cc4f 947 OLD: 949 13. Send /response/. 951 NEW: 953 13. Send the octets 0x8F, 0x18, /server nonce/ and /server digest/. 955 14. The *WebSocket connection is accepted*. Now the server may 956 send messages to the connection as described in the next section. 958 15. Read eighteen octets from the server. Let /client hello/ be those bytes. 960 If the connection closes before these bytes are received, then 961 fail the WebSocket connection and abort these steps. 963 48. If the first octet of /client hello/ is not 0x8f then fail the WebSocket 964 connection and abort these steps. 966 If the second octet of /client hello/ is not 0x10 then fail the WebSocket 967 connection and abort these steps. 969 50. Let /client expected/ be the 16 octets of MD5 digest of the 970 concatenation of /server nonce/, the ASCII string "WebSocket" and 971 /client nonce/ 973 EXAMPLE expressed as a hexadecimal number: 975 33122035D11258Fd7c764314580e539c 977 Let /client digest/ be the 16 octets starting from the third 978 octet of /client hello/ 980 51. If /client digest/ does not equal /client expected/ then fail 981 the WebSocket connection and abort these steps. 983 52. The *WebSocket connection is established*. Now the server 984 may send and receive to and from the connection as described in 985 the next section. 987 14. Security Considerations 989 15. IANA Considerations 991 This requirements document does not mandate any IANA actions. 993 16. Acknowledgments 995 Thanks to Scott Ferguson, Willy Tarreau, Dave Cridland, among others. 997 17. References 998 17.1. Normative References 1000 [RFC2119] Bradner, S., "Key words for 1001 use in RFCs to Indicate 1002 Requirement Levels", BCP 14, 1003 RFC 2119, March 1997. 1005 [RFC2616] Fielding, R., Gettys, J., 1006 Mogul, J., Frystyk, H., 1007 Masinter, L., Leach, P., and 1008 T. Berners-Lee, "Hypertext 1009 Transfer Protocol -- 1010 HTTP/1.1", RFC 2616, 1011 June 1999. 1013 [I-D.ietf-hybi-websocket-requirements] Montenegro, G., "HyBi 1014 WebSocket Requirements and 1015 Features", draft-ietf-hybi- 1016 websocket-requirements-01 1017 (work in progress), 1018 August 2010. 1020 [I-D.ietf-hybi-thewebsocketprotocol] Fette, I., "The WebSocket 1021 protocol", draft-ietf-hybi- 1022 thewebsocketprotocol-03 (work 1023 in progress), October 2010. 1025 17.2. Informative References 1027 [I-D.ietf-hybi-design-space] Moffitt, J., Loreto, S., 1028 Saint-Andre, P., and S. 1029 Salsano, "Design Space for 1030 Bidirectional Protocols", dra 1031 ft-ietf-hybi-design-space-00 1032 (work in progress), 1033 June 2010. 1035 Authors' Addresses 1037 Greg Wilkins 1038 WebTide 1040 EMail: gregw@webtide.com 1041 Gabriel Montenegro 1042 Microsoft Corporation 1044 EMail: gabriel.montenegro@microsoft.com