X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Frecord%2Fssl3_record.c;h=7383f137b70130e8897cf0fe534a7709fe550ad0;hp=cfd8290d33cf1f3c15e991d685e096ef08dc8f07;hb=912c89c529de78de807f58072ae77456b4a251b5;hpb=e5bf62f716f71e4df6995a07d1fbc4cad82a2637 diff --git a/ssl/record/ssl3_record.c b/ssl/record/ssl3_record.c index cfd8290d33..7383f137b7 100644 --- a/ssl/record/ssl3_record.c +++ b/ssl/record/ssl3_record.c @@ -110,7 +110,7 @@ */ #include "../ssl_locl.h" -#include "../../crypto/constant_time_locl.h" +#include "internal/constant_time_locl.h" #include #include "record_locl.h" @@ -132,15 +132,20 @@ static const unsigned char ssl3_pad_2[48] = { 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c }; +/* + * Clear the contents of an SSL3_RECORD but retain any memory allocated + */ void SSL3_RECORD_clear(SSL3_RECORD *r) { - memset(r->seq_num, 0, sizeof(r->seq_num)); + unsigned char *comp = r->comp; + + memset(r, 0, sizeof(*r)); + r->comp = comp; } void SSL3_RECORD_release(SSL3_RECORD *r) { - if (r->comp != NULL) - OPENSSL_free(r->comp); + OPENSSL_free(r->comp); r->comp = NULL; } @@ -167,6 +172,7 @@ void SSL3_RECORD_set_seq_num(SSL3_RECORD *r, const unsigned char *seq_num) */ #define MAX_EMPTY_RECORDS 32 +#define SSL2_RT_HEADER_LENGTH 2 /*- * Call this to get a new input record. * It will return <= 0 if more data is needed, normally due to an error @@ -217,71 +223,118 @@ int ssl3_get_record(SSL *s) RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_BODY); p = RECORD_LAYER_get_packet(&s->rlayer); - if (s->msg_callback) - s->msg_callback(0, 0, SSL3_RT_HEADER, p, 5, s, - s->msg_callback_arg); - /* Pull apart the header into the SSL3_RECORD */ - rr->type = *(p++); - ssl_major = *(p++); - ssl_minor = *(p++); - version = (ssl_major << 8) | ssl_minor; - n2s(p, rr->length); + /* + * Check whether this is a regular record or an SSLv2 style record. The + * latter is only used in an initial ClientHello for old clients. We + * check s->read_hash and s->enc_read_ctx to ensure this does not apply + * during renegotiation + */ + if (s->first_packet && s->server && !s->read_hash && !s->enc_read_ctx + && (p[0] & 0x80) && (p[2] == SSL2_MT_CLIENT_HELLO)) { + /* SSLv2 style record */ + rr->type = SSL3_RT_HANDSHAKE; + rr->rec_version = SSL2_VERSION; + + rr->length = ((p[0] & 0x7f) << 8) | p[1]; + + if (rr->length > SSL3_BUFFER_get_len(&s->rlayer.rbuf) + - SSL2_RT_HEADER_LENGTH) { + al = SSL_AD_RECORD_OVERFLOW; + SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_PACKET_LENGTH_TOO_LONG); + goto f_err; + } - /* Lets check version */ - if (!s->first_packet) { - if (version != s->version) { + if (rr->length < MIN_SSL2_RECORD_LEN) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + } else { + /* SSLv3+ style record */ + if (s->msg_callback) + s->msg_callback(0, 0, SSL3_RT_HEADER, p, 5, s, + s->msg_callback_arg); + + /* Pull apart the header into the SSL3_RECORD */ + rr->type = *(p++); + ssl_major = *(p++); + ssl_minor = *(p++); + version = (ssl_major << 8) | ssl_minor; + rr->rec_version = version; + n2s(p, rr->length); + + /* Lets check version */ + if (!s->first_packet && version != s->version) { SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_WRONG_VERSION_NUMBER); if ((s->version & 0xFF00) == (version & 0xFF00) - && !s->enc_write_ctx && !s->write_hash) + && !s->enc_write_ctx && !s->write_hash) { + if (rr->type == SSL3_RT_ALERT) { + /* + * The record is using an incorrect version number, but + * what we've got appears to be an alert. We haven't + * read the body yet to check whether its a fatal or + * not - but chances are it is. We probably shouldn't + * send a fatal alert back. We'll just end. + */ + goto err; + } /* * Send back error using their minor version number :-) */ s->version = (unsigned short)version; + } al = SSL_AD_PROTOCOL_VERSION; goto f_err; } - } - if ((version >> 8) != SSL3_VERSION_MAJOR) { - SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_WRONG_VERSION_NUMBER); - goto err; - } + if ((version >> 8) != SSL3_VERSION_MAJOR) { + SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_WRONG_VERSION_NUMBER); + goto err; + } - if (rr->length > - SSL3_BUFFER_get_len(&s->rlayer.rbuf) - - SSL3_RT_HEADER_LENGTH) { - al = SSL_AD_RECORD_OVERFLOW; - SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_PACKET_LENGTH_TOO_LONG); - goto f_err; + if (rr->length > + SSL3_BUFFER_get_len(&s->rlayer.rbuf) + - SSL3_RT_HEADER_LENGTH) { + al = SSL_AD_RECORD_OVERFLOW; + SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_PACKET_LENGTH_TOO_LONG); + goto f_err; + } } /* now s->rlayer.rstate == SSL_ST_READ_BODY */ } - /* s->rlayer.rstate == SSL_ST_READ_BODY, get and decode the data */ - - if (rr->length > - RECORD_LAYER_get_packet_length(&s->rlayer) - SSL3_RT_HEADER_LENGTH) { - /* now s->packet_length == SSL3_RT_HEADER_LENGTH */ + /* + * s->rlayer.rstate == SSL_ST_READ_BODY, get and decode the data. + * Calculate how much more data we need to read for the rest of the record + */ + if (rr->rec_version == SSL2_VERSION) { + i = rr->length + SSL2_RT_HEADER_LENGTH - SSL3_RT_HEADER_LENGTH; + } else { i = rr->length; + } + if (i > 0) { + /* now s->packet_length == SSL3_RT_HEADER_LENGTH */ + n = ssl3_read_n(s, i, i, 1); if (n <= 0) return (n); /* error or non-blocking io */ - /* - * now n == rr->length, and s->packet_length == SSL3_RT_HEADER_LENGTH - * + rr->length - */ } /* set state for later operations */ RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_HEADER); /* - * At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length, + * At this point, s->packet_length == SSL3_RT_HEADER_LENGTH + rr->length, + * or s->packet_length == SSL2_RT_HEADER_LENGTH + rr->length * and we have that many bytes in s->packet */ - rr->input = &(RECORD_LAYER_get_packet(&s->rlayer)[SSL3_RT_HEADER_LENGTH]); + if(rr->rec_version == SSL2_VERSION) { + rr->input = &(RECORD_LAYER_get_packet(&s->rlayer)[SSL2_RT_HEADER_LENGTH]); + } else { + rr->input = &(RECORD_LAYER_get_packet(&s->rlayer)[SSL3_RT_HEADER_LENGTH]); + } /* * ok, we can now read from 's->packet' data into 'rr' rr->input points @@ -645,10 +698,6 @@ int tls1_enc(SSL *s, int send) enc = EVP_CIPHER_CTX_cipher(s->enc_read_ctx); } -#ifdef KSSL_DEBUG - fprintf(stderr, "tls1_enc(%d)\n", send); -#endif /* KSSL_DEBUG */ - if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) { memmove(rec->data, rec->input, rec->length); rec->input = rec->data; @@ -658,7 +707,7 @@ int tls1_enc(SSL *s, int send) bs = EVP_CIPHER_block_size(ds->cipher); if (EVP_CIPHER_flags(ds->cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) { - unsigned char buf[13], *seq; + unsigned char buf[EVP_AEAD_TLS1_AAD_LEN], *seq; seq = send ? RECORD_LAYER_get_write_sequence(&s->rlayer) : RECORD_LAYER_get_read_sequence(&s->rlayer); @@ -684,7 +733,10 @@ int tls1_enc(SSL *s, int send) buf[10] = (unsigned char)(s->version); buf[11] = rec->length >> 8; buf[12] = rec->length & 0xff; - pad = EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_AEAD_TLS1_AAD, 13, buf); + pad = EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_AEAD_TLS1_AAD, + EVP_AEAD_TLS1_AAD_LEN, buf); + if (pad <= 0) + return -1; if (send) { l += pad; rec->length += pad; @@ -696,35 +748,11 @@ int tls1_enc(SSL *s, int send) /* we need to add 'i' padding bytes of value j */ j = i - 1; - if (s->options & SSL_OP_TLS_BLOCK_PADDING_BUG) { - if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) - j++; - } for (k = (int)l; k < (int)(l + i); k++) rec->input[k] = j; l += i; rec->length += i; } -#ifdef KSSL_DEBUG - { - unsigned long ui; - fprintf(stderr, - "EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n", - ds, rec->data, rec->input, l); - fprintf(stderr, - "\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%lu %lu], %d iv_len\n", - ds->buf_len, ds->cipher->key_len, DES_KEY_SZ, - DES_SCHEDULE_SZ, ds->cipher->iv_len); - fprintf(stderr, "\t\tIV: "); - for (i = 0; i < ds->cipher->iv_len; i++) - fprintf(stderr, "%02X", ds->iv[i]); - fprintf(stderr, "\n"); - fprintf(stderr, "\trec->input="); - for (ui = 0; ui < l; ui++) - fprintf(stderr, " %02x", rec->input[ui]); - fprintf(stderr, "\n"); - } -#endif /* KSSL_DEBUG */ if (!send) { if (l == 0 || l % bs != 0) @@ -736,20 +764,17 @@ int tls1_enc(SSL *s, int send) ? (i < 0) : (i == 0)) return -1; /* AEAD can fail to verify MAC */ - if (EVP_CIPHER_mode(enc) == EVP_CIPH_GCM_MODE && !send) { - rec->data += EVP_GCM_TLS_EXPLICIT_IV_LEN; - rec->input += EVP_GCM_TLS_EXPLICIT_IV_LEN; - rec->length -= EVP_GCM_TLS_EXPLICIT_IV_LEN; - } -#ifdef KSSL_DEBUG - { - unsigned long i; - fprintf(stderr, "\trec->data="); - for (i = 0; i < l; i++) - fprintf(stderr, " %02x", rec->data[i]); - fprintf(stderr, "\n"); + if (send == 0) { + if (EVP_CIPHER_mode(enc) == EVP_CIPH_GCM_MODE) { + rec->data += EVP_GCM_TLS_EXPLICIT_IV_LEN; + rec->input += EVP_GCM_TLS_EXPLICIT_IV_LEN; + rec->length -= EVP_GCM_TLS_EXPLICIT_IV_LEN; + } else if (EVP_CIPHER_mode(enc) == EVP_CIPH_CCM_MODE) { + rec->data += EVP_CCM_TLS_EXPLICIT_IV_LEN; + rec->input += EVP_CCM_TLS_EXPLICIT_IV_LEN; + rec->length -= EVP_CCM_TLS_EXPLICIT_IV_LEN; + } } -#endif /* KSSL_DEBUG */ ret = 1; if (!SSL_USE_ETM(s) && EVP_MD_CTX_md(s->read_hash) != NULL) @@ -1041,24 +1066,6 @@ int tls1_cbc_remove_padding(const SSL *s, padding_length = rec->data[rec->length - 1]; - /* - * NB: if compression is in operation the first packet may not be of even - * length so the padding bug check cannot be performed. This bug - * workaround has been around since SSLeay so hopefully it is either - * fixed now or no buggy implementation supports compression [steve] - */ - if ((s->options & SSL_OP_TLS_BLOCK_PADDING_BUG) && !s->expand) { - /* First packet is even in size, so check */ - if ((memcmp(RECORD_LAYER_get_read_sequence(&s->rlayer), - "\0\0\0\0\0\0\0\0", 8) == 0) && - !(padding_length & 1)) { - s->s3->flags |= TLS1_FLAGS_TLS_PADDING_BUG; - } - if ((s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) && padding_length > 0) { - padding_length--; - } - } - if (EVP_CIPHER_flags(s->enc_read_ctx->cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) { /* padding is already verified */ rec->length -= padding_length + 1; @@ -1501,18 +1508,8 @@ int dtls1_get_record(SSL *s) /* Only do replay check if no SCTP bio */ if (!BIO_dgram_is_sctp(SSL_get_rbio(s))) { #endif - /* - * Check whether this is a repeat, or aged record. Don't check if - * we're listening and this message is a ClientHello. They can look - * as if they're replayed, since they arrive from different - * connections and would be dropped unnecessarily. - */ - if (!(s->d1->listen && rr->type == SSL3_RT_HANDSHAKE && - RECORD_LAYER_get_packet_length(&s->rlayer) - > DTLS1_RT_HEADER_LENGTH && - RECORD_LAYER_get_packet(&s->rlayer)[DTLS1_RT_HEADER_LENGTH] - == SSL3_MT_CLIENT_HELLO) && - !dtls1_record_replay_check(s, bitmap)) { + /* Check whether this is a repeat, or aged record. */ + if (!dtls1_record_replay_check(s, bitmap)) { rr->length = 0; RECORD_LAYER_reset_packet_length(&s->rlayer); /* dump this record */ goto again; /* get another record */ @@ -1528,11 +1525,10 @@ int dtls1_get_record(SSL *s) /* * If this record is from the next epoch (either HM or ALERT), and a * handshake is currently in progress, buffer it since it cannot be - * processed at this time. However, do not buffer anything while - * listening. + * processed at this time. */ if (is_next_epoch) { - if ((SSL_in_init(s) || s->in_handshake) && !s->d1->listen) { + if ((SSL_in_init(s) || s->in_handshake)) { if (dtls1_buffer_record (s, &(DTLS_RECORD_LAYER_get_unprocessed_rcds(&s->rlayer)), rr->seq_num) < 0) @@ -1555,4 +1551,3 @@ int dtls1_get_record(SSL *s) return (1); } -