X-Git-Url: https://git.openssl.org/?a=blobdiff_plain;f=ssl%2Fd1_pkt.c;h=41e4cfa77e2418e566648b61946767f9366628e7;hb=aae3233e1e08e9f11742f8f351af5c98cd8add16;hp=8ace79a8acc6f412e28aafbc461cffcd5d6fc743;hpb=b60b9e7afe649a564db13dbf10ca571e973844c1;p=openssl.git diff --git a/ssl/d1_pkt.c b/ssl/d1_pkt.c index 8ace79a8ac..41e4cfa77e 100644 --- a/ssl/d1_pkt.c +++ b/ssl/d1_pkt.c @@ -212,7 +212,7 @@ dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority) /* Limit the size of the queue to prevent DOS attacks */ if (pqueue_size(queue->q) >= 100) return 0; - + rdata = OPENSSL_malloc(sizeof(DTLS1_RECORD_DATA)); item = pitem_new(priority, rdata); if (rdata == NULL || item == NULL) @@ -239,14 +239,6 @@ dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority) } #endif - /* insert should not fail, since duplicates are dropped */ - if (pqueue_insert(queue->q, item) == NULL) - { - OPENSSL_free(rdata); - pitem_free(item); - return(0); - } - s->packet = NULL; s->packet_length = 0; memset(&(s->s3->rbuf), 0, sizeof(SSL3_BUFFER)); @@ -255,11 +247,24 @@ dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority) if (!ssl3_setup_buffers(s)) { SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR); + if (rdata->rbuf.buf != NULL) + OPENSSL_free(rdata->rbuf.buf); OPENSSL_free(rdata); pitem_free(item); - return(0); + return(-1); } - + + /* insert should not fail, since duplicates are dropped */ + if (pqueue_insert(queue->q, item) == NULL) + { + SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR); + if (rdata->rbuf.buf != NULL) + OPENSSL_free(rdata->rbuf.buf); + OPENSSL_free(rdata); + pitem_free(item); + return(-1); + } + return(1); } @@ -313,8 +318,9 @@ dtls1_process_buffered_records(SSL *s) dtls1_get_unprocessed_record(s); if ( ! dtls1_process_record(s)) return(0); - dtls1_buffer_record(s, &(s->d1->processed_rcds), - s->s3->rrec.seq_num); + if(dtls1_buffer_record(s, &(s->d1->processed_rcds), + s->s3->rrec.seq_num)<0) + return -1; } } @@ -337,8 +343,8 @@ dtls1_get_buffered_record(SSL *s) (((PQ_64BIT)s->d1->handshake_read_seq) << 32) | ((PQ_64BIT)s->d1->r_msg_hdr.frag_off); - if ( ! SSL_in_init(s)) /* if we're not (re)negotiating, - nothing buffered */ + /* if we're not (re)negotiating, nothing buffered */ + if ( ! SSL_in_init(s)) return 0; @@ -412,10 +418,12 @@ dtls1_process_record(SSL *s) rr->data=rr->input; enc_err = s->method->ssl3_enc->enc(s,0); - /* enc_err is: + /*- + * enc_err is: * 0: (in non-constant time) if the record is publically invalid. * 1: if the padding is valid - * -1: if the padding is invalid */ + * -1: if the padding is invalid + */ if (enc_err == 0) { /* For DTLS we simply ignore bad packets. */ @@ -519,7 +527,8 @@ printf("\n"); } rr->off=0; - /* So at this point the following is true + /*- + * So at this point the following is true * ssl->s3->rrec.type is the type of record * ssl->s3->rrec.length == number of bytes in record * ssl->s3->rrec.off == offset to first valid byte @@ -529,7 +538,6 @@ printf("\n"); /* we have pulled in a full packet so zero things */ s->packet_length=0; - dtls1_record_bitmap_update(s, &(s->d1->bitmap));/* Mark receipt of record. */ return(1); f_err: @@ -539,7 +547,8 @@ err: } -/* Call this to get a new input record. +/*- + * Call this to get a new input record. * It will return <= 0 if more data is needed, normally due to an error * or non-blocking IO. * When it finishes, one packet has been decoded and can be found in @@ -562,7 +571,8 @@ int dtls1_get_record(SSL *s) /* The epoch may have changed. If so, process all the * pending records. This is a non-blocking operation. */ - dtls1_process_buffered_records(s); + if(dtls1_process_buffered_records(s)<0) + return -1; /* if we're renegotiating, then there may be buffered records */ if (dtls1_get_processed_record(s)) @@ -589,6 +599,9 @@ again: p=s->packet; + if (s->msg_callback) + s->msg_callback(0, 0, SSL3_RT_HEADER, p, DTLS1_RT_HEADER_LENGTH, s, s->msg_callback_arg); + /* Pull apart the header into the DTLS1_RECORD */ rr->type= *(p++); ssl_major= *(p++); @@ -641,8 +654,6 @@ again: /* now s->packet_length == DTLS1_RT_HEADER_LENGTH */ i=rr->length; n=ssl3_read_n(s,i,i,1); - if (n <= 0) return(n); /* error or non-blocking io */ - /* this packet contained a partial record, dump it */ if ( n != i) { @@ -677,7 +688,8 @@ again: * would be dropped unnecessarily. */ if (!(s->d1->listen && rr->type == SSL3_RT_HANDSHAKE && - *p == SSL3_MT_CLIENT_HELLO) && + s->packet_length > DTLS1_RT_HEADER_LENGTH && + s->packet[DTLS1_RT_HEADER_LENGTH] == SSL3_MT_CLIENT_HELLO) && !dtls1_record_replay_check(s, bitmap)) { rr->length = 0; @@ -700,7 +712,10 @@ again: { if ((SSL_in_init(s) || s->in_handshake) && !s->d1->listen) { - dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num); + if(dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num)<0) + return -1; + /* Mark receipt of record. */ + dtls1_record_bitmap_update(s, bitmap); } rr->length = 0; s->packet_length = 0; @@ -713,12 +728,14 @@ again: s->packet_length = 0; /* dump this record */ goto again; /* get another record */ } + dtls1_record_bitmap_update(s, bitmap);/* Mark receipt of record. */ return(1); } -/* Return up to 'len' payload bytes received in 'type' records. +/*- + * Return up to 'len' payload bytes received in 'type' records. * 'type' is one of the following: * * - SSL3_RT_HANDSHAKE (when ssl3_get_message calls us) @@ -796,10 +813,12 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) start: s->rwstate=SSL_NOTHING; - /* s->s3->rrec.type - is the type of record + /*- + * s->s3->rrec.type - is the type of record * s->s3->rrec.data, - data * s->s3->rrec.off, - offset into 'data' for next read - * s->s3->rrec.length, - number of bytes. */ + * s->s3->rrec.length, - number of bytes. + */ rr = &(s->s3->rrec); /* We are not handshaking and have no data yet, @@ -864,7 +883,11 @@ start: * buffer the application data for later processing rather * than dropping the connection. */ - dtls1_buffer_record(s, &(s->d1->buffered_app_data), rr->seq_num); + if(dtls1_buffer_record(s, &(s->d1->buffered_app_data), rr->seq_num)<0) + { + SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR); + return -1; + } rr->length = 0; goto start; } @@ -1026,9 +1049,11 @@ start: } } - /* s->d1->handshake_fragment_len == 12 iff rr->type == SSL3_RT_HANDSHAKE; + /*- + * s->d1->handshake_fragment_len == 12 iff rr->type == SSL3_RT_HANDSHAKE; * s->d1->alert_fragment_len == 7 iff rr->type == SSL3_RT_ALERT. - * (Possibly rr is 'empty' now, i.e. rr->length may be 0.) */ + * (Possibly rr is 'empty' now, i.e. rr->length may be 0.) + */ /* If we are a client, check for an incoming 'Hello Request': */ if ((!s->server) && @@ -1552,9 +1577,20 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len, *(p++)=type&0xff; wr->type=type; - - *(p++)=(s->version>>8); - *(p++)=s->version&0xff; + /* Special case: for hello verify request, client version 1.0 and + * we haven't decided which version to use yet send back using + * version 1.0 header: otherwise some clients will ignore it. + */ + if (s->method->version == DTLS_ANY_VERSION) + { + *(p++)=DTLS1_VERSION>>8; + *(p++)=DTLS1_VERSION&0xff; + } + else + { + *(p++)=s->version>>8; + *(p++)=s->version&0xff; + } /* field where we are to write out packet epoch, seq num and len */ pseq=p; @@ -1620,7 +1656,7 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len, if (eivlen) wr->length += eivlen; - s->method->ssl3_enc->enc(s,1); + if(s->method->ssl3_enc->enc(s,1) < 1) goto err; /* record length after mac and block padding */ /* if (type == SSL3_RT_APPLICATION_DATA || @@ -1638,6 +1674,9 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len, pseq+=6; s2n(wr->length,pseq); + if (s->msg_callback) + s->msg_callback(1, 0, SSL3_RT_HEADER, pseq - DTLS1_RT_HEADER_LENGTH, DTLS1_RT_HEADER_LENGTH, s, s->msg_callback_arg); + /* we should now have * wr->data pointing to the encrypted data, which is * wr->length long */