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