aboutsummaryrefslogtreecommitdiff
path: root/ssl
diff options
context:
space:
mode:
Diffstat (limited to 'ssl')
-rw-r--r--ssl/bio_ssl.c10
-rw-r--r--ssl/d1_lib.c3
-rw-r--r--ssl/packet.c8
-rw-r--r--ssl/packet_local.h39
-rw-r--r--ssl/record/rec_layer_s3.c39
-rw-r--r--ssl/record/ssl3_buffer.c10
-rw-r--r--ssl/record/ssl3_record.c52
-rw-r--r--ssl/s3_cbc.c4
-rw-r--r--ssl/s3_enc.c4
-rw-r--r--ssl/s3_lib.c31
-rw-r--r--ssl/s3_msg.c4
-rw-r--r--ssl/ssl_asn1.c4
-rw-r--r--ssl/ssl_cert.c46
-rw-r--r--ssl/ssl_ciph.c7
-rw-r--r--ssl/ssl_err.c7
-rw-r--r--ssl/ssl_init.c19
-rw-r--r--ssl/ssl_lib.c103
-rw-r--r--ssl/ssl_local.h7
-rw-r--r--ssl/ssl_rsa.c83
-rw-r--r--ssl/ssl_txt.c6
-rw-r--r--ssl/statem/README2
-rw-r--r--ssl/statem/extensions.c35
-rw-r--r--ssl/statem/extensions_clnt.c42
-rw-r--r--ssl/statem/extensions_cust.c13
-rw-r--r--ssl/statem/extensions_srvr.c28
-rw-r--r--ssl/statem/statem_clnt.c20
-rw-r--r--ssl/statem/statem_dtls.c8
-rw-r--r--ssl/statem/statem_lib.c4
-rw-r--r--ssl/statem/statem_local.h4
-rw-r--r--ssl/statem/statem_srvr.c49
-rw-r--r--ssl/t1_enc.c4
-rw-r--r--ssl/t1_lib.c27
-rw-r--r--ssl/tls13_enc.c3
33 files changed, 522 insertions, 203 deletions
diff --git a/ssl/bio_ssl.c b/ssl/bio_ssl.c
index 53129bfb8811..67097d5cca41 100644
--- a/ssl/bio_ssl.c
+++ b/ssl/bio_ssl.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -76,13 +76,12 @@ static int ssl_free(BIO *a)
if (a == NULL)
return 0;
bs = BIO_get_data(a);
- if (bs->ssl != NULL)
- SSL_shutdown(bs->ssl);
if (BIO_get_shutdown(a)) {
+ if (bs->ssl != NULL)
+ SSL_shutdown(bs->ssl);
if (BIO_get_init(a))
SSL_free(bs->ssl);
- /* Clear all flags */
- BIO_clear_flags(a, ~0);
+ BIO_clear_flags(a, ~0); /* Clear all flags */
BIO_set_init(a, 0);
}
OPENSSL_free(bs);
@@ -451,6 +450,7 @@ BIO *BIO_new_ssl_connect(SSL_CTX *ctx)
goto err;
return ret;
err:
+ BIO_free(ssl);
BIO_free(con);
#endif
return NULL;
diff --git a/ssl/d1_lib.c b/ssl/d1_lib.c
index afbf015216a3..05b85c1078c0 100644
--- a/ssl/d1_lib.c
+++ b/ssl/d1_lib.c
@@ -342,12 +342,11 @@ int dtls1_is_timer_expired(SSL *s)
return 1;
}
-void dtls1_double_timeout(SSL *s)
+static void dtls1_double_timeout(SSL *s)
{
s->d1->timeout_duration_us *= 2;
if (s->d1->timeout_duration_us > 60000000)
s->d1->timeout_duration_us = 60000000;
- dtls1_start_timer(s);
}
void dtls1_stop_timer(SSL *s)
diff --git a/ssl/packet.c b/ssl/packet.c
index 1ddde969f3b2..d6357495f53e 100644
--- a/ssl/packet.c
+++ b/ssl/packet.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -161,7 +161,7 @@ int WPACKET_set_flags(WPACKET *pkt, unsigned int flags)
}
/* Store the |value| of length |len| at location |data| */
-static int put_value(unsigned char *data, size_t value, size_t len)
+static int put_value(unsigned char *data, uint64_t value, size_t len)
{
for (data += len - 1; len > 0; len--) {
*data = (unsigned char)(value & 0xff);
@@ -306,12 +306,12 @@ int WPACKET_start_sub_packet(WPACKET *pkt)
return WPACKET_start_sub_packet_len__(pkt, 0);
}
-int WPACKET_put_bytes__(WPACKET *pkt, unsigned int val, size_t size)
+int WPACKET_put_bytes__(WPACKET *pkt, uint64_t val, size_t size)
{
unsigned char *data;
/* Internal API, so should not fail */
- if (!ossl_assert(size <= sizeof(unsigned int))
+ if (!ossl_assert(size <= sizeof(uint64_t))
|| !WPACKET_allocate_bytes(pkt, size, &data)
|| !put_value(data, val, size))
return 0;
diff --git a/ssl/packet_local.h b/ssl/packet_local.h
index 1b6c2fb9bc3f..5b1d3fe56edb 100644
--- a/ssl/packet_local.h
+++ b/ssl/packet_local.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -227,6 +227,28 @@ __owur static ossl_inline int PACKET_peek_net_4(const PACKET *pkt,
return 1;
}
+/*
+ * Peek ahead at 8 bytes in network order from |pkt| and store the value in
+ * |*data|
+ */
+__owur static ossl_inline int PACKET_peek_net_8(const PACKET *pkt,
+ uint64_t *data)
+{
+ if (PACKET_remaining(pkt) < 8)
+ return 0;
+
+ *data = ((uint64_t)(*pkt->curr)) << 56;
+ *data |= ((uint64_t)(*(pkt->curr + 1))) << 48;
+ *data |= ((uint64_t)(*(pkt->curr + 2))) << 40;
+ *data |= ((uint64_t)(*(pkt->curr + 3))) << 32;
+ *data |= ((uint64_t)(*(pkt->curr + 4))) << 24;
+ *data |= ((uint64_t)(*(pkt->curr + 5))) << 16;
+ *data |= ((uint64_t)(*(pkt->curr + 6))) << 8;
+ *data |= *(pkt->curr + 7);
+
+ return 1;
+}
+
/* Equivalent of n2l */
/* Get 4 bytes in network order from |pkt| and store the value in |*data| */
__owur static ossl_inline int PACKET_get_net_4(PACKET *pkt, unsigned long *data)
@@ -250,6 +272,17 @@ __owur static ossl_inline int PACKET_get_net_4_len(PACKET *pkt, size_t *data)
return ret;
}
+
+/* Get 8 bytes in network order from |pkt| and store the value in |*data| */
+__owur static ossl_inline int PACKET_get_net_8(PACKET *pkt, uint64_t *data)
+{
+ if (!PACKET_peek_net_8(pkt, data))
+ return 0;
+
+ packet_forward(pkt, 8);
+
+ return 1;
+}
/* Peek ahead at 1 byte from |pkt| and store the value in |*data| */
__owur static ossl_inline int PACKET_peek_1(const PACKET *pkt,
@@ -808,7 +841,7 @@ int WPACKET_sub_reserve_bytes__(WPACKET *pkt, size_t len,
* 1 byte will fail. Don't call this directly. Use the convenience macros below
* instead.
*/
-int WPACKET_put_bytes__(WPACKET *pkt, unsigned int val, size_t bytes);
+int WPACKET_put_bytes__(WPACKET *pkt, uint64_t val, size_t bytes);
/*
* Convenience macros for calling WPACKET_put_bytes with different
@@ -822,6 +855,8 @@ int WPACKET_put_bytes__(WPACKET *pkt, unsigned int val, size_t bytes);
WPACKET_put_bytes__((pkt), (val), 3)
#define WPACKET_put_bytes_u32(pkt, val) \
WPACKET_put_bytes__((pkt), (val), 4)
+#define WPACKET_put_bytes_u64(pkt, val) \
+ WPACKET_put_bytes__((pkt), (val), 8)
/* Set a maximum size that we will not allow the WPACKET to grow beyond */
int WPACKET_set_max_size(WPACKET *pkt, size_t maxsize);
diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c
index b2a7a47eb075..1db1712a0986 100644
--- a/ssl/record/rec_layer_s3.c
+++ b/ssl/record/rec_layer_s3.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -16,6 +16,7 @@
#include <openssl/rand.h>
#include "record_local.h"
#include "../packet_local.h"
+#include "internal/cryptlib.h"
#if defined(OPENSSL_SMALL_FOOTPRINT) || \
!( defined(AESNI_ASM) && ( \
@@ -115,10 +116,22 @@ size_t ssl3_pending(const SSL *s)
if (s->rlayer.rstate == SSL_ST_READ_BODY)
return 0;
+ /* Take into account DTLS buffered app data */
+ if (SSL_IS_DTLS(s)) {
+ DTLS1_RECORD_DATA *rdata;
+ pitem *item, *iter;
+
+ iter = pqueue_iterator(s->rlayer.d->buffered_app_data.q);
+ while ((item = pqueue_next(&iter)) != NULL) {
+ rdata = item->data;
+ num += rdata->rrec.length;
+ }
+ }
+
for (i = 0; i < RECORD_LAYER_get_numrpipes(&s->rlayer); i++) {
if (SSL3_RECORD_get_type(&s->rlayer.rrec[i])
!= SSL3_RT_APPLICATION_DATA)
- return 0;
+ return num;
num += SSL3_RECORD_get_length(&s->rlayer.rrec[i]);
}
@@ -172,9 +185,9 @@ int ssl3_read_n(SSL *s, size_t n, size_t max, int extend, int clearold,
/*
* If extend == 0, obtain new n-byte packet; if extend == 1, increase
* packet by another n bytes. The packet will be in the sub-array of
- * s->s3->rbuf.buf specified by s->packet and s->packet_length. (If
- * s->rlayer.read_ahead is set, 'max' bytes may be stored in rbuf [plus
- * s->packet_length bytes if extend == 1].)
+ * s->rlayer.rbuf.buf specified by s->rlayer.packet and
+ * s->rlayer.packet_length. (If s->rlayer.read_ahead is set, 'max' bytes may
+ * be stored in rbuf [plus s->rlayer.packet_length bytes if extend == 1].)
* if clearold == 1, move the packet to the start of the buffer; if
* clearold == 0 then leave any old packets where they were
*/
@@ -971,11 +984,14 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
}
/*
- * Reserve some bytes for any growth that may occur during encryption.
- * This will be at most one cipher block or the tag length if using
- * AEAD. SSL_RT_MAX_CIPHER_BLOCK_SIZE covers either case.
- */
- if (!WPACKET_reserve_bytes(thispkt, SSL_RT_MAX_CIPHER_BLOCK_SIZE,
+ * Reserve some bytes for any growth that may occur during encryption. If
+ * we are adding the MAC independently of the cipher algorithm, then the
+ * max encrypted overhead does not need to include an allocation for that
+ * MAC
+ */
+ if (!WPACKET_reserve_bytes(thispkt,
+ SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD
+ - mac_size,
NULL)
/*
* We also need next the amount of bytes written to this
@@ -1025,6 +1041,9 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
/* Allocate bytes for the encryption overhead */
if (!WPACKET_get_length(thispkt, &origlen)
+ /* Check we allowed enough room for the encryption growth */
+ || !ossl_assert(origlen + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD
+ - mac_size >= thiswr->length)
/* Encryption should never shrink the data! */
|| origlen > thiswr->length
|| (thiswr->length > origlen
diff --git a/ssl/record/ssl3_buffer.c b/ssl/record/ssl3_buffer.c
index 9b2a6964c689..fa597c274671 100644
--- a/ssl/record/ssl3_buffer.c
+++ b/ssl/record/ssl3_buffer.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -74,7 +74,6 @@ int ssl3_setup_read_buffer(SSL *s)
b->len = len;
}
- RECORD_LAYER_set_packet(&s->rlayer, &(b->buf[0]));
return 1;
}
@@ -98,11 +97,16 @@ int ssl3_setup_write_buffer(SSL *s, size_t numwpipes, size_t len)
#endif
len = ssl_get_max_send_fragment(s)
- + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
+ + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + headerlen + align
+ + SSL_RT_MAX_CIPHER_BLOCK_SIZE /* Explicit IV allowance */;
#ifndef OPENSSL_NO_COMP
if (ssl_allow_compression(s))
len += SSL3_RT_MAX_COMPRESSED_OVERHEAD;
#endif
+ /*
+ * We don't need to add an allowance for eivlen here since empty
+ * fragments only occur when we don't have an explicit IV
+ */
if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
len += headerlen + align + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
}
diff --git a/ssl/record/ssl3_record.c b/ssl/record/ssl3_record.c
index ab5d22aa10cb..47c7369ed549 100644
--- a/ssl/record/ssl3_record.c
+++ b/ssl/record/ssl3_record.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -405,7 +405,7 @@ int ssl3_get_record(SSL *s)
more = thisrr->length;
}
if (more > 0) {
- /* now s->packet_length == SSL3_RT_HEADER_LENGTH */
+ /* now s->rlayer.packet_length == SSL3_RT_HEADER_LENGTH */
rret = ssl3_read_n(s, more, more, 1, 0, &n);
if (rret <= 0)
@@ -416,9 +416,9 @@ int ssl3_get_record(SSL *s)
RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_HEADER);
/*
- * At this point, s->packet_length == SSL3_RT_HEADER_LENGTH
- * + thisrr->length, or s->packet_length == SSL2_RT_HEADER_LENGTH
- * + thisrr->length and we have that many bytes in s->packet
+ * At this point, s->rlayer.packet_length == SSL3_RT_HEADER_LENGTH
+ * + thisrr->length, or s->rlayer.packet_length == SSL2_RT_HEADER_LENGTH
+ * + thisrr->length and we have that many bytes in s->rlayer.packet
*/
if (thisrr->rec_version == SSL2_VERSION) {
thisrr->input =
@@ -429,11 +429,11 @@ int ssl3_get_record(SSL *s)
}
/*
- * ok, we can now read from 's->packet' data into 'thisrr' thisrr->input
- * points at thisrr->length bytes, which need to be copied into
- * thisrr->data by either the decryption or by the decompression When
- * the data is 'copied' into the thisrr->data buffer, thisrr->input will
- * be pointed at the new buffer
+ * ok, we can now read from 's->rlayer.packet' data into 'thisrr'.
+ * thisrr->input points at thisrr->length bytes, which need to be copied
+ * into thisrr->data by either the decryption or by the decompression.
+ * When the data is 'copied' into the thisrr->data buffer,
+ * thisrr->input will be updated to point at the new buffer
*/
/*
@@ -1039,7 +1039,7 @@ int tls1_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending)
if (SSL_IS_DTLS(s)) {
/* DTLS does not support pipelining */
- unsigned char dtlsseq[9], *p = dtlsseq;
+ unsigned char dtlsseq[8], *p = dtlsseq;
s2n(sending ? DTLS_RECORD_LAYER_get_w_epoch(&s->rlayer) :
DTLS_RECORD_LAYER_get_r_epoch(&s->rlayer), p);
@@ -1532,6 +1532,7 @@ int ssl3_cbc_copy_mac(unsigned char *out,
#if defined(CBC_MAC_ROTATE_IN_PLACE)
unsigned char rotated_mac_buf[64 + EVP_MAX_MD_SIZE];
unsigned char *rotated_mac;
+ char aux1, aux2, aux3, mask;
#else
unsigned char rotated_mac[EVP_MAX_MD_SIZE];
#endif
@@ -1581,9 +1582,16 @@ int ssl3_cbc_copy_mac(unsigned char *out,
#if defined(CBC_MAC_ROTATE_IN_PLACE)
j = 0;
for (i = 0; i < md_size; i++) {
- /* in case cache-line is 32 bytes, touch second line */
- ((volatile unsigned char *)rotated_mac)[rotate_offset ^ 32];
- out[j++] = rotated_mac[rotate_offset++];
+ /*
+ * in case cache-line is 32 bytes,
+ * load from both lines and select appropriately
+ */
+ aux1 = rotated_mac[rotate_offset & ~32];
+ aux2 = rotated_mac[rotate_offset | 32];
+ mask = constant_time_eq_8(rotate_offset & ~32, rotate_offset);
+ aux3 = constant_time_select_8(mask, aux1, aux2);
+ out[j++] = aux3;
+ rotate_offset++;
rotate_offset &= constant_time_lt_s(rotate_offset, md_size);
}
#else
@@ -1616,16 +1624,16 @@ int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap)
sess = s->session;
/*
- * At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length,
- * and we have that many bytes in s->packet
+ * At this point, s->rlayer.packet_length == SSL3_RT_HEADER_LNGTH + rr->length,
+ * and we have that many bytes in s->rlayer.packet
*/
rr->input = &(RECORD_LAYER_get_packet(&s->rlayer)[DTLS1_RT_HEADER_LENGTH]);
/*
- * ok, we can now read from 's->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
+ * ok, we can now read from 's->rlayer.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
*/
/*
@@ -1947,7 +1955,7 @@ int dtls1_get_record(SSL *s)
if (rr->length >
RECORD_LAYER_get_packet_length(&s->rlayer) - DTLS1_RT_HEADER_LENGTH) {
- /* now s->packet_length == DTLS1_RT_HEADER_LENGTH */
+ /* now s->rlayer.packet_length == DTLS1_RT_HEADER_LENGTH */
more = rr->length;
rret = ssl3_read_n(s, more, more, 1, 1, &n);
/* this packet contained a partial record, dump it */
@@ -1963,7 +1971,7 @@ int dtls1_get_record(SSL *s)
}
/*
- * now n == rr->length, and s->packet_length ==
+ * now n == rr->length, and s->rlayer.packet_length ==
* DTLS1_RT_HEADER_LENGTH + rr->length
*/
}
diff --git a/ssl/s3_cbc.c b/ssl/s3_cbc.c
index aa7d63f84a9f..c95dcd9fdec1 100644
--- a/ssl/s3_cbc.c
+++ b/ssl/s3_cbc.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2012-2021 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -128,7 +128,7 @@ char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx)
int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
unsigned char *md_out,
size_t *md_out_size,
- const unsigned char header[13],
+ const unsigned char *header,
const unsigned char *data,
size_t data_plus_mac_size,
size_t data_plus_mac_plus_padding_size,
diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c
index 8a89f512fe60..7b119b452fd7 100644
--- a/ssl/s3_enc.c
+++ b/ssl/s3_enc.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2005 Nokia. All rights reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
@@ -589,6 +589,8 @@ int ssl3_alert_code(int code)
return TLS1_AD_NO_APPLICATION_PROTOCOL;
case SSL_AD_CERTIFICATE_REQUIRED:
return SSL_AD_HANDSHAKE_FAILURE;
+ case SSL_AD_MISSING_EXTENSION:
+ return SSL_AD_HANDSHAKE_FAILURE;
default:
return -1;
}
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index 4511b52c9afc..32f9b257106b 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
* Copyright 2005 Nokia. All rights reserved.
*
@@ -2171,7 +2171,7 @@ static SSL_CIPHER ssl3_ciphers[] = {
TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256,
TLS1_RFC_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256,
TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256,
- SSL_kEDH,
+ SSL_kDHE,
SSL_aDSS,
SSL_CAMELLIA128,
SSL_SHA256,
@@ -2187,7 +2187,7 @@ static SSL_CIPHER ssl3_ciphers[] = {
TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
TLS1_RFC_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
- SSL_kEDH,
+ SSL_kDHE,
SSL_aRSA,
SSL_CAMELLIA128,
SSL_SHA256,
@@ -2203,7 +2203,7 @@ static SSL_CIPHER ssl3_ciphers[] = {
TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA256,
TLS1_RFC_ADH_WITH_CAMELLIA_128_CBC_SHA256,
TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA256,
- SSL_kEDH,
+ SSL_kDHE,
SSL_aNULL,
SSL_CAMELLIA128,
SSL_SHA256,
@@ -2235,7 +2235,7 @@ static SSL_CIPHER ssl3_ciphers[] = {
TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256,
TLS1_RFC_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256,
TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256,
- SSL_kEDH,
+ SSL_kDHE,
SSL_aDSS,
SSL_CAMELLIA256,
SSL_SHA256,
@@ -2251,7 +2251,7 @@ static SSL_CIPHER ssl3_ciphers[] = {
TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
TLS1_RFC_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
- SSL_kEDH,
+ SSL_kDHE,
SSL_aRSA,
SSL_CAMELLIA256,
SSL_SHA256,
@@ -2267,7 +2267,7 @@ static SSL_CIPHER ssl3_ciphers[] = {
TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA256,
TLS1_RFC_ADH_WITH_CAMELLIA_256_CBC_SHA256,
TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA256,
- SSL_kEDH,
+ SSL_kDHE,
SSL_aNULL,
SSL_CAMELLIA256,
SSL_SHA256,
@@ -3676,6 +3676,12 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
case SSL_CTRL_SET_CHAIN_CERT_STORE:
return ssl_cert_set_cert_store(s->cert, parg, 1, larg);
+ case SSL_CTRL_GET_VERIFY_CERT_STORE:
+ return ssl_cert_get_cert_store(s->cert, parg, 0);
+
+ case SSL_CTRL_GET_CHAIN_CERT_STORE:
+ return ssl_cert_get_cert_store(s->cert, parg, 1);
+
case SSL_CTRL_GET_PEER_SIGNATURE_NID:
if (s->s3->tmp.peer_sigalg == NULL)
return 0;
@@ -3949,6 +3955,12 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
case SSL_CTRL_SET_CHAIN_CERT_STORE:
return ssl_cert_set_cert_store(ctx->cert, parg, 1, larg);
+ case SSL_CTRL_GET_VERIFY_CERT_STORE:
+ return ssl_cert_get_cert_store(ctx->cert, parg, 0);
+
+ case SSL_CTRL_GET_CHAIN_CERT_STORE:
+ return ssl_cert_get_cert_store(ctx->cert, parg, 1);
+
/* A Thawte special :-) */
case SSL_CTRL_EXTRA_CHAIN_CERT:
if (ctx->extra_certs == NULL) {
@@ -4629,6 +4641,7 @@ int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen,
OPENSSL_clear_free(s->s3->tmp.psk, psklen);
s->s3->tmp.psk = NULL;
+ s->s3->tmp.psklen = 0;
if (!s->method->ssl3_enc->generate_master_secret(s,
s->session->master_key, pskpms, pskpmslen,
&s->session->master_key_length)) {
@@ -4658,8 +4671,10 @@ int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen,
else
OPENSSL_cleanse(pms, pmslen);
}
- if (s->server == 0)
+ if (s->server == 0) {
s->s3->tmp.pms = NULL;
+ s->s3->tmp.pmslen = 0;
+ }
return ret;
}
diff --git a/ssl/s3_msg.c b/ssl/s3_msg.c
index 339fb2774a63..707e962d73d4 100644
--- a/ssl/s3_msg.c
+++ b/ssl/s3_msg.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -48,6 +48,8 @@ int ssl3_send_alert(SSL *s, int level, int desc)
* protocol_version alerts */
if (desc < 0)
return -1;
+ if (s->shutdown & SSL_SENT_SHUTDOWN && desc != SSL_AD_CLOSE_NOTIFY)
+ return -1;
/* If a fatal one, remove from cache */
if ((level == SSL3_AL_FATAL) && (s->session != NULL))
SSL_CTX_remove_session(s->session_ctx, s->session);
diff --git a/ssl/ssl_asn1.c b/ssl/ssl_asn1.c
index 799fee771ba5..926436410050 100644
--- a/ssl/ssl_asn1.c
+++ b/ssl/ssl_asn1.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2005 Nokia. All rights reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
@@ -225,7 +225,7 @@ static int ssl_session_strndup(char **pdst, ASN1_OCTET_STRING *src)
static int ssl_session_memcpy(unsigned char *dst, size_t *pdstlen,
ASN1_OCTET_STRING *src, size_t maxlen)
{
- if (src == NULL) {
+ if (src == NULL || src->length == 0) {
*pdstlen = 0;
return 1;
}
diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c
index 5d3e83f32897..b615e7048da4 100644
--- a/ssl/ssl_cert.c
+++ b/ssl/ssl_cert.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
*
* Licensed under the OpenSSL license (the "License"). You may not use
@@ -876,18 +876,42 @@ int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, int ref)
return 1;
}
-static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx,
- int op, int bits, int nid, void *other,
- void *ex)
+int ssl_cert_get_cert_store(CERT *c, X509_STORE **pstore, int chain)
{
- int level, minbits;
- static const int minbits_table[5] = { 80, 112, 128, 192, 256 };
- if (ctx)
+ *pstore = (chain ? c->chain_store : c->verify_store);
+ return 1;
+}
+
+int ssl_get_security_level_bits(const SSL *s, const SSL_CTX *ctx, int *levelp)
+{
+ int level;
+ static const int minbits_table[5 + 1] = { 0, 80, 112, 128, 192, 256 };
+
+ if (ctx != NULL)
level = SSL_CTX_get_security_level(ctx);
else
level = SSL_get_security_level(s);
- if (level <= 0) {
+ if (level > 5)
+ level = 5;
+ else if (level < 0)
+ level = 0;
+
+ if (levelp != NULL)
+ *levelp = level;
+
+ return minbits_table[level];
+}
+
+static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx,
+ int op, int bits, int nid, void *other,
+ void *ex)
+{
+ int level, minbits, pfs_mask;
+
+ minbits = ssl_get_security_level_bits(s, ctx, &level);
+
+ if (level == 0) {
/*
* No EDH keys weaker than 1024-bits even at level 0, otherwise,
* anything goes.
@@ -896,9 +920,6 @@ static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx,
return 0;
return 1;
}
- if (level > 5)
- level = 5;
- minbits = minbits_table[level - 1];
switch (op) {
case SSL_SECOP_CIPHER_SUPPORTED:
case SSL_SECOP_CIPHER_SHARED:
@@ -921,8 +942,9 @@ static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx,
if (level >= 2 && c->algorithm_enc == SSL_RC4)
return 0;
/* Level 3: forward secure ciphersuites only */
+ pfs_mask = SSL_kDHE | SSL_kECDHE | SSL_kDHEPSK | SSL_kECDHEPSK;
if (level >= 3 && c->min_tls != TLS1_3_VERSION &&
- !(c->algorithm_mkey & (SSL_kEDH | SSL_kEECDH)))
+ !(c->algorithm_mkey & pfs_mask))
return 0;
break;
}
diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c
index 735a483c6448..a3ca5294be2e 100644
--- a/ssl/ssl_ciph.c
+++ b/ssl/ssl_ciph.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
* Copyright 2005 Nokia. All rights reserved.
*
@@ -1026,9 +1026,7 @@ static int ssl_cipher_process_rulestr(const char *rule_str,
* alphanumeric, so we call this an error.
*/
SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, SSL_R_INVALID_COMMAND);
- retval = found = 0;
- l++;
- break;
+ return 0;
}
if (rule == CIPHER_SPECIAL) {
@@ -1601,6 +1599,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
for (i = 0; i < sk_SSL_CIPHER_num(tls13_ciphersuites); i++) {
if (!sk_SSL_CIPHER_push(cipherstack,
sk_SSL_CIPHER_value(tls13_ciphersuites, i))) {
+ OPENSSL_free(co_list);
sk_SSL_CIPHER_free(cipherstack);
return NULL;
}
diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c
index 4b12ed1485d9..324f2ccbb0de 100644
--- a/ssl/ssl_err.c
+++ b/ssl/ssl_err.c
@@ -1,6 +1,6 @@
/*
* Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -85,6 +85,7 @@ static const ERR_STRING_DATA SSL_str_functs[] = {
{ERR_PACK(ERR_LIB_SSL, SSL_F_FINAL_KEY_SHARE, 0), "final_key_share"},
{ERR_PACK(ERR_LIB_SSL, SSL_F_FINAL_MAXFRAGMENTLEN, 0),
"final_maxfragmentlen"},
+ {ERR_PACK(ERR_LIB_SSL, SSL_F_FINAL_PSK, 0), "final_psk"},
{ERR_PACK(ERR_LIB_SSL, SSL_F_FINAL_RENEGOTIATE, 0), "final_renegotiate"},
{ERR_PACK(ERR_LIB_SSL, SSL_F_FINAL_SERVER_NAME, 0), "final_server_name"},
{ERR_PACK(ERR_LIB_SSL, SSL_F_FINAL_SIG_ALGS, 0), "final_sig_algs"},
@@ -948,6 +949,8 @@ static const ERR_STRING_DATA SSL_str_reasons[] = {
"missing ecdsa signing cert"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MISSING_FATAL), "missing fatal"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MISSING_PARAMETERS), "missing parameters"},
+ {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MISSING_PSK_KEX_MODES_EXTENSION),
+ "missing psk kex modes extension"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MISSING_RSA_CERTIFICATE),
"missing rsa certificate"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MISSING_RSA_ENCRYPTING_CERT),
@@ -1018,6 +1021,8 @@ static const ERR_STRING_DATA SSL_str_reasons[] = {
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NULL_SSL_CTX), "null ssl ctx"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NULL_SSL_METHOD_PASSED),
"null ssl method passed"},
+ {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_OCSP_CALLBACK_FAILURE),
+ "ocsp callback failure"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED),
"old session cipher not returned"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED),
diff --git a/ssl/ssl_init.c b/ssl/ssl_init.c
index d083d9597091..a5d45480c9e0 100644
--- a/ssl/ssl_init.c
+++ b/ssl/ssl_init.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -116,7 +116,7 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_ssl_base)
}
static CRYPTO_ONCE ssl_strings = CRYPTO_ONCE_STATIC_INIT;
-static int ssl_strings_inited = 0;
+
DEFINE_RUN_ONCE_STATIC(ossl_init_load_ssl_strings)
{
/*
@@ -129,7 +129,6 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_load_ssl_strings)
"ERR_load_SSL_strings()\n");
# endif
ERR_load_SSL_strings();
- ssl_strings_inited = 1;
#endif
return 1;
}
@@ -157,20 +156,6 @@ static void ssl_library_stop(void)
ssl_comp_free_compression_methods_int();
#endif
}
-
- if (ssl_strings_inited) {
-#ifdef OPENSSL_INIT_DEBUG
- fprintf(stderr, "OPENSSL_INIT: ssl_library_stop: "
- "err_free_strings_int()\n");
-#endif
- /*
- * If both crypto and ssl error strings are inited we will end up
- * calling err_free_strings_int() twice - but that's ok. The second
- * time will be a no-op. It's easier to do that than to try and track
- * between the two libraries whether they have both been inited.
- */
- err_free_strings_int();
- }
}
/*
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 98057921f840..47adc3211c85 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
* Copyright 2005 Nokia. All rights reserved.
*
@@ -779,8 +779,10 @@ SSL *SSL_new(SSL_CTX *ctx)
s->ext.ecpointformats =
OPENSSL_memdup(ctx->ext.ecpointformats,
ctx->ext.ecpointformats_len);
- if (!s->ext.ecpointformats)
+ if (!s->ext.ecpointformats) {
+ s->ext.ecpointformats_len = 0;
goto err;
+ }
s->ext.ecpointformats_len =
ctx->ext.ecpointformats_len;
}
@@ -789,8 +791,10 @@ SSL *SSL_new(SSL_CTX *ctx)
OPENSSL_memdup(ctx->ext.supportedgroups,
ctx->ext.supportedgroups_len
* sizeof(*ctx->ext.supportedgroups));
- if (!s->ext.supportedgroups)
+ if (!s->ext.supportedgroups) {
+ s->ext.supportedgroups_len = 0;
goto err;
+ }
s->ext.supportedgroups_len = ctx->ext.supportedgroups_len;
}
#endif
@@ -800,8 +804,10 @@ SSL *SSL_new(SSL_CTX *ctx)
if (s->ctx->ext.alpn) {
s->ext.alpn = OPENSSL_malloc(s->ctx->ext.alpn_len);
- if (s->ext.alpn == NULL)
+ if (s->ext.alpn == NULL) {
+ s->ext.alpn_len = 0;
goto err;
+ }
memcpy(s->ext.alpn, s->ctx->ext.alpn, s->ctx->ext.alpn_len);
s->ext.alpn_len = s->ctx->ext.alpn_len;
}
@@ -1504,12 +1510,26 @@ int SSL_has_pending(const SSL *s)
{
/*
* Similar to SSL_pending() but returns a 1 to indicate that we have
- * unprocessed data available or 0 otherwise (as opposed to the number of
- * bytes available). Unlike SSL_pending() this will take into account
- * read_ahead data. A 1 return simply indicates that we have unprocessed
- * data. That data may not result in any application data, or we may fail
- * to parse the records for some reason.
+ * processed or unprocessed data available or 0 otherwise (as opposed to the
+ * number of bytes available). Unlike SSL_pending() this will take into
+ * account read_ahead data. A 1 return simply indicates that we have data.
+ * That data may not result in any application data, or we may fail to parse
+ * the records for some reason.
*/
+
+ /* Check buffered app data if any first */
+ if (SSL_IS_DTLS(s)) {
+ DTLS1_RECORD_DATA *rdata;
+ pitem *item, *iter;
+
+ iter = pqueue_iterator(s->rlayer.d->buffered_app_data.q);
+ while ((item = pqueue_next(&iter)) != NULL) {
+ rdata = item->data;
+ if (rdata->rrec.length > 0)
+ return 1;
+ }
+ }
+
if (RECORD_LAYER_processed_read_pending(&s->rlayer))
return 1;
@@ -1678,6 +1698,8 @@ static int ssl_start_async_job(SSL *s, struct ssl_async_args *args,
if (s->waitctx == NULL)
return -1;
}
+
+ s->rwstate = SSL_NOTHING;
switch (ASYNC_start_job(&s->job, s->waitctx, &ret, func, args,
sizeof(struct ssl_async_args))) {
case ASYNC_ERR:
@@ -2076,6 +2098,7 @@ int SSL_shutdown(SSL *s)
if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
struct ssl_async_args args;
+ memset(&args, 0, sizeof(args));
args.s = s;
args.type = OTHERFUNC;
args.f.func_other = s->method->ssl_shutdown;
@@ -2113,6 +2136,11 @@ int SSL_key_update(SSL *s, int updatetype)
return 0;
}
+ if (RECORD_LAYER_write_pending(&s->rlayer)) {
+ SSLerr(SSL_F_SSL_KEY_UPDATE, SSL_R_BAD_WRITE_RETRY);
+ return 0;
+ }
+
ossl_statem_set_in_init(s, 1);
s->key_update = updatetype;
return 1;
@@ -2823,6 +2851,19 @@ void SSL_CTX_set_npn_select_cb(SSL_CTX *ctx,
}
#endif
+static int alpn_value_ok(const unsigned char *protos, unsigned int protos_len)
+{
+ unsigned int idx;
+
+ if (protos_len < 2 || protos == NULL)
+ return 0;
+
+ for (idx = 0; idx < protos_len; idx += protos[idx] + 1) {
+ if (protos[idx] == 0)
+ return 0;
+ }
+ return idx == protos_len;
+}
/*
* SSL_CTX_set_alpn_protos sets the ALPN protocol list on |ctx| to |protos|.
* |protos| must be in wire-format (i.e. a series of non-empty, 8-bit
@@ -2831,12 +2872,25 @@ void SSL_CTX_set_npn_select_cb(SSL_CTX *ctx,
int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos,
unsigned int protos_len)
{
- OPENSSL_free(ctx->ext.alpn);
- ctx->ext.alpn = OPENSSL_memdup(protos, protos_len);
- if (ctx->ext.alpn == NULL) {
+ unsigned char *alpn;
+
+ if (protos_len == 0 || protos == NULL) {
+ OPENSSL_free(ctx->ext.alpn);
+ ctx->ext.alpn = NULL;
+ ctx->ext.alpn_len = 0;
+ return 0;
+ }
+ /* Not valid per RFC */
+ if (!alpn_value_ok(protos, protos_len))
+ return 1;
+
+ alpn = OPENSSL_memdup(protos, protos_len);
+ if (alpn == NULL) {
SSLerr(SSL_F_SSL_CTX_SET_ALPN_PROTOS, ERR_R_MALLOC_FAILURE);
return 1;
}
+ OPENSSL_free(ctx->ext.alpn);
+ ctx->ext.alpn = alpn;
ctx->ext.alpn_len = protos_len;
return 0;
@@ -2850,12 +2904,25 @@ int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos,
int SSL_set_alpn_protos(SSL *ssl, const unsigned char *protos,
unsigned int protos_len)
{
- OPENSSL_free(ssl->ext.alpn);
- ssl->ext.alpn = OPENSSL_memdup(protos, protos_len);
- if (ssl->ext.alpn == NULL) {
+ unsigned char *alpn;
+
+ if (protos_len == 0 || protos == NULL) {
+ OPENSSL_free(ssl->ext.alpn);
+ ssl->ext.alpn = NULL;
+ ssl->ext.alpn_len = 0;
+ return 0;
+ }
+ /* Not valid per RFC */
+ if (!alpn_value_ok(protos, protos_len))
+ return 1;
+
+ alpn = OPENSSL_memdup(protos, protos_len);
+ if (alpn == NULL) {
SSLerr(SSL_F_SSL_SET_ALPN_PROTOS, ERR_R_MALLOC_FAILURE);
return 1;
}
+ OPENSSL_free(ssl->ext.alpn);
+ ssl->ext.alpn = alpn;
ssl->ext.alpn_len = protos_len;
return 0;
@@ -3657,6 +3724,7 @@ int SSL_do_handshake(SSL *s)
if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
struct ssl_async_args args;
+ memset(&args, 0, sizeof(args));
args.s = s;
ret = ssl_start_async_job(s, &args, ssl_do_handshake_intern);
@@ -4512,8 +4580,11 @@ int ssl_handshake_hash(SSL *s, unsigned char *out, size_t outlen,
}
ctx = EVP_MD_CTX_new();
- if (ctx == NULL)
+ if (ctx == NULL) {
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_HANDSHAKE_HASH,
+ ERR_R_INTERNAL_ERROR);
goto err;
+ }
if (!EVP_MD_CTX_copy_ex(ctx, hdgst)
|| EVP_DigestFinal_ex(ctx, out, NULL) <= 0) {
diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h
index 8c3542a5422f..5c7921542310 100644
--- a/ssl/ssl_local.h
+++ b/ssl/ssl_local.h
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
* Copyright 2005 Nokia. All rights reserved.
*
@@ -2301,10 +2301,12 @@ __owur int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk);
__owur int ssl_build_cert_chain(SSL *s, SSL_CTX *ctx, int flags);
__owur int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain,
int ref);
+__owur int ssl_cert_get_cert_store(CERT *c, X509_STORE **pstore, int chain);
__owur int ssl_security(const SSL *s, int op, int bits, int nid, void *other);
__owur int ssl_ctx_security(const SSL_CTX *ctx, int op, int bits, int nid,
void *other);
+int ssl_get_security_level_bits(const SSL *s, const SSL_CTX *ctx, int *levelp);
__owur int ssl_cert_lookup_by_nid(int nid, size_t *pidx);
__owur const SSL_CERT_LOOKUP *ssl_cert_lookup_by_pkey(const EVP_PKEY *pk,
@@ -2426,7 +2428,6 @@ __owur int dtls1_handle_timeout(SSL *s);
void dtls1_start_timer(SSL *s);
void dtls1_stop_timer(SSL *s);
__owur int dtls1_is_timer_expired(SSL *s);
-void dtls1_double_timeout(SSL *s);
__owur int dtls_raw_hello_verify_request(WPACKET *pkt, unsigned char *cookie,
size_t cookie_len);
__owur size_t dtls1_min_mtu(SSL *s);
@@ -2622,7 +2623,7 @@ __owur char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx);
__owur int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
unsigned char *md_out,
size_t *md_out_size,
- const unsigned char header[13],
+ const unsigned char *header,
const unsigned char *data,
size_t data_plus_mac_size,
size_t data_plus_mac_plus_padding_size,
diff --git a/ssl/ssl_rsa.c b/ssl/ssl_rsa.c
index 6457c0c0efa3..2df07bea6782 100644
--- a/ssl/ssl_rsa.c
+++ b/ssl/ssl_rsa.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -727,6 +727,34 @@ static int serverinfoex_srv_parse_cb(SSL *s, unsigned int ext_type,
return 1;
}
+static size_t extension_contextoff(unsigned int version)
+{
+ return version == SSL_SERVERINFOV1 ? 4 : 0;
+}
+
+static size_t extension_append_length(unsigned int version, size_t extension_length)
+{
+ return extension_length + extension_contextoff(version);
+}
+
+static void extension_append(unsigned int version,
+ const unsigned char *extension,
+ const size_t extension_length,
+ unsigned char *serverinfo)
+{
+ const size_t contextoff = extension_contextoff(version);
+
+ if (contextoff > 0) {
+ /* We know this only uses the last 2 bytes */
+ serverinfo[0] = 0;
+ serverinfo[1] = 0;
+ serverinfo[2] = (SYNTHV1CONTEXT >> 8) & 0xff;
+ serverinfo[3] = SYNTHV1CONTEXT & 0xff;
+ }
+
+ memcpy(serverinfo + contextoff, extension, extension_length);
+}
+
static int serverinfo_srv_parse_cb(SSL *s, unsigned int ext_type,
const unsigned char *in,
size_t inlen, int *al, void *arg)
@@ -842,12 +870,36 @@ int SSL_CTX_use_serverinfo_ex(SSL_CTX *ctx, unsigned int version,
const unsigned char *serverinfo,
size_t serverinfo_length)
{
- unsigned char *new_serverinfo;
+ unsigned char *new_serverinfo = NULL;
if (ctx == NULL || serverinfo == NULL || serverinfo_length == 0) {
SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_EX, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
+ if (version == SSL_SERVERINFOV1) {
+ /*
+ * Convert serverinfo version v1 to v2 and call yourself recursively
+ * over the converted serverinfo.
+ */
+ const size_t sinfo_length = extension_append_length(SSL_SERVERINFOV1,
+ serverinfo_length);
+ unsigned char *sinfo;
+ int ret;
+
+ sinfo = OPENSSL_malloc(sinfo_length);
+ if (sinfo == NULL) {
+ SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_EX, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+
+ extension_append(SSL_SERVERINFOV1, serverinfo, serverinfo_length, sinfo);
+
+ ret = SSL_CTX_use_serverinfo_ex(ctx, SSL_SERVERINFOV2, sinfo,
+ sinfo_length);
+
+ OPENSSL_free(sinfo);
+ return ret;
+ }
if (!serverinfo_process_buffer(version, serverinfo, serverinfo_length,
NULL)) {
SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_EX, SSL_R_INVALID_SERVERINFO_DATA);
@@ -899,7 +951,7 @@ int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file)
char namePrefix2[] = "SERVERINFOV2 FOR ";
int ret = 0;
BIO *bin = NULL;
- size_t num_extensions = 0, contextoff = 0;
+ size_t num_extensions = 0;
if (ctx == NULL || file == NULL) {
SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_PASSED_NULL_PARAMETER);
@@ -918,6 +970,7 @@ int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file)
for (num_extensions = 0;; num_extensions++) {
unsigned int version;
+ size_t append_length;
if (PEM_read_bio(bin, &name, &header, &extension, &extension_length)
== 0) {
@@ -962,11 +1015,6 @@ int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file)
SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, SSL_R_BAD_DATA);
goto end;
}
- /*
- * File does not have a context value so we must take account of
- * this later.
- */
- contextoff = 4;
} else {
/* 8 byte header: 4 bytes context, 2 bytes type, 2 bytes len */
if (extension_length < 8
@@ -977,25 +1025,16 @@ int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file)
}
}
/* Append the decoded extension to the serverinfo buffer */
- tmp = OPENSSL_realloc(serverinfo, serverinfo_length + extension_length
- + contextoff);
+ append_length = extension_append_length(version, extension_length);
+ tmp = OPENSSL_realloc(serverinfo, serverinfo_length + append_length);
if (tmp == NULL) {
SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_MALLOC_FAILURE);
goto end;
}
serverinfo = tmp;
- if (contextoff > 0) {
- unsigned char *sinfo = serverinfo + serverinfo_length;
-
- /* We know this only uses the last 2 bytes */
- sinfo[0] = 0;
- sinfo[1] = 0;
- sinfo[2] = (SYNTHV1CONTEXT >> 8) & 0xff;
- sinfo[3] = SYNTHV1CONTEXT & 0xff;
- }
- memcpy(serverinfo + serverinfo_length + contextoff,
- extension, extension_length);
- serverinfo_length += extension_length + contextoff;
+ extension_append(version, extension, extension_length,
+ serverinfo + serverinfo_length);
+ serverinfo_length += append_length;
OPENSSL_free(name);
name = NULL;
diff --git a/ssl/ssl_txt.c b/ssl/ssl_txt.c
index 457bc8b3c20a..759e1873e6b1 100644
--- a/ssl/ssl_txt.c
+++ b/ssl/ssl_txt.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2005 Nokia. All rights reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
@@ -130,11 +130,11 @@ int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x)
}
#endif
if (x->time != 0L) {
- if (BIO_printf(bp, "\n Start Time: %ld", x->time) <= 0)
+ if (BIO_printf(bp, "\n Start Time: %lld", (long long)x->time) <= 0)
goto err;
}
if (x->timeout != 0L) {
- if (BIO_printf(bp, "\n Timeout : %ld (sec)", x->timeout) <= 0)
+ if (BIO_printf(bp, "\n Timeout : %lld (sec)", (long long)x->timeout) <= 0)
goto err;
}
if (BIO_puts(bp, "\n") <= 0)
diff --git a/ssl/statem/README b/ssl/statem/README
index 86cc06637291..bafe33060c92 100644
--- a/ssl/statem/README
+++ b/ssl/statem/README
@@ -55,7 +55,7 @@ Conceptually the state machine component is designed as follows:
| | | |
____________V_______V________ ________V______V_______________
| | | |
- | statem_both.c | | statem_dtls.c |
+ | statem_lib.c | | statem_dtls.c |
| | | |
| Non core functions common | | Non core functions common to |
| to both servers and clients | | both DTLS servers and clients |
diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c
index 9f51a6eb28d9..0f39275baa01 100644
--- a/ssl/statem/extensions.c
+++ b/ssl/statem/extensions.c
@@ -18,6 +18,7 @@ static int final_renegotiate(SSL *s, unsigned int context, int sent);
static int init_server_name(SSL *s, unsigned int context);
static int final_server_name(SSL *s, unsigned int context, int sent);
#ifndef OPENSSL_NO_EC
+static int init_ec_point_formats(SSL *s, unsigned int context);
static int final_ec_pt_formats(SSL *s, unsigned int context, int sent);
#endif
static int init_session_ticket(SSL *s, unsigned int context);
@@ -56,6 +57,7 @@ static int final_sig_algs(SSL *s, unsigned int context, int sent);
static int final_early_data(SSL *s, unsigned int context, int sent);
static int final_maxfragmentlen(SSL *s, unsigned int context, int sent);
static int init_post_handshake_auth(SSL *s, unsigned int context);
+static int final_psk(SSL *s, unsigned int context, int sent);
/* Structure to define a built-in extension */
typedef struct extensions_definition_st {
@@ -158,7 +160,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
TLSEXT_TYPE_ec_point_formats,
SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_2_SERVER_HELLO
| SSL_EXT_TLS1_2_AND_BELOW_ONLY,
- NULL, tls_parse_ctos_ec_pt_formats, tls_parse_stoc_ec_pt_formats,
+ init_ec_point_formats, tls_parse_ctos_ec_pt_formats, tls_parse_stoc_ec_pt_formats,
tls_construct_stoc_ec_pt_formats, tls_construct_ctos_ec_pt_formats,
final_ec_pt_formats
},
@@ -336,6 +338,8 @@ static const EXTENSION_DEFINITION ext_defs[] = {
tls_construct_stoc_key_share, tls_construct_ctos_key_share,
final_key_share
},
+#else
+ INVALID_EXTENSION,
#endif
{
/* Must be after key_share */
@@ -387,7 +391,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_SERVER_HELLO
| SSL_EXT_TLS_IMPLEMENTATION_ONLY | SSL_EXT_TLS1_3_ONLY,
NULL, tls_parse_ctos_psk, tls_parse_stoc_psk, tls_construct_stoc_psk,
- tls_construct_ctos_psk, NULL
+ tls_construct_ctos_psk, final_psk
}
};
@@ -1024,6 +1028,15 @@ static int final_server_name(SSL *s, unsigned int context, int sent)
}
#ifndef OPENSSL_NO_EC
+static int init_ec_point_formats(SSL *s, unsigned int context)
+{
+ OPENSSL_free(s->ext.peer_ecpointformats);
+ s->ext.peer_ecpointformats = NULL;
+ s->ext.peer_ecpointformats_len = 0;
+
+ return 1;
+}
+
static int final_ec_pt_formats(SSL *s, unsigned int context, int sent)
{
unsigned long alg_k, alg_a;
@@ -1137,6 +1150,7 @@ static int init_sig_algs(SSL *s, unsigned int context)
/* Clear any signature algorithms extension received */
OPENSSL_free(s->s3->tmp.peer_sigalgs);
s->s3->tmp.peer_sigalgs = NULL;
+ s->s3->tmp.peer_sigalgslen = 0;
return 1;
}
@@ -1146,6 +1160,7 @@ static int init_sig_algs_cert(SSL *s, unsigned int context)
/* Clear any signature algorithms extension received */
OPENSSL_free(s->s3->tmp.peer_cert_sigalgs);
s->s3->tmp.peer_cert_sigalgs = NULL;
+ s->s3->tmp.peer_cert_sigalgslen = 0;
return 1;
}
@@ -1714,3 +1729,19 @@ static int init_post_handshake_auth(SSL *s, unsigned int context)
return 1;
}
+
+/*
+ * If clients offer "pre_shared_key" without a "psk_key_exchange_modes"
+ * extension, servers MUST abort the handshake.
+ */
+static int final_psk(SSL *s, unsigned int context, int sent)
+{
+ if (s->server && sent && s->clienthello != NULL
+ && !s->clienthello->pre_proc_exts[TLSEXT_IDX_psk_kex_modes].present) {
+ SSLfatal(s, TLS13_AD_MISSING_EXTENSION, SSL_F_FINAL_PSK,
+ SSL_R_MISSING_PSK_KEX_MODES_EXTENSION);
+ return 0;
+ }
+
+ return 1;
+}
diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c
index bcce0f1d9534..1cbaefa9f123 100644
--- a/ssl/statem/extensions_clnt.c
+++ b/ssl/statem/extensions_clnt.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -118,6 +118,8 @@ static int use_ecc(SSL *s)
int i, end, ret = 0;
unsigned long alg_k, alg_a;
STACK_OF(SSL_CIPHER) *cipher_stack = NULL;
+ const uint16_t *pgroups = NULL;
+ size_t num_groups, j;
/* See if we support any ECC ciphersuites */
if (s->version == SSL3_VERSION)
@@ -139,7 +141,19 @@ static int use_ecc(SSL *s)
}
sk_SSL_CIPHER_free(cipher_stack);
- return ret;
+ if (!ret)
+ return 0;
+
+ /* Check we have at least one EC supported group */
+ tls1_get_supported_groups(s, &pgroups, &num_groups);
+ for (j = 0; j < num_groups; j++) {
+ uint16_t ctmp = pgroups[j];
+
+ if (tls_curve_allowed(s, ctmp, SSL_SECOP_CURVE_SUPPORTED))
+ return 1;
+ }
+
+ return 0;
}
EXT_RETURN tls_construct_ctos_ec_pt_formats(SSL *s, WPACKET *pkt,
@@ -816,6 +830,7 @@ EXT_RETURN tls_construct_ctos_early_data(SSL *s, WPACKET *pkt,
OPENSSL_free(s->psksession_id);
s->psksession_id = OPENSSL_memdup(id, idlen);
if (s->psksession_id == NULL) {
+ s->psksession_id_len = 0;
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA, ERR_R_INTERNAL_ERROR);
return EXT_RETURN_FAIL;
@@ -987,7 +1002,7 @@ EXT_RETURN tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context,
X509 *x, size_t chainidx)
{
#ifndef OPENSSL_NO_TLS1_3
- uint32_t now, agesec, agems = 0;
+ uint32_t agesec, agems = 0;
size_t reshashsize = 0, pskhashsize = 0, binderoffset, msglen;
unsigned char *resbinder = NULL, *pskbinder = NULL, *msgstart = NULL;
const EVP_MD *handmd = NULL, *mdres = NULL, *mdpsk = NULL;
@@ -1044,8 +1059,7 @@ EXT_RETURN tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context,
* this in multiple places in the code, so portability shouldn't be an
* issue.
*/
- now = (uint32_t)time(NULL);
- agesec = now - (uint32_t)s->session->time;
+ agesec = (uint32_t)(time(NULL) - s->session->time);
/*
* We calculate the age in seconds but the server may work in ms. Due to
* rounding errors we could overestimate the age by up to 1s. It is
@@ -1375,6 +1389,7 @@ int tls_parse_stoc_ec_pt_formats(SSL *s, PACKET *pkt, unsigned int context,
OPENSSL_free(s->ext.peer_ecpointformats);
s->ext.peer_ecpointformats = OPENSSL_malloc(ecpointformats_len);
if (s->ext.peer_ecpointformats == NULL) {
+ s->ext.peer_ecpointformats_len = 0;
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
SSL_F_TLS_PARSE_STOC_EC_PT_FORMATS, ERR_R_INTERNAL_ERROR);
return 0;
@@ -1492,8 +1507,13 @@ int tls_parse_stoc_sct(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
s->ext.scts_len = (uint16_t)size;
if (size > 0) {
s->ext.scts = OPENSSL_malloc(size);
- if (s->ext.scts == NULL
- || !PACKET_copy_bytes(pkt, s->ext.scts, size)) {
+ if (s->ext.scts == NULL) {
+ s->ext.scts_len = 0;
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_SCT,
+ ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ if (!PACKET_copy_bytes(pkt, s->ext.scts, size)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_SCT,
ERR_R_INTERNAL_ERROR);
return 0;
@@ -1592,6 +1612,7 @@ int tls_parse_stoc_npn(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
OPENSSL_free(s->ext.npn);
s->ext.npn = OPENSSL_malloc(selected_len);
if (s->ext.npn == NULL) {
+ s->ext.npn_len = 0;
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_NPN,
ERR_R_INTERNAL_ERROR);
return 0;
@@ -1632,6 +1653,7 @@ int tls_parse_stoc_alpn(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
OPENSSL_free(s->s3->alpn_selected);
s->s3->alpn_selected = OPENSSL_malloc(len);
if (s->s3->alpn_selected == NULL) {
+ s->s3->alpn_selected_len = 0;
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_ALPN,
ERR_R_INTERNAL_ERROR);
return 0;
@@ -1663,6 +1685,7 @@ int tls_parse_stoc_alpn(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
s->session->ext.alpn_selected =
OPENSSL_memdup(s->s3->alpn_selected, s->s3->alpn_selected_len);
if (s->session->ext.alpn_selected == NULL) {
+ s->session->ext.alpn_selected_len = 0;
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_ALPN,
ERR_R_INTERNAL_ERROR);
return 0;
@@ -1731,7 +1754,9 @@ int tls_parse_stoc_etm(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
/* Ignore if inappropriate ciphersuite */
if (!(s->options & SSL_OP_NO_ENCRYPT_THEN_MAC)
&& s->s3->tmp.new_cipher->algorithm_mac != SSL_AEAD
- && s->s3->tmp.new_cipher->algorithm_enc != SSL_RC4)
+ && s->s3->tmp.new_cipher->algorithm_enc != SSL_RC4
+ && s->s3->tmp.new_cipher->algorithm_enc != SSL_eGOST2814789CNT
+ && s->s3->tmp.new_cipher->algorithm_enc != SSL_eGOST2814789CNT12)
s->ext.use_etm = 1;
return 1;
@@ -1862,6 +1887,7 @@ int tls_parse_stoc_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
if (skey == NULL || EVP_PKEY_copy_parameters(skey, ckey) <= 0) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_KEY_SHARE,
ERR_R_MALLOC_FAILURE);
+ EVP_PKEY_free(skey);
return 0;
}
if (!EVP_PKEY_set1_tls_encodedpoint(skey, PACKET_data(&encoded_pt),
diff --git a/ssl/statem/extensions_cust.c b/ssl/statem/extensions_cust.c
index a0ba18efa704..1fe226f9f264 100644
--- a/ssl/statem/extensions_cust.c
+++ b/ssl/statem/extensions_cust.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2014-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2014-2021 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -146,11 +146,12 @@ int custom_ext_parse(SSL *s, unsigned int context, unsigned int ext_type,
}
/*
- * Extensions received in the ClientHello are marked with the
- * SSL_EXT_FLAG_RECEIVED. This is so we know to add the equivalent
- * extensions in the ServerHello/EncryptedExtensions message
+ * Extensions received in the ClientHello or CertificateRequest are marked
+ * with the SSL_EXT_FLAG_RECEIVED. This is so we know to add the equivalent
+ * extensions in the response messages
*/
- if ((context & SSL_EXT_CLIENT_HELLO) != 0)
+ if ((context & (SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_CERTIFICATE_REQUEST))
+ != 0)
meth->ext_flags |= SSL_EXT_FLAG_RECEIVED;
/* If no parse function set return success */
@@ -192,7 +193,7 @@ int custom_ext_add(SSL *s, int context, WPACKET *pkt, X509 *x, size_t chainidx,
| SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS
| SSL_EXT_TLS1_3_CERTIFICATE
| SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST)) != 0) {
- /* Only send extensions present in ClientHello. */
+ /* Only send extensions present in ClientHello/CertificateRequest */
if (!(meth->ext_flags & SSL_EXT_FLAG_RECEIVED))
continue;
}
diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c
index 3c7395c0eb26..47541101db50 100644
--- a/ssl/statem/extensions_srvr.c
+++ b/ssl/statem/extensions_srvr.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -12,16 +12,16 @@
#include "statem_local.h"
#include "internal/cryptlib.h"
-#define COOKIE_STATE_FORMAT_VERSION 0
+#define COOKIE_STATE_FORMAT_VERSION 1
/*
* 2 bytes for packet length, 2 bytes for format version, 2 bytes for
* protocol version, 2 bytes for group id, 2 bytes for cipher id, 1 byte for
- * key_share present flag, 4 bytes for timestamp, 2 bytes for the hashlen,
+ * key_share present flag, 8 bytes for timestamp, 2 bytes for the hashlen,
* EVP_MAX_MD_SIZE for transcript hash, 1 byte for app cookie length, app cookie
* length bytes, SHA256_DIGEST_LENGTH bytes for the HMAC of the whole thing.
*/
-#define MAX_COOKIE_SIZE (2 + 2 + 2 + 2 + 2 + 1 + 4 + 2 + EVP_MAX_MD_SIZE + 1 \
+#define MAX_COOKIE_SIZE (2 + 2 + 2 + 2 + 2 + 1 + 8 + 2 + EVP_MAX_MD_SIZE + 1 \
+ SSL_COOKIE_LENGTH + SHA256_DIGEST_LENGTH)
/*
@@ -741,7 +741,7 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
unsigned char hmac[SHA256_DIGEST_LENGTH];
unsigned char hrr[MAX_HRR_SIZE];
size_t rawlen, hmaclen, hrrlen, ciphlen;
- unsigned long tm, now;
+ uint64_t tm, now;
/* Ignore any cookie if we're not set up to verify it */
if (s->ctx->verify_stateless_cookie_cb == NULL
@@ -851,7 +851,7 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
}
if (!PACKET_get_1(&cookie, &key_share)
- || !PACKET_get_net_4(&cookie, &tm)
+ || !PACKET_get_net_8(&cookie, &tm)
|| !PACKET_get_length_prefixed_2(&cookie, &chhash)
|| !PACKET_get_length_prefixed_1(&cookie, &appcookie)
|| PACKET_remaining(&cookie) != SHA256_DIGEST_LENGTH) {
@@ -861,7 +861,7 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
}
/* We tolerate a cookie age of up to 10 minutes (= 60 * 10 seconds) */
- now = (unsigned long)time(NULL);
+ now = time(NULL);
if (tm > now || (now - tm) > 600) {
/* Cookie is stale. Ignore it */
return 1;
@@ -1167,7 +1167,7 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
s->ext.early_data_ok = 1;
s->ext.ticket_expected = 1;
} else {
- uint32_t ticket_age = 0, now, agesec, agems;
+ uint32_t ticket_age = 0, agesec, agems;
int ret;
/*
@@ -1209,8 +1209,7 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
}
ticket_age = (uint32_t)ticket_agel;
- now = (uint32_t)time(NULL);
- agesec = now - (uint32_t)sess->time;
+ agesec = (uint32_t)(time(NULL) - sess->time);
agems = agesec * (uint32_t)1000;
ticket_age -= sess->ext.tick_age_add;
@@ -1714,6 +1713,13 @@ EXT_RETURN tls_construct_stoc_key_share(SSL *s, WPACKET *pkt,
}
return EXT_RETURN_NOT_SENT;
}
+ if (s->hit && (s->ext.psk_kex_mode & TLSEXT_KEX_MODE_FLAG_KE_DHE) == 0) {
+ /*
+ * PSK ('hit') and explicitly not doing DHE (if the client sent the
+ * DHE option we always take it); don't send key share.
+ */
+ return EXT_RETURN_NOT_SENT;
+ }
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_key_share)
|| !WPACKET_start_sub_packet_u16(pkt)
@@ -1793,7 +1799,7 @@ EXT_RETURN tls_construct_stoc_cookie(SSL *s, WPACKET *pkt, unsigned int context,
&ciphlen)
/* Is there a key_share extension present in this HRR? */
|| !WPACKET_put_bytes_u8(pkt, s->s3->peer_tmp == NULL)
- || !WPACKET_put_bytes_u32(pkt, (unsigned int)time(NULL))
+ || !WPACKET_put_bytes_u64(pkt, time(NULL))
|| !WPACKET_start_sub_packet_u16(pkt)
|| !WPACKET_reserve_bytes(pkt, EVP_MAX_MD_SIZE, &hashval1)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_COOKIE,
diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c
index d84cc0460f4e..d19c44e8d984 100644
--- a/ssl/statem/statem_clnt.c
+++ b/ssl/statem/statem_clnt.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
* Copyright 2005 Nokia. All rights reserved.
*
@@ -1001,7 +1001,8 @@ size_t ossl_statem_client_max_message_size(SSL *s)
return CCS_MAX_LENGTH;
case TLS_ST_CR_SESSION_TICKET:
- return SSL3_RT_MAX_PLAIN_LENGTH;
+ return (SSL_IS_TLS13(s)) ? SESSION_TICKET_MAX_LENGTH_TLS13
+ : SESSION_TICKET_MAX_LENGTH_TLS12;
case TLS_ST_CR_FINISHED:
return FINISHED_MAX_LENGTH;
@@ -1421,6 +1422,11 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt)
&& sversion == TLS1_2_VERSION
&& PACKET_remaining(pkt) >= SSL3_RANDOM_SIZE
&& memcmp(hrrrandom, PACKET_data(pkt), SSL3_RANDOM_SIZE) == 0) {
+ if (s->hello_retry_request != SSL_HRR_NONE) {
+ SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE,
+ SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_UNEXPECTED_MESSAGE);
+ goto err;
+ }
s->hello_retry_request = SSL_HRR_PENDING;
hrr = 1;
if (!PACKET_forward(pkt, SSL3_RANDOM_SIZE)) {
@@ -2462,6 +2468,7 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt)
s->s3->tmp.ctype_len = 0;
OPENSSL_free(s->pha_context);
s->pha_context = NULL;
+ s->pha_context_len = 0;
if (!PACKET_get_length_prefixed_1(pkt, &reqctx) ||
!PACKET_memdup(&reqctx, &s->pha_context, &s->pha_context_len)) {
@@ -2771,16 +2778,17 @@ int tls_process_cert_status_body(SSL *s, PACKET *pkt)
}
s->ext.ocsp.resp = OPENSSL_malloc(resplen);
if (s->ext.ocsp.resp == NULL) {
+ s->ext.ocsp.resp_len = 0;
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CERT_STATUS_BODY,
ERR_R_MALLOC_FAILURE);
return 0;
}
+ s->ext.ocsp.resp_len = resplen;
if (!PACKET_copy_bytes(pkt, s->ext.ocsp.resp, resplen)) {
SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CERT_STATUS_BODY,
SSL_R_LENGTH_MISMATCH);
return 0;
}
- s->ext.ocsp.resp_len = resplen;
return 1;
}
@@ -2831,7 +2839,7 @@ int tls_process_initial_server_flight(SSL *s)
if (ret < 0) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
SSL_F_TLS_PROCESS_INITIAL_SERVER_FLIGHT,
- ERR_R_MALLOC_FAILURE);
+ SSL_R_OCSP_CALLBACK_FAILURE);
return 0;
}
}
@@ -2905,6 +2913,7 @@ static int tls_construct_cke_psk_preamble(SSL *s, WPACKET *pkt)
if (psklen > PSK_MAX_PSK_LEN) {
SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE, ERR_R_INTERNAL_ERROR);
+ psklen = PSK_MAX_PSK_LEN; /* Avoid overrunning the array on cleanse */
goto err;
} else if (psklen == 0) {
SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
@@ -3350,9 +3359,11 @@ int tls_construct_client_key_exchange(SSL *s, WPACKET *pkt)
err:
OPENSSL_clear_free(s->s3->tmp.pms, s->s3->tmp.pmslen);
s->s3->tmp.pms = NULL;
+ s->s3->tmp.pmslen = 0;
#ifndef OPENSSL_NO_PSK
OPENSSL_clear_free(s->s3->tmp.psk, s->s3->tmp.psklen);
s->s3->tmp.psk = NULL;
+ s->s3->tmp.psklen = 0;
#endif
return 0;
}
@@ -3427,6 +3438,7 @@ int tls_client_key_exchange_post_work(SSL *s)
err:
OPENSSL_clear_free(pms, pmslen);
s->s3->tmp.pms = NULL;
+ s->s3->tmp.pmslen = 0;
return 0;
}
diff --git a/ssl/statem/statem_dtls.c b/ssl/statem/statem_dtls.c
index 8e3fb686ee27..8fe6cea72359 100644
--- a/ssl/statem/statem_dtls.c
+++ b/ssl/statem/statem_dtls.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2005-2022 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -218,8 +218,8 @@ int dtls1_do_write(SSL *s, int type)
else
len = s->init_num;
- if (len > s->max_send_fragment)
- len = s->max_send_fragment;
+ if (len > ssl_get_max_send_fragment(s))
+ len = ssl_get_max_send_fragment(s);
/*
* XDTLS: this function is too long. split out the CCS part
@@ -241,7 +241,7 @@ int dtls1_do_write(SSL *s, int type)
ret = dtls1_write_bytes(s, type, &s->init_buf->data[s->init_off], len,
&written);
- if (ret < 0) {
+ if (ret <= 0) {
/*
* might need to update MTU here, but we don't know which
* previous packet caused the failure -- so can't really
diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c
index c3b6f8f4569a..695caab3d628 100644
--- a/ssl/statem/statem_lib.c
+++ b/ssl/statem/statem_lib.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
*
* Licensed under the OpenSSL license (the "License"). You may not use
@@ -2410,6 +2410,8 @@ int tls13_save_handshake_digest_for_pha(SSL *s)
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
SSL_F_TLS13_SAVE_HANDSHAKE_DIGEST_FOR_PHA,
ERR_R_INTERNAL_ERROR);
+ EVP_MD_CTX_free(s->pha_dgst);
+ s->pha_dgst = NULL;
return 0;
}
}
diff --git a/ssl/statem/statem_local.h b/ssl/statem/statem_local.h
index e27c0c13a2bb..eae88053dcd7 100644
--- a/ssl/statem/statem_local.h
+++ b/ssl/statem/statem_local.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -22,6 +22,8 @@
#define SERVER_HELLO_MAX_LENGTH 20000
#define HELLO_RETRY_REQUEST_MAX_LENGTH 20000
#define ENCRYPTED_EXTENSIONS_MAX_LENGTH 20000
+#define SESSION_TICKET_MAX_LENGTH_TLS13 131338
+#define SESSION_TICKET_MAX_LENGTH_TLS12 65541
#define SERVER_KEY_EXCH_MAX_LENGTH 102400
#define SERVER_HELLO_DONE_MAX_LENGTH 0
#define KEY_UPDATE_MAX_LENGTH 1
diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c
index cf45a40ce4e3..43f77a58992f 100644
--- a/ssl/statem/statem_srvr.c
+++ b/ssl/statem/statem_srvr.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
* Copyright 2005 Nokia. All rights reserved.
*
@@ -2178,6 +2178,7 @@ int tls_handle_alpn(SSL *s)
OPENSSL_free(s->s3->alpn_selected);
s->s3->alpn_selected = OPENSSL_memdup(selected, selected_len);
if (s->s3->alpn_selected == NULL) {
+ s->s3->alpn_selected_len = 0;
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_HANDLE_ALPN,
ERR_R_INTERNAL_ERROR);
return 0;
@@ -2853,9 +2854,16 @@ int tls_construct_certificate_request(SSL *s, WPACKET *pkt)
if (s->post_handshake_auth == SSL_PHA_REQUEST_PENDING) {
OPENSSL_free(s->pha_context);
s->pha_context_len = 32;
- if ((s->pha_context = OPENSSL_malloc(s->pha_context_len)) == NULL
- || RAND_bytes(s->pha_context, s->pha_context_len) <= 0
- || !WPACKET_sub_memcpy_u8(pkt, s->pha_context, s->pha_context_len)) {
+ if ((s->pha_context = OPENSSL_malloc(s->pha_context_len)) == NULL) {
+ s->pha_context_len = 0;
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR,
+ SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST,
+ ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+ if (RAND_bytes(s->pha_context, s->pha_context_len) <= 0
+ || !WPACKET_sub_memcpy_u8(pkt, s->pha_context,
+ s->pha_context_len)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST,
ERR_R_INTERNAL_ERROR);
@@ -2969,6 +2977,7 @@ static int tls_process_cke_psk_preamble(SSL *s, PACKET *pkt)
OPENSSL_cleanse(psk, psklen);
if (s->s3->tmp.psk == NULL) {
+ s->s3->tmp.psklen = 0;
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE, ERR_R_MALLOC_FAILURE);
return 0;
@@ -3508,6 +3517,7 @@ MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt)
#ifndef OPENSSL_NO_PSK
OPENSSL_clear_free(s->s3->tmp.psk, s->s3->tmp.psklen);
s->s3->tmp.psk = NULL;
+ s->s3->tmp.psklen = 0;
#endif
return MSG_PROCESS_ERROR;
}
@@ -3743,6 +3753,7 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt)
sk_X509_pop_free(s->session->peer_chain, X509_free);
s->session->peer_chain = sk;
+ sk = NULL;
/*
* Freeze the handshake buffer. For <TLS1.3 we do this after the CKE
@@ -3757,7 +3768,6 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt)
* Inconsistency alert: cert_chain does *not* include the peer's own
* certificate, while we do include it in statem_clnt.c
*/
- sk = NULL;
/* Save the current hash state for when we receive the CertificateVerify */
if (SSL_IS_TLS13(s)) {
@@ -3810,15 +3820,24 @@ int tls_construct_server_certificate(SSL *s, WPACKET *pkt)
static int create_ticket_prequel(SSL *s, WPACKET *pkt, uint32_t age_add,
unsigned char *tick_nonce)
{
+ uint32_t timeout = (uint32_t)s->session->timeout;
+
/*
- * Ticket lifetime hint: For TLSv1.2 this is advisory only and we leave this
- * unspecified for resumed session (for simplicity).
+ * Ticket lifetime hint:
* In TLSv1.3 we reset the "time" field above, and always specify the
- * timeout.
+ * timeout, limited to a 1 week period per RFC8446.
+ * For TLSv1.2 this is advisory only and we leave this unspecified for
+ * resumed session (for simplicity).
*/
- if (!WPACKET_put_bytes_u32(pkt,
- (s->hit && !SSL_IS_TLS13(s))
- ? 0 : s->session->timeout)) {
+#define ONE_WEEK_SEC (7 * 24 * 60 * 60)
+
+ if (SSL_IS_TLS13(s)) {
+ if (s->session->timeout > ONE_WEEK_SEC)
+ timeout = ONE_WEEK_SEC;
+ } else if (s->hit)
+ timeout = 0;
+
+ if (!WPACKET_put_bytes_u32(pkt, timeout)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CREATE_TICKET_PREQUEL,
ERR_R_INTERNAL_ERROR);
return 0;
@@ -4117,6 +4136,7 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt)
s->session->ext.alpn_selected =
OPENSSL_memdup(s->s3->alpn_selected, s->s3->alpn_selected_len);
if (s->session->ext.alpn_selected == NULL) {
+ s->session->ext.alpn_selected_len = 0;
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET,
ERR_R_MALLOC_FAILURE);
@@ -4128,9 +4148,12 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt)
}
if (tctx->generate_ticket_cb != NULL &&
- tctx->generate_ticket_cb(s, tctx->ticket_cb_data) == 0)
+ tctx->generate_ticket_cb(s, tctx->ticket_cb_data) == 0) {
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR,
+ SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET,
+ ERR_R_INTERNAL_ERROR);
goto err;
-
+ }
/*
* If we are using anti-replay protection then we behave as if
* SSL_OP_NO_TICKET is set - we are caching tickets anyway so there
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
index c85c0b0310e1..f8e53d4efc79 100644
--- a/ssl/t1_enc.c
+++ b/ssl/t1_enc.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2005 Nokia. All rights reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
@@ -672,6 +672,8 @@ int tls1_alert_code(int code)
return TLS1_AD_NO_APPLICATION_PROTOCOL;
case SSL_AD_CERTIFICATE_REQUIRED:
return SSL_AD_HANDSHAKE_FAILURE;
+ case SSL_AD_MISSING_EXTENSION:
+ return SSL_AD_HANDSHAKE_FAILURE;
default:
return -1;
}
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index 48d46f8a48bd..5f657f888e0d 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -2369,22 +2369,20 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain,
ca_dn = s->s3->tmp.peer_ca_names;
- if (!sk_X509_NAME_num(ca_dn))
+ if (ca_dn == NULL
+ || sk_X509_NAME_num(ca_dn) == 0
+ || ssl_check_ca_name(ca_dn, x))
rv |= CERT_PKEY_ISSUER_NAME;
-
- if (!(rv & CERT_PKEY_ISSUER_NAME)) {
- if (ssl_check_ca_name(ca_dn, x))
- rv |= CERT_PKEY_ISSUER_NAME;
- }
- if (!(rv & CERT_PKEY_ISSUER_NAME)) {
+ else
for (i = 0; i < sk_X509_num(chain); i++) {
X509 *xtmp = sk_X509_value(chain, i);
+
if (ssl_check_ca_name(ca_dn, xtmp)) {
rv |= CERT_PKEY_ISSUER_NAME;
break;
}
}
- }
+
if (!check_flags && !(rv & CERT_PKEY_ISSUER_NAME))
goto end;
} else
@@ -2441,7 +2439,8 @@ DH *ssl_get_auto_dh(SSL *s)
{
DH *dhp = NULL;
BIGNUM *p = NULL, *g = NULL;
- int dh_secbits = 80;
+ int dh_secbits = 80, sec_level_bits;
+
if (s->cert->dh_tmp_auto != 2) {
if (s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aPSK)) {
if (s->s3->tmp.new_cipher->strength_bits == 256)
@@ -2464,6 +2463,12 @@ DH *ssl_get_auto_dh(SSL *s)
BN_free(g);
return NULL;
}
+
+ /* Do not pick a prime that is too weak for the current security level */
+ sec_level_bits = ssl_get_security_level_bits(s, NULL, NULL);
+ if (dh_secbits < sec_level_bits)
+ dh_secbits = sec_level_bits;
+
if (dh_secbits >= 192)
p = BN_get_rfc3526_prime_8192(NULL);
else if (dh_secbits >= 152)
@@ -2548,6 +2553,8 @@ int ssl_security_cert_chain(SSL *s, STACK_OF(X509) *sk, X509 *x, int vfy)
int rv, start_idx, i;
if (x == NULL) {
x = sk_X509_value(sk, 0);
+ if (x == NULL)
+ return ERR_R_INTERNAL_ERROR;
start_idx = 1;
} else
start_idx = 0;
diff --git a/ssl/tls13_enc.c b/ssl/tls13_enc.c
index b8fb07f210ef..ff85df4483f7 100644
--- a/ssl/tls13_enc.c
+++ b/ssl/tls13_enc.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -190,6 +190,7 @@ int tls13_generate_secret(SSL *s, const EVP_MD *md,
if (!ossl_assert(mdleni >= 0)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_GENERATE_SECRET,
ERR_R_INTERNAL_ERROR);
+ EVP_PKEY_CTX_free(pctx);
return 0;
}
mdlen = (size_t)mdleni;