| 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 |