X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fs3_pkt.c;h=f02e3c80d0d7319e5828b965ed25b3183a6decde;hp=41193bb7d162a42cd46dd6deca97de55ab175e57;hb=50cc4f7b3d64621b6062ad1f16a7630b7c730d9b;hpb=c388d8b40cb9a3cb67401455509c1497a1a1fcb4 diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c index 41193bb7d1..f02e3c80d0 100644 --- a/ssl/s3_pkt.c +++ b/ssl/s3_pkt.c @@ -644,6 +644,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) int i; s->rwstate=SSL_NOTHING; + OPENSSL_assert(s->s3->wnum <= INT_MAX); tot=s->s3->wnum; s->s3->wnum=0; @@ -658,6 +659,21 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) } } + /* ensure that if we end up with a smaller value of data to write + * out than the the original len from a write which didn't complete + * for non-blocking I/O and also somehow ended up avoiding + * the check for this in ssl3_write_pending/SSL_R_BAD_WRITE_RETRY as + * it must never be possible to end up with (len-tot) as a large + * number that will then promptly send beyond the end of the users + * buffer ... so we trap and report the error in a way the user + * will notice + */ + if (len < tot) + { + SSLerr(SSL_F_SSL3_WRITE_BYTES,SSL_R_BAD_LENGTH); + return(-1); + } + /* first check if there is a SSL3_BUFFER still being written * out. This will happen with non blocking IO */ if (wb->left != 0) @@ -680,7 +696,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) * compromise is considered worthy. */ if (type==SSL3_RT_APPLICATION_DATA && - len >= 4*(max_send_fragment=s->max_send_fragment) && + len >= 4*(int)(max_send_fragment=s->max_send_fragment) && s->compress==NULL && s->msg_callback==NULL && !SSL_USE_ETM(s) && SSL_USE_EXPLICIT_IV(s) && EVP_CIPHER_flags(s->enc_write_ctx->cipher)&EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK) @@ -701,7 +717,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE, max_send_fragment,NULL); - if (len>=8*max_send_fragment) packlen *= 8; + if (len>=8*(int)max_send_fragment) packlen *= 8; else packlen *= 4; wb->buf=OPENSSL_malloc(packlen); @@ -753,7 +769,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) EVP_CTRL_TLS1_1_MULTIBLOCK_AAD, sizeof(mb_param),&mb_param); - if (packlen<=0 || packlen>wb->len) /* never happens */ + if (packlen<=0 || packlen>(int)wb->len) /* never happens */ { OPENSSL_free(wb->buf); /* free jumbo buffer */ wb->buf = NULL; @@ -816,20 +832,6 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) return tot; } - /* ensure that if we end up with a smaller value of data to write - * out than the the original len from a write which didn't complete - * for non-blocking I/O and also somehow ended up avoiding - * the check for this in ssl3_write_pending/SSL_R_BAD_WRITE_RETRY as - * it must never be possible to end up with (len-tot) as a large - * number that will then promptly send beyond the end of the users - * buffer ... so we trap and report the error in a way the user - * will notice - */ - if ( len < tot) - { - SSLerr(SSL_F_SSL3_WRITE_BYTES,SSL_R_BAD_LENGTH); - return(-1); - } n=(len-tot); for (;;) @@ -879,9 +881,6 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, SSL3_BUFFER *wb=&(s->s3->wbuf); SSL_SESSION *sess; - if (wb->buf == NULL) - if (!ssl3_setup_write_buffer(s)) - return -1; /* first check if there is a SSL3_BUFFER still being written * out. This will happen with non blocking IO */ @@ -897,6 +896,10 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, /* if it went, fall through and send more stuff */ } + if (wb->buf == NULL) + if (!ssl3_setup_write_buffer(s)) + return -1; + if (len == 0 && !create_empty_fragment) return 0; @@ -1591,6 +1594,15 @@ start: goto f_err; } + if (!(s->s3->flags & SSL3_FLAGS_CCS_OK)) + { + al=SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_CCS_RECEIVED_EARLY); + goto f_err; + } + + s->s3->flags &= ~SSL3_FLAGS_CCS_OK; + rr->length=0; if (s->msg_callback) @@ -1725,7 +1737,7 @@ int ssl3_do_change_cipher_spec(SSL *s) if (s->s3->tmp.key_block == NULL) { - if (s->session == NULL) + if (s->session == NULL || s->session->master_key_length == 0) { /* might happen if dtls1_read_bytes() calls this */ SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC,SSL_R_CCS_RECEIVED_EARLY);