diff options
author | Tomas Mraz <tomas@openssl.org> | 2021-11-18 20:09:57 +0100 |
---|---|---|
committer | Tomas Mraz <tomas@openssl.org> | 2021-11-22 10:50:10 +0100 |
commit | 615a9b8798e6ec58f1b2e1ec08a0f6b3c8cb7f60 (patch) | |
tree | 36c43f08d40f17f157054647c357c046342432ff /crypto | |
parent | f87b4c4ea67393c9269663ed40a7ea3463cc59d3 (diff) | |
download | openssl-new-615a9b8798e6ec58f1b2e1ec08a0f6b3c8cb7f60.tar.gz |
d2i_PublicKey: Make it work with EC parameters in a provided key
Fixes #16989
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/17065)
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/asn1/d2i_pu.c | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/crypto/asn1/d2i_pu.c b/crypto/asn1/d2i_pu.c index ddf1aad700..1be114b8a2 100644 --- a/crypto/asn1/d2i_pu.c +++ b/crypto/asn1/d2i_pu.c @@ -29,16 +29,27 @@ EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp, long length) { EVP_PKEY *ret; + EVP_PKEY *copy = NULL; if ((a == NULL) || (*a == NULL)) { if ((ret = EVP_PKEY_new()) == NULL) { ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); return NULL; } - } else + } else { ret = *a; - if (type != EVP_PKEY_get_id(ret) && !EVP_PKEY_set_type(ret, type)) { +#ifndef OPENSSL_NO_EC + if (evp_pkey_is_provided(ret) + && EVP_PKEY_get_base_id(ret) == EVP_PKEY_EC) { + if (!evp_pkey_copy_downgraded(©, ret)) + goto err; + } +#endif + } + + if ((type != EVP_PKEY_get_id(ret) || copy != NULL) + && !EVP_PKEY_set_type(ret, type)) { ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); goto err; } @@ -52,7 +63,6 @@ EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp, break; #ifndef OPENSSL_NO_DSA case EVP_PKEY_DSA: - /* TMP UGLY CAST */ if (!d2i_DSAPublicKey(&ret->pkey.dsa, pp, length)) { ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); goto err; @@ -61,6 +71,11 @@ EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp, #endif #ifndef OPENSSL_NO_EC case EVP_PKEY_EC: + if (copy != NULL) { + /* use downgraded parameters from copy */ + ret->pkey.ec = copy->pkey.ec; + copy->pkey.ec = NULL; + } if (!o2i_ECPublicKey(&ret->pkey.ec, pp, length)) { ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); goto err; @@ -73,9 +88,11 @@ EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp, } if (a != NULL) (*a) = ret; + EVP_PKEY_free(copy); return ret; err: if (a == NULL || *a != ret) EVP_PKEY_free(ret); + EVP_PKEY_free(copy); return NULL; } |