1160814Ssimon/* ssl/d1_pkt.c */ 2160814Ssimon/* 3160814Ssimon * DTLS implementation written by Nagendra Modadugu 4160814Ssimon * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. 5160814Ssimon */ 6160814Ssimon/* ==================================================================== 7160814Ssimon * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. 8160814Ssimon * 9160814Ssimon * Redistribution and use in source and binary forms, with or without 10160814Ssimon * modification, are permitted provided that the following conditions 11160814Ssimon * are met: 12160814Ssimon * 13160814Ssimon * 1. Redistributions of source code must retain the above copyright 14160814Ssimon * notice, this list of conditions and the following disclaimer. 15160814Ssimon * 16160814Ssimon * 2. Redistributions in binary form must reproduce the above copyright 17160814Ssimon * notice, this list of conditions and the following disclaimer in 18160814Ssimon * the documentation and/or other materials provided with the 19160814Ssimon * distribution. 20160814Ssimon * 21160814Ssimon * 3. All advertising materials mentioning features or use of this 22160814Ssimon * software must display the following acknowledgment: 23160814Ssimon * "This product includes software developed by the OpenSSL Project 24160814Ssimon * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 25160814Ssimon * 26160814Ssimon * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 27160814Ssimon * endorse or promote products derived from this software without 28160814Ssimon * prior written permission. For written permission, please contact 29160814Ssimon * openssl-core@openssl.org. 30160814Ssimon * 31160814Ssimon * 5. Products derived from this software may not be called "OpenSSL" 32160814Ssimon * nor may "OpenSSL" appear in their names without prior written 33160814Ssimon * permission of the OpenSSL Project. 34160814Ssimon * 35160814Ssimon * 6. Redistributions of any form whatsoever must retain the following 36160814Ssimon * acknowledgment: 37160814Ssimon * "This product includes software developed by the OpenSSL Project 38160814Ssimon * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 39160814Ssimon * 40160814Ssimon * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 41160814Ssimon * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42160814Ssimon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43160814Ssimon * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 44160814Ssimon * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45160814Ssimon * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46160814Ssimon * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47160814Ssimon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48160814Ssimon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 49160814Ssimon * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50160814Ssimon * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51160814Ssimon * OF THE POSSIBILITY OF SUCH DAMAGE. 52160814Ssimon * ==================================================================== 53160814Ssimon * 54160814Ssimon * This product includes cryptographic software written by Eric Young 55160814Ssimon * (eay@cryptsoft.com). This product includes software written by Tim 56160814Ssimon * Hudson (tjh@cryptsoft.com). 57160814Ssimon * 58160814Ssimon */ 59160814Ssimon/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 60160814Ssimon * All rights reserved. 61160814Ssimon * 62160814Ssimon * This package is an SSL implementation written 63160814Ssimon * by Eric Young (eay@cryptsoft.com). 64160814Ssimon * The implementation was written so as to conform with Netscapes SSL. 65160814Ssimon * 66160814Ssimon * This library is free for commercial and non-commercial use as long as 67160814Ssimon * the following conditions are aheared to. The following conditions 68160814Ssimon * apply to all code found in this distribution, be it the RC4, RSA, 69160814Ssimon * lhash, DES, etc., code; not just the SSL code. The SSL documentation 70160814Ssimon * included with this distribution is covered by the same copyright terms 71160814Ssimon * except that the holder is Tim Hudson (tjh@cryptsoft.com). 72160814Ssimon * 73160814Ssimon * Copyright remains Eric Young's, and as such any Copyright notices in 74160814Ssimon * the code are not to be removed. 75160814Ssimon * If this package is used in a product, Eric Young should be given attribution 76160814Ssimon * as the author of the parts of the library used. 77160814Ssimon * This can be in the form of a textual message at program startup or 78160814Ssimon * in documentation (online or textual) provided with the package. 79160814Ssimon * 80160814Ssimon * Redistribution and use in source and binary forms, with or without 81160814Ssimon * modification, are permitted provided that the following conditions 82160814Ssimon * are met: 83160814Ssimon * 1. Redistributions of source code must retain the copyright 84160814Ssimon * notice, this list of conditions and the following disclaimer. 85160814Ssimon * 2. Redistributions in binary form must reproduce the above copyright 86160814Ssimon * notice, this list of conditions and the following disclaimer in the 87160814Ssimon * documentation and/or other materials provided with the distribution. 88160814Ssimon * 3. All advertising materials mentioning features or use of this software 89160814Ssimon * must display the following acknowledgement: 90160814Ssimon * "This product includes cryptographic software written by 91160814Ssimon * Eric Young (eay@cryptsoft.com)" 92160814Ssimon * The word 'cryptographic' can be left out if the rouines from the library 93160814Ssimon * being used are not cryptographic related :-). 94160814Ssimon * 4. If you include any Windows specific code (or a derivative thereof) from 95160814Ssimon * the apps directory (application code) you must include an acknowledgement: 96160814Ssimon * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 97160814Ssimon * 98160814Ssimon * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 99160814Ssimon * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 100160814Ssimon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 101160814Ssimon * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 102160814Ssimon * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 103160814Ssimon * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 104160814Ssimon * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 105160814Ssimon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 106160814Ssimon * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 107160814Ssimon * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 108160814Ssimon * SUCH DAMAGE. 109160814Ssimon * 110160814Ssimon * The licence and distribution terms for any publically available version or 111160814Ssimon * derivative of this code cannot be changed. i.e. this code cannot simply be 112160814Ssimon * copied and put under another distribution licence 113160814Ssimon * [including the GNU Public Licence.] 114160814Ssimon */ 115160814Ssimon 116160814Ssimon#include <stdio.h> 117160814Ssimon#include <errno.h> 118160814Ssimon#define USE_SOCKETS 119160814Ssimon#include "ssl_locl.h" 120160814Ssimon#include <openssl/evp.h> 121160814Ssimon#include <openssl/buffer.h> 122160814Ssimon#include <openssl/pqueue.h> 123194206Ssimon#include <openssl/rand.h> 124160814Ssimon 125238405Sjkim/* mod 128 saturating subtract of two 64-bit values in big-endian order */ 126238405Sjkimstatic int satsub64be(const unsigned char *v1,const unsigned char *v2) 127238405Sjkim{ int ret,sat,brw,i; 128238405Sjkim 129238405Sjkim if (sizeof(long) == 8) do 130238405Sjkim { const union { long one; char little; } is_endian = {1}; 131238405Sjkim long l; 132238405Sjkim 133238405Sjkim if (is_endian.little) break; 134238405Sjkim /* not reached on little-endians */ 135238405Sjkim /* following test is redundant, because input is 136238405Sjkim * always aligned, but I take no chances... */ 137238405Sjkim if (((size_t)v1|(size_t)v2)&0x7) break; 138238405Sjkim 139238405Sjkim l = *((long *)v1); 140238405Sjkim l -= *((long *)v2); 141238405Sjkim if (l>128) return 128; 142238405Sjkim else if (l<-128) return -128; 143238405Sjkim else return (int)l; 144238405Sjkim } while (0); 145238405Sjkim 146238405Sjkim ret = (int)v1[7]-(int)v2[7]; 147238405Sjkim sat = 0; 148238405Sjkim brw = ret>>8; /* brw is either 0 or -1 */ 149238405Sjkim if (ret & 0x80) 150238405Sjkim { for (i=6;i>=0;i--) 151238405Sjkim { brw += (int)v1[i]-(int)v2[i]; 152238405Sjkim sat |= ~brw; 153238405Sjkim brw >>= 8; 154238405Sjkim } 155238405Sjkim } 156238405Sjkim else 157238405Sjkim { for (i=6;i>=0;i--) 158238405Sjkim { brw += (int)v1[i]-(int)v2[i]; 159238405Sjkim sat |= brw; 160238405Sjkim brw >>= 8; 161238405Sjkim } 162238405Sjkim } 163238405Sjkim brw <<= 8; /* brw is either 0 or -256 */ 164238405Sjkim 165238405Sjkim if (sat&0xff) return brw | 0x80; 166238405Sjkim else return brw + (ret&0xFF); 167238405Sjkim} 168238405Sjkim 169160814Ssimonstatic int have_handshake_fragment(SSL *s, int type, unsigned char *buf, 170160814Ssimon int len, int peek); 171238405Sjkimstatic int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap); 172160814Ssimonstatic void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap); 173160814Ssimonstatic DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, 174160814Ssimon unsigned int *is_next_epoch); 175160814Ssimon#if 0 176160814Ssimonstatic int dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr, 177160814Ssimon unsigned short *priority, unsigned long *offset); 178160814Ssimon#endif 179160814Ssimonstatic int dtls1_buffer_record(SSL *s, record_pqueue *q, 180238405Sjkim unsigned char *priority); 181160814Ssimonstatic int dtls1_process_record(SSL *s); 182160814Ssimon 183160814Ssimon/* copy buffered record into SSL structure */ 184160814Ssimonstatic int 185160814Ssimondtls1_copy_record(SSL *s, pitem *item) 186160814Ssimon { 187160814Ssimon DTLS1_RECORD_DATA *rdata; 188160814Ssimon 189160814Ssimon rdata = (DTLS1_RECORD_DATA *)item->data; 190160814Ssimon 191160814Ssimon if (s->s3->rbuf.buf != NULL) 192160814Ssimon OPENSSL_free(s->s3->rbuf.buf); 193160814Ssimon 194160814Ssimon s->packet = rdata->packet; 195160814Ssimon s->packet_length = rdata->packet_length; 196160814Ssimon memcpy(&(s->s3->rbuf), &(rdata->rbuf), sizeof(SSL3_BUFFER)); 197160814Ssimon memcpy(&(s->s3->rrec), &(rdata->rrec), sizeof(SSL3_RECORD)); 198215697Ssimon 199215697Ssimon /* Set proper sequence number for mac calculation */ 200215697Ssimon memcpy(&(s->s3->read_sequence[2]), &(rdata->packet[5]), 6); 201160814Ssimon 202160814Ssimon return(1); 203160814Ssimon } 204160814Ssimon 205160814Ssimon 206160814Ssimonstatic int 207238405Sjkimdtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority) 208238405Sjkim { 209238405Sjkim DTLS1_RECORD_DATA *rdata; 210160814Ssimon pitem *item; 211160814Ssimon 212196474Ssimon /* Limit the size of the queue to prevent DOS attacks */ 213196474Ssimon if (pqueue_size(queue->q) >= 100) 214196474Ssimon return 0; 215277195Sdelphij 216160814Ssimon rdata = OPENSSL_malloc(sizeof(DTLS1_RECORD_DATA)); 217238405Sjkim item = pitem_new(priority, rdata); 218160814Ssimon if (rdata == NULL || item == NULL) 219160814Ssimon { 220160814Ssimon if (rdata != NULL) OPENSSL_free(rdata); 221160814Ssimon if (item != NULL) pitem_free(item); 222160814Ssimon 223160814Ssimon SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR); 224160814Ssimon return(0); 225160814Ssimon } 226160814Ssimon 227160814Ssimon rdata->packet = s->packet; 228160814Ssimon rdata->packet_length = s->packet_length; 229160814Ssimon memcpy(&(rdata->rbuf), &(s->s3->rbuf), sizeof(SSL3_BUFFER)); 230160814Ssimon memcpy(&(rdata->rrec), &(s->s3->rrec), sizeof(SSL3_RECORD)); 231160814Ssimon 232160814Ssimon item->data = rdata; 233160814Ssimon 234238405Sjkim#ifndef OPENSSL_NO_SCTP 235238405Sjkim /* Store bio_dgram_sctp_rcvinfo struct */ 236238405Sjkim if (BIO_dgram_is_sctp(SSL_get_rbio(s)) && 237238405Sjkim (s->state == SSL3_ST_SR_FINISHED_A || s->state == SSL3_ST_CR_FINISHED_A)) { 238238405Sjkim BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SCTP_GET_RCVINFO, sizeof(rdata->recordinfo), &rdata->recordinfo); 239238405Sjkim } 240238405Sjkim#endif 241238405Sjkim 242160814Ssimon s->packet = NULL; 243160814Ssimon s->packet_length = 0; 244160814Ssimon memset(&(s->s3->rbuf), 0, sizeof(SSL3_BUFFER)); 245160814Ssimon memset(&(s->s3->rrec), 0, sizeof(SSL3_RECORD)); 246160814Ssimon 247160814Ssimon if (!ssl3_setup_buffers(s)) 248160814Ssimon { 249160814Ssimon SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR); 250277195Sdelphij if (rdata->rbuf.buf != NULL) 251277195Sdelphij OPENSSL_free(rdata->rbuf.buf); 252160814Ssimon OPENSSL_free(rdata); 253160814Ssimon pitem_free(item); 254277195Sdelphij return(-1); 255160814Ssimon } 256277195Sdelphij 257277195Sdelphij /* insert should not fail, since duplicates are dropped */ 258277195Sdelphij if (pqueue_insert(queue->q, item) == NULL) 259277195Sdelphij { 260277195Sdelphij SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR); 261277195Sdelphij if (rdata->rbuf.buf != NULL) 262277195Sdelphij OPENSSL_free(rdata->rbuf.buf); 263277195Sdelphij OPENSSL_free(rdata); 264277195Sdelphij pitem_free(item); 265277195Sdelphij return(-1); 266277195Sdelphij } 267277195Sdelphij 268160814Ssimon return(1); 269238405Sjkim } 270160814Ssimon 271160814Ssimon 272160814Ssimonstatic int 273160814Ssimondtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue) 274160814Ssimon { 275160814Ssimon pitem *item; 276160814Ssimon 277160814Ssimon item = pqueue_pop(queue->q); 278160814Ssimon if (item) 279160814Ssimon { 280160814Ssimon dtls1_copy_record(s, item); 281160814Ssimon 282160814Ssimon OPENSSL_free(item->data); 283160814Ssimon pitem_free(item); 284160814Ssimon 285160814Ssimon return(1); 286160814Ssimon } 287160814Ssimon 288160814Ssimon return(0); 289160814Ssimon } 290160814Ssimon 291160814Ssimon 292160814Ssimon/* retrieve a buffered record that belongs to the new epoch, i.e., not processed 293160814Ssimon * yet */ 294160814Ssimon#define dtls1_get_unprocessed_record(s) \ 295160814Ssimon dtls1_retrieve_buffered_record((s), \ 296160814Ssimon &((s)->d1->unprocessed_rcds)) 297160814Ssimon 298160814Ssimon/* retrieve a buffered record that belongs to the current epoch, ie, processed */ 299160814Ssimon#define dtls1_get_processed_record(s) \ 300160814Ssimon dtls1_retrieve_buffered_record((s), \ 301160814Ssimon &((s)->d1->processed_rcds)) 302160814Ssimon 303160814Ssimonstatic int 304160814Ssimondtls1_process_buffered_records(SSL *s) 305160814Ssimon { 306160814Ssimon pitem *item; 307160814Ssimon 308160814Ssimon item = pqueue_peek(s->d1->unprocessed_rcds.q); 309160814Ssimon if (item) 310160814Ssimon { 311160814Ssimon /* Check if epoch is current. */ 312160814Ssimon if (s->d1->unprocessed_rcds.epoch != s->d1->r_epoch) 313160814Ssimon return(1); /* Nothing to do. */ 314160814Ssimon 315160814Ssimon /* Process all the records. */ 316160814Ssimon while (pqueue_peek(s->d1->unprocessed_rcds.q)) 317160814Ssimon { 318160814Ssimon dtls1_get_unprocessed_record(s); 319160814Ssimon if ( ! dtls1_process_record(s)) 320160814Ssimon return(0); 321277195Sdelphij if(dtls1_buffer_record(s, &(s->d1->processed_rcds), 322277195Sdelphij s->s3->rrec.seq_num)<0) 323277195Sdelphij return -1; 324160814Ssimon } 325160814Ssimon } 326160814Ssimon 327160814Ssimon /* sync epoch numbers once all the unprocessed records 328160814Ssimon * have been processed */ 329160814Ssimon s->d1->processed_rcds.epoch = s->d1->r_epoch; 330160814Ssimon s->d1->unprocessed_rcds.epoch = s->d1->r_epoch + 1; 331160814Ssimon 332160814Ssimon return(1); 333160814Ssimon } 334160814Ssimon 335160814Ssimon 336160814Ssimon#if 0 337160814Ssimon 338160814Ssimonstatic int 339160814Ssimondtls1_get_buffered_record(SSL *s) 340160814Ssimon { 341160814Ssimon pitem *item; 342160814Ssimon PQ_64BIT priority = 343160814Ssimon (((PQ_64BIT)s->d1->handshake_read_seq) << 32) | 344160814Ssimon ((PQ_64BIT)s->d1->r_msg_hdr.frag_off); 345160814Ssimon 346160814Ssimon if ( ! SSL_in_init(s)) /* if we're not (re)negotiating, 347160814Ssimon nothing buffered */ 348160814Ssimon return 0; 349160814Ssimon 350160814Ssimon 351160814Ssimon item = pqueue_peek(s->d1->rcvd_records); 352160814Ssimon if (item && item->priority == priority) 353160814Ssimon { 354160814Ssimon /* Check if we've received the record of interest. It must be 355160814Ssimon * a handshake record, since data records as passed up without 356160814Ssimon * buffering */ 357160814Ssimon DTLS1_RECORD_DATA *rdata; 358160814Ssimon item = pqueue_pop(s->d1->rcvd_records); 359160814Ssimon rdata = (DTLS1_RECORD_DATA *)item->data; 360160814Ssimon 361160814Ssimon if (s->s3->rbuf.buf != NULL) 362160814Ssimon OPENSSL_free(s->s3->rbuf.buf); 363160814Ssimon 364160814Ssimon s->packet = rdata->packet; 365160814Ssimon s->packet_length = rdata->packet_length; 366160814Ssimon memcpy(&(s->s3->rbuf), &(rdata->rbuf), sizeof(SSL3_BUFFER)); 367160814Ssimon memcpy(&(s->s3->rrec), &(rdata->rrec), sizeof(SSL3_RECORD)); 368160814Ssimon 369160814Ssimon OPENSSL_free(item->data); 370160814Ssimon pitem_free(item); 371160814Ssimon 372160814Ssimon /* s->d1->next_expected_seq_num++; */ 373160814Ssimon return(1); 374160814Ssimon } 375160814Ssimon 376160814Ssimon return 0; 377160814Ssimon } 378160814Ssimon 379160814Ssimon#endif 380160814Ssimon 381160814Ssimonstatic int 382160814Ssimondtls1_process_record(SSL *s) 383160814Ssimon{ 384238405Sjkim int i,al; 385238405Sjkim int enc_err; 386160814Ssimon SSL_SESSION *sess; 387238405Sjkim SSL3_RECORD *rr; 388246772Sjkim unsigned int mac_size, orig_len; 389160814Ssimon unsigned char md[EVP_MAX_MD_SIZE]; 390160814Ssimon 391160814Ssimon rr= &(s->s3->rrec); 392238405Sjkim sess = s->session; 393160814Ssimon 394160814Ssimon /* At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length, 395160814Ssimon * and we have that many bytes in s->packet 396160814Ssimon */ 397160814Ssimon rr->input= &(s->packet[DTLS1_RT_HEADER_LENGTH]); 398160814Ssimon 399160814Ssimon /* ok, we can now read from 's->packet' data into 'rr' 400160814Ssimon * rr->input points at rr->length bytes, which 401160814Ssimon * need to be copied into rr->data by either 402160814Ssimon * the decryption or by the decompression 403160814Ssimon * When the data is 'copied' into the rr->data buffer, 404160814Ssimon * rr->input will be pointed at the new buffer */ 405160814Ssimon 406160814Ssimon /* We now have - encrypted [ MAC [ compressed [ plain ] ] ] 407160814Ssimon * rr->length bytes of encrypted compressed stuff. */ 408160814Ssimon 409160814Ssimon /* check is not needed I believe */ 410160814Ssimon if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) 411160814Ssimon { 412160814Ssimon al=SSL_AD_RECORD_OVERFLOW; 413160814Ssimon SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_ENCRYPTED_LENGTH_TOO_LONG); 414160814Ssimon goto f_err; 415160814Ssimon } 416160814Ssimon 417160814Ssimon /* decrypt in place in 'rr->input' */ 418160814Ssimon rr->data=rr->input; 419160814Ssimon 420160814Ssimon enc_err = s->method->ssl3_enc->enc(s,0); 421246772Sjkim /* enc_err is: 422246772Sjkim * 0: (in non-constant time) if the record is publically invalid. 423246772Sjkim * 1: if the padding is valid 424246772Sjkim * -1: if the padding is invalid */ 425246772Sjkim if (enc_err == 0) 426160814Ssimon { 427246772Sjkim /* For DTLS we simply ignore bad packets. */ 428246772Sjkim rr->length = 0; 429246772Sjkim s->packet_length = 0; 430246772Sjkim goto err; 431160814Ssimon } 432160814Ssimon 433160814Ssimon#ifdef TLS_DEBUG 434160814Ssimonprintf("dec %d\n",rr->length); 435160814Ssimon{ unsigned int z; for (z=0; z<rr->length; z++) printf("%02X%c",rr->data[z],((z+1)%16)?' ':'\n'); } 436160814Ssimonprintf("\n"); 437160814Ssimon#endif 438160814Ssimon 439160814Ssimon /* r->length is now the compressed data plus mac */ 440246772Sjkim if ((sess != NULL) && 441246772Sjkim (s->enc_read_ctx != NULL) && 442246772Sjkim (EVP_MD_CTX_md(s->read_hash) != NULL)) 443160814Ssimon { 444246772Sjkim /* s->read_hash != NULL => mac_size != -1 */ 445246772Sjkim unsigned char *mac = NULL; 446246772Sjkim unsigned char mac_tmp[EVP_MAX_MD_SIZE]; 447246772Sjkim mac_size=EVP_MD_CTX_size(s->read_hash); 448246772Sjkim OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE); 449160814Ssimon 450246772Sjkim /* kludge: *_cbc_remove_padding passes padding length in rr->type */ 451246772Sjkim orig_len = rr->length+((unsigned int)rr->type>>8); 452246772Sjkim 453246772Sjkim /* orig_len is the length of the record before any padding was 454246772Sjkim * removed. This is public information, as is the MAC in use, 455246772Sjkim * therefore we can safely process the record in a different 456246772Sjkim * amount of time if it's too short to possibly contain a MAC. 457246772Sjkim */ 458246772Sjkim if (orig_len < mac_size || 459246772Sjkim /* CBC records must have a padding length byte too. */ 460246772Sjkim (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE && 461246772Sjkim orig_len < mac_size+1)) 462160814Ssimon { 463246772Sjkim al=SSL_AD_DECODE_ERROR; 464246772Sjkim SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_LENGTH_TOO_SHORT); 465160814Ssimon goto f_err; 466160814Ssimon } 467246772Sjkim 468246772Sjkim if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) 469160814Ssimon { 470246772Sjkim /* We update the length so that the TLS header bytes 471246772Sjkim * can be constructed correctly but we need to extract 472246772Sjkim * the MAC in constant time from within the record, 473246772Sjkim * without leaking the contents of the padding bytes. 474246772Sjkim * */ 475246772Sjkim mac = mac_tmp; 476246772Sjkim ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len); 477237657Sjkim rr->length -= mac_size; 478160814Ssimon } 479237657Sjkim else 480160814Ssimon { 481246772Sjkim /* In this case there's no padding, so |orig_len| 482246772Sjkim * equals |rec->length| and we checked that there's 483246772Sjkim * enough bytes for |mac_size| above. */ 484246772Sjkim rr->length -= mac_size; 485246772Sjkim mac = &rr->data[rr->length]; 486160814Ssimon } 487246772Sjkim 488246772Sjkim i=s->method->ssl3_enc->mac(s,md,0 /* not send */); 489246772Sjkim if (i < 0 || mac == NULL || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0) 490246772Sjkim enc_err = -1; 491246772Sjkim if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+mac_size) 492246772Sjkim enc_err = -1; 493160814Ssimon } 494160814Ssimon 495246772Sjkim if (enc_err < 0) 496237657Sjkim { 497237657Sjkim /* decryption failed, silently discard message */ 498237657Sjkim rr->length = 0; 499237657Sjkim s->packet_length = 0; 500237657Sjkim goto err; 501237657Sjkim } 502237657Sjkim 503160814Ssimon /* r->length is now just compressed */ 504160814Ssimon if (s->expand != NULL) 505160814Ssimon { 506160814Ssimon if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH) 507160814Ssimon { 508160814Ssimon al=SSL_AD_RECORD_OVERFLOW; 509160814Ssimon SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_COMPRESSED_LENGTH_TOO_LONG); 510160814Ssimon goto f_err; 511160814Ssimon } 512160814Ssimon if (!ssl3_do_uncompress(s)) 513160814Ssimon { 514160814Ssimon al=SSL_AD_DECOMPRESSION_FAILURE; 515160814Ssimon SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_BAD_DECOMPRESSION); 516160814Ssimon goto f_err; 517160814Ssimon } 518160814Ssimon } 519160814Ssimon 520160814Ssimon if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH) 521160814Ssimon { 522160814Ssimon al=SSL_AD_RECORD_OVERFLOW; 523160814Ssimon SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_DATA_LENGTH_TOO_LONG); 524160814Ssimon goto f_err; 525160814Ssimon } 526160814Ssimon 527160814Ssimon rr->off=0; 528160814Ssimon /* So at this point the following is true 529160814Ssimon * ssl->s3->rrec.type is the type of record 530160814Ssimon * ssl->s3->rrec.length == number of bytes in record 531160814Ssimon * ssl->s3->rrec.off == offset to first valid byte 532160814Ssimon * ssl->s3->rrec.data == where to take bytes from, increment 533160814Ssimon * after use :-). 534160814Ssimon */ 535160814Ssimon 536160814Ssimon /* we have pulled in a full packet so zero things */ 537160814Ssimon s->packet_length=0; 538238405Sjkim return(1); 539160814Ssimon 540160814Ssimonf_err: 541160814Ssimon ssl3_send_alert(s,SSL3_AL_FATAL,al); 542160814Ssimonerr: 543160814Ssimon return(0); 544160814Ssimon} 545160814Ssimon 546160814Ssimon 547160814Ssimon/* Call this to get a new input record. 548160814Ssimon * It will return <= 0 if more data is needed, normally due to an error 549160814Ssimon * or non-blocking IO. 550160814Ssimon * When it finishes, one packet has been decoded and can be found in 551160814Ssimon * ssl->s3->rrec.type - is the type of record 552160814Ssimon * ssl->s3->rrec.data, - data 553160814Ssimon * ssl->s3->rrec.length, - number of bytes 554160814Ssimon */ 555160814Ssimon/* used only by dtls1_read_bytes */ 556160814Ssimonint dtls1_get_record(SSL *s) 557160814Ssimon { 558205128Ssimon int ssl_major,ssl_minor; 559160814Ssimon int i,n; 560160814Ssimon SSL3_RECORD *rr; 561205128Ssimon unsigned char *p = NULL; 562194206Ssimon unsigned short version; 563160814Ssimon DTLS1_BITMAP *bitmap; 564194206Ssimon unsigned int is_next_epoch; 565160814Ssimon 566160814Ssimon rr= &(s->s3->rrec); 567160814Ssimon 568238405Sjkim /* The epoch may have changed. If so, process all the 569238405Sjkim * pending records. This is a non-blocking operation. */ 570277195Sdelphij if(dtls1_process_buffered_records(s)<0) 571277195Sdelphij return -1; 572160814Ssimon 573160814Ssimon /* if we're renegotiating, then there may be buffered records */ 574160814Ssimon if (dtls1_get_processed_record(s)) 575160814Ssimon return 1; 576160814Ssimon 577160814Ssimon /* get something from the wire */ 578160814Ssimonagain: 579160814Ssimon /* check if we have the header */ 580160814Ssimon if ( (s->rstate != SSL_ST_READ_BODY) || 581160814Ssimon (s->packet_length < DTLS1_RT_HEADER_LENGTH)) 582160814Ssimon { 583160814Ssimon n=ssl3_read_n(s, DTLS1_RT_HEADER_LENGTH, s->s3->rbuf.len, 0); 584160814Ssimon /* read timeout is handled by dtls1_read_bytes */ 585160814Ssimon if (n <= 0) return(n); /* error or non-blocking */ 586160814Ssimon 587205128Ssimon /* this packet contained a partial record, dump it */ 588205128Ssimon if (s->packet_length != DTLS1_RT_HEADER_LENGTH) 589205128Ssimon { 590205128Ssimon s->packet_length = 0; 591205128Ssimon goto again; 592205128Ssimon } 593160814Ssimon 594160814Ssimon s->rstate=SSL_ST_READ_BODY; 595160814Ssimon 596160814Ssimon p=s->packet; 597160814Ssimon 598160814Ssimon /* Pull apart the header into the DTLS1_RECORD */ 599160814Ssimon rr->type= *(p++); 600160814Ssimon ssl_major= *(p++); 601160814Ssimon ssl_minor= *(p++); 602160814Ssimon version=(ssl_major<<8)|ssl_minor; 603160814Ssimon 604194206Ssimon /* sequence number is 64 bits, with top 2 bytes = epoch */ 605160814Ssimon n2s(p,rr->epoch); 606160814Ssimon 607160814Ssimon memcpy(&(s->s3->read_sequence[2]), p, 6); 608160814Ssimon p+=6; 609160814Ssimon 610160814Ssimon n2s(p,rr->length); 611160814Ssimon 612160814Ssimon /* Lets check version */ 613167612Ssimon if (!s->first_packet) 614160814Ssimon { 615238405Sjkim if (version != s->version) 616160814Ssimon { 617205128Ssimon /* unexpected version, silently discard */ 618205128Ssimon rr->length = 0; 619205128Ssimon s->packet_length = 0; 620205128Ssimon goto again; 621160814Ssimon } 622160814Ssimon } 623160814Ssimon 624238405Sjkim if ((version & 0xff00) != (s->version & 0xff00)) 625160814Ssimon { 626205128Ssimon /* wrong version, silently discard record */ 627205128Ssimon rr->length = 0; 628205128Ssimon s->packet_length = 0; 629205128Ssimon goto again; 630160814Ssimon } 631160814Ssimon 632160814Ssimon if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) 633160814Ssimon { 634205128Ssimon /* record too long, silently discard it */ 635205128Ssimon rr->length = 0; 636205128Ssimon s->packet_length = 0; 637205128Ssimon goto again; 638160814Ssimon } 639160814Ssimon 640160814Ssimon /* now s->rstate == SSL_ST_READ_BODY */ 641160814Ssimon } 642160814Ssimon 643160814Ssimon /* s->rstate == SSL_ST_READ_BODY, get and decode the data */ 644160814Ssimon 645160814Ssimon if (rr->length > s->packet_length-DTLS1_RT_HEADER_LENGTH) 646160814Ssimon { 647160814Ssimon /* now s->packet_length == DTLS1_RT_HEADER_LENGTH */ 648160814Ssimon i=rr->length; 649160814Ssimon n=ssl3_read_n(s,i,i,1); 650160814Ssimon /* this packet contained a partial record, dump it */ 651160814Ssimon if ( n != i) 652160814Ssimon { 653205128Ssimon rr->length = 0; 654160814Ssimon s->packet_length = 0; 655160814Ssimon goto again; 656160814Ssimon } 657160814Ssimon 658160814Ssimon /* now n == rr->length, 659160814Ssimon * and s->packet_length == DTLS1_RT_HEADER_LENGTH + rr->length */ 660160814Ssimon } 661160814Ssimon s->rstate=SSL_ST_READ_HEADER; /* set state for later operations */ 662160814Ssimon 663160814Ssimon /* match epochs. NULL means the packet is dropped on the floor */ 664160814Ssimon bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch); 665160814Ssimon if ( bitmap == NULL) 666160814Ssimon { 667194206Ssimon rr->length = 0; 668238405Sjkim s->packet_length = 0; /* dump this record */ 669238405Sjkim goto again; /* get another record */ 670160814Ssimon } 671160814Ssimon 672238405Sjkim#ifndef OPENSSL_NO_SCTP 673238405Sjkim /* Only do replay check if no SCTP bio */ 674238405Sjkim if (!BIO_dgram_is_sctp(SSL_get_rbio(s))) 675238405Sjkim { 676238405Sjkim#endif 677238405Sjkim /* Check whether this is a repeat, or aged record. 678238405Sjkim * Don't check if we're listening and this message is 679238405Sjkim * a ClientHello. They can look as if they're replayed, 680238405Sjkim * since they arrive from different connections and 681238405Sjkim * would be dropped unnecessarily. 682238405Sjkim */ 683238405Sjkim if (!(s->d1->listen && rr->type == SSL3_RT_HANDSHAKE && 684277195Sdelphij s->packet_length > DTLS1_RT_HEADER_LENGTH && 685277195Sdelphij s->packet[DTLS1_RT_HEADER_LENGTH] == SSL3_MT_CLIENT_HELLO) && 686238405Sjkim !dtls1_record_replay_check(s, bitmap)) 687238405Sjkim { 688238405Sjkim rr->length = 0; 689238405Sjkim s->packet_length=0; /* dump this record */ 690238405Sjkim goto again; /* get another record */ 691238405Sjkim } 692238405Sjkim#ifndef OPENSSL_NO_SCTP 693238405Sjkim } 694238405Sjkim#endif 695238405Sjkim 696160814Ssimon /* just read a 0 length packet */ 697160814Ssimon if (rr->length == 0) goto again; 698160814Ssimon 699215697Ssimon /* If this record is from the next epoch (either HM or ALERT), 700215697Ssimon * and a handshake is currently in progress, buffer it since it 701237657Sjkim * cannot be processed at this time. However, do not buffer 702237657Sjkim * anything while listening. 703237657Sjkim */ 704215697Ssimon if (is_next_epoch) 705215697Ssimon { 706237657Sjkim if ((SSL_in_init(s) || s->in_handshake) && !s->d1->listen) 707215697Ssimon { 708277195Sdelphij if(dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num)<0) 709277195Sdelphij return -1; 710277195Sdelphij dtls1_record_bitmap_update(s, bitmap);/* Mark receipt of record. */ 711215697Ssimon } 712215697Ssimon rr->length = 0; 713238405Sjkim s->packet_length = 0; 714238405Sjkim goto again; 715238405Sjkim } 716160814Ssimon 717238405Sjkim if (!dtls1_process_record(s)) 718215697Ssimon { 719215697Ssimon rr->length = 0; 720238405Sjkim s->packet_length = 0; /* dump this record */ 721238405Sjkim goto again; /* get another record */ 722215697Ssimon } 723277195Sdelphij dtls1_record_bitmap_update(s, bitmap);/* Mark receipt of record. */ 724160814Ssimon 725160814Ssimon return(1); 726160814Ssimon 727160814Ssimon } 728160814Ssimon 729160814Ssimon/* Return up to 'len' payload bytes received in 'type' records. 730160814Ssimon * 'type' is one of the following: 731160814Ssimon * 732160814Ssimon * - SSL3_RT_HANDSHAKE (when ssl3_get_message calls us) 733160814Ssimon * - SSL3_RT_APPLICATION_DATA (when ssl3_read calls us) 734160814Ssimon * - 0 (during a shutdown, no data has to be returned) 735160814Ssimon * 736160814Ssimon * If we don't have stored data to work from, read a SSL/TLS record first 737160814Ssimon * (possibly multiple records if we still don't have anything to return). 738160814Ssimon * 739160814Ssimon * This function must handle any surprises the peer may have for us, such as 740160814Ssimon * Alert records (e.g. close_notify), ChangeCipherSpec records (not really 741160814Ssimon * a surprise, but handled as if it were), or renegotiation requests. 742160814Ssimon * Also if record payloads contain fragments too small to process, we store 743160814Ssimon * them until there is enough for the respective protocol (the record protocol 744160814Ssimon * may use arbitrary fragmentation and even interleaving): 745160814Ssimon * Change cipher spec protocol 746160814Ssimon * just 1 byte needed, no need for keeping anything stored 747160814Ssimon * Alert protocol 748160814Ssimon * 2 bytes needed (AlertLevel, AlertDescription) 749160814Ssimon * Handshake protocol 750160814Ssimon * 4 bytes needed (HandshakeType, uint24 length) -- we just have 751160814Ssimon * to detect unexpected Client Hello and Hello Request messages 752160814Ssimon * here, anything else is handled by higher layers 753160814Ssimon * Application data protocol 754160814Ssimon * none of our business 755160814Ssimon */ 756160814Ssimonint dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) 757160814Ssimon { 758160814Ssimon int al,i,j,ret; 759160814Ssimon unsigned int n; 760160814Ssimon SSL3_RECORD *rr; 761160814Ssimon void (*cb)(const SSL *ssl,int type2,int val)=NULL; 762160814Ssimon 763160814Ssimon if (s->s3->rbuf.buf == NULL) /* Not initialized yet */ 764160814Ssimon if (!ssl3_setup_buffers(s)) 765160814Ssimon return(-1); 766160814Ssimon 767160814Ssimon /* XXX: check what the second '&& type' is about */ 768160814Ssimon if ((type && (type != SSL3_RT_APPLICATION_DATA) && 769160814Ssimon (type != SSL3_RT_HANDSHAKE) && type) || 770160814Ssimon (peek && (type != SSL3_RT_APPLICATION_DATA))) 771160814Ssimon { 772160814Ssimon SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR); 773160814Ssimon return -1; 774160814Ssimon } 775160814Ssimon 776160814Ssimon /* check whether there's a handshake message (client hello?) waiting */ 777160814Ssimon if ( (ret = have_handshake_fragment(s, type, buf, len, peek))) 778160814Ssimon return ret; 779160814Ssimon 780160814Ssimon /* Now s->d1->handshake_fragment_len == 0 if type == SSL3_RT_HANDSHAKE. */ 781160814Ssimon 782238405Sjkim#ifndef OPENSSL_NO_SCTP 783238405Sjkim /* Continue handshake if it had to be interrupted to read 784238405Sjkim * app data with SCTP. 785238405Sjkim */ 786238405Sjkim if ((!s->in_handshake && SSL_in_init(s)) || 787238405Sjkim (BIO_dgram_is_sctp(SSL_get_rbio(s)) && 788238405Sjkim (s->state == DTLS1_SCTP_ST_SR_READ_SOCK || s->state == DTLS1_SCTP_ST_CR_READ_SOCK) && 789238405Sjkim s->s3->in_read_app_data != 2)) 790238405Sjkim#else 791160814Ssimon if (!s->in_handshake && SSL_in_init(s)) 792238405Sjkim#endif 793160814Ssimon { 794160814Ssimon /* type == SSL3_RT_APPLICATION_DATA */ 795160814Ssimon i=s->handshake_func(s); 796160814Ssimon if (i < 0) return(i); 797160814Ssimon if (i == 0) 798160814Ssimon { 799160814Ssimon SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE); 800160814Ssimon return(-1); 801160814Ssimon } 802160814Ssimon } 803160814Ssimon 804160814Ssimonstart: 805160814Ssimon s->rwstate=SSL_NOTHING; 806160814Ssimon 807160814Ssimon /* s->s3->rrec.type - is the type of record 808160814Ssimon * s->s3->rrec.data, - data 809160814Ssimon * s->s3->rrec.off, - offset into 'data' for next read 810160814Ssimon * s->s3->rrec.length, - number of bytes. */ 811160814Ssimon rr = &(s->s3->rrec); 812160814Ssimon 813205128Ssimon /* We are not handshaking and have no data yet, 814205128Ssimon * so process data buffered during the last handshake 815205128Ssimon * in advance, if any. 816205128Ssimon */ 817205128Ssimon if (s->state == SSL_ST_OK && rr->length == 0) 818205128Ssimon { 819205128Ssimon pitem *item; 820205128Ssimon item = pqueue_pop(s->d1->buffered_app_data.q); 821205128Ssimon if (item) 822205128Ssimon { 823238405Sjkim#ifndef OPENSSL_NO_SCTP 824238405Sjkim /* Restore bio_dgram_sctp_rcvinfo struct */ 825238405Sjkim if (BIO_dgram_is_sctp(SSL_get_rbio(s))) 826238405Sjkim { 827238405Sjkim DTLS1_RECORD_DATA *rdata = (DTLS1_RECORD_DATA *) item->data; 828238405Sjkim BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SCTP_SET_RCVINFO, sizeof(rdata->recordinfo), &rdata->recordinfo); 829238405Sjkim } 830238405Sjkim#endif 831238405Sjkim 832205128Ssimon dtls1_copy_record(s, item); 833205128Ssimon 834205128Ssimon OPENSSL_free(item->data); 835205128Ssimon pitem_free(item); 836205128Ssimon } 837205128Ssimon } 838205128Ssimon 839205128Ssimon /* Check for timeout */ 840205128Ssimon if (dtls1_handle_timeout(s) > 0) 841205128Ssimon goto start; 842205128Ssimon 843160814Ssimon /* get new packet if necessary */ 844160814Ssimon if ((rr->length == 0) || (s->rstate == SSL_ST_READ_BODY)) 845160814Ssimon { 846160814Ssimon ret=dtls1_get_record(s); 847160814Ssimon if (ret <= 0) 848160814Ssimon { 849160814Ssimon ret = dtls1_read_failed(s, ret); 850160814Ssimon /* anything other than a timeout is an error */ 851160814Ssimon if (ret <= 0) 852160814Ssimon return(ret); 853160814Ssimon else 854160814Ssimon goto start; 855160814Ssimon } 856160814Ssimon } 857160814Ssimon 858279264Sdelphij if (s->d1->listen && rr->type != SSL3_RT_HANDSHAKE) 859279264Sdelphij { 860279264Sdelphij rr->length = 0; 861279264Sdelphij goto start; 862279264Sdelphij } 863279264Sdelphij 864160814Ssimon /* we now have a packet which can be read and processed */ 865160814Ssimon 866160814Ssimon if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec, 867160814Ssimon * reset by ssl3_get_finished */ 868160814Ssimon && (rr->type != SSL3_RT_HANDSHAKE)) 869160814Ssimon { 870205128Ssimon /* We now have application data between CCS and Finished. 871205128Ssimon * Most likely the packets were reordered on their way, so 872205128Ssimon * buffer the application data for later processing rather 873205128Ssimon * than dropping the connection. 874205128Ssimon */ 875277195Sdelphij if(dtls1_buffer_record(s, &(s->d1->buffered_app_data), rr->seq_num)<0) 876277195Sdelphij { 877277195Sdelphij SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR); 878277195Sdelphij return -1; 879277195Sdelphij } 880205128Ssimon rr->length = 0; 881205128Ssimon goto start; 882160814Ssimon } 883160814Ssimon 884160814Ssimon /* If the other end has shut down, throw anything we read away 885160814Ssimon * (even in 'peek' mode) */ 886160814Ssimon if (s->shutdown & SSL_RECEIVED_SHUTDOWN) 887160814Ssimon { 888160814Ssimon rr->length=0; 889160814Ssimon s->rwstate=SSL_NOTHING; 890160814Ssimon return(0); 891160814Ssimon } 892160814Ssimon 893160814Ssimon 894160814Ssimon if (type == rr->type) /* SSL3_RT_APPLICATION_DATA or SSL3_RT_HANDSHAKE */ 895160814Ssimon { 896160814Ssimon /* make sure that we are not getting application data when we 897160814Ssimon * are doing a handshake for the first time */ 898160814Ssimon if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) && 899160814Ssimon (s->enc_read_ctx == NULL)) 900160814Ssimon { 901160814Ssimon al=SSL_AD_UNEXPECTED_MESSAGE; 902160814Ssimon SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_APP_DATA_IN_HANDSHAKE); 903160814Ssimon goto f_err; 904160814Ssimon } 905160814Ssimon 906160814Ssimon if (len <= 0) return(len); 907160814Ssimon 908160814Ssimon if ((unsigned int)len > rr->length) 909160814Ssimon n = rr->length; 910160814Ssimon else 911160814Ssimon n = (unsigned int)len; 912160814Ssimon 913160814Ssimon memcpy(buf,&(rr->data[rr->off]),n); 914160814Ssimon if (!peek) 915160814Ssimon { 916160814Ssimon rr->length-=n; 917160814Ssimon rr->off+=n; 918160814Ssimon if (rr->length == 0) 919160814Ssimon { 920160814Ssimon s->rstate=SSL_ST_READ_HEADER; 921160814Ssimon rr->off=0; 922160814Ssimon } 923160814Ssimon } 924238405Sjkim 925238405Sjkim#ifndef OPENSSL_NO_SCTP 926238405Sjkim /* We were about to renegotiate but had to read 927238405Sjkim * belated application data first, so retry. 928238405Sjkim */ 929238405Sjkim if (BIO_dgram_is_sctp(SSL_get_rbio(s)) && 930238405Sjkim rr->type == SSL3_RT_APPLICATION_DATA && 931238405Sjkim (s->state == DTLS1_SCTP_ST_SR_READ_SOCK || s->state == DTLS1_SCTP_ST_CR_READ_SOCK)) 932238405Sjkim { 933238405Sjkim s->rwstate=SSL_READING; 934238405Sjkim BIO_clear_retry_flags(SSL_get_rbio(s)); 935238405Sjkim BIO_set_retry_read(SSL_get_rbio(s)); 936238405Sjkim } 937238405Sjkim 938238405Sjkim /* We might had to delay a close_notify alert because 939238405Sjkim * of reordered app data. If there was an alert and there 940238405Sjkim * is no message to read anymore, finally set shutdown. 941238405Sjkim */ 942238405Sjkim if (BIO_dgram_is_sctp(SSL_get_rbio(s)) && 943238405Sjkim s->d1->shutdown_received && !BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) 944238405Sjkim { 945238405Sjkim s->shutdown |= SSL_RECEIVED_SHUTDOWN; 946238405Sjkim return(0); 947238405Sjkim } 948238405Sjkim#endif 949160814Ssimon return(n); 950160814Ssimon } 951160814Ssimon 952160814Ssimon 953160814Ssimon /* If we get here, then type != rr->type; if we have a handshake 954160814Ssimon * message, then it was unexpected (Hello Request or Client Hello). */ 955160814Ssimon 956160814Ssimon /* In case of record types for which we have 'fragment' storage, 957160814Ssimon * fill that so that we can process the data at a fixed place. 958160814Ssimon */ 959160814Ssimon { 960160814Ssimon unsigned int k, dest_maxlen = 0; 961160814Ssimon unsigned char *dest = NULL; 962160814Ssimon unsigned int *dest_len = NULL; 963160814Ssimon 964160814Ssimon if (rr->type == SSL3_RT_HANDSHAKE) 965160814Ssimon { 966160814Ssimon dest_maxlen = sizeof s->d1->handshake_fragment; 967160814Ssimon dest = s->d1->handshake_fragment; 968160814Ssimon dest_len = &s->d1->handshake_fragment_len; 969160814Ssimon } 970160814Ssimon else if (rr->type == SSL3_RT_ALERT) 971160814Ssimon { 972160814Ssimon dest_maxlen = sizeof(s->d1->alert_fragment); 973160814Ssimon dest = s->d1->alert_fragment; 974160814Ssimon dest_len = &s->d1->alert_fragment_len; 975160814Ssimon } 976238405Sjkim#ifndef OPENSSL_NO_HEARTBEATS 977238405Sjkim else if (rr->type == TLS1_RT_HEARTBEAT) 978238405Sjkim { 979238405Sjkim dtls1_process_heartbeat(s); 980238405Sjkim 981238405Sjkim /* Exit and notify application to read again */ 982238405Sjkim rr->length = 0; 983238405Sjkim s->rwstate=SSL_READING; 984238405Sjkim BIO_clear_retry_flags(SSL_get_rbio(s)); 985238405Sjkim BIO_set_retry_read(SSL_get_rbio(s)); 986238405Sjkim return(-1); 987238405Sjkim } 988238405Sjkim#endif 989205128Ssimon /* else it's a CCS message, or application data or wrong */ 990205128Ssimon else if (rr->type != SSL3_RT_CHANGE_CIPHER_SPEC) 991205128Ssimon { 992205128Ssimon /* Application data while renegotiating 993205128Ssimon * is allowed. Try again reading. 994205128Ssimon */ 995205128Ssimon if (rr->type == SSL3_RT_APPLICATION_DATA) 996205128Ssimon { 997205128Ssimon BIO *bio; 998205128Ssimon s->s3->in_read_app_data=2; 999205128Ssimon bio=SSL_get_rbio(s); 1000205128Ssimon s->rwstate=SSL_READING; 1001205128Ssimon BIO_clear_retry_flags(bio); 1002205128Ssimon BIO_set_retry_read(bio); 1003205128Ssimon return(-1); 1004205128Ssimon } 1005160814Ssimon 1006205128Ssimon /* Not certain if this is the right error handling */ 1007205128Ssimon al=SSL_AD_UNEXPECTED_MESSAGE; 1008205128Ssimon SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNEXPECTED_RECORD); 1009205128Ssimon goto f_err; 1010205128Ssimon } 1011160814Ssimon 1012160814Ssimon if (dest_maxlen > 0) 1013160814Ssimon { 1014160814Ssimon /* XDTLS: In a pathalogical case, the Client Hello 1015160814Ssimon * may be fragmented--don't always expect dest_maxlen bytes */ 1016160814Ssimon if ( rr->length < dest_maxlen) 1017160814Ssimon { 1018194206Ssimon#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE 1019194206Ssimon /* 1020194206Ssimon * for normal alerts rr->length is 2, while 1021194206Ssimon * dest_maxlen is 7 if we were to handle this 1022194206Ssimon * non-existing alert... 1023194206Ssimon */ 1024194206Ssimon FIX ME 1025194206Ssimon#endif 1026160814Ssimon s->rstate=SSL_ST_READ_HEADER; 1027160814Ssimon rr->length = 0; 1028160814Ssimon goto start; 1029160814Ssimon } 1030160814Ssimon 1031160814Ssimon /* now move 'n' bytes: */ 1032160814Ssimon for ( k = 0; k < dest_maxlen; k++) 1033160814Ssimon { 1034160814Ssimon dest[k] = rr->data[rr->off++]; 1035160814Ssimon rr->length--; 1036160814Ssimon } 1037160814Ssimon *dest_len = dest_maxlen; 1038160814Ssimon } 1039160814Ssimon } 1040160814Ssimon 1041160814Ssimon /* s->d1->handshake_fragment_len == 12 iff rr->type == SSL3_RT_HANDSHAKE; 1042160814Ssimon * s->d1->alert_fragment_len == 7 iff rr->type == SSL3_RT_ALERT. 1043160814Ssimon * (Possibly rr is 'empty' now, i.e. rr->length may be 0.) */ 1044160814Ssimon 1045160814Ssimon /* If we are a client, check for an incoming 'Hello Request': */ 1046160814Ssimon if ((!s->server) && 1047160814Ssimon (s->d1->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) && 1048160814Ssimon (s->d1->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) && 1049160814Ssimon (s->session != NULL) && (s->session->cipher != NULL)) 1050160814Ssimon { 1051160814Ssimon s->d1->handshake_fragment_len = 0; 1052160814Ssimon 1053160814Ssimon if ((s->d1->handshake_fragment[1] != 0) || 1054160814Ssimon (s->d1->handshake_fragment[2] != 0) || 1055160814Ssimon (s->d1->handshake_fragment[3] != 0)) 1056160814Ssimon { 1057160814Ssimon al=SSL_AD_DECODE_ERROR; 1058160814Ssimon SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_BAD_HELLO_REQUEST); 1059160814Ssimon goto err; 1060160814Ssimon } 1061160814Ssimon 1062160814Ssimon /* no need to check sequence number on HELLO REQUEST messages */ 1063160814Ssimon 1064160814Ssimon if (s->msg_callback) 1065160814Ssimon s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, 1066160814Ssimon s->d1->handshake_fragment, 4, s, s->msg_callback_arg); 1067160814Ssimon 1068160814Ssimon if (SSL_is_init_finished(s) && 1069160814Ssimon !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) && 1070160814Ssimon !s->s3->renegotiate) 1071160814Ssimon { 1072279264Sdelphij s->d1->handshake_read_seq++; 1073238405Sjkim s->new_session = 1; 1074160814Ssimon ssl3_renegotiate(s); 1075160814Ssimon if (ssl3_renegotiate_check(s)) 1076160814Ssimon { 1077160814Ssimon i=s->handshake_func(s); 1078160814Ssimon if (i < 0) return(i); 1079160814Ssimon if (i == 0) 1080160814Ssimon { 1081160814Ssimon SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE); 1082160814Ssimon return(-1); 1083160814Ssimon } 1084160814Ssimon 1085160814Ssimon if (!(s->mode & SSL_MODE_AUTO_RETRY)) 1086160814Ssimon { 1087160814Ssimon if (s->s3->rbuf.left == 0) /* no read-ahead left? */ 1088160814Ssimon { 1089160814Ssimon BIO *bio; 1090160814Ssimon /* In the case where we try to read application data, 1091160814Ssimon * but we trigger an SSL handshake, we return -1 with 1092160814Ssimon * the retry option set. Otherwise renegotiation may 1093160814Ssimon * cause nasty problems in the blocking world */ 1094160814Ssimon s->rwstate=SSL_READING; 1095160814Ssimon bio=SSL_get_rbio(s); 1096160814Ssimon BIO_clear_retry_flags(bio); 1097160814Ssimon BIO_set_retry_read(bio); 1098160814Ssimon return(-1); 1099160814Ssimon } 1100160814Ssimon } 1101160814Ssimon } 1102160814Ssimon } 1103160814Ssimon /* we either finished a handshake or ignored the request, 1104160814Ssimon * now try again to obtain the (application) data we were asked for */ 1105160814Ssimon goto start; 1106160814Ssimon } 1107160814Ssimon 1108160814Ssimon if (s->d1->alert_fragment_len >= DTLS1_AL_HEADER_LENGTH) 1109160814Ssimon { 1110160814Ssimon int alert_level = s->d1->alert_fragment[0]; 1111160814Ssimon int alert_descr = s->d1->alert_fragment[1]; 1112160814Ssimon 1113160814Ssimon s->d1->alert_fragment_len = 0; 1114160814Ssimon 1115160814Ssimon if (s->msg_callback) 1116160814Ssimon s->msg_callback(0, s->version, SSL3_RT_ALERT, 1117160814Ssimon s->d1->alert_fragment, 2, s, s->msg_callback_arg); 1118160814Ssimon 1119160814Ssimon if (s->info_callback != NULL) 1120160814Ssimon cb=s->info_callback; 1121160814Ssimon else if (s->ctx->info_callback != NULL) 1122160814Ssimon cb=s->ctx->info_callback; 1123160814Ssimon 1124160814Ssimon if (cb != NULL) 1125160814Ssimon { 1126160814Ssimon j = (alert_level << 8) | alert_descr; 1127160814Ssimon cb(s, SSL_CB_READ_ALERT, j); 1128160814Ssimon } 1129160814Ssimon 1130160814Ssimon if (alert_level == 1) /* warning */ 1131160814Ssimon { 1132160814Ssimon s->s3->warn_alert = alert_descr; 1133160814Ssimon if (alert_descr == SSL_AD_CLOSE_NOTIFY) 1134160814Ssimon { 1135238405Sjkim#ifndef OPENSSL_NO_SCTP 1136238405Sjkim /* With SCTP and streams the socket may deliver app data 1137238405Sjkim * after a close_notify alert. We have to check this 1138238405Sjkim * first so that nothing gets discarded. 1139238405Sjkim */ 1140238405Sjkim if (BIO_dgram_is_sctp(SSL_get_rbio(s)) && 1141238405Sjkim BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) 1142238405Sjkim { 1143238405Sjkim s->d1->shutdown_received = 1; 1144238405Sjkim s->rwstate=SSL_READING; 1145238405Sjkim BIO_clear_retry_flags(SSL_get_rbio(s)); 1146238405Sjkim BIO_set_retry_read(SSL_get_rbio(s)); 1147238405Sjkim return -1; 1148238405Sjkim } 1149238405Sjkim#endif 1150160814Ssimon s->shutdown |= SSL_RECEIVED_SHUTDOWN; 1151160814Ssimon return(0); 1152160814Ssimon } 1153160814Ssimon#if 0 1154160814Ssimon /* XXX: this is a possible improvement in the future */ 1155160814Ssimon /* now check if it's a missing record */ 1156160814Ssimon if (alert_descr == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE) 1157160814Ssimon { 1158160814Ssimon unsigned short seq; 1159160814Ssimon unsigned int frag_off; 1160160814Ssimon unsigned char *p = &(s->d1->alert_fragment[2]); 1161160814Ssimon 1162160814Ssimon n2s(p, seq); 1163160814Ssimon n2l3(p, frag_off); 1164160814Ssimon 1165205128Ssimon dtls1_retransmit_message(s, 1166205128Ssimon dtls1_get_queue_priority(frag->msg_header.seq, 0), 1167205128Ssimon frag_off, &found); 1168160814Ssimon if ( ! found && SSL_in_init(s)) 1169160814Ssimon { 1170160814Ssimon /* fprintf( stderr,"in init = %d\n", SSL_in_init(s)); */ 1171160814Ssimon /* requested a message not yet sent, 1172160814Ssimon send an alert ourselves */ 1173160814Ssimon ssl3_send_alert(s,SSL3_AL_WARNING, 1174160814Ssimon DTLS1_AD_MISSING_HANDSHAKE_MESSAGE); 1175160814Ssimon } 1176160814Ssimon } 1177160814Ssimon#endif 1178160814Ssimon } 1179160814Ssimon else if (alert_level == 2) /* fatal */ 1180160814Ssimon { 1181160814Ssimon char tmp[16]; 1182160814Ssimon 1183160814Ssimon s->rwstate=SSL_NOTHING; 1184160814Ssimon s->s3->fatal_alert = alert_descr; 1185160814Ssimon SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_AD_REASON_OFFSET + alert_descr); 1186160814Ssimon BIO_snprintf(tmp,sizeof tmp,"%d",alert_descr); 1187160814Ssimon ERR_add_error_data(2,"SSL alert number ",tmp); 1188160814Ssimon s->shutdown|=SSL_RECEIVED_SHUTDOWN; 1189160814Ssimon SSL_CTX_remove_session(s->ctx,s->session); 1190160814Ssimon return(0); 1191160814Ssimon } 1192160814Ssimon else 1193160814Ssimon { 1194160814Ssimon al=SSL_AD_ILLEGAL_PARAMETER; 1195160814Ssimon SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNKNOWN_ALERT_TYPE); 1196160814Ssimon goto f_err; 1197160814Ssimon } 1198160814Ssimon 1199160814Ssimon goto start; 1200160814Ssimon } 1201160814Ssimon 1202160814Ssimon if (s->shutdown & SSL_SENT_SHUTDOWN) /* but we have not received a shutdown */ 1203160814Ssimon { 1204160814Ssimon s->rwstate=SSL_NOTHING; 1205160814Ssimon rr->length=0; 1206160814Ssimon return(0); 1207160814Ssimon } 1208160814Ssimon 1209160814Ssimon if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) 1210194206Ssimon { 1211194206Ssimon struct ccs_header_st ccs_hdr; 1212205128Ssimon unsigned int ccs_hdr_len = DTLS1_CCS_HEADER_LENGTH; 1213160814Ssimon 1214160814Ssimon dtls1_get_ccs_header(rr->data, &ccs_hdr); 1215160814Ssimon 1216238405Sjkim if (s->version == DTLS1_BAD_VER) 1217238405Sjkim ccs_hdr_len = 3; 1218238405Sjkim 1219194206Ssimon /* 'Change Cipher Spec' is just a single byte, so we know 1220194206Ssimon * exactly what the record payload has to look like */ 1221194206Ssimon /* XDTLS: check that epoch is consistent */ 1222238405Sjkim if ( (rr->length != ccs_hdr_len) || 1223238405Sjkim (rr->off != 0) || (rr->data[0] != SSL3_MT_CCS)) 1224160814Ssimon { 1225194206Ssimon i=SSL_AD_ILLEGAL_PARAMETER; 1226194206Ssimon SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_BAD_CHANGE_CIPHER_SPEC); 1227194206Ssimon goto err; 1228194206Ssimon } 1229194206Ssimon 1230194206Ssimon rr->length=0; 1231194206Ssimon 1232194206Ssimon if (s->msg_callback) 1233194206Ssimon s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, 1234194206Ssimon rr->data, 1, s, s->msg_callback_arg); 1235194206Ssimon 1236205128Ssimon /* We can't process a CCS now, because previous handshake 1237205128Ssimon * messages are still missing, so just drop it. 1238205128Ssimon */ 1239205128Ssimon if (!s->d1->change_cipher_spec_ok) 1240205128Ssimon { 1241205128Ssimon goto start; 1242205128Ssimon } 1243205128Ssimon 1244205128Ssimon s->d1->change_cipher_spec_ok = 0; 1245205128Ssimon 1246194206Ssimon s->s3->change_cipher_spec=1; 1247194206Ssimon if (!ssl3_do_change_cipher_spec(s)) 1248194206Ssimon goto err; 1249194206Ssimon 1250194206Ssimon /* do this whenever CCS is processed */ 1251194206Ssimon dtls1_reset_seq_numbers(s, SSL3_CC_READ); 1252194206Ssimon 1253238405Sjkim if (s->version == DTLS1_BAD_VER) 1254160814Ssimon s->d1->handshake_read_seq++; 1255194206Ssimon 1256238405Sjkim#ifndef OPENSSL_NO_SCTP 1257238405Sjkim /* Remember that a CCS has been received, 1258238405Sjkim * so that an old key of SCTP-Auth can be 1259238405Sjkim * deleted when a CCS is sent. Will be ignored 1260238405Sjkim * if no SCTP is used 1261238405Sjkim */ 1262238405Sjkim BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD, 1, NULL); 1263238405Sjkim#endif 1264238405Sjkim 1265194206Ssimon goto start; 1266160814Ssimon } 1267160814Ssimon 1268160814Ssimon /* Unexpected handshake message (Client Hello, or protocol violation) */ 1269160814Ssimon if ((s->d1->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) && 1270160814Ssimon !s->in_handshake) 1271160814Ssimon { 1272160814Ssimon struct hm_header_st msg_hdr; 1273160814Ssimon 1274160814Ssimon /* this may just be a stale retransmit */ 1275160814Ssimon dtls1_get_message_header(rr->data, &msg_hdr); 1276160814Ssimon if( rr->epoch != s->d1->r_epoch) 1277160814Ssimon { 1278160814Ssimon rr->length = 0; 1279160814Ssimon goto start; 1280160814Ssimon } 1281160814Ssimon 1282205128Ssimon /* If we are server, we may have a repeated FINISHED of the 1283205128Ssimon * client here, then retransmit our CCS and FINISHED. 1284205128Ssimon */ 1285205128Ssimon if (msg_hdr.type == SSL3_MT_FINISHED) 1286205128Ssimon { 1287237657Sjkim if (dtls1_check_timeout_num(s) < 0) 1288237657Sjkim return -1; 1289237657Sjkim 1290205128Ssimon dtls1_retransmit_buffered_messages(s); 1291205128Ssimon rr->length = 0; 1292205128Ssimon goto start; 1293205128Ssimon } 1294205128Ssimon 1295160814Ssimon if (((s->state&SSL_ST_MASK) == SSL_ST_OK) && 1296160814Ssimon !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) 1297160814Ssimon { 1298160814Ssimon#if 0 /* worked only because C operator preferences are not as expected (and 1299160814Ssimon * because this is not really needed for clients except for detecting 1300160814Ssimon * protocol violations): */ 1301160814Ssimon s->state=SSL_ST_BEFORE|(s->server) 1302160814Ssimon ?SSL_ST_ACCEPT 1303160814Ssimon :SSL_ST_CONNECT; 1304160814Ssimon#else 1305160814Ssimon s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT; 1306160814Ssimon#endif 1307238405Sjkim s->renegotiate=1; 1308160814Ssimon s->new_session=1; 1309160814Ssimon } 1310160814Ssimon i=s->handshake_func(s); 1311160814Ssimon if (i < 0) return(i); 1312160814Ssimon if (i == 0) 1313160814Ssimon { 1314160814Ssimon SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE); 1315160814Ssimon return(-1); 1316160814Ssimon } 1317160814Ssimon 1318160814Ssimon if (!(s->mode & SSL_MODE_AUTO_RETRY)) 1319160814Ssimon { 1320160814Ssimon if (s->s3->rbuf.left == 0) /* no read-ahead left? */ 1321160814Ssimon { 1322160814Ssimon BIO *bio; 1323160814Ssimon /* In the case where we try to read application data, 1324160814Ssimon * but we trigger an SSL handshake, we return -1 with 1325160814Ssimon * the retry option set. Otherwise renegotiation may 1326160814Ssimon * cause nasty problems in the blocking world */ 1327160814Ssimon s->rwstate=SSL_READING; 1328160814Ssimon bio=SSL_get_rbio(s); 1329160814Ssimon BIO_clear_retry_flags(bio); 1330160814Ssimon BIO_set_retry_read(bio); 1331160814Ssimon return(-1); 1332160814Ssimon } 1333160814Ssimon } 1334160814Ssimon goto start; 1335160814Ssimon } 1336160814Ssimon 1337160814Ssimon switch (rr->type) 1338160814Ssimon { 1339160814Ssimon default: 1340160814Ssimon#ifndef OPENSSL_NO_TLS 1341160814Ssimon /* TLS just ignores unknown message types */ 1342160814Ssimon if (s->version == TLS1_VERSION) 1343160814Ssimon { 1344160814Ssimon rr->length = 0; 1345160814Ssimon goto start; 1346160814Ssimon } 1347160814Ssimon#endif 1348160814Ssimon al=SSL_AD_UNEXPECTED_MESSAGE; 1349160814Ssimon SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNEXPECTED_RECORD); 1350160814Ssimon goto f_err; 1351160814Ssimon case SSL3_RT_CHANGE_CIPHER_SPEC: 1352160814Ssimon case SSL3_RT_ALERT: 1353160814Ssimon case SSL3_RT_HANDSHAKE: 1354160814Ssimon /* we already handled all of these, with the possible exception 1355160814Ssimon * of SSL3_RT_HANDSHAKE when s->in_handshake is set, but that 1356160814Ssimon * should not happen when type != rr->type */ 1357160814Ssimon al=SSL_AD_UNEXPECTED_MESSAGE; 1358160814Ssimon SSLerr(SSL_F_DTLS1_READ_BYTES,ERR_R_INTERNAL_ERROR); 1359160814Ssimon goto f_err; 1360160814Ssimon case SSL3_RT_APPLICATION_DATA: 1361160814Ssimon /* At this point, we were expecting handshake data, 1362160814Ssimon * but have application data. If the library was 1363160814Ssimon * running inside ssl3_read() (i.e. in_read_app_data 1364160814Ssimon * is set) and it makes sense to read application data 1365160814Ssimon * at this point (session renegotiation not yet started), 1366160814Ssimon * we will indulge it. 1367160814Ssimon */ 1368160814Ssimon if (s->s3->in_read_app_data && 1369160814Ssimon (s->s3->total_renegotiations != 0) && 1370160814Ssimon (( 1371160814Ssimon (s->state & SSL_ST_CONNECT) && 1372160814Ssimon (s->state >= SSL3_ST_CW_CLNT_HELLO_A) && 1373160814Ssimon (s->state <= SSL3_ST_CR_SRVR_HELLO_A) 1374160814Ssimon ) || ( 1375160814Ssimon (s->state & SSL_ST_ACCEPT) && 1376160814Ssimon (s->state <= SSL3_ST_SW_HELLO_REQ_A) && 1377160814Ssimon (s->state >= SSL3_ST_SR_CLNT_HELLO_A) 1378160814Ssimon ) 1379160814Ssimon )) 1380160814Ssimon { 1381160814Ssimon s->s3->in_read_app_data=2; 1382160814Ssimon return(-1); 1383160814Ssimon } 1384160814Ssimon else 1385160814Ssimon { 1386160814Ssimon al=SSL_AD_UNEXPECTED_MESSAGE; 1387160814Ssimon SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNEXPECTED_RECORD); 1388160814Ssimon goto f_err; 1389160814Ssimon } 1390160814Ssimon } 1391160814Ssimon /* not reached */ 1392160814Ssimon 1393160814Ssimonf_err: 1394160814Ssimon ssl3_send_alert(s,SSL3_AL_FATAL,al); 1395160814Ssimonerr: 1396160814Ssimon return(-1); 1397160814Ssimon } 1398160814Ssimon 1399160814Ssimonint 1400160814Ssimondtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, int len) 1401160814Ssimon { 1402160814Ssimon int i; 1403160814Ssimon 1404238405Sjkim#ifndef OPENSSL_NO_SCTP 1405238405Sjkim /* Check if we have to continue an interrupted handshake 1406238405Sjkim * for reading belated app data with SCTP. 1407238405Sjkim */ 1408238405Sjkim if ((SSL_in_init(s) && !s->in_handshake) || 1409238405Sjkim (BIO_dgram_is_sctp(SSL_get_wbio(s)) && 1410238405Sjkim (s->state == DTLS1_SCTP_ST_SR_READ_SOCK || s->state == DTLS1_SCTP_ST_CR_READ_SOCK))) 1411238405Sjkim#else 1412238405Sjkim if (SSL_in_init(s) && !s->in_handshake) 1413238405Sjkim#endif 1414160814Ssimon { 1415160814Ssimon i=s->handshake_func(s); 1416160814Ssimon if (i < 0) return(i); 1417160814Ssimon if (i == 0) 1418160814Ssimon { 1419160814Ssimon SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE); 1420160814Ssimon return -1; 1421160814Ssimon } 1422160814Ssimon } 1423160814Ssimon 1424205128Ssimon if (len > SSL3_RT_MAX_PLAIN_LENGTH) 1425160814Ssimon { 1426205128Ssimon SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES,SSL_R_DTLS_MESSAGE_TOO_BIG); 1427205128Ssimon return -1; 1428160814Ssimon } 1429160814Ssimon 1430205128Ssimon i = dtls1_write_bytes(s, type, buf_, len); 1431205128Ssimon return i; 1432160814Ssimon } 1433160814Ssimon 1434160814Ssimon 1435160814Ssimon /* this only happens when a client hello is received and a handshake 1436160814Ssimon * is started. */ 1437160814Ssimonstatic int 1438160814Ssimonhave_handshake_fragment(SSL *s, int type, unsigned char *buf, 1439160814Ssimon int len, int peek) 1440160814Ssimon { 1441160814Ssimon 1442160814Ssimon if ((type == SSL3_RT_HANDSHAKE) && (s->d1->handshake_fragment_len > 0)) 1443160814Ssimon /* (partially) satisfy request from storage */ 1444160814Ssimon { 1445160814Ssimon unsigned char *src = s->d1->handshake_fragment; 1446160814Ssimon unsigned char *dst = buf; 1447160814Ssimon unsigned int k,n; 1448160814Ssimon 1449160814Ssimon /* peek == 0 */ 1450160814Ssimon n = 0; 1451160814Ssimon while ((len > 0) && (s->d1->handshake_fragment_len > 0)) 1452160814Ssimon { 1453160814Ssimon *dst++ = *src++; 1454160814Ssimon len--; s->d1->handshake_fragment_len--; 1455160814Ssimon n++; 1456160814Ssimon } 1457160814Ssimon /* move any remaining fragment bytes: */ 1458160814Ssimon for (k = 0; k < s->d1->handshake_fragment_len; k++) 1459160814Ssimon s->d1->handshake_fragment[k] = *src++; 1460160814Ssimon return n; 1461160814Ssimon } 1462160814Ssimon 1463160814Ssimon return 0; 1464160814Ssimon } 1465160814Ssimon 1466160814Ssimon 1467160814Ssimon 1468160814Ssimon 1469160814Ssimon/* Call this to write data in records of type 'type' 1470160814Ssimon * It will return <= 0 if not all data has been sent or non-blocking IO. 1471160814Ssimon */ 1472205128Ssimonint dtls1_write_bytes(SSL *s, int type, const void *buf, int len) 1473160814Ssimon { 1474160814Ssimon int i; 1475160814Ssimon 1476205128Ssimon OPENSSL_assert(len <= SSL3_RT_MAX_PLAIN_LENGTH); 1477160814Ssimon s->rwstate=SSL_NOTHING; 1478205128Ssimon i=do_dtls1_write(s, type, buf, len, 0); 1479194206Ssimon return i; 1480160814Ssimon } 1481160814Ssimon 1482160814Ssimonint do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len, int create_empty_fragment) 1483160814Ssimon { 1484160814Ssimon unsigned char *p,*pseq; 1485160814Ssimon int i,mac_size,clear=0; 1486160814Ssimon int prefix_len = 0; 1487160814Ssimon SSL3_RECORD *wr; 1488160814Ssimon SSL3_BUFFER *wb; 1489160814Ssimon SSL_SESSION *sess; 1490160814Ssimon int bs; 1491160814Ssimon 1492160814Ssimon /* first check if there is a SSL3_BUFFER still being written 1493160814Ssimon * out. This will happen with non blocking IO */ 1494160814Ssimon if (s->s3->wbuf.left != 0) 1495160814Ssimon { 1496160814Ssimon OPENSSL_assert(0); /* XDTLS: want to see if we ever get here */ 1497160814Ssimon return(ssl3_write_pending(s,type,buf,len)); 1498160814Ssimon } 1499160814Ssimon 1500160814Ssimon /* If we have an alert to send, lets send it */ 1501160814Ssimon if (s->s3->alert_dispatch) 1502160814Ssimon { 1503160814Ssimon i=s->method->ssl_dispatch_alert(s); 1504160814Ssimon if (i <= 0) 1505160814Ssimon return(i); 1506160814Ssimon /* if it went, fall through and send more stuff */ 1507160814Ssimon } 1508160814Ssimon 1509160814Ssimon if (len == 0 && !create_empty_fragment) 1510160814Ssimon return 0; 1511160814Ssimon 1512160814Ssimon wr= &(s->s3->wrec); 1513160814Ssimon wb= &(s->s3->wbuf); 1514160814Ssimon sess=s->session; 1515160814Ssimon 1516160814Ssimon if ( (sess == NULL) || 1517160814Ssimon (s->enc_write_ctx == NULL) || 1518238405Sjkim (EVP_MD_CTX_md(s->write_hash) == NULL)) 1519160814Ssimon clear=1; 1520160814Ssimon 1521160814Ssimon if (clear) 1522160814Ssimon mac_size=0; 1523160814Ssimon else 1524238405Sjkim { 1525238405Sjkim mac_size=EVP_MD_CTX_size(s->write_hash); 1526238405Sjkim if (mac_size < 0) 1527238405Sjkim goto err; 1528238405Sjkim } 1529160814Ssimon 1530160814Ssimon /* DTLS implements explicit IV, so no need for empty fragments */ 1531160814Ssimon#if 0 1532160814Ssimon /* 'create_empty_fragment' is true only when this function calls itself */ 1533160814Ssimon if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done 1534205128Ssimon && SSL_version(s) != DTLS1_VERSION && SSL_version(s) != DTLS1_BAD_VER) 1535160814Ssimon { 1536160814Ssimon /* countermeasure against known-IV weakness in CBC ciphersuites 1537160814Ssimon * (see http://www.openssl.org/~bodo/tls-cbc.txt) 1538160814Ssimon */ 1539160814Ssimon 1540160814Ssimon if (s->s3->need_empty_fragments && type == SSL3_RT_APPLICATION_DATA) 1541160814Ssimon { 1542160814Ssimon /* recursive function call with 'create_empty_fragment' set; 1543160814Ssimon * this prepares and buffers the data for an empty fragment 1544160814Ssimon * (these 'prefix_len' bytes are sent out later 1545160814Ssimon * together with the actual payload) */ 1546160814Ssimon prefix_len = s->method->do_ssl_write(s, type, buf, 0, 1); 1547160814Ssimon if (prefix_len <= 0) 1548160814Ssimon goto err; 1549160814Ssimon 1550160814Ssimon if (s->s3->wbuf.len < (size_t)prefix_len + SSL3_RT_MAX_PACKET_SIZE) 1551160814Ssimon { 1552160814Ssimon /* insufficient space */ 1553160814Ssimon SSLerr(SSL_F_DO_DTLS1_WRITE, ERR_R_INTERNAL_ERROR); 1554160814Ssimon goto err; 1555160814Ssimon } 1556160814Ssimon } 1557160814Ssimon 1558160814Ssimon s->s3->empty_fragment_done = 1; 1559160814Ssimon } 1560160814Ssimon#endif 1561160814Ssimon p = wb->buf + prefix_len; 1562160814Ssimon 1563160814Ssimon /* write the header */ 1564160814Ssimon 1565160814Ssimon *(p++)=type&0xff; 1566160814Ssimon wr->type=type; 1567160814Ssimon 1568238405Sjkim *(p++)=(s->version>>8); 1569238405Sjkim *(p++)=s->version&0xff; 1570160814Ssimon 1571160814Ssimon /* field where we are to write out packet epoch, seq num and len */ 1572160814Ssimon pseq=p; 1573160814Ssimon p+=10; 1574160814Ssimon 1575160814Ssimon /* lets setup the record stuff. */ 1576160814Ssimon 1577160814Ssimon /* Make space for the explicit IV in case of CBC. 1578160814Ssimon * (this is a bit of a boundary violation, but what the heck). 1579160814Ssimon */ 1580160814Ssimon if ( s->enc_write_ctx && 1581160814Ssimon (EVP_CIPHER_mode( s->enc_write_ctx->cipher ) & EVP_CIPH_CBC_MODE)) 1582160814Ssimon bs = EVP_CIPHER_block_size(s->enc_write_ctx->cipher); 1583160814Ssimon else 1584160814Ssimon bs = 0; 1585160814Ssimon 1586160814Ssimon wr->data=p + bs; /* make room for IV in case of CBC */ 1587160814Ssimon wr->length=(int)len; 1588160814Ssimon wr->input=(unsigned char *)buf; 1589160814Ssimon 1590160814Ssimon /* we now 'read' from wr->input, wr->length bytes into 1591160814Ssimon * wr->data */ 1592160814Ssimon 1593160814Ssimon /* first we compress */ 1594160814Ssimon if (s->compress != NULL) 1595160814Ssimon { 1596160814Ssimon if (!ssl3_do_compress(s)) 1597160814Ssimon { 1598160814Ssimon SSLerr(SSL_F_DO_DTLS1_WRITE,SSL_R_COMPRESSION_FAILURE); 1599160814Ssimon goto err; 1600160814Ssimon } 1601160814Ssimon } 1602160814Ssimon else 1603160814Ssimon { 1604160814Ssimon memcpy(wr->data,wr->input,wr->length); 1605160814Ssimon wr->input=wr->data; 1606160814Ssimon } 1607160814Ssimon 1608160814Ssimon /* we should still have the output to wr->data and the input 1609160814Ssimon * from wr->input. Length should be wr->length. 1610160814Ssimon * wr->data still points in the wb->buf */ 1611160814Ssimon 1612160814Ssimon if (mac_size != 0) 1613160814Ssimon { 1614238405Sjkim if(s->method->ssl3_enc->mac(s,&(p[wr->length + bs]),1) < 0) 1615238405Sjkim goto err; 1616160814Ssimon wr->length+=mac_size; 1617160814Ssimon } 1618160814Ssimon 1619160814Ssimon /* this is true regardless of mac size */ 1620160814Ssimon wr->input=p; 1621160814Ssimon wr->data=p; 1622160814Ssimon 1623160814Ssimon 1624160814Ssimon /* ssl3_enc can only have an error on read */ 1625194206Ssimon if (bs) /* bs != 0 in case of CBC */ 1626194206Ssimon { 1627194206Ssimon RAND_pseudo_bytes(p,bs); 1628194206Ssimon /* master IV and last CBC residue stand for 1629194206Ssimon * the rest of randomness */ 1630194206Ssimon wr->length += bs; 1631194206Ssimon } 1632194206Ssimon 1633279264Sdelphij if(s->method->ssl3_enc->enc(s,1) < 1) goto err; 1634160814Ssimon 1635160814Ssimon /* record length after mac and block padding */ 1636160814Ssimon/* if (type == SSL3_RT_APPLICATION_DATA || 1637160814Ssimon (type == SSL3_RT_ALERT && ! SSL_in_init(s))) */ 1638160814Ssimon 1639160814Ssimon /* there's only one epoch between handshake and app data */ 1640160814Ssimon 1641160814Ssimon s2n(s->d1->w_epoch, pseq); 1642160814Ssimon 1643160814Ssimon /* XDTLS: ?? */ 1644160814Ssimon/* else 1645160814Ssimon s2n(s->d1->handshake_epoch, pseq); */ 1646160814Ssimon 1647160814Ssimon memcpy(pseq, &(s->s3->write_sequence[2]), 6); 1648160814Ssimon pseq+=6; 1649160814Ssimon s2n(wr->length,pseq); 1650160814Ssimon 1651160814Ssimon /* we should now have 1652160814Ssimon * wr->data pointing to the encrypted data, which is 1653160814Ssimon * wr->length long */ 1654160814Ssimon wr->type=type; /* not needed but helps for debugging */ 1655160814Ssimon wr->length+=DTLS1_RT_HEADER_LENGTH; 1656160814Ssimon 1657160814Ssimon#if 0 /* this is now done at the message layer */ 1658160814Ssimon /* buffer the record, making it easy to handle retransmits */ 1659160814Ssimon if ( type == SSL3_RT_HANDSHAKE || type == SSL3_RT_CHANGE_CIPHER_SPEC) 1660160814Ssimon dtls1_buffer_record(s, wr->data, wr->length, 1661160814Ssimon *((PQ_64BIT *)&(s->s3->write_sequence[0]))); 1662160814Ssimon#endif 1663160814Ssimon 1664160814Ssimon ssl3_record_sequence_update(&(s->s3->write_sequence[0])); 1665160814Ssimon 1666160814Ssimon if (create_empty_fragment) 1667160814Ssimon { 1668160814Ssimon /* we are in a recursive call; 1669160814Ssimon * just return the length, don't write out anything here 1670160814Ssimon */ 1671160814Ssimon return wr->length; 1672160814Ssimon } 1673160814Ssimon 1674160814Ssimon /* now let's set up wb */ 1675160814Ssimon wb->left = prefix_len + wr->length; 1676160814Ssimon wb->offset = 0; 1677160814Ssimon 1678160814Ssimon /* memorize arguments so that ssl3_write_pending can detect bad write retries later */ 1679160814Ssimon s->s3->wpend_tot=len; 1680160814Ssimon s->s3->wpend_buf=buf; 1681160814Ssimon s->s3->wpend_type=type; 1682160814Ssimon s->s3->wpend_ret=len; 1683160814Ssimon 1684160814Ssimon /* we now just need to write the buffer */ 1685160814Ssimon return ssl3_write_pending(s,type,buf,len); 1686160814Ssimonerr: 1687160814Ssimon return -1; 1688160814Ssimon } 1689160814Ssimon 1690160814Ssimon 1691160814Ssimon 1692238405Sjkimstatic int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap) 1693160814Ssimon { 1694238405Sjkim int cmp; 1695238405Sjkim unsigned int shift; 1696238405Sjkim const unsigned char *seq = s->s3->read_sequence; 1697160814Ssimon 1698238405Sjkim cmp = satsub64be(seq,bitmap->max_seq_num); 1699238405Sjkim if (cmp > 0) 1700160814Ssimon { 1701238405Sjkim memcpy (s->s3->rrec.seq_num,seq,8); 1702238405Sjkim return 1; /* this record in new */ 1703160814Ssimon } 1704238405Sjkim shift = -cmp; 1705238405Sjkim if (shift >= sizeof(bitmap->map)*8) 1706238405Sjkim return 0; /* stale, outside the window */ 1707238405Sjkim else if (bitmap->map & (1UL<<shift)) 1708238405Sjkim return 0; /* record previously received */ 1709160814Ssimon 1710238405Sjkim memcpy (s->s3->rrec.seq_num,seq,8); 1711160814Ssimon return 1; 1712160814Ssimon } 1713160814Ssimon 1714160814Ssimon 1715160814Ssimonstatic void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap) 1716160814Ssimon { 1717238405Sjkim int cmp; 1718160814Ssimon unsigned int shift; 1719238405Sjkim const unsigned char *seq = s->s3->read_sequence; 1720160814Ssimon 1721238405Sjkim cmp = satsub64be(seq,bitmap->max_seq_num); 1722238405Sjkim if (cmp > 0) 1723160814Ssimon { 1724238405Sjkim shift = cmp; 1725238405Sjkim if (shift < sizeof(bitmap->map)*8) 1726238405Sjkim bitmap->map <<= shift, bitmap->map |= 1UL; 1727238405Sjkim else 1728238405Sjkim bitmap->map = 1UL; 1729238405Sjkim memcpy(bitmap->max_seq_num,seq,8); 1730160814Ssimon } 1731238405Sjkim else { 1732238405Sjkim shift = -cmp; 1733238405Sjkim if (shift < sizeof(bitmap->map)*8) 1734238405Sjkim bitmap->map |= 1UL<<shift; 1735160814Ssimon } 1736160814Ssimon } 1737160814Ssimon 1738160814Ssimon 1739160814Ssimonint dtls1_dispatch_alert(SSL *s) 1740160814Ssimon { 1741160814Ssimon int i,j; 1742160814Ssimon void (*cb)(const SSL *ssl,int type,int val)=NULL; 1743194206Ssimon unsigned char buf[DTLS1_AL_HEADER_LENGTH]; 1744160814Ssimon unsigned char *ptr = &buf[0]; 1745160814Ssimon 1746160814Ssimon s->s3->alert_dispatch=0; 1747160814Ssimon 1748160814Ssimon memset(buf, 0x00, sizeof(buf)); 1749160814Ssimon *ptr++ = s->s3->send_alert[0]; 1750160814Ssimon *ptr++ = s->s3->send_alert[1]; 1751160814Ssimon 1752194206Ssimon#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE 1753160814Ssimon if (s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE) 1754160814Ssimon { 1755160814Ssimon s2n(s->d1->handshake_read_seq, ptr); 1756160814Ssimon#if 0 1757160814Ssimon if ( s->d1->r_msg_hdr.frag_off == 0) /* waiting for a new msg */ 1758160814Ssimon 1759160814Ssimon else 1760160814Ssimon s2n(s->d1->r_msg_hdr.seq, ptr); /* partial msg read */ 1761160814Ssimon#endif 1762160814Ssimon 1763160814Ssimon#if 0 1764160814Ssimon fprintf(stderr, "s->d1->handshake_read_seq = %d, s->d1->r_msg_hdr.seq = %d\n",s->d1->handshake_read_seq,s->d1->r_msg_hdr.seq); 1765160814Ssimon#endif 1766160814Ssimon l2n3(s->d1->r_msg_hdr.frag_off, ptr); 1767160814Ssimon } 1768194206Ssimon#endif 1769160814Ssimon 1770160814Ssimon i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf), 0); 1771160814Ssimon if (i <= 0) 1772160814Ssimon { 1773160814Ssimon s->s3->alert_dispatch=1; 1774160814Ssimon /* fprintf( stderr, "not done with alert\n" ); */ 1775160814Ssimon } 1776160814Ssimon else 1777160814Ssimon { 1778194206Ssimon if (s->s3->send_alert[0] == SSL3_AL_FATAL 1779194206Ssimon#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE 1780194206Ssimon || s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE 1781194206Ssimon#endif 1782238405Sjkim ) 1783160814Ssimon (void)BIO_flush(s->wbio); 1784160814Ssimon 1785160814Ssimon if (s->msg_callback) 1786160814Ssimon s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert, 1787160814Ssimon 2, s, s->msg_callback_arg); 1788160814Ssimon 1789160814Ssimon if (s->info_callback != NULL) 1790160814Ssimon cb=s->info_callback; 1791160814Ssimon else if (s->ctx->info_callback != NULL) 1792160814Ssimon cb=s->ctx->info_callback; 1793160814Ssimon 1794160814Ssimon if (cb != NULL) 1795160814Ssimon { 1796160814Ssimon j=(s->s3->send_alert[0]<<8)|s->s3->send_alert[1]; 1797160814Ssimon cb(s,SSL_CB_WRITE_ALERT,j); 1798160814Ssimon } 1799160814Ssimon } 1800160814Ssimon return(i); 1801160814Ssimon } 1802160814Ssimon 1803160814Ssimon 1804160814Ssimonstatic DTLS1_BITMAP * 1805160814Ssimondtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, unsigned int *is_next_epoch) 1806160814Ssimon { 1807160814Ssimon 1808160814Ssimon *is_next_epoch = 0; 1809160814Ssimon 1810160814Ssimon /* In current epoch, accept HM, CCS, DATA, & ALERT */ 1811160814Ssimon if (rr->epoch == s->d1->r_epoch) 1812160814Ssimon return &s->d1->bitmap; 1813160814Ssimon 1814160814Ssimon /* Only HM and ALERT messages can be from the next epoch */ 1815160814Ssimon else if (rr->epoch == (unsigned long)(s->d1->r_epoch + 1) && 1816160814Ssimon (rr->type == SSL3_RT_HANDSHAKE || 1817160814Ssimon rr->type == SSL3_RT_ALERT)) 1818160814Ssimon { 1819160814Ssimon *is_next_epoch = 1; 1820160814Ssimon return &s->d1->next_bitmap; 1821160814Ssimon } 1822160814Ssimon 1823160814Ssimon return NULL; 1824160814Ssimon } 1825160814Ssimon 1826160814Ssimon#if 0 1827160814Ssimonstatic int 1828160814Ssimondtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr, unsigned short *priority, 1829160814Ssimon unsigned long *offset) 1830160814Ssimon { 1831160814Ssimon 1832160814Ssimon /* alerts are passed up immediately */ 1833160814Ssimon if ( rr->type == SSL3_RT_APPLICATION_DATA || 1834160814Ssimon rr->type == SSL3_RT_ALERT) 1835160814Ssimon return 0; 1836160814Ssimon 1837160814Ssimon /* Only need to buffer if a handshake is underway. 1838160814Ssimon * (this implies that Hello Request and Client Hello are passed up 1839160814Ssimon * immediately) */ 1840160814Ssimon if ( SSL_in_init(s)) 1841160814Ssimon { 1842160814Ssimon unsigned char *data = rr->data; 1843160814Ssimon /* need to extract the HM/CCS sequence number here */ 1844160814Ssimon if ( rr->type == SSL3_RT_HANDSHAKE || 1845160814Ssimon rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) 1846160814Ssimon { 1847160814Ssimon unsigned short seq_num; 1848160814Ssimon struct hm_header_st msg_hdr; 1849160814Ssimon struct ccs_header_st ccs_hdr; 1850160814Ssimon 1851160814Ssimon if ( rr->type == SSL3_RT_HANDSHAKE) 1852160814Ssimon { 1853160814Ssimon dtls1_get_message_header(data, &msg_hdr); 1854160814Ssimon seq_num = msg_hdr.seq; 1855160814Ssimon *offset = msg_hdr.frag_off; 1856160814Ssimon } 1857160814Ssimon else 1858160814Ssimon { 1859160814Ssimon dtls1_get_ccs_header(data, &ccs_hdr); 1860160814Ssimon seq_num = ccs_hdr.seq; 1861160814Ssimon *offset = 0; 1862160814Ssimon } 1863160814Ssimon 1864160814Ssimon /* this is either a record we're waiting for, or a 1865160814Ssimon * retransmit of something we happened to previously 1866160814Ssimon * receive (higher layers will drop the repeat silently */ 1867160814Ssimon if ( seq_num < s->d1->handshake_read_seq) 1868160814Ssimon return 0; 1869160814Ssimon if (rr->type == SSL3_RT_HANDSHAKE && 1870160814Ssimon seq_num == s->d1->handshake_read_seq && 1871160814Ssimon msg_hdr.frag_off < s->d1->r_msg_hdr.frag_off) 1872160814Ssimon return 0; 1873160814Ssimon else if ( seq_num == s->d1->handshake_read_seq && 1874160814Ssimon (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC || 1875160814Ssimon msg_hdr.frag_off == s->d1->r_msg_hdr.frag_off)) 1876160814Ssimon return 0; 1877160814Ssimon else 1878160814Ssimon { 1879160814Ssimon *priority = seq_num; 1880160814Ssimon return 1; 1881160814Ssimon } 1882160814Ssimon } 1883160814Ssimon else /* unknown record type */ 1884160814Ssimon return 0; 1885160814Ssimon } 1886160814Ssimon 1887160814Ssimon return 0; 1888160814Ssimon } 1889160814Ssimon#endif 1890160814Ssimon 1891160814Ssimonvoid 1892160814Ssimondtls1_reset_seq_numbers(SSL *s, int rw) 1893160814Ssimon { 1894160814Ssimon unsigned char *seq; 1895160814Ssimon unsigned int seq_bytes = sizeof(s->s3->read_sequence); 1896160814Ssimon 1897160814Ssimon if ( rw & SSL3_CC_READ) 1898160814Ssimon { 1899160814Ssimon seq = s->s3->read_sequence; 1900160814Ssimon s->d1->r_epoch++; 1901238405Sjkim memcpy(&(s->d1->bitmap), &(s->d1->next_bitmap), sizeof(DTLS1_BITMAP)); 1902160814Ssimon memset(&(s->d1->next_bitmap), 0x00, sizeof(DTLS1_BITMAP)); 1903160814Ssimon } 1904160814Ssimon else 1905160814Ssimon { 1906160814Ssimon seq = s->s3->write_sequence; 1907205128Ssimon memcpy(s->d1->last_write_sequence, seq, sizeof(s->s3->write_sequence)); 1908160814Ssimon s->d1->w_epoch++; 1909160814Ssimon } 1910160814Ssimon 1911160814Ssimon memset(seq, 0x00, seq_bytes); 1912160814Ssimon } 1913