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