summaryrefslogtreecommitdiffstats
path: root/ssl
diff options
context:
space:
mode:
authorTomas Mraz <tomas@openssl.org>2022-02-10 11:49:37 +0100
committerTomas Mraz <tomas@openssl.org>2022-03-03 13:21:43 +0100
commit2e8be29cad5811c85a7c2844198ba1e824f1314c (patch)
treeced3c430b19e32d5c62ab6aa311666cc41fa9d0c /ssl
parentdeaf22669a76ca014996e6d42883b3d43c8c3384 (diff)
Add back check for the DH public key size
This is needed for TLS-1.3. Also add check for uncompressed point format for ECDHE as the other formats are not allowed by RFC 8446. Fixes #17667 Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: Paul Dale <pauli@openssl.org> (Merged from https://github.com/openssl/openssl/pull/17785)
Diffstat (limited to 'ssl')
-rw-r--r--ssl/ssl_local.h3
-rw-r--r--ssl/statem/extensions_clnt.c4
-rw-r--r--ssl/statem/extensions_srvr.c6
-rw-r--r--ssl/t1_lib.c19
4 files changed, 27 insertions, 5 deletions
diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h
index 9f119a9d79..158fee5c4c 100644
--- a/ssl/ssl_local.h
+++ b/ssl/ssl_local.h
@@ -811,6 +811,9 @@ int ssl_hmac_final(SSL_HMAC *ctx, unsigned char *md, size_t *len,
size_t ssl_hmac_size(const SSL_HMAC *ctx);
int ssl_get_EC_curve_nid(const EVP_PKEY *pkey);
+__owur int tls13_set_encoded_pub_key(EVP_PKEY *pkey,
+ const unsigned char *enckey,
+ size_t enckeylen);
typedef struct tls_group_info_st {
char *tlsname; /* Curve Name as in TLS specs */
diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c
index 4cd7affe23..7e68fd3495 100644
--- a/ssl/statem/extensions_clnt.c
+++ b/ssl/statem/extensions_clnt.c
@@ -1838,8 +1838,8 @@ int tls_parse_stoc_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
return 0;
}
- if (EVP_PKEY_set1_encoded_public_key(skey, PACKET_data(&encoded_pt),
- PACKET_remaining(&encoded_pt)) <= 0) {
+ if (tls13_set_encoded_pub_key(skey, PACKET_data(&encoded_pt),
+ PACKET_remaining(&encoded_pt)) <= 0) {
SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_ECPOINT);
EVP_PKEY_free(skey);
return 0;
diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c
index e8e57cd5d9..08ead316b1 100644
--- a/ssl/statem/extensions_srvr.c
+++ b/ssl/statem/extensions_srvr.c
@@ -663,9 +663,9 @@ int tls_parse_ctos_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
/* Cache the selected group ID in the SSL_SESSION */
s->session->kex_group = group_id;
- if (EVP_PKEY_set1_encoded_public_key(s->s3.peer_tmp,
- PACKET_data(&encoded_pt),
- PACKET_remaining(&encoded_pt)) <= 0) {
+ if (tls13_set_encoded_pub_key(s->s3.peer_tmp,
+ PACKET_data(&encoded_pt),
+ PACKET_remaining(&encoded_pt)) <= 0) {
SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_ECPOINT);
return 0;
}
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index fc32bb3556..1b22610f73 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -3477,3 +3477,22 @@ int ssl_get_EC_curve_nid(const EVP_PKEY *pkey)
return NID_undef;
}
+
+__owur int tls13_set_encoded_pub_key(EVP_PKEY *pkey,
+ const unsigned char *enckey,
+ size_t enckeylen)
+{
+ if (EVP_PKEY_is_a(pkey, "DH")) {
+ int bits = EVP_PKEY_get_bits(pkey);
+
+ if (bits <= 0 || enckeylen != (size_t)bits / 8)
+ /* the encoded key must be padded to the length of the p */
+ return 0;
+ } else if (EVP_PKEY_is_a(pkey, "EC")) {
+ if (enckeylen < 3 /* point format and at least 1 byte for x and y */
+ || enckey[0] != 0x04)
+ return 0;
+ }
+
+ return EVP_PKEY_set1_encoded_public_key(pkey, enckey, enckeylen);
+}