Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / net / third_party / nss / ssl / dtlscon.c
blob89315eee041b9a85eb5d9d18927e617d339789a4
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/. */
5 /*
6 * DTLS Protocol
7 */
9 #include "ssl.h"
10 #include "sslimpl.h"
11 #include "sslproto.h"
13 #ifndef PR_ARRAY_SIZE
14 #define PR_ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
15 #endif
17 static SECStatus dtls_TransmitMessageFlight(sslSocket *ss);
18 static void dtls_RetransmitTimerExpiredCb(sslSocket *ss);
19 static SECStatus dtls_SendSavedWriteData(sslSocket *ss);
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 */
29 #define DTLS_COOKIE_BYTES 32
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 */
49 /* Map back and forth between TLS and DTLS versions in wire format.
50 * Mapping table is:
52 * TLS DTLS
53 * 1.1 (0302) 1.0 (feff)
54 * 1.2 (0303) 1.2 (fefd)
55 * 1.3 (0304) 1.3 (fefc)
57 SSL3ProtocolVersion
58 dtls_TLSVersionToDTLSVersion(SSL3ProtocolVersion tlsv)
60 if (tlsv == SSL_LIBRARY_VERSION_TLS_1_1) {
61 return SSL_LIBRARY_VERSION_DTLS_1_0_WIRE;
63 if (tlsv == SSL_LIBRARY_VERSION_TLS_1_2) {
64 return SSL_LIBRARY_VERSION_DTLS_1_2_WIRE;
66 if (tlsv == SSL_LIBRARY_VERSION_TLS_1_3) {
67 return SSL_LIBRARY_VERSION_DTLS_1_3_WIRE;
70 /* Anything other than TLS 1.1 or 1.2 is an error, so return
71 * the invalid version 0xffff. */
72 return 0xffff;
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)
82 if (MSB(dtlsv) == 0xff) {
83 return 0;
86 if (dtlsv == SSL_LIBRARY_VERSION_DTLS_1_0_WIRE) {
87 return SSL_LIBRARY_VERSION_TLS_1_1;
89 if (dtlsv == SSL_LIBRARY_VERSION_DTLS_1_2_WIRE) {
90 return SSL_LIBRARY_VERSION_TLS_1_2;
92 if (dtlsv == SSL_LIBRARY_VERSION_DTLS_1_3_WIRE) {
93 return SSL_LIBRARY_VERSION_TLS_1_3;
96 /* Return a fictional higher version than we know of */
97 return SSL_LIBRARY_VERSION_TLS_1_2 + 1;
100 /* On this socket, Disable non-DTLS cipher suites in the argument's list */
101 SECStatus
102 ssl3_DisableNonDTLSSuites(sslSocket * ss)
104 const ssl3CipherSuite * suite;
106 for (suite = nonDTLSSuites; *suite; ++suite) {
107 SECStatus rv = ssl3_CipherPrefSet(ss, *suite, PR_FALSE);
109 PORT_Assert(rv == SECSuccess); /* else is coding error */
111 return SECSuccess;
114 /* Allocate a DTLSQueuedMessage.
116 * Called from dtls_QueueMessage()
118 static DTLSQueuedMessage *
119 dtls_AllocQueuedMessage(PRUint16 epoch, SSL3ContentType type,
120 const unsigned char *data, PRUint32 len)
122 DTLSQueuedMessage *msg = NULL;
124 msg = PORT_ZAlloc(sizeof(DTLSQueuedMessage));
125 if (!msg)
126 return NULL;
128 msg->data = PORT_Alloc(len);
129 if (!msg->data) {
130 PORT_Free(msg);
131 return NULL;
133 PORT_Memcpy(msg->data, data, len);
135 msg->len = len;
136 msg->epoch = epoch;
137 msg->type = type;
139 return msg;
143 * Free a handshake message
145 * Called from dtls_FreeHandshakeMessages()
147 static void
148 dtls_FreeHandshakeMessage(DTLSQueuedMessage *msg)
150 if (!msg)
151 return;
153 PORT_ZFree(msg->data, msg->len);
154 PORT_Free(msg);
158 * Free a list of handshake messages
160 * Called from:
161 * dtls_HandleHandshake()
162 * ssl3_DestroySSL3Info()
164 void
165 dtls_FreeHandshakeMessages(PRCList *list)
167 PRCList *cur_p;
169 while (!PR_CLIST_IS_EMPTY(list)) {
170 cur_p = PR_LIST_TAIL(list);
171 PR_REMOVE_LINK(cur_p);
172 dtls_FreeHandshakeMessage((DTLSQueuedMessage *)cur_p);
176 /* Called only from ssl3_HandleRecord, for each (deciphered) DTLS record.
177 * origBuf is the decrypted ssl record content and is expected to contain
178 * complete handshake records
179 * Caller must hold the handshake and RecvBuf locks.
181 * Note that this code uses msg_len for two purposes:
183 * (1) To pass the length to ssl3_HandleHandshakeMessage()
184 * (2) To carry the length of a message currently being reassembled
186 * However, unlike ssl3_HandleHandshake(), it is not used to carry
187 * the state of reassembly (i.e., whether one is in progress). That
188 * is carried in recvdHighWater and recvdFragments.
190 #define OFFSET_BYTE(o) (o/8)
191 #define OFFSET_MASK(o) (1 << (o%8))
193 SECStatus
194 dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
196 /* XXX OK for now.
197 * This doesn't work properly with asynchronous certificate validation.
198 * because that returns a WOULDBLOCK error. The current DTLS
199 * applications do not need asynchronous validation, but in the
200 * future we will need to add this.
202 sslBuffer buf = *origBuf;
203 SECStatus rv = SECSuccess;
205 PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
206 PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
208 while (buf.len > 0) {
209 PRUint8 type;
210 PRUint32 message_length;
211 PRUint16 message_seq;
212 PRUint32 fragment_offset;
213 PRUint32 fragment_length;
214 PRUint32 offset;
216 if (buf.len < 12) {
217 PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
218 rv = SECFailure;
219 break;
222 /* Parse the header */
223 type = buf.buf[0];
224 message_length = (buf.buf[1] << 16) | (buf.buf[2] << 8) | buf.buf[3];
225 message_seq = (buf.buf[4] << 8) | buf.buf[5];
226 fragment_offset = (buf.buf[6] << 16) | (buf.buf[7] << 8) | buf.buf[8];
227 fragment_length = (buf.buf[9] << 16) | (buf.buf[10] << 8) | buf.buf[11];
229 #define MAX_HANDSHAKE_MSG_LEN 0x1ffff /* 128k - 1 */
230 if (message_length > MAX_HANDSHAKE_MSG_LEN) {
231 (void)ssl3_DecodeError(ss);
232 PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
233 return SECFailure;
235 #undef MAX_HANDSHAKE_MSG_LEN
237 buf.buf += 12;
238 buf.len -= 12;
240 /* This fragment must be complete */
241 if (buf.len < fragment_length) {
242 PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
243 rv = SECFailure;
244 break;
247 /* Sanity check the packet contents */
248 if ((fragment_length + fragment_offset) > message_length) {
249 PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
250 rv = SECFailure;
251 break;
254 /* There are three ways we could not be ready for this packet.
256 * 1. It's a partial next message.
257 * 2. It's a partial or complete message beyond the next
258 * 3. It's a message we've already seen
260 * If it's the complete next message we accept it right away.
261 * This is the common case for short messages
263 if ((message_seq == ss->ssl3.hs.recvMessageSeq)
264 && (fragment_offset == 0)
265 && (fragment_length == message_length)) {
266 /* Complete next message. Process immediately */
267 ss->ssl3.hs.msg_type = (SSL3HandshakeType)type;
268 ss->ssl3.hs.msg_len = message_length;
270 /* At this point we are advancing our state machine, so
271 * we can free our last flight of messages */
272 dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight);
273 ss->ssl3.hs.recvdHighWater = -1;
274 dtls_CancelTimer(ss);
276 /* Reset the timer to the initial value if the retry counter
277 * is 0, per Sec. 4.2.4.1 */
278 if (ss->ssl3.hs.rtRetries == 0) {
279 ss->ssl3.hs.rtTimeoutMs = INITIAL_DTLS_TIMEOUT_MS;
282 rv = ssl3_HandleHandshakeMessage(ss, buf.buf, ss->ssl3.hs.msg_len);
283 if (rv == SECFailure) {
284 /* Do not attempt to process rest of messages in this record */
285 break;
287 } else {
288 if (message_seq < ss->ssl3.hs.recvMessageSeq) {
289 /* Case 3: we do an immediate retransmit if we're
290 * in a waiting state*/
291 if (ss->ssl3.hs.rtTimerCb == NULL) {
292 /* Ignore */
293 } else if (ss->ssl3.hs.rtTimerCb ==
294 dtls_RetransmitTimerExpiredCb) {
295 SSL_TRC(30, ("%d: SSL3[%d]: Retransmit detected",
296 SSL_GETPID(), ss->fd));
297 /* Check to see if we retransmitted recently. If so,
298 * suppress the triggered retransmit. This avoids
299 * retransmit wars after packet loss.
300 * This is not in RFC 5346 but should be
302 if ((PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted) >
303 (ss->ssl3.hs.rtTimeoutMs / 4)) {
304 SSL_TRC(30,
305 ("%d: SSL3[%d]: Shortcutting retransmit timer",
306 SSL_GETPID(), ss->fd));
308 /* Cancel the timer and call the CB,
309 * which re-arms the timer */
310 dtls_CancelTimer(ss);
311 dtls_RetransmitTimerExpiredCb(ss);
312 rv = SECSuccess;
313 break;
314 } else {
315 SSL_TRC(30,
316 ("%d: SSL3[%d]: We just retransmitted. Ignoring.",
317 SSL_GETPID(), ss->fd));
318 rv = SECSuccess;
319 break;
321 } else if (ss->ssl3.hs.rtTimerCb == dtls_FinishedTimerCb) {
322 /* Retransmit the messages and re-arm the timer
323 * Note that we are not backing off the timer here.
324 * The spec isn't clear and my reasoning is that this
325 * may be a re-ordered packet rather than slowness,
326 * so let's be aggressive. */
327 dtls_CancelTimer(ss);
328 rv = dtls_TransmitMessageFlight(ss);
329 if (rv == SECSuccess) {
330 rv = dtls_StartTimer(ss, dtls_FinishedTimerCb);
332 if (rv != SECSuccess)
333 return rv;
334 break;
336 } else if (message_seq > ss->ssl3.hs.recvMessageSeq) {
337 /* Case 2
339 * Ignore this message. This means we don't handle out of
340 * order complete messages that well, but we're still
341 * compliant and this probably does not happen often
343 * XXX OK for now. Maybe do something smarter at some point?
345 } else {
346 /* Case 1
348 * Buffer the fragment for reassembly
350 /* Make room for the message */
351 if (ss->ssl3.hs.recvdHighWater == -1) {
352 PRUint32 map_length = OFFSET_BYTE(message_length) + 1;
354 rv = sslBuffer_Grow(&ss->ssl3.hs.msg_body, message_length);
355 if (rv != SECSuccess)
356 break;
357 /* Make room for the fragment map */
358 rv = sslBuffer_Grow(&ss->ssl3.hs.recvdFragments,
359 map_length);
360 if (rv != SECSuccess)
361 break;
363 /* Reset the reassembly map */
364 ss->ssl3.hs.recvdHighWater = 0;
365 PORT_Memset(ss->ssl3.hs.recvdFragments.buf, 0,
366 ss->ssl3.hs.recvdFragments.space);
367 ss->ssl3.hs.msg_type = (SSL3HandshakeType)type;
368 ss->ssl3.hs.msg_len = message_length;
371 /* If we have a message length mismatch, abandon the reassembly
372 * in progress and hope that the next retransmit will give us
373 * something sane
375 if (message_length != ss->ssl3.hs.msg_len) {
376 ss->ssl3.hs.recvdHighWater = -1;
377 PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
378 rv = SECFailure;
379 break;
382 /* Now copy this fragment into the buffer */
383 PORT_Assert((fragment_offset + fragment_length) <=
384 ss->ssl3.hs.msg_body.space);
385 PORT_Memcpy(ss->ssl3.hs.msg_body.buf + fragment_offset,
386 buf.buf, fragment_length);
388 /* This logic is a bit tricky. We have two values for
389 * reassembly state:
391 * - recvdHighWater contains the highest contiguous number of
392 * bytes received
393 * - recvdFragments contains a bitmask of packets received
394 * above recvdHighWater
396 * This avoids having to fill in the bitmask in the common
397 * case of adjacent fragments received in sequence
399 if (fragment_offset <= ss->ssl3.hs.recvdHighWater) {
400 /* Either this is the adjacent fragment or an overlapping
401 * fragment */
402 ss->ssl3.hs.recvdHighWater = fragment_offset +
403 fragment_length;
404 } else {
405 for (offset = fragment_offset;
406 offset < fragment_offset + fragment_length;
407 offset++) {
408 ss->ssl3.hs.recvdFragments.buf[OFFSET_BYTE(offset)] |=
409 OFFSET_MASK(offset);
413 /* Now figure out the new high water mark if appropriate */
414 for (offset = ss->ssl3.hs.recvdHighWater;
415 offset < ss->ssl3.hs.msg_len; offset++) {
416 /* Note that this loop is not efficient, since it counts
417 * bit by bit. If we have a lot of out-of-order packets,
418 * we should optimize this */
419 if (ss->ssl3.hs.recvdFragments.buf[OFFSET_BYTE(offset)] &
420 OFFSET_MASK(offset)) {
421 ss->ssl3.hs.recvdHighWater++;
422 } else {
423 break;
427 /* If we have all the bytes, then we are good to go */
428 if (ss->ssl3.hs.recvdHighWater == ss->ssl3.hs.msg_len) {
429 ss->ssl3.hs.recvdHighWater = -1;
431 rv = ssl3_HandleHandshakeMessage(ss,
432 ss->ssl3.hs.msg_body.buf,
433 ss->ssl3.hs.msg_len);
434 if (rv == SECFailure)
435 break; /* Skip rest of record */
437 /* At this point we are advancing our state machine, so
438 * we can free our last flight of messages */
439 dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight);
440 dtls_CancelTimer(ss);
442 /* If there have been no retries this time, reset the
443 * timer value to the default per Section 4.2.4.1 */
444 if (ss->ssl3.hs.rtRetries == 0) {
445 ss->ssl3.hs.rtTimeoutMs = INITIAL_DTLS_TIMEOUT_MS;
451 buf.buf += fragment_length;
452 buf.len -= fragment_length;
455 origBuf->len = 0; /* So ssl3_GatherAppDataRecord will keep looping. */
457 /* XXX OK for now. In future handle rv == SECWouldBlock safely in order
458 * to deal with asynchronous certificate verification */
459 return rv;
462 /* Enqueue a message (either handshake or CCS)
464 * Called from:
465 * dtls_StageHandshakeMessage()
466 * ssl3_SendChangeCipherSpecs()
468 SECStatus dtls_QueueMessage(sslSocket *ss, SSL3ContentType type,
469 const SSL3Opaque *pIn, PRInt32 nIn)
471 SECStatus rv = SECSuccess;
472 DTLSQueuedMessage *msg = NULL;
474 PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
475 PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
477 msg = dtls_AllocQueuedMessage(ss->ssl3.cwSpec->epoch, type, pIn, nIn);
479 if (!msg) {
480 PORT_SetError(SEC_ERROR_NO_MEMORY);
481 rv = SECFailure;
482 } else {
483 PR_APPEND_LINK(&msg->link, &ss->ssl3.hs.lastMessageFlight);
486 return rv;
489 /* Add DTLS handshake message to the pending queue
490 * Empty the sendBuf buffer.
491 * This function returns SECSuccess or SECFailure, never SECWouldBlock.
492 * Always set sendBuf.len to 0, even when returning SECFailure.
494 * Called from:
495 * ssl3_AppendHandshakeHeader()
496 * dtls_FlushHandshake()
498 SECStatus
499 dtls_StageHandshakeMessage(sslSocket *ss)
501 SECStatus rv = SECSuccess;
503 PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
504 PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
506 /* This function is sometimes called when no data is actually to
507 * be staged, so just return SECSuccess. */
508 if (!ss->sec.ci.sendBuf.buf || !ss->sec.ci.sendBuf.len)
509 return rv;
511 rv = dtls_QueueMessage(ss, content_handshake,
512 ss->sec.ci.sendBuf.buf, ss->sec.ci.sendBuf.len);
514 /* Whether we succeeded or failed, toss the old handshake data. */
515 ss->sec.ci.sendBuf.len = 0;
516 return rv;
519 /* Enqueue the handshake message in sendBuf (if any) and then
520 * transmit the resulting flight of handshake messages.
522 * Called from:
523 * ssl3_FlushHandshake()
525 SECStatus
526 dtls_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags)
528 SECStatus rv = SECSuccess;
530 PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
531 PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
533 rv = dtls_StageHandshakeMessage(ss);
534 if (rv != SECSuccess)
535 return rv;
537 if (!(flags & ssl_SEND_FLAG_FORCE_INTO_BUFFER)) {
538 rv = dtls_TransmitMessageFlight(ss);
539 if (rv != SECSuccess)
540 return rv;
542 if (!(flags & ssl_SEND_FLAG_NO_RETRANSMIT)) {
543 ss->ssl3.hs.rtRetries = 0;
544 rv = dtls_StartTimer(ss, dtls_RetransmitTimerExpiredCb);
548 return rv;
551 /* The callback for when the retransmit timer expires
553 * Called from:
554 * dtls_CheckTimer()
555 * dtls_HandleHandshake()
557 static void
558 dtls_RetransmitTimerExpiredCb(sslSocket *ss)
560 SECStatus rv = SECFailure;
562 ss->ssl3.hs.rtRetries++;
564 if (!(ss->ssl3.hs.rtRetries % 3)) {
565 /* If one of the messages was potentially greater than > MTU,
566 * then downgrade. Do this every time we have retransmitted a
567 * message twice, per RFC 6347 Sec. 4.1.1 */
568 dtls_SetMTU(ss, ss->ssl3.hs.maxMessageSent - 1);
571 rv = dtls_TransmitMessageFlight(ss);
572 if (rv == SECSuccess) {
574 /* Re-arm the timer */
575 rv = dtls_RestartTimer(ss, PR_TRUE, dtls_RetransmitTimerExpiredCb);
578 if (rv == SECFailure) {
579 /* XXX OK for now. In future maybe signal the stack that we couldn't
580 * transmit. For now, let the read handle any real network errors */
584 /* Transmit a flight of handshake messages, stuffing them
585 * into as few records as seems reasonable
587 * Called from:
588 * dtls_FlushHandshake()
589 * dtls_RetransmitTimerExpiredCb()
591 static SECStatus
592 dtls_TransmitMessageFlight(sslSocket *ss)
594 SECStatus rv = SECSuccess;
595 PRCList *msg_p;
596 PRUint16 room_left = ss->ssl3.mtu;
597 PRInt32 sent;
599 ssl_GetXmitBufLock(ss);
600 ssl_GetSpecReadLock(ss);
602 /* DTLS does not buffer its handshake messages in
603 * ss->pendingBuf, but rather in the lastMessageFlight
604 * structure. This is just a sanity check that
605 * some programming error hasn't inadvertantly
606 * stuffed something in ss->pendingBuf
608 PORT_Assert(!ss->pendingBuf.len);
609 for (msg_p = PR_LIST_HEAD(&ss->ssl3.hs.lastMessageFlight);
610 msg_p != &ss->ssl3.hs.lastMessageFlight;
611 msg_p = PR_NEXT_LINK(msg_p)) {
612 DTLSQueuedMessage *msg = (DTLSQueuedMessage *)msg_p;
614 /* The logic here is:
616 * 1. If this is a message that will not fit into the remaining
617 * space, then flush.
618 * 2. If the message will now fit into the remaining space,
619 * encrypt, buffer, and loop.
620 * 3. If the message will not fit, then fragment.
622 * At the end of the function, flush.
624 if ((msg->len + SSL3_BUFFER_FUDGE) > room_left) {
625 /* The message will not fit into the remaining space, so flush */
626 rv = dtls_SendSavedWriteData(ss);
627 if (rv != SECSuccess)
628 break;
630 room_left = ss->ssl3.mtu;
633 if ((msg->len + SSL3_BUFFER_FUDGE) <= room_left) {
634 /* The message will fit, so encrypt and then continue with the
635 * next packet */
636 sent = ssl3_SendRecord(ss, msg->epoch, msg->type,
637 msg->data, msg->len,
638 ssl_SEND_FLAG_FORCE_INTO_BUFFER |
639 ssl_SEND_FLAG_USE_EPOCH);
640 if (sent != msg->len) {
641 rv = SECFailure;
642 if (sent != -1) {
643 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
645 break;
648 room_left = ss->ssl3.mtu - ss->pendingBuf.len;
649 } else {
650 /* The message will not fit, so fragment.
652 * XXX OK for now. Arrange to coalesce the last fragment
653 * of this message with the next message if possible.
654 * That would be more efficient.
656 PRUint32 fragment_offset = 0;
657 unsigned char fragment[DTLS_MAX_MTU]; /* >= than largest
658 * plausible MTU */
660 /* Assert that we have already flushed */
661 PORT_Assert(room_left == ss->ssl3.mtu);
663 /* Case 3: We now need to fragment this message
664 * DTLS only supports fragmenting handshaking messages */
665 PORT_Assert(msg->type == content_handshake);
667 /* The headers consume 12 bytes so the smalles possible
668 * message (i.e., an empty one) is 12 bytes
670 PORT_Assert(msg->len >= 12);
672 while ((fragment_offset + 12) < msg->len) {
673 PRUint32 fragment_len;
674 const unsigned char *content = msg->data + 12;
675 PRUint32 content_len = msg->len - 12;
677 /* The reason we use 8 here is that that's the length of
678 * the new DTLS data that we add to the header */
679 fragment_len = PR_MIN(room_left - (SSL3_BUFFER_FUDGE + 8),
680 content_len - fragment_offset);
681 PORT_Assert(fragment_len < DTLS_MAX_MTU - 12);
682 /* Make totally sure that we are within the buffer.
683 * Note that the only way that fragment len could get
684 * adjusted here is if
686 * (a) we are in release mode so the PORT_Assert is compiled out
687 * (b) either the MTU table is inconsistent with DTLS_MAX_MTU
688 * or ss->ssl3.mtu has become corrupt.
690 fragment_len = PR_MIN(fragment_len, DTLS_MAX_MTU - 12);
692 /* Construct an appropriate-sized fragment */
693 /* Type, length, sequence */
694 PORT_Memcpy(fragment, msg->data, 6);
696 /* Offset */
697 fragment[6] = (fragment_offset >> 16) & 0xff;
698 fragment[7] = (fragment_offset >> 8) & 0xff;
699 fragment[8] = (fragment_offset) & 0xff;
701 /* Fragment length */
702 fragment[9] = (fragment_len >> 16) & 0xff;
703 fragment[10] = (fragment_len >> 8) & 0xff;
704 fragment[11] = (fragment_len) & 0xff;
706 PORT_Memcpy(fragment + 12, content + fragment_offset,
707 fragment_len);
710 * Send the record. We do this in two stages
711 * 1. Encrypt
713 sent = ssl3_SendRecord(ss, msg->epoch, msg->type,
714 fragment, fragment_len + 12,
715 ssl_SEND_FLAG_FORCE_INTO_BUFFER |
716 ssl_SEND_FLAG_USE_EPOCH);
717 if (sent != (fragment_len + 12)) {
718 rv = SECFailure;
719 if (sent != -1) {
720 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
722 break;
725 /* 2. Flush */
726 rv = dtls_SendSavedWriteData(ss);
727 if (rv != SECSuccess)
728 break;
730 fragment_offset += fragment_len;
735 /* Finally, we need to flush */
736 if (rv == SECSuccess)
737 rv = dtls_SendSavedWriteData(ss);
739 /* Give up the locks */
740 ssl_ReleaseSpecReadLock(ss);
741 ssl_ReleaseXmitBufLock(ss);
743 return rv;
746 /* Flush the data in the pendingBuf and update the max message sent
747 * so we can adjust the MTU estimate if we need to.
748 * Wrapper for ssl_SendSavedWriteData.
750 * Called from dtls_TransmitMessageFlight()
752 static
753 SECStatus dtls_SendSavedWriteData(sslSocket *ss)
755 PRInt32 sent;
757 sent = ssl_SendSavedWriteData(ss);
758 if (sent < 0)
759 return SECFailure;
761 /* We should always have complete writes b/c datagram sockets
762 * don't really block */
763 if (ss->pendingBuf.len > 0) {
764 ssl_MapLowLevelError(SSL_ERROR_SOCKET_WRITE_FAILURE);
765 return SECFailure;
768 /* Update the largest message sent so we can adjust the MTU
769 * estimate if necessary */
770 if (sent > ss->ssl3.hs.maxMessageSent)
771 ss->ssl3.hs.maxMessageSent = sent;
773 return SECSuccess;
776 /* Compress, MAC, encrypt a DTLS record. Allows specification of
777 * the epoch using epoch value. If use_epoch is PR_TRUE then
778 * we use the provided epoch. If use_epoch is PR_FALSE then
779 * whatever the current value is in effect is used.
781 * Called from ssl3_SendRecord()
783 SECStatus
784 dtls_CompressMACEncryptRecord(sslSocket * ss,
785 DTLSEpoch epoch,
786 PRBool use_epoch,
787 SSL3ContentType type,
788 const SSL3Opaque * pIn,
789 PRUint32 contentLen,
790 sslBuffer * wrBuf)
792 SECStatus rv = SECFailure;
793 ssl3CipherSpec * cwSpec;
795 ssl_GetSpecReadLock(ss); /********************************/
797 /* The reason for this switch-hitting code is that we might have
798 * a flight of records spanning an epoch boundary, e.g.,
800 * ClientKeyExchange (epoch = 0)
801 * ChangeCipherSpec (epoch = 0)
802 * Finished (epoch = 1)
804 * Thus, each record needs a different cipher spec. The information
805 * about which epoch to use is carried with the record.
807 if (use_epoch) {
808 if (ss->ssl3.cwSpec->epoch == epoch)
809 cwSpec = ss->ssl3.cwSpec;
810 else if (ss->ssl3.pwSpec->epoch == epoch)
811 cwSpec = ss->ssl3.pwSpec;
812 else
813 cwSpec = NULL;
814 } else {
815 cwSpec = ss->ssl3.cwSpec;
818 if (cwSpec) {
819 rv = ssl3_CompressMACEncryptRecord(cwSpec, ss->sec.isServer, PR_TRUE,
820 PR_FALSE, type, pIn, contentLen,
821 wrBuf);
822 } else {
823 PR_NOT_REACHED("Couldn't find a cipher spec matching epoch");
824 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
826 ssl_ReleaseSpecReadLock(ss); /************************************/
828 return rv;
831 /* Start a timer
833 * Called from:
834 * dtls_HandleHandshake()
835 * dtls_FlushHAndshake()
836 * dtls_RestartTimer()
838 SECStatus
839 dtls_StartTimer(sslSocket *ss, DTLSTimerCb cb)
841 PORT_Assert(ss->ssl3.hs.rtTimerCb == NULL);
843 ss->ssl3.hs.rtTimerStarted = PR_IntervalNow();
844 ss->ssl3.hs.rtTimerCb = cb;
846 return SECSuccess;
849 /* Restart a timer with optional backoff
851 * Called from dtls_RetransmitTimerExpiredCb()
853 SECStatus
854 dtls_RestartTimer(sslSocket *ss, PRBool backoff, DTLSTimerCb cb)
856 if (backoff) {
857 ss->ssl3.hs.rtTimeoutMs *= 2;
858 if (ss->ssl3.hs.rtTimeoutMs > MAX_DTLS_TIMEOUT_MS)
859 ss->ssl3.hs.rtTimeoutMs = MAX_DTLS_TIMEOUT_MS;
862 return dtls_StartTimer(ss, cb);
865 /* Cancel a pending timer
867 * Called from:
868 * dtls_HandleHandshake()
869 * dtls_CheckTimer()
871 void
872 dtls_CancelTimer(sslSocket *ss)
874 PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
876 ss->ssl3.hs.rtTimerCb = NULL;
879 /* Check the pending timer and fire the callback if it expired
881 * Called from ssl3_GatherCompleteHandshake()
883 void
884 dtls_CheckTimer(sslSocket *ss)
886 if (!ss->ssl3.hs.rtTimerCb)
887 return;
889 if ((PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted) >
890 PR_MillisecondsToInterval(ss->ssl3.hs.rtTimeoutMs)) {
891 /* Timer has expired */
892 DTLSTimerCb cb = ss->ssl3.hs.rtTimerCb;
894 /* Cancel the timer so that we can call the CB safely */
895 dtls_CancelTimer(ss);
897 /* Now call the CB */
898 cb(ss);
902 /* The callback to fire when the holddown timer for the Finished
903 * message expires and we can delete it
905 * Called from dtls_CheckTimer()
907 void
908 dtls_FinishedTimerCb(sslSocket *ss)
910 ssl3_DestroyCipherSpec(ss->ssl3.pwSpec, PR_FALSE);
913 /* Cancel the Finished hold-down timer and destroy the
914 * pending cipher spec. Note that this means that
915 * successive rehandshakes will fail if the Finished is
916 * lost.
918 * XXX OK for now. Figure out how to handle the combination
919 * of Finished lost and rehandshake
921 void
922 dtls_RehandshakeCleanup(sslSocket *ss)
924 dtls_CancelTimer(ss);
925 ssl3_DestroyCipherSpec(ss->ssl3.pwSpec, PR_FALSE);
926 ss->ssl3.hs.sendMessageSeq = 0;
927 ss->ssl3.hs.recvMessageSeq = 0;
930 /* Set the MTU to the next step less than or equal to the
931 * advertised value. Also used to downgrade the MTU by
932 * doing dtls_SetMTU(ss, biggest packet set).
934 * Passing 0 means set this to the largest MTU known
935 * (effectively resetting the PMTU backoff value).
937 * Called by:
938 * ssl3_InitState()
939 * dtls_RetransmitTimerExpiredCb()
941 void
942 dtls_SetMTU(sslSocket *ss, PRUint16 advertised)
944 int i;
946 if (advertised == 0) {
947 ss->ssl3.mtu = COMMON_MTU_VALUES[0];
948 SSL_TRC(30, ("Resetting MTU to %d", ss->ssl3.mtu));
949 return;
952 for (i = 0; i < PR_ARRAY_SIZE(COMMON_MTU_VALUES); i++) {
953 if (COMMON_MTU_VALUES[i] <= advertised) {
954 ss->ssl3.mtu = COMMON_MTU_VALUES[i];
955 SSL_TRC(30, ("Resetting MTU to %d", ss->ssl3.mtu));
956 return;
960 /* Fallback */
961 ss->ssl3.mtu = COMMON_MTU_VALUES[PR_ARRAY_SIZE(COMMON_MTU_VALUES)-1];
962 SSL_TRC(30, ("Resetting MTU to %d", ss->ssl3.mtu));
965 /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a
966 * DTLS hello_verify_request
967 * Caller must hold Handshake and RecvBuf locks.
969 SECStatus
970 dtls_HandleHelloVerifyRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
972 int errCode = SSL_ERROR_RX_MALFORMED_HELLO_VERIFY_REQUEST;
973 SECStatus rv;
974 PRInt32 temp;
975 SECItem cookie = {siBuffer, NULL, 0};
976 SSL3AlertDescription desc = illegal_parameter;
978 SSL_TRC(3, ("%d: SSL3[%d]: handle hello_verify_request handshake",
979 SSL_GETPID(), ss->fd));
980 PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
981 PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
983 if (ss->ssl3.hs.ws != wait_server_hello) {
984 errCode = SSL_ERROR_RX_UNEXPECTED_HELLO_VERIFY_REQUEST;
985 desc = unexpected_message;
986 goto alert_loser;
989 /* The version */
990 temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
991 if (temp < 0) {
992 goto loser; /* alert has been sent */
995 if (temp != SSL_LIBRARY_VERSION_DTLS_1_0_WIRE &&
996 temp != SSL_LIBRARY_VERSION_DTLS_1_2_WIRE) {
997 goto alert_loser;
1000 /* The cookie */
1001 rv = ssl3_ConsumeHandshakeVariable(ss, &cookie, 1, &b, &length);
1002 if (rv != SECSuccess) {
1003 goto loser; /* alert has been sent */
1005 if (cookie.len > DTLS_COOKIE_BYTES) {
1006 desc = decode_error;
1007 goto alert_loser; /* malformed. */
1010 PORT_Memcpy(ss->ssl3.hs.cookie, cookie.data, cookie.len);
1011 ss->ssl3.hs.cookieLen = cookie.len;
1014 ssl_GetXmitBufLock(ss); /*******************************/
1016 /* Now re-send the client hello */
1017 rv = ssl3_SendClientHello(ss, PR_TRUE);
1019 ssl_ReleaseXmitBufLock(ss); /*******************************/
1021 if (rv == SECSuccess)
1022 return rv;
1024 alert_loser:
1025 (void)SSL3_SendAlert(ss, alert_fatal, desc);
1027 loser:
1028 errCode = ssl_MapLowLevelError(errCode);
1029 return SECFailure;
1032 /* Initialize the DTLS anti-replay window
1034 * Called from:
1035 * ssl3_SetupPendingCipherSpec()
1036 * ssl3_InitCipherSpec()
1038 void
1039 dtls_InitRecvdRecords(DTLSRecvdRecords *records)
1041 PORT_Memset(records->data, 0, sizeof(records->data));
1042 records->left = 0;
1043 records->right = DTLS_RECVD_RECORDS_WINDOW - 1;
1047 * Has this DTLS record been received? Return values are:
1048 * -1 -- out of range to the left
1049 * 0 -- not received yet
1050 * 1 -- replay
1052 * Called from: dtls_HandleRecord()
1055 dtls_RecordGetRecvd(DTLSRecvdRecords *records, PRUint64 seq)
1057 PRUint64 offset;
1059 /* Out of range to the left */
1060 if (seq < records->left) {
1061 return -1;
1064 /* Out of range to the right; since we advance the window on
1065 * receipt, that means that this packet has not been received
1066 * yet */
1067 if (seq > records->right)
1068 return 0;
1070 offset = seq % DTLS_RECVD_RECORDS_WINDOW;
1072 return !!(records->data[offset / 8] & (1 << (offset % 8)));
1075 /* Update the DTLS anti-replay window
1077 * Called from ssl3_HandleRecord()
1079 void
1080 dtls_RecordSetRecvd(DTLSRecvdRecords *records, PRUint64 seq)
1082 PRUint64 offset;
1084 if (seq < records->left)
1085 return;
1087 if (seq > records->right) {
1088 PRUint64 new_left;
1089 PRUint64 new_right;
1090 PRUint64 right;
1092 /* Slide to the right; this is the tricky part
1094 * 1. new_top is set to have room for seq, on the
1095 * next byte boundary by setting the right 8
1096 * bits of seq
1097 * 2. new_left is set to compensate.
1098 * 3. Zero all bits between top and new_top. Since
1099 * this is a ring, this zeroes everything as-yet
1100 * unseen. Because we always operate on byte
1101 * boundaries, we can zero one byte at a time
1103 new_right = seq | 0x07;
1104 new_left = (new_right - DTLS_RECVD_RECORDS_WINDOW) + 1;
1106 for (right = records->right + 8; right <= new_right; right += 8) {
1107 offset = right % DTLS_RECVD_RECORDS_WINDOW;
1108 records->data[offset / 8] = 0;
1111 records->right = new_right;
1112 records->left = new_left;
1115 offset = seq % DTLS_RECVD_RECORDS_WINDOW;
1117 records->data[offset / 8] |= (1 << (offset % 8));
1120 SECStatus
1121 DTLS_GetHandshakeTimeout(PRFileDesc *socket, PRIntervalTime *timeout)
1123 sslSocket * ss = NULL;
1124 PRIntervalTime elapsed;
1125 PRIntervalTime desired;
1127 ss = ssl_FindSocket(socket);
1129 if (!ss)
1130 return SECFailure;
1132 if (!IS_DTLS(ss))
1133 return SECFailure;
1135 if (!ss->ssl3.hs.rtTimerCb)
1136 return SECFailure;
1138 elapsed = PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted;
1139 desired = PR_MillisecondsToInterval(ss->ssl3.hs.rtTimeoutMs);
1140 if (elapsed > desired) {
1141 /* Timer expired */
1142 *timeout = PR_INTERVAL_NO_WAIT;
1143 } else {
1144 *timeout = desired - elapsed;
1147 return SECSuccess;