summaryrefslogtreecommitdiffstats
path: root/ssl
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2021-03-18 17:52:10 +0100
committerMatt Caswell <matt@openssl.org>2021-03-25 10:48:08 +0100
commit39a140597d874e554b736885ac4dea16ac40a87a (patch)
tree4111ade117e62d5eb609109e6c47d7a866660046 /ssl
parentssl sigalg extension: fix NULL pointer dereference (diff)
downloadopenssl-39a140597d874e554b736885ac4dea16ac40a87a.tar.xz
openssl-39a140597d874e554b736885ac4dea16ac40a87a.zip
Ensure buffer/length pairs are always in sync
Following on from CVE-2021-3449 which was caused by a non-zero length associated with a NULL buffer, other buffer/length pairs are updated to ensure that they too are always in sync. Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Paul Dale <pauli@openssl.org>
Diffstat (limited to 'ssl')
-rw-r--r--ssl/s3_lib.c5
-rw-r--r--ssl/ssl_lib.c14
-rw-r--r--ssl/statem/extensions.c1
-rw-r--r--ssl/statem/extensions_clnt.c13
-rw-r--r--ssl/statem/statem_clnt.c7
-rw-r--r--ssl/statem/statem_srvr.c15
6 files changed, 45 insertions, 10 deletions
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index 19ae6d9a28..f5b063319b 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -4603,6 +4603,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)) {
@@ -4632,8 +4633,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/ssl_lib.c b/ssl/ssl_lib.c
index 4cb40bd89b..57e8d15798 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -772,8 +772,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;
}
@@ -782,8 +784,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;
}
@@ -793,8 +797,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;
}
@@ -2990,6 +2996,7 @@ int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos,
OPENSSL_free(ctx->ext.alpn);
ctx->ext.alpn = OPENSSL_memdup(protos, protos_len);
if (ctx->ext.alpn == NULL) {
+ ctx->ext.alpn_len = 0;
ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
return 1;
}
@@ -3009,6 +3016,7 @@ int SSL_set_alpn_protos(SSL *ssl, const unsigned char *protos,
OPENSSL_free(ssl->ext.alpn);
ssl->ext.alpn = OPENSSL_memdup(protos, protos_len);
if (ssl->ext.alpn == NULL) {
+ ssl->ext.alpn_len = 0;
ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
return 1;
}
diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c
index bc41b36594..0ce436d082 100644
--- a/ssl/statem/extensions.c
+++ b/ssl/statem/extensions.c
@@ -1124,6 +1124,7 @@ static int init_sig_algs_cert(SSL *s, ossl_unused 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;
}
diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c
index cac713fff0..b3ef1bc16a 100644
--- a/ssl/statem/extensions_clnt.c
+++ b/ssl/statem/extensions_clnt.c
@@ -810,6 +810,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, ERR_R_INTERNAL_ERROR);
return EXT_RETURN_FAIL;
}
@@ -1337,6 +1338,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, ERR_R_INTERNAL_ERROR);
return 0;
}
@@ -1446,8 +1448,12 @@ 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, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ if (!PACKET_copy_bytes(pkt, s->ext.scts, size)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
@@ -1541,6 +1547,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, ERR_R_INTERNAL_ERROR);
return 0;
}
@@ -1578,6 +1585,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, ERR_R_INTERNAL_ERROR);
return 0;
}
@@ -1606,6 +1614,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, ERR_R_INTERNAL_ERROR);
return 0;
}
diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c
index 666ee43363..8686b1e684 100644
--- a/ssl/statem/statem_clnt.c
+++ b/ssl/statem/statem_clnt.c
@@ -2352,6 +2352,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)) {
@@ -2642,14 +2643,15 @@ 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, 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_R_LENGTH_MISMATCH);
return 0;
}
- s->ext.ocsp.resp_len = resplen;
return 1;
}
@@ -3313,9 +3315,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;
}
@@ -3387,6 +3391,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_srvr.c b/ssl/statem/statem_srvr.c
index aca17868b1..bad3619170 100644
--- a/ssl/statem/statem_srvr.c
+++ b/ssl/statem/statem_srvr.c
@@ -2116,6 +2116,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, ERR_R_INTERNAL_ERROR);
return 0;
}
@@ -2725,10 +2726,15 @@ 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_ex(s->ctx->libctx, s->pha_context,
+ if ((s->pha_context = OPENSSL_malloc(s->pha_context_len)) == NULL) {
+ s->pha_context_len = 0;
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+ if (RAND_bytes_ex(s->ctx->libctx, s->pha_context,
s->pha_context_len) <= 0
- || !WPACKET_sub_memcpy_u8(pkt, s->pha_context, s->pha_context_len)) {
+ || !WPACKET_sub_memcpy_u8(pkt, s->pha_context,
+ s->pha_context_len)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
@@ -2828,6 +2834,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, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -3329,6 +3336,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;
}
@@ -3921,6 +3929,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, ERR_R_MALLOC_FAILURE);
goto err;
}