From: Matt Caswell Date: Mon, 18 Jan 2021 16:05:43 +0000 (+0000) Subject: Add EVP_PKEY functions to get EC conv form and field type X-Git-Tag: openssl-3.0.0-alpha11~19 X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff_plain;h=3d34bedfd7fb9120b6eb7b05c25cd0c3de14c562 Add EVP_PKEY functions to get EC conv form and field type libssl at the moment downgrades an EVP_PKEY to an EC_KEY object in order to get the conv form and field type. Instead we provide EVP_PKEY level functions to do this. Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/13139) --- diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index 6fdc186507..11e86a7e93 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -2211,3 +2211,82 @@ int EVP_PKEY_set_params(EVP_PKEY *pkey, OSSL_PARAM params[]) return 0; return evp_keymgmt_set_params(pkey->keymgmt, pkey->keydata, params); } + +#ifndef FIPS_MODULE +int EVP_PKEY_get_ec_point_conv_form(const EVP_PKEY *pkey) +{ + char name[80]; + size_t name_len; + + if (pkey == NULL) + return 0; + + if (pkey->keymgmt == NULL + || pkey->keydata == NULL) { +#ifndef OPENSSL_NO_EC + /* Might work through the legacy route */ + EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey); + + if (ec == NULL) + return 0; + + return EC_KEY_get_conv_form(ec); +#else + return 0; +#endif + } + + if (!EVP_PKEY_get_utf8_string_param(pkey, + OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, + name, sizeof(name), &name_len)) + return 0; + + if (strcmp(name, "uncompressed") == 0) + return POINT_CONVERSION_UNCOMPRESSED; + + if (strcmp(name, "compressed") == 0) + return POINT_CONVERSION_COMPRESSED; + + if (strcmp(name, "hybrid") == 0) + return POINT_CONVERSION_HYBRID; + + return 0; +} + +int EVP_PKEY_get_field_type(const EVP_PKEY *pkey) +{ + char fstr[80]; + size_t fstrlen; + + if (pkey == NULL) + return 0; + + if (pkey->keymgmt == NULL + || pkey->keydata == NULL) { +#ifndef OPENSSL_NO_EC + /* Might work through the legacy route */ + EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey); + const EC_GROUP *grp; + + if (ec == NULL) + return 0; + grp = EC_KEY_get0_group(ec); + + return EC_GROUP_get_field_type(grp); +#else + return 0; +#endif + } + + if (!EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_EC_FIELD_TYPE, + fstr, sizeof(fstr), &fstrlen)) + return 0; + + if (strcmp(fstr, SN_X9_62_prime_field) == 0) + return NID_X9_62_prime_field; + else if (strcmp(fstr, SN_X9_62_characteristic_two_field)) + return NID_X9_62_characteristic_two_field; + + return 0; +} +#endif diff --git a/include/openssl/ec.h b/include/openssl/ec.h index 2d9b7714e3..c7797e957d 100644 --- a/include/openssl/ec.h +++ b/include/openssl/ec.h @@ -68,18 +68,6 @@ int EVP_PKEY_CTX_get0_ecdh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char **ukm); */ # define EVP_PKEY_ECDH_KDF_X9_62 EVP_PKEY_ECDH_KDF_X9_63 -# ifndef OPENSSL_NO_EC -# include -# include -# ifndef OPENSSL_NO_DEPRECATED_1_1_0 -# include -# endif -# include - -# ifndef OPENSSL_ECC_MAX_FIELD_BITS -# define OPENSSL_ECC_MAX_FIELD_BITS 661 -# endif - /** Enum for the point conversion form as defined in X9.62 (ECDSA) * for the encoding of a elliptic curve point (x,y) */ typedef enum { @@ -93,6 +81,18 @@ typedef enum { POINT_CONVERSION_HYBRID = 6 } point_conversion_form_t; +# ifndef OPENSSL_NO_EC +# include +# include +# ifndef OPENSSL_NO_DEPRECATED_1_1_0 +# include +# endif +# include + +# ifndef OPENSSL_ECC_MAX_FIELD_BITS +# define OPENSSL_ECC_MAX_FIELD_BITS 661 +# endif + # include # ifndef OPENSSL_NO_DEPRECATED_3_0 typedef struct ec_method_st EC_METHOD; diff --git a/include/openssl/evp.h b/include/openssl/evp.h index bfab06d5df..ac92887aad 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h @@ -1812,6 +1812,9 @@ int EVP_PKEY_set_utf8_string_param(EVP_PKEY *pkey, const char *key_name, int EVP_PKEY_set_octet_string_param(EVP_PKEY *pkey, const char *key_name, unsigned char *buf, size_t bsize); +int EVP_PKEY_get_ec_point_conv_form(const EVP_PKEY *pkey); +int EVP_PKEY_get_field_type(const EVP_PKEY *pkey); + int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx); int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx); diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 799ff357f8..ccc71a1995 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -820,22 +820,19 @@ static int tls1_check_pkey_comp(SSL *s, EVP_PKEY *pkey) { unsigned char comp_id; size_t i; - char name[80]; - size_t name_len; - + int point_conv; /* If not an EC key nothing to check */ if (!EVP_PKEY_is_a(pkey, "EC")) return 1; - if (!EVP_PKEY_get_utf8_string_param(pkey, - OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, - name, sizeof(name), &name_len)) - return 0; /* Get required compression id */ - if (strcasecmp(name, "uncompressed") == 0) { - comp_id = TLSEXT_ECPOINTFORMAT_uncompressed; + point_conv = EVP_PKEY_get_ec_point_conv_form(pkey); + if (point_conv == 0) + return 0; + if (point_conv == POINT_CONVERSION_UNCOMPRESSED) { + comp_id = TLSEXT_ECPOINTFORMAT_uncompressed; } else if (SSL_IS_TLS13(s)) { /* * ec_point_formats extension is not used in TLSv1.3 so we ignore @@ -843,14 +840,11 @@ static int tls1_check_pkey_comp(SSL *s, EVP_PKEY *pkey) */ return 1; } else { - if (!EVP_PKEY_get_utf8_string_param(pkey, - OSSL_PKEY_PARAM_EC_FIELD_TYPE, - name, sizeof(name), &name_len)) - return 0; + int field_type = EVP_PKEY_get_field_type(pkey); - if (strcasecmp(name, SN_X9_62_prime_field) == 0) + if (field_type == NID_X9_62_prime_field) comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime; - else if (strcasecmp(name, SN_X9_62_characteristic_two_field) == 0) + else if (field_type == NID_X9_62_characteristic_two_field) comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2; else return 0; diff --git a/util/libcrypto.num b/util/libcrypto.num index 964ac7d725..509c694d69 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -5294,3 +5294,5 @@ EVP_PKEY_set_size_t_param ? 3_0_0 EXIST::FUNCTION: EVP_PKEY_set_bn_param ? 3_0_0 EXIST::FUNCTION: EVP_PKEY_set_utf8_string_param ? 3_0_0 EXIST::FUNCTION: EVP_PKEY_set_octet_string_param ? 3_0_0 EXIST::FUNCTION: +EVP_PKEY_get_ec_point_conv_form ? 3_0_0 EXIST::FUNCTION: +EVP_PKEY_get_field_type ? 3_0_0 EXIST::FUNCTION: