| OLD | NEW |
| (Empty) |
| 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 #include <limits.h> | |
| 117 #include <string.h> | |
| 118 #include <stdio.h> | |
| 119 #include "ssl_locl.h" | |
| 120 #include <openssl/buffer.h> | |
| 121 #include <openssl/rand.h> | |
| 122 #include <openssl/objects.h> | |
| 123 #include <openssl/evp.h> | |
| 124 #include <openssl/x509.h> | |
| 125 | |
| 126 #define RSMBLY_BITMASK_SIZE(msg_len) (((msg_len) + 7) / 8) | |
| 127 | |
| 128 #define RSMBLY_BITMASK_MARK(bitmask, start, end) { \ | |
| 129 if ((end) - (start) <= 8) { \ | |
| 130 long ii; \ | |
| 131 for (ii = (start); ii < (end); ii++) bitmask[((i
i) >> 3)] |= (1 << ((ii) & 7)); \ | |
| 132 } else { \ | |
| 133 long ii; \ | |
| 134 bitmask[((start) >> 3)] |= bitmask_start_values[
((start) & 7)]; \ | |
| 135 for (ii = (((start) >> 3) + 1); ii < ((((end) -
1)) >> 3); ii++) bitmask[ii] = 0xff; \ | |
| 136 bitmask[(((end) - 1) >> 3)] |= bitmask_end_value
s[((end) & 7)]; \ | |
| 137 } } | |
| 138 | |
| 139 #define RSMBLY_BITMASK_IS_COMPLETE(bitmask, msg_len, is_complete) { \ | |
| 140 long ii; \ | |
| 141 OPENSSL_assert((msg_len) > 0); \ | |
| 142 is_complete = 1; \ | |
| 143 if (bitmask[(((msg_len) - 1) >> 3)] != bitmask_end_value
s[((msg_len) & 7)]) is_complete = 0; \ | |
| 144 if (is_complete) for (ii = (((msg_len) - 1) >> 3) - 1; i
i >= 0 ; ii--) \ | |
| 145 if (bitmask[ii] != 0xff) { is_complete = 0; brea
k; } } | |
| 146 | |
| 147 #if 0 | |
| 148 #define RSMBLY_BITMASK_PRINT(bitmask, msg_len) { \ | |
| 149 long ii; \ | |
| 150 printf("bitmask: "); for (ii = 0; ii < (msg_len); ii++)
\ | |
| 151 printf("%d ", (bitmask[ii >> 3] & (1 << (ii & 7))) >> (i
i & 7)); \ | |
| 152 printf("\n"); } | |
| 153 #endif | |
| 154 | |
| 155 static unsigned char bitmask_start_values[] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe
0, 0xc0, 0x80}; | |
| 156 static unsigned char bitmask_end_values[] = {0xff, 0x01, 0x03, 0x07, 0x0f, 0x1
f, 0x3f, 0x7f}; | |
| 157 | |
| 158 /* XDTLS: figure out the right values */ | |
| 159 static unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28}; | |
| 160 | |
| 161 static unsigned int dtls1_guess_mtu(unsigned int curr_mtu); | |
| 162 static void dtls1_fix_message_header(SSL *s, unsigned long frag_off, | |
| 163 unsigned long frag_len); | |
| 164 static unsigned char *dtls1_write_message_header(SSL *s, | |
| 165 unsigned char *p); | |
| 166 static void dtls1_set_message_header_int(SSL *s, unsigned char mt, | |
| 167 unsigned long len, unsigned short seq_num, unsigned long frag_off, | |
| 168 unsigned long frag_len); | |
| 169 static long dtls1_get_message_fragment(SSL *s, int st1, int stn, | |
| 170 long max, int *ok); | |
| 171 | |
| 172 static hm_fragment * | |
| 173 dtls1_hm_fragment_new(unsigned long frag_len, int reassembly) | |
| 174 { | |
| 175 hm_fragment *frag = NULL; | |
| 176 unsigned char *buf = NULL; | |
| 177 unsigned char *bitmask = NULL; | |
| 178 | |
| 179 frag = (hm_fragment *)OPENSSL_malloc(sizeof(hm_fragment)); | |
| 180 if ( frag == NULL) | |
| 181 return NULL; | |
| 182 | |
| 183 if (frag_len) | |
| 184 { | |
| 185 buf = (unsigned char *)OPENSSL_malloc(frag_len); | |
| 186 if ( buf == NULL) | |
| 187 { | |
| 188 OPENSSL_free(frag); | |
| 189 return NULL; | |
| 190 } | |
| 191 } | |
| 192 | |
| 193 /* zero length fragment gets zero frag->fragment */ | |
| 194 frag->fragment = buf; | |
| 195 | |
| 196 /* Initialize reassembly bitmask if necessary */ | |
| 197 if (reassembly) | |
| 198 { | |
| 199 bitmask = (unsigned char *)OPENSSL_malloc(RSMBLY_BITMASK_SIZE(fr
ag_len)); | |
| 200 if (bitmask == NULL) | |
| 201 { | |
| 202 if (buf != NULL) OPENSSL_free(buf); | |
| 203 OPENSSL_free(frag); | |
| 204 return NULL; | |
| 205 } | |
| 206 memset(bitmask, 0, RSMBLY_BITMASK_SIZE(frag_len)); | |
| 207 } | |
| 208 | |
| 209 frag->reassembly = bitmask; | |
| 210 | |
| 211 return frag; | |
| 212 } | |
| 213 | |
| 214 static void | |
| 215 dtls1_hm_fragment_free(hm_fragment *frag) | |
| 216 { | |
| 217 if (frag->fragment) OPENSSL_free(frag->fragment); | |
| 218 if (frag->reassembly) OPENSSL_free(frag->reassembly); | |
| 219 OPENSSL_free(frag); | |
| 220 } | |
| 221 | |
| 222 /* send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or SSL3_RT_CHAN
GE_CIPHER_SPEC) */ | |
| 223 int dtls1_do_write(SSL *s, int type) | |
| 224 { | |
| 225 int ret; | |
| 226 int curr_mtu; | |
| 227 unsigned int len, frag_off, mac_size, blocksize; | |
| 228 | |
| 229 /* AHA! Figure out the MTU, and stick to the right size */ | |
| 230 if (s->d1->mtu < dtls1_min_mtu() && !(SSL_get_options(s) & SSL_OP_NO_QUE
RY_MTU)) | |
| 231 { | |
| 232 s->d1->mtu = | |
| 233 BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, N
ULL); | |
| 234 | |
| 235 /* I've seen the kernel return bogus numbers when it doesn't kno
w | |
| 236 * (initial write), so just make sure we have a reasonable numbe
r */ | |
| 237 if (s->d1->mtu < dtls1_min_mtu()) | |
| 238 { | |
| 239 s->d1->mtu = 0; | |
| 240 s->d1->mtu = dtls1_guess_mtu(s->d1->mtu); | |
| 241 BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU, | |
| 242 s->d1->mtu, NULL); | |
| 243 } | |
| 244 } | |
| 245 #if 0 | |
| 246 mtu = s->d1->mtu; | |
| 247 | |
| 248 fprintf(stderr, "using MTU = %d\n", mtu); | |
| 249 | |
| 250 mtu -= (DTLS1_HM_HEADER_LENGTH + DTLS1_RT_HEADER_LENGTH); | |
| 251 | |
| 252 curr_mtu = mtu - BIO_wpending(SSL_get_wbio(s)); | |
| 253 | |
| 254 if ( curr_mtu > 0) | |
| 255 mtu = curr_mtu; | |
| 256 else if ( ( ret = BIO_flush(SSL_get_wbio(s))) <= 0) | |
| 257 return ret; | |
| 258 | |
| 259 if ( BIO_wpending(SSL_get_wbio(s)) + s->init_num >= mtu) | |
| 260 { | |
| 261 ret = BIO_flush(SSL_get_wbio(s)); | |
| 262 if ( ret <= 0) | |
| 263 return ret; | |
| 264 mtu = s->d1->mtu - (DTLS1_HM_HEADER_LENGTH + DTLS1_RT_HEADER_LEN
GTH); | |
| 265 } | |
| 266 #endif | |
| 267 | |
| 268 OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu()); /* should have something
reasonable now */ | |
| 269 | |
| 270 if ( s->init_off == 0 && type == SSL3_RT_HANDSHAKE) | |
| 271 OPENSSL_assert(s->init_num == | |
| 272 (int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH); | |
| 273 | |
| 274 if (s->write_hash) | |
| 275 mac_size = EVP_MD_CTX_size(s->write_hash); | |
| 276 else | |
| 277 mac_size = 0; | |
| 278 | |
| 279 if (s->enc_write_ctx && | |
| 280 (EVP_CIPHER_mode( s->enc_write_ctx->cipher) & EVP_CIPH_CBC_MODE)
) | |
| 281 blocksize = 2 * EVP_CIPHER_block_size(s->enc_write_ctx->cipher); | |
| 282 else | |
| 283 blocksize = 0; | |
| 284 | |
| 285 frag_off = 0; | |
| 286 while( s->init_num) | |
| 287 { | |
| 288 curr_mtu = s->d1->mtu - BIO_wpending(SSL_get_wbio(s)) - | |
| 289 DTLS1_RT_HEADER_LENGTH - mac_size - blocksize; | |
| 290 | |
| 291 if ( curr_mtu <= DTLS1_HM_HEADER_LENGTH) | |
| 292 { | |
| 293 /* grr.. we could get an error if MTU picked was wrong *
/ | |
| 294 ret = BIO_flush(SSL_get_wbio(s)); | |
| 295 if ( ret <= 0) | |
| 296 return ret; | |
| 297 curr_mtu = s->d1->mtu - DTLS1_RT_HEADER_LENGTH - | |
| 298 mac_size - blocksize; | |
| 299 } | |
| 300 | |
| 301 if ( s->init_num > curr_mtu) | |
| 302 len = curr_mtu; | |
| 303 else | |
| 304 len = s->init_num; | |
| 305 | |
| 306 | |
| 307 /* XDTLS: this function is too long. split out the CCS part */ | |
| 308 if ( type == SSL3_RT_HANDSHAKE) | |
| 309 { | |
| 310 if ( s->init_off != 0) | |
| 311 { | |
| 312 OPENSSL_assert(s->init_off > DTLS1_HM_HEADER_LEN
GTH); | |
| 313 s->init_off -= DTLS1_HM_HEADER_LENGTH; | |
| 314 s->init_num += DTLS1_HM_HEADER_LENGTH; | |
| 315 | |
| 316 /* write atleast DTLS1_HM_HEADER_LENGTH bytes */ | |
| 317 if ( len <= DTLS1_HM_HEADER_LENGTH) | |
| 318 len += DTLS1_HM_HEADER_LENGTH; | |
| 319 } | |
| 320 | |
| 321 dtls1_fix_message_header(s, frag_off, | |
| 322 len - DTLS1_HM_HEADER_LENGTH); | |
| 323 | |
| 324 dtls1_write_message_header(s, (unsigned char *)&s->init_
buf->data[s->init_off]); | |
| 325 | |
| 326 OPENSSL_assert(len >= DTLS1_HM_HEADER_LENGTH); | |
| 327 } | |
| 328 | |
| 329 ret=dtls1_write_bytes(s,type,&s->init_buf->data[s->init_off], | |
| 330 len); | |
| 331 if (ret < 0) | |
| 332 { | |
| 333 /* might need to update MTU here, but we don't know | |
| 334 * which previous packet caused the failure -- so can't | |
| 335 * really retransmit anything. continue as if everythin
g | |
| 336 * is fine and wait for an alert to handle the | |
| 337 * retransmit | |
| 338 */ | |
| 339 if ( BIO_ctrl(SSL_get_wbio(s), | |
| 340 BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL) > 0 ) | |
| 341 s->d1->mtu = BIO_ctrl(SSL_get_wbio(s), | |
| 342 BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); | |
| 343 else | |
| 344 return(-1); | |
| 345 } | |
| 346 else | |
| 347 { | |
| 348 | |
| 349 /* bad if this assert fails, only part of the handshake | |
| 350 * message got sent. but why would this happen? */ | |
| 351 OPENSSL_assert(len == (unsigned int)ret); | |
| 352 | |
| 353 if (type == SSL3_RT_HANDSHAKE && ! s->d1->retransmitting
) | |
| 354 { | |
| 355 /* should not be done for 'Hello Request's, but
in that case | |
| 356 * we'll ignore the result anyway */ | |
| 357 unsigned char *p = (unsigned char *)&s->init_buf
->data[s->init_off]; | |
| 358 const struct hm_header_st *msg_hdr = &s->d1->w_m
sg_hdr; | |
| 359 int xlen; | |
| 360 | |
| 361 if (frag_off == 0 && s->version != DTLS1_BAD_VER
) | |
| 362 { | |
| 363 /* reconstruct message header is if it | |
| 364 * is being sent in single fragment */ | |
| 365 *p++ = msg_hdr->type; | |
| 366 l2n3(msg_hdr->msg_len,p); | |
| 367 s2n (msg_hdr->seq,p); | |
| 368 l2n3(0,p); | |
| 369 l2n3(msg_hdr->msg_len,p); | |
| 370 p -= DTLS1_HM_HEADER_LENGTH; | |
| 371 xlen = ret; | |
| 372 } | |
| 373 else | |
| 374 { | |
| 375 p += DTLS1_HM_HEADER_LENGTH; | |
| 376 xlen = ret - DTLS1_HM_HEADER_LENGTH; | |
| 377 } | |
| 378 | |
| 379 ssl3_finish_mac(s, p, xlen); | |
| 380 } | |
| 381 | |
| 382 if (ret == s->init_num) | |
| 383 { | |
| 384 if (s->msg_callback) | |
| 385 s->msg_callback(1, s->version, type, s->
init_buf->data, | |
| 386 (size_t)(s->init_off + s->init_n
um), s, | |
| 387 s->msg_callback_arg); | |
| 388 | |
| 389 s->init_off = 0; /* done writing this message *
/ | |
| 390 s->init_num = 0; | |
| 391 | |
| 392 return(1); | |
| 393 } | |
| 394 s->init_off+=ret; | |
| 395 s->init_num-=ret; | |
| 396 frag_off += (ret -= DTLS1_HM_HEADER_LENGTH); | |
| 397 } | |
| 398 } | |
| 399 return(0); | |
| 400 } | |
| 401 | |
| 402 | |
| 403 /* Obtain handshake message of message type 'mt' (any if mt == -1), | |
| 404 * maximum acceptable body length 'max'. | |
| 405 * Read an entire handshake message. Handshake messages arrive in | |
| 406 * fragments. | |
| 407 */ | |
| 408 long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) | |
| 409 { | |
| 410 int i, al; | |
| 411 struct hm_header_st *msg_hdr; | |
| 412 unsigned char *p; | |
| 413 unsigned long msg_len; | |
| 414 | |
| 415 /* s3->tmp is used to store messages that are unexpected, caused | |
| 416 * by the absence of an optional handshake message */ | |
| 417 if (s->s3->tmp.reuse_message) | |
| 418 { | |
| 419 s->s3->tmp.reuse_message=0; | |
| 420 if ((mt >= 0) && (s->s3->tmp.message_type != mt)) | |
| 421 { | |
| 422 al=SSL_AD_UNEXPECTED_MESSAGE; | |
| 423 SSLerr(SSL_F_DTLS1_GET_MESSAGE,SSL_R_UNEXPECTED_MESSAGE)
; | |
| 424 goto f_err; | |
| 425 } | |
| 426 *ok=1; | |
| 427 s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; | |
| 428 s->init_num = (int)s->s3->tmp.message_size; | |
| 429 return s->init_num; | |
| 430 } | |
| 431 | |
| 432 msg_hdr = &s->d1->r_msg_hdr; | |
| 433 memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); | |
| 434 | |
| 435 again: | |
| 436 i = dtls1_get_message_fragment(s, st1, stn, max, ok); | |
| 437 if ( i == DTLS1_HM_BAD_FRAGMENT || | |
| 438 i == DTLS1_HM_FRAGMENT_RETRY) /* bad fragment received */ | |
| 439 goto again; | |
| 440 else if ( i <= 0 && !*ok) | |
| 441 return i; | |
| 442 | |
| 443 p = (unsigned char *)s->init_buf->data; | |
| 444 msg_len = msg_hdr->msg_len; | |
| 445 | |
| 446 /* reconstruct message header */ | |
| 447 *(p++) = msg_hdr->type; | |
| 448 l2n3(msg_len,p); | |
| 449 s2n (msg_hdr->seq,p); | |
| 450 l2n3(0,p); | |
| 451 l2n3(msg_len,p); | |
| 452 if (s->version != DTLS1_BAD_VER) { | |
| 453 p -= DTLS1_HM_HEADER_LENGTH; | |
| 454 msg_len += DTLS1_HM_HEADER_LENGTH; | |
| 455 } | |
| 456 | |
| 457 ssl3_finish_mac(s, p, msg_len); | |
| 458 if (s->msg_callback) | |
| 459 s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, | |
| 460 p, msg_len, | |
| 461 s, s->msg_callback_arg); | |
| 462 | |
| 463 memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); | |
| 464 | |
| 465 /* Don't change sequence numbers while listening */ | |
| 466 if (!s->d1->listen) | |
| 467 s->d1->handshake_read_seq++; | |
| 468 | |
| 469 s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; | |
| 470 return s->init_num; | |
| 471 | |
| 472 f_err: | |
| 473 ssl3_send_alert(s,SSL3_AL_FATAL,al); | |
| 474 *ok = 0; | |
| 475 return -1; | |
| 476 } | |
| 477 | |
| 478 | |
| 479 static int dtls1_preprocess_fragment(SSL *s,struct hm_header_st *msg_hdr,int max
) | |
| 480 { | |
| 481 size_t frag_off,frag_len,msg_len; | |
| 482 | |
| 483 msg_len = msg_hdr->msg_len; | |
| 484 frag_off = msg_hdr->frag_off; | |
| 485 frag_len = msg_hdr->frag_len; | |
| 486 | |
| 487 /* sanity checking */ | |
| 488 if ( (frag_off+frag_len) > msg_len) | |
| 489 { | |
| 490 SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_S
IZE); | |
| 491 return SSL_AD_ILLEGAL_PARAMETER; | |
| 492 } | |
| 493 | |
| 494 if ( (frag_off+frag_len) > (unsigned long)max) | |
| 495 { | |
| 496 SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_S
IZE); | |
| 497 return SSL_AD_ILLEGAL_PARAMETER; | |
| 498 } | |
| 499 | |
| 500 if ( s->d1->r_msg_hdr.frag_off == 0) /* first fragment */ | |
| 501 { | |
| 502 /* msg_len is limited to 2^24, but is effectively checked | |
| 503 * against max above */ | |
| 504 if (!BUF_MEM_grow_clean(s->init_buf,msg_len+DTLS1_HM_HEADER_LENG
TH)) | |
| 505 { | |
| 506 SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,ERR_R_BUF_LIB); | |
| 507 return SSL_AD_INTERNAL_ERROR; | |
| 508 } | |
| 509 | |
| 510 s->s3->tmp.message_size = msg_len; | |
| 511 s->d1->r_msg_hdr.msg_len = msg_len; | |
| 512 s->s3->tmp.message_type = msg_hdr->type; | |
| 513 s->d1->r_msg_hdr.type = msg_hdr->type; | |
| 514 s->d1->r_msg_hdr.seq = msg_hdr->seq; | |
| 515 } | |
| 516 else if (msg_len != s->d1->r_msg_hdr.msg_len) | |
| 517 { | |
| 518 /* They must be playing with us! BTW, failure to enforce | |
| 519 * upper limit would open possibility for buffer overrun. */ | |
| 520 SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_S
IZE); | |
| 521 return SSL_AD_ILLEGAL_PARAMETER; | |
| 522 } | |
| 523 | |
| 524 return 0; /* no error */ | |
| 525 } | |
| 526 | |
| 527 | |
| 528 static int | |
| 529 dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok) | |
| 530 { | |
| 531 /* (0) check whether the desired fragment is available | |
| 532 * if so: | |
| 533 * (1) copy over the fragment to s->init_buf->data[] | |
| 534 * (2) update s->init_num | |
| 535 */ | |
| 536 pitem *item; | |
| 537 hm_fragment *frag; | |
| 538 int al; | |
| 539 | |
| 540 *ok = 0; | |
| 541 item = pqueue_peek(s->d1->buffered_messages); | |
| 542 if ( item == NULL) | |
| 543 return 0; | |
| 544 | |
| 545 frag = (hm_fragment *)item->data; | |
| 546 | |
| 547 /* Don't return if reassembly still in progress */ | |
| 548 if (frag->reassembly != NULL) | |
| 549 return 0; | |
| 550 | |
| 551 if ( s->d1->handshake_read_seq == frag->msg_header.seq) | |
| 552 { | |
| 553 unsigned long frag_len = frag->msg_header.frag_len; | |
| 554 pqueue_pop(s->d1->buffered_messages); | |
| 555 | |
| 556 al=dtls1_preprocess_fragment(s,&frag->msg_header,max); | |
| 557 | |
| 558 if (al==0) /* no alert */ | |
| 559 { | |
| 560 unsigned char *p = (unsigned char *)s->init_buf->data+DT
LS1_HM_HEADER_LENGTH; | |
| 561 memcpy(&p[frag->msg_header.frag_off], | |
| 562 frag->fragment,frag->msg_header.frag_len); | |
| 563 } | |
| 564 | |
| 565 dtls1_hm_fragment_free(frag); | |
| 566 pitem_free(item); | |
| 567 | |
| 568 if (al==0) | |
| 569 { | |
| 570 *ok = 1; | |
| 571 return frag_len; | |
| 572 } | |
| 573 | |
| 574 ssl3_send_alert(s,SSL3_AL_FATAL,al); | |
| 575 s->init_num = 0; | |
| 576 *ok = 0; | |
| 577 return -1; | |
| 578 } | |
| 579 else | |
| 580 return 0; | |
| 581 } | |
| 582 | |
| 583 | |
| 584 static int | |
| 585 dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok) | |
| 586 { | |
| 587 hm_fragment *frag = NULL; | |
| 588 pitem *item = NULL; | |
| 589 int i = -1, is_complete; | |
| 590 unsigned char seq64be[8]; | |
| 591 unsigned long frag_len = msg_hdr->frag_len, max_len; | |
| 592 | |
| 593 if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len) | |
| 594 goto err; | |
| 595 | |
| 596 /* Determine maximum allowed message size. Depends on (user set) | |
| 597 * maximum certificate length, but 16k is minimum. | |
| 598 */ | |
| 599 if (DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH < s->max_cert_
list) | |
| 600 max_len = s->max_cert_list; | |
| 601 else | |
| 602 max_len = DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH; | |
| 603 | |
| 604 if ((msg_hdr->frag_off+frag_len) > max_len) | |
| 605 goto err; | |
| 606 | |
| 607 /* Try to find item in queue */ | |
| 608 memset(seq64be,0,sizeof(seq64be)); | |
| 609 seq64be[6] = (unsigned char) (msg_hdr->seq>>8); | |
| 610 seq64be[7] = (unsigned char) msg_hdr->seq; | |
| 611 item = pqueue_find(s->d1->buffered_messages, seq64be); | |
| 612 | |
| 613 if (item == NULL) | |
| 614 { | |
| 615 frag = dtls1_hm_fragment_new(msg_hdr->msg_len, 1); | |
| 616 if ( frag == NULL) | |
| 617 goto err; | |
| 618 memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); | |
| 619 frag->msg_header.frag_len = frag->msg_header.msg_len; | |
| 620 frag->msg_header.frag_off = 0; | |
| 621 } | |
| 622 else | |
| 623 { | |
| 624 frag = (hm_fragment*) item->data; | |
| 625 if (frag->msg_header.msg_len != msg_hdr->msg_len) | |
| 626 { | |
| 627 item = NULL; | |
| 628 frag = NULL; | |
| 629 goto err; | |
| 630 } | |
| 631 } | |
| 632 | |
| 633 | |
| 634 /* If message is already reassembled, this must be a | |
| 635 * retransmit and can be dropped. | |
| 636 */ | |
| 637 if (frag->reassembly == NULL) | |
| 638 { | |
| 639 unsigned char devnull [256]; | |
| 640 | |
| 641 while (frag_len) | |
| 642 { | |
| 643 i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, | |
| 644 devnull, | |
| 645 frag_len>sizeof(devnull)?sizeof(devnull):frag_le
n,0); | |
| 646 if (i<=0) goto err; | |
| 647 frag_len -= i; | |
| 648 } | |
| 649 return DTLS1_HM_FRAGMENT_RETRY; | |
| 650 } | |
| 651 | |
| 652 /* read the body of the fragment (header has already been read */ | |
| 653 i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, | |
| 654 frag->fragment + msg_hdr->frag_off,frag_len,0); | |
| 655 if (i<=0 || (unsigned long)i!=frag_len) | |
| 656 goto err; | |
| 657 | |
| 658 RSMBLY_BITMASK_MARK(frag->reassembly, (long)msg_hdr->frag_off, | |
| 659 (long)(msg_hdr->frag_off + frag_len)); | |
| 660 | |
| 661 RSMBLY_BITMASK_IS_COMPLETE(frag->reassembly, (long)msg_hdr->msg_len, | |
| 662 is_complete); | |
| 663 | |
| 664 if (is_complete) | |
| 665 { | |
| 666 OPENSSL_free(frag->reassembly); | |
| 667 frag->reassembly = NULL; | |
| 668 } | |
| 669 | |
| 670 if (item == NULL) | |
| 671 { | |
| 672 memset(seq64be,0,sizeof(seq64be)); | |
| 673 seq64be[6] = (unsigned char)(msg_hdr->seq>>8); | |
| 674 seq64be[7] = (unsigned char)(msg_hdr->seq); | |
| 675 | |
| 676 item = pitem_new(seq64be, frag); | |
| 677 if (item == NULL) | |
| 678 { | |
| 679 goto err; | |
| 680 i = -1; | |
| 681 } | |
| 682 | |
| 683 pqueue_insert(s->d1->buffered_messages, item); | |
| 684 } | |
| 685 | |
| 686 return DTLS1_HM_FRAGMENT_RETRY; | |
| 687 | |
| 688 err: | |
| 689 if (frag != NULL) dtls1_hm_fragment_free(frag); | |
| 690 if (item != NULL) OPENSSL_free(item); | |
| 691 *ok = 0; | |
| 692 return i; | |
| 693 } | |
| 694 | |
| 695 | |
| 696 static int | |
| 697 dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok) | |
| 698 { | |
| 699 int i=-1; | |
| 700 hm_fragment *frag = NULL; | |
| 701 pitem *item = NULL; | |
| 702 unsigned char seq64be[8]; | |
| 703 unsigned long frag_len = msg_hdr->frag_len; | |
| 704 | |
| 705 if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len) | |
| 706 goto err; | |
| 707 | |
| 708 /* Try to find item in queue, to prevent duplicate entries */ | |
| 709 memset(seq64be,0,sizeof(seq64be)); | |
| 710 seq64be[6] = (unsigned char) (msg_hdr->seq>>8); | |
| 711 seq64be[7] = (unsigned char) msg_hdr->seq; | |
| 712 item = pqueue_find(s->d1->buffered_messages, seq64be); | |
| 713 | |
| 714 /* If we already have an entry and this one is a fragment, | |
| 715 * don't discard it and rather try to reassemble it. | |
| 716 */ | |
| 717 if (item != NULL && frag_len < msg_hdr->msg_len) | |
| 718 item = NULL; | |
| 719 | |
| 720 /* Discard the message if sequence number was already there, is | |
| 721 * too far in the future, already in the queue or if we received | |
| 722 * a FINISHED before the SERVER_HELLO, which then must be a stale | |
| 723 * retransmit. | |
| 724 */ | |
| 725 if (msg_hdr->seq <= s->d1->handshake_read_seq || | |
| 726 msg_hdr->seq > s->d1->handshake_read_seq + 10 || item != NULL || | |
| 727 (s->d1->handshake_read_seq == 0 && msg_hdr->type == SSL3_MT_FINI
SHED)) | |
| 728 { | |
| 729 unsigned char devnull [256]; | |
| 730 | |
| 731 while (frag_len) | |
| 732 { | |
| 733 i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, | |
| 734 devnull, | |
| 735 frag_len>sizeof(devnull)?sizeof(devnull):frag_le
n,0); | |
| 736 if (i<=0) goto err; | |
| 737 frag_len -= i; | |
| 738 } | |
| 739 } | |
| 740 else | |
| 741 { | |
| 742 if (frag_len && frag_len < msg_hdr->msg_len) | |
| 743 return dtls1_reassemble_fragment(s, msg_hdr, ok); | |
| 744 | |
| 745 frag = dtls1_hm_fragment_new(frag_len, 0); | |
| 746 if ( frag == NULL) | |
| 747 goto err; | |
| 748 | |
| 749 memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); | |
| 750 | |
| 751 if (frag_len) | |
| 752 { | |
| 753 /* read the body of the fragment (header has already bee
n read */ | |
| 754 i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, | |
| 755 frag->fragment,frag_len,0); | |
| 756 if (i<=0 || (unsigned long)i!=frag_len) | |
| 757 goto err; | |
| 758 } | |
| 759 | |
| 760 memset(seq64be,0,sizeof(seq64be)); | |
| 761 seq64be[6] = (unsigned char)(msg_hdr->seq>>8); | |
| 762 seq64be[7] = (unsigned char)(msg_hdr->seq); | |
| 763 | |
| 764 item = pitem_new(seq64be, frag); | |
| 765 if ( item == NULL) | |
| 766 goto err; | |
| 767 | |
| 768 pqueue_insert(s->d1->buffered_messages, item); | |
| 769 } | |
| 770 | |
| 771 return DTLS1_HM_FRAGMENT_RETRY; | |
| 772 | |
| 773 err: | |
| 774 if ( frag != NULL) dtls1_hm_fragment_free(frag); | |
| 775 if ( item != NULL) OPENSSL_free(item); | |
| 776 *ok = 0; | |
| 777 return i; | |
| 778 } | |
| 779 | |
| 780 | |
| 781 static long | |
| 782 dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok) | |
| 783 { | |
| 784 unsigned char wire[DTLS1_HM_HEADER_LENGTH]; | |
| 785 unsigned long len, frag_off, frag_len; | |
| 786 int i,al; | |
| 787 struct hm_header_st msg_hdr; | |
| 788 | |
| 789 redo: | |
| 790 /* see if we have the required fragment already */ | |
| 791 if ((frag_len = dtls1_retrieve_buffered_fragment(s,max,ok)) || *ok) | |
| 792 { | |
| 793 if (*ok) s->init_num = frag_len; | |
| 794 return frag_len; | |
| 795 } | |
| 796 | |
| 797 /* read handshake message header */ | |
| 798 i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,wire, | |
| 799 DTLS1_HM_HEADER_LENGTH, 0); | |
| 800 if (i <= 0) /* nbio, or an error */ | |
| 801 { | |
| 802 s->rwstate=SSL_READING; | |
| 803 *ok = 0; | |
| 804 return i; | |
| 805 } | |
| 806 /* Handshake fails if message header is incomplete */ | |
| 807 if (i != DTLS1_HM_HEADER_LENGTH) | |
| 808 { | |
| 809 al=SSL_AD_UNEXPECTED_MESSAGE; | |
| 810 SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_UNEXPECTED_MESSAGE
); | |
| 811 goto f_err; | |
| 812 } | |
| 813 | |
| 814 /* parse the message fragment header */ | |
| 815 dtls1_get_message_header(wire, &msg_hdr); | |
| 816 | |
| 817 /* | |
| 818 * if this is a future (or stale) message it gets buffered | |
| 819 * (or dropped)--no further processing at this time | |
| 820 * While listening, we accept seq 1 (ClientHello with cookie) | |
| 821 * although we're still expecting seq 0 (ClientHello) | |
| 822 */ | |
| 823 if (msg_hdr.seq != s->d1->handshake_read_seq && !(s->d1->listen && msg_h
dr.seq == 1)) | |
| 824 return dtls1_process_out_of_seq_message(s, &msg_hdr, ok); | |
| 825 | |
| 826 len = msg_hdr.msg_len; | |
| 827 frag_off = msg_hdr.frag_off; | |
| 828 frag_len = msg_hdr.frag_len; | |
| 829 | |
| 830 if (frag_len && frag_len < len) | |
| 831 return dtls1_reassemble_fragment(s, &msg_hdr, ok); | |
| 832 | |
| 833 if (!s->server && s->d1->r_msg_hdr.frag_off == 0 && | |
| 834 wire[0] == SSL3_MT_HELLO_REQUEST) | |
| 835 { | |
| 836 /* The server may always send 'Hello Request' messages -- | |
| 837 * we are doing a handshake anyway now, so ignore them | |
| 838 * if their format is correct. Does not count for | |
| 839 * 'Finished' MAC. */ | |
| 840 if (wire[1] == 0 && wire[2] == 0 && wire[3] == 0) | |
| 841 { | |
| 842 if (s->msg_callback) | |
| 843 s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE
, | |
| 844 wire, DTLS1_HM_HEADER_LENGTH, s, | |
| 845 s->msg_callback_arg); | |
| 846 | |
| 847 s->init_num = 0; | |
| 848 goto redo; | |
| 849 } | |
| 850 else /* Incorrectly formated Hello request */ | |
| 851 { | |
| 852 al=SSL_AD_UNEXPECTED_MESSAGE; | |
| 853 SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_UNEXPECTED
_MESSAGE); | |
| 854 goto f_err; | |
| 855 } | |
| 856 } | |
| 857 | |
| 858 if ((al=dtls1_preprocess_fragment(s,&msg_hdr,max))) | |
| 859 goto f_err; | |
| 860 | |
| 861 /* XDTLS: ressurect this when restart is in place */ | |
| 862 s->state=stn; | |
| 863 | |
| 864 if ( frag_len > 0) | |
| 865 { | |
| 866 unsigned char *p=(unsigned char *)s->init_buf->data+DTLS1_HM_HEA
DER_LENGTH; | |
| 867 | |
| 868 i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, | |
| 869 &p[frag_off],frag_len,0); | |
| 870 /* XDTLS: fix this--message fragments cannot span multiple pack
ets */ | |
| 871 if (i <= 0) | |
| 872 { | |
| 873 s->rwstate=SSL_READING; | |
| 874 *ok = 0; | |
| 875 return i; | |
| 876 } | |
| 877 } | |
| 878 else | |
| 879 i = 0; | |
| 880 | |
| 881 /* XDTLS: an incorrectly formatted fragment should cause the | |
| 882 * handshake to fail */ | |
| 883 if (i != (int)frag_len) | |
| 884 { | |
| 885 al=SSL3_AD_ILLEGAL_PARAMETER; | |
| 886 SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL3_AD_ILLEGAL_PARAMETE
R); | |
| 887 goto f_err; | |
| 888 } | |
| 889 | |
| 890 *ok = 1; | |
| 891 | |
| 892 /* Note that s->init_num is *not* used as current offset in | |
| 893 * s->init_buf->data, but as a counter summing up fragments' | |
| 894 * lengths: as soon as they sum up to handshake packet | |
| 895 * length, we assume we have got all the fragments. */ | |
| 896 s->init_num = frag_len; | |
| 897 return frag_len; | |
| 898 | |
| 899 f_err: | |
| 900 ssl3_send_alert(s,SSL3_AL_FATAL,al); | |
| 901 s->init_num = 0; | |
| 902 | |
| 903 *ok=0; | |
| 904 return(-1); | |
| 905 } | |
| 906 | |
| 907 int dtls1_send_finished(SSL *s, int a, int b, const char *sender, int slen) | |
| 908 { | |
| 909 unsigned char *p,*d; | |
| 910 int i; | |
| 911 unsigned long l; | |
| 912 | |
| 913 if (s->state == a) | |
| 914 { | |
| 915 d=(unsigned char *)s->init_buf->data; | |
| 916 p= &(d[DTLS1_HM_HEADER_LENGTH]); | |
| 917 | |
| 918 i=s->method->ssl3_enc->final_finish_mac(s, | |
| 919 sender,slen,s->s3->tmp.finish_md); | |
| 920 s->s3->tmp.finish_md_len = i; | |
| 921 memcpy(p, s->s3->tmp.finish_md, i); | |
| 922 p+=i; | |
| 923 l=i; | |
| 924 | |
| 925 /* Copy the finished so we can use it for | |
| 926 * renegotiation checks | |
| 927 */ | |
| 928 if(s->type == SSL_ST_CONNECT) | |
| 929 { | |
| 930 OPENSSL_assert(i <= EVP_MAX_MD_SIZE); | |
| 931 memcpy(s->s3->previous_client_finished, | |
| 932 s->s3->tmp.finish_md, i); | |
| 933 s->s3->previous_client_finished_len=i; | |
| 934 } | |
| 935 else | |
| 936 { | |
| 937 OPENSSL_assert(i <= EVP_MAX_MD_SIZE); | |
| 938 memcpy(s->s3->previous_server_finished, | |
| 939 s->s3->tmp.finish_md, i); | |
| 940 s->s3->previous_server_finished_len=i; | |
| 941 } | |
| 942 | |
| 943 #ifdef OPENSSL_SYS_WIN16 | |
| 944 /* MSVC 1.5 does not clear the top bytes of the word unless | |
| 945 * I do this. | |
| 946 */ | |
| 947 l&=0xffff; | |
| 948 #endif | |
| 949 | |
| 950 d = dtls1_set_message_header(s, d, SSL3_MT_FINISHED, l, 0, l); | |
| 951 s->init_num=(int)l+DTLS1_HM_HEADER_LENGTH; | |
| 952 s->init_off=0; | |
| 953 | |
| 954 /* buffer the message to handle re-xmits */ | |
| 955 dtls1_buffer_message(s, 0); | |
| 956 | |
| 957 s->state=b; | |
| 958 } | |
| 959 | |
| 960 /* SSL3_ST_SEND_xxxxxx_HELLO_B */ | |
| 961 return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); | |
| 962 } | |
| 963 | |
| 964 /* for these 2 messages, we need to | |
| 965 * ssl->enc_read_ctx re-init | |
| 966 * ssl->s3->read_sequence zero | |
| 967 * ssl->s3->read_mac_secret re-init | |
| 968 * ssl->session->read_sym_enc assign | |
| 969 * ssl->session->read_compression assign | |
| 970 * ssl->session->read_hash assign | |
| 971 */ | |
| 972 int dtls1_send_change_cipher_spec(SSL *s, int a, int b) | |
| 973 { | |
| 974 unsigned char *p; | |
| 975 | |
| 976 if (s->state == a) | |
| 977 { | |
| 978 p=(unsigned char *)s->init_buf->data; | |
| 979 *p++=SSL3_MT_CCS; | |
| 980 s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; | |
| 981 s->init_num=DTLS1_CCS_HEADER_LENGTH; | |
| 982 | |
| 983 if (s->version == DTLS1_BAD_VER) { | |
| 984 s->d1->next_handshake_write_seq++; | |
| 985 s2n(s->d1->handshake_write_seq,p); | |
| 986 s->init_num+=2; | |
| 987 } | |
| 988 | |
| 989 s->init_off=0; | |
| 990 | |
| 991 dtls1_set_message_header_int(s, SSL3_MT_CCS, 0, | |
| 992 s->d1->handshake_write_seq, 0, 0); | |
| 993 | |
| 994 /* buffer the message to handle re-xmits */ | |
| 995 dtls1_buffer_message(s, 1); | |
| 996 | |
| 997 s->state=b; | |
| 998 } | |
| 999 | |
| 1000 /* SSL3_ST_CW_CHANGE_B */ | |
| 1001 return(dtls1_do_write(s,SSL3_RT_CHANGE_CIPHER_SPEC)); | |
| 1002 } | |
| 1003 | |
| 1004 static int dtls1_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x) | |
| 1005 { | |
| 1006 int n; | |
| 1007 unsigned char *p; | |
| 1008 | |
| 1009 n=i2d_X509(x,NULL); | |
| 1010 if (!BUF_MEM_grow_clean(buf,(int)(n+(*l)+3))) | |
| 1011 { | |
| 1012 SSLerr(SSL_F_DTLS1_ADD_CERT_TO_BUF,ERR_R_BUF_LIB); | |
| 1013 return 0; | |
| 1014 } | |
| 1015 p=(unsigned char *)&(buf->data[*l]); | |
| 1016 l2n3(n,p); | |
| 1017 i2d_X509(x,&p); | |
| 1018 *l+=n+3; | |
| 1019 | |
| 1020 return 1; | |
| 1021 } | |
| 1022 unsigned long dtls1_output_cert_chain(SSL *s, X509 *x) | |
| 1023 { | |
| 1024 unsigned char *p; | |
| 1025 int i; | |
| 1026 unsigned long l= 3 + DTLS1_HM_HEADER_LENGTH; | |
| 1027 BUF_MEM *buf; | |
| 1028 | |
| 1029 /* TLSv1 sends a chain with nothing in it, instead of an alert */ | |
| 1030 buf=s->init_buf; | |
| 1031 if (!BUF_MEM_grow_clean(buf,10)) | |
| 1032 { | |
| 1033 SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB); | |
| 1034 return(0); | |
| 1035 } | |
| 1036 if (x != NULL) | |
| 1037 { | |
| 1038 X509_STORE_CTX xs_ctx; | |
| 1039 | |
| 1040 if (!X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,x,NULL)) | |
| 1041 { | |
| 1042 SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_X509_LIB); | |
| 1043 return(0); | |
| 1044 } | |
| 1045 | |
| 1046 X509_verify_cert(&xs_ctx); | |
| 1047 /* Don't leave errors in the queue */ | |
| 1048 ERR_clear_error(); | |
| 1049 for (i=0; i < sk_X509_num(xs_ctx.chain); i++) | |
| 1050 { | |
| 1051 x = sk_X509_value(xs_ctx.chain, i); | |
| 1052 | |
| 1053 if (!dtls1_add_cert_to_buf(buf, &l, x)) | |
| 1054 { | |
| 1055 X509_STORE_CTX_cleanup(&xs_ctx); | |
| 1056 return 0; | |
| 1057 } | |
| 1058 } | |
| 1059 X509_STORE_CTX_cleanup(&xs_ctx); | |
| 1060 } | |
| 1061 /* Thawte special :-) */ | |
| 1062 for (i=0; i<sk_X509_num(s->ctx->extra_certs); i++) | |
| 1063 { | |
| 1064 x=sk_X509_value(s->ctx->extra_certs,i); | |
| 1065 if (!dtls1_add_cert_to_buf(buf, &l, x)) | |
| 1066 return 0; | |
| 1067 } | |
| 1068 | |
| 1069 l-= (3 + DTLS1_HM_HEADER_LENGTH); | |
| 1070 | |
| 1071 p=(unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH]); | |
| 1072 l2n3(l,p); | |
| 1073 l+=3; | |
| 1074 p=(unsigned char *)&(buf->data[0]); | |
| 1075 p = dtls1_set_message_header(s, p, SSL3_MT_CERTIFICATE, l, 0, l); | |
| 1076 | |
| 1077 l+=DTLS1_HM_HEADER_LENGTH; | |
| 1078 return(l); | |
| 1079 } | |
| 1080 | |
| 1081 int dtls1_read_failed(SSL *s, int code) | |
| 1082 { | |
| 1083 if ( code > 0) | |
| 1084 { | |
| 1085 fprintf( stderr, "invalid state reached %s:%d", __FILE__, __LINE
__); | |
| 1086 return 1; | |
| 1087 } | |
| 1088 | |
| 1089 if (!dtls1_is_timer_expired(s)) | |
| 1090 { | |
| 1091 /* not a timeout, none of our business, | |
| 1092 let higher layers handle this. in fact it's probably an erro
r */ | |
| 1093 return code; | |
| 1094 } | |
| 1095 | |
| 1096 #ifndef OPENSSL_NO_HEARTBEATS | |
| 1097 if (!SSL_in_init(s) && !s->tlsext_hb_pending) /* done, no need to send
a retransmit */ | |
| 1098 #else | |
| 1099 if (!SSL_in_init(s)) /* done, no need to send a retransmit */ | |
| 1100 #endif | |
| 1101 { | |
| 1102 BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ); | |
| 1103 return code; | |
| 1104 } | |
| 1105 | |
| 1106 #if 0 /* for now, each alert contains only one record number */ | |
| 1107 item = pqueue_peek(state->rcvd_records); | |
| 1108 if ( item ) | |
| 1109 { | |
| 1110 /* send an alert immediately for all the missing records */ | |
| 1111 } | |
| 1112 else | |
| 1113 #endif | |
| 1114 | |
| 1115 #if 0 /* no more alert sending, just retransmit the last set of messages */ | |
| 1116 if ( state->timeout.read_timeouts >= DTLS1_TMO_READ_COUNT) | |
| 1117 ssl3_send_alert(s,SSL3_AL_WARNING, | |
| 1118 DTLS1_AD_MISSING_HANDSHAKE_MESSAGE); | |
| 1119 #endif | |
| 1120 | |
| 1121 return dtls1_handle_timeout(s); | |
| 1122 } | |
| 1123 | |
| 1124 int | |
| 1125 dtls1_get_queue_priority(unsigned short seq, int is_ccs) | |
| 1126 { | |
| 1127 /* The index of the retransmission queue actually is the message sequenc
e number, | |
| 1128 * since the queue only contains messages of a single handshake. However
, the | |
| 1129 * ChangeCipherSpec has no message sequence number and so using only the
sequence | |
| 1130 * will result in the CCS and Finished having the same index. To prevent
this, | |
| 1131 * the sequence number is multiplied by 2. In case of a CCS 1 is subtrac
ted. | |
| 1132 * This does not only differ CSS and Finished, it also maintains the ord
er of the | |
| 1133 * index (important for priority queues) and fits in the unsigned short
variable. | |
| 1134 */ | |
| 1135 return seq * 2 - is_ccs; | |
| 1136 } | |
| 1137 | |
| 1138 int | |
| 1139 dtls1_retransmit_buffered_messages(SSL *s) | |
| 1140 { | |
| 1141 pqueue sent = s->d1->sent_messages; | |
| 1142 piterator iter; | |
| 1143 pitem *item; | |
| 1144 hm_fragment *frag; | |
| 1145 int found = 0; | |
| 1146 | |
| 1147 iter = pqueue_iterator(sent); | |
| 1148 | |
| 1149 for ( item = pqueue_next(&iter); item != NULL; item = pqueue_next(&iter)
) | |
| 1150 { | |
| 1151 frag = (hm_fragment *)item->data; | |
| 1152 if ( dtls1_retransmit_message(s, | |
| 1153 (unsigned short)dtls1_get_queue_priority(frag->m
sg_header.seq, frag->msg_header.is_ccs), | |
| 1154 0, &found) <= 0 && found) | |
| 1155 { | |
| 1156 fprintf(stderr, "dtls1_retransmit_message() failed\n"); | |
| 1157 return -1; | |
| 1158 } | |
| 1159 } | |
| 1160 | |
| 1161 return 1; | |
| 1162 } | |
| 1163 | |
| 1164 int | |
| 1165 dtls1_buffer_message(SSL *s, int is_ccs) | |
| 1166 { | |
| 1167 pitem *item; | |
| 1168 hm_fragment *frag; | |
| 1169 unsigned char seq64be[8]; | |
| 1170 | |
| 1171 /* this function is called immediately after a message has | |
| 1172 * been serialized */ | |
| 1173 OPENSSL_assert(s->init_off == 0); | |
| 1174 | |
| 1175 frag = dtls1_hm_fragment_new(s->init_num, 0); | |
| 1176 | |
| 1177 memcpy(frag->fragment, s->init_buf->data, s->init_num); | |
| 1178 | |
| 1179 if ( is_ccs) | |
| 1180 { | |
| 1181 OPENSSL_assert(s->d1->w_msg_hdr.msg_len + | |
| 1182 ((s->version==DTLS1_VERSION)?DTLS1_CCS_HEADER_LEN
GTH:3) == (unsigned int)s->init_num); | |
| 1183 } | |
| 1184 else | |
| 1185 { | |
| 1186 OPENSSL_assert(s->d1->w_msg_hdr.msg_len + | |
| 1187 DTLS1_HM_HEADER_LENGTH == (unsigned int)s->init_num); | |
| 1188 } | |
| 1189 | |
| 1190 frag->msg_header.msg_len = s->d1->w_msg_hdr.msg_len; | |
| 1191 frag->msg_header.seq = s->d1->w_msg_hdr.seq; | |
| 1192 frag->msg_header.type = s->d1->w_msg_hdr.type; | |
| 1193 frag->msg_header.frag_off = 0; | |
| 1194 frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len; | |
| 1195 frag->msg_header.is_ccs = is_ccs; | |
| 1196 | |
| 1197 /* save current state*/ | |
| 1198 frag->msg_header.saved_retransmit_state.enc_write_ctx = s->enc_write_ctx
; | |
| 1199 frag->msg_header.saved_retransmit_state.write_hash = s->write_hash; | |
| 1200 frag->msg_header.saved_retransmit_state.compress = s->compress; | |
| 1201 frag->msg_header.saved_retransmit_state.session = s->session; | |
| 1202 frag->msg_header.saved_retransmit_state.epoch = s->d1->w_epoch; | |
| 1203 | |
| 1204 memset(seq64be,0,sizeof(seq64be)); | |
| 1205 seq64be[6] = (unsigned char)(dtls1_get_queue_priority(frag->msg_header.s
eq, | |
| 1206
frag->msg_header.is_ccs)>>8); | |
| 1207 seq64be[7] = (unsigned char)(dtls1_get_queue_priority(frag->msg_header.s
eq, | |
| 1208
frag->msg_header.is_ccs)); | |
| 1209 | |
| 1210 item = pitem_new(seq64be, frag); | |
| 1211 if ( item == NULL) | |
| 1212 { | |
| 1213 dtls1_hm_fragment_free(frag); | |
| 1214 return 0; | |
| 1215 } | |
| 1216 | |
| 1217 #if 0 | |
| 1218 fprintf( stderr, "buffered messge: \ttype = %xx\n", msg_buf->type); | |
| 1219 fprintf( stderr, "\t\t\t\t\tlen = %d\n", msg_buf->len); | |
| 1220 fprintf( stderr, "\t\t\t\t\tseq_num = %d\n", msg_buf->seq_num); | |
| 1221 #endif | |
| 1222 | |
| 1223 pqueue_insert(s->d1->sent_messages, item); | |
| 1224 return 1; | |
| 1225 } | |
| 1226 | |
| 1227 int | |
| 1228 dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off, | |
| 1229 int *found) | |
| 1230 { | |
| 1231 int ret; | |
| 1232 /* XDTLS: for now assuming that read/writes are blocking */ | |
| 1233 pitem *item; | |
| 1234 hm_fragment *frag ; | |
| 1235 unsigned long header_length; | |
| 1236 unsigned char seq64be[8]; | |
| 1237 struct dtls1_retransmit_state saved_state; | |
| 1238 unsigned char save_write_sequence[8]; | |
| 1239 | |
| 1240 /* | |
| 1241 OPENSSL_assert(s->init_num == 0); | |
| 1242 OPENSSL_assert(s->init_off == 0); | |
| 1243 */ | |
| 1244 | |
| 1245 /* XDTLS: the requested message ought to be found, otherwise error */ | |
| 1246 memset(seq64be,0,sizeof(seq64be)); | |
| 1247 seq64be[6] = (unsigned char)(seq>>8); | |
| 1248 seq64be[7] = (unsigned char)seq; | |
| 1249 | |
| 1250 item = pqueue_find(s->d1->sent_messages, seq64be); | |
| 1251 if ( item == NULL) | |
| 1252 { | |
| 1253 fprintf(stderr, "retransmit: message %d non-existant\n", seq); | |
| 1254 *found = 0; | |
| 1255 return 0; | |
| 1256 } | |
| 1257 | |
| 1258 *found = 1; | |
| 1259 frag = (hm_fragment *)item->data; | |
| 1260 | |
| 1261 if ( frag->msg_header.is_ccs) | |
| 1262 header_length = DTLS1_CCS_HEADER_LENGTH; | |
| 1263 else | |
| 1264 header_length = DTLS1_HM_HEADER_LENGTH; | |
| 1265 | |
| 1266 memcpy(s->init_buf->data, frag->fragment, | |
| 1267 frag->msg_header.msg_len + header_length); | |
| 1268 s->init_num = frag->msg_header.msg_len + header_length; | |
| 1269 | |
| 1270 dtls1_set_message_header_int(s, frag->msg_header.type, | |
| 1271 frag->msg_header.msg_len, frag->msg_header.seq, 0, | |
| 1272 frag->msg_header.frag_len); | |
| 1273 | |
| 1274 /* save current state */ | |
| 1275 saved_state.enc_write_ctx = s->enc_write_ctx; | |
| 1276 saved_state.write_hash = s->write_hash; | |
| 1277 saved_state.compress = s->compress; | |
| 1278 saved_state.session = s->session; | |
| 1279 saved_state.epoch = s->d1->w_epoch; | |
| 1280 saved_state.epoch = s->d1->w_epoch; | |
| 1281 | |
| 1282 s->d1->retransmitting = 1; | |
| 1283 | |
| 1284 /* restore state in which the message was originally sent */ | |
| 1285 s->enc_write_ctx = frag->msg_header.saved_retransmit_state.enc_write_ctx
; | |
| 1286 s->write_hash = frag->msg_header.saved_retransmit_state.write_hash; | |
| 1287 s->compress = frag->msg_header.saved_retransmit_state.compress; | |
| 1288 s->session = frag->msg_header.saved_retransmit_state.session; | |
| 1289 s->d1->w_epoch = frag->msg_header.saved_retransmit_state.epoch; | |
| 1290 | |
| 1291 if (frag->msg_header.saved_retransmit_state.epoch == saved_state.epoch -
1) | |
| 1292 { | |
| 1293 memcpy(save_write_sequence, s->s3->write_sequence, sizeof(s->s3-
>write_sequence)); | |
| 1294 memcpy(s->s3->write_sequence, s->d1->last_write_sequence, sizeof
(s->s3->write_sequence)); | |
| 1295 } | |
| 1296 | |
| 1297 ret = dtls1_do_write(s, frag->msg_header.is_ccs ? | |
| 1298 SSL3_RT_CHANGE_CIPHER_SPEC : SS
L3_RT_HANDSHAKE); | |
| 1299 | |
| 1300 /* restore current state */ | |
| 1301 s->enc_write_ctx = saved_state.enc_write_ctx; | |
| 1302 s->write_hash = saved_state.write_hash; | |
| 1303 s->compress = saved_state.compress; | |
| 1304 s->session = saved_state.session; | |
| 1305 s->d1->w_epoch = saved_state.epoch; | |
| 1306 | |
| 1307 if (frag->msg_header.saved_retransmit_state.epoch == saved_state.epoch -
1) | |
| 1308 { | |
| 1309 memcpy(s->d1->last_write_sequence, s->s3->write_sequence, sizeof
(s->s3->write_sequence)); | |
| 1310 memcpy(s->s3->write_sequence, save_write_sequence, sizeof(s->s3-
>write_sequence)); | |
| 1311 } | |
| 1312 | |
| 1313 s->d1->retransmitting = 0; | |
| 1314 | |
| 1315 (void)BIO_flush(SSL_get_wbio(s)); | |
| 1316 return ret; | |
| 1317 } | |
| 1318 | |
| 1319 /* call this function when the buffered messages are no longer needed */ | |
| 1320 void | |
| 1321 dtls1_clear_record_buffer(SSL *s) | |
| 1322 { | |
| 1323 pitem *item; | |
| 1324 | |
| 1325 for(item = pqueue_pop(s->d1->sent_messages); | |
| 1326 item != NULL; item = pqueue_pop(s->d1->sent_messages)) | |
| 1327 { | |
| 1328 dtls1_hm_fragment_free((hm_fragment *)item->data); | |
| 1329 pitem_free(item); | |
| 1330 } | |
| 1331 } | |
| 1332 | |
| 1333 | |
| 1334 unsigned char * | |
| 1335 dtls1_set_message_header(SSL *s, unsigned char *p, unsigned char mt, | |
| 1336 unsigned long len, unsigned long frag_off, unsigned long
frag_len) | |
| 1337 { | |
| 1338 /* Don't change sequence numbers while listening */ | |
| 1339 if (frag_off == 0 && !s->d1->listen) | |
| 1340 { | |
| 1341 s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; | |
| 1342 s->d1->next_handshake_write_seq++; | |
| 1343 } | |
| 1344 | |
| 1345 dtls1_set_message_header_int(s, mt, len, s->d1->handshake_write_seq, | |
| 1346 frag_off, frag_len); | |
| 1347 | |
| 1348 return p += DTLS1_HM_HEADER_LENGTH; | |
| 1349 } | |
| 1350 | |
| 1351 | |
| 1352 /* don't actually do the writing, wait till the MTU has been retrieved */ | |
| 1353 static void | |
| 1354 dtls1_set_message_header_int(SSL *s, unsigned char mt, | |
| 1355 unsigned long len, unsigned short seq_num, unsigned
long frag_off, | |
| 1356 unsigned long frag_len) | |
| 1357 { | |
| 1358 struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; | |
| 1359 | |
| 1360 msg_hdr->type = mt; | |
| 1361 msg_hdr->msg_len = len; | |
| 1362 msg_hdr->seq = seq_num; | |
| 1363 msg_hdr->frag_off = frag_off; | |
| 1364 msg_hdr->frag_len = frag_len; | |
| 1365 } | |
| 1366 | |
| 1367 static void | |
| 1368 dtls1_fix_message_header(SSL *s, unsigned long frag_off, | |
| 1369 unsigned long frag_len) | |
| 1370 { | |
| 1371 struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; | |
| 1372 | |
| 1373 msg_hdr->frag_off = frag_off; | |
| 1374 msg_hdr->frag_len = frag_len; | |
| 1375 } | |
| 1376 | |
| 1377 static unsigned char * | |
| 1378 dtls1_write_message_header(SSL *s, unsigned char *p) | |
| 1379 { | |
| 1380 struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; | |
| 1381 | |
| 1382 *p++ = msg_hdr->type; | |
| 1383 l2n3(msg_hdr->msg_len, p); | |
| 1384 | |
| 1385 s2n(msg_hdr->seq, p); | |
| 1386 l2n3(msg_hdr->frag_off, p); | |
| 1387 l2n3(msg_hdr->frag_len, p); | |
| 1388 | |
| 1389 return p; | |
| 1390 } | |
| 1391 | |
| 1392 unsigned int | |
| 1393 dtls1_min_mtu(void) | |
| 1394 { | |
| 1395 return (g_probable_mtu[(sizeof(g_probable_mtu) / | |
| 1396 sizeof(g_probable_mtu[0])) - 1]); | |
| 1397 } | |
| 1398 | |
| 1399 static unsigned int | |
| 1400 dtls1_guess_mtu(unsigned int curr_mtu) | |
| 1401 { | |
| 1402 unsigned int i; | |
| 1403 | |
| 1404 if ( curr_mtu == 0 ) | |
| 1405 return g_probable_mtu[0] ; | |
| 1406 | |
| 1407 for ( i = 0; i < sizeof(g_probable_mtu)/sizeof(g_probable_mtu[0]); i++) | |
| 1408 if ( curr_mtu > g_probable_mtu[i]) | |
| 1409 return g_probable_mtu[i]; | |
| 1410 | |
| 1411 return curr_mtu; | |
| 1412 } | |
| 1413 | |
| 1414 void | |
| 1415 dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr) | |
| 1416 { | |
| 1417 memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); | |
| 1418 msg_hdr->type = *(data++); | |
| 1419 n2l3(data, msg_hdr->msg_len); | |
| 1420 | |
| 1421 n2s(data, msg_hdr->seq); | |
| 1422 n2l3(data, msg_hdr->frag_off); | |
| 1423 n2l3(data, msg_hdr->frag_len); | |
| 1424 } | |
| 1425 | |
| 1426 void | |
| 1427 dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr) | |
| 1428 { | |
| 1429 memset(ccs_hdr, 0x00, sizeof(struct ccs_header_st)); | |
| 1430 | |
| 1431 ccs_hdr->type = *(data++); | |
| 1432 } | |
| 1433 | |
| 1434 int dtls1_shutdown(SSL *s) | |
| 1435 { | |
| 1436 int ret; | |
| 1437 #ifndef OPENSSL_NO_SCTP | |
| 1438 if (BIO_dgram_is_sctp(SSL_get_wbio(s)) && | |
| 1439 !(s->shutdown & SSL_SENT_SHUTDOWN)) | |
| 1440 { | |
| 1441 ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s)); | |
| 1442 if (ret < 0) return -1; | |
| 1443 | |
| 1444 if (ret == 0) | |
| 1445 BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SAVE_SHUTD
OWN, 1, NULL); | |
| 1446 } | |
| 1447 #endif | |
| 1448 ret = ssl3_shutdown(s); | |
| 1449 #ifndef OPENSSL_NO_SCTP | |
| 1450 BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN, 0, NULL); | |
| 1451 #endif | |
| 1452 return ret; | |
| 1453 } | |
| 1454 | |
| 1455 #ifndef OPENSSL_NO_HEARTBEATS | |
| 1456 int | |
| 1457 dtls1_process_heartbeat(SSL *s) | |
| 1458 { | |
| 1459 unsigned char *p = &s->s3->rrec.data[0], *pl; | |
| 1460 unsigned short hbtype; | |
| 1461 unsigned int payload; | |
| 1462 unsigned int padding = 16; /* Use minimum padding */ | |
| 1463 | |
| 1464 /* Read type and payload length first */ | |
| 1465 hbtype = *p++; | |
| 1466 n2s(p, payload); | |
| 1467 pl = p; | |
| 1468 | |
| 1469 if (s->msg_callback) | |
| 1470 s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT, | |
| 1471 &s->s3->rrec.data[0], s->s3->rrec.length, | |
| 1472 s, s->msg_callback_arg); | |
| 1473 | |
| 1474 if (hbtype == TLS1_HB_REQUEST) | |
| 1475 { | |
| 1476 unsigned char *buffer, *bp; | |
| 1477 int r; | |
| 1478 | |
| 1479 /* Allocate memory for the response, size is 1 byte | |
| 1480 * message type, plus 2 bytes payload length, plus | |
| 1481 * payload, plus padding | |
| 1482 */ | |
| 1483 buffer = OPENSSL_malloc(1 + 2 + payload + padding); | |
| 1484 bp = buffer; | |
| 1485 | |
| 1486 /* Enter response type, length and copy payload */ | |
| 1487 *bp++ = TLS1_HB_RESPONSE; | |
| 1488 s2n(payload, bp); | |
| 1489 memcpy(bp, pl, payload); | |
| 1490 bp += payload; | |
| 1491 /* Random padding */ | |
| 1492 RAND_pseudo_bytes(bp, padding); | |
| 1493 | |
| 1494 r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload
+ padding); | |
| 1495 | |
| 1496 if (r >= 0 && s->msg_callback) | |
| 1497 s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT, | |
| 1498 buffer, 3 + payload + padding, | |
| 1499 s, s->msg_callback_arg); | |
| 1500 | |
| 1501 OPENSSL_free(buffer); | |
| 1502 | |
| 1503 if (r < 0) | |
| 1504 return r; | |
| 1505 } | |
| 1506 else if (hbtype == TLS1_HB_RESPONSE) | |
| 1507 { | |
| 1508 unsigned int seq; | |
| 1509 | |
| 1510 /* We only send sequence numbers (2 bytes unsigned int), | |
| 1511 * and 16 random bytes, so we just try to read the | |
| 1512 * sequence number */ | |
| 1513 n2s(pl, seq); | |
| 1514 | |
| 1515 if (payload == 18 && seq == s->tlsext_hb_seq) | |
| 1516 { | |
| 1517 dtls1_stop_timer(s); | |
| 1518 s->tlsext_hb_seq++; | |
| 1519 s->tlsext_hb_pending = 0; | |
| 1520 } | |
| 1521 } | |
| 1522 | |
| 1523 return 0; | |
| 1524 } | |
| 1525 | |
| 1526 int | |
| 1527 dtls1_heartbeat(SSL *s) | |
| 1528 { | |
| 1529 unsigned char *buf, *p; | |
| 1530 int ret; | |
| 1531 unsigned int payload = 18; /* Sequence number + random bytes */ | |
| 1532 unsigned int padding = 16; /* Use minimum padding */ | |
| 1533 | |
| 1534 /* Only send if peer supports and accepts HB requests... */ | |
| 1535 if (!(s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) || | |
| 1536 s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_SEND_REQUESTS) | |
| 1537 { | |
| 1538 SSLerr(SSL_F_DTLS1_HEARTBEAT,SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACC
EPT); | |
| 1539 return -1; | |
| 1540 } | |
| 1541 | |
| 1542 /* ...and there is none in flight yet... */ | |
| 1543 if (s->tlsext_hb_pending) | |
| 1544 { | |
| 1545 SSLerr(SSL_F_DTLS1_HEARTBEAT,SSL_R_TLS_HEARTBEAT_PENDING); | |
| 1546 return -1; | |
| 1547 } | |
| 1548 | |
| 1549 /* ...and no handshake in progress. */ | |
| 1550 if (SSL_in_init(s) || s->in_handshake) | |
| 1551 { | |
| 1552 SSLerr(SSL_F_DTLS1_HEARTBEAT,SSL_R_UNEXPECTED_MESSAGE); | |
| 1553 return -1; | |
| 1554 } | |
| 1555 | |
| 1556 /* Check if padding is too long, payload and padding | |
| 1557 * must not exceed 2^14 - 3 = 16381 bytes in total. | |
| 1558 */ | |
| 1559 OPENSSL_assert(payload + padding <= 16381); | |
| 1560 | |
| 1561 /* Create HeartBeat message, we just use a sequence number | |
| 1562 * as payload to distuingish different messages and add | |
| 1563 * some random stuff. | |
| 1564 * - Message Type, 1 byte | |
| 1565 * - Payload Length, 2 bytes (unsigned int) | |
| 1566 * - Payload, the sequence number (2 bytes uint) | |
| 1567 * - Payload, random bytes (16 bytes uint) | |
| 1568 * - Padding | |
| 1569 */ | |
| 1570 buf = OPENSSL_malloc(1 + 2 + payload + padding); | |
| 1571 p = buf; | |
| 1572 /* Message Type */ | |
| 1573 *p++ = TLS1_HB_REQUEST; | |
| 1574 /* Payload length (18 bytes here) */ | |
| 1575 s2n(payload, p); | |
| 1576 /* Sequence number */ | |
| 1577 s2n(s->tlsext_hb_seq, p); | |
| 1578 /* 16 random bytes */ | |
| 1579 RAND_pseudo_bytes(p, 16); | |
| 1580 p += 16; | |
| 1581 /* Random padding */ | |
| 1582 RAND_pseudo_bytes(p, padding); | |
| 1583 | |
| 1584 ret = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding
); | |
| 1585 if (ret >= 0) | |
| 1586 { | |
| 1587 if (s->msg_callback) | |
| 1588 s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT, | |
| 1589 buf, 3 + payload + padding, | |
| 1590 s, s->msg_callback_arg); | |
| 1591 | |
| 1592 dtls1_start_timer(s); | |
| 1593 s->tlsext_hb_pending = 1; | |
| 1594 } | |
| 1595 | |
| 1596 OPENSSL_free(buf); | |
| 1597 | |
| 1598 return ret; | |
| 1599 } | |
| 1600 #endif | |
| OLD | NEW |