| OLD | NEW |
| (Empty) |
| 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 | |
| 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
| 4 | |
| 5 /* | |
| 6 * DTLS Protocol | |
| 7 */ | |
| 8 | |
| 9 #include "ssl.h" | |
| 10 #include "sslimpl.h" | |
| 11 #include "sslproto.h" | |
| 12 | |
| 13 #ifndef PR_ARRAY_SIZE | |
| 14 #define PR_ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) | |
| 15 #endif | |
| 16 | |
| 17 static SECStatus dtls_TransmitMessageFlight(sslSocket *ss); | |
| 18 static void dtls_RetransmitTimerExpiredCb(sslSocket *ss); | |
| 19 static SECStatus dtls_SendSavedWriteData(sslSocket *ss); | |
| 20 | |
| 21 /* -28 adjusts for the IP/UDP header */ | |
| 22 static const PRUint16 COMMON_MTU_VALUES[] = { | |
| 23 1500 - 28, /* Ethernet MTU */ | |
| 24 1280 - 28, /* IPv6 minimum MTU */ | |
| 25 576 - 28, /* Common assumption */ | |
| 26 256 - 28 /* We're in serious trouble now */ | |
| 27 }; | |
| 28 | |
| 29 #define DTLS_COOKIE_BYTES 32 | |
| 30 | |
| 31 /* List copied from ssl3con.c:cipherSuites */ | |
| 32 static const ssl3CipherSuite nonDTLSSuites[] = { | |
| 33 #ifndef NSS_DISABLE_ECC | |
| 34 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, | |
| 35 TLS_ECDHE_RSA_WITH_RC4_128_SHA, | |
| 36 #endif /* NSS_DISABLE_ECC */ | |
| 37 TLS_DHE_DSS_WITH_RC4_128_SHA, | |
| 38 #ifndef NSS_DISABLE_ECC | |
| 39 TLS_ECDH_RSA_WITH_RC4_128_SHA, | |
| 40 TLS_ECDH_ECDSA_WITH_RC4_128_SHA, | |
| 41 #endif /* NSS_DISABLE_ECC */ | |
| 42 TLS_RSA_WITH_RC4_128_MD5, | |
| 43 TLS_RSA_WITH_RC4_128_SHA, | |
| 44 TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, | |
| 45 TLS_RSA_EXPORT_WITH_RC4_40_MD5, | |
| 46 0 /* End of list marker */ | |
| 47 }; | |
| 48 | |
| 49 /* Map back and forth between TLS and DTLS versions in wire format. | |
| 50 * Mapping table is: | |
| 51 * | |
| 52 * TLS DTLS | |
| 53 * 1.1 (0302) 1.0 (feff) | |
| 54 * 1.2 (0303) 1.2 (fefd) | |
| 55 * 1.3 (0304) 1.3 (fefc) | |
| 56 */ | |
| 57 SSL3ProtocolVersion | |
| 58 dtls_TLSVersionToDTLSVersion(SSL3ProtocolVersion tlsv) | |
| 59 { | |
| 60 if (tlsv == SSL_LIBRARY_VERSION_TLS_1_1) { | |
| 61 return SSL_LIBRARY_VERSION_DTLS_1_0_WIRE; | |
| 62 } | |
| 63 if (tlsv == SSL_LIBRARY_VERSION_TLS_1_2) { | |
| 64 return SSL_LIBRARY_VERSION_DTLS_1_2_WIRE; | |
| 65 } | |
| 66 if (tlsv == SSL_LIBRARY_VERSION_TLS_1_3) { | |
| 67 return SSL_LIBRARY_VERSION_DTLS_1_3_WIRE; | |
| 68 } | |
| 69 | |
| 70 /* Anything other than TLS 1.1 or 1.2 is an error, so return | |
| 71 * the invalid version 0xffff. */ | |
| 72 return 0xffff; | |
| 73 } | |
| 74 | |
| 75 /* Map known DTLS versions to known TLS versions. | |
| 76 * - Invalid versions (< 1.0) return a version of 0 | |
| 77 * - Versions > known return a version one higher than we know of | |
| 78 * to accomodate a theoretically newer version */ | |
| 79 SSL3ProtocolVersion | |
| 80 dtls_DTLSVersionToTLSVersion(SSL3ProtocolVersion dtlsv) | |
| 81 { | |
| 82 if (MSB(dtlsv) == 0xff) { | |
| 83 return 0; | |
| 84 } | |
| 85 | |
| 86 if (dtlsv == SSL_LIBRARY_VERSION_DTLS_1_0_WIRE) { | |
| 87 return SSL_LIBRARY_VERSION_TLS_1_1; | |
| 88 } | |
| 89 /* Handle the skipped version of DTLS 1.1 by returning | |
| 90 * an error. */ | |
| 91 if (dtlsv == ((~0x0101) & 0xffff)) { | |
| 92 return 0; | |
| 93 } | |
| 94 if (dtlsv == SSL_LIBRARY_VERSION_DTLS_1_2_WIRE) { | |
| 95 return SSL_LIBRARY_VERSION_TLS_1_2; | |
| 96 } | |
| 97 if (dtlsv == SSL_LIBRARY_VERSION_DTLS_1_3_WIRE) { | |
| 98 return SSL_LIBRARY_VERSION_TLS_1_3; | |
| 99 } | |
| 100 | |
| 101 /* Return a fictional higher version than we know of */ | |
| 102 return SSL_LIBRARY_VERSION_MAX_SUPPORTED + 1; | |
| 103 } | |
| 104 | |
| 105 /* On this socket, Disable non-DTLS cipher suites in the argument's list */ | |
| 106 SECStatus | |
| 107 ssl3_DisableNonDTLSSuites(sslSocket *ss) | |
| 108 { | |
| 109 const ssl3CipherSuite *suite; | |
| 110 | |
| 111 for (suite = nonDTLSSuites; *suite; ++suite) { | |
| 112 PORT_CheckSuccess(ssl3_CipherPrefSet(ss, *suite, PR_FALSE)); | |
| 113 } | |
| 114 return SECSuccess; | |
| 115 } | |
| 116 | |
| 117 /* Allocate a DTLSQueuedMessage. | |
| 118 * | |
| 119 * Called from dtls_QueueMessage() | |
| 120 */ | |
| 121 static DTLSQueuedMessage * | |
| 122 dtls_AllocQueuedMessage(PRUint16 epoch, SSL3ContentType type, | |
| 123 const unsigned char *data, PRUint32 len) | |
| 124 { | |
| 125 DTLSQueuedMessage *msg = NULL; | |
| 126 | |
| 127 msg = PORT_ZAlloc(sizeof(DTLSQueuedMessage)); | |
| 128 if (!msg) | |
| 129 return NULL; | |
| 130 | |
| 131 msg->data = PORT_Alloc(len); | |
| 132 if (!msg->data) { | |
| 133 PORT_Free(msg); | |
| 134 return NULL; | |
| 135 } | |
| 136 PORT_Memcpy(msg->data, data, len); | |
| 137 | |
| 138 msg->len = len; | |
| 139 msg->epoch = epoch; | |
| 140 msg->type = type; | |
| 141 | |
| 142 return msg; | |
| 143 } | |
| 144 | |
| 145 /* | |
| 146 * Free a handshake message | |
| 147 * | |
| 148 * Called from dtls_FreeHandshakeMessages() | |
| 149 */ | |
| 150 static void | |
| 151 dtls_FreeHandshakeMessage(DTLSQueuedMessage *msg) | |
| 152 { | |
| 153 if (!msg) | |
| 154 return; | |
| 155 | |
| 156 PORT_ZFree(msg->data, msg->len); | |
| 157 PORT_Free(msg); | |
| 158 } | |
| 159 | |
| 160 /* | |
| 161 * Free a list of handshake messages | |
| 162 * | |
| 163 * Called from: | |
| 164 * dtls_HandleHandshake() | |
| 165 * ssl3_DestroySSL3Info() | |
| 166 */ | |
| 167 void | |
| 168 dtls_FreeHandshakeMessages(PRCList *list) | |
| 169 { | |
| 170 PRCList *cur_p; | |
| 171 | |
| 172 while (!PR_CLIST_IS_EMPTY(list)) { | |
| 173 cur_p = PR_LIST_TAIL(list); | |
| 174 PR_REMOVE_LINK(cur_p); | |
| 175 dtls_FreeHandshakeMessage((DTLSQueuedMessage *)cur_p); | |
| 176 } | |
| 177 } | |
| 178 | |
| 179 /* Called only from ssl3_HandleRecord, for each (deciphered) DTLS record. | |
| 180 * origBuf is the decrypted ssl record content and is expected to contain | |
| 181 * complete handshake records | |
| 182 * Caller must hold the handshake and RecvBuf locks. | |
| 183 * | |
| 184 * Note that this code uses msg_len for two purposes: | |
| 185 * | |
| 186 * (1) To pass the length to ssl3_HandleHandshakeMessage() | |
| 187 * (2) To carry the length of a message currently being reassembled | |
| 188 * | |
| 189 * However, unlike ssl3_HandleHandshake(), it is not used to carry | |
| 190 * the state of reassembly (i.e., whether one is in progress). That | |
| 191 * is carried in recvdHighWater and recvdFragments. | |
| 192 */ | |
| 193 #define OFFSET_BYTE(o) (o / 8) | |
| 194 #define OFFSET_MASK(o) (1 << (o % 8)) | |
| 195 | |
| 196 SECStatus | |
| 197 dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf) | |
| 198 { | |
| 199 /* XXX OK for now. | |
| 200 * This doesn't work properly with asynchronous certificate validation. | |
| 201 * because that returns a WOULDBLOCK error. The current DTLS | |
| 202 * applications do not need asynchronous validation, but in the | |
| 203 * future we will need to add this. | |
| 204 */ | |
| 205 sslBuffer buf = *origBuf; | |
| 206 SECStatus rv = SECSuccess; | |
| 207 | |
| 208 PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); | |
| 209 PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); | |
| 210 | |
| 211 while (buf.len > 0) { | |
| 212 PRUint8 type; | |
| 213 PRUint32 message_length; | |
| 214 PRUint16 message_seq; | |
| 215 PRUint32 fragment_offset; | |
| 216 PRUint32 fragment_length; | |
| 217 PRUint32 offset; | |
| 218 | |
| 219 if (buf.len < 12) { | |
| 220 PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE); | |
| 221 rv = SECFailure; | |
| 222 break; | |
| 223 } | |
| 224 | |
| 225 /* Parse the header */ | |
| 226 type = buf.buf[0]; | |
| 227 message_length = (buf.buf[1] << 16) | (buf.buf[2] << 8) | buf.buf[3]; | |
| 228 message_seq = (buf.buf[4] << 8) | buf.buf[5]; | |
| 229 fragment_offset = (buf.buf[6] << 16) | (buf.buf[7] << 8) | buf.buf[8]; | |
| 230 fragment_length = (buf.buf[9] << 16) | (buf.buf[10] << 8) | buf.buf[11]; | |
| 231 | |
| 232 #define MAX_HANDSHAKE_MSG_LEN 0x1ffff /* 128k - 1 */ | |
| 233 if (message_length > MAX_HANDSHAKE_MSG_LEN) { | |
| 234 (void)ssl3_DecodeError(ss); | |
| 235 PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE); | |
| 236 return SECFailure; | |
| 237 } | |
| 238 #undef MAX_HANDSHAKE_MSG_LEN | |
| 239 | |
| 240 buf.buf += 12; | |
| 241 buf.len -= 12; | |
| 242 | |
| 243 /* This fragment must be complete */ | |
| 244 if (buf.len < fragment_length) { | |
| 245 PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE); | |
| 246 rv = SECFailure; | |
| 247 break; | |
| 248 } | |
| 249 | |
| 250 /* Sanity check the packet contents */ | |
| 251 if ((fragment_length + fragment_offset) > message_length) { | |
| 252 PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE); | |
| 253 rv = SECFailure; | |
| 254 break; | |
| 255 } | |
| 256 | |
| 257 /* There are three ways we could not be ready for this packet. | |
| 258 * | |
| 259 * 1. It's a partial next message. | |
| 260 * 2. It's a partial or complete message beyond the next | |
| 261 * 3. It's a message we've already seen | |
| 262 * | |
| 263 * If it's the complete next message we accept it right away. | |
| 264 * This is the common case for short messages | |
| 265 */ | |
| 266 if ((message_seq == ss->ssl3.hs.recvMessageSeq) && | |
| 267 (fragment_offset == 0) && | |
| 268 (fragment_length == message_length)) { | |
| 269 /* Complete next message. Process immediately */ | |
| 270 ss->ssl3.hs.msg_type = (SSL3HandshakeType)type; | |
| 271 ss->ssl3.hs.msg_len = message_length; | |
| 272 | |
| 273 /* At this point we are advancing our state machine, so | |
| 274 * we can free our last flight of messages */ | |
| 275 dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight); | |
| 276 ss->ssl3.hs.recvdHighWater = -1; | |
| 277 dtls_CancelTimer(ss); | |
| 278 | |
| 279 /* Reset the timer to the initial value if the retry counter | |
| 280 * is 0, per Sec. 4.2.4.1 */ | |
| 281 if (ss->ssl3.hs.rtRetries == 0) { | |
| 282 ss->ssl3.hs.rtTimeoutMs = INITIAL_DTLS_TIMEOUT_MS; | |
| 283 } | |
| 284 | |
| 285 rv = ssl3_HandleHandshakeMessage(ss, buf.buf, ss->ssl3.hs.msg_len); | |
| 286 if (rv == SECFailure) { | |
| 287 /* Do not attempt to process rest of messages in this record */ | |
| 288 break; | |
| 289 } | |
| 290 } else { | |
| 291 if (message_seq < ss->ssl3.hs.recvMessageSeq) { | |
| 292 /* Case 3: we do an immediate retransmit if we're | |
| 293 * in a waiting state*/ | |
| 294 if (ss->ssl3.hs.rtTimerCb == NULL) { | |
| 295 /* Ignore */ | |
| 296 } else if (ss->ssl3.hs.rtTimerCb == | |
| 297 dtls_RetransmitTimerExpiredCb) { | |
| 298 SSL_TRC(30, ("%d: SSL3[%d]: Retransmit detected", | |
| 299 SSL_GETPID(), ss->fd)); | |
| 300 /* Check to see if we retransmitted recently. If so, | |
| 301 * suppress the triggered retransmit. This avoids | |
| 302 * retransmit wars after packet loss. | |
| 303 * This is not in RFC 5346 but should be | |
| 304 */ | |
| 305 if ((PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted) > | |
| 306 (ss->ssl3.hs.rtTimeoutMs / 4)) { | |
| 307 SSL_TRC(30, | |
| 308 ("%d: SSL3[%d]: Shortcutting retransmit timer", | |
| 309 SSL_GETPID(), ss->fd)); | |
| 310 | |
| 311 /* Cancel the timer and call the CB, | |
| 312 * which re-arms the timer */ | |
| 313 dtls_CancelTimer(ss); | |
| 314 dtls_RetransmitTimerExpiredCb(ss); | |
| 315 rv = SECSuccess; | |
| 316 break; | |
| 317 } else { | |
| 318 SSL_TRC(30, | |
| 319 ("%d: SSL3[%d]: We just retransmitted. Ignoring.
", | |
| 320 SSL_GETPID(), ss->fd)); | |
| 321 rv = SECSuccess; | |
| 322 break; | |
| 323 } | |
| 324 } else if (ss->ssl3.hs.rtTimerCb == dtls_FinishedTimerCb) { | |
| 325 /* Retransmit the messages and re-arm the timer | |
| 326 * Note that we are not backing off the timer here. | |
| 327 * The spec isn't clear and my reasoning is that this | |
| 328 * may be a re-ordered packet rather than slowness, | |
| 329 * so let's be aggressive. */ | |
| 330 dtls_CancelTimer(ss); | |
| 331 rv = dtls_TransmitMessageFlight(ss); | |
| 332 if (rv == SECSuccess) { | |
| 333 rv = dtls_StartTimer(ss, dtls_FinishedTimerCb); | |
| 334 } | |
| 335 if (rv != SECSuccess) | |
| 336 return rv; | |
| 337 break; | |
| 338 } | |
| 339 } else if (message_seq > ss->ssl3.hs.recvMessageSeq) { | |
| 340 /* Case 2 | |
| 341 * | |
| 342 * Ignore this message. This means we don't handle out of | |
| 343 * order complete messages that well, but we're still | |
| 344 * compliant and this probably does not happen often | |
| 345 * | |
| 346 * XXX OK for now. Maybe do something smarter at some point? | |
| 347 */ | |
| 348 } else { | |
| 349 /* Case 1 | |
| 350 * | |
| 351 * Buffer the fragment for reassembly | |
| 352 */ | |
| 353 /* Make room for the message */ | |
| 354 if (ss->ssl3.hs.recvdHighWater == -1) { | |
| 355 PRUint32 map_length = OFFSET_BYTE(message_length) + 1; | |
| 356 | |
| 357 rv = sslBuffer_Grow(&ss->ssl3.hs.msg_body, message_length); | |
| 358 if (rv != SECSuccess) | |
| 359 break; | |
| 360 /* Make room for the fragment map */ | |
| 361 rv = sslBuffer_Grow(&ss->ssl3.hs.recvdFragments, | |
| 362 map_length); | |
| 363 if (rv != SECSuccess) | |
| 364 break; | |
| 365 | |
| 366 /* Reset the reassembly map */ | |
| 367 ss->ssl3.hs.recvdHighWater = 0; | |
| 368 PORT_Memset(ss->ssl3.hs.recvdFragments.buf, 0, | |
| 369 ss->ssl3.hs.recvdFragments.space); | |
| 370 ss->ssl3.hs.msg_type = (SSL3HandshakeType)type; | |
| 371 ss->ssl3.hs.msg_len = message_length; | |
| 372 } | |
| 373 | |
| 374 /* If we have a message length mismatch, abandon the reassembly | |
| 375 * in progress and hope that the next retransmit will give us | |
| 376 * something sane | |
| 377 */ | |
| 378 if (message_length != ss->ssl3.hs.msg_len) { | |
| 379 ss->ssl3.hs.recvdHighWater = -1; | |
| 380 PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE); | |
| 381 rv = SECFailure; | |
| 382 break; | |
| 383 } | |
| 384 | |
| 385 /* Now copy this fragment into the buffer */ | |
| 386 PORT_Assert((fragment_offset + fragment_length) <= | |
| 387 ss->ssl3.hs.msg_body.space); | |
| 388 PORT_Memcpy(ss->ssl3.hs.msg_body.buf + fragment_offset, | |
| 389 buf.buf, fragment_length); | |
| 390 | |
| 391 /* This logic is a bit tricky. We have two values for | |
| 392 * reassembly state: | |
| 393 * | |
| 394 * - recvdHighWater contains the highest contiguous number of | |
| 395 * bytes received | |
| 396 * - recvdFragments contains a bitmask of packets received | |
| 397 * above recvdHighWater | |
| 398 * | |
| 399 * This avoids having to fill in the bitmask in the common | |
| 400 * case of adjacent fragments received in sequence | |
| 401 */ | |
| 402 if (fragment_offset <= (unsigned int)ss->ssl3.hs.recvdHighWater)
{ | |
| 403 /* Either this is the adjacent fragment or an overlapping | |
| 404 * fragment */ | |
| 405 ss->ssl3.hs.recvdHighWater = fragment_offset + | |
| 406 fragment_length; | |
| 407 } else { | |
| 408 for (offset = fragment_offset; | |
| 409 offset < fragment_offset + fragment_length; | |
| 410 offset++) { | |
| 411 ss->ssl3.hs.recvdFragments.buf[OFFSET_BYTE(offset)] |= | |
| 412 OFFSET_MASK(offset); | |
| 413 } | |
| 414 } | |
| 415 | |
| 416 /* Now figure out the new high water mark if appropriate */ | |
| 417 for (offset = ss->ssl3.hs.recvdHighWater; | |
| 418 offset < ss->ssl3.hs.msg_len; offset++) { | |
| 419 /* Note that this loop is not efficient, since it counts | |
| 420 * bit by bit. If we have a lot of out-of-order packets, | |
| 421 * we should optimize this */ | |
| 422 if (ss->ssl3.hs.recvdFragments.buf[OFFSET_BYTE(offset)] & | |
| 423 OFFSET_MASK(offset)) { | |
| 424 ss->ssl3.hs.recvdHighWater++; | |
| 425 } else { | |
| 426 break; | |
| 427 } | |
| 428 } | |
| 429 | |
| 430 /* If we have all the bytes, then we are good to go */ | |
| 431 if (ss->ssl3.hs.recvdHighWater == ss->ssl3.hs.msg_len) { | |
| 432 ss->ssl3.hs.recvdHighWater = -1; | |
| 433 | |
| 434 rv = ssl3_HandleHandshakeMessage(ss, | |
| 435 ss->ssl3.hs.msg_body.buf, | |
| 436 ss->ssl3.hs.msg_len); | |
| 437 if (rv == SECFailure) | |
| 438 break; /* Skip rest of record */ | |
| 439 | |
| 440 /* At this point we are advancing our state machine, so | |
| 441 * we can free our last flight of messages */ | |
| 442 dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight); | |
| 443 dtls_CancelTimer(ss); | |
| 444 | |
| 445 /* If there have been no retries this time, reset the | |
| 446 * timer value to the default per Section 4.2.4.1 */ | |
| 447 if (ss->ssl3.hs.rtRetries == 0) { | |
| 448 ss->ssl3.hs.rtTimeoutMs = INITIAL_DTLS_TIMEOUT_MS; | |
| 449 } | |
| 450 } | |
| 451 } | |
| 452 } | |
| 453 | |
| 454 buf.buf += fragment_length; | |
| 455 buf.len -= fragment_length; | |
| 456 } | |
| 457 | |
| 458 origBuf->len = 0; /* So ssl3_GatherAppDataRecord will keep looping. */ | |
| 459 | |
| 460 /* XXX OK for now. In future handle rv == SECWouldBlock safely in order | |
| 461 * to deal with asynchronous certificate verification */ | |
| 462 return rv; | |
| 463 } | |
| 464 | |
| 465 /* Enqueue a message (either handshake or CCS) | |
| 466 * | |
| 467 * Called from: | |
| 468 * dtls_StageHandshakeMessage() | |
| 469 * ssl3_SendChangeCipherSpecs() | |
| 470 */ | |
| 471 SECStatus | |
| 472 dtls_QueueMessage(sslSocket *ss, SSL3ContentType type, | |
| 473 const SSL3Opaque *pIn, PRInt32 nIn) | |
| 474 { | |
| 475 SECStatus rv = SECSuccess; | |
| 476 DTLSQueuedMessage *msg = NULL; | |
| 477 | |
| 478 PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); | |
| 479 PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); | |
| 480 | |
| 481 msg = dtls_AllocQueuedMessage(ss->ssl3.cwSpec->epoch, type, pIn, nIn); | |
| 482 | |
| 483 if (!msg) { | |
| 484 PORT_SetError(SEC_ERROR_NO_MEMORY); | |
| 485 rv = SECFailure; | |
| 486 } else { | |
| 487 PR_APPEND_LINK(&msg->link, &ss->ssl3.hs.lastMessageFlight); | |
| 488 } | |
| 489 | |
| 490 return rv; | |
| 491 } | |
| 492 | |
| 493 /* Add DTLS handshake message to the pending queue | |
| 494 * Empty the sendBuf buffer. | |
| 495 * This function returns SECSuccess or SECFailure, never SECWouldBlock. | |
| 496 * Always set sendBuf.len to 0, even when returning SECFailure. | |
| 497 * | |
| 498 * Called from: | |
| 499 * ssl3_AppendHandshakeHeader() | |
| 500 * dtls_FlushHandshake() | |
| 501 */ | |
| 502 SECStatus | |
| 503 dtls_StageHandshakeMessage(sslSocket *ss) | |
| 504 { | |
| 505 SECStatus rv = SECSuccess; | |
| 506 | |
| 507 PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); | |
| 508 PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); | |
| 509 | |
| 510 /* This function is sometimes called when no data is actually to | |
| 511 * be staged, so just return SECSuccess. */ | |
| 512 if (!ss->sec.ci.sendBuf.buf || !ss->sec.ci.sendBuf.len) | |
| 513 return rv; | |
| 514 | |
| 515 rv = dtls_QueueMessage(ss, content_handshake, | |
| 516 ss->sec.ci.sendBuf.buf, ss->sec.ci.sendBuf.len); | |
| 517 | |
| 518 /* Whether we succeeded or failed, toss the old handshake data. */ | |
| 519 ss->sec.ci.sendBuf.len = 0; | |
| 520 return rv; | |
| 521 } | |
| 522 | |
| 523 /* Enqueue the handshake message in sendBuf (if any) and then | |
| 524 * transmit the resulting flight of handshake messages. | |
| 525 * | |
| 526 * Called from: | |
| 527 * ssl3_FlushHandshake() | |
| 528 */ | |
| 529 SECStatus | |
| 530 dtls_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags) | |
| 531 { | |
| 532 SECStatus rv = SECSuccess; | |
| 533 | |
| 534 PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); | |
| 535 PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); | |
| 536 | |
| 537 rv = dtls_StageHandshakeMessage(ss); | |
| 538 if (rv != SECSuccess) | |
| 539 return rv; | |
| 540 | |
| 541 if (!(flags & ssl_SEND_FLAG_FORCE_INTO_BUFFER)) { | |
| 542 rv = dtls_TransmitMessageFlight(ss); | |
| 543 if (rv != SECSuccess) | |
| 544 return rv; | |
| 545 | |
| 546 if (!(flags & ssl_SEND_FLAG_NO_RETRANSMIT)) { | |
| 547 ss->ssl3.hs.rtRetries = 0; | |
| 548 rv = dtls_StartTimer(ss, dtls_RetransmitTimerExpiredCb); | |
| 549 } | |
| 550 } | |
| 551 | |
| 552 return rv; | |
| 553 } | |
| 554 | |
| 555 /* The callback for when the retransmit timer expires | |
| 556 * | |
| 557 * Called from: | |
| 558 * dtls_CheckTimer() | |
| 559 * dtls_HandleHandshake() | |
| 560 */ | |
| 561 static void | |
| 562 dtls_RetransmitTimerExpiredCb(sslSocket *ss) | |
| 563 { | |
| 564 SECStatus rv = SECFailure; | |
| 565 | |
| 566 ss->ssl3.hs.rtRetries++; | |
| 567 | |
| 568 if (!(ss->ssl3.hs.rtRetries % 3)) { | |
| 569 /* If one of the messages was potentially greater than > MTU, | |
| 570 * then downgrade. Do this every time we have retransmitted a | |
| 571 * message twice, per RFC 6347 Sec. 4.1.1 */ | |
| 572 dtls_SetMTU(ss, ss->ssl3.hs.maxMessageSent - 1); | |
| 573 } | |
| 574 | |
| 575 rv = dtls_TransmitMessageFlight(ss); | |
| 576 if (rv == SECSuccess) { | |
| 577 | |
| 578 /* Re-arm the timer */ | |
| 579 rv = dtls_RestartTimer(ss, PR_TRUE, dtls_RetransmitTimerExpiredCb); | |
| 580 } | |
| 581 | |
| 582 if (rv == SECFailure) { | |
| 583 /* XXX OK for now. In future maybe signal the stack that we couldn't | |
| 584 * transmit. For now, let the read handle any real network errors */ | |
| 585 } | |
| 586 } | |
| 587 | |
| 588 /* Transmit a flight of handshake messages, stuffing them | |
| 589 * into as few records as seems reasonable | |
| 590 * | |
| 591 * Called from: | |
| 592 * dtls_FlushHandshake() | |
| 593 * dtls_RetransmitTimerExpiredCb() | |
| 594 */ | |
| 595 static SECStatus | |
| 596 dtls_TransmitMessageFlight(sslSocket *ss) | |
| 597 { | |
| 598 SECStatus rv = SECSuccess; | |
| 599 PRCList *msg_p; | |
| 600 PRUint16 room_left = ss->ssl3.mtu; | |
| 601 PRInt32 sent; | |
| 602 | |
| 603 ssl_GetXmitBufLock(ss); | |
| 604 ssl_GetSpecReadLock(ss); | |
| 605 | |
| 606 /* DTLS does not buffer its handshake messages in | |
| 607 * ss->pendingBuf, but rather in the lastMessageFlight | |
| 608 * structure. This is just a sanity check that | |
| 609 * some programming error hasn't inadvertantly | |
| 610 * stuffed something in ss->pendingBuf | |
| 611 */ | |
| 612 PORT_Assert(!ss->pendingBuf.len); | |
| 613 for (msg_p = PR_LIST_HEAD(&ss->ssl3.hs.lastMessageFlight); | |
| 614 msg_p != &ss->ssl3.hs.lastMessageFlight; | |
| 615 msg_p = PR_NEXT_LINK(msg_p)) { | |
| 616 DTLSQueuedMessage *msg = (DTLSQueuedMessage *)msg_p; | |
| 617 | |
| 618 /* The logic here is: | |
| 619 * | |
| 620 * 1. If this is a message that will not fit into the remaining | |
| 621 * space, then flush. | |
| 622 * 2. If the message will now fit into the remaining space, | |
| 623 * encrypt, buffer, and loop. | |
| 624 * 3. If the message will not fit, then fragment. | |
| 625 * | |
| 626 * At the end of the function, flush. | |
| 627 */ | |
| 628 if ((msg->len + SSL3_BUFFER_FUDGE) > room_left) { | |
| 629 /* The message will not fit into the remaining space, so flush */ | |
| 630 rv = dtls_SendSavedWriteData(ss); | |
| 631 if (rv != SECSuccess) | |
| 632 break; | |
| 633 | |
| 634 room_left = ss->ssl3.mtu; | |
| 635 } | |
| 636 | |
| 637 if ((msg->len + SSL3_BUFFER_FUDGE) <= room_left) { | |
| 638 /* The message will fit, so encrypt and then continue with the | |
| 639 * next packet */ | |
| 640 sent = ssl3_SendRecord(ss, msg->epoch, msg->type, | |
| 641 msg->data, msg->len, | |
| 642 ssl_SEND_FLAG_FORCE_INTO_BUFFER | | |
| 643 ssl_SEND_FLAG_USE_EPOCH); | |
| 644 if (sent != msg->len) { | |
| 645 rv = SECFailure; | |
| 646 if (sent != -1) { | |
| 647 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); | |
| 648 } | |
| 649 break; | |
| 650 } | |
| 651 | |
| 652 room_left = ss->ssl3.mtu - ss->pendingBuf.len; | |
| 653 } else { | |
| 654 /* The message will not fit, so fragment. | |
| 655 * | |
| 656 * XXX OK for now. Arrange to coalesce the last fragment | |
| 657 * of this message with the next message if possible. | |
| 658 * That would be more efficient. | |
| 659 */ | |
| 660 PRUint32 fragment_offset = 0; | |
| 661 unsigned char fragment[DTLS_MAX_MTU]; /* >= than largest | |
| 662 * plausible MTU */ | |
| 663 | |
| 664 /* Assert that we have already flushed */ | |
| 665 PORT_Assert(room_left == ss->ssl3.mtu); | |
| 666 | |
| 667 /* Case 3: We now need to fragment this message | |
| 668 * DTLS only supports fragmenting handshaking messages */ | |
| 669 PORT_Assert(msg->type == content_handshake); | |
| 670 | |
| 671 /* The headers consume 12 bytes so the smalles possible | |
| 672 * message (i.e., an empty one) is 12 bytes | |
| 673 */ | |
| 674 PORT_Assert(msg->len >= 12); | |
| 675 | |
| 676 while ((fragment_offset + 12) < msg->len) { | |
| 677 PRUint32 fragment_len; | |
| 678 const unsigned char *content = msg->data + 12; | |
| 679 PRUint32 content_len = msg->len - 12; | |
| 680 | |
| 681 /* The reason we use 8 here is that that's the length of | |
| 682 * the new DTLS data that we add to the header */ | |
| 683 fragment_len = PR_MIN((PRUint32)room_left - (SSL3_BUFFER_FUDGE +
8), | |
| 684 content_len - fragment_offset); | |
| 685 PORT_Assert(fragment_len < DTLS_MAX_MTU - 12); | |
| 686 /* Make totally sure that we are within the buffer. | |
| 687 * Note that the only way that fragment len could get | |
| 688 * adjusted here is if | |
| 689 * | |
| 690 * (a) we are in release mode so the PORT_Assert is compiled out | |
| 691 * (b) either the MTU table is inconsistent with DTLS_MAX_MTU | |
| 692 * or ss->ssl3.mtu has become corrupt. | |
| 693 */ | |
| 694 fragment_len = PR_MIN(fragment_len, DTLS_MAX_MTU - 12); | |
| 695 | |
| 696 /* Construct an appropriate-sized fragment */ | |
| 697 /* Type, length, sequence */ | |
| 698 PORT_Memcpy(fragment, msg->data, 6); | |
| 699 | |
| 700 /* Offset */ | |
| 701 fragment[6] = (fragment_offset >> 16) & 0xff; | |
| 702 fragment[7] = (fragment_offset >> 8) & 0xff; | |
| 703 fragment[8] = (fragment_offset)&0xff; | |
| 704 | |
| 705 /* Fragment length */ | |
| 706 fragment[9] = (fragment_len >> 16) & 0xff; | |
| 707 fragment[10] = (fragment_len >> 8) & 0xff; | |
| 708 fragment[11] = (fragment_len)&0xff; | |
| 709 | |
| 710 PORT_Memcpy(fragment + 12, content + fragment_offset, | |
| 711 fragment_len); | |
| 712 | |
| 713 /* | |
| 714 * Send the record. We do this in two stages | |
| 715 * 1. Encrypt | |
| 716 */ | |
| 717 sent = ssl3_SendRecord(ss, msg->epoch, msg->type, | |
| 718 fragment, fragment_len + 12, | |
| 719 ssl_SEND_FLAG_FORCE_INTO_BUFFER | | |
| 720 ssl_SEND_FLAG_USE_EPOCH); | |
| 721 if (sent != (fragment_len + 12)) { | |
| 722 rv = SECFailure; | |
| 723 if (sent != -1) { | |
| 724 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); | |
| 725 } | |
| 726 break; | |
| 727 } | |
| 728 | |
| 729 /* 2. Flush */ | |
| 730 rv = dtls_SendSavedWriteData(ss); | |
| 731 if (rv != SECSuccess) | |
| 732 break; | |
| 733 | |
| 734 fragment_offset += fragment_len; | |
| 735 } | |
| 736 } | |
| 737 } | |
| 738 | |
| 739 /* Finally, we need to flush */ | |
| 740 if (rv == SECSuccess) | |
| 741 rv = dtls_SendSavedWriteData(ss); | |
| 742 | |
| 743 /* Give up the locks */ | |
| 744 ssl_ReleaseSpecReadLock(ss); | |
| 745 ssl_ReleaseXmitBufLock(ss); | |
| 746 | |
| 747 return rv; | |
| 748 } | |
| 749 | |
| 750 /* Flush the data in the pendingBuf and update the max message sent | |
| 751 * so we can adjust the MTU estimate if we need to. | |
| 752 * Wrapper for ssl_SendSavedWriteData. | |
| 753 * | |
| 754 * Called from dtls_TransmitMessageFlight() | |
| 755 */ | |
| 756 static SECStatus | |
| 757 dtls_SendSavedWriteData(sslSocket *ss) | |
| 758 { | |
| 759 PRInt32 sent; | |
| 760 | |
| 761 sent = ssl_SendSavedWriteData(ss); | |
| 762 if (sent < 0) | |
| 763 return SECFailure; | |
| 764 | |
| 765 /* We should always have complete writes b/c datagram sockets | |
| 766 * don't really block */ | |
| 767 if (ss->pendingBuf.len > 0) { | |
| 768 ssl_MapLowLevelError(SSL_ERROR_SOCKET_WRITE_FAILURE); | |
| 769 return SECFailure; | |
| 770 } | |
| 771 | |
| 772 /* Update the largest message sent so we can adjust the MTU | |
| 773 * estimate if necessary */ | |
| 774 if (sent > ss->ssl3.hs.maxMessageSent) | |
| 775 ss->ssl3.hs.maxMessageSent = sent; | |
| 776 | |
| 777 return SECSuccess; | |
| 778 } | |
| 779 | |
| 780 /* Compress, MAC, encrypt a DTLS record. Allows specification of | |
| 781 * the epoch using epoch value. If use_epoch is PR_TRUE then | |
| 782 * we use the provided epoch. If use_epoch is PR_FALSE then | |
| 783 * whatever the current value is in effect is used. | |
| 784 * | |
| 785 * Called from ssl3_SendRecord() | |
| 786 */ | |
| 787 SECStatus | |
| 788 dtls_CompressMACEncryptRecord(sslSocket *ss, | |
| 789 DTLSEpoch epoch, | |
| 790 PRBool use_epoch, | |
| 791 SSL3ContentType type, | |
| 792 const SSL3Opaque *pIn, | |
| 793 PRUint32 contentLen, | |
| 794 sslBuffer *wrBuf) | |
| 795 { | |
| 796 SECStatus rv = SECFailure; | |
| 797 ssl3CipherSpec *cwSpec; | |
| 798 | |
| 799 ssl_GetSpecReadLock(ss); /********************************/ | |
| 800 | |
| 801 /* The reason for this switch-hitting code is that we might have | |
| 802 * a flight of records spanning an epoch boundary, e.g., | |
| 803 * | |
| 804 * ClientKeyExchange (epoch = 0) | |
| 805 * ChangeCipherSpec (epoch = 0) | |
| 806 * Finished (epoch = 1) | |
| 807 * | |
| 808 * Thus, each record needs a different cipher spec. The information | |
| 809 * about which epoch to use is carried with the record. | |
| 810 */ | |
| 811 if (use_epoch) { | |
| 812 if (ss->ssl3.cwSpec->epoch == epoch) | |
| 813 cwSpec = ss->ssl3.cwSpec; | |
| 814 else if (ss->ssl3.pwSpec->epoch == epoch) | |
| 815 cwSpec = ss->ssl3.pwSpec; | |
| 816 else | |
| 817 cwSpec = NULL; | |
| 818 } else { | |
| 819 cwSpec = ss->ssl3.cwSpec; | |
| 820 } | |
| 821 | |
| 822 if (cwSpec) { | |
| 823 if (ss->ssl3.cwSpec->version < SSL_LIBRARY_VERSION_TLS_1_3) { | |
| 824 rv = ssl3_CompressMACEncryptRecord(cwSpec, ss->sec.isServer, PR_TRUE
, | |
| 825 PR_FALSE, type, pIn, contentLen, | |
| 826 wrBuf); | |
| 827 } else { | |
| 828 rv = tls13_ProtectRecord(ss, type, pIn, contentLen, wrBuf); | |
| 829 } | |
| 830 } else { | |
| 831 PR_NOT_REACHED("Couldn't find a cipher spec matching epoch"); | |
| 832 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); | |
| 833 } | |
| 834 ssl_ReleaseSpecReadLock(ss); /************************************/ | |
| 835 | |
| 836 return rv; | |
| 837 } | |
| 838 | |
| 839 /* Start a timer | |
| 840 * | |
| 841 * Called from: | |
| 842 * dtls_HandleHandshake() | |
| 843 * dtls_FlushHAndshake() | |
| 844 * dtls_RestartTimer() | |
| 845 */ | |
| 846 SECStatus | |
| 847 dtls_StartTimer(sslSocket *ss, DTLSTimerCb cb) | |
| 848 { | |
| 849 PORT_Assert(ss->ssl3.hs.rtTimerCb == NULL); | |
| 850 | |
| 851 ss->ssl3.hs.rtTimerStarted = PR_IntervalNow(); | |
| 852 ss->ssl3.hs.rtTimerCb = cb; | |
| 853 | |
| 854 return SECSuccess; | |
| 855 } | |
| 856 | |
| 857 /* Restart a timer with optional backoff | |
| 858 * | |
| 859 * Called from dtls_RetransmitTimerExpiredCb() | |
| 860 */ | |
| 861 SECStatus | |
| 862 dtls_RestartTimer(sslSocket *ss, PRBool backoff, DTLSTimerCb cb) | |
| 863 { | |
| 864 if (backoff) { | |
| 865 ss->ssl3.hs.rtTimeoutMs *= 2; | |
| 866 if (ss->ssl3.hs.rtTimeoutMs > MAX_DTLS_TIMEOUT_MS) | |
| 867 ss->ssl3.hs.rtTimeoutMs = MAX_DTLS_TIMEOUT_MS; | |
| 868 } | |
| 869 | |
| 870 return dtls_StartTimer(ss, cb); | |
| 871 } | |
| 872 | |
| 873 /* Cancel a pending timer | |
| 874 * | |
| 875 * Called from: | |
| 876 * dtls_HandleHandshake() | |
| 877 * dtls_CheckTimer() | |
| 878 */ | |
| 879 void | |
| 880 dtls_CancelTimer(sslSocket *ss) | |
| 881 { | |
| 882 PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); | |
| 883 | |
| 884 ss->ssl3.hs.rtTimerCb = NULL; | |
| 885 } | |
| 886 | |
| 887 /* Check the pending timer and fire the callback if it expired | |
| 888 * | |
| 889 * Called from ssl3_GatherCompleteHandshake() | |
| 890 */ | |
| 891 void | |
| 892 dtls_CheckTimer(sslSocket *ss) | |
| 893 { | |
| 894 if (!ss->ssl3.hs.rtTimerCb) | |
| 895 return; | |
| 896 | |
| 897 if ((PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted) > | |
| 898 PR_MillisecondsToInterval(ss->ssl3.hs.rtTimeoutMs)) { | |
| 899 /* Timer has expired */ | |
| 900 DTLSTimerCb cb = ss->ssl3.hs.rtTimerCb; | |
| 901 | |
| 902 /* Cancel the timer so that we can call the CB safely */ | |
| 903 dtls_CancelTimer(ss); | |
| 904 | |
| 905 /* Now call the CB */ | |
| 906 cb(ss); | |
| 907 } | |
| 908 } | |
| 909 | |
| 910 /* The callback to fire when the holddown timer for the Finished | |
| 911 * message expires and we can delete it | |
| 912 * | |
| 913 * Called from dtls_CheckTimer() | |
| 914 */ | |
| 915 void | |
| 916 dtls_FinishedTimerCb(sslSocket *ss) | |
| 917 { | |
| 918 ssl3_DestroyCipherSpec(ss->ssl3.pwSpec, PR_FALSE); | |
| 919 } | |
| 920 | |
| 921 /* Cancel the Finished hold-down timer and destroy the | |
| 922 * pending cipher spec. Note that this means that | |
| 923 * successive rehandshakes will fail if the Finished is | |
| 924 * lost. | |
| 925 * | |
| 926 * XXX OK for now. Figure out how to handle the combination | |
| 927 * of Finished lost and rehandshake | |
| 928 */ | |
| 929 void | |
| 930 dtls_RehandshakeCleanup(sslSocket *ss) | |
| 931 { | |
| 932 dtls_CancelTimer(ss); | |
| 933 ssl3_DestroyCipherSpec(ss->ssl3.pwSpec, PR_FALSE); | |
| 934 ss->ssl3.hs.sendMessageSeq = 0; | |
| 935 ss->ssl3.hs.recvMessageSeq = 0; | |
| 936 } | |
| 937 | |
| 938 /* Set the MTU to the next step less than or equal to the | |
| 939 * advertised value. Also used to downgrade the MTU by | |
| 940 * doing dtls_SetMTU(ss, biggest packet set). | |
| 941 * | |
| 942 * Passing 0 means set this to the largest MTU known | |
| 943 * (effectively resetting the PMTU backoff value). | |
| 944 * | |
| 945 * Called by: | |
| 946 * ssl3_InitState() | |
| 947 * dtls_RetransmitTimerExpiredCb() | |
| 948 */ | |
| 949 void | |
| 950 dtls_SetMTU(sslSocket *ss, PRUint16 advertised) | |
| 951 { | |
| 952 int i; | |
| 953 | |
| 954 if (advertised == 0) { | |
| 955 ss->ssl3.mtu = COMMON_MTU_VALUES[0]; | |
| 956 SSL_TRC(30, ("Resetting MTU to %d", ss->ssl3.mtu)); | |
| 957 return; | |
| 958 } | |
| 959 | |
| 960 for (i = 0; i < PR_ARRAY_SIZE(COMMON_MTU_VALUES); i++) { | |
| 961 if (COMMON_MTU_VALUES[i] <= advertised) { | |
| 962 ss->ssl3.mtu = COMMON_MTU_VALUES[i]; | |
| 963 SSL_TRC(30, ("Resetting MTU to %d", ss->ssl3.mtu)); | |
| 964 return; | |
| 965 } | |
| 966 } | |
| 967 | |
| 968 /* Fallback */ | |
| 969 ss->ssl3.mtu = COMMON_MTU_VALUES[PR_ARRAY_SIZE(COMMON_MTU_VALUES) - 1]; | |
| 970 SSL_TRC(30, ("Resetting MTU to %d", ss->ssl3.mtu)); | |
| 971 } | |
| 972 | |
| 973 /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a | |
| 974 * DTLS hello_verify_request | |
| 975 * Caller must hold Handshake and RecvBuf locks. | |
| 976 */ | |
| 977 SECStatus | |
| 978 dtls_HandleHelloVerifyRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length) | |
| 979 { | |
| 980 int errCode = SSL_ERROR_RX_MALFORMED_HELLO_VERIFY_REQUEST; | |
| 981 SECStatus rv; | |
| 982 PRInt32 temp; | |
| 983 SECItem cookie = { siBuffer, NULL, 0 }; | |
| 984 SSL3AlertDescription desc = illegal_parameter; | |
| 985 | |
| 986 SSL_TRC(3, ("%d: SSL3[%d]: handle hello_verify_request handshake", | |
| 987 SSL_GETPID(), ss->fd)); | |
| 988 PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); | |
| 989 PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); | |
| 990 | |
| 991 if (ss->ssl3.hs.ws != wait_server_hello) { | |
| 992 errCode = SSL_ERROR_RX_UNEXPECTED_HELLO_VERIFY_REQUEST; | |
| 993 desc = unexpected_message; | |
| 994 goto alert_loser; | |
| 995 } | |
| 996 | |
| 997 /* The version */ | |
| 998 temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length); | |
| 999 if (temp < 0) { | |
| 1000 goto loser; /* alert has been sent */ | |
| 1001 } | |
| 1002 | |
| 1003 if (temp != SSL_LIBRARY_VERSION_DTLS_1_0_WIRE && | |
| 1004 temp != SSL_LIBRARY_VERSION_DTLS_1_2_WIRE) { | |
| 1005 goto alert_loser; | |
| 1006 } | |
| 1007 | |
| 1008 /* The cookie */ | |
| 1009 rv = ssl3_ConsumeHandshakeVariable(ss, &cookie, 1, &b, &length); | |
| 1010 if (rv != SECSuccess) { | |
| 1011 goto loser; /* alert has been sent */ | |
| 1012 } | |
| 1013 if (cookie.len > DTLS_COOKIE_BYTES) { | |
| 1014 desc = decode_error; | |
| 1015 goto alert_loser; /* malformed. */ | |
| 1016 } | |
| 1017 | |
| 1018 PORT_Memcpy(ss->ssl3.hs.cookie, cookie.data, cookie.len); | |
| 1019 ss->ssl3.hs.cookieLen = cookie.len; | |
| 1020 | |
| 1021 ssl_GetXmitBufLock(ss); /*******************************/ | |
| 1022 | |
| 1023 /* Now re-send the client hello */ | |
| 1024 rv = ssl3_SendClientHello(ss, PR_TRUE); | |
| 1025 | |
| 1026 ssl_ReleaseXmitBufLock(ss); /*******************************/ | |
| 1027 | |
| 1028 if (rv == SECSuccess) | |
| 1029 return rv; | |
| 1030 | |
| 1031 alert_loser: | |
| 1032 (void)SSL3_SendAlert(ss, alert_fatal, desc); | |
| 1033 | |
| 1034 loser: | |
| 1035 ssl_MapLowLevelError(errCode); | |
| 1036 return SECFailure; | |
| 1037 } | |
| 1038 | |
| 1039 /* Initialize the DTLS anti-replay window | |
| 1040 * | |
| 1041 * Called from: | |
| 1042 * ssl3_SetupPendingCipherSpec() | |
| 1043 * ssl3_InitCipherSpec() | |
| 1044 */ | |
| 1045 void | |
| 1046 dtls_InitRecvdRecords(DTLSRecvdRecords *records) | |
| 1047 { | |
| 1048 PORT_Memset(records->data, 0, sizeof(records->data)); | |
| 1049 records->left = 0; | |
| 1050 records->right = DTLS_RECVD_RECORDS_WINDOW - 1; | |
| 1051 } | |
| 1052 | |
| 1053 /* | |
| 1054 * Has this DTLS record been received? Return values are: | |
| 1055 * -1 -- out of range to the left | |
| 1056 * 0 -- not received yet | |
| 1057 * 1 -- replay | |
| 1058 * | |
| 1059 * Called from: ssl3_HandleRecord() | |
| 1060 */ | |
| 1061 int | |
| 1062 dtls_RecordGetRecvd(const DTLSRecvdRecords *records, PRUint64 seq) | |
| 1063 { | |
| 1064 PRUint64 offset; | |
| 1065 | |
| 1066 /* Out of range to the left */ | |
| 1067 if (seq < records->left) { | |
| 1068 return -1; | |
| 1069 } | |
| 1070 | |
| 1071 /* Out of range to the right; since we advance the window on | |
| 1072 * receipt, that means that this packet has not been received | |
| 1073 * yet */ | |
| 1074 if (seq > records->right) | |
| 1075 return 0; | |
| 1076 | |
| 1077 offset = seq % DTLS_RECVD_RECORDS_WINDOW; | |
| 1078 | |
| 1079 return !!(records->data[offset / 8] & (1 << (offset % 8))); | |
| 1080 } | |
| 1081 | |
| 1082 /* Update the DTLS anti-replay window | |
| 1083 * | |
| 1084 * Called from ssl3_HandleRecord() | |
| 1085 */ | |
| 1086 void | |
| 1087 dtls_RecordSetRecvd(DTLSRecvdRecords *records, PRUint64 seq) | |
| 1088 { | |
| 1089 PRUint64 offset; | |
| 1090 | |
| 1091 if (seq < records->left) | |
| 1092 return; | |
| 1093 | |
| 1094 if (seq > records->right) { | |
| 1095 PRUint64 new_left; | |
| 1096 PRUint64 new_right; | |
| 1097 PRUint64 right; | |
| 1098 | |
| 1099 /* Slide to the right; this is the tricky part | |
| 1100 * | |
| 1101 * 1. new_top is set to have room for seq, on the | |
| 1102 * next byte boundary by setting the right 8 | |
| 1103 * bits of seq | |
| 1104 * 2. new_left is set to compensate. | |
| 1105 * 3. Zero all bits between top and new_top. Since | |
| 1106 * this is a ring, this zeroes everything as-yet | |
| 1107 * unseen. Because we always operate on byte | |
| 1108 * boundaries, we can zero one byte at a time | |
| 1109 */ | |
| 1110 new_right = seq | 0x07; | |
| 1111 new_left = (new_right - DTLS_RECVD_RECORDS_WINDOW) + 1; | |
| 1112 | |
| 1113 for (right = records->right + 8; right <= new_right; right += 8) { | |
| 1114 offset = right % DTLS_RECVD_RECORDS_WINDOW; | |
| 1115 records->data[offset / 8] = 0; | |
| 1116 } | |
| 1117 | |
| 1118 records->right = new_right; | |
| 1119 records->left = new_left; | |
| 1120 } | |
| 1121 | |
| 1122 offset = seq % DTLS_RECVD_RECORDS_WINDOW; | |
| 1123 | |
| 1124 records->data[offset / 8] |= (1 << (offset % 8)); | |
| 1125 } | |
| 1126 | |
| 1127 SECStatus | |
| 1128 DTLS_GetHandshakeTimeout(PRFileDesc *socket, PRIntervalTime *timeout) | |
| 1129 { | |
| 1130 sslSocket *ss = NULL; | |
| 1131 PRIntervalTime elapsed; | |
| 1132 PRIntervalTime desired; | |
| 1133 | |
| 1134 ss = ssl_FindSocket(socket); | |
| 1135 | |
| 1136 if (!ss) | |
| 1137 return SECFailure; | |
| 1138 | |
| 1139 if (!IS_DTLS(ss)) | |
| 1140 return SECFailure; | |
| 1141 | |
| 1142 if (!ss->ssl3.hs.rtTimerCb) | |
| 1143 return SECFailure; | |
| 1144 | |
| 1145 elapsed = PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted; | |
| 1146 desired = PR_MillisecondsToInterval(ss->ssl3.hs.rtTimeoutMs); | |
| 1147 if (elapsed > desired) { | |
| 1148 /* Timer expired */ | |
| 1149 *timeout = PR_INTERVAL_NO_WAIT; | |
| 1150 } else { | |
| 1151 *timeout = desired - elapsed; | |
| 1152 } | |
| 1153 | |
| 1154 return SECSuccess; | |
| 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 |