security/nss/lib/ssl/dtlscon.c

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

mercurial