Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(334)

Side by Side Diff: net/third_party/nss/ssl/dtlscon.c

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

Powered by Google App Engine
This is Rietveld 408576698