|
1 /* ssl/d1_both.c */ |
|
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 © Portions copyright (c) 2006 Nokia Corporation. All rights reserved. |
|
117 */ |
|
118 |
|
119 #include <limits.h> |
|
120 #include <string.h> |
|
121 #include <stdio.h> |
|
122 #include "ssl_locl.h" |
|
123 #include <openssl/buffer.h> |
|
124 #include <openssl/rand.h> |
|
125 #include <openssl/objects.h> |
|
126 #include <openssl/evp.h> |
|
127 #include <openssl/x509.h> |
|
128 |
|
129 |
|
130 /* XDTLS: figure out the right values */ |
|
131 #ifdef EMULATOR |
|
132 static const unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28}; |
|
133 #else |
|
134 static unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28}; |
|
135 #endif |
|
136 |
|
137 static unsigned int dtls1_min_mtu(void); |
|
138 static unsigned int dtls1_guess_mtu(unsigned int curr_mtu); |
|
139 static void dtls1_fix_message_header(SSL *s, unsigned long frag_off, |
|
140 unsigned long frag_len); |
|
141 static unsigned char *dtls1_write_message_header(SSL *s, |
|
142 unsigned char *p); |
|
143 static void dtls1_set_message_header_int(SSL *s, unsigned char mt, |
|
144 unsigned long len, unsigned short seq_num, unsigned long frag_off, |
|
145 unsigned long frag_len); |
|
146 static int dtls1_retransmit_buffered_messages(SSL *s); |
|
147 static long dtls1_get_message_fragment(SSL *s, int st1, int stn, |
|
148 long max, int *ok); |
|
149 |
|
150 static hm_fragment * |
|
151 dtls1_hm_fragment_new(unsigned long frag_len) |
|
152 { |
|
153 hm_fragment *frag = NULL; |
|
154 unsigned char *buf = NULL; |
|
155 |
|
156 frag = (hm_fragment *)OPENSSL_malloc(sizeof(hm_fragment)); |
|
157 if ( frag == NULL) |
|
158 return NULL; |
|
159 |
|
160 if (frag_len) |
|
161 { |
|
162 buf = (unsigned char *)OPENSSL_malloc(frag_len); |
|
163 if ( buf == NULL) |
|
164 { |
|
165 OPENSSL_free(frag); |
|
166 return NULL; |
|
167 } |
|
168 } |
|
169 |
|
170 /* zero length fragment gets zero frag->fragment */ |
|
171 frag->fragment = buf; |
|
172 |
|
173 return frag; |
|
174 } |
|
175 |
|
176 static void |
|
177 dtls1_hm_fragment_free(hm_fragment *frag) |
|
178 { |
|
179 if (frag->fragment) OPENSSL_free(frag->fragment); |
|
180 OPENSSL_free(frag); |
|
181 } |
|
182 |
|
183 /* send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or SSL3_RT_CHANGE_CIPHER_SPEC) */ |
|
184 int dtls1_do_write(SSL *s, int type) |
|
185 { |
|
186 int ret; |
|
187 int curr_mtu; |
|
188 unsigned int len, frag_off; |
|
189 |
|
190 /* AHA! Figure out the MTU, and stick to the right size */ |
|
191 if ( ! (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) |
|
192 { |
|
193 s->d1->mtu = |
|
194 BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); |
|
195 |
|
196 /* I've seen the kernel return bogus numbers when it doesn't know |
|
197 * (initial write), so just make sure we have a reasonable number */ |
|
198 if ( s->d1->mtu < dtls1_min_mtu()) |
|
199 { |
|
200 s->d1->mtu = 0; |
|
201 s->d1->mtu = dtls1_guess_mtu(s->d1->mtu); |
|
202 BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU, |
|
203 s->d1->mtu, NULL); |
|
204 } |
|
205 } |
|
206 #if 0 |
|
207 mtu = s->d1->mtu; |
|
208 |
|
209 fprintf(stderr, "using MTU = %d\n", mtu); |
|
210 |
|
211 mtu -= (DTLS1_HM_HEADER_LENGTH + DTLS1_RT_HEADER_LENGTH); |
|
212 |
|
213 curr_mtu = mtu - BIO_wpending(SSL_get_wbio(s)); |
|
214 |
|
215 if ( curr_mtu > 0) |
|
216 mtu = curr_mtu; |
|
217 else if ( ( ret = BIO_flush(SSL_get_wbio(s))) <= 0) |
|
218 return ret; |
|
219 |
|
220 if ( BIO_wpending(SSL_get_wbio(s)) + s->init_num >= mtu) |
|
221 { |
|
222 ret = BIO_flush(SSL_get_wbio(s)); |
|
223 if ( ret <= 0) |
|
224 return ret; |
|
225 mtu = s->d1->mtu - (DTLS1_HM_HEADER_LENGTH + DTLS1_RT_HEADER_LENGTH); |
|
226 } |
|
227 |
|
228 OPENSSL_assert(mtu > 0); /* should have something reasonable now */ |
|
229 |
|
230 #endif |
|
231 |
|
232 if ( s->init_off == 0 && type == SSL3_RT_HANDSHAKE) |
|
233 OPENSSL_assert(s->init_num == |
|
234 (int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH); |
|
235 |
|
236 frag_off = 0; |
|
237 while( s->init_num) |
|
238 { |
|
239 curr_mtu = s->d1->mtu - BIO_wpending(SSL_get_wbio(s)) - |
|
240 DTLS1_RT_HEADER_LENGTH; |
|
241 |
|
242 if ( curr_mtu <= DTLS1_HM_HEADER_LENGTH) |
|
243 { |
|
244 /* grr.. we could get an error if MTU picked was wrong */ |
|
245 ret = BIO_flush(SSL_get_wbio(s)); |
|
246 if ( ret <= 0) |
|
247 return ret; |
|
248 curr_mtu = s->d1->mtu - DTLS1_RT_HEADER_LENGTH; |
|
249 } |
|
250 |
|
251 if ( s->init_num > curr_mtu) |
|
252 len = curr_mtu; |
|
253 else |
|
254 len = s->init_num; |
|
255 |
|
256 |
|
257 /* XDTLS: this function is too long. split out the CCS part */ |
|
258 if ( type == SSL3_RT_HANDSHAKE) |
|
259 { |
|
260 if ( s->init_off != 0) |
|
261 { |
|
262 OPENSSL_assert(s->init_off > DTLS1_HM_HEADER_LENGTH); |
|
263 s->init_off -= DTLS1_HM_HEADER_LENGTH; |
|
264 s->init_num += DTLS1_HM_HEADER_LENGTH; |
|
265 |
|
266 /* write atleast DTLS1_HM_HEADER_LENGTH bytes */ |
|
267 if ( len <= DTLS1_HM_HEADER_LENGTH) |
|
268 len += DTLS1_HM_HEADER_LENGTH; |
|
269 } |
|
270 |
|
271 dtls1_fix_message_header(s, frag_off, |
|
272 len - DTLS1_HM_HEADER_LENGTH); |
|
273 |
|
274 dtls1_write_message_header(s, (unsigned char *)&s->init_buf->data[s->init_off]); |
|
275 |
|
276 OPENSSL_assert(len >= DTLS1_HM_HEADER_LENGTH); |
|
277 } |
|
278 |
|
279 ret=dtls1_write_bytes(s,type,&s->init_buf->data[s->init_off], |
|
280 len); |
|
281 if (ret < 0) |
|
282 { |
|
283 /* might need to update MTU here, but we don't know |
|
284 * which previous packet caused the failure -- so can't |
|
285 * really retransmit anything. continue as if everything |
|
286 * is fine and wait for an alert to handle the |
|
287 * retransmit |
|
288 */ |
|
289 if ( BIO_ctrl(SSL_get_wbio(s), |
|
290 BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL)) |
|
291 s->d1->mtu = BIO_ctrl(SSL_get_wbio(s), |
|
292 BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); |
|
293 else |
|
294 return(-1); |
|
295 } |
|
296 else |
|
297 { |
|
298 |
|
299 /* bad if this assert fails, only part of the handshake |
|
300 * message got sent. but why would this happen? */ |
|
301 OPENSSL_assert(len == (unsigned int)ret); |
|
302 |
|
303 if (type == SSL3_RT_HANDSHAKE && ! s->d1->retransmitting) |
|
304 { |
|
305 /* should not be done for 'Hello Request's, but in that case |
|
306 * we'll ignore the result anyway */ |
|
307 unsigned char *p = (unsigned char *)&s->init_buf->data[s->init_off]; |
|
308 const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; |
|
309 int xlen; |
|
310 |
|
311 if (frag_off == 0 && s->client_version != DTLS1_BAD_VER) |
|
312 { |
|
313 /* reconstruct message header is if it |
|
314 * is being sent in single fragment */ |
|
315 *p++ = msg_hdr->type; |
|
316 l2n3(msg_hdr->msg_len,p); |
|
317 s2n (msg_hdr->seq,p); |
|
318 l2n3(0,p); |
|
319 l2n3(msg_hdr->msg_len,p); |
|
320 p -= DTLS1_HM_HEADER_LENGTH; |
|
321 xlen = ret; |
|
322 } |
|
323 else |
|
324 { |
|
325 p += DTLS1_HM_HEADER_LENGTH; |
|
326 xlen = ret - DTLS1_HM_HEADER_LENGTH; |
|
327 } |
|
328 |
|
329 ssl3_finish_mac(s, p, xlen); |
|
330 } |
|
331 |
|
332 if (ret == s->init_num) |
|
333 { |
|
334 if (s->msg_callback) |
|
335 s->msg_callback(1, s->version, type, s->init_buf->data, |
|
336 (size_t)(s->init_off + s->init_num), s, |
|
337 s->msg_callback_arg); |
|
338 |
|
339 s->init_off = 0; /* done writing this message */ |
|
340 s->init_num = 0; |
|
341 |
|
342 return(1); |
|
343 } |
|
344 s->init_off+=ret; |
|
345 s->init_num-=ret; |
|
346 frag_off += (ret -= DTLS1_HM_HEADER_LENGTH); |
|
347 } |
|
348 } |
|
349 return(0); |
|
350 } |
|
351 |
|
352 |
|
353 /* Obtain handshake message of message type 'mt' (any if mt == -1), |
|
354 * maximum acceptable body length 'max'. |
|
355 * Read an entire handshake message. Handshake messages arrive in |
|
356 * fragments. |
|
357 */ |
|
358 long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) |
|
359 { |
|
360 int i, al; |
|
361 struct hm_header_st *msg_hdr; |
|
362 |
|
363 /* s3->tmp is used to store messages that are unexpected, caused |
|
364 * by the absence of an optional handshake message */ |
|
365 if (s->s3->tmp.reuse_message) |
|
366 { |
|
367 s->s3->tmp.reuse_message=0; |
|
368 if ((mt >= 0) && (s->s3->tmp.message_type != mt)) |
|
369 { |
|
370 al=SSL_AD_UNEXPECTED_MESSAGE; |
|
371 SSLerr(SSL_F_DTLS1_GET_MESSAGE,SSL_R_UNEXPECTED_MESSAGE); |
|
372 goto f_err; |
|
373 } |
|
374 *ok=1; |
|
375 s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; |
|
376 s->init_num = (int)s->s3->tmp.message_size; |
|
377 return s->init_num; |
|
378 } |
|
379 |
|
380 msg_hdr = &s->d1->r_msg_hdr; |
|
381 do |
|
382 { |
|
383 if ( msg_hdr->frag_off == 0) |
|
384 { |
|
385 /* s->d1->r_message_header.msg_len = 0; */ |
|
386 memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); |
|
387 } |
|
388 |
|
389 i = dtls1_get_message_fragment(s, st1, stn, max, ok); |
|
390 if ( i == DTLS1_HM_BAD_FRAGMENT || |
|
391 i == DTLS1_HM_FRAGMENT_RETRY) /* bad fragment received */ |
|
392 continue; |
|
393 else if ( i <= 0 && !*ok) |
|
394 return i; |
|
395 |
|
396 /* Note that s->init_sum is used as a counter summing |
|
397 * up fragments' lengths: as soon as they sum up to |
|
398 * handshake packet length, we assume we have got all |
|
399 * the fragments. Overlapping fragments would cause |
|
400 * premature termination, so we don't expect overlaps. |
|
401 * Well, handling overlaps would require something more |
|
402 * drastic. Indeed, as it is now there is no way to |
|
403 * tell if out-of-order fragment from the middle was |
|
404 * the last. '>=' is the best/least we can do to control |
|
405 * the potential damage caused by malformed overlaps. */ |
|
406 if ((unsigned int)s->init_num >= msg_hdr->msg_len) |
|
407 { |
|
408 unsigned char *p = (unsigned char *)s->init_buf->data; |
|
409 unsigned long msg_len = msg_hdr->msg_len; |
|
410 |
|
411 /* reconstruct message header as if it was |
|
412 * sent in single fragment */ |
|
413 *(p++) = msg_hdr->type; |
|
414 l2n3(msg_len,p); |
|
415 s2n (msg_hdr->seq,p); |
|
416 l2n3(0,p); |
|
417 l2n3(msg_len,p); |
|
418 if (s->client_version != DTLS1_BAD_VER) |
|
419 p -= DTLS1_HM_HEADER_LENGTH, |
|
420 msg_len += DTLS1_HM_HEADER_LENGTH; |
|
421 |
|
422 ssl3_finish_mac(s, p, msg_len); |
|
423 if (s->msg_callback) |
|
424 s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, |
|
425 p, msg_len, |
|
426 s, s->msg_callback_arg); |
|
427 |
|
428 memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); |
|
429 |
|
430 s->d1->handshake_read_seq++; |
|
431 /* we just read a handshake message from the other side: |
|
432 * this means that we don't need to retransmit of the |
|
433 * buffered messages. |
|
434 * XDTLS: may be able clear out this |
|
435 * buffer a little sooner (i.e if an out-of-order |
|
436 * handshake message/record is received at the record |
|
437 * layer. |
|
438 * XDTLS: exception is that the server needs to |
|
439 * know that change cipher spec and finished messages |
|
440 * have been received by the client before clearing this |
|
441 * buffer. this can simply be done by waiting for the |
|
442 * first data segment, but is there a better way? */ |
|
443 dtls1_clear_record_buffer(s); |
|
444 |
|
445 s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; |
|
446 return s->init_num; |
|
447 } |
|
448 else |
|
449 msg_hdr->frag_off = i; |
|
450 } while(1) ; |
|
451 |
|
452 f_err: |
|
453 ssl3_send_alert(s,SSL3_AL_FATAL,al); |
|
454 *ok = 0; |
|
455 return -1; |
|
456 } |
|
457 |
|
458 |
|
459 static int dtls1_preprocess_fragment(SSL *s,struct hm_header_st *msg_hdr,int max) |
|
460 { |
|
461 size_t frag_off,frag_len,msg_len; |
|
462 |
|
463 msg_len = msg_hdr->msg_len; |
|
464 frag_off = msg_hdr->frag_off; |
|
465 frag_len = msg_hdr->frag_len; |
|
466 |
|
467 /* sanity checking */ |
|
468 if ( (frag_off+frag_len) > msg_len) |
|
469 { |
|
470 SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE); |
|
471 return SSL_AD_ILLEGAL_PARAMETER; |
|
472 } |
|
473 |
|
474 if ( (frag_off+frag_len) > (unsigned long)max) |
|
475 { |
|
476 SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE); |
|
477 return SSL_AD_ILLEGAL_PARAMETER; |
|
478 } |
|
479 |
|
480 if ( s->d1->r_msg_hdr.frag_off == 0) /* first fragment */ |
|
481 { |
|
482 /* msg_len is limited to 2^24, but is effectively checked |
|
483 * against max above */ |
|
484 if (!BUF_MEM_grow_clean(s->init_buf,(int)msg_len+DTLS1_HM_HEADER_LENGTH)) |
|
485 { |
|
486 SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,ERR_R_BUF_LIB); |
|
487 return SSL_AD_INTERNAL_ERROR; |
|
488 } |
|
489 |
|
490 s->s3->tmp.message_size = msg_len; |
|
491 s->d1->r_msg_hdr.msg_len = msg_len; |
|
492 s->s3->tmp.message_type = msg_hdr->type; |
|
493 s->d1->r_msg_hdr.type = msg_hdr->type; |
|
494 s->d1->r_msg_hdr.seq = msg_hdr->seq; |
|
495 } |
|
496 else if (msg_len != s->d1->r_msg_hdr.msg_len) |
|
497 { |
|
498 /* They must be playing with us! BTW, failure to enforce |
|
499 * upper limit would open possibility for buffer overrun. */ |
|
500 SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE); |
|
501 return SSL_AD_ILLEGAL_PARAMETER; |
|
502 } |
|
503 |
|
504 return 0; /* no error */ |
|
505 } |
|
506 |
|
507 |
|
508 static int |
|
509 dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok) |
|
510 { |
|
511 /* (0) check whether the desired fragment is available |
|
512 * if so: |
|
513 * (1) copy over the fragment to s->init_buf->data[] |
|
514 * (2) update s->init_num |
|
515 */ |
|
516 pitem *item; |
|
517 hm_fragment *frag; |
|
518 int al; |
|
519 |
|
520 *ok = 0; |
|
521 item = pqueue_peek(s->d1->buffered_messages); |
|
522 if ( item == NULL) |
|
523 return 0; |
|
524 |
|
525 frag = (hm_fragment *)item->data; |
|
526 |
|
527 if ( s->d1->handshake_read_seq == frag->msg_header.seq) |
|
528 { |
|
529 pqueue_pop(s->d1->buffered_messages); |
|
530 |
|
531 al=dtls1_preprocess_fragment(s,&frag->msg_header,max); |
|
532 |
|
533 if (al==0) /* no alert */ |
|
534 { |
|
535 unsigned char *p = (unsigned char *)s->init_buf->data+DTLS1_HM_HEADER_LENGTH; |
|
536 memcpy(&p[frag->msg_header.frag_off], |
|
537 frag->fragment,frag->msg_header.frag_len); |
|
538 } |
|
539 |
|
540 dtls1_hm_fragment_free(frag); |
|
541 pitem_free(item); |
|
542 |
|
543 if (al==0) |
|
544 { |
|
545 *ok = 1; |
|
546 return frag->msg_header.frag_len; |
|
547 } |
|
548 |
|
549 ssl3_send_alert(s,SSL3_AL_FATAL,al); |
|
550 s->init_num = 0; |
|
551 *ok = 0; |
|
552 return -1; |
|
553 } |
|
554 else |
|
555 return 0; |
|
556 } |
|
557 |
|
558 |
|
559 static int |
|
560 dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok) |
|
561 { |
|
562 int i=-1; |
|
563 hm_fragment *frag = NULL; |
|
564 pitem *item = NULL; |
|
565 PQ_64BIT seq64; |
|
566 unsigned long frag_len = msg_hdr->frag_len; |
|
567 |
|
568 if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len) |
|
569 goto err; |
|
570 |
|
571 if (msg_hdr->seq <= s->d1->handshake_read_seq) |
|
572 { |
|
573 unsigned char devnull [256]; |
|
574 |
|
575 while (frag_len) |
|
576 { |
|
577 i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, |
|
578 devnull, |
|
579 frag_len>sizeof(devnull)?sizeof(devnull):frag_len,0); |
|
580 if (i<=0) goto err; |
|
581 frag_len -= i; |
|
582 } |
|
583 } |
|
584 frag = dtls1_hm_fragment_new(frag_len); |
|
585 if ( frag == NULL) |
|
586 goto err; |
|
587 |
|
588 |
|
589 memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); |
|
590 |
|
591 if (frag_len) |
|
592 { |
|
593 /* read the body of the fragment (header has already been read */ |
|
594 i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, |
|
595 frag->fragment,frag_len,0); |
|
596 if (i<=0 || (unsigned long)i!=frag_len) |
|
597 goto err; |
|
598 } |
|
599 pq_64bit_init(&seq64); |
|
600 pq_64bit_assign_word(&seq64, msg_hdr->seq); |
|
601 |
|
602 item = pitem_new(seq64, frag); |
|
603 pq_64bit_free(&seq64); |
|
604 if ( item == NULL) |
|
605 goto err; |
|
606 |
|
607 pqueue_insert(s->d1->buffered_messages, item); |
|
608 return DTLS1_HM_FRAGMENT_RETRY; |
|
609 |
|
610 err: |
|
611 if ( frag != NULL) dtls1_hm_fragment_free(frag); |
|
612 if ( item != NULL) OPENSSL_free(item); |
|
613 *ok = 0; |
|
614 return i; |
|
615 } |
|
616 |
|
617 |
|
618 static long |
|
619 dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok) |
|
620 { |
|
621 unsigned char wire[DTLS1_HM_HEADER_LENGTH]; |
|
622 unsigned long l, frag_off, frag_len; |
|
623 int i,al; |
|
624 struct hm_header_st msg_hdr; |
|
625 |
|
626 /* see if we have the required fragment already */ |
|
627 if ((frag_len = dtls1_retrieve_buffered_fragment(s,max,ok)) || *ok) |
|
628 { |
|
629 if (*ok) s->init_num += frag_len; |
|
630 return frag_len; |
|
631 } |
|
632 |
|
633 /* read handshake message header */ |
|
634 i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,wire, |
|
635 DTLS1_HM_HEADER_LENGTH, 0); |
|
636 if (i <= 0) /* nbio, or an error */ |
|
637 { |
|
638 s->rwstate=SSL_READING; |
|
639 *ok = 0; |
|
640 return i; |
|
641 } |
|
642 |
|
643 OPENSSL_assert(i == DTLS1_HM_HEADER_LENGTH); |
|
644 |
|
645 /* parse the message fragment header */ |
|
646 |
|
647 dtls1_get_message_header(wire, &msg_hdr); |
|
648 |
|
649 /* |
|
650 * if this is a future (or stale) message it gets buffered |
|
651 * (or dropped)--no further processing at this time |
|
652 */ |
|
653 if ( msg_hdr.seq != s->d1->handshake_read_seq) |
|
654 return dtls1_process_out_of_seq_message(s, &msg_hdr, ok); |
|
655 |
|
656 l = msg_hdr.msg_len; |
|
657 frag_off = msg_hdr.frag_off; |
|
658 frag_len = msg_hdr.frag_len; |
|
659 |
|
660 if (!s->server && s->d1->r_msg_hdr.frag_off == 0 && |
|
661 wire[0] == SSL3_MT_HELLO_REQUEST) |
|
662 { |
|
663 /* The server may always send 'Hello Request' messages -- |
|
664 * we are doing a handshake anyway now, so ignore them |
|
665 * if their format is correct. Does not count for |
|
666 * 'Finished' MAC. */ |
|
667 if (wire[1] == 0 && wire[2] == 0 && wire[3] == 0) |
|
668 { |
|
669 if (s->msg_callback) |
|
670 s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, |
|
671 wire, DTLS1_HM_HEADER_LENGTH, s, |
|
672 s->msg_callback_arg); |
|
673 |
|
674 s->init_num = 0; |
|
675 return dtls1_get_message_fragment(s, st1, stn, |
|
676 max, ok); |
|
677 } |
|
678 else /* Incorrectly formated Hello request */ |
|
679 { |
|
680 al=SSL_AD_UNEXPECTED_MESSAGE; |
|
681 SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_UNEXPECTED_MESSAGE); |
|
682 goto f_err; |
|
683 } |
|
684 } |
|
685 |
|
686 if ((al=dtls1_preprocess_fragment(s,&msg_hdr,max))) |
|
687 goto f_err; |
|
688 |
|
689 /* XDTLS: ressurect this when restart is in place */ |
|
690 s->state=stn; |
|
691 |
|
692 if ( frag_len > 0) |
|
693 { |
|
694 unsigned char *p=(unsigned char *)s->init_buf->data+DTLS1_HM_HEADER_LENGTH; |
|
695 |
|
696 i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, |
|
697 &p[frag_off],frag_len,0); |
|
698 /* XDTLS: fix this--message fragments cannot span multiple packets */ |
|
699 if (i <= 0) |
|
700 { |
|
701 s->rwstate=SSL_READING; |
|
702 *ok = 0; |
|
703 return i; |
|
704 } |
|
705 } |
|
706 else |
|
707 i = 0; |
|
708 |
|
709 /* XDTLS: an incorrectly formatted fragment should cause the |
|
710 * handshake to fail */ |
|
711 OPENSSL_assert(i == (int)frag_len); |
|
712 |
|
713 *ok = 1; |
|
714 |
|
715 /* Note that s->init_num is *not* used as current offset in |
|
716 * s->init_buf->data, but as a counter summing up fragments' |
|
717 * lengths: as soon as they sum up to handshake packet |
|
718 * length, we assume we have got all the fragments. */ |
|
719 s->init_num += frag_len; |
|
720 return frag_len; |
|
721 |
|
722 f_err: |
|
723 ssl3_send_alert(s,SSL3_AL_FATAL,al); |
|
724 s->init_num = 0; |
|
725 |
|
726 *ok=0; |
|
727 return(-1); |
|
728 } |
|
729 |
|
730 int dtls1_send_finished(SSL *s, int a, int b, const char *sender, int slen) |
|
731 { |
|
732 unsigned char *p,*d; |
|
733 int i; |
|
734 unsigned long l; |
|
735 |
|
736 if (s->state == a) |
|
737 { |
|
738 d=(unsigned char *)s->init_buf->data; |
|
739 p= &(d[DTLS1_HM_HEADER_LENGTH]); |
|
740 |
|
741 i=s->method->ssl3_enc->final_finish_mac(s, |
|
742 &(s->s3->finish_dgst1), |
|
743 &(s->s3->finish_dgst2), |
|
744 sender,slen,s->s3->tmp.finish_md); |
|
745 s->s3->tmp.finish_md_len = i; |
|
746 memcpy(p, s->s3->tmp.finish_md, i); |
|
747 p+=i; |
|
748 l=i; |
|
749 |
|
750 #ifdef OPENSSL_SYS_WIN16 |
|
751 /* MSVC 1.5 does not clear the top bytes of the word unless |
|
752 * I do this. |
|
753 */ |
|
754 l&=0xffff; |
|
755 #endif |
|
756 |
|
757 d = dtls1_set_message_header(s, d, SSL3_MT_FINISHED, l, 0, l); |
|
758 s->init_num=(int)l+DTLS1_HM_HEADER_LENGTH; |
|
759 s->init_off=0; |
|
760 |
|
761 /* buffer the message to handle re-xmits */ |
|
762 dtls1_buffer_message(s, 0); |
|
763 |
|
764 s->state=b; |
|
765 } |
|
766 |
|
767 /* SSL3_ST_SEND_xxxxxx_HELLO_B */ |
|
768 return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); |
|
769 } |
|
770 |
|
771 /* for these 2 messages, we need to |
|
772 * ssl->enc_read_ctx re-init |
|
773 * ssl->s3->read_sequence zero |
|
774 * ssl->s3->read_mac_secret re-init |
|
775 * ssl->session->read_sym_enc assign |
|
776 * ssl->session->read_compression assign |
|
777 * ssl->session->read_hash assign |
|
778 */ |
|
779 int dtls1_send_change_cipher_spec(SSL *s, int a, int b) |
|
780 { |
|
781 unsigned char *p; |
|
782 |
|
783 if (s->state == a) |
|
784 { |
|
785 p=(unsigned char *)s->init_buf->data; |
|
786 *p++=SSL3_MT_CCS; |
|
787 s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; |
|
788 s->init_num=DTLS1_CCS_HEADER_LENGTH; |
|
789 |
|
790 if (s->client_version == DTLS1_BAD_VER) |
|
791 { |
|
792 s->d1->next_handshake_write_seq++; |
|
793 s2n(s->d1->handshake_write_seq,p); |
|
794 s->init_num+=2; |
|
795 } |
|
796 |
|
797 s->init_off=0; |
|
798 |
|
799 dtls1_set_message_header_int(s, SSL3_MT_CCS, 0, |
|
800 s->d1->handshake_write_seq, 0, 0); |
|
801 |
|
802 /* buffer the message to handle re-xmits */ |
|
803 dtls1_buffer_message(s, 1); |
|
804 |
|
805 s->state=b; |
|
806 } |
|
807 |
|
808 /* SSL3_ST_CW_CHANGE_B */ |
|
809 return(dtls1_do_write(s,SSL3_RT_CHANGE_CIPHER_SPEC)); |
|
810 } |
|
811 |
|
812 unsigned long dtls1_output_cert_chain(SSL *s, X509 *x) |
|
813 { |
|
814 unsigned char *p; |
|
815 int n,i; |
|
816 unsigned long l= 3 + DTLS1_HM_HEADER_LENGTH; |
|
817 BUF_MEM *buf; |
|
818 X509_STORE_CTX xs_ctx; |
|
819 X509_OBJECT obj; |
|
820 |
|
821 /* TLSv1 sends a chain with nothing in it, instead of an alert */ |
|
822 buf=s->init_buf; |
|
823 if (!BUF_MEM_grow_clean(buf,10)) |
|
824 { |
|
825 SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB); |
|
826 return(0); |
|
827 } |
|
828 if (x != NULL) |
|
829 { |
|
830 if(!X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,NULL,NULL)) |
|
831 { |
|
832 SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_X509_LIB); |
|
833 return(0); |
|
834 } |
|
835 |
|
836 for (;;) |
|
837 { |
|
838 n=i2d_X509(x,NULL); |
|
839 if (!BUF_MEM_grow_clean(buf,(int)(n+l+3))) |
|
840 { |
|
841 SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB); |
|
842 return(0); |
|
843 } |
|
844 p=(unsigned char *)&(buf->data[l]); |
|
845 l2n3(n,p); |
|
846 i2d_X509(x,&p); |
|
847 l+=n+3; |
|
848 if (X509_NAME_cmp(X509_get_subject_name(x), |
|
849 X509_get_issuer_name(x)) == 0) break; |
|
850 |
|
851 i=X509_STORE_get_by_subject(&xs_ctx,X509_LU_X509, |
|
852 X509_get_issuer_name(x),&obj); |
|
853 if (i <= 0) break; |
|
854 x=obj.data.x509; |
|
855 /* Count is one too high since the X509_STORE_get uped the |
|
856 * ref count */ |
|
857 X509_free(x); |
|
858 } |
|
859 |
|
860 X509_STORE_CTX_cleanup(&xs_ctx); |
|
861 } |
|
862 |
|
863 /* Thawte special :-) */ |
|
864 if (s->ctx->extra_certs != NULL) |
|
865 for (i=0; i<sk_X509_num(s->ctx->extra_certs); i++) |
|
866 { |
|
867 x=sk_X509_value(s->ctx->extra_certs,i); |
|
868 n=i2d_X509(x,NULL); |
|
869 if (!BUF_MEM_grow_clean(buf,(int)(n+l+3))) |
|
870 { |
|
871 SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB); |
|
872 return(0); |
|
873 } |
|
874 p=(unsigned char *)&(buf->data[l]); |
|
875 l2n3(n,p); |
|
876 i2d_X509(x,&p); |
|
877 l+=n+3; |
|
878 } |
|
879 |
|
880 l-= (3 + DTLS1_HM_HEADER_LENGTH); |
|
881 |
|
882 p=(unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH]); |
|
883 l2n3(l,p); |
|
884 l+=3; |
|
885 p=(unsigned char *)&(buf->data[0]); |
|
886 p = dtls1_set_message_header(s, p, SSL3_MT_CERTIFICATE, l, 0, l); |
|
887 |
|
888 l+=DTLS1_HM_HEADER_LENGTH; |
|
889 return(l); |
|
890 } |
|
891 |
|
892 int dtls1_read_failed(SSL *s, int code) |
|
893 { |
|
894 DTLS1_STATE *state; |
|
895 BIO *bio; |
|
896 int send_alert = 0; |
|
897 |
|
898 if ( code > 0) |
|
899 { |
|
900 fprintf( stderr, "invalid state reached %s:%d", __FILE__, __LINE__); |
|
901 return 1; |
|
902 } |
|
903 |
|
904 bio = SSL_get_rbio(s); |
|
905 if ( ! BIO_dgram_recv_timedout(bio)) |
|
906 { |
|
907 /* not a timeout, none of our business, |
|
908 let higher layers handle this. in fact it's probably an error */ |
|
909 return code; |
|
910 } |
|
911 |
|
912 if ( ! SSL_in_init(s)) /* done, no need to send a retransmit */ |
|
913 { |
|
914 BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ); |
|
915 return code; |
|
916 } |
|
917 |
|
918 state = s->d1; |
|
919 state->timeout.num_alerts++; |
|
920 if ( state->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) |
|
921 { |
|
922 /* fail the connection, enough alerts have been sent */ |
|
923 SSLerr(SSL_F_DTLS1_READ_FAILED,SSL_R_READ_TIMEOUT_EXPIRED); |
|
924 return 0; |
|
925 } |
|
926 |
|
927 state->timeout.read_timeouts++; |
|
928 if ( state->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) |
|
929 { |
|
930 send_alert = 1; |
|
931 state->timeout.read_timeouts = 1; |
|
932 } |
|
933 |
|
934 |
|
935 #if 0 /* for now, each alert contains only one record number */ |
|
936 item = pqueue_peek(state->rcvd_records); |
|
937 if ( item ) |
|
938 { |
|
939 /* send an alert immediately for all the missing records */ |
|
940 } |
|
941 else |
|
942 #endif |
|
943 |
|
944 #if 0 /* no more alert sending, just retransmit the last set of messages */ |
|
945 if ( send_alert) |
|
946 ssl3_send_alert(s,SSL3_AL_WARNING, |
|
947 DTLS1_AD_MISSING_HANDSHAKE_MESSAGE); |
|
948 #endif |
|
949 |
|
950 return dtls1_retransmit_buffered_messages(s) ; |
|
951 } |
|
952 |
|
953 |
|
954 static int |
|
955 dtls1_retransmit_buffered_messages(SSL *s) |
|
956 { |
|
957 pqueue sent = s->d1->sent_messages; |
|
958 piterator iter; |
|
959 pitem *item; |
|
960 hm_fragment *frag; |
|
961 int found = 0; |
|
962 |
|
963 iter = pqueue_iterator(sent); |
|
964 |
|
965 for ( item = pqueue_next(&iter); item != NULL; item = pqueue_next(&iter)) |
|
966 { |
|
967 frag = (hm_fragment *)item->data; |
|
968 if ( dtls1_retransmit_message(s, frag->msg_header.seq, 0, &found) <= 0 && |
|
969 found) |
|
970 { |
|
971 fprintf(stderr, "dtls1_retransmit_message() failed\n"); |
|
972 return -1; |
|
973 } |
|
974 } |
|
975 |
|
976 return 1; |
|
977 } |
|
978 |
|
979 |
|
980 int |
|
981 dtls1_buffer_message(SSL *s, int is_ccs) |
|
982 { |
|
983 pitem *item; |
|
984 hm_fragment *frag; |
|
985 PQ_64BIT seq64; |
|
986 unsigned int epoch = s->d1->w_epoch; |
|
987 |
|
988 /* this function is called immediately after a message has |
|
989 * been serialized */ |
|
990 OPENSSL_assert(s->init_off == 0); |
|
991 |
|
992 frag = dtls1_hm_fragment_new(s->init_num); |
|
993 |
|
994 memcpy(frag->fragment, s->init_buf->data, s->init_num); |
|
995 |
|
996 if ( is_ccs) |
|
997 { |
|
998 OPENSSL_assert(s->d1->w_msg_hdr.msg_len + |
|
999 DTLS1_CCS_HEADER_LENGTH <= (unsigned int)s->init_num); |
|
1000 epoch++; |
|
1001 } |
|
1002 else |
|
1003 { |
|
1004 OPENSSL_assert(s->d1->w_msg_hdr.msg_len + |
|
1005 DTLS1_HM_HEADER_LENGTH == (unsigned int)s->init_num); |
|
1006 } |
|
1007 |
|
1008 frag->msg_header.msg_len = s->d1->w_msg_hdr.msg_len; |
|
1009 frag->msg_header.seq = s->d1->w_msg_hdr.seq; |
|
1010 frag->msg_header.type = s->d1->w_msg_hdr.type; |
|
1011 frag->msg_header.frag_off = 0; |
|
1012 frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len; |
|
1013 frag->msg_header.is_ccs = is_ccs; |
|
1014 |
|
1015 pq_64bit_init(&seq64); |
|
1016 pq_64bit_assign_word(&seq64, epoch<<16 | frag->msg_header.seq); |
|
1017 |
|
1018 item = pitem_new(seq64, frag); |
|
1019 pq_64bit_free(&seq64); |
|
1020 if ( item == NULL) |
|
1021 { |
|
1022 dtls1_hm_fragment_free(frag); |
|
1023 return 0; |
|
1024 } |
|
1025 |
|
1026 #if 0 |
|
1027 fprintf( stderr, "buffered messge: \ttype = %xx\n", msg_buf->type); |
|
1028 fprintf( stderr, "\t\t\t\t\tlen = %d\n", msg_buf->len); |
|
1029 fprintf( stderr, "\t\t\t\t\tseq_num = %d\n", msg_buf->seq_num); |
|
1030 #endif |
|
1031 |
|
1032 pqueue_insert(s->d1->sent_messages, item); |
|
1033 return 1; |
|
1034 } |
|
1035 |
|
1036 int |
|
1037 dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off, |
|
1038 int *found) |
|
1039 { |
|
1040 int ret; |
|
1041 /* XDTLS: for now assuming that read/writes are blocking */ |
|
1042 pitem *item; |
|
1043 hm_fragment *frag ; |
|
1044 unsigned long header_length; |
|
1045 PQ_64BIT seq64; |
|
1046 |
|
1047 /* |
|
1048 OPENSSL_assert(s->init_num == 0); |
|
1049 OPENSSL_assert(s->init_off == 0); |
|
1050 */ |
|
1051 |
|
1052 /* XDTLS: the requested message ought to be found, otherwise error */ |
|
1053 pq_64bit_init(&seq64); |
|
1054 pq_64bit_assign_word(&seq64, seq); |
|
1055 |
|
1056 item = pqueue_find(s->d1->sent_messages, seq64); |
|
1057 pq_64bit_free(&seq64); |
|
1058 if ( item == NULL) |
|
1059 { |
|
1060 fprintf(stderr, "retransmit: message %d non-existant\n", seq); |
|
1061 *found = 0; |
|
1062 return 0; |
|
1063 } |
|
1064 |
|
1065 *found = 1; |
|
1066 frag = (hm_fragment *)item->data; |
|
1067 |
|
1068 if ( frag->msg_header.is_ccs) |
|
1069 header_length = DTLS1_CCS_HEADER_LENGTH; |
|
1070 else |
|
1071 header_length = DTLS1_HM_HEADER_LENGTH; |
|
1072 |
|
1073 memcpy(s->init_buf->data, frag->fragment, |
|
1074 frag->msg_header.msg_len + header_length); |
|
1075 s->init_num = frag->msg_header.msg_len + header_length; |
|
1076 |
|
1077 dtls1_set_message_header_int(s, frag->msg_header.type, |
|
1078 frag->msg_header.msg_len, frag->msg_header.seq, 0, |
|
1079 frag->msg_header.frag_len); |
|
1080 |
|
1081 s->d1->retransmitting = 1; |
|
1082 ret = dtls1_do_write(s, frag->msg_header.is_ccs ? |
|
1083 SSL3_RT_CHANGE_CIPHER_SPEC : SSL3_RT_HANDSHAKE); |
|
1084 s->d1->retransmitting = 0; |
|
1085 |
|
1086 (void)BIO_flush(SSL_get_wbio(s)); |
|
1087 return ret; |
|
1088 } |
|
1089 |
|
1090 /* call this function when the buffered messages are no longer needed */ |
|
1091 void |
|
1092 dtls1_clear_record_buffer(SSL *s) |
|
1093 { |
|
1094 pitem *item; |
|
1095 |
|
1096 for(item = pqueue_pop(s->d1->sent_messages); |
|
1097 item != NULL; item = pqueue_pop(s->d1->sent_messages)) |
|
1098 { |
|
1099 dtls1_hm_fragment_free((hm_fragment *)item->data); |
|
1100 pitem_free(item); |
|
1101 } |
|
1102 } |
|
1103 |
|
1104 |
|
1105 unsigned char * |
|
1106 dtls1_set_message_header(SSL *s, unsigned char *p, unsigned char mt, |
|
1107 unsigned long len, unsigned long frag_off, unsigned long frag_len) |
|
1108 { |
|
1109 if ( frag_off == 0) |
|
1110 { |
|
1111 s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; |
|
1112 s->d1->next_handshake_write_seq++; |
|
1113 } |
|
1114 |
|
1115 dtls1_set_message_header_int(s, mt, len, s->d1->handshake_write_seq, |
|
1116 frag_off, frag_len); |
|
1117 |
|
1118 return p += DTLS1_HM_HEADER_LENGTH; |
|
1119 } |
|
1120 |
|
1121 |
|
1122 /* don't actually do the writing, wait till the MTU has been retrieved */ |
|
1123 static void |
|
1124 dtls1_set_message_header_int(SSL *s, unsigned char mt, |
|
1125 unsigned long len, unsigned short seq_num, unsigned long frag_off, |
|
1126 unsigned long frag_len) |
|
1127 { |
|
1128 struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; |
|
1129 |
|
1130 msg_hdr->type = mt; |
|
1131 msg_hdr->msg_len = len; |
|
1132 msg_hdr->seq = seq_num; |
|
1133 msg_hdr->frag_off = frag_off; |
|
1134 msg_hdr->frag_len = frag_len; |
|
1135 } |
|
1136 |
|
1137 static void |
|
1138 dtls1_fix_message_header(SSL *s, unsigned long frag_off, |
|
1139 unsigned long frag_len) |
|
1140 { |
|
1141 struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; |
|
1142 |
|
1143 msg_hdr->frag_off = frag_off; |
|
1144 msg_hdr->frag_len = frag_len; |
|
1145 } |
|
1146 |
|
1147 static unsigned char * |
|
1148 dtls1_write_message_header(SSL *s, unsigned char *p) |
|
1149 { |
|
1150 struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; |
|
1151 |
|
1152 *p++ = msg_hdr->type; |
|
1153 l2n3(msg_hdr->msg_len, p); |
|
1154 |
|
1155 s2n(msg_hdr->seq, p); |
|
1156 l2n3(msg_hdr->frag_off, p); |
|
1157 l2n3(msg_hdr->frag_len, p); |
|
1158 |
|
1159 return p; |
|
1160 } |
|
1161 |
|
1162 static unsigned int |
|
1163 dtls1_min_mtu(void) |
|
1164 { |
|
1165 return (g_probable_mtu[(sizeof(g_probable_mtu) / |
|
1166 sizeof(g_probable_mtu[0])) - 1]); |
|
1167 } |
|
1168 |
|
1169 static unsigned int |
|
1170 dtls1_guess_mtu(unsigned int curr_mtu) |
|
1171 { |
|
1172 size_t i; |
|
1173 |
|
1174 if ( curr_mtu == 0 ) |
|
1175 return g_probable_mtu[0] ; |
|
1176 |
|
1177 for ( i = 0; i < sizeof(g_probable_mtu)/sizeof(g_probable_mtu[0]); i++) |
|
1178 if ( curr_mtu > g_probable_mtu[i]) |
|
1179 return g_probable_mtu[i]; |
|
1180 |
|
1181 return curr_mtu; |
|
1182 } |
|
1183 |
|
1184 void |
|
1185 dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr) |
|
1186 { |
|
1187 memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); |
|
1188 msg_hdr->type = *(data++); |
|
1189 n2l3(data, msg_hdr->msg_len); |
|
1190 |
|
1191 n2s(data, msg_hdr->seq); |
|
1192 n2l3(data, msg_hdr->frag_off); |
|
1193 n2l3(data, msg_hdr->frag_len); |
|
1194 } |
|
1195 |
|
1196 void |
|
1197 dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr) |
|
1198 { |
|
1199 memset(ccs_hdr, 0x00, sizeof(struct ccs_header_st)); |
|
1200 |
|
1201 ccs_hdr->type = *(data++); |
|
1202 } |