Bug Summary

File:src/lib/libssl/d1_both.c
Warning:line 358, column 17
Although the value stored to 'ret' is used in the enclosing expression, the value is never actually read from 'ret'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name d1_both.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/lib/libssl/obj -resource-dir /usr/local/lib/clang/13.0.0 -D LIBRESSL_INTERNAL -I /usr/src/lib/libssl -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/lib/libssl/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/lib/libssl/d1_both.c
1/* $OpenBSD: d1_both.c,v 1.80 2021/10/23 13:36:03 jsing Exp $ */
2/*
3 * DTLS implementation written by Nagendra Modadugu
4 * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
5 */
6/* ====================================================================
7 * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. All advertising materials mentioning features or use of this
22 * software must display the following acknowledgment:
23 * "This product includes software developed by the OpenSSL Project
24 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
25 *
26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 * endorse or promote products derived from this software without
28 * prior written permission. For written permission, please contact
29 * openssl-core@openssl.org.
30 *
31 * 5. Products derived from this software may not be called "OpenSSL"
32 * nor may "OpenSSL" appear in their names without prior written
33 * permission of the OpenSSL Project.
34 *
35 * 6. Redistributions of any form whatsoever must retain the following
36 * acknowledgment:
37 * "This product includes software developed by the OpenSSL Project
38 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 * OF THE POSSIBILITY OF SUCH DAMAGE.
52 * ====================================================================
53 *
54 * This product includes cryptographic software written by Eric Young
55 * (eay@cryptsoft.com). This product includes software written by Tim
56 * Hudson (tjh@cryptsoft.com).
57 *
58 */
59/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
60 * All rights reserved.
61 *
62 * This package is an SSL implementation written
63 * by Eric Young (eay@cryptsoft.com).
64 * The implementation was written so as to conform with Netscapes SSL.
65 *
66 * This library is free for commercial and non-commercial use as long as
67 * the following conditions are aheared to. The following conditions
68 * apply to all code found in this distribution, be it the RC4, RSA,
69 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
70 * included with this distribution is covered by the same copyright terms
71 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
72 *
73 * Copyright remains Eric Young's, and as such any Copyright notices in
74 * the code are not to be removed.
75 * If this package is used in a product, Eric Young should be given attribution
76 * as the author of the parts of the library used.
77 * This can be in the form of a textual message at program startup or
78 * in documentation (online or textual) provided with the package.
79 *
80 * Redistribution and use in source and binary forms, with or without
81 * modification, are permitted provided that the following conditions
82 * are met:
83 * 1. Redistributions of source code must retain the copyright
84 * notice, this list of conditions and the following disclaimer.
85 * 2. Redistributions in binary form must reproduce the above copyright
86 * notice, this list of conditions and the following disclaimer in the
87 * documentation and/or other materials provided with the distribution.
88 * 3. All advertising materials mentioning features or use of this software
89 * must display the following acknowledgement:
90 * "This product includes cryptographic software written by
91 * Eric Young (eay@cryptsoft.com)"
92 * The word 'cryptographic' can be left out if the rouines from the library
93 * being used are not cryptographic related :-).
94 * 4. If you include any Windows specific code (or a derivative thereof) from
95 * the apps directory (application code) you must include an acknowledgement:
96 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
97 *
98 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
99 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
100 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
101 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
102 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
103 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
104 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
105 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
106 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
107 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
108 * SUCH DAMAGE.
109 *
110 * The licence and distribution terms for any publically available version or
111 * derivative of this code cannot be changed. i.e. this code cannot simply be
112 * copied and put under another distribution licence
113 * [including the GNU Public Licence.]
114 */
115
116#include <limits.h>
117#include <stdio.h>
118#include <string.h>
119
120#include <openssl/buffer.h>
121#include <openssl/evp.h>
122#include <openssl/objects.h>
123#include <openssl/x509.h>
124
125#include "bytestring.h"
126#include "dtls_locl.h"
127#include "pqueue.h"
128#include "ssl_locl.h"
129
130#define RSMBLY_BITMASK_SIZE(msg_len)(((msg_len) + 7) / 8) (((msg_len) + 7) / 8)
131
132#define RSMBLY_BITMASK_MARK(bitmask, start, end){ if ((end) - (start) <= 8) { long ii; for (ii = (start); ii
< (end); ii++) bitmask[((ii) >> 3)] |= (1 << (
(ii) & 7)); } else { long ii; bitmask[((start) >> 3
)] |= bitmask_start_values[((start) & 7)]; for (ii = (((start
) >> 3) + 1); ii < ((((end) - 1)) >> 3); ii++)
bitmask[ii] = 0xff; bitmask[(((end) - 1) >> 3)] |= bitmask_end_values
[((end) & 7)]; } }
{ \
133 if ((end) - (start) <= 8) { \
134 long ii; \
135 for (ii = (start); ii < (end); ii++) bitmask[((ii) >> 3)] |= (1 << ((ii) & 7)); \
136 } else { \
137 long ii; \
138 bitmask[((start) >> 3)] |= bitmask_start_values[((start) & 7)]; \
139 for (ii = (((start) >> 3) + 1); ii < ((((end) - 1)) >> 3); ii++) bitmask[ii] = 0xff; \
140 bitmask[(((end) - 1) >> 3)] |= bitmask_end_values[((end) & 7)]; \
141 } }
142
143#define RSMBLY_BITMASK_IS_COMPLETE(bitmask, msg_len, is_complete){ long ii; (void)(((msg_len) > 0) ? 0 : (OpenSSLDie("/usr/src/lib/libssl/d1_both.c"
, 143, "(msg_len) > 0"),1)); is_complete = 1; if (bitmask[
(((msg_len) - 1) >> 3)] != bitmask_end_values[((msg_len
) & 7)]) is_complete = 0; if (is_complete) for (ii = (((msg_len
) - 1) >> 3) - 1; ii >= 0 ; ii--) if (bitmask[ii] !=
0xff) { is_complete = 0; break; } }
{ \
144 long ii; \
145 OPENSSL_assert((msg_len) > 0)(void)(((msg_len) > 0) ? 0 : (OpenSSLDie("/usr/src/lib/libssl/d1_both.c"
, 145, "(msg_len) > 0"),1))
; \
146 is_complete = 1; \
147 if (bitmask[(((msg_len) - 1) >> 3)] != bitmask_end_values[((msg_len) & 7)]) is_complete = 0; \
148 if (is_complete) for (ii = (((msg_len) - 1) >> 3) - 1; ii >= 0 ; ii--) \
149 if (bitmask[ii] != 0xff) { is_complete = 0; break; } }
150
151static const unsigned char bitmask_start_values[] = {
152 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80
153};
154static const unsigned char bitmask_end_values[] = {
155 0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f
156};
157
158/* XDTLS: figure out the right values */
159static const unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28};
160
161static unsigned int dtls1_guess_mtu(unsigned int curr_mtu);
162static void dtls1_fix_message_header(SSL *s, unsigned long frag_off,
163 unsigned long frag_len);
164static int dtls1_write_message_header(const struct hm_header_st *msg_hdr,
165 unsigned long frag_off, unsigned long frag_len, unsigned char *p);
166static long dtls1_get_message_fragment(SSL *s, int st1, int stn, long max,
167 int *ok);
168
169void dtls1_hm_fragment_free(hm_fragment *frag);
170
171static hm_fragment *
172dtls1_hm_fragment_new(unsigned long frag_len, int reassembly)
173{
174 hm_fragment *frag;
175
176 if ((frag = calloc(1, sizeof(*frag))) == NULL((void*)0))
177 goto err;
178
179 if (frag_len > 0) {
180 if ((frag->fragment = calloc(1, frag_len)) == NULL((void*)0))
181 goto err;
182 }
183
184 /* Initialize reassembly bitmask if necessary. */
185 if (reassembly) {
186 if ((frag->reassembly = calloc(1,
187 RSMBLY_BITMASK_SIZE(frag_len)(((frag_len) + 7) / 8))) == NULL((void*)0))
188 goto err;
189 }
190
191 return frag;
192
193 err:
194 dtls1_hm_fragment_free(frag);
195 return NULL((void*)0);
196}
197
198void
199dtls1_hm_fragment_free(hm_fragment *frag)
200{
201 if (frag == NULL((void*)0))
202 return;
203
204 free(frag->fragment);
205 free(frag->reassembly);
206 free(frag);
207}
208
209/* send s->internal->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or SSL3_RT_CHANGE_CIPHER_SPEC) */
210int
211dtls1_do_write(SSL *s, int type)
212{
213 int ret;
214 int curr_mtu;
215 unsigned int len, frag_off;
216 size_t overhead;
217
218 /* AHA! Figure out the MTU, and stick to the right size */
219 if (s->d1->mtu < dtls1_min_mtu() &&
220 !(SSL_get_options(s)SSL_ctrl((s),32,0,((void*)0)) & SSL_OP_NO_QUERY_MTU0x00001000L)) {
221 s->d1->mtu = BIO_ctrl(SSL_get_wbio(s),
222 BIO_CTRL_DGRAM_QUERY_MTU40, 0, NULL((void*)0));
223
224 /*
225 * I've seen the kernel return bogus numbers when it
226 * doesn't know the MTU (ie., the initial write), so just
227 * make sure we have a reasonable number
228 */
229 if (s->d1->mtu < dtls1_min_mtu()) {
230 s->d1->mtu = 0;
231 s->d1->mtu = dtls1_guess_mtu(s->d1->mtu);
232 BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU42,
233 s->d1->mtu, NULL((void*)0));
234 }
235 }
236
237 OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu())(void)((s->d1->mtu >= dtls1_min_mtu()) ? 0 : (OpenSSLDie
("/usr/src/lib/libssl/d1_both.c", 237, "s->d1->mtu >= dtls1_min_mtu()"
),1))
;
238 /* should have something reasonable now */
239
240 if (s->internal->init_off == 0 && type == SSL3_RT_HANDSHAKE22)
241 OPENSSL_assert(s->internal->init_num ==(void)((s->internal->init_num == (int)s->d1->w_msg_hdr
.msg_len + 12) ? 0 : (OpenSSLDie("/usr/src/lib/libssl/d1_both.c"
, 242, "s->internal->init_num == (int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH"
),1))
242 (int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH)(void)((s->internal->init_num == (int)s->d1->w_msg_hdr
.msg_len + 12) ? 0 : (OpenSSLDie("/usr/src/lib/libssl/d1_both.c"
, 242, "s->internal->init_num == (int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH"
),1))
;
243
244 if (!tls12_record_layer_write_overhead(s->internal->rl, &overhead))
245 return -1;
246
247 frag_off = 0;
248 while (s->internal->init_num) {
249 curr_mtu = s->d1->mtu - BIO_wpending(SSL_get_wbio(s))(int)BIO_ctrl(SSL_get_wbio(s),13,0,((void*)0)) -
250 DTLS1_RT_HEADER_LENGTH13 - overhead;
251
252 if (curr_mtu <= DTLS1_HM_HEADER_LENGTH12) {
253 /* grr.. we could get an error if MTU picked was wrong */
254 ret = BIO_flush(SSL_get_wbio(s))(int)BIO_ctrl(SSL_get_wbio(s),11,0,((void*)0));
255 if (ret <= 0)
256 return ret;
257 curr_mtu = s->d1->mtu - DTLS1_RT_HEADER_LENGTH13 -
258 overhead;
259 }
260
261 if (s->internal->init_num > curr_mtu)
262 len = curr_mtu;
263 else
264 len = s->internal->init_num;
265
266 /* XDTLS: this function is too long. split out the CCS part */
267 if (type == SSL3_RT_HANDSHAKE22) {
268 if (s->internal->init_off != 0) {
269 OPENSSL_assert(s->internal->init_off > DTLS1_HM_HEADER_LENGTH)(void)((s->internal->init_off > 12) ? 0 : (OpenSSLDie
("/usr/src/lib/libssl/d1_both.c", 269, "s->internal->init_off > DTLS1_HM_HEADER_LENGTH"
),1))
;
270 s->internal->init_off -= DTLS1_HM_HEADER_LENGTH12;
271 s->internal->init_num += DTLS1_HM_HEADER_LENGTH12;
272
273 if (s->internal->init_num > curr_mtu)
274 len = curr_mtu;
275 else
276 len = s->internal->init_num;
277 }
278
279 dtls1_fix_message_header(s, frag_off,
280 len - DTLS1_HM_HEADER_LENGTH12);
281
282 if (!dtls1_write_message_header(&s->d1->w_msg_hdr,
283 s->d1->w_msg_hdr.frag_off, s->d1->w_msg_hdr.frag_len,
284 (unsigned char *)&s->internal->init_buf->data[s->internal->init_off]))
285 return -1;
286
287 OPENSSL_assert(len >= DTLS1_HM_HEADER_LENGTH)(void)((len >= 12) ? 0 : (OpenSSLDie("/usr/src/lib/libssl/d1_both.c"
, 287, "len >= DTLS1_HM_HEADER_LENGTH"),1))
;
288 }
289
290 ret = dtls1_write_bytes(s, type,
291 &s->internal->init_buf->data[s->internal->init_off], len);
292 if (ret < 0) {
293 /*
294 * Might need to update MTU here, but we don't know
295 * which previous packet caused the failure -- so
296 * can't really retransmit anything. continue as
297 * if everything is fine and wait for an alert to
298 * handle the retransmit
299 */
300 if (BIO_ctrl(SSL_get_wbio(s),
301 BIO_CTRL_DGRAM_MTU_EXCEEDED43, 0, NULL((void*)0)) > 0)
302 s->d1->mtu = BIO_ctrl(SSL_get_wbio(s),
303 BIO_CTRL_DGRAM_QUERY_MTU40, 0, NULL((void*)0));
304 else
305 return (-1);
306 } else {
307
308 /*
309 * Bad if this assert fails, only part of the
310 * handshake message got sent. but why would
311 * this happen?
312 */
313 OPENSSL_assert(len == (unsigned int)ret)(void)((len == (unsigned int)ret) ? 0 : (OpenSSLDie("/usr/src/lib/libssl/d1_both.c"
, 313, "len == (unsigned int)ret"),1))
;
314
315 if (type == SSL3_RT_HANDSHAKE22 &&
316 !s->d1->retransmitting) {
317 /*
318 * Should not be done for 'Hello Request's,
319 * but in that case we'll ignore the result
320 * anyway
321 */
322 unsigned char *p = (unsigned char *)&s->internal->init_buf->data[s->internal->init_off];
323 const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
324 int xlen;
325
326 if (frag_off == 0) {
327 /*
328 * Reconstruct message header is if it
329 * is being sent in single fragment
330 */
331 if (!dtls1_write_message_header(msg_hdr,
332 0, msg_hdr->msg_len, p))
333 return (-1);
334 xlen = ret;
335 } else {
336 p += DTLS1_HM_HEADER_LENGTH12;
337 xlen = ret - DTLS1_HM_HEADER_LENGTH12;
338 }
339
340 tls1_transcript_record(s, p, xlen);
341 }
342
343 if (ret == s->internal->init_num) {
344 if (s->internal->msg_callback)
345 s->internal->msg_callback(1, s->version, type,
346 s->internal->init_buf->data,
347 (size_t)(s->internal->init_off + s->internal->init_num),
348 s, s->internal->msg_callback_arg);
349
350 s->internal->init_off = 0;
351 /* done writing this message */
352 s->internal->init_num = 0;
353
354 return (1);
355 }
356 s->internal->init_off += ret;
357 s->internal->init_num -= ret;
358 frag_off += (ret -= DTLS1_HM_HEADER_LENGTH12);
Although the value stored to 'ret' is used in the enclosing expression, the value is never actually read from 'ret'
359 }
360 }
361 return (0);
362}
363
364
365/*
366 * Obtain handshake message of message type 'mt' (any if mt == -1),
367 * maximum acceptable body length 'max'.
368 * Read an entire handshake message. Handshake messages arrive in
369 * fragments.
370 */
371int
372dtls1_get_message(SSL *s, int st1, int stn, int mt, long max)
373{
374 struct hm_header_st *msg_hdr;
375 unsigned char *p;
376 unsigned long msg_len;
377 int i, al, ok;
378
379 /*
380 * s3->internal->tmp is used to store messages that are unexpected, caused
381 * by the absence of an optional handshake message
382 */
383 if (S3I(s)(s->s3->internal)->hs.tls12.reuse_message) {
384 S3I(s)(s->s3->internal)->hs.tls12.reuse_message = 0;
385 if ((mt >= 0) && (S3I(s)(s->s3->internal)->hs.tls12.message_type != mt)) {
386 al = SSL_AD_UNEXPECTED_MESSAGE10;
387 SSLerror(s, SSL_R_UNEXPECTED_MESSAGE)SSL_error_internal(s, 244, "/usr/src/lib/libssl/d1_both.c", 387
)
;
388 goto fatal_err;
389 }
390 s->internal->init_msg = s->internal->init_buf->data + DTLS1_HM_HEADER_LENGTH12;
391 s->internal->init_num = (int)S3I(s)(s->s3->internal)->hs.tls12.message_size;
392 return 1;
393 }
394
395 msg_hdr = &s->d1->r_msg_hdr;
396 memset(msg_hdr, 0, sizeof(struct hm_header_st));
397
398 again:
399 i = dtls1_get_message_fragment(s, st1, stn, max, &ok);
400 if (i == DTLS1_HM_BAD_FRAGMENT-2 ||
401 i == DTLS1_HM_FRAGMENT_RETRY-3) /* bad fragment received */
402 goto again;
403 else if (i <= 0 && !ok)
404 return i;
405
406 p = (unsigned char *)s->internal->init_buf->data;
407 msg_len = msg_hdr->msg_len;
408
409 /* reconstruct message header */
410 if (!dtls1_write_message_header(msg_hdr, 0, msg_len, p))
411 return -1;
412
413 msg_len += DTLS1_HM_HEADER_LENGTH12;
414
415 tls1_transcript_record(s, p, msg_len);
416 if (s->internal->msg_callback)
417 s->internal->msg_callback(0, s->version, SSL3_RT_HANDSHAKE22, p, msg_len,
418 s, s->internal->msg_callback_arg);
419
420 memset(msg_hdr, 0, sizeof(struct hm_header_st));
421
422 /* Don't change sequence numbers while listening */
423 if (!s->d1->listen)
424 s->d1->handshake_read_seq++;
425
426 s->internal->init_msg = s->internal->init_buf->data + DTLS1_HM_HEADER_LENGTH12;
427 return 1;
428
429 fatal_err:
430 ssl3_send_alert(s, SSL3_AL_FATAL2, al);
431 return -1;
432}
433
434static int
435dtls1_preprocess_fragment(SSL *s, struct hm_header_st *msg_hdr, int max)
436{
437 size_t frag_off, frag_len, msg_len;
438
439 msg_len = msg_hdr->msg_len;
440 frag_off = msg_hdr->frag_off;
441 frag_len = msg_hdr->frag_len;
442
443 /* sanity checking */
444 if ((frag_off + frag_len) > msg_len) {
445 SSLerror(s, SSL_R_EXCESSIVE_MESSAGE_SIZE)SSL_error_internal(s, 152, "/usr/src/lib/libssl/d1_both.c", 445
)
;
446 return SSL_AD_ILLEGAL_PARAMETER47;
447 }
448
449 if ((frag_off + frag_len) > (unsigned long)max) {
450 SSLerror(s, SSL_R_EXCESSIVE_MESSAGE_SIZE)SSL_error_internal(s, 152, "/usr/src/lib/libssl/d1_both.c", 450
)
;
451 return SSL_AD_ILLEGAL_PARAMETER47;
452 }
453
454 if ( s->d1->r_msg_hdr.frag_off == 0) /* first fragment */
455 {
456 /*
457 * msg_len is limited to 2^24, but is effectively checked
458 * against max above
459 */
460 if (!BUF_MEM_grow_clean(s->internal->init_buf,
461 msg_len + DTLS1_HM_HEADER_LENGTH12)) {
462 SSLerror(s, ERR_R_BUF_LIB)SSL_error_internal(s, 7, "/usr/src/lib/libssl/d1_both.c", 462
)
;
463 return SSL_AD_INTERNAL_ERROR80;
464 }
465
466 S3I(s)(s->s3->internal)->hs.tls12.message_size = msg_len;
467 s->d1->r_msg_hdr.msg_len = msg_len;
468 S3I(s)(s->s3->internal)->hs.tls12.message_type = msg_hdr->type;
469 s->d1->r_msg_hdr.type = msg_hdr->type;
470 s->d1->r_msg_hdr.seq = msg_hdr->seq;
471 } else if (msg_len != s->d1->r_msg_hdr.msg_len) {
472 /*
473 * They must be playing with us! BTW, failure to enforce
474 * upper limit would open possibility for buffer overrun.
475 */
476 SSLerror(s, SSL_R_EXCESSIVE_MESSAGE_SIZE)SSL_error_internal(s, 152, "/usr/src/lib/libssl/d1_both.c", 476
)
;
477 return SSL_AD_ILLEGAL_PARAMETER47;
478 }
479
480 return 0; /* no error */
481}
482
483static int
484dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok)
485{
486 /*
487 * (0) check whether the desired fragment is available
488 * if so:
489 * (1) copy over the fragment to s->internal->init_buf->data[]
490 * (2) update s->internal->init_num
491 */
492 pitem *item;
493 hm_fragment *frag;
494 int al;
495
496 *ok = 0;
497 item = pqueue_peek(s->d1->buffered_messages);
498 if (item == NULL((void*)0))
499 return 0;
500
501 frag = (hm_fragment *)item->data;
502
503 /* Don't return if reassembly still in progress */
504 if (frag->reassembly != NULL((void*)0))
505 return 0;
506
507 if (s->d1->handshake_read_seq == frag->msg_header.seq) {
508 unsigned long frag_len = frag->msg_header.frag_len;
509 pqueue_pop(s->d1->buffered_messages);
510
511 al = dtls1_preprocess_fragment(s, &frag->msg_header, max);
512
513 if (al == 0) /* no alert */
514 {
515 unsigned char *p = (unsigned char *)s->internal->init_buf->data + DTLS1_HM_HEADER_LENGTH12;
516 memcpy(&p[frag->msg_header.frag_off],
517 frag->fragment, frag->msg_header.frag_len);
518 }
519
520 dtls1_hm_fragment_free(frag);
521 pitem_free(item);
522
523 if (al == 0) {
524 *ok = 1;
525 return frag_len;
526 }
527
528 ssl3_send_alert(s, SSL3_AL_FATAL2, al);
529 s->internal->init_num = 0;
530 *ok = 0;
531 return -1;
532 } else
533 return 0;
534}
535
536/*
537 * dtls1_max_handshake_message_len returns the maximum number of bytes
538 * permitted in a DTLS handshake message for |s|. The minimum is 16KB,
539 * but may be greater if the maximum certificate list size requires it.
540 */
541static unsigned long
542dtls1_max_handshake_message_len(const SSL *s)
543{
544 unsigned long max_len;
545
546 max_len = DTLS1_HM_HEADER_LENGTH12 + SSL3_RT_MAX_ENCRYPTED_LENGTH((256 + 64)+16384);
547 if (max_len < (unsigned long)s->internal->max_cert_list)
548 return s->internal->max_cert_list;
549 return max_len;
550}
551
552static int
553dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok)
554{
555 hm_fragment *frag = NULL((void*)0);
556 pitem *item = NULL((void*)0);
557 int i = -1, is_complete;
558 unsigned char seq64be[8];
559 unsigned long frag_len = msg_hdr->frag_len;
560
561 if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len ||
562 msg_hdr->msg_len > dtls1_max_handshake_message_len(s))
563 goto err;
564
565 if (frag_len == 0) {
566 i = DTLS1_HM_FRAGMENT_RETRY-3;
567 goto err;
568 }
569
570 /* Try to find item in queue */
571 memset(seq64be, 0, sizeof(seq64be));
572 seq64be[6] = (unsigned char)(msg_hdr->seq >> 8);
573 seq64be[7] = (unsigned char)msg_hdr->seq;
574 item = pqueue_find(s->d1->buffered_messages, seq64be);
575
576 if (item == NULL((void*)0)) {
577 frag = dtls1_hm_fragment_new(msg_hdr->msg_len, 1);
578 if (frag == NULL((void*)0))
579 goto err;
580 memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr));
581 frag->msg_header.frag_len = frag->msg_header.msg_len;
582 frag->msg_header.frag_off = 0;
583 } else {
584 frag = (hm_fragment*)item->data;
585 if (frag->msg_header.msg_len != msg_hdr->msg_len) {
586 item = NULL((void*)0);
587 frag = NULL((void*)0);
588 goto err;
589 }
590 }
591
592 /*
593 * If message is already reassembled, this must be a
594 * retransmit and can be dropped.
595 */
596 if (frag->reassembly == NULL((void*)0)) {
597 unsigned char devnull [256];
598
599 while (frag_len) {
600 i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE22,
601 devnull, frag_len > sizeof(devnull) ?
602 sizeof(devnull) : frag_len, 0);
603 if (i <= 0)
604 goto err;
605 frag_len -= i;
606 }
607 i = DTLS1_HM_FRAGMENT_RETRY-3;
608 goto err;
609 }
610
611 /* read the body of the fragment (header has already been read */
612 i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE22,
613 frag->fragment + msg_hdr->frag_off, frag_len, 0);
614 if (i <= 0 || (unsigned long)i != frag_len)
615 goto err;
616
617 RSMBLY_BITMASK_MARK(frag->reassembly, (long)msg_hdr->frag_off,{ if (((long)(msg_hdr->frag_off + frag_len)) - ((long)msg_hdr
->frag_off) <= 8) { long ii; for (ii = ((long)msg_hdr->
frag_off); ii < ((long)(msg_hdr->frag_off + frag_len));
ii++) frag->reassembly[((ii) >> 3)] |= (1 << (
(ii) & 7)); } else { long ii; frag->reassembly[(((long
)msg_hdr->frag_off) >> 3)] |= bitmask_start_values[(
((long)msg_hdr->frag_off) & 7)]; for (ii = ((((long)msg_hdr
->frag_off) >> 3) + 1); ii < (((((long)(msg_hdr->
frag_off + frag_len)) - 1)) >> 3); ii++) frag->reassembly
[ii] = 0xff; frag->reassembly[((((long)(msg_hdr->frag_off
+ frag_len)) - 1) >> 3)] |= bitmask_end_values[(((long
)(msg_hdr->frag_off + frag_len)) & 7)]; } }
618 (long)(msg_hdr->frag_off + frag_len)){ if (((long)(msg_hdr->frag_off + frag_len)) - ((long)msg_hdr
->frag_off) <= 8) { long ii; for (ii = ((long)msg_hdr->
frag_off); ii < ((long)(msg_hdr->frag_off + frag_len));
ii++) frag->reassembly[((ii) >> 3)] |= (1 << (
(ii) & 7)); } else { long ii; frag->reassembly[(((long
)msg_hdr->frag_off) >> 3)] |= bitmask_start_values[(
((long)msg_hdr->frag_off) & 7)]; for (ii = ((((long)msg_hdr
->frag_off) >> 3) + 1); ii < (((((long)(msg_hdr->
frag_off + frag_len)) - 1)) >> 3); ii++) frag->reassembly
[ii] = 0xff; frag->reassembly[((((long)(msg_hdr->frag_off
+ frag_len)) - 1) >> 3)] |= bitmask_end_values[(((long
)(msg_hdr->frag_off + frag_len)) & 7)]; } }
;
619
620 RSMBLY_BITMASK_IS_COMPLETE(frag->reassembly, (long)msg_hdr->msg_len,{ long ii; (void)((((long)msg_hdr->msg_len) > 0) ? 0 : (
OpenSSLDie("/usr/src/lib/libssl/d1_both.c", 621, "((long)msg_hdr->msg_len) > 0"
),1)); is_complete = 1; if (frag->reassembly[((((long)msg_hdr
->msg_len) - 1) >> 3)] != bitmask_end_values[(((long
)msg_hdr->msg_len) & 7)]) is_complete = 0; if (is_complete
) for (ii = ((((long)msg_hdr->msg_len) - 1) >> 3) - 1
; ii >= 0 ; ii--) if (frag->reassembly[ii] != 0xff) { is_complete
= 0; break; } }
621 is_complete){ long ii; (void)((((long)msg_hdr->msg_len) > 0) ? 0 : (
OpenSSLDie("/usr/src/lib/libssl/d1_both.c", 621, "((long)msg_hdr->msg_len) > 0"
),1)); is_complete = 1; if (frag->reassembly[((((long)msg_hdr
->msg_len) - 1) >> 3)] != bitmask_end_values[(((long
)msg_hdr->msg_len) & 7)]) is_complete = 0; if (is_complete
) for (ii = ((((long)msg_hdr->msg_len) - 1) >> 3) - 1
; ii >= 0 ; ii--) if (frag->reassembly[ii] != 0xff) { is_complete
= 0; break; } }
;
622
623 if (is_complete) {
624 free(frag->reassembly);
625 frag->reassembly = NULL((void*)0);
626 }
627
628 if (item == NULL((void*)0)) {
629 memset(seq64be, 0, sizeof(seq64be));
630 seq64be[6] = (unsigned char)(msg_hdr->seq >> 8);
631 seq64be[7] = (unsigned char)(msg_hdr->seq);
632
633 item = pitem_new(seq64be, frag);
634 if (item == NULL((void*)0)) {
635 i = -1;
636 goto err;
637 }
638
639 pqueue_insert(s->d1->buffered_messages, item);
640 }
641
642 return DTLS1_HM_FRAGMENT_RETRY-3;
643
644 err:
645 if (item == NULL((void*)0) && frag != NULL((void*)0))
646 dtls1_hm_fragment_free(frag);
647 *ok = 0;
648 return i;
649}
650
651
652static int
653dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok)
654{
655 int i = -1;
656 hm_fragment *frag = NULL((void*)0);
657 pitem *item = NULL((void*)0);
658 unsigned char seq64be[8];
659 unsigned long frag_len = msg_hdr->frag_len;
660
661 if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len)
662 goto err;
663
664 /* Try to find item in queue, to prevent duplicate entries */
665 memset(seq64be, 0, sizeof(seq64be));
666 seq64be[6] = (unsigned char) (msg_hdr->seq >> 8);
667 seq64be[7] = (unsigned char) msg_hdr->seq;
668 item = pqueue_find(s->d1->buffered_messages, seq64be);
669
670 /*
671 * If we already have an entry and this one is a fragment,
672 * don't discard it and rather try to reassemble it.
673 */
674 if (item != NULL((void*)0) && frag_len < msg_hdr->msg_len)
675 item = NULL((void*)0);
676
677 /*
678 * Discard the message if sequence number was already there, is
679 * too far in the future, already in the queue or if we received
680 * a FINISHED before the SERVER_HELLO, which then must be a stale
681 * retransmit.
682 */
683 if (msg_hdr->seq <= s->d1->handshake_read_seq ||
684 msg_hdr->seq > s->d1->handshake_read_seq + 10 || item != NULL((void*)0) ||
685 (s->d1->handshake_read_seq == 0 &&
686 msg_hdr->type == SSL3_MT_FINISHED20)) {
687 unsigned char devnull [256];
688
689 while (frag_len) {
690 i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE22,
691 devnull, frag_len > sizeof(devnull) ?
692 sizeof(devnull) : frag_len, 0);
693 if (i <= 0)
694 goto err;
695 frag_len -= i;
696 }
697 } else {
698 if (frag_len < msg_hdr->msg_len)
699 return dtls1_reassemble_fragment(s, msg_hdr, ok);
700
701 if (frag_len > dtls1_max_handshake_message_len(s))
702 goto err;
703
704 frag = dtls1_hm_fragment_new(frag_len, 0);
705 if (frag == NULL((void*)0))
706 goto err;
707
708 memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr));
709
710 if (frag_len) {
711 /* read the body of the fragment (header has already been read */
712 i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE22,
713 frag->fragment, frag_len, 0);
714 if (i <= 0 || (unsigned long)i != frag_len)
715 goto err;
716 }
717
718 memset(seq64be, 0, sizeof(seq64be));
719 seq64be[6] = (unsigned char)(msg_hdr->seq >> 8);
720 seq64be[7] = (unsigned char)(msg_hdr->seq);
721
722 item = pitem_new(seq64be, frag);
723 if (item == NULL((void*)0))
724 goto err;
725
726 pqueue_insert(s->d1->buffered_messages, item);
727 }
728
729 return DTLS1_HM_FRAGMENT_RETRY-3;
730
731 err:
732 if (item == NULL((void*)0) && frag != NULL((void*)0))
733 dtls1_hm_fragment_free(frag);
734 *ok = 0;
735 return i;
736}
737
738
739static long
740dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok)
741{
742 unsigned char wire[DTLS1_HM_HEADER_LENGTH12];
743 unsigned long len, frag_off, frag_len;
744 struct hm_header_st msg_hdr;
745 int i, al;
746 CBS cbs;
747
748 again:
749 /* see if we have the required fragment already */
750 if ((frag_len = dtls1_retrieve_buffered_fragment(s, max, ok)) || *ok) {
751 if (*ok)
752 s->internal->init_num = frag_len;
753 return frag_len;
754 }
755
756 /* read handshake message header */
757 i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE22, wire,
758 DTLS1_HM_HEADER_LENGTH12, 0);
759 if (i <= 0) {
760 /* nbio, or an error */
761 s->internal->rwstate = SSL_READING3;
762 *ok = 0;
763 return i;
764 }
765
766 CBS_init(&cbs, wire, i);
767 if (!dtls1_get_message_header(&cbs, &msg_hdr)) {
768 /* Handshake fails if message header is incomplete. */
769 al = SSL_AD_UNEXPECTED_MESSAGE10;
770 SSLerror(s, SSL_R_UNEXPECTED_MESSAGE)SSL_error_internal(s, 244, "/usr/src/lib/libssl/d1_both.c", 770
)
;
771 goto fatal_err;
772 }
773
774 /*
775 * if this is a future (or stale) message it gets buffered
776 * (or dropped)--no further processing at this time
777 * While listening, we accept seq 1 (ClientHello with cookie)
778 * although we're still expecting seq 0 (ClientHello)
779 */
780 if (msg_hdr.seq != s->d1->handshake_read_seq &&
781 !(s->d1->listen && msg_hdr.seq == 1))
782 return dtls1_process_out_of_seq_message(s, &msg_hdr, ok);
783
784 len = msg_hdr.msg_len;
785 frag_off = msg_hdr.frag_off;
786 frag_len = msg_hdr.frag_len;
787
788 if (frag_len && frag_len < len)
789 return dtls1_reassemble_fragment(s, &msg_hdr, ok);
790
791 if (!s->server && s->d1->r_msg_hdr.frag_off == 0 &&
792 wire[0] == SSL3_MT_HELLO_REQUEST0) {
793 /*
794 * The server may always send 'Hello Request' messages --
795 * we are doing a handshake anyway now, so ignore them
796 * if their format is correct. Does not count for
797 * 'Finished' MAC.
798 */
799 if (wire[1] == 0 && wire[2] == 0 && wire[3] == 0) {
800 if (s->internal->msg_callback)
801 s->internal->msg_callback(0, s->version,
802 SSL3_RT_HANDSHAKE22, wire,
803 DTLS1_HM_HEADER_LENGTH12, s,
804 s->internal->msg_callback_arg);
805
806 s->internal->init_num = 0;
807 goto again;
808 }
809 else /* Incorrectly formated Hello request */
810 {
811 al = SSL_AD_UNEXPECTED_MESSAGE10;
812 SSLerror(s, SSL_R_UNEXPECTED_MESSAGE)SSL_error_internal(s, 244, "/usr/src/lib/libssl/d1_both.c", 812
)
;
813 goto fatal_err;
814 }
815 }
816
817 if ((al = dtls1_preprocess_fragment(s, &msg_hdr, max)))
818 goto fatal_err;
819
820 /* XDTLS: ressurect this when restart is in place */
821 S3I(s)(s->s3->internal)->hs.state = stn;
822
823 if (frag_len > 0) {
824 unsigned char *p = (unsigned char *)s->internal->init_buf->data + DTLS1_HM_HEADER_LENGTH12;
825
826 i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE22,
827 &p[frag_off], frag_len, 0);
828 /* XDTLS: fix this--message fragments cannot span multiple packets */
829 if (i <= 0) {
830 s->internal->rwstate = SSL_READING3;
831 *ok = 0;
832 return i;
833 }
834 } else
835 i = 0;
836
837 /*
838 * XDTLS: an incorrectly formatted fragment should cause the
839 * handshake to fail
840 */
841 if (i != (int)frag_len) {
842 al = SSL_AD_ILLEGAL_PARAMETER47;
843 SSLerror(s, SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER)SSL_error_internal(s, 1047, "/usr/src/lib/libssl/d1_both.c", 843
)
;
844 goto fatal_err;
845 }
846
847 /*
848 * Note that s->internal->init_num is *not* used as current offset in
849 * s->internal->init_buf->data, but as a counter summing up fragments'
850 * lengths: as soon as they sum up to handshake packet
851 * length, we assume we have got all the fragments.
852 */
853 s->internal->init_num = frag_len;
854 *ok = 1;
855 return frag_len;
856
857 fatal_err:
858 ssl3_send_alert(s, SSL3_AL_FATAL2, al);
859 s->internal->init_num = 0;
860
861 *ok = 0;
862 return (-1);
863}
864
865int
866dtls1_read_failed(SSL *s, int code)
867{
868 if (code > 0) {
869#ifdef DEBUG
870 fprintf(stderr(&__sF[2]), "invalid state reached %s:%d",
871 __FILE__"/usr/src/lib/libssl/d1_both.c", __LINE__871);
872#endif
873 return 1;
874 }
875
876 if (!dtls1_is_timer_expired(s)) {
877 /*
878 * not a timeout, none of our business, let higher layers
879 * handle this. in fact it's probably an error
880 */
881 return code;
882 }
883
884 if (!SSL_in_init(s)(SSL_state((s))&(0x1000|0x2000))) /* done, no need to send a retransmit */
885 {
886 BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ0x01);
887 return code;
888 }
889
890 return dtls1_handle_timeout(s);
891}
892
893int
894dtls1_get_queue_priority(unsigned short seq, int is_ccs)
895{
896 /*
897 * The index of the retransmission queue actually is the message
898 * sequence number, since the queue only contains messages of a
899 * single handshake. However, the ChangeCipherSpec has no message
900 * sequence number and so using only the sequence will result in
901 * the CCS and Finished having the same index. To prevent this, the
902 * sequence number is multiplied by 2. In case of a CCS 1 is
903 * subtracted. This does not only differ CSS and Finished, it also
904 * maintains the order of the index (important for priority queues)
905 * and fits in the unsigned short variable.
906 */
907 return seq * 2 - is_ccs;
908}
909
910int
911dtls1_retransmit_buffered_messages(SSL *s)
912{
913 pqueue sent = s->d1->sent_messages;
914 piterator iter;
915 pitem *item;
916 hm_fragment *frag;
917 int found = 0;
918
919 iter = pqueue_iterator(sent);
920
921 for (item = pqueue_next(&iter); item != NULL((void*)0);
922 item = pqueue_next(&iter)) {
923 frag = (hm_fragment *)item->data;
924 if (dtls1_retransmit_message(s,
925 (unsigned short)dtls1_get_queue_priority(
926 frag->msg_header.seq, frag->msg_header.is_ccs), 0,
927 &found) <= 0 && found) {
928#ifdef DEBUG
929 fprintf(stderr(&__sF[2]), "dtls1_retransmit_message() failed\n");
930#endif
931 return -1;
932 }
933 }
934
935 return 1;
936}
937
938int
939dtls1_buffer_message(SSL *s, int is_ccs)
940{
941 pitem *item;
942 hm_fragment *frag;
943 unsigned char seq64be[8];
944
945 /* Buffer the messsage in order to handle DTLS retransmissions. */
946
947 /*
948 * This function is called immediately after a message has
949 * been serialized
950 */
951 OPENSSL_assert(s->internal->init_off == 0)(void)((s->internal->init_off == 0) ? 0 : (OpenSSLDie("/usr/src/lib/libssl/d1_both.c"
, 951, "s->internal->init_off == 0"),1))
;
952
953 frag = dtls1_hm_fragment_new(s->internal->init_num, 0);
954 if (frag == NULL((void*)0))
955 return 0;
956
957 memcpy(frag->fragment, s->internal->init_buf->data, s->internal->init_num);
958
959 OPENSSL_assert(s->d1->w_msg_hdr.msg_len +(void)((s->d1->w_msg_hdr.msg_len + (is_ccs ? 1 : 12) ==
(unsigned int)s->internal->init_num) ? 0 : (OpenSSLDie
("/usr/src/lib/libssl/d1_both.c", 961, "s->d1->w_msg_hdr.msg_len + (is_ccs ? DTLS1_CCS_HEADER_LENGTH : DTLS1_HM_HEADER_LENGTH) == (unsigned int)s->internal->init_num"
),1))
960 (is_ccs ? DTLS1_CCS_HEADER_LENGTH : DTLS1_HM_HEADER_LENGTH) ==(void)((s->d1->w_msg_hdr.msg_len + (is_ccs ? 1 : 12) ==
(unsigned int)s->internal->init_num) ? 0 : (OpenSSLDie
("/usr/src/lib/libssl/d1_both.c", 961, "s->d1->w_msg_hdr.msg_len + (is_ccs ? DTLS1_CCS_HEADER_LENGTH : DTLS1_HM_HEADER_LENGTH) == (unsigned int)s->internal->init_num"
),1))
961 (unsigned int)s->internal->init_num)(void)((s->d1->w_msg_hdr.msg_len + (is_ccs ? 1 : 12) ==
(unsigned int)s->internal->init_num) ? 0 : (OpenSSLDie
("/usr/src/lib/libssl/d1_both.c", 961, "s->d1->w_msg_hdr.msg_len + (is_ccs ? DTLS1_CCS_HEADER_LENGTH : DTLS1_HM_HEADER_LENGTH) == (unsigned int)s->internal->init_num"
),1))
;
962
963 frag->msg_header.msg_len = s->d1->w_msg_hdr.msg_len;
964 frag->msg_header.seq = s->d1->w_msg_hdr.seq;
965 frag->msg_header.type = s->d1->w_msg_hdr.type;
966 frag->msg_header.frag_off = 0;
967 frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len;
968 frag->msg_header.is_ccs = is_ccs;
969
970 /* save current state*/
971 frag->msg_header.saved_retransmit_state.session = s->session;
972 frag->msg_header.saved_retransmit_state.epoch =
973 tls12_record_layer_write_epoch(s->internal->rl);
974
975 memset(seq64be, 0, sizeof(seq64be));
976 seq64be[6] = (unsigned char)(dtls1_get_queue_priority(
977 frag->msg_header.seq, frag->msg_header.is_ccs) >> 8);
978 seq64be[7] = (unsigned char)(dtls1_get_queue_priority(
979 frag->msg_header.seq, frag->msg_header.is_ccs));
980
981 item = pitem_new(seq64be, frag);
982 if (item == NULL((void*)0)) {
983 dtls1_hm_fragment_free(frag);
984 return 0;
985 }
986
987 pqueue_insert(s->d1->sent_messages, item);
988 return 1;
989}
990
991int
992dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off,
993 int *found)
994{
995 int ret;
996 /* XDTLS: for now assuming that read/writes are blocking */
997 pitem *item;
998 hm_fragment *frag;
999 unsigned long header_length;
1000 unsigned char seq64be[8];
1001 struct dtls1_retransmit_state saved_state;
1002
1003 /*
1004 OPENSSL_assert(s->internal->init_num == 0);
1005 OPENSSL_assert(s->internal->init_off == 0);
1006 */
1007
1008 /* XDTLS: the requested message ought to be found, otherwise error */
1009 memset(seq64be, 0, sizeof(seq64be));
1010 seq64be[6] = (unsigned char)(seq >> 8);
1011 seq64be[7] = (unsigned char)seq;
1012
1013 item = pqueue_find(s->d1->sent_messages, seq64be);
1014 if (item == NULL((void*)0)) {
1015#ifdef DEBUG
1016 fprintf(stderr(&__sF[2]), "retransmit: message %d non-existent\n", seq);
1017#endif
1018 *found = 0;
1019 return 0;
1020 }
1021
1022 *found = 1;
1023 frag = (hm_fragment *)item->data;
1024
1025 if (frag->msg_header.is_ccs)
1026 header_length = DTLS1_CCS_HEADER_LENGTH1;
1027 else
1028 header_length = DTLS1_HM_HEADER_LENGTH12;
1029
1030 memcpy(s->internal->init_buf->data, frag->fragment,
1031 frag->msg_header.msg_len + header_length);
1032 s->internal->init_num = frag->msg_header.msg_len + header_length;
1033
1034 dtls1_set_message_header_int(s, frag->msg_header.type,
1035 frag->msg_header.msg_len, frag->msg_header.seq, 0,
1036 frag->msg_header.frag_len);
1037
1038 /* save current state */
1039 saved_state.session = s->session;
1040 saved_state.epoch = tls12_record_layer_write_epoch(s->internal->rl);
1041
1042 s->d1->retransmitting = 1;
1043
1044 /* restore state in which the message was originally sent */
1045 s->session = frag->msg_header.saved_retransmit_state.session;
1046 if (!tls12_record_layer_use_write_epoch(s->internal->rl,
1047 frag->msg_header.saved_retransmit_state.epoch))
1048 return 0;
1049
1050 ret = dtls1_do_write(s, frag->msg_header.is_ccs ?
1051 SSL3_RT_CHANGE_CIPHER_SPEC20 : SSL3_RT_HANDSHAKE22);
1052
1053 /* restore current state */
1054 s->session = saved_state.session;
1055 if (!tls12_record_layer_use_write_epoch(s->internal->rl,
1056 saved_state.epoch))
1057 return 0;
1058
1059 s->d1->retransmitting = 0;
1060
1061 (void)BIO_flush(SSL_get_wbio(s))(int)BIO_ctrl(SSL_get_wbio(s),11,0,((void*)0));
1062 return ret;
1063}
1064
1065/* call this function when the buffered messages are no longer needed */
1066void
1067dtls1_clear_record_buffer(SSL *s)
1068{
1069 hm_fragment *frag;
1070 pitem *item;
1071
1072 for(item = pqueue_pop(s->d1->sent_messages); item != NULL((void*)0);
1073 item = pqueue_pop(s->d1->sent_messages)) {
1074 frag = item->data;
1075 if (frag->msg_header.is_ccs)
1076 tls12_record_layer_write_epoch_done(s->internal->rl,
1077 frag->msg_header.saved_retransmit_state.epoch);
1078 dtls1_hm_fragment_free(frag);
1079 pitem_free(item);
1080 }
1081}
1082
1083void
1084dtls1_set_message_header(SSL *s, unsigned char mt, unsigned long len,
1085 unsigned long frag_off, unsigned long frag_len)
1086{
1087 /* Don't change sequence numbers while listening */
1088 if (frag_off == 0 && !s->d1->listen) {
1089 s->d1->handshake_write_seq = s->d1->next_handshake_write_seq;
1090 s->d1->next_handshake_write_seq++;
1091 }
1092
1093 dtls1_set_message_header_int(s, mt, len, s->d1->handshake_write_seq,
1094 frag_off, frag_len);
1095}
1096
1097/* don't actually do the writing, wait till the MTU has been retrieved */
1098void
1099dtls1_set_message_header_int(SSL *s, unsigned char mt, unsigned long len,
1100 unsigned short seq_num, unsigned long frag_off, unsigned long frag_len)
1101{
1102 struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
1103
1104 msg_hdr->type = mt;
1105 msg_hdr->msg_len = len;
1106 msg_hdr->seq = seq_num;
1107 msg_hdr->frag_off = frag_off;
1108 msg_hdr->frag_len = frag_len;
1109}
1110
1111static void
1112dtls1_fix_message_header(SSL *s, unsigned long frag_off, unsigned long frag_len)
1113{
1114 struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
1115
1116 msg_hdr->frag_off = frag_off;
1117 msg_hdr->frag_len = frag_len;
1118}
1119
1120static int
1121dtls1_write_message_header(const struct hm_header_st *msg_hdr,
1122 unsigned long frag_off, unsigned long frag_len, unsigned char *p)
1123{
1124 CBB cbb;
1125
1126 /* We assume DTLS1_HM_HEADER_LENGTH bytes are available for now... */
1127 if (!CBB_init_fixed(&cbb, p, DTLS1_HM_HEADER_LENGTH12))
1128 return 0;
1129 if (!CBB_add_u8(&cbb, msg_hdr->type))
1130 goto err;
1131 if (!CBB_add_u24(&cbb, msg_hdr->msg_len))
1132 goto err;
1133 if (!CBB_add_u16(&cbb, msg_hdr->seq))
1134 goto err;
1135 if (!CBB_add_u24(&cbb, frag_off))
1136 goto err;
1137 if (!CBB_add_u24(&cbb, frag_len))
1138 goto err;
1139 if (!CBB_finish(&cbb, NULL((void*)0), NULL((void*)0)))
1140 goto err;
1141
1142 return 1;
1143
1144 err:
1145 CBB_cleanup(&cbb);
1146 return 0;
1147}
1148
1149unsigned int
1150dtls1_min_mtu(void)
1151{
1152 return (g_probable_mtu[(sizeof(g_probable_mtu) /
1153 sizeof(g_probable_mtu[0])) - 1]);
1154}
1155
1156static unsigned int
1157dtls1_guess_mtu(unsigned int curr_mtu)
1158{
1159 unsigned int i;
1160
1161 if (curr_mtu == 0)
1162 return g_probable_mtu[0];
1163
1164 for (i = 0; i < sizeof(g_probable_mtu) / sizeof(g_probable_mtu[0]); i++)
1165 if (curr_mtu > g_probable_mtu[i])
1166 return g_probable_mtu[i];
1167
1168 return curr_mtu;
1169}
1170
1171int
1172dtls1_get_message_header(CBS *header, struct hm_header_st *msg_hdr)
1173{
1174 uint32_t msg_len, frag_off, frag_len;
1175 uint16_t seq;
1176 uint8_t type;
1177
1178 memset(msg_hdr, 0, sizeof(*msg_hdr));
1179
1180 if (!CBS_get_u8(header, &type))
1181 return 0;
1182 if (!CBS_get_u24(header, &msg_len))
1183 return 0;
1184 if (!CBS_get_u16(header, &seq))
1185 return 0;
1186 if (!CBS_get_u24(header, &frag_off))
1187 return 0;
1188 if (!CBS_get_u24(header, &frag_len))
1189 return 0;
1190
1191 msg_hdr->type = type;
1192 msg_hdr->msg_len = msg_len;
1193 msg_hdr->seq = seq;
1194 msg_hdr->frag_off = frag_off;
1195 msg_hdr->frag_len = frag_len;
1196
1197 return 1;
1198}