Add EVP_PKEY functions to get EC conv form and field type
authorMatt Caswell <matt@openssl.org>
Mon, 18 Jan 2021 16:05:43 +0000 (16:05 +0000)
committerTomas Mraz <tomas@openssl.org>
Tue, 26 Jan 2021 14:26:17 +0000 (15:26 +0100)
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 <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/13139)

crypto/evp/p_lib.c
include/openssl/ec.h
include/openssl/evp.h
ssl/t1_lib.c
util/libcrypto.num

index 6fdc186507fbe27ab38b5fb60c65520dc66404b6..11e86a7e930f0757735aec68b51a23d2f7385a23 100644 (file)
@@ -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);
 }
         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
index 2d9b7714e31fefa9c04b81558744b9e08e4b4a66..c7797e957daa309bfe632445f8fe472d6c5bf40a 100644 (file)
@@ -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
 
  */
 # define EVP_PKEY_ECDH_KDF_X9_62   EVP_PKEY_ECDH_KDF_X9_63
 
-# ifndef OPENSSL_NO_EC
-#  include <openssl/asn1.h>
-#  include <openssl/symhacks.h>
-#  ifndef OPENSSL_NO_DEPRECATED_1_1_0
-#   include <openssl/bn.h>
-#  endif
-#  include <openssl/ecerr.h>
-
-#  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 {
 /** 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;
 
     POINT_CONVERSION_HYBRID = 6
 } point_conversion_form_t;
 
+# ifndef OPENSSL_NO_EC
+#  include <openssl/asn1.h>
+#  include <openssl/symhacks.h>
+#  ifndef OPENSSL_NO_DEPRECATED_1_1_0
+#   include <openssl/bn.h>
+#  endif
+#  include <openssl/ecerr.h>
+
+#  ifndef OPENSSL_ECC_MAX_FIELD_BITS
+#   define OPENSSL_ECC_MAX_FIELD_BITS 661
+#  endif
+
 #  include <openssl/params.h>
 #  ifndef OPENSSL_NO_DEPRECATED_3_0
 typedef struct ec_method_st EC_METHOD;
 #  include <openssl/params.h>
 #  ifndef OPENSSL_NO_DEPRECATED_3_0
 typedef struct ec_method_st EC_METHOD;
index bfab06d5df1b84ce5ac6922a7310cc0a91aa3df9..ac92887aaddd2bba4e947b182d9f3d2fe51115cb 100644 (file)
@@ -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_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);
 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);
index 799ff357f8103399b7e2093c2b83b9fe91254057..ccc71a199592546aed9386e6d63876f4c979c450 100644 (file)
@@ -820,22 +820,19 @@ static int tls1_check_pkey_comp(SSL *s, EVP_PKEY *pkey)
 {
     unsigned char comp_id;
     size_t i;
 {
     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 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 */
 
     /* 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
     } 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 {
          */
         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;
             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;
             comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2;
         else
             return 0;
index 964ac7d7259fd9fc5c339c5c17b4829b0a0a0fe1..509c694d698928f892ca6d441e809f12fdcb68d7 100644 (file)
@@ -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_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: