diff options
author | Tomas Mraz <tomas@openssl.org> | 2021-04-13 17:31:08 +0200 |
---|---|---|
committer | Tomas Mraz <tomas@openssl.org> | 2021-04-19 11:36:16 +0200 |
commit | b247113c053903ebb61a54ba5324847ba883ed70 (patch) | |
tree | d01dfc99a0b4f52ba94b186ff1e476f1b1916e2f | |
parent | 5ae52001e115452ca285713feb1c2feaf07902ad (diff) |
Detect low-level engine and app method based keys
The low-level engine and app method based keys have to be treated
as foreign and must be used with old legacy pmeths.
Fixes #14632
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14859)
-rw-r--r-- | crypto/dh/dh_backend.c | 13 | ||||
-rw-r--r-- | crypto/dsa/dsa_backend.c | 13 | ||||
-rw-r--r-- | crypto/ec/ec_backend.c | 10 | ||||
-rw-r--r-- | crypto/evp/p_lib.c | 41 | ||||
-rw-r--r-- | crypto/evp/pmeth_lib.c | 4 | ||||
-rw-r--r-- | crypto/rsa/rsa_backend.c | 13 | ||||
-rw-r--r-- | include/crypto/dh.h | 1 | ||||
-rw-r--r-- | include/crypto/dsa.h | 1 | ||||
-rw-r--r-- | include/crypto/ec.h | 1 | ||||
-rw-r--r-- | include/crypto/evp.h | 3 | ||||
-rw-r--r-- | include/crypto/rsa.h | 1 |
11 files changed, 88 insertions, 13 deletions
diff --git a/crypto/dh/dh_backend.c b/crypto/dh/dh_backend.c index 18cf3f5992..a727d5c87b 100644 --- a/crypto/dh/dh_backend.c +++ b/crypto/dh/dh_backend.c @@ -118,6 +118,15 @@ int ossl_dh_key_todata(DH *dh, OSSL_PARAM_BLD *bld, OSSL_PARAM params[]) return 1; } +int ossl_dh_is_foreign(const DH *dh) +{ +#ifndef FIPS_MODULE + if (dh->engine != NULL || ossl_dh_get_method(dh) != DH_OpenSSL()) + return 1; +#endif + return 0; +} + static ossl_inline int dh_bn_dup_check(BIGNUM **out, const BIGNUM *f) { if (f != NULL && (*out = BN_dup(f)) == NULL) @@ -129,11 +138,9 @@ DH *ossl_dh_dup(const DH *dh, int selection) { DH *dupkey = NULL; -#ifndef FIPS_MODULE /* Do not try to duplicate foreign DH keys */ - if (ossl_dh_get_method(dh) != DH_OpenSSL()) + if (ossl_dh_is_foreign(dh)) return NULL; -#endif if ((dupkey = ossl_dh_new_ex(dh->libctx)) == NULL) return NULL; diff --git a/crypto/dsa/dsa_backend.c b/crypto/dsa/dsa_backend.c index 2ef8cbc9f3..e4fa070f23 100644 --- a/crypto/dsa/dsa_backend.c +++ b/crypto/dsa/dsa_backend.c @@ -57,6 +57,15 @@ int ossl_dsa_key_fromdata(DSA *dsa, const OSSL_PARAM params[]) return 0; } +int ossl_dsa_is_foreign(const DSA *dsa) +{ +#ifndef FIPS_MODULE + if (dsa->engine != NULL || DSA_get_method((DSA *)dsa) != DSA_OpenSSL()) + return 1; +#endif + return 0; +} + static ossl_inline int dsa_bn_dup_check(BIGNUM **out, const BIGNUM *f) { if (f != NULL && (*out = BN_dup(f)) == NULL) @@ -68,11 +77,9 @@ DSA *ossl_dsa_dup(const DSA *dsa, int selection) { DSA *dupkey = NULL; -#ifndef FIPS_MODULE /* Do not try to duplicate foreign DSA keys */ - if (DSA_get_method((DSA *)dsa) != DSA_OpenSSL()) + if (ossl_dsa_is_foreign(dsa)) return NULL; -#endif if ((dupkey = ossl_dsa_new(dsa->libctx)) == NULL) return NULL; diff --git a/crypto/ec/ec_backend.c b/crypto/ec/ec_backend.c index 0189a33a91..e9843eb4ac 100644 --- a/crypto/ec/ec_backend.c +++ b/crypto/ec/ec_backend.c @@ -520,6 +520,16 @@ int ossl_ec_key_otherparams_fromdata(EC_KEY *ec, const OSSL_PARAM params[]) return 1; } +int ossl_ec_key_is_foreign(const EC_KEY *ec) +{ +#ifndef FIPS_MODULE + if (ec->engine != NULL || EC_KEY_get_method(ec) != EC_KEY_OpenSSL()) + return 1; +#endif + return 0; + +} + EC_KEY *ossl_ec_key_dup(const EC_KEY *src, int selection) { EC_KEY *ret = ossl_ec_key_new_method_int(src->libctx, src->propq, diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index 407ef22154..db334fb1ef 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -37,14 +37,15 @@ #include "internal/ffc.h" #include "crypto/asn1.h" #include "crypto/evp.h" +#include "crypto/dh.h" +#include "crypto/dsa.h" #include "crypto/ec.h" #include "crypto/ecx.h" +#include "crypto/rsa.h" #include "crypto/x509.h" #include "internal/provider.h" #include "evp_local.h" -#include "crypto/ec.h" - #include "e_os.h" /* strcasecmp on Windows */ static int pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str, @@ -691,6 +692,38 @@ ENGINE *EVP_PKEY_get0_engine(const EVP_PKEY *pkey) # endif # ifndef OPENSSL_NO_DEPRECATED_3_0 +static void detect_foreign_key(EVP_PKEY *pkey) +{ + switch (pkey->type) { + case EVP_PKEY_RSA: + pkey->foreign = pkey->pkey.rsa != NULL + && ossl_rsa_is_foreign(pkey->pkey.rsa); + break; +# ifndef OPENSSL_NO_EC + case EVP_PKEY_SM2: + case EVP_PKEY_EC: + pkey->foreign = pkey->pkey.ec != NULL + && ossl_ec_key_is_foreign(pkey->pkey.ec); + break; +# endif +# ifndef OPENSSL_NO_DSA + case EVP_PKEY_DSA: + pkey->foreign = pkey->pkey.dsa != NULL + && ossl_dsa_is_foreign(pkey->pkey.dsa); + break; +#endif +# ifndef OPENSSL_NO_DH + case EVP_PKEY_DH: + pkey->foreign = pkey->pkey.dh != NULL + && ossl_dh_is_foreign(pkey->pkey.dh); + break; +#endif + default: + pkey->foreign = 0; + break; + } +} + int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) { # ifndef OPENSSL_NO_EC @@ -719,6 +752,8 @@ int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) return 0; pkey->pkey.ptr = key; + detect_foreign_key(pkey); + return (key != NULL); } # endif @@ -1354,7 +1389,6 @@ EVP_PKEY *EVP_PKEY_new(void) ret->type = EVP_PKEY_NONE; ret->save_type = EVP_PKEY_NONE; ret->references = 1; - ret->save_parameters = 1; ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) { @@ -1363,6 +1397,7 @@ EVP_PKEY *EVP_PKEY_new(void) } #ifndef FIPS_MODULE + ret->save_parameters = 1; if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_EVP_PKEY, ret, &ret->ex_data)) { ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); goto err; diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c index f145bdfdc6..f00394e081 100644 --- a/crypto/evp/pmeth_lib.c +++ b/crypto/evp/pmeth_lib.c @@ -224,7 +224,7 @@ static EVP_PKEY_CTX *int_ctx_new(OSSL_LIB_CTX *libctx, */ if (!ossl_assert(e == NULL || keytype == NULL)) return NULL; - if (e == NULL) + if (e == NULL && (pkey == NULL || pkey->foreign == 0)) keytype = OBJ_nid2sn(id); # ifndef OPENSSL_NO_ENGINE @@ -246,6 +246,8 @@ static EVP_PKEY_CTX *int_ctx_new(OSSL_LIB_CTX *libctx, */ if (e != NULL) pmeth = ENGINE_get_pkey_meth(e, id); + else if (pkey != NULL && pkey->foreign) + pmeth = EVP_PKEY_meth_find(id); else # endif pmeth = evp_pkey_meth_find_added_by_application(id); diff --git a/crypto/rsa/rsa_backend.c b/crypto/rsa/rsa_backend.c index 192b3fdbf7..4a0ad2856b 100644 --- a/crypto/rsa/rsa_backend.c +++ b/crypto/rsa/rsa_backend.c @@ -323,6 +323,15 @@ int ossl_rsa_pss_params_30_fromdata(RSA_PSS_PARAMS_30 *pss_params, return ret; } +int ossl_rsa_is_foreign(const RSA *rsa) +{ +#ifndef FIPS_MODULE + if (rsa->engine != NULL || RSA_get_method(rsa) != RSA_PKCS1_OpenSSL()) + return 1; +#endif + return 0; +} + static ossl_inline int rsa_bn_dup_check(BIGNUM **out, const BIGNUM *f) { if (f != NULL && (*out = BN_dup(f)) == NULL) @@ -335,11 +344,11 @@ RSA *ossl_rsa_dup(const RSA *rsa, int selection) RSA *dupkey = NULL; #ifndef FIPS_MODULE int pnum, i; +#endif /* Do not try to duplicate foreign RSA keys */ - if (RSA_get_method(rsa) != RSA_PKCS1_OpenSSL()) + if (ossl_rsa_is_foreign(rsa)) return NULL; -#endif if ((dupkey = ossl_rsa_new_with_ctx(rsa->libctx)) == NULL) return NULL; diff --git a/include/crypto/dh.h b/include/crypto/dh.h index 291e008c9c..ff7c65a468 100644 --- a/include/crypto/dh.h +++ b/include/crypto/dh.h @@ -56,6 +56,7 @@ int ossl_dh_kdf_X9_42_asn1(unsigned char *out, size_t outlen, const unsigned char *ukm, size_t ukmlen, const EVP_MD *md, OSSL_LIB_CTX *libctx, const char *propq); +int ossl_dh_is_foreign(const DH *dh); DH *ossl_dh_dup(const DH *dh, int selection); #endif /* OSSL_CRYPTO_DH_H */ diff --git a/include/crypto/dsa.h b/include/crypto/dsa.h index ed0c887b83..dad056bb28 100644 --- a/include/crypto/dsa.h +++ b/include/crypto/dsa.h @@ -43,6 +43,7 @@ int ossl_dsa_check_pub_key_partial(const DSA *dsa, const BIGNUM *pub_key, int *ret); int ossl_dsa_check_priv_key(const DSA *dsa, const BIGNUM *priv_key, int *ret); int ossl_dsa_check_pairwise(const DSA *dsa); +int ossl_dsa_is_foreign(const DSA *dsa); DSA *ossl_dsa_dup(const DSA *dsa, int selection); #endif diff --git a/include/crypto/ec.h b/include/crypto/ec.h index 80b5ce0735..9743dcc3a7 100644 --- a/include/crypto/ec.h +++ b/include/crypto/ec.h @@ -79,6 +79,7 @@ int ossl_ec_group_set_params(EC_GROUP *group, const OSSL_PARAM params[]); int ossl_ec_key_fromdata(EC_KEY *ecx, const OSSL_PARAM params[], int include_private); int ossl_ec_key_otherparams_fromdata(EC_KEY *ec, const OSSL_PARAM params[]); +int ossl_ec_key_is_foreign(const EC_KEY *ec); EC_KEY *ossl_ec_key_dup(const EC_KEY *key, int selection); EC_KEY *ossl_ec_key_param_from_x509_algor(const X509_ALGOR *palg, OSSL_LIB_CTX *libctx, diff --git a/include/crypto/evp.h b/include/crypto/evp.h index 0cd0434774..99e884ecfb 100644 --- a/include/crypto/evp.h +++ b/include/crypto/evp.h @@ -663,9 +663,10 @@ struct evp_pkey_st { /* == Common attributes == */ CRYPTO_REF_COUNT references; CRYPTO_RWLOCK *lock; +#ifndef FIPS_MODULE STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */ int save_parameters; -#ifndef FIPS_MODULE + int foreign:1; /* the low-level key is using an engine or an app-method */ CRYPTO_EX_DATA ex_data; #endif diff --git a/include/crypto/rsa.h b/include/crypto/rsa.h index f252363465..cc67e1f709 100644 --- a/include/crypto/rsa.h +++ b/include/crypto/rsa.h @@ -63,6 +63,7 @@ int ossl_rsa_set0_all_params(RSA *r, const STACK_OF(BIGNUM) *primes, int ossl_rsa_get0_all_params(RSA *r, STACK_OF(BIGNUM_const) *primes, STACK_OF(BIGNUM_const) *exps, STACK_OF(BIGNUM_const) *coeffs); +int ossl_rsa_is_foreign(const RSA *rsa); RSA *ossl_rsa_dup(const RSA *rsa, int selection); int ossl_rsa_todata(RSA *rsa, OSSL_PARAM_BLD *bld, OSSL_PARAM params[]); |