/src/nss/lib/ssl/dtlscon.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
3 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
4 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
5 | | |
6 | | /* |
7 | | * DTLS Protocol |
8 | | */ |
9 | | |
10 | | #include "ssl.h" |
11 | | #include "sslimpl.h" |
12 | | #include "sslproto.h" |
13 | | #include "dtls13con.h" |
14 | | |
15 | | #ifndef PR_ARRAY_SIZE |
16 | | #define PR_ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) |
17 | | #endif |
18 | | |
19 | | static SECStatus dtls_StartRetransmitTimer(sslSocket *ss); |
20 | | static void dtls_RetransmitTimerExpiredCb(sslSocket *ss); |
21 | | static SECStatus dtls_SendSavedWriteData(sslSocket *ss); |
22 | | static void dtls_FinishedTimerCb(sslSocket *ss); |
23 | | static void dtls_CancelAllTimers(sslSocket *ss); |
24 | | |
25 | | /* -28 adjusts for the IP/UDP header */ |
26 | | static const PRUint16 COMMON_MTU_VALUES[] = { |
27 | | 1500 - 28, /* Ethernet MTU */ |
28 | | 1280 - 28, /* IPv6 minimum MTU */ |
29 | | 576 - 28, /* Common assumption */ |
30 | | 256 - 28 /* We're in serious trouble now */ |
31 | | }; |
32 | | |
33 | 201 | #define DTLS_COOKIE_BYTES 32 |
34 | | /* Maximum DTLS expansion = header + IV + max CBC padding + |
35 | | * maximum MAC. */ |
36 | 63.8k | #define DTLS_MAX_EXPANSION (DTLS_RECORD_HEADER_LENGTH + 16 + 16 + 32) |
37 | | |
38 | | /* List copied from ssl3con.c:cipherSuites */ |
39 | | static const ssl3CipherSuite nonDTLSSuites[] = { |
40 | | TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, |
41 | | TLS_ECDHE_RSA_WITH_RC4_128_SHA, |
42 | | TLS_DHE_DSS_WITH_RC4_128_SHA, |
43 | | TLS_ECDH_RSA_WITH_RC4_128_SHA, |
44 | | TLS_ECDH_ECDSA_WITH_RC4_128_SHA, |
45 | | TLS_RSA_WITH_RC4_128_MD5, |
46 | | TLS_RSA_WITH_RC4_128_SHA, |
47 | | 0 /* End of list marker */ |
48 | | }; |
49 | | |
50 | | /* Map back and forth between TLS and DTLS versions in wire format. |
51 | | * Mapping table is: |
52 | | * |
53 | | * TLS DTLS |
54 | | * 1.1 (0302) 1.0 (feff) |
55 | | * 1.2 (0303) 1.2 (fefd) |
56 | | * 1.3 (0304) 1.3 (fefc) |
57 | | */ |
58 | | SSL3ProtocolVersion |
59 | | dtls_TLSVersionToDTLSVersion(SSL3ProtocolVersion tlsv) |
60 | 52.0k | { |
61 | 52.0k | if (tlsv == SSL_LIBRARY_VERSION_TLS_1_1) { |
62 | 2.87k | return SSL_LIBRARY_VERSION_DTLS_1_0_WIRE; |
63 | 2.87k | } |
64 | 49.1k | if (tlsv == SSL_LIBRARY_VERSION_TLS_1_2) { |
65 | 47.0k | return SSL_LIBRARY_VERSION_DTLS_1_2_WIRE; |
66 | 47.0k | } |
67 | 2.13k | if (tlsv == SSL_LIBRARY_VERSION_TLS_1_3) { |
68 | 2.06k | return SSL_LIBRARY_VERSION_DTLS_1_3_WIRE; |
69 | 2.06k | } |
70 | | |
71 | | /* Anything else is an error, so return |
72 | | * the invalid version 0xffff. */ |
73 | 72 | return 0xffff; |
74 | 2.13k | } |
75 | | |
76 | | /* Map known DTLS versions to known TLS versions. |
77 | | * - Invalid versions (< 1.0) return a version of 0 |
78 | | * - Versions > known return a version one higher than we know of |
79 | | * to accomodate a theoretically newer version */ |
80 | | SSL3ProtocolVersion |
81 | | dtls_DTLSVersionToTLSVersion(SSL3ProtocolVersion dtlsv) |
82 | 17.8k | { |
83 | 17.8k | if (MSB(dtlsv) == 0xff) { |
84 | 106 | return 0; |
85 | 106 | } |
86 | | |
87 | 17.7k | if (dtlsv == SSL_LIBRARY_VERSION_DTLS_1_0_WIRE) { |
88 | 481 | return SSL_LIBRARY_VERSION_TLS_1_1; |
89 | 481 | } |
90 | | /* Handle the skipped version of DTLS 1.1 by returning |
91 | | * an error. */ |
92 | 17.3k | if (dtlsv == ((~0x0101) & 0xffff)) { |
93 | 12 | return 0; |
94 | 12 | } |
95 | 17.2k | if (dtlsv == SSL_LIBRARY_VERSION_DTLS_1_2_WIRE) { |
96 | 12.9k | return SSL_LIBRARY_VERSION_TLS_1_2; |
97 | 12.9k | } |
98 | 4.38k | if (dtlsv == SSL_LIBRARY_VERSION_DTLS_1_3_WIRE) { |
99 | 24 | return SSL_LIBRARY_VERSION_TLS_1_3; |
100 | 24 | } |
101 | | |
102 | | /* Return a fictional higher version than we know of */ |
103 | 4.35k | return SSL_LIBRARY_VERSION_MAX_SUPPORTED + 1; |
104 | 4.38k | } |
105 | | |
106 | | /* On this socket, Disable non-DTLS cipher suites in the argument's list */ |
107 | | SECStatus |
108 | | ssl3_DisableNonDTLSSuites(sslSocket *ss) |
109 | 13.7k | { |
110 | 13.7k | const ssl3CipherSuite *suite; |
111 | | |
112 | 109k | for (suite = nonDTLSSuites; *suite; ++suite) { |
113 | 96.0k | PORT_CheckSuccess(ssl3_CipherPrefSet(ss, *suite, PR_FALSE)); |
114 | 96.0k | } |
115 | 13.7k | return SECSuccess; |
116 | 13.7k | } |
117 | | |
118 | | /* Allocate a DTLSQueuedMessage. |
119 | | * |
120 | | * Called from dtls_QueueMessage() |
121 | | */ |
122 | | static DTLSQueuedMessage * |
123 | | dtls_AllocQueuedMessage(ssl3CipherSpec *cwSpec, SSLContentType ct, |
124 | | const unsigned char *data, PRUint32 len) |
125 | 39.0k | { |
126 | 39.0k | DTLSQueuedMessage *msg; |
127 | | |
128 | 39.0k | msg = PORT_ZNew(DTLSQueuedMessage); |
129 | 39.0k | if (!msg) |
130 | 0 | return NULL; |
131 | | |
132 | 39.0k | msg->data = PORT_Alloc(len); |
133 | 39.0k | if (!msg->data) { |
134 | 0 | PORT_Free(msg); |
135 | 0 | return NULL; |
136 | 0 | } |
137 | 39.0k | PORT_Memcpy(msg->data, data, len); |
138 | | |
139 | 39.0k | msg->len = len; |
140 | 39.0k | msg->cwSpec = cwSpec; |
141 | 39.0k | msg->type = ct; |
142 | | /* Safe if we are < 1.3, since the refct is |
143 | | * already very high. */ |
144 | 39.0k | ssl_CipherSpecAddRef(cwSpec); |
145 | | |
146 | 39.0k | return msg; |
147 | 39.0k | } |
148 | | |
149 | | /* |
150 | | * Free a handshake message |
151 | | * |
152 | | * Called from dtls_FreeHandshakeMessages() |
153 | | */ |
154 | | void |
155 | | dtls_FreeHandshakeMessage(DTLSQueuedMessage *msg) |
156 | 39.0k | { |
157 | 39.0k | if (!msg) |
158 | 0 | return; |
159 | | |
160 | | /* Safe if we are < 1.3, since the refct is |
161 | | * already very high. */ |
162 | 39.0k | ssl_CipherSpecRelease(msg->cwSpec); |
163 | 39.0k | PORT_ZFree(msg->data, msg->len); |
164 | 39.0k | PORT_Free(msg); |
165 | 39.0k | } |
166 | | |
167 | | /* |
168 | | * Free a list of handshake messages |
169 | | * |
170 | | * Called from: |
171 | | * dtls_HandleHandshake() |
172 | | * ssl3_DestroySSL3Info() |
173 | | */ |
174 | | void |
175 | | dtls_FreeHandshakeMessages(PRCList *list) |
176 | 38.2k | { |
177 | 38.2k | PRCList *cur_p; |
178 | | |
179 | 77.2k | while (!PR_CLIST_IS_EMPTY(list)) { |
180 | 38.9k | cur_p = PR_LIST_TAIL(list); |
181 | 38.9k | PR_REMOVE_LINK(cur_p); |
182 | 38.9k | dtls_FreeHandshakeMessage((DTLSQueuedMessage *)cur_p); |
183 | 38.9k | } |
184 | 38.2k | } |
185 | | |
186 | | /* Called by dtls_HandleHandshake() and dtls_MaybeRetransmitHandshake() if a |
187 | | * handshake message retransmission is detected. */ |
188 | | static SECStatus |
189 | | dtls_RetransmitDetected(sslSocket *ss) |
190 | 604 | { |
191 | 604 | dtlsTimer *rtTimer = ss->ssl3.hs.rtTimer; |
192 | 604 | dtlsTimer *hdTimer = ss->ssl3.hs.hdTimer; |
193 | 604 | SECStatus rv = SECSuccess; |
194 | | |
195 | 604 | PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); |
196 | 604 | PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); |
197 | | |
198 | 604 | if (rtTimer->cb == dtls_RetransmitTimerExpiredCb) { |
199 | | /* Check to see if we retransmitted recently. If so, |
200 | | * suppress the triggered retransmit. This avoids |
201 | | * retransmit wars after packet loss. |
202 | | * This is not in RFC 5346 but it should be. |
203 | | */ |
204 | 285 | if ((PR_IntervalNow() - rtTimer->started) > |
205 | 285 | (rtTimer->timeout / 4)) { |
206 | 2 | SSL_TRC(30, |
207 | 2 | ("%d: SSL3[%d]: Shortcutting retransmit timer", |
208 | 2 | SSL_GETPID(), ss->fd)); |
209 | | |
210 | | /* Cancel the timer and call the CB, |
211 | | * which re-arms the timer */ |
212 | 2 | dtls_CancelTimer(ss, ss->ssl3.hs.rtTimer); |
213 | 2 | dtls_RetransmitTimerExpiredCb(ss); |
214 | 283 | } else { |
215 | 283 | SSL_TRC(30, |
216 | 283 | ("%d: SSL3[%d]: Ignoring retransmission: " |
217 | 283 | "last retransmission %dms ago, suppressed for %dms", |
218 | 283 | SSL_GETPID(), ss->fd, |
219 | 283 | PR_IntervalNow() - rtTimer->started, |
220 | 283 | rtTimer->timeout / 4)); |
221 | 283 | } |
222 | 319 | } else if (hdTimer->cb == dtls_FinishedTimerCb) { |
223 | 0 | SSL_TRC(30, ("%d: SSL3[%d]: Retransmit detected in holddown", |
224 | 0 | SSL_GETPID(), ss->fd)); |
225 | | /* Retransmit the messages and re-arm the timer |
226 | | * Note that we are not backing off the timer here. |
227 | | * The spec isn't clear and my reasoning is that this |
228 | | * may be a re-ordered packet rather than slowness, |
229 | | * so let's be aggressive. */ |
230 | 0 | dtls_CancelTimer(ss, ss->ssl3.hs.hdTimer); |
231 | 0 | rv = dtls_TransmitMessageFlight(ss); |
232 | 0 | if (rv == SECSuccess) { |
233 | 0 | rv = dtls_StartHolddownTimer(ss); |
234 | 0 | } |
235 | 319 | } else { |
236 | | /* Otherwise handled in dtls13_HandleOutOfEpochRecord. */ |
237 | 319 | if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { |
238 | 316 | PORT_Assert(hdTimer->cb == NULL); |
239 | 316 | } |
240 | | |
241 | 319 | PORT_Assert(rtTimer->cb == NULL); |
242 | | /* ... and ignore it. */ |
243 | 319 | } |
244 | 604 | return rv; |
245 | 604 | } |
246 | | |
247 | | static SECStatus |
248 | | dtls_HandleHandshakeMessage(sslSocket *ss, PRUint8 *data, PRBool last) |
249 | 32.5k | { |
250 | 32.5k | ss->ssl3.hs.recvdHighWater = -1; |
251 | | |
252 | 32.5k | return ssl3_HandleHandshakeMessage(ss, data, ss->ssl3.hs.msg_len, |
253 | 32.5k | last); |
254 | 32.5k | } |
255 | | |
256 | | /* Called only from ssl3_HandleRecord, for each (deciphered) DTLS record. |
257 | | * origBuf is the decrypted ssl record content and is expected to contain |
258 | | * complete handshake records |
259 | | * Caller must hold the handshake and RecvBuf locks. |
260 | | * |
261 | | * Note that this code uses msg_len for two purposes: |
262 | | * |
263 | | * (1) To pass the length to ssl3_HandleHandshakeMessage() |
264 | | * (2) To carry the length of a message currently being reassembled |
265 | | * |
266 | | * However, unlike ssl3_HandleHandshake(), it is not used to carry |
267 | | * the state of reassembly (i.e., whether one is in progress). That |
268 | | * is carried in recvdHighWater and recvdFragments. |
269 | | */ |
270 | 250k | #define OFFSET_BYTE(o) (o / 8) |
271 | 249k | #define OFFSET_MASK(o) (1 << (o % 8)) |
272 | | |
273 | | SECStatus |
274 | | dtls_HandleHandshake(sslSocket *ss, DTLSEpoch epoch, sslSequenceNumber seqNum, |
275 | | sslBuffer *origBuf) |
276 | 39.4k | { |
277 | 39.4k | sslBuffer buf = *origBuf; |
278 | 39.4k | SECStatus rv = SECSuccess; |
279 | 39.4k | PRBool discarded = PR_FALSE; |
280 | | |
281 | 39.4k | ss->ssl3.hs.endOfFlight = PR_FALSE; |
282 | | |
283 | 39.4k | PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); |
284 | 39.4k | PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); |
285 | | |
286 | 69.7k | while (buf.len > 0) { |
287 | 36.5k | PRUint8 type; |
288 | 36.5k | PRUint32 message_length; |
289 | 36.5k | PRUint16 message_seq; |
290 | 36.5k | PRUint32 fragment_offset; |
291 | 36.5k | PRUint32 fragment_length; |
292 | 36.5k | PRUint32 offset; |
293 | | |
294 | 36.5k | if (buf.len < 12) { |
295 | 79 | PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE); |
296 | 79 | rv = SECFailure; |
297 | 79 | goto loser; |
298 | 79 | } |
299 | | |
300 | | /* Parse the header */ |
301 | 36.5k | type = buf.buf[0]; |
302 | 36.5k | message_length = (buf.buf[1] << 16) | (buf.buf[2] << 8) | buf.buf[3]; |
303 | 36.5k | message_seq = (buf.buf[4] << 8) | buf.buf[5]; |
304 | 36.5k | fragment_offset = (buf.buf[6] << 16) | (buf.buf[7] << 8) | buf.buf[8]; |
305 | 36.5k | fragment_length = (buf.buf[9] << 16) | (buf.buf[10] << 8) | buf.buf[11]; |
306 | | |
307 | 36.5k | #define MAX_HANDSHAKE_MSG_LEN 0x1ffff /* 128k - 1 */ |
308 | 36.5k | if (message_length > MAX_HANDSHAKE_MSG_LEN) { |
309 | 61 | (void)ssl3_DecodeError(ss); |
310 | 61 | PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE); |
311 | 61 | rv = SECFailure; |
312 | 61 | goto loser; |
313 | 61 | } |
314 | 36.4k | #undef MAX_HANDSHAKE_MSG_LEN |
315 | | |
316 | 36.4k | buf.buf += 12; |
317 | 36.4k | buf.len -= 12; |
318 | | |
319 | | /* This fragment must be complete */ |
320 | 36.4k | if (buf.len < fragment_length) { |
321 | 64 | PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE); |
322 | 64 | rv = SECFailure; |
323 | 64 | goto loser; |
324 | 64 | } |
325 | | |
326 | | /* Sanity check the packet contents */ |
327 | 36.3k | if ((fragment_length + fragment_offset) > message_length) { |
328 | 65 | PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE); |
329 | 65 | rv = SECFailure; |
330 | 65 | goto loser; |
331 | 65 | } |
332 | | |
333 | | /* If we're a server and we receive what appears to be a retried |
334 | | * ClientHello, and we are expecting a ClientHello, move the receive |
335 | | * sequence number forward. This allows for a retried ClientHello if we |
336 | | * send a stateless HelloRetryRequest. */ |
337 | 36.3k | if (message_seq > ss->ssl3.hs.recvMessageSeq && |
338 | 36.3k | message_seq == 1 && |
339 | 36.3k | fragment_offset == 0 && |
340 | 36.3k | ss->ssl3.hs.ws == wait_client_hello && |
341 | 36.3k | (SSLHandshakeType)type == ssl_hs_client_hello) { |
342 | 52 | SSL_TRC(5, ("%d: DTLS[%d]: Received apparent 2nd ClientHello", |
343 | 52 | SSL_GETPID(), ss->fd)); |
344 | 52 | ss->ssl3.hs.recvMessageSeq = 1; |
345 | 52 | ss->ssl3.hs.helloRetry = PR_TRUE; |
346 | 52 | } |
347 | | |
348 | | /* There are three ways we could not be ready for this packet. |
349 | | * |
350 | | * 1. It's a partial next message. |
351 | | * 2. It's a partial or complete message beyond the next |
352 | | * 3. It's a message we've already seen |
353 | | * |
354 | | * If it's the complete next message we accept it right away. |
355 | | * This is the common case for short messages |
356 | | */ |
357 | 36.3k | if ((message_seq == ss->ssl3.hs.recvMessageSeq) && |
358 | 36.3k | (fragment_offset == 0) && |
359 | 36.3k | (fragment_length == message_length)) { |
360 | | /* Complete next message. Process immediately */ |
361 | 31.9k | ss->ssl3.hs.msg_type = (SSLHandshakeType)type; |
362 | 31.9k | ss->ssl3.hs.msg_len = message_length; |
363 | | |
364 | 31.9k | rv = dtls_HandleHandshakeMessage(ss, buf.buf, |
365 | 31.9k | buf.len == fragment_length); |
366 | 31.9k | if (rv != SECSuccess) { |
367 | 5.30k | goto loser; |
368 | 5.30k | } |
369 | 31.9k | } else { |
370 | 4.40k | if (message_seq < ss->ssl3.hs.recvMessageSeq) { |
371 | | /* Case 3: we do an immediate retransmit if we're |
372 | | * in a waiting state. */ |
373 | 604 | rv = dtls_RetransmitDetected(ss); |
374 | 604 | goto loser; |
375 | 3.80k | } else if (message_seq > ss->ssl3.hs.recvMessageSeq) { |
376 | | /* Case 2 |
377 | | * |
378 | | * Ignore this message. This means we don't handle out of |
379 | | * order complete messages that well, but we're still |
380 | | * compliant and this probably does not happen often |
381 | | * |
382 | | * XXX OK for now. Maybe do something smarter at some point? |
383 | | */ |
384 | 905 | SSL_TRC(10, ("%d: SSL3[%d]: dtls_HandleHandshake, discarding handshake message", |
385 | 905 | SSL_GETPID(), ss->fd)); |
386 | 905 | discarded = PR_TRUE; |
387 | 2.90k | } else { |
388 | 2.90k | PRInt32 end = fragment_offset + fragment_length; |
389 | | |
390 | | /* Case 1 |
391 | | * |
392 | | * Buffer the fragment for reassembly |
393 | | */ |
394 | | /* Make room for the message */ |
395 | 2.90k | if (ss->ssl3.hs.recvdHighWater == -1) { |
396 | 1.00k | PRUint32 map_length = OFFSET_BYTE(message_length) + 1; |
397 | | |
398 | 1.00k | rv = sslBuffer_Grow(&ss->ssl3.hs.msg_body, message_length); |
399 | 1.00k | if (rv != SECSuccess) |
400 | 0 | goto loser; |
401 | | /* Make room for the fragment map */ |
402 | 1.00k | rv = sslBuffer_Grow(&ss->ssl3.hs.recvdFragments, |
403 | 1.00k | map_length); |
404 | 1.00k | if (rv != SECSuccess) |
405 | 0 | goto loser; |
406 | | |
407 | | /* Reset the reassembly map */ |
408 | 1.00k | ss->ssl3.hs.recvdHighWater = 0; |
409 | 1.00k | PORT_Memset(ss->ssl3.hs.recvdFragments.buf, 0, |
410 | 1.00k | ss->ssl3.hs.recvdFragments.space); |
411 | 1.00k | ss->ssl3.hs.msg_type = (SSLHandshakeType)type; |
412 | 1.00k | ss->ssl3.hs.msg_len = message_length; |
413 | 1.00k | } |
414 | | |
415 | | /* If we have a message length mismatch, abandon the reassembly |
416 | | * in progress and hope that the next retransmit will give us |
417 | | * something sane |
418 | | */ |
419 | 2.90k | if (message_length != ss->ssl3.hs.msg_len) { |
420 | 56 | ss->ssl3.hs.recvdHighWater = -1; |
421 | 56 | PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE); |
422 | 56 | rv = SECFailure; |
423 | 56 | goto loser; |
424 | 56 | } |
425 | | |
426 | | /* Now copy this fragment into the buffer. */ |
427 | 2.84k | if (end > ss->ssl3.hs.recvdHighWater) { |
428 | 2.31k | PORT_Memcpy(ss->ssl3.hs.msg_body.buf + fragment_offset, |
429 | 2.31k | buf.buf, fragment_length); |
430 | 2.31k | } |
431 | | |
432 | | /* This logic is a bit tricky. We have two values for |
433 | | * reassembly state: |
434 | | * |
435 | | * - recvdHighWater contains the highest contiguous number of |
436 | | * bytes received |
437 | | * - recvdFragments contains a bitmask of packets received |
438 | | * above recvdHighWater |
439 | | * |
440 | | * This avoids having to fill in the bitmask in the common |
441 | | * case of adjacent fragments received in sequence |
442 | | */ |
443 | 2.84k | if (fragment_offset <= (unsigned int)ss->ssl3.hs.recvdHighWater) { |
444 | | /* Either this is the adjacent fragment or an overlapping |
445 | | * fragment */ |
446 | 1.51k | if (end > ss->ssl3.hs.recvdHighWater) { |
447 | 976 | ss->ssl3.hs.recvdHighWater = end; |
448 | 976 | } |
449 | 1.51k | } else { |
450 | 137k | for (offset = fragment_offset; offset < end; offset++) { |
451 | 136k | ss->ssl3.hs.recvdFragments.buf[OFFSET_BYTE(offset)] |= |
452 | 136k | OFFSET_MASK(offset); |
453 | 136k | } |
454 | 1.33k | } |
455 | | |
456 | | /* Now figure out the new high water mark if appropriate */ |
457 | 2.84k | for (offset = ss->ssl3.hs.recvdHighWater; |
458 | 113k | offset < ss->ssl3.hs.msg_len; offset++) { |
459 | | /* Note that this loop is not efficient, since it counts |
460 | | * bit by bit. If we have a lot of out-of-order packets, |
461 | | * we should optimize this */ |
462 | 112k | if (ss->ssl3.hs.recvdFragments.buf[OFFSET_BYTE(offset)] & |
463 | 112k | OFFSET_MASK(offset)) { |
464 | 110k | ss->ssl3.hs.recvdHighWater++; |
465 | 110k | } else { |
466 | 2.22k | break; |
467 | 2.22k | } |
468 | 112k | } |
469 | | |
470 | | /* If we have all the bytes, then we are good to go */ |
471 | 2.84k | if (ss->ssl3.hs.recvdHighWater == ss->ssl3.hs.msg_len) { |
472 | 620 | rv = dtls_HandleHandshakeMessage(ss, ss->ssl3.hs.msg_body.buf, |
473 | 620 | buf.len == fragment_length); |
474 | | |
475 | 620 | if (rv != SECSuccess) { |
476 | 56 | goto loser; |
477 | 56 | } |
478 | 620 | } |
479 | 2.84k | } |
480 | 4.40k | } |
481 | | |
482 | 30.2k | buf.buf += fragment_length; |
483 | 30.2k | buf.len -= fragment_length; |
484 | 30.2k | } |
485 | | |
486 | | // This should never happen, but belt and suspenders. |
487 | 33.1k | if (rv != SECSuccess) { |
488 | 0 | PORT_Assert(0); |
489 | 0 | goto loser; |
490 | 0 | } |
491 | | |
492 | | /* If we processed all the fragments in this message, then mark it as remembered. |
493 | | * TODO(ekr@rtfm.com): Store out of order messages for DTLS 1.3 so ACKs work |
494 | | * better. Bug 1392620.*/ |
495 | 33.1k | if (!discarded && tls13_MaybeTls13(ss)) { |
496 | 2.21k | rv = dtls13_RememberFragment(ss, &ss->ssl3.hs.dtlsRcvdHandshake, |
497 | 2.21k | 0, 0, 0, epoch, seqNum); |
498 | 2.21k | } |
499 | 33.1k | if (rv != SECSuccess) { |
500 | 0 | goto loser; |
501 | 0 | } |
502 | 33.1k | rv = dtls13_SetupAcks(ss); |
503 | | |
504 | 39.4k | loser: |
505 | 39.4k | origBuf->len = 0; /* So ssl3_GatherAppDataRecord will keep looping. */ |
506 | 39.4k | return rv; |
507 | 33.1k | } |
508 | | |
509 | | /* Enqueue a message (either handshake or CCS) |
510 | | * |
511 | | * Called from: |
512 | | * dtls_StageHandshakeMessage() |
513 | | * ssl3_SendChangeCipherSpecs() |
514 | | */ |
515 | | SECStatus |
516 | | dtls_QueueMessage(sslSocket *ss, SSLContentType ct, |
517 | | const PRUint8 *pIn, PRInt32 nIn) |
518 | 39.0k | { |
519 | 39.0k | SECStatus rv = SECSuccess; |
520 | 39.0k | DTLSQueuedMessage *msg = NULL; |
521 | 39.0k | ssl3CipherSpec *spec; |
522 | | |
523 | 39.0k | PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); |
524 | 39.0k | PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); |
525 | | |
526 | 39.0k | spec = ss->ssl3.cwSpec; |
527 | 39.0k | msg = dtls_AllocQueuedMessage(spec, ct, pIn, nIn); |
528 | | |
529 | 39.0k | if (!msg) { |
530 | 0 | PORT_SetError(SEC_ERROR_NO_MEMORY); |
531 | 0 | rv = SECFailure; |
532 | 39.0k | } else { |
533 | 39.0k | PR_APPEND_LINK(&msg->link, &ss->ssl3.hs.lastMessageFlight); |
534 | 39.0k | } |
535 | | |
536 | 39.0k | return rv; |
537 | 39.0k | } |
538 | | |
539 | | /* Add DTLS handshake message to the pending queue |
540 | | * Empty the sendBuf buffer. |
541 | | * Always set sendBuf.len to 0, even when returning SECFailure. |
542 | | * |
543 | | * Called from: |
544 | | * ssl3_AppendHandshakeHeader() |
545 | | * dtls_FlushHandshake() |
546 | | */ |
547 | | SECStatus |
548 | | dtls_StageHandshakeMessage(sslSocket *ss) |
549 | 61.5k | { |
550 | 61.5k | SECStatus rv = SECSuccess; |
551 | | |
552 | 61.5k | PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); |
553 | 61.5k | PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); |
554 | | |
555 | | /* This function is sometimes called when no data is actually to |
556 | | * be staged, so just return SECSuccess. */ |
557 | 61.5k | if (!ss->sec.ci.sendBuf.buf || !ss->sec.ci.sendBuf.len) |
558 | 23.6k | return rv; |
559 | | |
560 | 37.9k | rv = dtls_QueueMessage(ss, ssl_ct_handshake, |
561 | 37.9k | ss->sec.ci.sendBuf.buf, ss->sec.ci.sendBuf.len); |
562 | | |
563 | | /* Whether we succeeded or failed, toss the old handshake data. */ |
564 | 37.9k | ss->sec.ci.sendBuf.len = 0; |
565 | 37.9k | return rv; |
566 | 61.5k | } |
567 | | |
568 | | /* Enqueue the handshake message in sendBuf (if any) and then |
569 | | * transmit the resulting flight of handshake messages. |
570 | | * |
571 | | * Called from: |
572 | | * ssl3_FlushHandshake() |
573 | | */ |
574 | | SECStatus |
575 | | dtls_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags) |
576 | 23.6k | { |
577 | 23.6k | SECStatus rv = SECSuccess; |
578 | | |
579 | 23.6k | PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); |
580 | 23.6k | PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); |
581 | | |
582 | 23.6k | rv = dtls_StageHandshakeMessage(ss); |
583 | 23.6k | if (rv != SECSuccess) { |
584 | 0 | return rv; |
585 | 0 | } |
586 | | |
587 | 23.6k | if (!(flags & ssl_SEND_FLAG_FORCE_INTO_BUFFER)) { |
588 | 14.7k | rv = dtls_TransmitMessageFlight(ss); |
589 | 14.7k | if (rv != SECSuccess) { |
590 | 0 | return rv; |
591 | 0 | } |
592 | | |
593 | 14.7k | if (!(flags & ssl_SEND_FLAG_NO_RETRANSMIT)) { |
594 | 14.7k | rv = dtls_StartRetransmitTimer(ss); |
595 | 14.7k | } else { |
596 | 0 | PORT_Assert(ss->version < SSL_LIBRARY_VERSION_TLS_1_3); |
597 | 0 | } |
598 | 14.7k | } |
599 | | |
600 | 23.6k | return rv; |
601 | 23.6k | } |
602 | | |
603 | | /* The callback for when the retransmit timer expires |
604 | | * |
605 | | * Called from: |
606 | | * dtls_CheckTimer() |
607 | | * dtls_HandleHandshake() |
608 | | */ |
609 | | static void |
610 | | dtls_RetransmitTimerExpiredCb(sslSocket *ss) |
611 | 2 | { |
612 | 2 | SECStatus rv; |
613 | 2 | dtlsTimer *timer = ss->ssl3.hs.rtTimer; |
614 | 2 | ss->ssl3.hs.rtRetries++; |
615 | | |
616 | 2 | if (!(ss->ssl3.hs.rtRetries % 3)) { |
617 | | /* If one of the messages was potentially greater than > MTU, |
618 | | * then downgrade. Do this every time we have retransmitted a |
619 | | * message twice, per RFC 9147 Sec. 4.4 */ |
620 | 0 | dtls_SetMTU(ss, ss->ssl3.hs.maxMessageSent - 1); |
621 | 0 | } |
622 | | |
623 | 2 | rv = dtls_TransmitMessageFlight(ss); |
624 | 2 | if (rv == SECSuccess) { |
625 | | /* Re-arm the timer */ |
626 | 2 | timer->timeout *= 2; |
627 | 2 | if (timer->timeout > DTLS_RETRANSMIT_MAX_MS) { |
628 | 0 | timer->timeout = DTLS_RETRANSMIT_MAX_MS; |
629 | 0 | } |
630 | | |
631 | 2 | timer->started = PR_IntervalNow(); |
632 | 2 | timer->cb = dtls_RetransmitTimerExpiredCb; |
633 | | |
634 | 2 | SSL_TRC(30, |
635 | 2 | ("%d: SSL3[%d]: Retransmit #%d, next in %d", |
636 | 2 | SSL_GETPID(), ss->fd, |
637 | 2 | ss->ssl3.hs.rtRetries, timer->timeout)); |
638 | 2 | } |
639 | | /* else: OK for now. In future maybe signal the stack that we couldn't |
640 | | * transmit. For now, let the read handle any real network errors */ |
641 | 2 | } |
642 | | |
643 | 272k | #define DTLS_HS_HDR_LEN 12 |
644 | 63.8k | #define DTLS_MIN_FRAGMENT (DTLS_HS_HDR_LEN + 1 + DTLS_MAX_EXPANSION) |
645 | | |
646 | | /* Encrypt and encode a handshake message fragment. Flush the data out to the |
647 | | * network if there is insufficient space for any fragment. */ |
648 | | static SECStatus |
649 | | dtls_SendFragment(sslSocket *ss, DTLSQueuedMessage *msg, PRUint8 *data, |
650 | | unsigned int len) |
651 | 63.8k | { |
652 | 63.8k | PRInt32 sent; |
653 | 63.8k | SECStatus rv; |
654 | | |
655 | 63.8k | PRINT_BUF(40, (ss, "dtls_SendFragment", data, len)); |
656 | 63.8k | sent = ssl3_SendRecord(ss, msg->cwSpec, msg->type, data, len, |
657 | 63.8k | ssl_SEND_FLAG_FORCE_INTO_BUFFER); |
658 | 63.8k | if (sent != len) { |
659 | 0 | if (sent != -1) { |
660 | 0 | PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
661 | 0 | } |
662 | 0 | return SECFailure; |
663 | 0 | } |
664 | | |
665 | | /* If another fragment won't fit, flush. */ |
666 | 63.8k | if (ss->ssl3.mtu < ss->pendingBuf.len + DTLS_MIN_FRAGMENT) { |
667 | 5.03k | SSL_TRC(20, ("%d: DTLS[%d]: dtls_SendFragment: flush", |
668 | 5.03k | SSL_GETPID(), ss->fd)); |
669 | 5.03k | rv = dtls_SendSavedWriteData(ss); |
670 | 5.03k | if (rv != SECSuccess) { |
671 | 0 | return SECFailure; |
672 | 0 | } |
673 | 5.03k | } |
674 | 63.8k | return SECSuccess; |
675 | 63.8k | } |
676 | | |
677 | | /* Fragment a handshake message into multiple records and send them. */ |
678 | | static SECStatus |
679 | | dtls_FragmentHandshake(sslSocket *ss, DTLSQueuedMessage *msg) |
680 | 41.6k | { |
681 | 41.6k | PRBool fragmentWritten = PR_FALSE; |
682 | 41.6k | PRUint16 msgSeq; |
683 | 41.6k | PRUint8 *fragment; |
684 | 41.6k | PRUint32 fragmentOffset = 0; |
685 | 41.6k | PRUint32 fragmentLen; |
686 | 41.6k | const PRUint8 *content = msg->data + DTLS_HS_HDR_LEN; |
687 | 41.6k | PRUint32 contentLen = msg->len - DTLS_HS_HDR_LEN; |
688 | 41.6k | SECStatus rv; |
689 | | |
690 | | /* The headers consume 12 bytes so the smallest possible message (i.e., an |
691 | | * empty one) is 12 bytes. */ |
692 | 41.6k | PORT_Assert(msg->len >= DTLS_HS_HDR_LEN); |
693 | | |
694 | | /* DTLS only supports fragmenting handshaking messages. */ |
695 | 41.6k | PORT_Assert(msg->type == ssl_ct_handshake); |
696 | | |
697 | 41.6k | msgSeq = (msg->data[4] << 8) | msg->data[5]; |
698 | | |
699 | | /* do {} while() so that empty messages are sent at least once. */ |
700 | 62.8k | do { |
701 | 62.8k | PRUint8 buf[DTLS_MAX_MTU]; /* >= than largest plausible MTU */ |
702 | 62.8k | PRBool hasUnackedRange; |
703 | 62.8k | PRUint32 end; |
704 | | |
705 | 62.8k | hasUnackedRange = dtls_NextUnackedRange(ss, msgSeq, |
706 | 62.8k | fragmentOffset, contentLen, |
707 | 62.8k | &fragmentOffset, &end); |
708 | 62.8k | if (!hasUnackedRange) { |
709 | 160 | SSL_TRC(20, ("%d: SSL3[%d]: FragmentHandshake %d: all acknowledged", |
710 | 160 | SSL_GETPID(), ss->fd, msgSeq)); |
711 | 160 | break; |
712 | 160 | } |
713 | | |
714 | 62.7k | SSL_TRC(20, ("%d: SSL3[%d]: FragmentHandshake %d: unacked=%u-%u", |
715 | 62.7k | SSL_GETPID(), ss->fd, msgSeq, fragmentOffset, end)); |
716 | | |
717 | | /* Cut down to the data we have available. */ |
718 | 62.7k | PORT_Assert(fragmentOffset <= contentLen); |
719 | 62.7k | PORT_Assert(fragmentOffset <= end); |
720 | 62.7k | PORT_Assert(end <= contentLen); |
721 | 62.7k | fragmentLen = PR_MIN(end, contentLen) - fragmentOffset; |
722 | | |
723 | | /* Limit further by the record size limit. Account for the header. */ |
724 | 62.7k | fragmentLen = PR_MIN(fragmentLen, |
725 | 62.7k | msg->cwSpec->recordSizeLimit - DTLS_HS_HDR_LEN); |
726 | | |
727 | | /* Reduce to the space remaining in the MTU. */ |
728 | 62.7k | fragmentLen = PR_MIN(fragmentLen, |
729 | 62.7k | ss->ssl3.mtu - /* MTU estimate. */ |
730 | 62.7k | ss->pendingBuf.len - /* Less any unsent records. */ |
731 | 62.7k | DTLS_MAX_EXPANSION - /* Allow for expansion. */ |
732 | 62.7k | DTLS_HS_HDR_LEN); /* And the handshake header. */ |
733 | 62.7k | PORT_Assert(fragmentLen > 0 || fragmentOffset == 0); |
734 | | |
735 | | /* Make totally sure that we will fit in the buffer. This should be |
736 | | * impossible; DTLS_MAX_MTU should always be more than ss->ssl3.mtu. */ |
737 | 62.7k | if (fragmentLen >= (DTLS_MAX_MTU - DTLS_HS_HDR_LEN)) { |
738 | 0 | PORT_Assert(0); |
739 | 0 | PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
740 | 0 | return SECFailure; |
741 | 0 | } |
742 | | |
743 | 62.7k | if (fragmentLen == contentLen) { |
744 | 36.1k | fragment = msg->data; |
745 | 36.1k | } else { |
746 | 26.6k | sslBuffer tmp = SSL_BUFFER_FIXED(buf, sizeof(buf)); |
747 | | |
748 | | /* Construct an appropriate-sized fragment */ |
749 | | /* Type, length, sequence */ |
750 | 26.6k | rv = sslBuffer_Append(&tmp, msg->data, 6); |
751 | 26.6k | if (rv != SECSuccess) { |
752 | 0 | return SECFailure; |
753 | 0 | } |
754 | | /* Offset. */ |
755 | 26.6k | rv = sslBuffer_AppendNumber(&tmp, fragmentOffset, 3); |
756 | 26.6k | if (rv != SECSuccess) { |
757 | 0 | return SECFailure; |
758 | 0 | } |
759 | | /* Length. */ |
760 | 26.6k | rv = sslBuffer_AppendNumber(&tmp, fragmentLen, 3); |
761 | 26.6k | if (rv != SECSuccess) { |
762 | 0 | return SECFailure; |
763 | 0 | } |
764 | | /* Data. */ |
765 | 26.6k | rv = sslBuffer_Append(&tmp, content + fragmentOffset, fragmentLen); |
766 | 26.6k | if (rv != SECSuccess) { |
767 | 0 | return SECFailure; |
768 | 0 | } |
769 | | |
770 | 26.6k | fragment = SSL_BUFFER_BASE(&tmp); |
771 | 26.6k | } |
772 | | |
773 | | /* Record that we are sending first, because encrypting |
774 | | * increments the sequence number. */ |
775 | 62.7k | rv = dtls13_RememberFragment(ss, &ss->ssl3.hs.dtlsSentHandshake, |
776 | 62.7k | msgSeq, fragmentOffset, fragmentLen, |
777 | 62.7k | msg->cwSpec->epoch, |
778 | 62.7k | msg->cwSpec->nextSeqNum); |
779 | 62.7k | if (rv != SECSuccess) { |
780 | 0 | return SECFailure; |
781 | 0 | } |
782 | | |
783 | 62.7k | rv = dtls_SendFragment(ss, msg, fragment, |
784 | 62.7k | fragmentLen + DTLS_HS_HDR_LEN); |
785 | 62.7k | if (rv != SECSuccess) { |
786 | 0 | return SECFailure; |
787 | 0 | } |
788 | | |
789 | 62.7k | fragmentWritten = PR_TRUE; |
790 | 62.7k | fragmentOffset += fragmentLen; |
791 | 62.7k | } while (fragmentOffset < contentLen); |
792 | | |
793 | 41.6k | if (!fragmentWritten) { |
794 | | /* Nothing was written if we got here, so the whole message must have |
795 | | * been acknowledged. Discard it. */ |
796 | 109 | SSL_TRC(10, ("%d: SSL3[%d]: FragmentHandshake %d: removed", |
797 | 109 | SSL_GETPID(), ss->fd, msgSeq)); |
798 | 109 | PR_REMOVE_LINK(&msg->link); |
799 | 109 | dtls_FreeHandshakeMessage(msg); |
800 | 109 | } |
801 | | |
802 | 41.6k | return SECSuccess; |
803 | 41.6k | } |
804 | | |
805 | | /* Transmit a flight of handshake messages, stuffing them |
806 | | * into as few records as seems reasonable. |
807 | | * |
808 | | * TODO: Space separate UDP packets out a little. |
809 | | * |
810 | | * Called from: |
811 | | * dtls_FlushHandshake() |
812 | | * dtls_RetransmitTimerExpiredCb() |
813 | | */ |
814 | | SECStatus |
815 | | dtls_TransmitMessageFlight(sslSocket *ss) |
816 | 15.5k | { |
817 | 15.5k | SECStatus rv = SECSuccess; |
818 | 15.5k | PRCList *msg_p; |
819 | | |
820 | 15.5k | SSL_TRC(10, ("%d: SSL3[%d]: dtls_TransmitMessageFlight", |
821 | 15.5k | SSL_GETPID(), ss->fd)); |
822 | | |
823 | 15.5k | ssl_GetXmitBufLock(ss); |
824 | 15.5k | ssl_GetSpecReadLock(ss); |
825 | | |
826 | | /* DTLS does not buffer its handshake messages in ss->pendingBuf, but rather |
827 | | * in the lastMessageFlight structure. This is just a sanity check that some |
828 | | * programming error hasn't inadvertantly stuffed something in |
829 | | * ss->pendingBuf. This function uses ss->pendingBuf temporarily and it |
830 | | * needs to be empty to start. |
831 | | */ |
832 | 15.5k | PORT_Assert(!ss->pendingBuf.len); |
833 | | |
834 | 15.5k | for (msg_p = PR_LIST_HEAD(&ss->ssl3.hs.lastMessageFlight); |
835 | 58.4k | msg_p != &ss->ssl3.hs.lastMessageFlight;) { |
836 | 42.8k | DTLSQueuedMessage *msg = (DTLSQueuedMessage *)msg_p; |
837 | | |
838 | | /* Move the pointer forward so that the functions below are free to |
839 | | * remove messages from the list. */ |
840 | 42.8k | msg_p = PR_NEXT_LINK(msg_p); |
841 | | |
842 | | /* Note: This function fragments messages so that each record is close |
843 | | * to full. This produces fewer records, but it means that messages can |
844 | | * be quite fragmented. Adding an extra flush here would push new |
845 | | * messages into new records and reduce fragmentation. */ |
846 | 42.8k | if (msg->type == ssl_ct_handshake) { |
847 | 41.6k | rv = dtls_FragmentHandshake(ss, msg); |
848 | 41.6k | } else { |
849 | 1.15k | PORT_Assert(!tls13_MaybeTls13(ss)); |
850 | 1.15k | rv = dtls_SendFragment(ss, msg, msg->data, msg->len); |
851 | 1.15k | } |
852 | 42.8k | if (rv != SECSuccess) { |
853 | 0 | break; |
854 | 0 | } |
855 | 42.8k | } |
856 | | |
857 | | /* Finally, flush any data that wasn't flushed already. */ |
858 | 15.5k | if (rv == SECSuccess) { |
859 | 15.5k | rv = dtls_SendSavedWriteData(ss); |
860 | 15.5k | } |
861 | | |
862 | | /* Give up the locks */ |
863 | 15.5k | ssl_ReleaseSpecReadLock(ss); |
864 | 15.5k | ssl_ReleaseXmitBufLock(ss); |
865 | | |
866 | 15.5k | return rv; |
867 | 15.5k | } |
868 | | |
869 | | /* Flush the data in the pendingBuf and update the max message sent |
870 | | * so we can adjust the MTU estimate if we need to. |
871 | | * Wrapper for ssl_SendSavedWriteData. |
872 | | * |
873 | | * Called from dtls_TransmitMessageFlight() |
874 | | */ |
875 | | static SECStatus |
876 | | dtls_SendSavedWriteData(sslSocket *ss) |
877 | 20.6k | { |
878 | 20.6k | PRInt32 sent; |
879 | | |
880 | 20.6k | sent = ssl_SendSavedWriteData(ss); |
881 | 20.6k | if (sent < 0) |
882 | 0 | return SECFailure; |
883 | | |
884 | | /* We should always have complete writes b/c datagram sockets |
885 | | * don't really block */ |
886 | 20.6k | if (ss->pendingBuf.len > 0) { |
887 | 0 | ssl_MapLowLevelError(SSL_ERROR_SOCKET_WRITE_FAILURE); |
888 | 0 | return SECFailure; |
889 | 0 | } |
890 | | |
891 | | /* Update the largest message sent so we can adjust the MTU |
892 | | * estimate if necessary */ |
893 | 20.6k | if (sent > ss->ssl3.hs.maxMessageSent) |
894 | 13.4k | ss->ssl3.hs.maxMessageSent = sent; |
895 | | |
896 | 20.6k | return SECSuccess; |
897 | 20.6k | } |
898 | | |
899 | | void |
900 | | dtls_InitTimers(sslSocket *ss) |
901 | 49.8k | { |
902 | 49.8k | unsigned int i; |
903 | 49.8k | dtlsTimer **timers[PR_ARRAY_SIZE(ss->ssl3.hs.timers)] = { |
904 | 49.8k | &ss->ssl3.hs.rtTimer, |
905 | 49.8k | &ss->ssl3.hs.ackTimer, |
906 | 49.8k | &ss->ssl3.hs.hdTimer |
907 | 49.8k | }; |
908 | 49.8k | static const char *timerLabels[] = { |
909 | 49.8k | "retransmit", "ack", "holddown" |
910 | 49.8k | }; |
911 | | |
912 | 49.8k | PORT_Assert(PR_ARRAY_SIZE(timers) == PR_ARRAY_SIZE(timerLabels)); |
913 | 199k | for (i = 0; i < PR_ARRAY_SIZE(ss->ssl3.hs.timers); ++i) { |
914 | 149k | *timers[i] = &ss->ssl3.hs.timers[i]; |
915 | 149k | ss->ssl3.hs.timers[i].label = timerLabels[i]; |
916 | 149k | } |
917 | 49.8k | } |
918 | | |
919 | | SECStatus |
920 | | dtls_StartTimer(sslSocket *ss, dtlsTimer *timer, PRUint32 time, DTLSTimerCb cb) |
921 | 14.7k | { |
922 | 14.7k | PORT_Assert(timer->cb == NULL); |
923 | | |
924 | 14.7k | SSL_TRC(10, ("%d: SSL3[%d]: %s dtls_StartTimer %s timeout=%d", |
925 | 14.7k | SSL_GETPID(), ss->fd, SSL_ROLE(ss), timer->label, time)); |
926 | | |
927 | 14.7k | timer->started = PR_IntervalNow(); |
928 | 14.7k | timer->timeout = time; |
929 | 14.7k | timer->cb = cb; |
930 | 14.7k | return SECSuccess; |
931 | 14.7k | } |
932 | | |
933 | | SECStatus |
934 | | dtls_RestartTimer(sslSocket *ss, dtlsTimer *timer) |
935 | 741 | { |
936 | 741 | timer->started = PR_IntervalNow(); |
937 | 741 | return SECSuccess; |
938 | 741 | } |
939 | | |
940 | | PRBool |
941 | | dtls_TimerActive(sslSocket *ss, dtlsTimer *timer) |
942 | 0 | { |
943 | 0 | return timer->cb != NULL; |
944 | 0 | } |
945 | | /* Start a timer for retransmission. */ |
946 | | static SECStatus |
947 | | dtls_StartRetransmitTimer(sslSocket *ss) |
948 | 14.7k | { |
949 | 14.7k | ss->ssl3.hs.rtRetries = 0; |
950 | 14.7k | return dtls_StartTimer(ss, ss->ssl3.hs.rtTimer, |
951 | 14.7k | DTLS_RETRANSMIT_INITIAL_MS, |
952 | 14.7k | dtls_RetransmitTimerExpiredCb); |
953 | 14.7k | } |
954 | | |
955 | | /* Start a timer for holding an old cipher spec. */ |
956 | | SECStatus |
957 | | dtls_StartHolddownTimer(sslSocket *ss) |
958 | 0 | { |
959 | | /* DTLS1.3 starts the timer without calling this function, see tls13_ServerHandleFinished.*/ |
960 | 0 | PORT_Assert(ss->version < SSL_LIBRARY_VERSION_TLS_1_3); |
961 | 0 | return dtls_StartTimer(ss, ss->ssl3.hs.hdTimer, |
962 | 0 | DTLS_RETRANSMIT_FINISHED_MS, |
963 | 0 | dtls_FinishedTimerCb); |
964 | 0 | } |
965 | | |
966 | | /* Cancel a pending timer |
967 | | * |
968 | | * Called from: |
969 | | * dtls_HandleHandshake() |
970 | | * dtls_CheckTimer() |
971 | | */ |
972 | | void |
973 | | dtls_CancelTimer(sslSocket *ss, dtlsTimer *timer) |
974 | 38.7k | { |
975 | 38.7k | SSL_TRC(30, ("%d: SSL3[%d]: %s dtls_CancelTimer %s", |
976 | 38.7k | SSL_GETPID(), ss->fd, SSL_ROLE(ss), |
977 | 38.7k | timer->label)); |
978 | | |
979 | 38.7k | PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); |
980 | | |
981 | 38.7k | timer->cb = NULL; |
982 | 38.7k | } |
983 | | |
984 | | static void |
985 | | dtls_CancelAllTimers(sslSocket *ss) |
986 | 7.38k | { |
987 | 7.38k | unsigned int i; |
988 | | |
989 | 29.5k | for (i = 0; i < PR_ARRAY_SIZE(ss->ssl3.hs.timers); ++i) { |
990 | 22.1k | dtls_CancelTimer(ss, &ss->ssl3.hs.timers[i]); |
991 | 22.1k | } |
992 | 7.38k | } |
993 | | |
994 | | /* Check the pending timer and fire the callback if it expired |
995 | | * |
996 | | * Called from ssl3_GatherCompleteHandshake() |
997 | | */ |
998 | | void |
999 | | dtls_CheckTimer(sslSocket *ss) |
1000 | 7.93k | { |
1001 | 7.93k | unsigned int i; |
1002 | 7.93k | SSL_TRC(30, ("%d: SSL3[%d]: dtls_CheckTimer (%s)", |
1003 | 7.93k | SSL_GETPID(), ss->fd, ss->sec.isServer ? "server" : "client")); |
1004 | | |
1005 | 7.93k | ssl_GetSSL3HandshakeLock(ss); |
1006 | | |
1007 | 31.7k | for (i = 0; i < PR_ARRAY_SIZE(ss->ssl3.hs.timers); ++i) { |
1008 | 23.7k | dtlsTimer *timer = &ss->ssl3.hs.timers[i]; |
1009 | 23.7k | if (!timer->cb) { |
1010 | 19.9k | continue; |
1011 | 19.9k | } |
1012 | | |
1013 | 3.88k | if ((PR_IntervalNow() - timer->started) >= |
1014 | 3.88k | PR_MillisecondsToInterval(timer->timeout)) { |
1015 | | /* Timer has expired */ |
1016 | 0 | DTLSTimerCb cb = timer->cb; |
1017 | |
|
1018 | 0 | SSL_TRC(10, ("%d: SSL3[%d]: %s firing timer %s", |
1019 | 0 | SSL_GETPID(), ss->fd, SSL_ROLE(ss), |
1020 | 0 | timer->label)); |
1021 | | |
1022 | | /* Cancel the timer so that we can call the CB safely */ |
1023 | 0 | dtls_CancelTimer(ss, timer); |
1024 | | |
1025 | | /* Now call the CB */ |
1026 | 0 | cb(ss); |
1027 | 0 | } |
1028 | 3.88k | } |
1029 | 7.93k | ssl_ReleaseSSL3HandshakeLock(ss); |
1030 | 7.93k | } |
1031 | | |
1032 | | /* The callback to fire when the holddown timer for the Finished |
1033 | | * message expires and we can delete it |
1034 | | * |
1035 | | * Called from dtls_CheckTimer() |
1036 | | */ |
1037 | | static void |
1038 | | dtls_FinishedTimerCb(sslSocket *ss) |
1039 | 0 | { |
1040 | 0 | dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight); |
1041 | 0 | } |
1042 | | |
1043 | | /* Cancel the Finished hold-down timer and destroy the |
1044 | | * pending cipher spec. Note that this means that |
1045 | | * successive rehandshakes will fail if the Finished is |
1046 | | * lost. |
1047 | | * |
1048 | | * XXX OK for now. Figure out how to handle the combination |
1049 | | * of Finished lost and rehandshake |
1050 | | */ |
1051 | | void |
1052 | | dtls_RehandshakeCleanup(sslSocket *ss) |
1053 | 7.47k | { |
1054 | | /* Skip this if we are handling a second ClientHello. */ |
1055 | 7.47k | if (ss->ssl3.hs.helloRetry) { |
1056 | 85 | return; |
1057 | 85 | } |
1058 | 7.38k | PORT_Assert((ss->version < SSL_LIBRARY_VERSION_TLS_1_3)); |
1059 | 7.38k | dtls_CancelAllTimers(ss); |
1060 | 7.38k | dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight); |
1061 | 7.38k | ss->ssl3.hs.sendMessageSeq = 0; |
1062 | 7.38k | ss->ssl3.hs.recvMessageSeq = 0; |
1063 | 7.38k | } |
1064 | | |
1065 | | /* Set the MTU to the next step less than or equal to the |
1066 | | * advertised value. Also used to downgrade the MTU by |
1067 | | * doing dtls_SetMTU(ss, biggest packet set). |
1068 | | * |
1069 | | * Passing 0 means set this to the largest MTU known |
1070 | | * (effectively resetting the PMTU backoff value). |
1071 | | * |
1072 | | * Called by: |
1073 | | * ssl3_InitState() |
1074 | | * dtls_RetransmitTimerExpiredCb() |
1075 | | */ |
1076 | | void |
1077 | | dtls_SetMTU(sslSocket *ss, PRUint16 advertised) |
1078 | 15.3k | { |
1079 | 15.3k | int i; |
1080 | | |
1081 | 15.3k | if (advertised == 0) { |
1082 | 15.3k | ss->ssl3.mtu = COMMON_MTU_VALUES[0]; |
1083 | 15.3k | SSL_TRC(30, ("Resetting MTU to %d", ss->ssl3.mtu)); |
1084 | 15.3k | return; |
1085 | 15.3k | } |
1086 | | |
1087 | 0 | for (i = 0; i < PR_ARRAY_SIZE(COMMON_MTU_VALUES); i++) { |
1088 | 0 | if (COMMON_MTU_VALUES[i] <= advertised) { |
1089 | 0 | ss->ssl3.mtu = COMMON_MTU_VALUES[i]; |
1090 | 0 | SSL_TRC(30, ("Resetting MTU to %d", ss->ssl3.mtu)); |
1091 | 0 | return; |
1092 | 0 | } |
1093 | 0 | } |
1094 | | |
1095 | | /* Fallback */ |
1096 | 0 | ss->ssl3.mtu = COMMON_MTU_VALUES[PR_ARRAY_SIZE(COMMON_MTU_VALUES) - 1]; |
1097 | 0 | SSL_TRC(30, ("Resetting MTU to %d", ss->ssl3.mtu)); |
1098 | 0 | } |
1099 | | |
1100 | | /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a |
1101 | | * DTLS hello_verify_request |
1102 | | * Caller must hold Handshake and RecvBuf locks. |
1103 | | */ |
1104 | | SECStatus |
1105 | | dtls_HandleHelloVerifyRequest(sslSocket *ss, PRUint8 *b, PRUint32 length) |
1106 | 242 | { |
1107 | 242 | int errCode = SSL_ERROR_RX_MALFORMED_HELLO_VERIFY_REQUEST; |
1108 | 242 | SECStatus rv; |
1109 | 242 | SSL3ProtocolVersion temp; |
1110 | 242 | SSL3AlertDescription desc = illegal_parameter; |
1111 | | |
1112 | 242 | SSL_TRC(3, ("%d: SSL3[%d]: handle hello_verify_request handshake", |
1113 | 242 | SSL_GETPID(), ss->fd)); |
1114 | 242 | PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); |
1115 | 242 | PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); |
1116 | | |
1117 | 242 | if (ss->ssl3.hs.ws != wait_server_hello) { |
1118 | 2 | errCode = SSL_ERROR_RX_UNEXPECTED_HELLO_VERIFY_REQUEST; |
1119 | 2 | desc = unexpected_message; |
1120 | 2 | goto alert_loser; |
1121 | 2 | } |
1122 | | |
1123 | 240 | dtls_ReceivedFirstMessageInFlight(ss); |
1124 | | |
1125 | | /* The version. |
1126 | | * |
1127 | | * RFC 4347 required that you verify that the server versions |
1128 | | * match (Section 4.2.1) in the HelloVerifyRequest and the |
1129 | | * ServerHello. |
1130 | | * |
1131 | | * RFC 6347 (Section 4.2.1) suggests (SHOULD) that servers always use 1.0 in |
1132 | | * HelloVerifyRequest and allows the versions not to match, |
1133 | | * especially when 1.2 is being negotiated. |
1134 | | * |
1135 | | * Therefore we do not do anything to enforce a match, just |
1136 | | * read and check that this value is sane. |
1137 | | */ |
1138 | 240 | rv = ssl_ClientReadVersion(ss, &b, &length, &temp); |
1139 | 240 | if (rv != SECSuccess) { |
1140 | 32 | goto loser; /* alert has been sent */ |
1141 | 32 | } |
1142 | | |
1143 | | /* Read the cookie. |
1144 | | * IMPORTANT: The value of ss->ssl3.hs.cookie is only valid while the |
1145 | | * HelloVerifyRequest message remains valid. */ |
1146 | 208 | rv = ssl3_ConsumeHandshakeVariable(ss, &ss->ssl3.hs.cookie, 1, &b, &length); |
1147 | 208 | if (rv != SECSuccess) { |
1148 | 7 | goto loser; /* alert has been sent */ |
1149 | 7 | } |
1150 | 201 | if (ss->ssl3.hs.cookie.len > DTLS_COOKIE_BYTES) { |
1151 | 1 | desc = decode_error; |
1152 | 1 | goto alert_loser; /* malformed. */ |
1153 | 1 | } |
1154 | | |
1155 | 200 | ssl_GetXmitBufLock(ss); /*******************************/ |
1156 | | |
1157 | | /* Now re-send the client hello */ |
1158 | 200 | rv = ssl3_SendClientHello(ss, client_hello_retransmit); |
1159 | | |
1160 | 200 | ssl_ReleaseXmitBufLock(ss); /*******************************/ |
1161 | | |
1162 | 200 | if (rv == SECSuccess) |
1163 | 200 | return rv; |
1164 | | |
1165 | 3 | alert_loser: |
1166 | 3 | (void)SSL3_SendAlert(ss, alert_fatal, desc); |
1167 | | |
1168 | 42 | loser: |
1169 | 42 | ssl_MapLowLevelError(errCode); |
1170 | 42 | return SECFailure; |
1171 | 3 | } |
1172 | | |
1173 | | /* Initialize the DTLS anti-replay window |
1174 | | * |
1175 | | * Called from: |
1176 | | * ssl3_SetupPendingCipherSpec() |
1177 | | * ssl3_InitCipherSpec() |
1178 | | */ |
1179 | | void |
1180 | | dtls_InitRecvdRecords(DTLSRecvdRecords *records) |
1181 | 112k | { |
1182 | 112k | PORT_Memset(records->data, 0, sizeof(records->data)); |
1183 | 112k | records->left = 0; |
1184 | 112k | records->right = DTLS_RECVD_RECORDS_WINDOW - 1; |
1185 | 112k | } |
1186 | | |
1187 | | /* |
1188 | | * Has this DTLS record been received? Return values are: |
1189 | | * -1 -- out of range to the left |
1190 | | * 0 -- not received yet |
1191 | | * 1 -- replay |
1192 | | * |
1193 | | * Called from: ssl3_HandleRecord() |
1194 | | */ |
1195 | | int |
1196 | | dtls_RecordGetRecvd(const DTLSRecvdRecords *records, sslSequenceNumber seq) |
1197 | 1.24M | { |
1198 | 1.24M | PRUint64 offset; |
1199 | | |
1200 | | /* Out of range to the left */ |
1201 | 1.24M | if (seq < records->left) { |
1202 | 1.15M | return -1; |
1203 | 1.15M | } |
1204 | | |
1205 | | /* Out of range to the right; since we advance the window on |
1206 | | * receipt, that means that this packet has not been received |
1207 | | * yet */ |
1208 | 90.8k | if (seq > records->right) |
1209 | 23.5k | return 0; |
1210 | | |
1211 | 67.2k | offset = seq % DTLS_RECVD_RECORDS_WINDOW; |
1212 | | |
1213 | 67.2k | return !!(records->data[offset / 8] & (1 << (offset % 8))); |
1214 | 90.8k | } |
1215 | | |
1216 | | /* Update the DTLS anti-replay window |
1217 | | * |
1218 | | * Called from ssl3_HandleRecord() |
1219 | | */ |
1220 | | void |
1221 | | dtls_RecordSetRecvd(DTLSRecvdRecords *records, sslSequenceNumber seq) |
1222 | 44.5k | { |
1223 | 44.5k | PRUint64 offset; |
1224 | | |
1225 | 44.5k | if (seq < records->left) |
1226 | 0 | return; |
1227 | | |
1228 | 44.5k | if (seq > records->right) { |
1229 | 11.5k | sslSequenceNumber new_left; |
1230 | 11.5k | sslSequenceNumber new_right; |
1231 | 11.5k | sslSequenceNumber right; |
1232 | | |
1233 | | /* Slide to the right; this is the tricky part |
1234 | | * |
1235 | | * 1. new_top is set to have room for seq, on the |
1236 | | * next byte boundary by setting the right 8 |
1237 | | * bits of seq |
1238 | | * 2. new_left is set to compensate. |
1239 | | * 3. Zero all bits between top and new_top. Since |
1240 | | * this is a ring, this zeroes everything as-yet |
1241 | | * unseen. Because we always operate on byte |
1242 | | * boundaries, we can zero one byte at a time |
1243 | | */ |
1244 | 11.5k | new_right = seq | 0x07; |
1245 | 11.5k | new_left = (new_right - DTLS_RECVD_RECORDS_WINDOW) + 1; |
1246 | | |
1247 | 11.5k | if (new_right > records->right + DTLS_RECVD_RECORDS_WINDOW) { |
1248 | 10.6k | PORT_Memset(records->data, 0, sizeof(records->data)); |
1249 | 10.6k | } else { |
1250 | 30.7k | for (right = records->right + 8; right <= new_right; right += 8) { |
1251 | 29.8k | offset = right % DTLS_RECVD_RECORDS_WINDOW; |
1252 | 29.8k | records->data[offset / 8] = 0; |
1253 | 29.8k | } |
1254 | 892 | } |
1255 | | |
1256 | 11.5k | records->right = new_right; |
1257 | 11.5k | records->left = new_left; |
1258 | 11.5k | } |
1259 | | |
1260 | 44.5k | offset = seq % DTLS_RECVD_RECORDS_WINDOW; |
1261 | | |
1262 | 44.5k | records->data[offset / 8] |= (1 << (offset % 8)); |
1263 | 44.5k | } |
1264 | | |
1265 | | SECStatus |
1266 | | DTLS_GetHandshakeTimeout(PRFileDesc *socket, PRIntervalTime *timeout) |
1267 | 0 | { |
1268 | 0 | sslSocket *ss = NULL; |
1269 | 0 | PRBool found = PR_FALSE; |
1270 | 0 | PRIntervalTime now = PR_IntervalNow(); |
1271 | 0 | PRIntervalTime to; |
1272 | 0 | unsigned int i; |
1273 | |
|
1274 | 0 | *timeout = PR_INTERVAL_NO_TIMEOUT; |
1275 | |
|
1276 | 0 | ss = ssl_FindSocket(socket); |
1277 | |
|
1278 | 0 | if (!ss) { |
1279 | 0 | PORT_SetError(SEC_ERROR_INVALID_ARGS); |
1280 | 0 | return SECFailure; |
1281 | 0 | } |
1282 | | |
1283 | 0 | if (!IS_DTLS(ss)) { |
1284 | 0 | PORT_SetError(SEC_ERROR_INVALID_ARGS); |
1285 | 0 | return SECFailure; |
1286 | 0 | } |
1287 | | |
1288 | 0 | for (i = 0; i < PR_ARRAY_SIZE(ss->ssl3.hs.timers); ++i) { |
1289 | 0 | PRIntervalTime elapsed; |
1290 | 0 | PRIntervalTime desired; |
1291 | 0 | dtlsTimer *timer = &ss->ssl3.hs.timers[i]; |
1292 | |
|
1293 | 0 | if (!timer->cb) { |
1294 | 0 | continue; |
1295 | 0 | } |
1296 | 0 | found = PR_TRUE; |
1297 | |
|
1298 | 0 | elapsed = now - timer->started; |
1299 | 0 | desired = PR_MillisecondsToInterval(timer->timeout); |
1300 | 0 | if (elapsed > desired) { |
1301 | | /* Timer expired */ |
1302 | 0 | *timeout = PR_INTERVAL_NO_WAIT; |
1303 | 0 | return SECSuccess; |
1304 | 0 | } else { |
1305 | 0 | to = desired - elapsed; |
1306 | 0 | } |
1307 | | |
1308 | 0 | if (*timeout > to) { |
1309 | 0 | *timeout = to; |
1310 | 0 | } |
1311 | 0 | } |
1312 | | |
1313 | 0 | if (!found) { |
1314 | 0 | PORT_SetError(SSL_ERROR_NO_TIMERS_FOUND); |
1315 | 0 | return SECFailure; |
1316 | 0 | } |
1317 | | |
1318 | 0 | return SECSuccess; |
1319 | 0 | } |
1320 | | |
1321 | | PRBool |
1322 | | dtls_IsLongHeader(SSL3ProtocolVersion version, PRUint8 firstOctet) |
1323 | 3.79M | { |
1324 | | #ifndef UNSAFE_FUZZER_MODE |
1325 | 2.45M | return version < SSL_LIBRARY_VERSION_TLS_1_3 || |
1326 | 2.45M | firstOctet == ssl_ct_handshake || |
1327 | 2.45M | firstOctet == ssl_ct_ack || |
1328 | 12.6k | firstOctet == ssl_ct_alert; |
1329 | | #else |
1330 | 1.34M | return PR_TRUE; |
1331 | | #endif |
1332 | 3.79M | } Line | Count | Source | 1323 | 1.34M | { | 1324 | | #ifndef UNSAFE_FUZZER_MODE | 1325 | | return version < SSL_LIBRARY_VERSION_TLS_1_3 || | 1326 | | firstOctet == ssl_ct_handshake || | 1327 | | firstOctet == ssl_ct_ack || | 1328 | | firstOctet == ssl_ct_alert; | 1329 | | #else | 1330 | 1.34M | return PR_TRUE; | 1331 | 1.34M | #endif | 1332 | 1.34M | } |
Line | Count | Source | 1323 | 2.45M | { | 1324 | 2.45M | #ifndef UNSAFE_FUZZER_MODE | 1325 | 2.45M | return version < SSL_LIBRARY_VERSION_TLS_1_3 || | 1326 | 2.45M | firstOctet == ssl_ct_handshake || | 1327 | 2.45M | firstOctet == ssl_ct_ack || | 1328 | 2.45M | firstOctet == ssl_ct_alert; | 1329 | | #else | 1330 | | return PR_TRUE; | 1331 | | #endif | 1332 | 2.45M | } |
|
1333 | | |
1334 | | PRBool |
1335 | | dtls_IsDtls13Ciphertext(SSL3ProtocolVersion version, PRUint8 firstOctet) |
1336 | 52.7k | { |
1337 | | // Allow no version in case we haven't negotiated one yet. |
1338 | 52.7k | return (version == 0 || version >= SSL_LIBRARY_VERSION_TLS_1_3) && |
1339 | 52.7k | (firstOctet & 0xe0) == 0x20; |
1340 | 52.7k | } |
1341 | | |
1342 | | DTLSEpoch |
1343 | | dtls_ReadEpoch(const SSL3ProtocolVersion version, const DTLSEpoch specEpoch, const PRUint8 *hdr) |
1344 | 1.27M | { |
1345 | 1.27M | if (dtls_IsLongHeader(version, hdr[0])) { |
1346 | 1.26M | return ((DTLSEpoch)hdr[3] << 8) | hdr[4]; |
1347 | 1.26M | } |
1348 | | |
1349 | 3.99k | DTLSEpoch epoch = (specEpoch & ~3) | (hdr[0] & 3); |
1350 | | /* The epoch cannot be higher than the current read epoch, |
1351 | | though guard against underflow. */ |
1352 | 3.99k | if (epoch > specEpoch && epoch > 4) { |
1353 | 0 | epoch -= 4; |
1354 | 0 | } |
1355 | | |
1356 | 3.99k | return epoch; |
1357 | 1.27M | } |
1358 | | |
1359 | | static sslSequenceNumber |
1360 | | dtls_ReadSequenceNumber(const ssl3CipherSpec *spec, const PRUint8 *hdr) |
1361 | 1.24M | { |
1362 | 1.24M | sslSequenceNumber cap; |
1363 | 1.24M | sslSequenceNumber partial; |
1364 | 1.24M | sslSequenceNumber seqNum; |
1365 | 1.24M | sslSequenceNumber mask; |
1366 | | |
1367 | 1.24M | if (dtls_IsLongHeader(spec->version, hdr[0])) { |
1368 | 1.24M | static const unsigned int seqNumOffset = 5; /* type, version, epoch */ |
1369 | 1.24M | static const unsigned int seqNumLength = 6; |
1370 | 1.24M | sslReader r = SSL_READER(hdr + seqNumOffset, seqNumLength); |
1371 | 1.24M | (void)sslRead_ReadNumber(&r, seqNumLength, &seqNum); |
1372 | 1.24M | return seqNum; |
1373 | 1.24M | } |
1374 | | |
1375 | | /* Only the least significant bits of the sequence number is available here. |
1376 | | * This recovers the value based on the next expected sequence number. |
1377 | | * |
1378 | | * This works by determining the maximum possible sequence number, which is |
1379 | | * half the range of possible values above the expected next value (the |
1380 | | * expected next value is in |spec->seqNum|). Then, the last part of the |
1381 | | * sequence number is replaced. If that causes the value to exceed the |
1382 | | * maximum, subtract an entire range. |
1383 | | */ |
1384 | 2.63k | if (hdr[0] & 0x08) { |
1385 | 2.51k | cap = spec->nextSeqNum + (1ULL << 15); |
1386 | 2.51k | partial = (((sslSequenceNumber)hdr[1]) << 8) | |
1387 | 2.51k | (sslSequenceNumber)hdr[2]; |
1388 | 2.51k | mask = (1ULL << 16) - 1; |
1389 | 2.51k | } else { |
1390 | 116 | cap = spec->nextSeqNum + (1ULL << 7); |
1391 | 116 | partial = (sslSequenceNumber)hdr[1]; |
1392 | 116 | mask = (1ULL << 8) - 1; |
1393 | 116 | } |
1394 | 2.63k | seqNum = (cap & ~mask) | partial; |
1395 | | /* The second check prevents the value from underflowing if we get a large |
1396 | | * gap at the start of a connection, where this subtraction would cause the |
1397 | | * sequence number to wrap to near UINT64_MAX. */ |
1398 | 2.63k | if ((partial > (cap & mask)) && (seqNum > mask)) { |
1399 | 0 | seqNum -= mask + 1; |
1400 | 0 | } |
1401 | 2.63k | return seqNum; |
1402 | 1.24M | } |
1403 | | |
1404 | | /* |
1405 | | * DTLS relevance checks: |
1406 | | * Note that this code currently ignores all out-of-epoch packets, |
1407 | | * which means we lose some in the case of rehandshake + |
1408 | | * loss/reordering. Since DTLS is explicitly unreliable, this |
1409 | | * seems like a good tradeoff for implementation effort and is |
1410 | | * consistent with the guidance of RFC 6347 Sections 4.1 and 4.2.4.1. |
1411 | | * |
1412 | | * If the packet is not relevant, this function returns PR_FALSE. If the packet |
1413 | | * is relevant, this function returns PR_TRUE and sets |*seqNumOut| to the |
1414 | | * packet sequence number (removing the epoch). |
1415 | | */ |
1416 | | PRBool |
1417 | | dtls_IsRelevant(sslSocket *ss, const ssl3CipherSpec *spec, |
1418 | | const SSL3Ciphertext *cText, |
1419 | | sslSequenceNumber *seqNumOut) |
1420 | 1.24M | { |
1421 | 1.24M | sslSequenceNumber seqNum = dtls_ReadSequenceNumber(spec, cText->hdr); |
1422 | 1.24M | if (dtls_RecordGetRecvd(&spec->recvdRecords, seqNum) != 0) { |
1423 | 1.17M | SSL_TRC(10, ("%d: SSL3[%d]: dtls_IsRelevant, rejecting " |
1424 | 1.17M | "potentially replayed packet", |
1425 | 1.17M | SSL_GETPID(), ss->fd)); |
1426 | 1.17M | return PR_FALSE; |
1427 | 1.17M | } |
1428 | | |
1429 | 77.5k | *seqNumOut = seqNum; |
1430 | 77.5k | return PR_TRUE; |
1431 | 1.24M | } |
1432 | | |
1433 | | void |
1434 | | dtls_ReceivedFirstMessageInFlight(sslSocket *ss) |
1435 | 145k | { |
1436 | 145k | if (!IS_DTLS(ss)) |
1437 | 129k | return; |
1438 | | |
1439 | | /* At this point we are advancing our state machine, so we can free our last |
1440 | | * flight of messages. */ |
1441 | 15.5k | if (ss->ssl3.hs.ws != idle_handshake || |
1442 | 15.5k | ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) { |
1443 | | /* We need to keep our last flight around in DTLS 1.2 and below, |
1444 | | * so we can retransmit it in response to other people's |
1445 | | * retransmits. */ |
1446 | 15.5k | dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight); |
1447 | | |
1448 | | /* Reset the timer to the initial value if the retry counter |
1449 | | * is 0, per RFC 6347, Sec. 4.2.4.1 */ |
1450 | 15.5k | dtls_CancelTimer(ss, ss->ssl3.hs.rtTimer); |
1451 | 15.5k | if (ss->ssl3.hs.rtRetries == 0) { |
1452 | 15.5k | ss->ssl3.hs.rtTimer->timeout = DTLS_RETRANSMIT_INITIAL_MS; |
1453 | 15.5k | } |
1454 | 15.5k | } |
1455 | | |
1456 | | /* Empty the ACK queue (TLS 1.3 only). */ |
1457 | 15.5k | ssl_ClearPRCList(&ss->ssl3.hs.dtlsRcvdHandshake, NULL); |
1458 | 15.5k | } |