summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomas Mraz <tmraz@fedoraproject.org>2020-08-21 14:50:52 +0200
committerTomas Mraz <tmraz@fedoraproject.org>2020-09-21 10:32:42 +0200
commit398c8da5c8c3cf3369ac7e8883823e0c94735ca7 (patch)
treed7f9a71b41d5871262243201783c7e7092ee077e
parentee617d0e020d6dd28c079fa7819d009790f2d2b9 (diff)
EC_KEY: add EC_KEY_decoded_from_explicit_params()
The function returns 1 when the encoding of a decoded EC key used explicit encoding of the curve parameters. Reviewed-by: David von Oheimb <david.von.oheimb@siemens.com> Reviewed-by: Nicola Tuveri <nic.tuv@gmail.com> (Merged from https://github.com/openssl/openssl/pull/12909)
-rw-r--r--crypto/ec/ec_asn1.c31
-rw-r--r--crypto/ec/ec_key.c7
-rw-r--r--crypto/ec/ec_lib.c1
-rw-r--r--crypto/ec/ec_local.h2
-rw-r--r--doc/man3/EC_KEY_new.pod8
-rw-r--r--include/openssl/ec.h2
-rw-r--r--test/ec_internal_test.c101
-rw-r--r--util/libcrypto.num1
8 files changed, 144 insertions, 9 deletions
diff --git a/crypto/ec/ec_asn1.c b/crypto/ec/ec_asn1.c
index 96e7d83ea7..7b7c75ce84 100644
--- a/crypto/ec/ec_asn1.c
+++ b/crypto/ec/ec_asn1.c
@@ -137,6 +137,12 @@ struct ec_parameters_st {
ASN1_INTEGER *cofactor;
} /* ECPARAMETERS */ ;
+typedef enum {
+ ECPKPARAMETERS_TYPE_NAMED = 0,
+ ECPKPARAMETERS_TYPE_EXPLICIT,
+ ECPKPARAMETERS_TYPE_IMPLICIT
+} ecpk_parameters_type_t;
+
struct ecpk_parameters_st {
int type;
union {
@@ -535,9 +541,10 @@ ECPKPARAMETERS *EC_GROUP_get_ecpkparameters(const EC_GROUP *group,
return NULL;
}
} else {
- if (ret->type == 0)
+ if (ret->type == ECPKPARAMETERS_TYPE_NAMED)
ASN1_OBJECT_free(ret->value.named_curve);
- else if (ret->type == 1 && ret->value.parameters)
+ else if (ret->type == ECPKPARAMETERS_TYPE_EXPLICIT
+ && ret->value.parameters != NULL)
ECPARAMETERS_free(ret->value.parameters);
}
@@ -554,7 +561,7 @@ ECPKPARAMETERS *EC_GROUP_get_ecpkparameters(const EC_GROUP *group,
ECerr(EC_F_EC_GROUP_GET_ECPKPARAMETERS, EC_R_MISSING_OID);
ok = 0;
} else {
- ret->type = 0;
+ ret->type = ECPKPARAMETERS_TYPE_NAMED;
ret->value.named_curve = asn1obj;
}
} else
@@ -562,7 +569,7 @@ ECPKPARAMETERS *EC_GROUP_get_ecpkparameters(const EC_GROUP *group,
ok = 0;
} else {
/* use the ECPARAMETERS structure */
- ret->type = 1;
+ ret->type = ECPKPARAMETERS_TYPE_EXPLICIT;
if ((ret->value.parameters =
EC_GROUP_get_ecparameters(group, NULL)) == NULL)
ok = 0;
@@ -901,7 +908,8 @@ EC_GROUP *EC_GROUP_new_from_ecpkparameters(const ECPKPARAMETERS *params)
return NULL;
}
- if (params->type == 0) { /* the curve is given by an OID */
+ if (params->type == ECPKPARAMETERS_TYPE_NAMED) {
+ /* the curve is given by an OID */
tmp = OBJ_obj2nid(params->value.named_curve);
if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL) {
ECerr(EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS,
@@ -909,15 +917,16 @@ EC_GROUP *EC_GROUP_new_from_ecpkparameters(const ECPKPARAMETERS *params)
return NULL;
}
EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE);
- } else if (params->type == 1) { /* the parameters are given by a
- * ECPARAMETERS structure */
+ } else if (params->type == ECPKPARAMETERS_TYPE_EXPLICIT) {
+ /* the parameters are given by an ECPARAMETERS structure */
ret = EC_GROUP_new_from_ecparameters(params->value.parameters);
if (!ret) {
ECerr(EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS, ERR_R_EC_LIB);
return NULL;
}
EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_EXPLICIT_CURVE);
- } else if (params->type == 2) { /* implicitlyCA */
+ } else if (params->type == ECPKPARAMETERS_TYPE_IMPLICIT) {
+ /* implicit parameters inherited from CA - unsupported */
return NULL;
} else {
ECerr(EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS, EC_R_ASN1_ERROR);
@@ -947,6 +956,9 @@ EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len)
return NULL;
}
+ if (params->type == ECPKPARAMETERS_TYPE_EXPLICIT)
+ group->decoded_from_explicit_params = 1;
+
if (a) {
EC_GROUP_free(*a);
*a = group;
@@ -998,6 +1010,9 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
if (priv_key->parameters) {
EC_GROUP_free(ret->group);
ret->group = EC_GROUP_new_from_ecpkparameters(priv_key->parameters);
+ if (ret->group != NULL
+ && priv_key->parameters->type == ECPKPARAMETERS_TYPE_EXPLICIT)
+ ret->group->decoded_from_explicit_params = 1;
}
if (ret->group == NULL) {
diff --git a/crypto/ec/ec_key.c b/crypto/ec/ec_key.c
index 261087ce23..23efbd015c 100644
--- a/crypto/ec/ec_key.c
+++ b/crypto/ec/ec_key.c
@@ -564,6 +564,13 @@ void EC_KEY_clear_flags(EC_KEY *key, int flags)
key->flags &= ~flags;
}
+int EC_KEY_decoded_from_explicit_params(const EC_KEY *key)
+{
+ if (key == NULL || key->group == NULL)
+ return -1;
+ return key->group->decoded_from_explicit_params;
+}
+
size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form,
unsigned char **pbuf, BN_CTX *ctx)
{
diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c
index 6832383cad..08db89fcee 100644
--- a/crypto/ec/ec_lib.c
+++ b/crypto/ec/ec_lib.c
@@ -211,6 +211,7 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
dest->asn1_flag = src->asn1_flag;
dest->asn1_form = src->asn1_form;
+ dest->decoded_from_explicit_params = src->decoded_from_explicit_params;
if (src->seed) {
OPENSSL_free(dest->seed);
diff --git a/crypto/ec/ec_local.h b/crypto/ec/ec_local.h
index e656fbd5e7..6ea26193e1 100644
--- a/crypto/ec/ec_local.h
+++ b/crypto/ec/ec_local.h
@@ -209,6 +209,8 @@ struct ec_group_st {
BIGNUM *order, *cofactor;
int curve_name; /* optional NID for named curve */
int asn1_flag; /* flag to control the asn1 encoding */
+ int decoded_from_explicit_params; /* set if decoded from explicit
+ * curve parameters encoding */
point_conversion_form_t asn1_form;
unsigned char *seed; /* optional seed for parameters (appears in
* ASN1) */
diff --git a/doc/man3/EC_KEY_new.pod b/doc/man3/EC_KEY_new.pod
index 21663a032e..530979833d 100644
--- a/doc/man3/EC_KEY_new.pod
+++ b/doc/man3/EC_KEY_new.pod
@@ -9,7 +9,8 @@ EC_KEY_get0_engine,
EC_KEY_get0_group, EC_KEY_set_group, EC_KEY_get0_private_key,
EC_KEY_set_private_key, EC_KEY_get0_public_key, EC_KEY_set_public_key,
EC_KEY_get_conv_form,
-EC_KEY_set_conv_form, EC_KEY_set_asn1_flag, EC_KEY_precompute_mult,
+EC_KEY_set_conv_form, EC_KEY_set_asn1_flag,
+EC_KEY_decoded_from_explicit_params, EC_KEY_precompute_mult,
EC_KEY_generate_key, EC_KEY_check_key, EC_KEY_set_public_key_affine_coordinates,
EC_KEY_oct2key, EC_KEY_key2buf, EC_KEY_oct2priv, EC_KEY_priv2oct,
EC_KEY_priv2buf - Functions for creating, destroying and manipulating
@@ -38,6 +39,7 @@ EC_KEY objects
point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key);
void EC_KEY_set_conv_form(EC_KEY *eckey, point_conversion_form_t cform);
void EC_KEY_set_asn1_flag(EC_KEY *eckey, int asn1_flag);
+ int EC_KEY_decoded_from_explicit_params(const EC_KEY *key);
int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx);
int EC_KEY_generate_key(EC_KEY *key);
int EC_KEY_check_key(const EC_KEY *key);
@@ -118,6 +120,10 @@ EC_KEY_set_asn1_flag() sets the asn1_flag on the underlying EC_GROUP object
(if set). Refer to L<EC_GROUP_copy(3)> for further information on the
asn1_flag.
+EC_KEY_decoded_from_explicit_params() returns 1 if the group of the I<key> was
+decoded from data with explicitly encoded group parameters, -1 if the I<key>
+is NULL or the group parameters are missing, and 0 otherwise.
+
EC_KEY_precompute_mult() stores multiples of the underlying EC_GROUP generator
for faster point multiplication. See also L<EC_POINT_add(3)>.
diff --git a/include/openssl/ec.h b/include/openssl/ec.h
index 5af9ebdc7f..ca86ec15c5 100644
--- a/include/openssl/ec.h
+++ b/include/openssl/ec.h
@@ -829,6 +829,8 @@ void EC_KEY_set_flags(EC_KEY *key, int flags);
void EC_KEY_clear_flags(EC_KEY *key, int flags);
+int EC_KEY_decoded_from_explicit_params(const EC_KEY *key);
+
/** Creates a new EC_KEY object using a named curve as underlying
* EC_GROUP object.
* \param nid NID of the named curve.
diff --git a/test/ec_internal_test.c b/test/ec_internal_test.c
index 4b849312be..d1eede3a7f 100644
--- a/test/ec_internal_test.c
+++ b/test/ec_internal_test.c
@@ -183,6 +183,106 @@ static int field_tests_default(int n)
return ret;
}
+/*
+ * Tests behavior of the decoded_from_explicit_params flag and API
+ */
+static int decoded_flag_test(void)
+{
+ EC_GROUP *grp;
+ EC_GROUP *grp_copy = NULL;
+ ECPARAMETERS *ecparams = NULL;
+ ECPKPARAMETERS *ecpkparams = NULL;
+ EC_KEY *key = NULL;
+ unsigned char *encodedparams = NULL;
+ const unsigned char *encp;
+ int encodedlen;
+ int testresult = 0;
+
+ /* Test EC_GROUP_new not setting the flag */
+ grp = EC_GROUP_new(EC_GFp_simple_method());
+ if (!TEST_ptr(grp)
+ || !TEST_int_eq(grp->decoded_from_explicit_params, 0))
+ goto err;
+ EC_GROUP_free(grp);
+
+ /* Test EC_GROUP_new_by_curve_name not setting the flag */
+ grp = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
+ if (!TEST_ptr(grp)
+ || !TEST_int_eq(grp->decoded_from_explicit_params, 0))
+ goto err;
+
+ /* Test EC_GROUP_new_from_ecparameters not setting the flag */
+ if (!TEST_ptr(ecparams = EC_GROUP_get_ecparameters(grp, NULL))
+ || !TEST_ptr(grp_copy = EC_GROUP_new_from_ecparameters(ecparams))
+ || !TEST_int_eq(grp_copy->decoded_from_explicit_params, 0))
+ goto err;
+ EC_GROUP_free(grp_copy);
+ grp_copy = NULL;
+ ECPARAMETERS_free(ecparams);
+ ecparams = NULL;
+
+ /* Test EC_GROUP_new_from_ecpkparameters not setting the flag */
+ if (!TEST_int_eq(EC_GROUP_get_asn1_flag(grp), OPENSSL_EC_NAMED_CURVE)
+ || !TEST_ptr(ecpkparams = EC_GROUP_get_ecpkparameters(grp, NULL))
+ || !TEST_ptr(grp_copy = EC_GROUP_new_from_ecpkparameters(ecpkparams))
+ || !TEST_int_eq(grp_copy->decoded_from_explicit_params, 0)
+ || !TEST_ptr(key = EC_KEY_new())
+ /* Test EC_KEY_decoded_from_explicit_params on key without a group */
+ || !TEST_int_eq(EC_KEY_decoded_from_explicit_params(key), -1)
+ || !TEST_int_eq(EC_KEY_set_group(key, grp_copy), 1)
+ /* Test EC_KEY_decoded_from_explicit_params negative case */
+ || !TEST_int_eq(EC_KEY_decoded_from_explicit_params(key), 0))
+ goto err;
+ EC_GROUP_free(grp_copy);
+ grp_copy = NULL;
+ ECPKPARAMETERS_free(ecpkparams);
+ ecpkparams = NULL;
+
+ /* Test d2i_ECPKParameters with named params not setting the flag */
+ if (!TEST_int_gt(encodedlen = i2d_ECPKParameters(grp, &encodedparams), 0)
+ || !TEST_ptr(encp = encodedparams)
+ || !TEST_ptr(grp_copy = d2i_ECPKParameters(NULL, &encp, encodedlen))
+ || !TEST_int_eq(grp_copy->decoded_from_explicit_params, 0))
+ goto err;
+ EC_GROUP_free(grp_copy);
+ grp_copy = NULL;
+ OPENSSL_free(encodedparams);
+ encodedparams = NULL;
+
+ /* Asn1 flag stays set to explicit with EC_GROUP_new_from_ecpkparameters */
+ EC_GROUP_set_asn1_flag(grp, OPENSSL_EC_EXPLICIT_CURVE);
+ if (!TEST_ptr(ecpkparams = EC_GROUP_get_ecpkparameters(grp, NULL))
+ || !TEST_ptr(grp_copy = EC_GROUP_new_from_ecpkparameters(ecpkparams))
+ || !TEST_int_eq(EC_GROUP_get_asn1_flag(grp_copy), OPENSSL_EC_EXPLICIT_CURVE)
+ || !TEST_int_eq(grp_copy->decoded_from_explicit_params, 0))
+ goto err;
+ EC_GROUP_free(grp_copy);
+ grp_copy = NULL;
+
+ /* Test d2i_ECPKParameters with explicit params setting the flag */
+ if (!TEST_int_gt(encodedlen = i2d_ECPKParameters(grp, &encodedparams), 0)
+ || !TEST_ptr(encp = encodedparams)
+ || !TEST_ptr(grp_copy = d2i_ECPKParameters(NULL, &encp, encodedlen))
+ || !TEST_int_eq(EC_GROUP_get_asn1_flag(grp_copy), OPENSSL_EC_EXPLICIT_CURVE)
+ || !TEST_int_eq(grp_copy->decoded_from_explicit_params, 1)
+ || !TEST_int_eq(EC_KEY_set_group(key, grp_copy), 1)
+ /* Test EC_KEY_decoded_from_explicit_params positive case */
+ || !TEST_int_eq(EC_KEY_decoded_from_explicit_params(key), 1))
+ goto err;
+
+ testresult = 1;
+
+ err:
+ EC_KEY_free(key);
+ EC_GROUP_free(grp);
+ EC_GROUP_free(grp_copy);
+ ECPARAMETERS_free(ecparams);
+ ECPKPARAMETERS_free(ecpkparams);
+ OPENSSL_free(encodedparams);
+
+ return testresult;
+}
+
int setup_tests(void)
{
crv_len = EC_get_builtin_curves(NULL, 0);
@@ -196,6 +296,7 @@ int setup_tests(void)
ADD_TEST(field_tests_ec2_simple);
#endif
ADD_ALL_TESTS(field_tests_default, crv_len);
+ ADD_TEST(decoded_flag_test);
return 1;
}
diff --git a/util/libcrypto.num b/util/libcrypto.num
index e16b836eb2..436f799bca 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -4590,3 +4590,4 @@ RSA_get0_pss_params 4543 1_1_1e EXIST::FUNCTION:RSA
X509_ALGOR_copy 4544 1_1_1h EXIST::FUNCTION:
X509_REQ_set0_signature 4545 1_1_1h EXIST::FUNCTION:
X509_REQ_set1_signature_algo 4546 1_1_1h EXIST::FUNCTION:
+EC_KEY_decoded_from_explicit_params 4547 1_1_1h EXIST::FUNCTION:EC