X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=ssl%2Fd1_both.c;h=0781a4b67029c24a6ef0b8b8e61810d3682561e6;hb=4a052f0bb94e5e6932b8c09102279ed2e79eaad2;hp=69b6b10ba22e614304f6bf0031d072eda7247c6f;hpb=1ddf6912449ca02e9cdd106f2c423117d6e2ea62;p=oweals%2Fopenssl.git diff --git a/ssl/d1_both.c b/ssl/d1_both.c index 69b6b10ba2..0781a4b670 100644 --- a/ssl/d1_both.c +++ b/ssl/d1_both.c @@ -177,7 +177,7 @@ int dtls1_do_write(SSL *s, int type) { int ret; int curr_mtu; - unsigned int len, frag_off; + unsigned int len, frag_off, mac_size, blocksize; /* AHA! Figure out the MTU, and stick to the right size */ if ( ! (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) @@ -225,11 +225,22 @@ int dtls1_do_write(SSL *s, int type) OPENSSL_assert(s->init_num == (int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH); + if (s->write_hash) + mac_size = EVP_MD_size(s->write_hash); + else + mac_size = 0; + + if (s->enc_write_ctx && + (EVP_CIPHER_mode( s->enc_write_ctx->cipher) & EVP_CIPH_CBC_MODE)) + blocksize = 2 * EVP_CIPHER_block_size(s->enc_write_ctx->cipher); + else + blocksize = 0; + frag_off = 0; while( s->init_num) { curr_mtu = s->d1->mtu - BIO_wpending(SSL_get_wbio(s)) - - DTLS1_RT_HEADER_LENGTH; + DTLS1_RT_HEADER_LENGTH - mac_size - blocksize; if ( curr_mtu <= DTLS1_HM_HEADER_LENGTH) { @@ -237,7 +248,8 @@ int dtls1_do_write(SSL *s, int type) ret = BIO_flush(SSL_get_wbio(s)); if ( ret <= 0) return ret; - curr_mtu = s->d1->mtu - DTLS1_RT_HEADER_LENGTH; + curr_mtu = s->d1->mtu - DTLS1_RT_HEADER_LENGTH - + mac_size - blocksize; } if ( s->init_num > curr_mtu) @@ -279,7 +291,7 @@ int dtls1_do_write(SSL *s, int type) * retransmit */ if ( BIO_ctrl(SSL_get_wbio(s), - BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL)) + BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL) > 0 ) s->d1->mtu = BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); else @@ -753,6 +765,24 @@ int dtls1_send_finished(SSL *s, int a, int b, const char *sender, int slen) p+=i; l=i; + /* Copy the finished so we can use it for + * renegotiation checks + */ + if(s->type == SSL_ST_CONNECT) + { + OPENSSL_assert(i <= EVP_MAX_MD_SIZE); + memcpy(s->s3->previous_client_finished, + s->s3->tmp.finish_md, i); + s->s3->previous_client_finished_len=i; + } + else + { + OPENSSL_assert(i <= EVP_MAX_MD_SIZE); + memcpy(s->s3->previous_server_finished, + s->s3->tmp.finish_md, i); + s->s3->previous_server_finished_len=i; + } + #ifdef OPENSSL_SYS_WIN16 /* MSVC 1.5 does not clear the top bytes of the word unless * I do this. @@ -815,14 +845,30 @@ int dtls1_send_change_cipher_spec(SSL *s, int a, int b) return(dtls1_do_write(s,SSL3_RT_CHANGE_CIPHER_SPEC)); } +static int dtls1_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x) + { + int n; + unsigned char *p; + + n=i2d_X509(x,NULL); + if (!BUF_MEM_grow_clean(buf,(int)(n+(*l)+3))) + { + SSLerr(SSL_F_DTLS1_ADD_CERT_TO_BUF,ERR_R_BUF_LIB); + return 0; + } + p=(unsigned char *)&(buf->data[*l]); + l2n3(n,p); + i2d_X509(x,&p); + *l+=n+3; + + return 1; + } unsigned long dtls1_output_cert_chain(SSL *s, X509 *x) { unsigned char *p; - int n,i; + int i; unsigned long l= 3 + DTLS1_HM_HEADER_LENGTH; BUF_MEM *buf; - X509_STORE_CTX xs_ctx; - X509_OBJECT obj; /* TLSv1 sends a chain with nothing in it, instead of an alert */ buf=s->init_buf; @@ -833,54 +879,35 @@ unsigned long dtls1_output_cert_chain(SSL *s, X509 *x) } if (x != NULL) { - if(!X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,NULL,NULL)) - { - SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_X509_LIB); - return(0); - } - - for (;;) - { - n=i2d_X509(x,NULL); - if (!BUF_MEM_grow_clean(buf,(int)(n+l+3))) - { - SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB); - return(0); - } - p=(unsigned char *)&(buf->data[l]); - l2n3(n,p); - i2d_X509(x,&p); - l+=n+3; - if (X509_NAME_cmp(X509_get_subject_name(x), - X509_get_issuer_name(x)) == 0) break; - - i=X509_STORE_get_by_subject(&xs_ctx,X509_LU_X509, - X509_get_issuer_name(x),&obj); - if (i <= 0) break; - x=obj.data.x509; - /* Count is one too high since the X509_STORE_get uped the - * ref count */ - X509_free(x); - } - - X509_STORE_CTX_cleanup(&xs_ctx); - } - + X509_STORE_CTX xs_ctx; + + if (!X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,x,NULL)) + { + SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_X509_LIB); + return(0); + } + + X509_verify_cert(&xs_ctx); + /* Don't leave errors in the queue */ + ERR_clear_error(); + for (i=0; i < sk_X509_num(xs_ctx.chain); i++) + { + x = sk_X509_value(xs_ctx.chain, i); + + if (!dtls1_add_cert_to_buf(buf, &l, x)) + { + X509_STORE_CTX_cleanup(&xs_ctx); + return 0; + } + } + X509_STORE_CTX_cleanup(&xs_ctx); + } /* Thawte special :-) */ - if (s->ctx->extra_certs != NULL) for (i=0; ictx->extra_certs); i++) { x=sk_X509_value(s->ctx->extra_certs,i); - n=i2d_X509(x,NULL); - if (!BUF_MEM_grow_clean(buf,(int)(n+l+3))) - { - SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB); - return(0); - } - p=(unsigned char *)&(buf->data[l]); - l2n3(n,p); - i2d_X509(x,&p); - l+=n+3; + if (!dtls1_add_cert_to_buf(buf, &l, x)) + return 0; } l-= (3 + DTLS1_HM_HEADER_LENGTH); @@ -897,9 +924,6 @@ unsigned long dtls1_output_cert_chain(SSL *s, X509 *x) int dtls1_read_failed(SSL *s, int code) { - DTLS1_STATE *state; - int send_alert = 0; - if ( code > 0) { fprintf( stderr, "invalid state reached %s:%d", __FILE__, __LINE__); @@ -919,24 +943,6 @@ int dtls1_read_failed(SSL *s, int code) return code; } - dtls1_double_timeout(s); - state = s->d1; - state->timeout.num_alerts++; - if ( state->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) - { - /* fail the connection, enough alerts have been sent */ - SSLerr(SSL_F_DTLS1_READ_FAILED,SSL_R_READ_TIMEOUT_EXPIRED); - return 0; - } - - state->timeout.read_timeouts++; - if ( state->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) - { - send_alert = 1; - state->timeout.read_timeouts = 1; - } - - #if 0 /* for now, each alert contains only one record number */ item = pqueue_peek(state->rcvd_records); if ( item ) @@ -947,12 +953,12 @@ int dtls1_read_failed(SSL *s, int code) #endif #if 0 /* no more alert sending, just retransmit the last set of messages */ - if ( send_alert) - ssl3_send_alert(s,SSL3_AL_WARNING, - DTLS1_AD_MISSING_HANDSHAKE_MESSAGE); + if ( state->timeout.read_timeouts >= DTLS1_TMO_READ_COUNT) + ssl3_send_alert(s,SSL3_AL_WARNING, + DTLS1_AD_MISSING_HANDSHAKE_MESSAGE); #endif - return dtls1_retransmit_buffered_messages(s) ; + return dtls1_handle_timeout(s); } int @@ -984,7 +990,7 @@ dtls1_retransmit_buffered_messages(SSL *s) { frag = (hm_fragment *)item->data; if ( dtls1_retransmit_message(s, - dtls1_get_queue_priority(frag->msg_header.seq, frag->msg_header.is_ccs), + (unsigned short)dtls1_get_queue_priority(frag->msg_header.seq, frag->msg_header.is_ccs), 0, &found) <= 0 && found) { fprintf(stderr, "dtls1_retransmit_message() failed\n");