From 2f2e6b6278bc4cbf670e42ae9f4ff818529df37c Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Mon, 18 Jun 2018 15:49:15 -0400 Subject: [PATCH] Add EVP_PKEY_set_alias_type Reviewed-by: Andy Polyakov Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/6443) --- crypto/err/openssl.txt | 1 + crypto/evp/evp_err.c | 2 ++ crypto/evp/p_lib.c | 20 ++++++++++++++++++++ crypto/evp/pmeth_lib.c | 5 ++--- doc/man3/EVP_PKEY_set1_RSA.pod | 16 +++++++++++++++- include/openssl/evp.h | 1 + include/openssl/evperr.h | 1 + util/libcrypto.num | 1 + 8 files changed, 43 insertions(+), 4 deletions(-) diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index 4b8e8c4ac7..363cca7337 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -774,6 +774,7 @@ EVP_F_EVP_PKEY_PARAMGEN_INIT:149:EVP_PKEY_paramgen_init EVP_F_EVP_PKEY_PARAM_CHECK:189:EVP_PKEY_param_check EVP_F_EVP_PKEY_PUBLIC_CHECK:190:EVP_PKEY_public_check EVP_F_EVP_PKEY_SET1_ENGINE:187:EVP_PKEY_set1_engine +EVP_F_EVP_PKEY_SET_ALIAS_TYPE:206:EVP_PKEY_set_alias_type EVP_F_EVP_PKEY_SIGN:140:EVP_PKEY_sign EVP_F_EVP_PKEY_SIGN_INIT:141:EVP_PKEY_sign_init EVP_F_EVP_PKEY_VERIFY:142:EVP_PKEY_verify diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c index 4403fa5746..3e14a7b509 100644 --- a/crypto/evp/evp_err.c +++ b/crypto/evp/evp_err.c @@ -122,6 +122,8 @@ static const ERR_STRING_DATA EVP_str_functs[] = { "EVP_PKEY_public_check"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_SET1_ENGINE, 0), "EVP_PKEY_set1_engine"}, + {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_SET_ALIAS_TYPE, 0), + "EVP_PKEY_set_alias_type"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_SIGN, 0), "EVP_PKEY_sign"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_SIGN_INIT, 0), "EVP_PKEY_sign_init"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_VERIFY, 0), "EVP_PKEY_verify"}, diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index d78f1d2d84..9429be97e3 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -356,6 +356,26 @@ int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len) { return pkey_set_type(pkey, NULL, EVP_PKEY_NONE, str, len); } + +int EVP_PKEY_set_alias_type(EVP_PKEY *pkey, int type) +{ + if (pkey->type == type) { + return 1; /* it already is that type */ + } + + /* + * The application is requesting to alias this to a different pkey type, + * but not one that resolves to the base type. + */ + if (EVP_PKEY_type(type) != EVP_PKEY_base_id(pkey)) { + EVPerr(EVP_F_EVP_PKEY_SET_ALIAS_TYPE, EVP_R_UNSUPPORTED_ALGORITHM); + return 0; + } + + pkey->type = type; + return 1; +} + #ifndef OPENSSL_NO_ENGINE int EVP_PKEY_set1_engine(EVP_PKEY *pkey, ENGINE *e) { diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c index cf4dd43914..c7dc453308 100644 --- a/crypto/evp/pmeth_lib.c +++ b/crypto/evp/pmeth_lib.c @@ -101,10 +101,9 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) { EVP_PKEY_CTX *ret; const EVP_PKEY_METHOD *pmeth; + if (id == -1) { - if (!pkey || !pkey->ameth) - return NULL; - id = pkey->ameth->pkey_id; + id = pkey->type; } #ifndef OPENSSL_NO_ENGINE if (e == NULL && pkey != NULL) diff --git a/doc/man3/EVP_PKEY_set1_RSA.pod b/doc/man3/EVP_PKEY_set1_RSA.pod index 884cf91cb7..2a1ec92268 100644 --- a/doc/man3/EVP_PKEY_set1_RSA.pod +++ b/doc/man3/EVP_PKEY_set1_RSA.pod @@ -7,7 +7,7 @@ EVP_PKEY_get1_RSA, EVP_PKEY_get1_DSA, EVP_PKEY_get1_DH, EVP_PKEY_get1_EC_KEY, EVP_PKEY_get0_RSA, EVP_PKEY_get0_DSA, EVP_PKEY_get0_DH, EVP_PKEY_get0_EC_KEY, EVP_PKEY_assign_RSA, EVP_PKEY_assign_DSA, EVP_PKEY_assign_DH, EVP_PKEY_assign_EC_KEY, EVP_PKEY_get0_hmac, EVP_PKEY_type, EVP_PKEY_id, -EVP_PKEY_base_id, EVP_PKEY_set1_engine - EVP_PKEY assignment functions +EVP_PKEY_base_id, EVP_PKEY_set_alias_type, EVP_PKEY_set1_engine - EVP_PKEY assignment functions =head1 SYNOPSIS @@ -37,6 +37,7 @@ EVP_PKEY_base_id, EVP_PKEY_set1_engine - EVP_PKEY assignment functions int EVP_PKEY_id(const EVP_PKEY *pkey); int EVP_PKEY_base_id(const EVP_PKEY *pkey); int EVP_PKEY_type(int type); + int EVP_PKEY_set_alias_type(EVP_PKEY *pkey, int type); int EVP_PKEY_set1_engine(EVP_PKEY *pkey, ENGINE *engine); @@ -78,6 +79,10 @@ must be called after the key algorithm and components are set up. If B does not include an B for B an error occurs. +EVP_PKEY_set_alias_type() allows modifying a EVP_PKEY to use a +different set of algorithms than the default. This is currently used +to support SM2 keys, which use an identical encoding to ECDSA. + =head1 NOTES In accordance with the OpenSSL naming convention the key obtained @@ -98,6 +103,13 @@ is no longer possible: the equivalent is EVP_PKEY_base_id(pkey). EVP_PKEY_set1_engine() is typically used by an ENGINE returning an HSM key as part of its routine to load a private key. +=head1 EXAMPLES + +After loading an ECC key, it is possible to convert it to using SM2 +algorithms with EVP_PKEY_set_alias_type: + + EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2); + =head1 RETURN VALUES EVP_PKEY_set1_RSA(), EVP_PKEY_set1_DSA(), EVP_PKEY_set1_DH() and @@ -115,6 +127,8 @@ type or B (equivalently B) on error. EVP_PKEY_set1_engine() returns 1 for success and 0 for failure. +EVP_PKEY_set_alias_type() returns 1 for success and 0 for error. + =head1 SEE ALSO L diff --git a/include/openssl/evp.h b/include/openssl/evp.h index 33ff674668..185cc29b88 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h @@ -995,6 +995,7 @@ int EVP_PKEY_security_bits(const EVP_PKEY *pkey); int EVP_PKEY_size(EVP_PKEY *pkey); int EVP_PKEY_set_type(EVP_PKEY *pkey, int type); int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len); +int EVP_PKEY_set_alias_type(EVP_PKEY *pkey, int type); # ifndef OPENSSL_NO_ENGINE int EVP_PKEY_set1_engine(EVP_PKEY *pkey, ENGINE *e); # endif diff --git a/include/openssl/evperr.h b/include/openssl/evperr.h index 8ab1765659..3484fa841d 100644 --- a/include/openssl/evperr.h +++ b/include/openssl/evperr.h @@ -96,6 +96,7 @@ int ERR_load_EVP_strings(void); # define EVP_F_EVP_PKEY_PARAM_CHECK 189 # define EVP_F_EVP_PKEY_PUBLIC_CHECK 190 # define EVP_F_EVP_PKEY_SET1_ENGINE 187 +# define EVP_F_EVP_PKEY_SET_ALIAS_TYPE 206 # define EVP_F_EVP_PKEY_SIGN 140 # define EVP_F_EVP_PKEY_SIGN_INIT 141 # define EVP_F_EVP_PKEY_VERIFY 142 diff --git a/util/libcrypto.num b/util/libcrypto.num index a25f65fb0d..f5122e2cfa 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -4567,3 +4567,4 @@ EVP_PKEY_get_raw_public_key 4518 1_1_1 EXIST::FUNCTION: EVP_PKEY_get_raw_private_key 4519 1_1_1 EXIST::FUNCTION: EVP_PKEY_asn1_set_get_priv_key 4520 1_1_1 EXIST::FUNCTION: EVP_PKEY_asn1_set_get_pub_key 4521 1_1_1 EXIST::FUNCTION: +EVP_PKEY_set_alias_type 4522 1_1_1 EXIST::FUNCTION: -- GitLab