X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Frecord%2Frec_layer_s3.c;h=c1e563c4b27ffb2e44a155598c5a08d86741537b;hp=8d0a97be98b0fd58a60d582fb4b512e5672ed20a;hb=3519bae518f0ed576daf05057e4fc79e49cb2bee;hpb=f66f8a4491f5c2207ed054fc35eb6a479ab8ecdc diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c index 8d0a97be98..c1e563c4b2 100644 --- a/ssl/record/rec_layer_s3.c +++ b/ssl/record/rec_layer_s3.c @@ -8,7 +8,6 @@ */ #include -#include #include #include #define USE_SOCKETS @@ -17,6 +16,7 @@ #include #include #include "record_locl.h" +#include "../packet_locl.h" #if defined(OPENSSL_SMALL_FOOTPRINT) || \ !( defined(AES_ASM) && ( \ @@ -47,8 +47,6 @@ void RECORD_LAYER_clear(RECORD_LAYER *rl) rl->packet = NULL; rl->packet_length = 0; rl->wnum = 0; - memset(rl->alert_fragment, 0, sizeof(rl->alert_fragment)); - rl->alert_fragment_len = 0; memset(rl->handshake_fragment, 0, sizeof(rl->handshake_fragment)); rl->handshake_fragment_len = 0; rl->wpend_tot = 0; @@ -349,14 +347,14 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, size_t len, tot = s->rlayer.wnum; /* * 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 + * than 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 < s->rlayer.wnum) + if ((len < s->rlayer.wnum) || ((wb->left != 0) && (len < (s->rlayer.wnum + s->rlayer.wpend_tot)))) { SSLerr(SSL_F_SSL3_WRITE_BYTES, SSL_R_BAD_LENGTH); return -1; @@ -843,9 +841,6 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, /* first we compress */ if (s->compress != NULL) { - /* - * TODO(TLS1.3): Make sure we prevent compression!!! - */ if (!ssl3_do_compress(s, thiswr) || !WPACKET_allocate_bytes(thispkt, thiswr->length, NULL)) { SSLerr(SSL_F_DO_SSL3_WRITE, SSL_R_COMPRESSION_FAILURE); @@ -947,7 +942,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, || s->early_data_state == SSL_EARLY_DATA_WRITE_RETRY) { /* * We haven't actually negotiated the version yet, but we're trying to - * send early data - so we need to use the the tls13enc function. + * send early data - so we need to use the tls13enc function. */ if (tls13_enc(s, wr, numpipes, 1) < 1) goto err; @@ -1402,10 +1397,6 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, dest_maxlen = sizeof s->rlayer.handshake_fragment; dest = s->rlayer.handshake_fragment; dest_len = &s->rlayer.handshake_fragment_len; - } else if (SSL3_RECORD_get_type(rr) == SSL3_RT_ALERT) { - dest_maxlen = sizeof s->rlayer.alert_fragment; - dest = s->rlayer.alert_fragment; - dest_len = &s->rlayer.alert_fragment_len; } if (dest_maxlen > 0) { @@ -1429,7 +1420,6 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, /*- * s->rlayer.handshake_fragment_len == 4 iff rr->type == SSL3_RT_HANDSHAKE; - * s->rlayer.alert_fragment_len == 2 iff rr->type == SSL3_RT_ALERT. * (Possibly rr is 'empty' now, i.e. rr->length may be 0.) */ @@ -1440,27 +1430,37 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, */ if (s->server && SSL_is_init_finished(s) && - !s->s3->send_connection_binding && (s->version > SSL3_VERSION) && !SSL_IS_TLS13(s) && + (SSL3_RECORD_get_type(rr) == SSL3_RT_HANDSHAKE) && (s->rlayer.handshake_fragment_len >= 4) && (s->rlayer.handshake_fragment[0] == SSL3_MT_CLIENT_HELLO) && (s->session != NULL) && (s->session->cipher != NULL) && - !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) { + ((!s->s3->send_connection_binding && + !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) || + (s->options & SSL_OP_NO_RENEGOTIATION))) { SSL3_RECORD_set_length(rr, 0); SSL3_RECORD_set_read(rr); ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION); goto start; } - if (s->rlayer.alert_fragment_len >= 2) { - int alert_level = s->rlayer.alert_fragment[0]; - int alert_descr = s->rlayer.alert_fragment[1]; - - s->rlayer.alert_fragment_len = 0; + if (SSL3_RECORD_get_type(rr) == SSL3_RT_ALERT) { + unsigned int alert_level, alert_descr; + unsigned char *alert_bytes = SSL3_RECORD_get_data(rr) + + SSL3_RECORD_get_off(rr); + PACKET alert; + + if (!PACKET_buf_init(&alert, alert_bytes, SSL3_RECORD_get_length(rr)) + || !PACKET_get_1(&alert, &alert_level) + || !PACKET_get_1(&alert, &alert_descr) + || PACKET_remaining(&alert) != 0) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_INVALID_ALERT); + goto f_err; + } if (s->msg_callback) - s->msg_callback(0, s->version, SSL3_RT_ALERT, - s->rlayer.alert_fragment, 2, s, + s->msg_callback(0, s->version, SSL3_RT_ALERT, alert_bytes, 2, s, s->msg_callback_arg); if (s->info_callback != NULL)