From c2041da8c15027ddde5afcf9809d8d3a975eb25b Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Wed, 18 Mar 2020 15:54:47 +0100 Subject: EVP & TLS: Add necessary EC_KEY data extraction functions, and use them libssl code uses EVP_PKEY_get0_EC_KEY() to extract certain basic data from the EC_KEY. We replace that with internal EVP_PKEY functions. This may or may not be refactored later on. Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/11358) --- ssl/ssl_rsa.c | 2 +- ssl/statem/statem_lib.c | 8 +++---- ssl/t1_lib.c | 61 ++++++++++++++++++++++++++----------------------- 3 files changed, 36 insertions(+), 35 deletions(-) (limited to 'ssl') diff --git a/ssl/ssl_rsa.c b/ssl/ssl_rsa.c index 3a222e5571..ac9d01a766 100644 --- a/ssl/ssl_rsa.c +++ b/ssl/ssl_rsa.c @@ -338,7 +338,7 @@ static int ssl_set_cert(CERT *c, X509 *x) return 0; } #ifndef OPENSSL_NO_EC - if (i == SSL_PKEY_ECC && !EC_KEY_can_sign(EVP_PKEY_get0_EC_KEY(pkey))) { + if (i == SSL_PKEY_ECC && !EVP_PKEY_can_sign(pkey)) { SSLerr(SSL_F_SSL_SET_CERT, SSL_R_ECC_CERT_NOT_FOR_SIGNING); return 0; } diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c index e9cfee027e..71a259e8f0 100644 --- a/ssl/statem/statem_lib.c +++ b/ssl/statem/statem_lib.c @@ -14,6 +14,7 @@ #include "../ssl_local.h" #include "statem_local.h" #include "internal/cryptlib.h" +#include "internal/evp.h" #include #include #include @@ -1531,7 +1532,6 @@ static int is_tls13_capable(const SSL *s) int i; #ifndef OPENSSL_NO_EC int curve; - EC_KEY *eckey; #endif #ifndef OPENSSL_NO_PSK @@ -1563,10 +1563,8 @@ static int is_tls13_capable(const SSL *s) * more restrictive so check that our sig algs are consistent with this * EC cert. See section 4.2.3 of RFC8446. */ - eckey = EVP_PKEY_get0_EC_KEY(s->cert->pkeys[SSL_PKEY_ECC].privatekey); - if (eckey == NULL) - continue; - curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(eckey)); + curve = evp_pkey_get_EC_KEY_curve_nid(s->cert->pkeys[SSL_PKEY_ECC] + .privatekey); if (tls_check_sigalg_curve(s, curve)) return 1; #else diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 624add64a8..beadf28f11 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -22,6 +22,7 @@ #include #include #include "internal/nelem.h" +#include "internal/evp.h" #include "ssl_local.h" #include @@ -583,7 +584,7 @@ static int tls1_check_pkey_comp(SSL *s, EVP_PKEY *pkey) size_t i; /* If not an EC key nothing to check */ - if (EVP_PKEY_id(pkey) != EVP_PKEY_EC) + if (!EVP_PKEY_is_a(pkey, "EC")) return 1; ec = EVP_PKEY_get0_EC_KEY(pkey); grp = EC_KEY_get0_group(ec); @@ -624,13 +625,11 @@ static int tls1_check_pkey_comp(SSL *s, EVP_PKEY *pkey) /* Return group id of a key */ static uint16_t tls1_get_group_id(EVP_PKEY *pkey) { - EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey); - const EC_GROUP *grp; + int curve_nid = evp_pkey_get_EC_KEY_curve_nid(pkey); - if (ec == NULL) + if (curve_nid == NID_undef) return 0; - grp = EC_KEY_get0_group(ec); - return tls1_nid2group_id(EC_GROUP_get_curve_name(grp)); + return tls1_nid2group_id(curve_nid); } /* @@ -645,7 +644,7 @@ static int tls1_check_cert_param(SSL *s, X509 *x, int check_ee_md) if (pkey == NULL) return 0; /* If not EC nothing to do */ - if (EVP_PKEY_id(pkey) != EVP_PKEY_EC) + if (!EVP_PKEY_is_a(pkey, "EC")) return 1; /* Check compression */ if (!tls1_check_pkey_comp(s, pkey)) @@ -1111,10 +1110,22 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) const EVP_MD *md = NULL; char sigalgstr[2]; size_t sent_sigslen, i, cidx; - int pkeyid = EVP_PKEY_id(pkey); + int pkeyid = -1; const SIGALG_LOOKUP *lu; int secbits = 0; + /* + * TODO(3.0) Remove this when we adapted this function for provider + * side keys. We know that EVP_PKEY_get0() downgrades an EVP_PKEY + * to contain a legacy key. + * + * THIS IS TEMPORARY + */ + EVP_PKEY_get0(pkey); + if (EVP_PKEY_id(pkey) == EVP_PKEY_NONE) + return 0; + + pkeyid = EVP_PKEY_id(pkey); /* Should never happen */ if (pkeyid == -1) return -1; @@ -1163,8 +1174,7 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) /* For TLS 1.3 or Suite B check curve matches signature algorithm */ if (SSL_IS_TLS13(s) || tls1_suiteb(s)) { - EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey); - int curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)); + int curve = evp_pkey_get_EC_KEY_curve_nid(pkey); if (lu->curve != NID_undef && curve != lu->curve) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, @@ -2449,17 +2459,14 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, if (!s->server && strict_mode) { STACK_OF(X509_NAME) *ca_dn; int check_type = 0; - switch (EVP_PKEY_id(pk)) { - case EVP_PKEY_RSA: + + if (EVP_PKEY_is_a(pk, "RSA")) check_type = TLS_CT_RSA_SIGN; - break; - case EVP_PKEY_DSA: + else if (EVP_PKEY_is_a(pk, "DSA")) check_type = TLS_CT_DSS_SIGN; - break; - case EVP_PKEY_EC: + else if (EVP_PKEY_is_a(pk, "EC")) check_type = TLS_CT_ECDSA_SIGN; - break; - } + if (check_type) { const uint8_t *ctypes = s->s3.tmp.ctype; size_t j; @@ -2820,10 +2827,8 @@ static const SIGALG_LOOKUP *find_sig_alg(SSL *s, X509 *x, EVP_PKEY *pkey) if (lu->sig == EVP_PKEY_EC) { #ifndef OPENSSL_NO_EC - if (curve == -1) { - EC_KEY *ec = EVP_PKEY_get0_EC_KEY(tmppkey); - curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)); - } + if (curve == -1) + curve = evp_pkey_get_EC_KEY_curve_nid(tmppkey); if (lu->curve != NID_undef && curve != lu->curve) continue; #else @@ -2882,15 +2887,13 @@ int tls_choose_sigalg(SSL *s, int fatalerrs) size_t i; if (s->s3.tmp.peer_sigalgs != NULL) { #ifndef OPENSSL_NO_EC - int curve; + int curve = -1; /* For Suite B need to match signature algorithm to curve */ - if (tls1_suiteb(s)) { - EC_KEY *ec = EVP_PKEY_get0_EC_KEY(s->cert->pkeys[SSL_PKEY_ECC].privatekey); - curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)); - } else { - curve = -1; - } + if (tls1_suiteb(s)) + curve = + evp_pkey_get_EC_KEY_curve_nid(s->cert->pkeys[SSL_PKEY_ECC] + .privatekey); #endif /* -- cgit v1.2.3