OLD | NEW |
1 /* This Source Code Form is subject to the terms of the Mozilla Public | 1 /* This Source Code Form is subject to the terms of the Mozilla Public |
2 * License, v. 2.0. If a copy of the MPL was not distributed with this | 2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
4 | 4 |
5 /* | 5 /* |
6 * DTLS Protocol | 6 * DTLS Protocol |
7 */ | 7 */ |
8 | 8 |
9 #include "ssl.h" | 9 #include "ssl.h" |
10 #include "sslimpl.h" | 10 #include "sslimpl.h" |
11 #include "sslproto.h" | 11 #include "sslproto.h" |
12 | 12 |
13 #ifndef PR_ARRAY_SIZE | 13 #ifndef PR_ARRAY_SIZE |
14 #define PR_ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0])) | 14 #define PR_ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) |
15 #endif | 15 #endif |
16 | 16 |
17 static SECStatus dtls_TransmitMessageFlight(sslSocket *ss); | 17 static SECStatus dtls_TransmitMessageFlight(sslSocket *ss); |
18 static void dtls_RetransmitTimerExpiredCb(sslSocket *ss); | 18 static void dtls_RetransmitTimerExpiredCb(sslSocket *ss); |
19 static SECStatus dtls_SendSavedWriteData(sslSocket *ss); | 19 static SECStatus dtls_SendSavedWriteData(sslSocket *ss); |
20 | 20 |
21 /* -28 adjusts for the IP/UDP header */ | 21 /* -28 adjusts for the IP/UDP header */ |
22 static const PRUint16 COMMON_MTU_VALUES[] = { | 22 static const PRUint16 COMMON_MTU_VALUES[] = { |
23 1500 - 28, /* Ethernet MTU */ | 23 1500 - 28, /* Ethernet MTU */ |
24 1280 - 28, /* IPv6 minimum MTU */ | 24 1280 - 28, /* IPv6 minimum MTU */ |
25 576 - 28, /* Common assumption */ | 25 576 - 28, /* Common assumption */ |
26 256 - 28 /* We're in serious trouble now */ | 26 256 - 28 /* We're in serious trouble now */ |
27 }; | 27 }; |
28 | 28 |
29 #define DTLS_COOKIE_BYTES 32 | 29 #define DTLS_COOKIE_BYTES 32 |
30 | 30 |
31 /* List copied from ssl3con.c:cipherSuites */ | 31 /* List copied from ssl3con.c:cipherSuites */ |
32 static const ssl3CipherSuite nonDTLSSuites[] = { | 32 static const ssl3CipherSuite nonDTLSSuites[] = { |
33 #ifndef NSS_DISABLE_ECC | 33 #ifndef NSS_DISABLE_ECC |
34 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, | 34 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, |
35 TLS_ECDHE_RSA_WITH_RC4_128_SHA, | 35 TLS_ECDHE_RSA_WITH_RC4_128_SHA, |
36 #endif /* NSS_DISABLE_ECC */ | 36 #endif /* NSS_DISABLE_ECC */ |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 SSL3ProtocolVersion | 79 SSL3ProtocolVersion |
80 dtls_DTLSVersionToTLSVersion(SSL3ProtocolVersion dtlsv) | 80 dtls_DTLSVersionToTLSVersion(SSL3ProtocolVersion dtlsv) |
81 { | 81 { |
82 if (MSB(dtlsv) == 0xff) { | 82 if (MSB(dtlsv) == 0xff) { |
83 return 0; | 83 return 0; |
84 } | 84 } |
85 | 85 |
86 if (dtlsv == SSL_LIBRARY_VERSION_DTLS_1_0_WIRE) { | 86 if (dtlsv == SSL_LIBRARY_VERSION_DTLS_1_0_WIRE) { |
87 return SSL_LIBRARY_VERSION_TLS_1_1; | 87 return SSL_LIBRARY_VERSION_TLS_1_1; |
88 } | 88 } |
| 89 /* Handle the skipped version of DTLS 1.1 by returning |
| 90 * an error. */ |
| 91 if (dtlsv == ((~0x0101) & 0xffff)) { |
| 92 return 0; |
| 93 } |
89 if (dtlsv == SSL_LIBRARY_VERSION_DTLS_1_2_WIRE) { | 94 if (dtlsv == SSL_LIBRARY_VERSION_DTLS_1_2_WIRE) { |
90 return SSL_LIBRARY_VERSION_TLS_1_2; | 95 return SSL_LIBRARY_VERSION_TLS_1_2; |
91 } | 96 } |
92 if (dtlsv == SSL_LIBRARY_VERSION_DTLS_1_3_WIRE) { | 97 if (dtlsv == SSL_LIBRARY_VERSION_DTLS_1_3_WIRE) { |
93 return SSL_LIBRARY_VERSION_TLS_1_3; | 98 return SSL_LIBRARY_VERSION_TLS_1_3; |
94 } | 99 } |
95 | 100 |
96 /* Return a fictional higher version than we know of */ | 101 /* Return a fictional higher version than we know of */ |
97 return SSL_LIBRARY_VERSION_TLS_1_2 + 1; | 102 return SSL_LIBRARY_VERSION_MAX_SUPPORTED + 1; |
98 } | 103 } |
99 | 104 |
100 /* On this socket, Disable non-DTLS cipher suites in the argument's list */ | 105 /* On this socket, Disable non-DTLS cipher suites in the argument's list */ |
101 SECStatus | 106 SECStatus |
102 ssl3_DisableNonDTLSSuites(sslSocket * ss) | 107 ssl3_DisableNonDTLSSuites(sslSocket *ss) |
103 { | 108 { |
104 const ssl3CipherSuite * suite; | 109 const ssl3CipherSuite *suite; |
105 | 110 |
106 for (suite = nonDTLSSuites; *suite; ++suite) { | 111 for (suite = nonDTLSSuites; *suite; ++suite) { |
107 PORT_CheckSuccess(ssl3_CipherPrefSet(ss, *suite, PR_FALSE)); | 112 PORT_CheckSuccess(ssl3_CipherPrefSet(ss, *suite, PR_FALSE)); |
108 } | 113 } |
109 return SECSuccess; | 114 return SECSuccess; |
110 } | 115 } |
111 | 116 |
112 /* Allocate a DTLSQueuedMessage. | 117 /* Allocate a DTLSQueuedMessage. |
113 * | 118 * |
114 * Called from dtls_QueueMessage() | 119 * Called from dtls_QueueMessage() |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
178 * | 183 * |
179 * Note that this code uses msg_len for two purposes: | 184 * Note that this code uses msg_len for two purposes: |
180 * | 185 * |
181 * (1) To pass the length to ssl3_HandleHandshakeMessage() | 186 * (1) To pass the length to ssl3_HandleHandshakeMessage() |
182 * (2) To carry the length of a message currently being reassembled | 187 * (2) To carry the length of a message currently being reassembled |
183 * | 188 * |
184 * However, unlike ssl3_HandleHandshake(), it is not used to carry | 189 * However, unlike ssl3_HandleHandshake(), it is not used to carry |
185 * the state of reassembly (i.e., whether one is in progress). That | 190 * the state of reassembly (i.e., whether one is in progress). That |
186 * is carried in recvdHighWater and recvdFragments. | 191 * is carried in recvdHighWater and recvdFragments. |
187 */ | 192 */ |
188 #define OFFSET_BYTE(o) (o/8) | 193 #define OFFSET_BYTE(o) (o / 8) |
189 #define OFFSET_MASK(o) (1 << (o%8)) | 194 #define OFFSET_MASK(o) (1 << (o % 8)) |
190 | 195 |
191 SECStatus | 196 SECStatus |
192 dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf) | 197 dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf) |
193 { | 198 { |
194 /* XXX OK for now. | 199 /* XXX OK for now. |
195 * This doesn't work properly with asynchronous certificate validation. | 200 * This doesn't work properly with asynchronous certificate validation. |
196 * because that returns a WOULDBLOCK error. The current DTLS | 201 * because that returns a WOULDBLOCK error. The current DTLS |
197 * applications do not need asynchronous validation, but in the | 202 * applications do not need asynchronous validation, but in the |
198 * future we will need to add this. | 203 * future we will need to add this. |
199 */ | 204 */ |
(...skipping 17 matching lines...) Expand all Loading... |
217 break; | 222 break; |
218 } | 223 } |
219 | 224 |
220 /* Parse the header */ | 225 /* Parse the header */ |
221 type = buf.buf[0]; | 226 type = buf.buf[0]; |
222 message_length = (buf.buf[1] << 16) | (buf.buf[2] << 8) | buf.buf[3]; | 227 message_length = (buf.buf[1] << 16) | (buf.buf[2] << 8) | buf.buf[3]; |
223 message_seq = (buf.buf[4] << 8) | buf.buf[5]; | 228 message_seq = (buf.buf[4] << 8) | buf.buf[5]; |
224 fragment_offset = (buf.buf[6] << 16) | (buf.buf[7] << 8) | buf.buf[8]; | 229 fragment_offset = (buf.buf[6] << 16) | (buf.buf[7] << 8) | buf.buf[8]; |
225 fragment_length = (buf.buf[9] << 16) | (buf.buf[10] << 8) | buf.buf[11]; | 230 fragment_length = (buf.buf[9] << 16) | (buf.buf[10] << 8) | buf.buf[11]; |
226 | 231 |
227 #define MAX_HANDSHAKE_MSG_LEN 0x1ffff /* 128k - 1 */ | 232 #define MAX_HANDSHAKE_MSG_LEN 0x1ffff /* 128k - 1 */ |
228 if (message_length > MAX_HANDSHAKE_MSG_LEN) { | 233 if (message_length > MAX_HANDSHAKE_MSG_LEN) { |
229 (void)ssl3_DecodeError(ss); | 234 (void)ssl3_DecodeError(ss); |
230 PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE); | 235 PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE); |
231 return SECFailure; | 236 return SECFailure; |
232 } | 237 } |
233 #undef MAX_HANDSHAKE_MSG_LEN | 238 #undef MAX_HANDSHAKE_MSG_LEN |
234 | 239 |
235 buf.buf += 12; | 240 buf.buf += 12; |
236 buf.len -= 12; | 241 buf.len -= 12; |
237 | 242 |
(...skipping 13 matching lines...) Expand all Loading... |
251 | 256 |
252 /* There are three ways we could not be ready for this packet. | 257 /* There are three ways we could not be ready for this packet. |
253 * | 258 * |
254 * 1. It's a partial next message. | 259 * 1. It's a partial next message. |
255 * 2. It's a partial or complete message beyond the next | 260 * 2. It's a partial or complete message beyond the next |
256 * 3. It's a message we've already seen | 261 * 3. It's a message we've already seen |
257 * | 262 * |
258 * If it's the complete next message we accept it right away. | 263 * If it's the complete next message we accept it right away. |
259 * This is the common case for short messages | 264 * This is the common case for short messages |
260 */ | 265 */ |
261 if ((message_seq == ss->ssl3.hs.recvMessageSeq) | 266 if ((message_seq == ss->ssl3.hs.recvMessageSeq) && |
262 && (fragment_offset == 0) | 267 (fragment_offset == 0) && |
263 && (fragment_length == message_length)) { | 268 (fragment_length == message_length)) { |
264 /* Complete next message. Process immediately */ | 269 /* Complete next message. Process immediately */ |
265 ss->ssl3.hs.msg_type = (SSL3HandshakeType)type; | 270 ss->ssl3.hs.msg_type = (SSL3HandshakeType)type; |
266 ss->ssl3.hs.msg_len = message_length; | 271 ss->ssl3.hs.msg_len = message_length; |
267 | 272 |
268 /* At this point we are advancing our state machine, so | 273 /* At this point we are advancing our state machine, so |
269 * we can free our last flight of messages */ | 274 * we can free our last flight of messages */ |
270 dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight); | 275 dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight); |
271 ss->ssl3.hs.recvdHighWater = -1; | 276 ss->ssl3.hs.recvdHighWater = -1; |
272 dtls_CancelTimer(ss); | 277 dtls_CancelTimer(ss); |
273 | 278 |
274 /* Reset the timer to the initial value if the retry counter | 279 /* Reset the timer to the initial value if the retry counter |
275 * is 0, per Sec. 4.2.4.1 */ | 280 * is 0, per Sec. 4.2.4.1 */ |
276 if (ss->ssl3.hs.rtRetries == 0) { | 281 if (ss->ssl3.hs.rtRetries == 0) { |
277 ss->ssl3.hs.rtTimeoutMs = INITIAL_DTLS_TIMEOUT_MS; | 282 ss->ssl3.hs.rtTimeoutMs = INITIAL_DTLS_TIMEOUT_MS; |
278 } | 283 } |
279 | 284 |
280 rv = ssl3_HandleHandshakeMessage(ss, buf.buf, ss->ssl3.hs.msg_len); | 285 rv = ssl3_HandleHandshakeMessage(ss, buf.buf, ss->ssl3.hs.msg_len); |
281 if (rv == SECFailure) { | 286 if (rv == SECFailure) { |
282 /* Do not attempt to process rest of messages in this record */ | 287 /* Do not attempt to process rest of messages in this record */ |
283 break; | 288 break; |
284 } | 289 } |
285 } else { | 290 } else { |
286 if (message_seq < ss->ssl3.hs.recvMessageSeq) { | 291 if (message_seq < ss->ssl3.hs.recvMessageSeq) { |
287 /* Case 3: we do an immediate retransmit if we're | 292 /* Case 3: we do an immediate retransmit if we're |
288 * in a waiting state*/ | 293 * in a waiting state*/ |
289 if (ss->ssl3.hs.rtTimerCb == NULL) { | 294 if (ss->ssl3.hs.rtTimerCb == NULL) { |
290 /* Ignore */ | 295 /* Ignore */ |
291 } else if (ss->ssl3.hs.rtTimerCb == | 296 } else if (ss->ssl3.hs.rtTimerCb == |
292 dtls_RetransmitTimerExpiredCb) { | 297 dtls_RetransmitTimerExpiredCb) { |
293 SSL_TRC(30, ("%d: SSL3[%d]: Retransmit detected", | 298 SSL_TRC(30, ("%d: SSL3[%d]: Retransmit detected", |
294 SSL_GETPID(), ss->fd)); | 299 SSL_GETPID(), ss->fd)); |
295 /* Check to see if we retransmitted recently. If so, | 300 /* Check to see if we retransmitted recently. If so, |
296 * suppress the triggered retransmit. This avoids | 301 * suppress the triggered retransmit. This avoids |
297 * retransmit wars after packet loss. | 302 * retransmit wars after packet loss. |
298 * This is not in RFC 5346 but should be | 303 * This is not in RFC 5346 but should be |
299 */ | 304 */ |
300 if ((PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted) > | 305 if ((PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted) > |
301 (ss->ssl3.hs.rtTimeoutMs / 4)) { | 306 (ss->ssl3.hs.rtTimeoutMs / 4)) { |
302 SSL_TRC(30, | 307 SSL_TRC(30, |
303 ("%d: SSL3[%d]: Shortcutting retransmit timer", | 308 ("%d: SSL3[%d]: Shortcutting retransmit timer", |
304 SSL_GETPID(), ss->fd)); | 309 SSL_GETPID(), ss->fd)); |
305 | 310 |
306 /* Cancel the timer and call the CB, | 311 /* Cancel the timer and call the CB, |
307 * which re-arms the timer */ | 312 * which re-arms the timer */ |
308 dtls_CancelTimer(ss); | 313 dtls_CancelTimer(ss); |
309 dtls_RetransmitTimerExpiredCb(ss); | 314 dtls_RetransmitTimerExpiredCb(ss); |
310 rv = SECSuccess; | 315 rv = SECSuccess; |
311 break; | 316 break; |
312 } else { | 317 } else { |
313 SSL_TRC(30, | 318 SSL_TRC(30, |
314 ("%d: SSL3[%d]: We just retransmitted. Ignoring.", | 319 ("%d: SSL3[%d]: We just retransmitted. Ignoring.
", |
315 SSL_GETPID(), ss->fd)); | 320 SSL_GETPID(), ss->fd)); |
316 rv = SECSuccess; | 321 rv = SECSuccess; |
317 break; | 322 break; |
318 } | 323 } |
319 } else if (ss->ssl3.hs.rtTimerCb == dtls_FinishedTimerCb) { | 324 } else if (ss->ssl3.hs.rtTimerCb == dtls_FinishedTimerCb) { |
320 /* Retransmit the messages and re-arm the timer | 325 /* Retransmit the messages and re-arm the timer |
321 * Note that we are not backing off the timer here. | 326 * Note that we are not backing off the timer here. |
322 * The spec isn't clear and my reasoning is that this | 327 * The spec isn't clear and my reasoning is that this |
323 * may be a re-ordered packet rather than slowness, | 328 * may be a re-ordered packet rather than slowness, |
324 * so let's be aggressive. */ | 329 * so let's be aggressive. */ |
325 dtls_CancelTimer(ss); | 330 dtls_CancelTimer(ss); |
326 rv = dtls_TransmitMessageFlight(ss); | 331 rv = dtls_TransmitMessageFlight(ss); |
327 if (rv == SECSuccess) { | 332 if (rv == SECSuccess) { |
328 rv = dtls_StartTimer(ss, dtls_FinishedTimerCb); | 333 rv = dtls_StartTimer(ss, dtls_FinishedTimerCb); |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
443 ss->ssl3.hs.rtTimeoutMs = INITIAL_DTLS_TIMEOUT_MS; | 448 ss->ssl3.hs.rtTimeoutMs = INITIAL_DTLS_TIMEOUT_MS; |
444 } | 449 } |
445 } | 450 } |
446 } | 451 } |
447 } | 452 } |
448 | 453 |
449 buf.buf += fragment_length; | 454 buf.buf += fragment_length; |
450 buf.len -= fragment_length; | 455 buf.len -= fragment_length; |
451 } | 456 } |
452 | 457 |
453 origBuf->len = 0; /* So ssl3_GatherAppDataRecord will keep looping. */ | 458 origBuf->len = 0; /* So ssl3_GatherAppDataRecord will keep looping. */ |
454 | 459 |
455 /* XXX OK for now. In future handle rv == SECWouldBlock safely in order | 460 /* XXX OK for now. In future handle rv == SECWouldBlock safely in order |
456 * to deal with asynchronous certificate verification */ | 461 * to deal with asynchronous certificate verification */ |
457 return rv; | 462 return rv; |
458 } | 463 } |
459 | 464 |
460 /* Enqueue a message (either handshake or CCS) | 465 /* Enqueue a message (either handshake or CCS) |
461 * | 466 * |
462 * Called from: | 467 * Called from: |
463 * dtls_StageHandshakeMessage() | 468 * dtls_StageHandshakeMessage() |
464 * ssl3_SendChangeCipherSpecs() | 469 * ssl3_SendChangeCipherSpecs() |
465 */ | 470 */ |
466 SECStatus dtls_QueueMessage(sslSocket *ss, SSL3ContentType type, | 471 SECStatus |
467 const SSL3Opaque *pIn, PRInt32 nIn) | 472 dtls_QueueMessage(sslSocket *ss, SSL3ContentType type, |
| 473 const SSL3Opaque *pIn, PRInt32 nIn) |
468 { | 474 { |
469 SECStatus rv = SECSuccess; | 475 SECStatus rv = SECSuccess; |
470 DTLSQueuedMessage *msg = NULL; | 476 DTLSQueuedMessage *msg = NULL; |
471 | 477 |
472 PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); | 478 PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); |
473 PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); | 479 PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); |
474 | 480 |
475 msg = dtls_AllocQueuedMessage(ss->ssl3.cwSpec->epoch, type, pIn, nIn); | 481 msg = dtls_AllocQueuedMessage(ss->ssl3.cwSpec->epoch, type, pIn, nIn); |
476 | 482 |
477 if (!msg) { | 483 if (!msg) { |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
627 | 633 |
628 room_left = ss->ssl3.mtu; | 634 room_left = ss->ssl3.mtu; |
629 } | 635 } |
630 | 636 |
631 if ((msg->len + SSL3_BUFFER_FUDGE) <= room_left) { | 637 if ((msg->len + SSL3_BUFFER_FUDGE) <= room_left) { |
632 /* The message will fit, so encrypt and then continue with the | 638 /* The message will fit, so encrypt and then continue with the |
633 * next packet */ | 639 * next packet */ |
634 sent = ssl3_SendRecord(ss, msg->epoch, msg->type, | 640 sent = ssl3_SendRecord(ss, msg->epoch, msg->type, |
635 msg->data, msg->len, | 641 msg->data, msg->len, |
636 ssl_SEND_FLAG_FORCE_INTO_BUFFER | | 642 ssl_SEND_FLAG_FORCE_INTO_BUFFER | |
637 ssl_SEND_FLAG_USE_EPOCH); | 643 ssl_SEND_FLAG_USE_EPOCH); |
638 if (sent != msg->len) { | 644 if (sent != msg->len) { |
639 rv = SECFailure; | 645 rv = SECFailure; |
640 if (sent != -1) { | 646 if (sent != -1) { |
641 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); | 647 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
642 } | 648 } |
643 break; | 649 break; |
644 } | 650 } |
645 | 651 |
646 room_left = ss->ssl3.mtu - ss->pendingBuf.len; | 652 room_left = ss->ssl3.mtu - ss->pendingBuf.len; |
647 } else { | 653 } else { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
687 */ | 693 */ |
688 fragment_len = PR_MIN(fragment_len, DTLS_MAX_MTU - 12); | 694 fragment_len = PR_MIN(fragment_len, DTLS_MAX_MTU - 12); |
689 | 695 |
690 /* Construct an appropriate-sized fragment */ | 696 /* Construct an appropriate-sized fragment */ |
691 /* Type, length, sequence */ | 697 /* Type, length, sequence */ |
692 PORT_Memcpy(fragment, msg->data, 6); | 698 PORT_Memcpy(fragment, msg->data, 6); |
693 | 699 |
694 /* Offset */ | 700 /* Offset */ |
695 fragment[6] = (fragment_offset >> 16) & 0xff; | 701 fragment[6] = (fragment_offset >> 16) & 0xff; |
696 fragment[7] = (fragment_offset >> 8) & 0xff; | 702 fragment[7] = (fragment_offset >> 8) & 0xff; |
697 fragment[8] = (fragment_offset) & 0xff; | 703 fragment[8] = (fragment_offset)&0xff; |
698 | 704 |
699 /* Fragment length */ | 705 /* Fragment length */ |
700 fragment[9] = (fragment_len >> 16) & 0xff; | 706 fragment[9] = (fragment_len >> 16) & 0xff; |
701 fragment[10] = (fragment_len >> 8) & 0xff; | 707 fragment[10] = (fragment_len >> 8) & 0xff; |
702 fragment[11] = (fragment_len) & 0xff; | 708 fragment[11] = (fragment_len)&0xff; |
703 | 709 |
704 PORT_Memcpy(fragment + 12, content + fragment_offset, | 710 PORT_Memcpy(fragment + 12, content + fragment_offset, |
705 fragment_len); | 711 fragment_len); |
706 | 712 |
707 /* | 713 /* |
708 * Send the record. We do this in two stages | 714 * Send the record. We do this in two stages |
709 * 1. Encrypt | 715 * 1. Encrypt |
710 */ | 716 */ |
711 sent = ssl3_SendRecord(ss, msg->epoch, msg->type, | 717 sent = ssl3_SendRecord(ss, msg->epoch, msg->type, |
712 fragment, fragment_len + 12, | 718 fragment, fragment_len + 12, |
713 ssl_SEND_FLAG_FORCE_INTO_BUFFER | | 719 ssl_SEND_FLAG_FORCE_INTO_BUFFER | |
714 ssl_SEND_FLAG_USE_EPOCH); | 720 ssl_SEND_FLAG_USE_EPOCH); |
715 if (sent != (fragment_len + 12)) { | 721 if (sent != (fragment_len + 12)) { |
716 rv = SECFailure; | 722 rv = SECFailure; |
717 if (sent != -1) { | 723 if (sent != -1) { |
718 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); | 724 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
719 } | 725 } |
720 break; | 726 break; |
721 } | 727 } |
722 | 728 |
723 /* 2. Flush */ | 729 /* 2. Flush */ |
724 rv = dtls_SendSavedWriteData(ss); | 730 rv = dtls_SendSavedWriteData(ss); |
(...skipping 15 matching lines...) Expand all Loading... |
740 | 746 |
741 return rv; | 747 return rv; |
742 } | 748 } |
743 | 749 |
744 /* Flush the data in the pendingBuf and update the max message sent | 750 /* Flush the data in the pendingBuf and update the max message sent |
745 * so we can adjust the MTU estimate if we need to. | 751 * so we can adjust the MTU estimate if we need to. |
746 * Wrapper for ssl_SendSavedWriteData. | 752 * Wrapper for ssl_SendSavedWriteData. |
747 * | 753 * |
748 * Called from dtls_TransmitMessageFlight() | 754 * Called from dtls_TransmitMessageFlight() |
749 */ | 755 */ |
750 static | 756 static SECStatus |
751 SECStatus dtls_SendSavedWriteData(sslSocket *ss) | 757 dtls_SendSavedWriteData(sslSocket *ss) |
752 { | 758 { |
753 PRInt32 sent; | 759 PRInt32 sent; |
754 | 760 |
755 sent = ssl_SendSavedWriteData(ss); | 761 sent = ssl_SendSavedWriteData(ss); |
756 if (sent < 0) | 762 if (sent < 0) |
757 return SECFailure; | 763 return SECFailure; |
758 | 764 |
759 /* We should always have complete writes b/c datagram sockets | 765 /* We should always have complete writes b/c datagram sockets |
760 * don't really block */ | 766 * don't really block */ |
761 if (ss->pendingBuf.len > 0) { | 767 if (ss->pendingBuf.len > 0) { |
(...skipping 10 matching lines...) Expand all Loading... |
772 } | 778 } |
773 | 779 |
774 /* Compress, MAC, encrypt a DTLS record. Allows specification of | 780 /* Compress, MAC, encrypt a DTLS record. Allows specification of |
775 * the epoch using epoch value. If use_epoch is PR_TRUE then | 781 * the epoch using epoch value. If use_epoch is PR_TRUE then |
776 * we use the provided epoch. If use_epoch is PR_FALSE then | 782 * we use the provided epoch. If use_epoch is PR_FALSE then |
777 * whatever the current value is in effect is used. | 783 * whatever the current value is in effect is used. |
778 * | 784 * |
779 * Called from ssl3_SendRecord() | 785 * Called from ssl3_SendRecord() |
780 */ | 786 */ |
781 SECStatus | 787 SECStatus |
782 dtls_CompressMACEncryptRecord(sslSocket * ss, | 788 dtls_CompressMACEncryptRecord(sslSocket *ss, |
783 DTLSEpoch epoch, | 789 DTLSEpoch epoch, |
784 PRBool use_epoch, | 790 PRBool use_epoch, |
785 SSL3ContentType type, | 791 SSL3ContentType type, |
786 const SSL3Opaque * pIn, | 792 const SSL3Opaque *pIn, |
787 PRUint32 contentLen, | 793 PRUint32 contentLen, |
788 sslBuffer * wrBuf) | 794 sslBuffer *wrBuf) |
789 { | 795 { |
790 SECStatus rv = SECFailure; | 796 SECStatus rv = SECFailure; |
791 ssl3CipherSpec * cwSpec; | 797 ssl3CipherSpec *cwSpec; |
792 | 798 |
793 ssl_GetSpecReadLock(ss); /********************************/ | 799 ssl_GetSpecReadLock(ss); /********************************/ |
794 | 800 |
795 /* The reason for this switch-hitting code is that we might have | 801 /* The reason for this switch-hitting code is that we might have |
796 * a flight of records spanning an epoch boundary, e.g., | 802 * a flight of records spanning an epoch boundary, e.g., |
797 * | 803 * |
798 * ClientKeyExchange (epoch = 0) | 804 * ClientKeyExchange (epoch = 0) |
799 * ChangeCipherSpec (epoch = 0) | 805 * ChangeCipherSpec (epoch = 0) |
800 * Finished (epoch = 1) | 806 * Finished (epoch = 1) |
801 * | 807 * |
802 * Thus, each record needs a different cipher spec. The information | 808 * Thus, each record needs a different cipher spec. The information |
803 * about which epoch to use is carried with the record. | 809 * about which epoch to use is carried with the record. |
804 */ | 810 */ |
805 if (use_epoch) { | 811 if (use_epoch) { |
806 if (ss->ssl3.cwSpec->epoch == epoch) | 812 if (ss->ssl3.cwSpec->epoch == epoch) |
807 cwSpec = ss->ssl3.cwSpec; | 813 cwSpec = ss->ssl3.cwSpec; |
808 else if (ss->ssl3.pwSpec->epoch == epoch) | 814 else if (ss->ssl3.pwSpec->epoch == epoch) |
809 cwSpec = ss->ssl3.pwSpec; | 815 cwSpec = ss->ssl3.pwSpec; |
810 else | 816 else |
811 cwSpec = NULL; | 817 cwSpec = NULL; |
812 } else { | 818 } else { |
813 cwSpec = ss->ssl3.cwSpec; | 819 cwSpec = ss->ssl3.cwSpec; |
814 } | 820 } |
815 | 821 |
816 if (cwSpec) { | 822 if (cwSpec) { |
817 rv = ssl3_CompressMACEncryptRecord(cwSpec, ss->sec.isServer, PR_TRUE, | 823 if (ss->ssl3.cwSpec->version < SSL_LIBRARY_VERSION_TLS_1_3) { |
818 PR_FALSE, type, pIn, contentLen, | 824 rv = ssl3_CompressMACEncryptRecord(cwSpec, ss->sec.isServer, PR_TRUE
, |
819 wrBuf); | 825 PR_FALSE, type, pIn, contentLen, |
| 826 wrBuf); |
| 827 } else { |
| 828 rv = tls13_ProtectRecord(ss, type, pIn, contentLen, wrBuf); |
| 829 } |
820 } else { | 830 } else { |
821 PR_NOT_REACHED("Couldn't find a cipher spec matching epoch"); | 831 PR_NOT_REACHED("Couldn't find a cipher spec matching epoch"); |
822 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); | 832 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
823 } | 833 } |
824 ssl_ReleaseSpecReadLock(ss); /************************************/ | 834 ssl_ReleaseSpecReadLock(ss); /************************************/ |
825 | 835 |
826 return rv; | 836 return rv; |
827 } | 837 } |
828 | 838 |
829 /* Start a timer | 839 /* Start a timer |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
949 | 959 |
950 for (i = 0; i < PR_ARRAY_SIZE(COMMON_MTU_VALUES); i++) { | 960 for (i = 0; i < PR_ARRAY_SIZE(COMMON_MTU_VALUES); i++) { |
951 if (COMMON_MTU_VALUES[i] <= advertised) { | 961 if (COMMON_MTU_VALUES[i] <= advertised) { |
952 ss->ssl3.mtu = COMMON_MTU_VALUES[i]; | 962 ss->ssl3.mtu = COMMON_MTU_VALUES[i]; |
953 SSL_TRC(30, ("Resetting MTU to %d", ss->ssl3.mtu)); | 963 SSL_TRC(30, ("Resetting MTU to %d", ss->ssl3.mtu)); |
954 return; | 964 return; |
955 } | 965 } |
956 } | 966 } |
957 | 967 |
958 /* Fallback */ | 968 /* Fallback */ |
959 ss->ssl3.mtu = COMMON_MTU_VALUES[PR_ARRAY_SIZE(COMMON_MTU_VALUES)-1]; | 969 ss->ssl3.mtu = COMMON_MTU_VALUES[PR_ARRAY_SIZE(COMMON_MTU_VALUES) - 1]; |
960 SSL_TRC(30, ("Resetting MTU to %d", ss->ssl3.mtu)); | 970 SSL_TRC(30, ("Resetting MTU to %d", ss->ssl3.mtu)); |
961 } | 971 } |
962 | 972 |
963 /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a | 973 /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a |
964 * DTLS hello_verify_request | 974 * DTLS hello_verify_request |
965 * Caller must hold Handshake and RecvBuf locks. | 975 * Caller must hold Handshake and RecvBuf locks. |
966 */ | 976 */ |
967 SECStatus | 977 SECStatus |
968 dtls_HandleHelloVerifyRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length) | 978 dtls_HandleHelloVerifyRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length) |
969 { | 979 { |
970 int errCode = SSL_ERROR_RX_MALFORMED_HELLO_VERIFY_REQUEST; | 980 int errCode = SSL_ERROR_RX_MALFORMED_HELLO_VERIFY_REQUEST; |
971 SECStatus rv; | 981 SECStatus rv; |
972 PRInt32 temp; | 982 PRInt32 temp; |
973 SECItem cookie = {siBuffer, NULL, 0}; | 983 SECItem cookie = { siBuffer, NULL, 0 }; |
974 SSL3AlertDescription desc = illegal_parameter; | 984 SSL3AlertDescription desc = illegal_parameter; |
975 | 985 |
976 SSL_TRC(3, ("%d: SSL3[%d]: handle hello_verify_request handshake", | 986 SSL_TRC(3, ("%d: SSL3[%d]: handle hello_verify_request handshake", |
977 SSL_GETPID(), ss->fd)); | 987 SSL_GETPID(), ss->fd)); |
978 PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); | 988 PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); |
979 PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); | 989 PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); |
980 | 990 |
981 if (ss->ssl3.hs.ws != wait_server_hello) { | 991 if (ss->ssl3.hs.ws != wait_server_hello) { |
982 errCode = SSL_ERROR_RX_UNEXPECTED_HELLO_VERIFY_REQUEST; | 992 errCode = SSL_ERROR_RX_UNEXPECTED_HELLO_VERIFY_REQUEST; |
983 desc = unexpected_message; | 993 desc = unexpected_message; |
984 goto alert_loser; | 994 goto alert_loser; |
985 } | 995 } |
986 | 996 |
987 /* The version */ | 997 /* The version */ |
988 temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length); | 998 temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length); |
989 if (temp < 0) { | 999 if (temp < 0) { |
990 goto loser; /* alert has been sent */ | 1000 goto loser; /* alert has been sent */ |
991 } | 1001 } |
992 | 1002 |
993 if (temp != SSL_LIBRARY_VERSION_DTLS_1_0_WIRE && | 1003 if (temp != SSL_LIBRARY_VERSION_DTLS_1_0_WIRE && |
994 temp != SSL_LIBRARY_VERSION_DTLS_1_2_WIRE) { | 1004 temp != SSL_LIBRARY_VERSION_DTLS_1_2_WIRE) { |
995 goto alert_loser; | 1005 goto alert_loser; |
996 } | 1006 } |
997 | 1007 |
998 /* The cookie */ | 1008 /* The cookie */ |
999 rv = ssl3_ConsumeHandshakeVariable(ss, &cookie, 1, &b, &length); | 1009 rv = ssl3_ConsumeHandshakeVariable(ss, &cookie, 1, &b, &length); |
1000 if (rv != SECSuccess) { | 1010 if (rv != SECSuccess) { |
1001 goto loser; /* alert has been sent */ | 1011 goto loser; /* alert has been sent */ |
1002 } | 1012 } |
1003 if (cookie.len > DTLS_COOKIE_BYTES) { | 1013 if (cookie.len > DTLS_COOKIE_BYTES) { |
1004 desc = decode_error; | 1014 desc = decode_error; |
1005 goto alert_loser; /* malformed. */ | 1015 goto alert_loser; /* malformed. */ |
1006 } | 1016 } |
1007 | 1017 |
1008 PORT_Memcpy(ss->ssl3.hs.cookie, cookie.data, cookie.len); | 1018 PORT_Memcpy(ss->ssl3.hs.cookie, cookie.data, cookie.len); |
1009 ss->ssl3.hs.cookieLen = cookie.len; | 1019 ss->ssl3.hs.cookieLen = cookie.len; |
1010 | 1020 |
1011 | 1021 ssl_GetXmitBufLock(ss); /*******************************/ |
1012 ssl_GetXmitBufLock(ss); /*******************************/ | |
1013 | 1022 |
1014 /* Now re-send the client hello */ | 1023 /* Now re-send the client hello */ |
1015 rv = ssl3_SendClientHello(ss, PR_TRUE); | 1024 rv = ssl3_SendClientHello(ss, PR_TRUE); |
1016 | 1025 |
1017 ssl_ReleaseXmitBufLock(ss); /*******************************/ | 1026 ssl_ReleaseXmitBufLock(ss); /*******************************/ |
1018 | 1027 |
1019 if (rv == SECSuccess) | 1028 if (rv == SECSuccess) |
1020 return rv; | 1029 return rv; |
1021 | 1030 |
1022 alert_loser: | 1031 alert_loser: |
1023 (void)SSL3_SendAlert(ss, alert_fatal, desc); | 1032 (void)SSL3_SendAlert(ss, alert_fatal, desc); |
1024 | 1033 |
1025 loser: | 1034 loser: |
1026 errCode = ssl_MapLowLevelError(errCode); | 1035 ssl_MapLowLevelError(errCode); |
1027 return SECFailure; | 1036 return SECFailure; |
1028 } | 1037 } |
1029 | 1038 |
1030 /* Initialize the DTLS anti-replay window | 1039 /* Initialize the DTLS anti-replay window |
1031 * | 1040 * |
1032 * Called from: | 1041 * Called from: |
1033 * ssl3_SetupPendingCipherSpec() | 1042 * ssl3_SetupPendingCipherSpec() |
1034 * ssl3_InitCipherSpec() | 1043 * ssl3_InitCipherSpec() |
1035 */ | 1044 */ |
1036 void | 1045 void |
1037 dtls_InitRecvdRecords(DTLSRecvdRecords *records) | 1046 dtls_InitRecvdRecords(DTLSRecvdRecords *records) |
1038 { | 1047 { |
1039 PORT_Memset(records->data, 0, sizeof(records->data)); | 1048 PORT_Memset(records->data, 0, sizeof(records->data)); |
1040 records->left = 0; | 1049 records->left = 0; |
1041 records->right = DTLS_RECVD_RECORDS_WINDOW - 1; | 1050 records->right = DTLS_RECVD_RECORDS_WINDOW - 1; |
1042 } | 1051 } |
1043 | 1052 |
1044 /* | 1053 /* |
1045 * Has this DTLS record been received? Return values are: | 1054 * Has this DTLS record been received? Return values are: |
1046 * -1 -- out of range to the left | 1055 * -1 -- out of range to the left |
1047 * 0 -- not received yet | 1056 * 0 -- not received yet |
1048 * 1 -- replay | 1057 * 1 -- replay |
1049 * | 1058 * |
1050 * Called from: dtls_HandleRecord() | 1059 * Called from: ssl3_HandleRecord() |
1051 */ | 1060 */ |
1052 int | 1061 int |
1053 dtls_RecordGetRecvd(DTLSRecvdRecords *records, PRUint64 seq) | 1062 dtls_RecordGetRecvd(const DTLSRecvdRecords *records, PRUint64 seq) |
1054 { | 1063 { |
1055 PRUint64 offset; | 1064 PRUint64 offset; |
1056 | 1065 |
1057 /* Out of range to the left */ | 1066 /* Out of range to the left */ |
1058 if (seq < records->left) { | 1067 if (seq < records->left) { |
1059 return -1; | 1068 return -1; |
1060 } | 1069 } |
1061 | 1070 |
1062 /* Out of range to the right; since we advance the window on | 1071 /* Out of range to the right; since we advance the window on |
1063 * receipt, that means that this packet has not been received | 1072 * receipt, that means that this packet has not been received |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1111 } | 1120 } |
1112 | 1121 |
1113 offset = seq % DTLS_RECVD_RECORDS_WINDOW; | 1122 offset = seq % DTLS_RECVD_RECORDS_WINDOW; |
1114 | 1123 |
1115 records->data[offset / 8] |= (1 << (offset % 8)); | 1124 records->data[offset / 8] |= (1 << (offset % 8)); |
1116 } | 1125 } |
1117 | 1126 |
1118 SECStatus | 1127 SECStatus |
1119 DTLS_GetHandshakeTimeout(PRFileDesc *socket, PRIntervalTime *timeout) | 1128 DTLS_GetHandshakeTimeout(PRFileDesc *socket, PRIntervalTime *timeout) |
1120 { | 1129 { |
1121 sslSocket * ss = NULL; | 1130 sslSocket *ss = NULL; |
1122 PRIntervalTime elapsed; | 1131 PRIntervalTime elapsed; |
1123 PRIntervalTime desired; | 1132 PRIntervalTime desired; |
1124 | 1133 |
1125 ss = ssl_FindSocket(socket); | 1134 ss = ssl_FindSocket(socket); |
1126 | 1135 |
1127 if (!ss) | 1136 if (!ss) |
1128 return SECFailure; | 1137 return SECFailure; |
1129 | 1138 |
1130 if (!IS_DTLS(ss)) | 1139 if (!IS_DTLS(ss)) |
1131 return SECFailure; | 1140 return SECFailure; |
1132 | 1141 |
1133 if (!ss->ssl3.hs.rtTimerCb) | 1142 if (!ss->ssl3.hs.rtTimerCb) |
1134 return SECFailure; | 1143 return SECFailure; |
1135 | 1144 |
1136 elapsed = PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted; | 1145 elapsed = PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted; |
1137 desired = PR_MillisecondsToInterval(ss->ssl3.hs.rtTimeoutMs); | 1146 desired = PR_MillisecondsToInterval(ss->ssl3.hs.rtTimeoutMs); |
1138 if (elapsed > desired) { | 1147 if (elapsed > desired) { |
1139 /* Timer expired */ | 1148 /* Timer expired */ |
1140 *timeout = PR_INTERVAL_NO_WAIT; | 1149 *timeout = PR_INTERVAL_NO_WAIT; |
1141 } else { | 1150 } else { |
1142 *timeout = desired - elapsed; | 1151 *timeout = desired - elapsed; |
1143 } | 1152 } |
1144 | 1153 |
1145 return SECSuccess; | 1154 return SECSuccess; |
1146 } | 1155 } |
| 1156 |
| 1157 /* |
| 1158 * DTLS relevance checks: |
| 1159 * Note that this code currently ignores all out-of-epoch packets, |
| 1160 * which means we lose some in the case of rehandshake + |
| 1161 * loss/reordering. Since DTLS is explicitly unreliable, this |
| 1162 * seems like a good tradeoff for implementation effort and is |
| 1163 * consistent with the guidance of RFC 6347 Sections 4.1 and 4.2.4.1. |
| 1164 * |
| 1165 * If the packet is not relevant, this function returns PR_FALSE. |
| 1166 * If the packet is relevant, this function returns PR_TRUE |
| 1167 * and sets |*seqNum| to the packet sequence number. |
| 1168 */ |
| 1169 PRBool |
| 1170 dtls_IsRelevant(sslSocket *ss, const ssl3CipherSpec *crSpec, |
| 1171 const SSL3Ciphertext *cText, PRUint64 *seqNum) |
| 1172 { |
| 1173 DTLSEpoch epoch = cText->seq_num.high >> 16; |
| 1174 PRUint64 dtls_seq_num; |
| 1175 |
| 1176 if (crSpec->epoch != epoch) { |
| 1177 SSL_DBG(("%d: SSL3[%d]: dtls_IsRelevant, received packet " |
| 1178 "from irrelevant epoch %d", |
| 1179 SSL_GETPID(), ss->fd, epoch)); |
| 1180 return PR_FALSE; |
| 1181 } |
| 1182 |
| 1183 dtls_seq_num = (((PRUint64)(cText->seq_num.high & 0xffff)) << 32) | |
| 1184 ((PRUint64)cText->seq_num.low); |
| 1185 |
| 1186 if (dtls_RecordGetRecvd(&crSpec->recvdRecords, dtls_seq_num) != 0) { |
| 1187 SSL_DBG(("%d: SSL3[%d]: dtls_IsRelevant, rejecting " |
| 1188 "potentially replayed packet", |
| 1189 SSL_GETPID(), ss->fd)); |
| 1190 return PR_FALSE; |
| 1191 } |
| 1192 |
| 1193 *seqNum = dtls_seq_num; |
| 1194 return PR_TRUE; |
| 1195 } |
OLD | NEW |