summaryrefslogtreecommitdiffstats
path: root/lib/libssl/ssl_pkt.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libssl/ssl_pkt.c')
-rw-r--r--lib/libssl/ssl_pkt.c166
1 files changed, 33 insertions, 133 deletions
diff --git a/lib/libssl/ssl_pkt.c b/lib/libssl/ssl_pkt.c
index c9c86471d3c..02a476ea82b 100644
--- a/lib/libssl/ssl_pkt.c
+++ b/lib/libssl/ssl_pkt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_pkt.c,v 1.31 2020/08/30 15:40:20 jsing Exp $ */
+/* $OpenBSD: ssl_pkt.c,v 1.32 2020/10/03 17:35:16 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -149,15 +149,14 @@ ssl_force_want_read(SSL *s)
static int
ssl3_read_n(SSL *s, int n, int max, int extend)
{
+ SSL3_BUFFER_INTERNAL *rb = &(S3I(s)->rbuf);
int i, len, left;
size_t align;
unsigned char *pkt;
- SSL3_BUFFER_INTERNAL *rb;
if (n <= 0)
return n;
- rb = &(S3I(s)->rbuf);
if (rb->buf == NULL)
if (!ssl3_setup_read_buffer(s))
return -1;
@@ -327,15 +326,13 @@ ssl3_packet_extend(SSL *s, int plen)
static int
ssl3_get_record(SSL *s)
{
- int al;
- int enc_err, n, i, ret = -1;
- SSL3_RECORD_INTERNAL *rr;
- SSL_SESSION *sess;
- unsigned char md[EVP_MAX_MD_SIZE];
- unsigned int mac_size, orig_len;
-
- rr = &(S3I(s)->rrec);
- sess = s->session;
+ SSL3_BUFFER_INTERNAL *rb = &(S3I(s)->rbuf);
+ SSL3_RECORD_INTERNAL *rr = &(S3I(s)->rrec);
+ uint8_t alert_desc;
+ uint8_t *out;
+ size_t out_len;
+ int al, n;
+ int ret = -1;
again:
/* check if we have the header */
@@ -387,17 +384,13 @@ ssl3_get_record(SSL *s)
goto err;
}
- if (rr->length > S3I(s)->rbuf.len - SSL3_RT_HEADER_LENGTH) {
+ if (rr->length > rb->len - SSL3_RT_HEADER_LENGTH) {
al = SSL_AD_RECORD_OVERFLOW;
SSLerror(s, SSL_R_PACKET_LENGTH_TOO_LONG);
goto f_err;
}
-
- /* now s->internal->rstate == SSL_ST_READ_BODY */
}
- /* s->internal->rstate == SSL_ST_READ_BODY, get and decode the data */
-
n = ssl3_packet_extend(s, SSL3_RT_HEADER_LENGTH + rr->length);
if (n <= 0)
return (n);
@@ -406,133 +399,40 @@ ssl3_get_record(SSL *s)
s->internal->rstate = SSL_ST_READ_HEADER; /* set state for later operations */
- /* At this point, s->internal->packet_length == SSL3_RT_HEADER_LNGTH + rr->length,
- * and we have that many bytes in s->internal->packet
+ /*
+ * A full record has now been read from the wire, which now needs
+ * to be processed.
*/
- rr->input = &(s->internal->packet[SSL3_RT_HEADER_LENGTH]);
-
- /* ok, we can now read from 's->internal->packet' data into 'rr'
- * rr->input points at rr->length bytes, which
- * need to be copied into rr->data by either
- * the decryption or by the decompression
- * When the data is 'copied' into the rr->data buffer,
- * rr->input will be pointed at the new buffer */
-
- /* We now have - encrypted [ MAC [ compressed [ plain ] ] ]
- * rr->length bytes of encrypted compressed stuff. */
-
- /* check is not needed I believe */
- if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) {
- al = SSL_AD_RECORD_OVERFLOW;
- SSLerror(s, SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
- goto f_err;
- }
-
- /* decrypt in place in 'rr->input' */
- rr->data = rr->input;
+ tls12_record_layer_set_version(s->internal->rl, s->version);
- /* 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 */
- if ((enc_err = tls1_enc(s, 0)) == 0) {
- al = SSL_AD_BAD_RECORD_MAC;
- SSLerror(s, SSL_R_BLOCK_CIPHER_PAD_IS_WRONG);
- goto f_err;
- }
-
- /* r->length is now the compressed data plus mac */
- if ((sess != NULL) && (s->enc_read_ctx != NULL) &&
- (EVP_MD_CTX_md(s->read_hash) != NULL)) {
- /* s->read_hash != NULL => mac_size != -1 */
- unsigned char *mac = NULL;
- unsigned char mac_tmp[EVP_MAX_MD_SIZE];
-
- mac_size = EVP_MD_CTX_size(s->read_hash);
- OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE);
-
- orig_len = rr->length + rr->padding_length;
+ if (!tls12_record_layer_open_record(s->internal->rl, s->internal->packet,
+ s->internal->packet_length, &out, &out_len)) {
+ tls12_record_layer_alert(s->internal->rl, &alert_desc);
- /* orig_len is the length of the record before any padding was
- * removed. This is public information, as is the MAC in use,
- * therefore we can safely process the record in a different
- * amount of time if it's too short to possibly contain a MAC.
- */
- if (orig_len < mac_size ||
- /* CBC records must have a padding length byte too. */
- (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
- orig_len < mac_size + 1)) {
- al = SSL_AD_DECODE_ERROR;
- SSLerror(s, SSL_R_LENGTH_TOO_SHORT);
- goto f_err;
- }
-
- if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) {
- /* We update the length so that the TLS header bytes
- * can be constructed correctly but we need to extract
- * the MAC in constant time from within the record,
- * without leaking the contents of the padding bytes.
- * */
- mac = mac_tmp;
- ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len);
- rr->length -= mac_size;
- } else {
- /* In this case there's no padding, so |orig_len|
- * equals |rec->length| and we checked that there's
- * enough bytes for |mac_size| above. */
- rr->length -= mac_size;
- mac = &rr->data[rr->length];
- }
+ if (alert_desc == 0)
+ goto err;
- i = tls1_mac(s,md,0 /* not send */);
- if (i < 0 || mac == NULL ||
- timingsafe_memcmp(md, mac, (size_t)mac_size) != 0)
- enc_err = -1;
- if (rr->length >
- SSL3_RT_MAX_COMPRESSED_LENGTH + mac_size)
- enc_err = -1;
- }
+ if (alert_desc == SSL_AD_RECORD_OVERFLOW)
+ SSLerror(s, SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
+ else if (alert_desc == SSL_AD_BAD_RECORD_MAC)
+ SSLerror(s, SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
- if (enc_err < 0) {
- /*
- * A separate 'decryption_failed' alert was introduced with
- * TLS 1.0, SSL 3.0 only has 'bad_record_mac'. But unless a
- * decryption failure is directly visible from the ciphertext
- * anyway, we should not reveal which kind of error
- * occurred -- this might become visible to an attacker
- * (e.g. via a logfile)
- */
- al = SSL_AD_BAD_RECORD_MAC;
- SSLerror(s, SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
- goto f_err;
- }
-
- if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH) {
- al = SSL_AD_RECORD_OVERFLOW;
- SSLerror(s, SSL_R_DATA_LENGTH_TOO_LONG);
+ al = alert_desc;
goto f_err;
}
+ rr->data = out;
+ rr->length = out_len;
rr->off = 0;
- /*
- * So at this point the following is true
- *
- * ssl->s3->internal->rrec.type is the type of record
- * ssl->s3->internal->rrec.length == number of bytes in record
- * ssl->s3->internal->rrec.off == offset to first valid byte
- * ssl->s3->internal->rrec.data == where to take bytes from, increment
- * after use :-).
- */
/* we have pulled in a full packet so zero things */
s->internal->packet_length = 0;
if (rr->length == 0) {
/*
- * CBC countermeasures for known IV weaknesses
- * can legitimately insert a single empty record,
- * so we allow ourselves to read once past a single
- * empty record without forcing want_read.
+ * CBC countermeasures for known IV weaknesses can legitimately
+ * insert a single empty record, so we allow ourselves to read
+ * once past a single empty record without forcing want_read.
*/
if (s->internal->empty_record_count++ > SSL_MAX_EMPTY_RECORDS) {
SSLerror(s, SSL_R_PEER_BEHAVING_BADLY);
@@ -543,15 +443,15 @@ ssl3_get_record(SSL *s)
return -1;
}
goto again;
- } else {
- s->internal->empty_record_count = 0;
}
+ s->internal->empty_record_count = 0;
+
return (1);
-f_err:
+ f_err:
ssl3_send_alert(s, SSL3_AL_FATAL, al);
-err:
+ err:
return (ret);
}