The branch master has been updated via f33c04b8de06aa3df22f776e3c26ad0277ed815f (commit) via bed7437b00734ee463de3c6fd6851458fa8c6cb0 (commit) via 0e5a4da4a86c6435c70d587d740c3096686a8500 (commit) from d5e08231dbef819b1d5381f851e72410df140f94 (commit)
- Log ----------------------------------------------------------------- commit f33c04b8de06aa3df22f776e3c26ad0277ed815f Author: Richard Levitte <levi...@openssl.org> Date: Sat May 15 07:45:31 2021 +0200 EVP: Modify EVP_PKEY_export() to handle legacy EVP_PKEYs We use a fake EVP_KEYMGMT import function with the newly modified EVP_PKEY_ASN1_METHOD export_to function to pass the exported OSSL_PARAM array directly to the EVP_PKEY_export() callback instead of exporting to an actual provided key and then getting the OSSL_PARAM array from there, just to throw away that key again. Fixes #15290 Reviewed-by: Tomas Mraz <to...@openssl.org> (Merged from https://github.com/openssl/openssl/pull/15293) commit bed7437b00734ee463de3c6fd6851458fa8c6cb0 Author: Richard Levitte <levi...@openssl.org> Date: Sat May 15 07:43:06 2021 +0200 Modify EVP_PKEY_ASN1_METHOD's export_to function to take an importer We previously took an EVP_KEYMGMT pointer, but now found it necessary to use a different import function in some cases. Since that's the only thing we use from EVP_KEYMGMT, we might as well pass the import function directly, allowing for some flexibility in how export_to is used. Reviewed-by: Tomas Mraz <to...@openssl.org> (Merged from https://github.com/openssl/openssl/pull/15293) commit 0e5a4da4a86c6435c70d587d740c3096686a8500 Author: Richard Levitte <levi...@openssl.org> Date: Sat May 15 08:14:49 2021 +0200 test/evp_extra_test2.c: Try EVP_PKEY_export() with a legacy RSA key Reviewed-by: Tomas Mraz <to...@openssl.org> (Merged from https://github.com/openssl/openssl/pull/15293) ----------------------------------------------------------------------- Summary of changes: crypto/dh/dh_ameth.c | 6 +++--- crypto/dsa/dsa_ameth.c | 6 +++--- crypto/ec/ec_ameth.c | 6 +++--- crypto/ec/ecx_meth.c | 6 +++--- crypto/evp/p_lib.c | 3 ++- crypto/evp/pmeth_gn.c | 35 +++++++++++++++++++++++++++++++++++ crypto/rsa/rsa_ameth.c | 17 +++++++++-------- include/crypto/asn1.h | 5 +++-- test/evp_extra_test2.c | 40 +++++++++++++++++++++++++++++++++------- 9 files changed, 94 insertions(+), 30 deletions(-) diff --git a/crypto/dh/dh_ameth.c b/crypto/dh/dh_ameth.c index d96b54285b..3d23321b59 100644 --- a/crypto/dh/dh_ameth.c +++ b/crypto/dh/dh_ameth.c @@ -440,8 +440,8 @@ static size_t dh_pkey_dirty_cnt(const EVP_PKEY *pkey) } static int dh_pkey_export_to(const EVP_PKEY *from, void *to_keydata, - EVP_KEYMGMT *to_keymgmt, OSSL_LIB_CTX *libctx, - const char *propq) + OSSL_FUNC_keymgmt_import_fn *importer, + OSSL_LIB_CTX *libctx, const char *propq) { DH *dh = from->pkey.dh; OSSL_PARAM_BLD *tmpl; @@ -495,7 +495,7 @@ static int dh_pkey_export_to(const EVP_PKEY *from, void *to_keydata, goto err; /* We export, the provider imports */ - rv = evp_keymgmt_import(to_keymgmt, to_keydata, selection, params); + rv = importer(to_keydata, selection, params); OSSL_PARAM_free(params); err: diff --git a/crypto/dsa/dsa_ameth.c b/crypto/dsa/dsa_ameth.c index 2e1ad081dc..ea9f839955 100644 --- a/crypto/dsa/dsa_ameth.c +++ b/crypto/dsa/dsa_ameth.c @@ -424,8 +424,8 @@ static size_t dsa_pkey_dirty_cnt(const EVP_PKEY *pkey) } static int dsa_pkey_export_to(const EVP_PKEY *from, void *to_keydata, - EVP_KEYMGMT *to_keymgmt, OSSL_LIB_CTX *libctx, - const char *propq) + OSSL_FUNC_keymgmt_import_fn *importer, + OSSL_LIB_CTX *libctx, const char *propq) { DSA *dsa = from->pkey.dsa; OSSL_PARAM_BLD *tmpl; @@ -472,7 +472,7 @@ static int dsa_pkey_export_to(const EVP_PKEY *from, void *to_keydata, goto err; /* We export, the provider imports */ - rv = evp_keymgmt_import(to_keymgmt, to_keydata, selection, params); + rv = importer(to_keydata, selection, params); OSSL_PARAM_free(params); err: diff --git a/crypto/ec/ec_ameth.c b/crypto/ec/ec_ameth.c index e49252449d..32fe692d8a 100644 --- a/crypto/ec/ec_ameth.c +++ b/crypto/ec/ec_ameth.c @@ -478,8 +478,8 @@ size_t ec_pkey_dirty_cnt(const EVP_PKEY *pkey) static int ec_pkey_export_to(const EVP_PKEY *from, void *to_keydata, - EVP_KEYMGMT *to_keymgmt, OSSL_LIB_CTX *libctx, - const char *propq) + OSSL_FUNC_keymgmt_import_fn *importer, + OSSL_LIB_CTX *libctx, const char *propq) { const EC_KEY *eckey = NULL; const EC_GROUP *ecg = NULL; @@ -607,7 +607,7 @@ int ec_pkey_export_to(const EVP_PKEY *from, void *to_keydata, params = OSSL_PARAM_BLD_to_param(tmpl); /* We export, the provider imports */ - rv = evp_keymgmt_import(to_keymgmt, to_keydata, selection, params); + rv = importer(to_keydata, selection, params); err: OSSL_PARAM_BLD_free(tmpl); diff --git a/crypto/ec/ecx_meth.c b/crypto/ec/ecx_meth.c index 61f062a2f8..c47bd9f9dd 100644 --- a/crypto/ec/ecx_meth.c +++ b/crypto/ec/ecx_meth.c @@ -346,8 +346,8 @@ static size_t ecx_pkey_dirty_cnt(const EVP_PKEY *pkey) } static int ecx_pkey_export_to(const EVP_PKEY *from, void *to_keydata, - EVP_KEYMGMT *to_keymgmt, OSSL_LIB_CTX *libctx, - const char *propq) + OSSL_FUNC_keymgmt_import_fn *importer, + OSSL_LIB_CTX *libctx, const char *propq) { const ECX_KEY *key = from->pkey.ecx; OSSL_PARAM_BLD *tmpl = OSSL_PARAM_BLD_new(); @@ -375,7 +375,7 @@ static int ecx_pkey_export_to(const EVP_PKEY *from, void *to_keydata, params = OSSL_PARAM_BLD_to_param(tmpl); /* We export, the provider imports */ - rv = evp_keymgmt_import(to_keymgmt, to_keydata, selection, params); + rv = importer(to_keydata, selection, params); err: OSSL_PARAM_BLD_free(tmpl); diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index 00a310d4e4..9b31c58288 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -1878,7 +1878,8 @@ void *evp_pkey_export_to_provider(EVP_PKEY *pk, OSSL_LIB_CTX *libctx, if ((keydata = evp_keymgmt_newdata(tmp_keymgmt)) == NULL) goto end; - if (!pk->ameth->export_to(pk, keydata, tmp_keymgmt, libctx, propquery)) { + if (!pk->ameth->export_to(pk, keydata, tmp_keymgmt->import, + libctx, propquery)) { evp_keymgmt_freedata(tmp_keymgmt, keydata); keydata = NULL; goto end; diff --git a/crypto/evp/pmeth_gn.c b/crypto/evp/pmeth_gn.c index 94499b1d45..9af18d90fc 100644 --- a/crypto/evp/pmeth_gn.c +++ b/crypto/evp/pmeth_gn.c @@ -413,8 +413,43 @@ int EVP_PKEY_todata(const EVP_PKEY *pkey, int selection, OSSL_PARAM **params) return EVP_PKEY_export(pkey, selection, ossl_pkey_todata_cb, params); } +#ifndef FIPS_MODULE +struct fake_import_data_st { + OSSL_CALLBACK *export_cb; + void *export_cbarg; +}; + +static OSSL_FUNC_keymgmt_import_fn pkey_fake_import; +static int pkey_fake_import(void *fake_keydata, int ignored_selection, + const OSSL_PARAM params[]) +{ + struct fake_import_data_st *data = fake_keydata; + + return data->export_cb(params, data->export_cbarg); +} +#endif + int EVP_PKEY_export(const EVP_PKEY *pkey, int selection, OSSL_CALLBACK *export_cb, void *export_cbarg) { + if (pkey == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } +#ifndef FIPS_MODULE + if (evp_pkey_is_legacy(pkey)) { + struct fake_import_data_st data; + + data.export_cb = export_cb; + data.export_cbarg = export_cbarg; + + /* + * We don't need to care about libctx or propq here, as we're only + * interested in the resulting OSSL_PARAM array. + */ + return pkey->ameth->export_to(pkey, &data, pkey_fake_import, + NULL, NULL); + } +#endif return evp_keymgmt_util_export(pkey, selection, export_cb, export_cbarg); } diff --git a/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c index 2f9d60a7b3..f2283d81bd 100644 --- a/crypto/rsa/rsa_ameth.c +++ b/crypto/rsa/rsa_ameth.c @@ -725,7 +725,8 @@ static size_t rsa_pkey_dirty_cnt(const EVP_PKEY *pkey) * checks in this method since the caller tests EVP_KEYMGMT_is_a() first. */ static int rsa_int_export_to(const EVP_PKEY *from, int rsa_type, - void *to_keydata, EVP_KEYMGMT *to_keymgmt, + void *to_keydata, + OSSL_FUNC_keymgmt_import_fn *importer, OSSL_LIB_CTX *libctx, const char *propq) { RSA *rsa = from->pkey.rsa; @@ -778,7 +779,7 @@ static int rsa_int_export_to(const EVP_PKEY *from, int rsa_type, goto err; /* We export, the provider imports */ - rv = evp_keymgmt_import(to_keymgmt, to_keydata, selection, params); + rv = importer(to_keydata, selection, params); err: OSSL_PARAM_free(params); @@ -859,19 +860,19 @@ static int rsa_int_import_from(const OSSL_PARAM params[], void *vpctx, } static int rsa_pkey_export_to(const EVP_PKEY *from, void *to_keydata, - EVP_KEYMGMT *to_keymgmt, OSSL_LIB_CTX *libctx, - const char *propq) + OSSL_FUNC_keymgmt_import_fn *importer, + OSSL_LIB_CTX *libctx, const char *propq) { return rsa_int_export_to(from, RSA_FLAG_TYPE_RSA, to_keydata, - to_keymgmt, libctx, propq); + importer, libctx, propq); } static int rsa_pss_pkey_export_to(const EVP_PKEY *from, void *to_keydata, - EVP_KEYMGMT *to_keymgmt, OSSL_LIB_CTX *libctx, - const char *propq) + OSSL_FUNC_keymgmt_import_fn *importer, + OSSL_LIB_CTX *libctx, const char *propq) { return rsa_int_export_to(from, RSA_FLAG_TYPE_RSASSAPSS, to_keydata, - to_keymgmt, libctx, propq); + importer, libctx, propq); } static int rsa_pkey_import_from(const OSSL_PARAM params[], void *vpctx) diff --git a/include/crypto/asn1.h b/include/crypto/asn1.h index 17d5f637ef..5a187e41a7 100644 --- a/include/crypto/asn1.h +++ b/include/crypto/asn1.h @@ -12,6 +12,7 @@ # pragma once # include <openssl/asn1.h> +# include <openssl/core_dispatch.h> /* OSSL_FUNC_keymgmt_import() */ /* Internal ASN1 structures and functions: not for application use */ @@ -80,8 +81,8 @@ struct evp_pkey_asn1_method_st { /* Exports and imports to / from providers */ size_t (*dirty_cnt) (const EVP_PKEY *pk); int (*export_to) (const EVP_PKEY *pk, void *to_keydata, - EVP_KEYMGMT *to_keymgmt, OSSL_LIB_CTX *libctx, - const char *propq); + OSSL_FUNC_keymgmt_import_fn *importer, + OSSL_LIB_CTX *libctx, const char *propq); OSSL_CALLBACK *import_from; int (*copy) (EVP_PKEY *to, EVP_PKEY *from); diff --git a/test/evp_extra_test2.c b/test/evp_extra_test2.c index 3ad28d867a..3f7edac278 100644 --- a/test/evp_extra_test2.c +++ b/test/evp_extra_test2.c @@ -7,6 +7,9 @@ * https://www.openssl.org/source/license.html */ +/* We need to use some deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + /* * Really these tests should be in evp_extra_test - but that doesn't * yet support testing with a non-default libctx. Once it does we should move @@ -17,6 +20,9 @@ #include <openssl/evp.h> #include <openssl/pem.h> #include <openssl/provider.h> +#ifndef OPENSSL_NO_DEPRECATED_3_0 +# include <openssl/rsa.h> +#endif #include <openssl/core_names.h> #include "testutil.h" #include "internal/nelem.h" @@ -744,16 +750,36 @@ static int test_pkey_export_null(void) static int test_pkey_export(void) { EVP_PKEY *pkey = NULL; - int ret = 0; +#ifndef OPENSSL_NO_DEPRECATED_3_0 + RSA *rsa = NULL; +#endif + int ret = 1; const unsigned char *pdata = keydata[0].kder; + int pdata_len = keydata[0].size; - ret = TEST_ptr(pkey = d2i_AutoPrivateKey_ex(NULL, &pdata, keydata[0].size, - mainctx, NULL)) - && TEST_int_eq(EVP_PKEY_export(pkey, EVP_PKEY_KEYPAIR, - test_pkey_export_cb, pkey), 1) - && TEST_int_eq(EVP_PKEY_export(pkey, EVP_PKEY_KEYPAIR, - test_pkey_export_cb, NULL), 0); + if (!TEST_ptr(pkey = d2i_AutoPrivateKey_ex(NULL, &pdata, pdata_len, + mainctx, NULL)) + || !TEST_true(EVP_PKEY_export(pkey, EVP_PKEY_KEYPAIR, + test_pkey_export_cb, pkey)) + || !TEST_false(EVP_PKEY_export(pkey, EVP_PKEY_KEYPAIR, + test_pkey_export_cb, NULL))) + ret = 0; EVP_PKEY_free(pkey); + +#ifndef OPENSSL_NO_DEPRECATED_3_0 + /* Now, try with a legacy key */ + pdata = keydata[0].kder; + pdata_len = keydata[0].size; + if (!TEST_ptr(rsa = d2i_RSAPrivateKey(NULL, &pdata, pdata_len)) + || !TEST_ptr(pkey = EVP_PKEY_new()) + || !TEST_true(EVP_PKEY_assign_RSA(pkey, rsa)) + || !TEST_true(EVP_PKEY_export(pkey, EVP_PKEY_KEYPAIR, + test_pkey_export_cb, pkey)) + || !TEST_false(EVP_PKEY_export(pkey, EVP_PKEY_KEYPAIR, + test_pkey_export_cb, NULL))) + ret = 0; + EVP_PKEY_free(pkey); +#endif return ret; }