]>
Commit | Line | Data |
---|---|---|
0f113f3e | 1 | /* |
fecb3aae | 2 | * Copyright 2005-2022 The OpenSSL Project Authors. All Rights Reserved. |
0f113f3e | 3 | * |
2c18d164 | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
846e33c7 RS |
5 | * this file except in compliance with the License. You can obtain a copy |
6 | * in the file LICENSE in the source distribution or at | |
7 | * https://www.openssl.org/source/license.html | |
36d16f8e BL |
8 | */ |
9 | ||
10 | #include <limits.h> | |
11 | #include <string.h> | |
12 | #include <stdio.h> | |
706457b7 DMSP |
13 | #include "../ssl_local.h" |
14 | #include "statem_local.h" | |
67dc995e | 15 | #include "internal/cryptlib.h" |
36d16f8e | 16 | #include <openssl/buffer.h> |
36d16f8e BL |
17 | #include <openssl/objects.h> |
18 | #include <openssl/evp.h> | |
19 | #include <openssl/x509.h> | |
20 | ||
934e22e8 DSH |
21 | #define RSMBLY_BITMASK_SIZE(msg_len) (((msg_len) + 7) / 8) |
22 | ||
23 | #define RSMBLY_BITMASK_MARK(bitmask, start, end) { \ | |
0f113f3e MC |
24 | if ((end) - (start) <= 8) { \ |
25 | long ii; \ | |
26 | for (ii = (start); ii < (end); ii++) bitmask[((ii) >> 3)] |= (1 << ((ii) & 7)); \ | |
27 | } else { \ | |
28 | long ii; \ | |
29 | bitmask[((start) >> 3)] |= bitmask_start_values[((start) & 7)]; \ | |
30 | for (ii = (((start) >> 3) + 1); ii < ((((end) - 1)) >> 3); ii++) bitmask[ii] = 0xff; \ | |
31 | bitmask[(((end) - 1) >> 3)] |= bitmask_end_values[((end) & 7)]; \ | |
32 | } } | |
934e22e8 DSH |
33 | |
34 | #define RSMBLY_BITMASK_IS_COMPLETE(bitmask, msg_len, is_complete) { \ | |
0f113f3e | 35 | long ii; \ |
0f113f3e MC |
36 | is_complete = 1; \ |
37 | if (bitmask[(((msg_len) - 1) >> 3)] != bitmask_end_values[((msg_len) & 7)]) is_complete = 0; \ | |
38 | if (is_complete) for (ii = (((msg_len) - 1) >> 3) - 1; ii >= 0 ; ii--) \ | |
39 | if (bitmask[ii] != 0xff) { is_complete = 0; break; } } | |
934e22e8 | 40 | |
0f113f3e MC |
41 | static unsigned char bitmask_start_values[] = |
42 | { 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80 }; | |
43 | static unsigned char bitmask_end_values[] = | |
44 | { 0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f }; | |
36d16f8e | 45 | |
38b051a1 | 46 | static void dtls1_fix_message_header(SSL_CONNECTION *s, size_t frag_off, |
7ee8627f | 47 | size_t frag_len); |
38b051a1 TM |
48 | static unsigned char *dtls1_write_message_header(SSL_CONNECTION *s, |
49 | unsigned char *p); | |
50 | static void dtls1_set_message_header_int(SSL_CONNECTION *s, unsigned char mt, | |
7ee8627f | 51 | size_t len, |
0f113f3e | 52 | unsigned short seq_num, |
7ee8627f MC |
53 | size_t frag_off, |
54 | size_t frag_len); | |
38b051a1 TM |
55 | static int dtls_get_reassembled_message(SSL_CONNECTION *s, int *errtype, |
56 | size_t *len); | |
0f113f3e | 57 | |
7ee8627f | 58 | static hm_fragment *dtls1_hm_fragment_new(size_t frag_len, int reassembly) |
0f113f3e MC |
59 | { |
60 | hm_fragment *frag = NULL; | |
61 | unsigned char *buf = NULL; | |
62 | unsigned char *bitmask = NULL; | |
63 | ||
e077455e | 64 | if ((frag = OPENSSL_malloc(sizeof(*frag))) == NULL) |
0f113f3e MC |
65 | return NULL; |
66 | ||
67 | if (frag_len) { | |
cdb10bae | 68 | if ((buf = OPENSSL_malloc(frag_len)) == NULL) { |
0f113f3e MC |
69 | OPENSSL_free(frag); |
70 | return NULL; | |
71 | } | |
72 | } | |
73 | ||
74 | /* zero length fragment gets zero frag->fragment */ | |
75 | frag->fragment = buf; | |
76 | ||
77 | /* Initialize reassembly bitmask if necessary */ | |
78 | if (reassembly) { | |
b51bce94 | 79 | bitmask = OPENSSL_zalloc(RSMBLY_BITMASK_SIZE(frag_len)); |
0f113f3e | 80 | if (bitmask == NULL) { |
b548a1f1 | 81 | OPENSSL_free(buf); |
0f113f3e MC |
82 | OPENSSL_free(frag); |
83 | return NULL; | |
84 | } | |
0f113f3e MC |
85 | } |
86 | ||
87 | frag->reassembly = bitmask; | |
88 | ||
89 | return frag; | |
90 | } | |
36d16f8e | 91 | |
8a35dbb6 | 92 | void dtls1_hm_fragment_free(hm_fragment *frag) |
0f113f3e | 93 | { |
25aaa98a RS |
94 | if (!frag) |
95 | return; | |
0f113f3e | 96 | if (frag->msg_header.is_ccs) { |
b9e37f8f MC |
97 | /* |
98 | * If we're freeing the CCS then we're done with the old wrl and it | |
99 | * can bee freed | |
100 | */ | |
101 | if (frag->msg_header.saved_retransmit_state.wrlmethod != NULL) | |
102 | frag->msg_header.saved_retransmit_state.wrlmethod->free(frag->msg_header.saved_retransmit_state.wrl); | |
0f113f3e | 103 | } |
b548a1f1 RS |
104 | OPENSSL_free(frag->fragment); |
105 | OPENSSL_free(frag->reassembly); | |
0f113f3e MC |
106 | OPENSSL_free(frag); |
107 | } | |
36d16f8e | 108 | |
0f113f3e MC |
109 | /* |
110 | * send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or | |
111 | * SSL3_RT_CHANGE_CIPHER_SPEC) | |
112 | */ | |
38b051a1 | 113 | int dtls1_do_write(SSL_CONNECTION *s, int type) |
0f113f3e MC |
114 | { |
115 | int ret; | |
7ee8627f MC |
116 | size_t written; |
117 | size_t curr_mtu; | |
0f113f3e | 118 | int retry = 1; |
7ee8627f | 119 | size_t len, frag_off, mac_size, blocksize, used_len; |
38b051a1 | 120 | SSL *ssl = SSL_CONNECTION_GET_SSL(s); |
0f113f3e MC |
121 | |
122 | if (!dtls1_query_mtu(s)) | |
123 | return -1; | |
124 | ||
50b4a9ba SGM |
125 | if (s->d1->mtu < dtls1_min_mtu(s)) |
126 | /* should have something reasonable now */ | |
127 | return -1; | |
0f113f3e | 128 | |
380a522f MC |
129 | if (s->init_off == 0 && type == SSL3_RT_HANDSHAKE) { |
130 | if (!ossl_assert(s->init_num == | |
131 | s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH)) | |
132 | return -1; | |
133 | } | |
0f113f3e MC |
134 | |
135 | if (s->write_hash) { | |
136 | if (s->enc_write_ctx | |
ed576acd | 137 | && (EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(s->enc_write_ctx)) & |
3e166c13 | 138 | EVP_CIPH_FLAG_AEAD_CIPHER) != 0) |
0f113f3e MC |
139 | mac_size = 0; |
140 | else | |
ed576acd | 141 | mac_size = EVP_MD_CTX_get_size(s->write_hash); |
0f113f3e MC |
142 | } else |
143 | mac_size = 0; | |
144 | ||
145 | if (s->enc_write_ctx && | |
ed576acd TM |
146 | (EVP_CIPHER_CTX_get_mode(s->enc_write_ctx) == EVP_CIPH_CBC_MODE)) |
147 | blocksize = 2 * EVP_CIPHER_CTX_get_block_size(s->enc_write_ctx); | |
0f113f3e MC |
148 | else |
149 | blocksize = 0; | |
150 | ||
151 | frag_off = 0; | |
67f60be8 MC |
152 | s->rwstate = SSL_NOTHING; |
153 | ||
0f113f3e MC |
154 | /* s->init_num shouldn't ever be < 0...but just in case */ |
155 | while (s->init_num > 0) { | |
2ad226e8 MC |
156 | if (type == SSL3_RT_HANDSHAKE && s->init_off != 0) { |
157 | /* We must be writing a fragment other than the first one */ | |
158 | ||
159 | if (frag_off > 0) { | |
160 | /* This is the first attempt at writing out this fragment */ | |
161 | ||
162 | if (s->init_off <= DTLS1_HM_HEADER_LENGTH) { | |
163 | /* | |
164 | * Each fragment that was already sent must at least have | |
165 | * contained the message header plus one other byte. | |
166 | * Therefore |init_off| must have progressed by at least | |
167 | * |DTLS1_HM_HEADER_LENGTH + 1| bytes. If not something went | |
168 | * wrong. | |
169 | */ | |
170 | return -1; | |
171 | } | |
172 | ||
173 | /* | |
174 | * Adjust |init_off| and |init_num| to allow room for a new | |
175 | * message header for this fragment. | |
176 | */ | |
177 | s->init_off -= DTLS1_HM_HEADER_LENGTH; | |
178 | s->init_num += DTLS1_HM_HEADER_LENGTH; | |
179 | } else { | |
180 | /* | |
181 | * We must have been called again after a retry so use the | |
182 | * fragment offset from our last attempt. We do not need | |
183 | * to adjust |init_off| and |init_num| as above, because | |
184 | * that should already have been done before the retry. | |
185 | */ | |
186 | frag_off = s->d1->w_msg_hdr.frag_off; | |
187 | } | |
188 | } | |
189 | ||
2e7dc7cd | 190 | used_len = BIO_wpending(s->wbio) + DTLS1_RT_HEADER_LENGTH |
0f113f3e MC |
191 | + mac_size + blocksize; |
192 | if (s->d1->mtu > used_len) | |
193 | curr_mtu = s->d1->mtu - used_len; | |
194 | else | |
195 | curr_mtu = 0; | |
196 | ||
197 | if (curr_mtu <= DTLS1_HM_HEADER_LENGTH) { | |
198 | /* | |
199 | * grr.. we could get an error if MTU picked was wrong | |
200 | */ | |
2e7dc7cd | 201 | ret = BIO_flush(s->wbio); |
67f60be8 MC |
202 | if (ret <= 0) { |
203 | s->rwstate = SSL_WRITING; | |
0f113f3e | 204 | return ret; |
67f60be8 | 205 | } |
0f113f3e MC |
206 | used_len = DTLS1_RT_HEADER_LENGTH + mac_size + blocksize; |
207 | if (s->d1->mtu > used_len + DTLS1_HM_HEADER_LENGTH) { | |
208 | curr_mtu = s->d1->mtu - used_len; | |
209 | } else { | |
210 | /* Shouldn't happen */ | |
211 | return -1; | |
212 | } | |
213 | } | |
214 | ||
215 | /* | |
216 | * We just checked that s->init_num > 0 so this cast should be safe | |
217 | */ | |
218 | if (((unsigned int)s->init_num) > curr_mtu) | |
219 | len = curr_mtu; | |
220 | else | |
221 | len = s->init_num; | |
222 | ||
e915c3f5 BE |
223 | if (len > ssl_get_max_send_fragment(s)) |
224 | len = ssl_get_max_send_fragment(s); | |
aefb9256 | 225 | |
0f113f3e MC |
226 | /* |
227 | * XDTLS: this function is too long. split out the CCS part | |
228 | */ | |
229 | if (type == SSL3_RT_HANDSHAKE) { | |
0f113f3e MC |
230 | if (len < DTLS1_HM_HEADER_LENGTH) { |
231 | /* | |
232 | * len is so small that we really can't do anything sensible | |
233 | * so fail | |
234 | */ | |
235 | return -1; | |
236 | } | |
a230b26e | 237 | dtls1_fix_message_header(s, frag_off, len - DTLS1_HM_HEADER_LENGTH); |
0f113f3e MC |
238 | |
239 | dtls1_write_message_header(s, | |
240 | (unsigned char *)&s->init_buf-> | |
241 | data[s->init_off]); | |
242 | } | |
243 | ||
7ee8627f MC |
244 | ret = dtls1_write_bytes(s, type, &s->init_buf->data[s->init_off], len, |
245 | &written); | |
e915c3f5 | 246 | if (ret <= 0) { |
0f113f3e MC |
247 | /* |
248 | * might need to update MTU here, but we don't know which | |
249 | * previous packet caused the failure -- so can't really | |
250 | * retransmit anything. continue as if everything is fine and | |
251 | * wait for an alert to handle the retransmit | |
252 | */ | |
38b051a1 | 253 | if (retry && BIO_ctrl(SSL_get_wbio(ssl), |
0f113f3e | 254 | BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL) > 0) { |
38b051a1 | 255 | if (!(SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) { |
0f113f3e MC |
256 | if (!dtls1_query_mtu(s)) |
257 | return -1; | |
258 | /* Have one more go */ | |
259 | retry = 0; | |
260 | } else | |
261 | return -1; | |
262 | } else { | |
380a522f | 263 | return -1; |
0f113f3e MC |
264 | } |
265 | } else { | |
266 | ||
267 | /* | |
268 | * bad if this assert fails, only part of the handshake message | |
269 | * got sent. but why would this happen? | |
270 | */ | |
380a522f MC |
271 | if (!ossl_assert(len == written)) |
272 | return -1; | |
0f113f3e MC |
273 | |
274 | if (type == SSL3_RT_HANDSHAKE && !s->d1->retransmitting) { | |
275 | /* | |
276 | * should not be done for 'Hello Request's, but in that case | |
277 | * we'll ignore the result anyway | |
278 | */ | |
279 | unsigned char *p = | |
280 | (unsigned char *)&s->init_buf->data[s->init_off]; | |
281 | const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; | |
7ee8627f | 282 | size_t xlen; |
0f113f3e MC |
283 | |
284 | if (frag_off == 0 && s->version != DTLS1_BAD_VER) { | |
285 | /* | |
286 | * reconstruct message header is if it is being sent in | |
287 | * single fragment | |
288 | */ | |
289 | *p++ = msg_hdr->type; | |
290 | l2n3(msg_hdr->msg_len, p); | |
291 | s2n(msg_hdr->seq, p); | |
292 | l2n3(0, p); | |
293 | l2n3(msg_hdr->msg_len, p); | |
294 | p -= DTLS1_HM_HEADER_LENGTH; | |
7ee8627f | 295 | xlen = written; |
0f113f3e MC |
296 | } else { |
297 | p += DTLS1_HM_HEADER_LENGTH; | |
7ee8627f | 298 | xlen = written - DTLS1_HM_HEADER_LENGTH; |
0f113f3e MC |
299 | } |
300 | ||
d166ed8c DSH |
301 | if (!ssl3_finish_mac(s, p, xlen)) |
302 | return -1; | |
0f113f3e MC |
303 | } |
304 | ||
7ee8627f | 305 | if (written == s->init_num) { |
0f113f3e MC |
306 | if (s->msg_callback) |
307 | s->msg_callback(1, s->version, type, s->init_buf->data, | |
38b051a1 | 308 | (size_t)(s->init_off + s->init_num), ssl, |
0f113f3e MC |
309 | s->msg_callback_arg); |
310 | ||
311 | s->init_off = 0; /* done writing this message */ | |
312 | s->init_num = 0; | |
313 | ||
7ee8627f | 314 | return 1; |
0f113f3e | 315 | } |
7ee8627f MC |
316 | s->init_off += written; |
317 | s->init_num -= written; | |
318 | written -= DTLS1_HM_HEADER_LENGTH; | |
319 | frag_off += written; | |
2ad226e8 MC |
320 | |
321 | /* | |
322 | * We save the fragment offset for the next fragment so we have it | |
323 | * available in case of an IO retry. We don't know the length of the | |
324 | * next fragment yet so just set that to 0 for now. It will be | |
325 | * updated again later. | |
326 | */ | |
327 | dtls1_fix_message_header(s, frag_off, 0); | |
0f113f3e MC |
328 | } |
329 | } | |
7ee8627f | 330 | return 0; |
0f113f3e MC |
331 | } |
332 | ||
38b051a1 | 333 | int dtls_get_message(SSL_CONNECTION *s, int *mt) |
76af3037 MC |
334 | { |
335 | struct hm_header_st *msg_hdr; | |
336 | unsigned char *p; | |
7ee8627f MC |
337 | size_t msg_len; |
338 | size_t tmplen; | |
339 | int errtype; | |
76af3037 MC |
340 | |
341 | msg_hdr = &s->d1->r_msg_hdr; | |
342 | memset(msg_hdr, 0, sizeof(*msg_hdr)); | |
343 | ||
344 | again: | |
7ee8627f MC |
345 | if (!dtls_get_reassembled_message(s, &errtype, &tmplen)) { |
346 | if (errtype == DTLS1_HM_BAD_FRAGMENT | |
347 | || errtype == DTLS1_HM_FRAGMENT_RETRY) { | |
348 | /* bad fragment received */ | |
349 | goto again; | |
350 | } | |
76af3037 MC |
351 | return 0; |
352 | } | |
353 | ||
555cbb32 | 354 | *mt = s->s3.tmp.message_type; |
76af3037 MC |
355 | |
356 | p = (unsigned char *)s->init_buf->data; | |
357 | ||
358 | if (*mt == SSL3_MT_CHANGE_CIPHER_SPEC) { | |
359 | if (s->msg_callback) { | |
360 | s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, | |
38b051a1 TM |
361 | p, 1, SSL_CONNECTION_GET_SSL(s), |
362 | s->msg_callback_arg); | |
76af3037 MC |
363 | } |
364 | /* | |
365 | * This isn't a real handshake message so skip the processing below. | |
366 | */ | |
367 | return 1; | |
368 | } | |
369 | ||
370 | msg_len = msg_hdr->msg_len; | |
371 | ||
372 | /* reconstruct message header */ | |
373 | *(p++) = msg_hdr->type; | |
374 | l2n3(msg_len, p); | |
375 | s2n(msg_hdr->seq, p); | |
376 | l2n3(0, p); | |
377 | l2n3(msg_len, p); | |
76af3037 | 378 | |
f42e68dc MC |
379 | memset(msg_hdr, 0, sizeof(*msg_hdr)); |
380 | ||
381 | s->d1->handshake_read_seq++; | |
382 | ||
383 | s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; | |
384 | ||
385 | return 1; | |
386 | } | |
387 | ||
388 | /* | |
389 | * Actually we already have the message body - but this is an opportunity for | |
390 | * DTLS to do any further processing it wants at the same point that TLS would | |
391 | * be asked for the message body. | |
392 | */ | |
38b051a1 | 393 | int dtls_get_message_body(SSL_CONNECTION *s, size_t *len) |
f42e68dc MC |
394 | { |
395 | unsigned char *msg = (unsigned char *)s->init_buf->data; | |
396 | size_t msg_len = s->init_num + DTLS1_HM_HEADER_LENGTH; | |
397 | ||
398 | if (s->s3.tmp.message_type == SSL3_MT_CHANGE_CIPHER_SPEC) { | |
399 | /* Nothing to be done */ | |
400 | goto end; | |
401 | } | |
5d671101 MC |
402 | /* |
403 | * If receiving Finished, record MAC of prior handshake messages for | |
404 | * Finished verification. | |
405 | */ | |
f42e68dc | 406 | if (*(s->init_buf->data) == SSL3_MT_FINISHED && !ssl3_take_mac(s)) { |
5d671101 MC |
407 | /* SSLfatal() already called */ |
408 | return 0; | |
409 | } | |
410 | ||
f42e68dc MC |
411 | if (s->version == DTLS1_BAD_VER) { |
412 | msg += DTLS1_HM_HEADER_LENGTH; | |
413 | msg_len -= DTLS1_HM_HEADER_LENGTH; | |
414 | } | |
415 | ||
416 | if (!ssl3_finish_mac(s, msg, msg_len)) | |
d166ed8c | 417 | return 0; |
f42e68dc | 418 | |
76af3037 MC |
419 | if (s->msg_callback) |
420 | s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, | |
f42e68dc | 421 | s->init_buf->data, s->init_num + DTLS1_HM_HEADER_LENGTH, |
38b051a1 | 422 | SSL_CONNECTION_GET_SSL(s), s->msg_callback_arg); |
76af3037 | 423 | |
f42e68dc MC |
424 | end: |
425 | *len = s->init_num; | |
76af3037 MC |
426 | return 1; |
427 | } | |
428 | ||
48c054fe MC |
429 | /* |
430 | * dtls1_max_handshake_message_len returns the maximum number of bytes | |
431 | * permitted in a DTLS handshake message for |s|. The minimum is 16KB, but | |
432 | * may be greater if the maximum certificate list size requires it. | |
433 | */ | |
38b051a1 | 434 | static size_t dtls1_max_handshake_message_len(const SSL_CONNECTION *s) |
48c054fe | 435 | { |
348240c6 MC |
436 | size_t max_len = DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH; |
437 | if (max_len < s->max_cert_list) | |
48c054fe MC |
438 | return s->max_cert_list; |
439 | return max_len; | |
440 | } | |
441 | ||
38b051a1 TM |
442 | static int dtls1_preprocess_fragment(SSL_CONNECTION *s, |
443 | struct hm_header_st *msg_hdr) | |
0f113f3e MC |
444 | { |
445 | size_t frag_off, frag_len, msg_len; | |
446 | ||
447 | msg_len = msg_hdr->msg_len; | |
448 | frag_off = msg_hdr->frag_off; | |
449 | frag_len = msg_hdr->frag_len; | |
450 | ||
451 | /* sanity checking */ | |
48c054fe MC |
452 | if ((frag_off + frag_len) > msg_len |
453 | || msg_len > dtls1_max_handshake_message_len(s)) { | |
c48ffbcc | 454 | SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_EXCESSIVE_MESSAGE_SIZE); |
d273b60b | 455 | return 0; |
0f113f3e MC |
456 | } |
457 | ||
0f113f3e MC |
458 | if (s->d1->r_msg_hdr.frag_off == 0) { /* first fragment */ |
459 | /* | |
48c054fe MC |
460 | * msg_len is limited to 2^24, but is effectively checked against |
461 | * dtls_max_handshake_message_len(s) above | |
0f113f3e | 462 | */ |
a230b26e | 463 | if (!BUF_MEM_grow_clean(s->init_buf, msg_len + DTLS1_HM_HEADER_LENGTH)) { |
c48ffbcc | 464 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_BUF_LIB); |
d273b60b | 465 | return 0; |
0f113f3e MC |
466 | } |
467 | ||
555cbb32 | 468 | s->s3.tmp.message_size = msg_len; |
0f113f3e | 469 | s->d1->r_msg_hdr.msg_len = msg_len; |
555cbb32 | 470 | s->s3.tmp.message_type = msg_hdr->type; |
0f113f3e MC |
471 | s->d1->r_msg_hdr.type = msg_hdr->type; |
472 | s->d1->r_msg_hdr.seq = msg_hdr->seq; | |
473 | } else if (msg_len != s->d1->r_msg_hdr.msg_len) { | |
474 | /* | |
475 | * They must be playing with us! BTW, failure to enforce upper limit | |
476 | * would open possibility for buffer overrun. | |
477 | */ | |
c48ffbcc | 478 | SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_EXCESSIVE_MESSAGE_SIZE); |
d273b60b | 479 | return 0; |
0f113f3e MC |
480 | } |
481 | ||
d273b60b | 482 | return 1; |
0f113f3e | 483 | } |
90acf770 | 484 | |
d273b60b MC |
485 | /* |
486 | * Returns 1 if there is a buffered fragment available, 0 if not, or -1 on a | |
487 | * fatal error. | |
488 | */ | |
38b051a1 | 489 | static int dtls1_retrieve_buffered_fragment(SSL_CONNECTION *s, size_t *len) |
0f113f3e | 490 | { |
50e735f9 MC |
491 | /*- |
492 | * (0) check whether the desired fragment is available | |
493 | * if so: | |
494 | * (1) copy over the fragment to s->init_buf->data[] | |
495 | * (2) update s->init_num | |
496 | */ | |
0f113f3e | 497 | pitem *item; |
81926c91 | 498 | piterator iter; |
0f113f3e | 499 | hm_fragment *frag; |
d273b60b | 500 | int ret; |
81926c91 | 501 | int chretran = 0; |
0f113f3e | 502 | |
81926c91 | 503 | iter = pqueue_iterator(s->d1->buffered_messages); |
f5c7f5df | 504 | do { |
81926c91 | 505 | item = pqueue_next(&iter); |
f5c7f5df MC |
506 | if (item == NULL) |
507 | return 0; | |
508 | ||
509 | frag = (hm_fragment *)item->data; | |
510 | ||
511 | if (frag->msg_header.seq < s->d1->handshake_read_seq) { | |
81926c91 MC |
512 | pitem *next; |
513 | hm_fragment *nextfrag; | |
514 | ||
515 | if (!s->server | |
516 | || frag->msg_header.seq != 0 | |
517 | || s->d1->handshake_read_seq != 1 | |
518 | || s->statem.hand_state != DTLS_ST_SW_HELLO_VERIFY_REQUEST) { | |
519 | /* | |
520 | * This is a stale message that has been buffered so clear it. | |
521 | * It is safe to pop this message from the queue even though | |
522 | * we have an active iterator | |
523 | */ | |
524 | pqueue_pop(s->d1->buffered_messages); | |
525 | dtls1_hm_fragment_free(frag); | |
526 | pitem_free(item); | |
527 | item = NULL; | |
528 | frag = NULL; | |
529 | } else { | |
530 | /* | |
531 | * We have fragments for a ClientHello without a cookie, | |
532 | * even though we have sent a HelloVerifyRequest. It is possible | |
533 | * that the HelloVerifyRequest got lost and this is a | |
534 | * retransmission of the original ClientHello | |
535 | */ | |
536 | next = pqueue_next(&iter); | |
537 | if (next != NULL) { | |
538 | nextfrag = (hm_fragment *)next->data; | |
539 | if (nextfrag->msg_header.seq == s->d1->handshake_read_seq) { | |
540 | /* | |
541 | * We have fragments for both a ClientHello without | |
542 | * cookie and one with. Ditch the one without. | |
543 | */ | |
544 | pqueue_pop(s->d1->buffered_messages); | |
545 | dtls1_hm_fragment_free(frag); | |
546 | pitem_free(item); | |
547 | item = next; | |
548 | frag = nextfrag; | |
549 | } else { | |
550 | chretran = 1; | |
551 | } | |
552 | } else { | |
553 | chretran = 1; | |
554 | } | |
555 | } | |
f5c7f5df MC |
556 | } |
557 | } while (item == NULL); | |
0f113f3e MC |
558 | |
559 | /* Don't return if reassembly still in progress */ | |
560 | if (frag->reassembly != NULL) | |
561 | return 0; | |
562 | ||
81926c91 | 563 | if (s->d1->handshake_read_seq == frag->msg_header.seq || chretran) { |
7ee8627f | 564 | size_t frag_len = frag->msg_header.frag_len; |
0f113f3e MC |
565 | pqueue_pop(s->d1->buffered_messages); |
566 | ||
d273b60b MC |
567 | /* Calls SSLfatal() as required */ |
568 | ret = dtls1_preprocess_fragment(s, &frag->msg_header); | |
0f113f3e | 569 | |
a925e7db | 570 | if (ret && frag->msg_header.frag_len > 0) { |
0f113f3e MC |
571 | unsigned char *p = |
572 | (unsigned char *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH; | |
573 | memcpy(&p[frag->msg_header.frag_off], frag->fragment, | |
574 | frag->msg_header.frag_len); | |
575 | } | |
576 | ||
577 | dtls1_hm_fragment_free(frag); | |
578 | pitem_free(item); | |
579 | ||
d273b60b | 580 | if (ret) { |
81926c91 MC |
581 | if (chretran) { |
582 | /* | |
583 | * We got a new ClientHello with a message sequence of 0. | |
584 | * Reset the read/write sequences back to the beginning. | |
585 | * We process it like this is the first time we've seen a | |
586 | * ClientHello from the client. | |
587 | */ | |
588 | s->d1->handshake_read_seq = 0; | |
589 | s->d1->next_handshake_write_seq = 0; | |
590 | } | |
7ee8627f MC |
591 | *len = frag_len; |
592 | return 1; | |
0f113f3e MC |
593 | } |
594 | ||
d273b60b | 595 | /* Fatal error */ |
0f113f3e | 596 | s->init_num = 0; |
d273b60b | 597 | return -1; |
7ee8627f MC |
598 | } else { |
599 | return 0; | |
600 | } | |
0f113f3e MC |
601 | } |
602 | ||
38b051a1 TM |
603 | static int dtls1_reassemble_fragment(SSL_CONNECTION *s, |
604 | const struct hm_header_st *msg_hdr) | |
0f113f3e MC |
605 | { |
606 | hm_fragment *frag = NULL; | |
607 | pitem *item = NULL; | |
608 | int i = -1, is_complete; | |
609 | unsigned char seq64be[8]; | |
7ee8627f | 610 | size_t frag_len = msg_hdr->frag_len; |
54105ddd | 611 | size_t readbytes; |
38b051a1 | 612 | SSL *ssl = SSL_CONNECTION_GET_SSL(s); |
0f113f3e MC |
613 | |
614 | if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len || | |
615 | msg_hdr->msg_len > dtls1_max_handshake_message_len(s)) | |
616 | goto err; | |
617 | ||
7ee8627f | 618 | if (frag_len == 0) { |
0f113f3e | 619 | return DTLS1_HM_FRAGMENT_RETRY; |
7ee8627f | 620 | } |
0f113f3e MC |
621 | |
622 | /* Try to find item in queue */ | |
623 | memset(seq64be, 0, sizeof(seq64be)); | |
624 | seq64be[6] = (unsigned char)(msg_hdr->seq >> 8); | |
625 | seq64be[7] = (unsigned char)msg_hdr->seq; | |
626 | item = pqueue_find(s->d1->buffered_messages, seq64be); | |
627 | ||
628 | if (item == NULL) { | |
629 | frag = dtls1_hm_fragment_new(msg_hdr->msg_len, 1); | |
630 | if (frag == NULL) | |
631 | goto err; | |
632 | memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); | |
633 | frag->msg_header.frag_len = frag->msg_header.msg_len; | |
634 | frag->msg_header.frag_off = 0; | |
635 | } else { | |
636 | frag = (hm_fragment *)item->data; | |
637 | if (frag->msg_header.msg_len != msg_hdr->msg_len) { | |
638 | item = NULL; | |
639 | frag = NULL; | |
640 | goto err; | |
641 | } | |
642 | } | |
643 | ||
644 | /* | |
645 | * If message is already reassembled, this must be a retransmit and can | |
646 | * be dropped. In this case item != NULL and so frag does not need to be | |
647 | * freed. | |
648 | */ | |
649 | if (frag->reassembly == NULL) { | |
650 | unsigned char devnull[256]; | |
651 | ||
652 | while (frag_len) { | |
38b051a1 TM |
653 | i = ssl->method->ssl_read_bytes(ssl, SSL3_RT_HANDSHAKE, NULL, |
654 | devnull, | |
655 | frag_len > | |
656 | sizeof(devnull) ? sizeof(devnull) : | |
657 | frag_len, 0, &readbytes); | |
0f113f3e MC |
658 | if (i <= 0) |
659 | goto err; | |
54105ddd | 660 | frag_len -= readbytes; |
0f113f3e MC |
661 | } |
662 | return DTLS1_HM_FRAGMENT_RETRY; | |
663 | } | |
664 | ||
665 | /* read the body of the fragment (header has already been read */ | |
38b051a1 TM |
666 | i = ssl->method->ssl_read_bytes(ssl, SSL3_RT_HANDSHAKE, NULL, |
667 | frag->fragment + msg_hdr->frag_off, | |
668 | frag_len, 0, &readbytes); | |
54105ddd | 669 | if (i <= 0 || readbytes != frag_len) |
0f113f3e MC |
670 | i = -1; |
671 | if (i <= 0) | |
672 | goto err; | |
673 | ||
674 | RSMBLY_BITMASK_MARK(frag->reassembly, (long)msg_hdr->frag_off, | |
675 | (long)(msg_hdr->frag_off + frag_len)); | |
676 | ||
380a522f MC |
677 | if (!ossl_assert(msg_hdr->msg_len > 0)) |
678 | goto err; | |
0f113f3e MC |
679 | RSMBLY_BITMASK_IS_COMPLETE(frag->reassembly, (long)msg_hdr->msg_len, |
680 | is_complete); | |
681 | ||
682 | if (is_complete) { | |
683 | OPENSSL_free(frag->reassembly); | |
684 | frag->reassembly = NULL; | |
685 | } | |
686 | ||
687 | if (item == NULL) { | |
688 | item = pitem_new(seq64be, frag); | |
689 | if (item == NULL) { | |
690 | i = -1; | |
691 | goto err; | |
692 | } | |
693 | ||
694 | item = pqueue_insert(s->d1->buffered_messages, item); | |
695 | /* | |
696 | * pqueue_insert fails iff a duplicate item is inserted. However, | |
697 | * |item| cannot be a duplicate. If it were, |pqueue_find|, above, | |
698 | * would have returned it and control would never have reached this | |
699 | * branch. | |
700 | */ | |
380a522f MC |
701 | if (!ossl_assert(item != NULL)) |
702 | goto err; | |
0f113f3e MC |
703 | } |
704 | ||
705 | return DTLS1_HM_FRAGMENT_RETRY; | |
706 | ||
707 | err: | |
25aaa98a | 708 | if (item == NULL) |
0f113f3e | 709 | dtls1_hm_fragment_free(frag); |
7ee8627f | 710 | return -1; |
0f113f3e | 711 | } |
934e22e8 | 712 | |
38b051a1 TM |
713 | static int dtls1_process_out_of_seq_message(SSL_CONNECTION *s, |
714 | const struct hm_header_st *msg_hdr) | |
36d16f8e | 715 | { |
0f113f3e MC |
716 | int i = -1; |
717 | hm_fragment *frag = NULL; | |
718 | pitem *item = NULL; | |
719 | unsigned char seq64be[8]; | |
7ee8627f | 720 | size_t frag_len = msg_hdr->frag_len; |
54105ddd | 721 | size_t readbytes; |
38b051a1 | 722 | SSL *ssl = SSL_CONNECTION_GET_SSL(s); |
0f113f3e MC |
723 | |
724 | if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len) | |
725 | goto err; | |
726 | ||
727 | /* Try to find item in queue, to prevent duplicate entries */ | |
728 | memset(seq64be, 0, sizeof(seq64be)); | |
729 | seq64be[6] = (unsigned char)(msg_hdr->seq >> 8); | |
730 | seq64be[7] = (unsigned char)msg_hdr->seq; | |
731 | item = pqueue_find(s->d1->buffered_messages, seq64be); | |
732 | ||
733 | /* | |
734 | * If we already have an entry and this one is a fragment, don't discard | |
735 | * it and rather try to reassemble it. | |
736 | */ | |
737 | if (item != NULL && frag_len != msg_hdr->msg_len) | |
738 | item = NULL; | |
739 | ||
740 | /* | |
741 | * Discard the message if sequence number was already there, is too far | |
742 | * in the future, already in the queue or if we received a FINISHED | |
743 | * before the SERVER_HELLO, which then must be a stale retransmit. | |
744 | */ | |
745 | if (msg_hdr->seq <= s->d1->handshake_read_seq || | |
746 | msg_hdr->seq > s->d1->handshake_read_seq + 10 || item != NULL || | |
a230b26e | 747 | (s->d1->handshake_read_seq == 0 && msg_hdr->type == SSL3_MT_FINISHED)) { |
0f113f3e MC |
748 | unsigned char devnull[256]; |
749 | ||
750 | while (frag_len) { | |
38b051a1 TM |
751 | i = ssl->method->ssl_read_bytes(ssl, SSL3_RT_HANDSHAKE, NULL, |
752 | devnull, | |
753 | frag_len > | |
754 | sizeof(devnull) ? sizeof(devnull) : | |
755 | frag_len, 0, &readbytes); | |
0f113f3e MC |
756 | if (i <= 0) |
757 | goto err; | |
54105ddd | 758 | frag_len -= readbytes; |
0f113f3e MC |
759 | } |
760 | } else { | |
7ee8627f | 761 | if (frag_len != msg_hdr->msg_len) { |
0fe2a0af | 762 | return dtls1_reassemble_fragment(s, msg_hdr); |
7ee8627f | 763 | } |
0f113f3e MC |
764 | |
765 | if (frag_len > dtls1_max_handshake_message_len(s)) | |
766 | goto err; | |
767 | ||
768 | frag = dtls1_hm_fragment_new(frag_len, 0); | |
769 | if (frag == NULL) | |
770 | goto err; | |
771 | ||
772 | memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); | |
773 | ||
774 | if (frag_len) { | |
775 | /* | |
776 | * read the body of the fragment (header has already been read | |
777 | */ | |
38b051a1 TM |
778 | i = ssl->method->ssl_read_bytes(ssl, SSL3_RT_HANDSHAKE, NULL, |
779 | frag->fragment, frag_len, 0, | |
780 | &readbytes); | |
54105ddd | 781 | if (i<=0 || readbytes != frag_len) |
0f113f3e MC |
782 | i = -1; |
783 | if (i <= 0) | |
784 | goto err; | |
785 | } | |
786 | ||
787 | item = pitem_new(seq64be, frag); | |
788 | if (item == NULL) | |
789 | goto err; | |
790 | ||
791 | item = pqueue_insert(s->d1->buffered_messages, item); | |
792 | /* | |
793 | * pqueue_insert fails iff a duplicate item is inserted. However, | |
794 | * |item| cannot be a duplicate. If it were, |pqueue_find|, above, | |
795 | * would have returned it. Then, either |frag_len| != | |
796 | * |msg_hdr->msg_len| in which case |item| is set to NULL and it will | |
797 | * have been processed with |dtls1_reassemble_fragment|, above, or | |
798 | * the record will have been discarded. | |
799 | */ | |
380a522f MC |
800 | if (!ossl_assert(item != NULL)) |
801 | goto err; | |
0f113f3e MC |
802 | } |
803 | ||
804 | return DTLS1_HM_FRAGMENT_RETRY; | |
805 | ||
806 | err: | |
25aaa98a | 807 | if (item == NULL) |
0f113f3e | 808 | dtls1_hm_fragment_free(frag); |
7ee8627f | 809 | return 0; |
0f113f3e | 810 | } |
36d16f8e | 811 | |
38b051a1 TM |
812 | static int dtls_get_reassembled_message(SSL_CONNECTION *s, int *errtype, |
813 | size_t *len) | |
0f113f3e MC |
814 | { |
815 | unsigned char wire[DTLS1_HM_HEADER_LENGTH]; | |
7ee8627f | 816 | size_t mlen, frag_off, frag_len; |
d273b60b | 817 | int i, ret, recvd_type; |
0f113f3e | 818 | struct hm_header_st msg_hdr; |
54105ddd | 819 | size_t readbytes; |
38b051a1 | 820 | SSL *ssl = SSL_CONNECTION_GET_SSL(s); |
81926c91 | 821 | int chretran = 0; |
0f113f3e | 822 | |
7ee8627f MC |
823 | *errtype = 0; |
824 | ||
0f113f3e MC |
825 | redo: |
826 | /* see if we have the required fragment already */ | |
d273b60b MC |
827 | ret = dtls1_retrieve_buffered_fragment(s, &frag_len); |
828 | if (ret < 0) { | |
829 | /* SSLfatal() already called */ | |
830 | return 0; | |
831 | } | |
832 | if (ret > 0) { | |
7ee8627f | 833 | s->init_num = frag_len; |
76af3037 | 834 | *len = frag_len; |
7ee8627f | 835 | return 1; |
0f113f3e MC |
836 | } |
837 | ||
838 | /* read handshake message header */ | |
38b051a1 TM |
839 | i = ssl->method->ssl_read_bytes(ssl, SSL3_RT_HANDSHAKE, &recvd_type, wire, |
840 | DTLS1_HM_HEADER_LENGTH, 0, &readbytes); | |
0f113f3e MC |
841 | if (i <= 0) { /* nbio, or an error */ |
842 | s->rwstate = SSL_READING; | |
7ee8627f | 843 | *len = 0; |
76af3037 | 844 | return 0; |
0f113f3e | 845 | } |
e8aa8b6c | 846 | if (recvd_type == SSL3_RT_CHANGE_CIPHER_SPEC) { |
76af3037 | 847 | if (wire[0] != SSL3_MT_CCS) { |
d273b60b | 848 | SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, |
d273b60b | 849 | SSL_R_BAD_CHANGE_CIPHER_SPEC); |
76af3037 | 850 | goto f_err; |
c69f2adf | 851 | } |
76af3037 | 852 | |
54105ddd MC |
853 | memcpy(s->init_buf->data, wire, readbytes); |
854 | s->init_num = readbytes - 1; | |
76af3037 | 855 | s->init_msg = s->init_buf->data + 1; |
555cbb32 TS |
856 | s->s3.tmp.message_type = SSL3_MT_CHANGE_CIPHER_SPEC; |
857 | s->s3.tmp.message_size = readbytes - 1; | |
54105ddd | 858 | *len = readbytes - 1; |
76af3037 | 859 | return 1; |
c69f2adf MC |
860 | } |
861 | ||
0f113f3e | 862 | /* Handshake fails if message header is incomplete */ |
54105ddd | 863 | if (readbytes != DTLS1_HM_HEADER_LENGTH) { |
c48ffbcc | 864 | SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); |
0f113f3e MC |
865 | goto f_err; |
866 | } | |
867 | ||
868 | /* parse the message fragment header */ | |
869 | dtls1_get_message_header(wire, &msg_hdr); | |
870 | ||
76af3037 | 871 | mlen = msg_hdr.msg_len; |
91d13f1a MC |
872 | frag_off = msg_hdr.frag_off; |
873 | frag_len = msg_hdr.frag_len; | |
874 | ||
875 | /* | |
876 | * We must have at least frag_len bytes left in the record to be read. | |
877 | * Fragments must not span records. | |
878 | */ | |
eddb067e | 879 | if (frag_len > s->rlayer.tlsrecs[s->rlayer.curr_rec].length) { |
c48ffbcc | 880 | SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_LENGTH); |
91d13f1a MC |
881 | goto f_err; |
882 | } | |
883 | ||
0f113f3e MC |
884 | /* |
885 | * if this is a future (or stale) message it gets buffered | |
886 | * (or dropped)--no further processing at this time | |
887 | * While listening, we accept seq 1 (ClientHello with cookie) | |
888 | * although we're still expecting seq 0 (ClientHello) | |
889 | */ | |
76af3037 | 890 | if (msg_hdr.seq != s->d1->handshake_read_seq) { |
81926c91 MC |
891 | if (!s->server |
892 | || msg_hdr.seq != 0 | |
893 | || s->d1->handshake_read_seq != 1 | |
894 | || wire[0] != SSL3_MT_CLIENT_HELLO | |
895 | || s->statem.hand_state != DTLS_ST_SW_HELLO_VERIFY_REQUEST) { | |
896 | *errtype = dtls1_process_out_of_seq_message(s, &msg_hdr); | |
897 | return 0; | |
898 | } | |
899 | /* | |
900 | * We received a ClientHello and sent back a HelloVerifyRequest. We | |
901 | * now seem to have received a retransmitted initial ClientHello. That | |
902 | * is allowed (possibly our HelloVerifyRequest got lost). | |
903 | */ | |
904 | chretran = 1; | |
76af3037 | 905 | } |
0f113f3e | 906 | |
76af3037 | 907 | if (frag_len && frag_len < mlen) { |
7ee8627f MC |
908 | *errtype = dtls1_reassemble_fragment(s, &msg_hdr); |
909 | return 0; | |
76af3037 | 910 | } |
0f113f3e | 911 | |
1f5b44e9 MC |
912 | if (!s->server |
913 | && s->d1->r_msg_hdr.frag_off == 0 | |
c7f47786 MC |
914 | && s->statem.hand_state != TLS_ST_OK |
915 | && wire[0] == SSL3_MT_HELLO_REQUEST) { | |
0f113f3e MC |
916 | /* |
917 | * The server may always send 'Hello Request' messages -- we are | |
918 | * doing a handshake anyway now, so ignore them if their format is | |
919 | * correct. Does not count for 'Finished' MAC. | |
920 | */ | |
921 | if (wire[1] == 0 && wire[2] == 0 && wire[3] == 0) { | |
922 | if (s->msg_callback) | |
923 | s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, | |
38b051a1 | 924 | wire, DTLS1_HM_HEADER_LENGTH, ssl, |
0f113f3e MC |
925 | s->msg_callback_arg); |
926 | ||
927 | s->init_num = 0; | |
928 | goto redo; | |
60250017 | 929 | } else { /* Incorrectly formatted Hello request */ |
0f113f3e | 930 | |
c48ffbcc | 931 | SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); |
0f113f3e MC |
932 | goto f_err; |
933 | } | |
934 | } | |
935 | ||
d273b60b MC |
936 | if (!dtls1_preprocess_fragment(s, &msg_hdr)) { |
937 | /* SSLfatal() already called */ | |
0f113f3e | 938 | goto f_err; |
d273b60b | 939 | } |
0f113f3e | 940 | |
0f113f3e MC |
941 | if (frag_len > 0) { |
942 | unsigned char *p = | |
943 | (unsigned char *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH; | |
944 | ||
38b051a1 TM |
945 | i = ssl->method->ssl_read_bytes(ssl, SSL3_RT_HANDSHAKE, NULL, |
946 | &p[frag_off], frag_len, 0, &readbytes); | |
91d13f1a | 947 | |
0f113f3e | 948 | /* |
91d13f1a MC |
949 | * This shouldn't ever fail due to NBIO because we already checked |
950 | * that we have enough data in the record | |
0f113f3e MC |
951 | */ |
952 | if (i <= 0) { | |
953 | s->rwstate = SSL_READING; | |
7ee8627f | 954 | *len = 0; |
76af3037 | 955 | return 0; |
0f113f3e | 956 | } |
7ee8627f | 957 | } else { |
54105ddd | 958 | readbytes = 0; |
7ee8627f | 959 | } |
0f113f3e MC |
960 | |
961 | /* | |
962 | * XDTLS: an incorrectly formatted fragment should cause the handshake | |
963 | * to fail | |
964 | */ | |
54105ddd | 965 | if (readbytes != frag_len) { |
c48ffbcc | 966 | SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_LENGTH); |
0f113f3e MC |
967 | goto f_err; |
968 | } | |
969 | ||
81926c91 MC |
970 | if (chretran) { |
971 | /* | |
972 | * We got a new ClientHello with a message sequence of 0. | |
973 | * Reset the read/write sequences back to the beginning. | |
974 | * We process it like this is the first time we've seen a ClientHello | |
975 | * from the client. | |
976 | */ | |
977 | s->d1->handshake_read_seq = 0; | |
978 | s->d1->next_handshake_write_seq = 0; | |
979 | } | |
980 | ||
0f113f3e MC |
981 | /* |
982 | * Note that s->init_num is *not* used as current offset in | |
983 | * s->init_buf->data, but as a counter summing up fragments' lengths: as | |
984 | * soon as they sum up to handshake packet length, we assume we have got | |
985 | * all the fragments. | |
986 | */ | |
76af3037 MC |
987 | *len = s->init_num = frag_len; |
988 | return 1; | |
0f113f3e MC |
989 | |
990 | f_err: | |
0f113f3e | 991 | s->init_num = 0; |
7ee8627f | 992 | *len = 0; |
76af3037 | 993 | return 0; |
0f113f3e | 994 | } |
36d16f8e | 995 | |
1d97c843 TH |
996 | /*- |
997 | * for these 2 messages, we need to | |
0f113f3e | 998 | * ssl->enc_read_ctx re-init |
555cbb32 | 999 | * ssl->s3.read_mac_secret re-init |
0f113f3e MC |
1000 | * ssl->session->read_sym_enc assign |
1001 | * ssl->session->read_compression assign | |
1002 | * ssl->session->read_hash assign | |
36d16f8e | 1003 | */ |
67ec6d2b MC |
1004 | CON_FUNC_RETURN dtls_construct_change_cipher_spec(SSL_CONNECTION *s, |
1005 | WPACKET *pkt) | |
0f113f3e | 1006 | { |
473483d4 MC |
1007 | if (s->version == DTLS1_BAD_VER) { |
1008 | s->d1->next_handshake_write_seq++; | |
85a7a5e6 | 1009 | |
7cea05dc | 1010 | if (!WPACKET_put_bytes_u16(pkt, s->d1->handshake_write_seq)) { |
c48ffbcc | 1011 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); |
67ec6d2b | 1012 | return CON_FUNC_ERROR; |
85a7a5e6 | 1013 | } |
0f113f3e | 1014 | } |
36d16f8e | 1015 | |
67ec6d2b | 1016 | return CON_FUNC_SUCCESS; |
473483d4 MC |
1017 | } |
1018 | ||
1019 | #ifndef OPENSSL_NO_SCTP | |
2e92af5e MC |
1020 | /* |
1021 | * Wait for a dry event. Should only be called at a point in the handshake | |
1022 | * where we are not expecting any data from the peer except an alert. | |
1023 | */ | |
38b051a1 | 1024 | WORK_STATE dtls_wait_for_dry(SSL_CONNECTION *s) |
473483d4 | 1025 | { |
2e92af5e MC |
1026 | int ret, errtype; |
1027 | size_t len; | |
38b051a1 | 1028 | SSL *ssl = SSL_CONNECTION_GET_SSL(s); |
473483d4 MC |
1029 | |
1030 | /* read app data until dry event */ | |
38b051a1 | 1031 | ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(ssl)); |
a2c2e000 | 1032 | if (ret < 0) { |
c48ffbcc | 1033 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); |
473483d4 | 1034 | return WORK_ERROR; |
a2c2e000 | 1035 | } |
473483d4 MC |
1036 | |
1037 | if (ret == 0) { | |
2e92af5e MC |
1038 | /* |
1039 | * We're not expecting any more messages from the peer at this point - | |
1040 | * but we could get an alert. If an alert is waiting then we will never | |
1041 | * return successfully. Therefore we attempt to read a message. This | |
1042 | * should never succeed but will process any waiting alerts. | |
1043 | */ | |
1044 | if (dtls_get_reassembled_message(s, &errtype, &len)) { | |
1045 | /* The call succeeded! This should never happen */ | |
c48ffbcc | 1046 | SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); |
2e92af5e MC |
1047 | return WORK_ERROR; |
1048 | } | |
1049 | ||
555cbb32 | 1050 | s->s3.in_read_app_data = 2; |
473483d4 | 1051 | s->rwstate = SSL_READING; |
38b051a1 TM |
1052 | BIO_clear_retry_flags(SSL_get_rbio(ssl)); |
1053 | BIO_set_retry_read(SSL_get_rbio(ssl)); | |
473483d4 MC |
1054 | return WORK_MORE_A; |
1055 | } | |
1056 | return WORK_FINISHED_CONTINUE; | |
0f113f3e | 1057 | } |
473483d4 | 1058 | #endif |
36d16f8e | 1059 | |
38b051a1 | 1060 | int dtls1_read_failed(SSL_CONNECTION *s, int code) |
0f113f3e | 1061 | { |
38b051a1 TM |
1062 | SSL *ssl = SSL_CONNECTION_GET_SSL(s); |
1063 | ||
0f113f3e | 1064 | if (code > 0) { |
c48ffbcc | 1065 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); |
d273b60b | 1066 | return 0; |
0f113f3e MC |
1067 | } |
1068 | ||
c2853382 | 1069 | if (!dtls1_is_timer_expired(s) || ossl_statem_in_error(s)) { |
0f113f3e MC |
1070 | /* |
1071 | * not a timeout, none of our business, let higher layers handle | |
1072 | * this. in fact it's probably an error | |
1073 | */ | |
1074 | return code; | |
1075 | } | |
0f113f3e | 1076 | /* done, no need to send a retransmit */ |
38b051a1 | 1077 | if (!SSL_in_init(ssl)) |
0f113f3e | 1078 | { |
38b051a1 | 1079 | BIO_set_flags(SSL_get_rbio(ssl), BIO_FLAGS_READ); |
0f113f3e MC |
1080 | return code; |
1081 | } | |
36d16f8e | 1082 | |
0f113f3e MC |
1083 | return dtls1_handle_timeout(s); |
1084 | } | |
36d16f8e | 1085 | |
0f113f3e MC |
1086 | int dtls1_get_queue_priority(unsigned short seq, int is_ccs) |
1087 | { | |
1088 | /* | |
1089 | * The index of the retransmission queue actually is the message sequence | |
1090 | * number, since the queue only contains messages of a single handshake. | |
1091 | * However, the ChangeCipherSpec has no message sequence number and so | |
1092 | * using only the sequence will result in the CCS and Finished having the | |
1093 | * same index. To prevent this, the sequence number is multiplied by 2. | |
1094 | * In case of a CCS 1 is subtracted. This does not only differ CSS and | |
1095 | * Finished, it also maintains the order of the index (important for | |
1096 | * priority queues) and fits in the unsigned short variable. | |
1097 | */ | |
1098 | return seq * 2 - is_ccs; | |
1099 | } | |
36d16f8e | 1100 | |
38b051a1 | 1101 | int dtls1_retransmit_buffered_messages(SSL_CONNECTION *s) |
0f113f3e | 1102 | { |
cf2cede4 | 1103 | pqueue *sent = s->d1->sent_messages; |
0f113f3e MC |
1104 | piterator iter; |
1105 | pitem *item; | |
1106 | hm_fragment *frag; | |
1107 | int found = 0; | |
1108 | ||
1109 | iter = pqueue_iterator(sent); | |
1110 | ||
1111 | for (item = pqueue_next(&iter); item != NULL; item = pqueue_next(&iter)) { | |
1112 | frag = (hm_fragment *)item->data; | |
1113 | if (dtls1_retransmit_message(s, (unsigned short) | |
1114 | dtls1_get_queue_priority | |
1115 | (frag->msg_header.seq, | |
a230b26e | 1116 | frag->msg_header.is_ccs), &found) <= 0) |
0f113f3e | 1117 | return -1; |
0f113f3e MC |
1118 | } |
1119 | ||
1120 | return 1; | |
1121 | } | |
36d16f8e | 1122 | |
38b051a1 | 1123 | int dtls1_buffer_message(SSL_CONNECTION *s, int is_ccs) |
0f113f3e MC |
1124 | { |
1125 | pitem *item; | |
1126 | hm_fragment *frag; | |
1127 | unsigned char seq64be[8]; | |
1128 | ||
1129 | /* | |
1130 | * this function is called immediately after a message has been | |
1131 | * serialized | |
1132 | */ | |
380a522f MC |
1133 | if (!ossl_assert(s->init_off == 0)) |
1134 | return 0; | |
0f113f3e MC |
1135 | |
1136 | frag = dtls1_hm_fragment_new(s->init_num, 0); | |
a71edf3b | 1137 | if (frag == NULL) |
0f113f3e MC |
1138 | return 0; |
1139 | ||
1140 | memcpy(frag->fragment, s->init_buf->data, s->init_num); | |
1141 | ||
1142 | if (is_ccs) { | |
5178a16c | 1143 | /* For DTLS1_BAD_VER the header length is non-standard */ |
380a522f MC |
1144 | if (!ossl_assert(s->d1->w_msg_hdr.msg_len + |
1145 | ((s->version == | |
1146 | DTLS1_BAD_VER) ? 3 : DTLS1_CCS_HEADER_LENGTH) | |
48ff651e P |
1147 | == (unsigned int)s->init_num)) { |
1148 | dtls1_hm_fragment_free(frag); | |
380a522f | 1149 | return 0; |
48ff651e | 1150 | } |
0f113f3e | 1151 | } else { |
380a522f | 1152 | if (!ossl_assert(s->d1->w_msg_hdr.msg_len + |
48ff651e P |
1153 | DTLS1_HM_HEADER_LENGTH == (unsigned int)s->init_num)) { |
1154 | dtls1_hm_fragment_free(frag); | |
380a522f | 1155 | return 0; |
48ff651e | 1156 | } |
0f113f3e MC |
1157 | } |
1158 | ||
1159 | frag->msg_header.msg_len = s->d1->w_msg_hdr.msg_len; | |
1160 | frag->msg_header.seq = s->d1->w_msg_hdr.seq; | |
1161 | frag->msg_header.type = s->d1->w_msg_hdr.type; | |
1162 | frag->msg_header.frag_off = 0; | |
1163 | frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len; | |
1164 | frag->msg_header.is_ccs = is_ccs; | |
1165 | ||
1166 | /* save current state */ | |
b9e37f8f MC |
1167 | frag->msg_header.saved_retransmit_state.wrlmethod = s->rlayer.wrlmethod; |
1168 | frag->msg_header.saved_retransmit_state.wrl = s->rlayer.wrl; | |
1169 | ||
0f113f3e MC |
1170 | |
1171 | memset(seq64be, 0, sizeof(seq64be)); | |
1172 | seq64be[6] = | |
1173 | (unsigned | |
1174 | char)(dtls1_get_queue_priority(frag->msg_header.seq, | |
1175 | frag->msg_header.is_ccs) >> 8); | |
1176 | seq64be[7] = | |
1177 | (unsigned | |
1178 | char)(dtls1_get_queue_priority(frag->msg_header.seq, | |
1179 | frag->msg_header.is_ccs)); | |
1180 | ||
1181 | item = pitem_new(seq64be, frag); | |
1182 | if (item == NULL) { | |
1183 | dtls1_hm_fragment_free(frag); | |
1184 | return 0; | |
1185 | } | |
36d16f8e | 1186 | |
0f113f3e MC |
1187 | pqueue_insert(s->d1->sent_messages, item); |
1188 | return 1; | |
1189 | } | |
36d16f8e | 1190 | |
38b051a1 | 1191 | int dtls1_retransmit_message(SSL_CONNECTION *s, unsigned short seq, int *found) |
0f113f3e MC |
1192 | { |
1193 | int ret; | |
1194 | /* XDTLS: for now assuming that read/writes are blocking */ | |
1195 | pitem *item; | |
1196 | hm_fragment *frag; | |
1197 | unsigned long header_length; | |
1198 | unsigned char seq64be[8]; | |
1199 | struct dtls1_retransmit_state saved_state; | |
0f113f3e | 1200 | |
0f113f3e MC |
1201 | /* XDTLS: the requested message ought to be found, otherwise error */ |
1202 | memset(seq64be, 0, sizeof(seq64be)); | |
1203 | seq64be[6] = (unsigned char)(seq >> 8); | |
1204 | seq64be[7] = (unsigned char)seq; | |
1205 | ||
1206 | item = pqueue_find(s->d1->sent_messages, seq64be); | |
1207 | if (item == NULL) { | |
c48ffbcc | 1208 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); |
0f113f3e MC |
1209 | *found = 0; |
1210 | return 0; | |
1211 | } | |
1212 | ||
1213 | *found = 1; | |
1214 | frag = (hm_fragment *)item->data; | |
1215 | ||
1216 | if (frag->msg_header.is_ccs) | |
1217 | header_length = DTLS1_CCS_HEADER_LENGTH; | |
1218 | else | |
1219 | header_length = DTLS1_HM_HEADER_LENGTH; | |
1220 | ||
1221 | memcpy(s->init_buf->data, frag->fragment, | |
1222 | frag->msg_header.msg_len + header_length); | |
1223 | s->init_num = frag->msg_header.msg_len + header_length; | |
1224 | ||
1225 | dtls1_set_message_header_int(s, frag->msg_header.type, | |
1226 | frag->msg_header.msg_len, | |
1227 | frag->msg_header.seq, 0, | |
1228 | frag->msg_header.frag_len); | |
1229 | ||
1230 | /* save current state */ | |
b9e37f8f MC |
1231 | saved_state.wrlmethod = s->rlayer.wrlmethod; |
1232 | saved_state.wrl = s->rlayer.wrl; | |
0f113f3e MC |
1233 | |
1234 | s->d1->retransmitting = 1; | |
1235 | ||
1236 | /* restore state in which the message was originally sent */ | |
b9e37f8f MC |
1237 | s->rlayer.wrlmethod = frag->msg_header.saved_retransmit_state.wrlmethod; |
1238 | s->rlayer.wrl = frag->msg_header.saved_retransmit_state.wrl; | |
1239 | ||
1240 | /* | |
1241 | * The old wrl may be still pointing at an old BIO. Update it to what we're | |
1242 | * using now. | |
1243 | */ | |
1244 | s->rlayer.wrlmethod->set1_bio(s->rlayer.wrl, s->wbio); | |
0f113f3e | 1245 | |
0f113f3e MC |
1246 | ret = dtls1_do_write(s, frag->msg_header.is_ccs ? |
1247 | SSL3_RT_CHANGE_CIPHER_SPEC : SSL3_RT_HANDSHAKE); | |
1248 | ||
1249 | /* restore current state */ | |
b9e37f8f MC |
1250 | s->rlayer.wrlmethod = saved_state.wrlmethod; |
1251 | s->rlayer.wrl = saved_state.wrl; | |
0f113f3e MC |
1252 | |
1253 | s->d1->retransmitting = 0; | |
1254 | ||
2e7dc7cd | 1255 | (void)BIO_flush(s->wbio); |
0f113f3e MC |
1256 | return ret; |
1257 | } | |
36d16f8e | 1258 | |
38b051a1 | 1259 | void dtls1_set_message_header(SSL_CONNECTION *s, |
d736bc1a MC |
1260 | unsigned char mt, size_t len, |
1261 | size_t frag_off, size_t frag_len) | |
0f113f3e | 1262 | { |
912c89c5 | 1263 | if (frag_off == 0) { |
0f113f3e MC |
1264 | s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; |
1265 | s->d1->next_handshake_write_seq++; | |
1266 | } | |
54ef01b5 | 1267 | |
0f113f3e MC |
1268 | dtls1_set_message_header_int(s, mt, len, s->d1->handshake_write_seq, |
1269 | frag_off, frag_len); | |
0f113f3e | 1270 | } |
36d16f8e BL |
1271 | |
1272 | /* don't actually do the writing, wait till the MTU has been retrieved */ | |
1273 | static void | |
38b051a1 | 1274 | dtls1_set_message_header_int(SSL_CONNECTION *s, unsigned char mt, |
7ee8627f MC |
1275 | size_t len, unsigned short seq_num, |
1276 | size_t frag_off, size_t frag_len) | |
0f113f3e MC |
1277 | { |
1278 | struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; | |
1279 | ||
1280 | msg_hdr->type = mt; | |
1281 | msg_hdr->msg_len = len; | |
1282 | msg_hdr->seq = seq_num; | |
1283 | msg_hdr->frag_off = frag_off; | |
1284 | msg_hdr->frag_len = frag_len; | |
1285 | } | |
36d16f8e BL |
1286 | |
1287 | static void | |
38b051a1 | 1288 | dtls1_fix_message_header(SSL_CONNECTION *s, size_t frag_off, size_t frag_len) |
0f113f3e MC |
1289 | { |
1290 | struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; | |
36d16f8e | 1291 | |
0f113f3e MC |
1292 | msg_hdr->frag_off = frag_off; |
1293 | msg_hdr->frag_len = frag_len; | |
1294 | } | |
54ef01b5 | 1295 | |
38b051a1 TM |
1296 | static unsigned char *dtls1_write_message_header(SSL_CONNECTION *s, |
1297 | unsigned char *p) | |
0f113f3e MC |
1298 | { |
1299 | struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; | |
54ef01b5 | 1300 | |
0f113f3e MC |
1301 | *p++ = msg_hdr->type; |
1302 | l2n3(msg_hdr->msg_len, p); | |
54ef01b5 | 1303 | |
0f113f3e MC |
1304 | s2n(msg_hdr->seq, p); |
1305 | l2n3(msg_hdr->frag_off, p); | |
1306 | l2n3(msg_hdr->frag_len, p); | |
36d16f8e | 1307 | |
0f113f3e MC |
1308 | return p; |
1309 | } | |
36d16f8e | 1310 | |
a230b26e | 1311 | void dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr) |
0f113f3e | 1312 | { |
16f8d4eb | 1313 | memset(msg_hdr, 0, sizeof(*msg_hdr)); |
0f113f3e MC |
1314 | msg_hdr->type = *(data++); |
1315 | n2l3(data, msg_hdr->msg_len); | |
54ef01b5 | 1316 | |
0f113f3e MC |
1317 | n2s(data, msg_hdr->seq); |
1318 | n2l3(data, msg_hdr->frag_off); | |
1319 | n2l3(data, msg_hdr->frag_len); | |
1320 | } | |
2c7b4dbc | 1321 | |
38b051a1 | 1322 | int dtls1_set_handshake_header(SSL_CONNECTION *s, WPACKET *pkt, int htype) |
2c7b4dbc MC |
1323 | { |
1324 | unsigned char *header; | |
de451856 | 1325 | |
4a01c59f MC |
1326 | if (htype == SSL3_MT_CHANGE_CIPHER_SPEC) { |
1327 | s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; | |
1328 | dtls1_set_message_header_int(s, SSL3_MT_CCS, 0, | |
1329 | s->d1->handshake_write_seq, 0, 0); | |
1330 | if (!WPACKET_put_bytes_u8(pkt, SSL3_MT_CCS)) | |
1331 | return 0; | |
1332 | } else { | |
1333 | dtls1_set_message_header(s, htype, 0, 0, 0); | |
1334 | /* | |
1335 | * We allocate space at the start for the message header. This gets | |
1336 | * filled in later | |
1337 | */ | |
1338 | if (!WPACKET_allocate_bytes(pkt, DTLS1_HM_HEADER_LENGTH, &header) | |
1339 | || !WPACKET_start_sub_packet(pkt)) | |
1340 | return 0; | |
1341 | } | |
2c7b4dbc MC |
1342 | |
1343 | return 1; | |
1344 | } | |
1345 | ||
38b051a1 | 1346 | int dtls1_close_construct_packet(SSL_CONNECTION *s, WPACKET *pkt, int htype) |
2c7b4dbc MC |
1347 | { |
1348 | size_t msglen; | |
1349 | ||
4a01c59f | 1350 | if ((htype != SSL3_MT_CHANGE_CIPHER_SPEC && !WPACKET_close(pkt)) |
f1ec23c0 | 1351 | || !WPACKET_get_length(pkt, &msglen) |
7cea05dc | 1352 | || msglen > INT_MAX) |
2c7b4dbc | 1353 | return 0; |
4a01c59f MC |
1354 | |
1355 | if (htype != SSL3_MT_CHANGE_CIPHER_SPEC) { | |
1356 | s->d1->w_msg_hdr.msg_len = msglen - DTLS1_HM_HEADER_LENGTH; | |
1357 | s->d1->w_msg_hdr.frag_len = msglen - DTLS1_HM_HEADER_LENGTH; | |
1358 | } | |
2c7b4dbc MC |
1359 | s->init_num = (int)msglen; |
1360 | s->init_off = 0; | |
1361 | ||
4a01c59f MC |
1362 | if (htype != DTLS1_MT_HELLO_VERIFY_REQUEST) { |
1363 | /* Buffer the message to handle re-xmits */ | |
1364 | if (!dtls1_buffer_message(s, htype == SSL3_MT_CHANGE_CIPHER_SPEC | |
1365 | ? 1 : 0)) | |
1366 | return 0; | |
1367 | } | |
2c7b4dbc MC |
1368 | |
1369 | return 1; | |
1370 | } |