diff options
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/dh/dh_ameth.c | 44 | ||||
-rw-r--r-- | crypto/dsa/dsa_ameth.c | 42 | ||||
-rw-r--r-- | crypto/dsa/dsa_lib.c | 50 | ||||
-rw-r--r-- | crypto/evp/evp_local.h | 46 | ||||
-rw-r--r-- | crypto/evp/exchange.c | 4 | ||||
-rw-r--r-- | crypto/evp/keymgmt_lib.c | 153 | ||||
-rw-r--r-- | crypto/evp/keymgmt_meth.c | 334 | ||||
-rw-r--r-- | crypto/evp/m_sigver.c | 2 | ||||
-rw-r--r-- | crypto/evp/p_lib.c | 19 | ||||
-rw-r--r-- | crypto/evp/pmeth_check.c | 30 | ||||
-rw-r--r-- | crypto/evp/pmeth_fn.c | 2 | ||||
-rw-r--r-- | crypto/evp/pmeth_gn.c | 22 | ||||
-rw-r--r-- | crypto/evp/signature.c | 2 | ||||
-rw-r--r-- | crypto/rsa/rsa_ameth.c | 54 | ||||
-rw-r--r-- | crypto/serializer/serializer_local.h | 2 | ||||
-rw-r--r-- | crypto/serializer/serializer_pkey.c | 58 |
16 files changed, 329 insertions, 535 deletions
diff --git a/crypto/dh/dh_ameth.c b/crypto/dh/dh_ameth.c index fd241831dc..4f74ab6f4a 100644 --- a/crypto/dh/dh_ameth.c +++ b/crypto/dh/dh_ameth.c @@ -482,51 +482,47 @@ static size_t dh_pkey_dirty_cnt(const EVP_PKEY *pkey) return pkey->pkey.dh->dirty_cnt; } -static void *dh_pkey_export_to(const EVP_PKEY *pk, EVP_KEYMGMT *keymgmt, - int want_domainparams) +static int dh_pkey_export_to(const EVP_PKEY *from, void *to_keydata, + EVP_KEYMGMT *to_keymgmt) { - DH *dh = pk->pkey.dh; + DH *dh = from->pkey.dh; OSSL_PARAM_BLD tmpl; const BIGNUM *p = DH_get0_p(dh), *g = DH_get0_g(dh), *q = DH_get0_q(dh); const BIGNUM *pub_key = DH_get0_pub_key(dh); const BIGNUM *priv_key = DH_get0_priv_key(dh); OSSL_PARAM *params; - void *provdata = NULL; + int rv; if (p == NULL || g == NULL) - return NULL; + return 0; ossl_param_bld_init(&tmpl); if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_P, p) || !ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_G, g)) - return NULL; + return 0; if (q != NULL) { if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_Q, q)) - return NULL; + return 0; } - - if (!want_domainparams) { - /* A key must at least have a public part. */ - if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DH_PUB_KEY, - pub_key)) - return NULL; - - if (priv_key != NULL) { - if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DH_PRIV_KEY, - priv_key)) - return NULL; - } + /* A key must at least have a public part. */ + if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DH_PUB_KEY, pub_key)) + return 0; + if (priv_key != NULL) { + if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DH_PRIV_KEY, + priv_key)) + return 0; } - params = ossl_param_bld_to_param(&tmpl); + if ((params = ossl_param_bld_to_param(&tmpl)) == NULL) + return 0; /* We export, the provider imports */ - provdata = want_domainparams - ? evp_keymgmt_importdomparams(keymgmt, params) - : evp_keymgmt_importkey(keymgmt, params); + rv = evp_keymgmt_import(to_keymgmt, to_keydata, OSSL_KEYMGMT_SELECT_ALL, + params); ossl_param_bld_free(params); - return provdata; + + return rv; } const EVP_PKEY_ASN1_METHOD dh_asn1_meth = { diff --git a/crypto/dsa/dsa_ameth.c b/crypto/dsa/dsa_ameth.c index 510b204b2d..9d1b89717c 100644 --- a/crypto/dsa/dsa_ameth.c +++ b/crypto/dsa/dsa_ameth.c @@ -511,48 +511,44 @@ static size_t dsa_pkey_dirty_cnt(const EVP_PKEY *pkey) return pkey->pkey.dsa->dirty_cnt; } -static void *dsa_pkey_export_to(const EVP_PKEY *pk, EVP_KEYMGMT *keymgmt, - int want_domainparams) +static int dsa_pkey_export_to(const EVP_PKEY *from, void *to_keydata, + EVP_KEYMGMT *to_keymgmt) { - DSA *dsa = pk->pkey.dsa; + DSA *dsa = from->pkey.dsa; OSSL_PARAM_BLD tmpl; const BIGNUM *p = DSA_get0_p(dsa), *g = DSA_get0_g(dsa); const BIGNUM *q = DSA_get0_q(dsa), *pub_key = DSA_get0_pub_key(dsa); const BIGNUM *priv_key = DSA_get0_priv_key(dsa); OSSL_PARAM *params; - void *provdata = NULL; + int rv; if (p == NULL || q == NULL || g == NULL) - return NULL; + return 0; ossl_param_bld_init(&tmpl); if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_P, p) || !ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_Q, q) || !ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_G, g)) - return NULL; - - if (!want_domainparams) { - /* A key must at least have a public part. */ - if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DSA_PUB_KEY, - pub_key)) - return NULL; - - if (priv_key != NULL) { - if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DSA_PRIV_KEY, - priv_key)) - return NULL; - } + return 0; + if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DSA_PUB_KEY, + pub_key)) + return 0; + if (priv_key != NULL) { + if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DSA_PRIV_KEY, + priv_key)) + return 0; } - params = ossl_param_bld_to_param(&tmpl); + if ((params = ossl_param_bld_to_param(&tmpl)) == NULL) + return 0; /* We export, the provider imports */ - provdata = want_domainparams - ? evp_keymgmt_importdomparams(keymgmt, params) - : evp_keymgmt_importkey(keymgmt, params); + rv = evp_keymgmt_import(to_keymgmt, to_keydata, OSSL_KEYMGMT_SELECT_ALL, + params); ossl_param_bld_free(params); - return provdata; + + return rv; } /* NB these are sorted in pkey_id order, lowest first */ diff --git a/crypto/dsa/dsa_lib.c b/crypto/dsa/dsa_lib.c index 469746e65d..334ee747dd 100644 --- a/crypto/dsa/dsa_lib.c +++ b/crypto/dsa/dsa_lib.c @@ -75,31 +75,6 @@ DH *DSA_dup_DH(const DSA *r) } # endif /* OPENSSL_NO_DH */ -const BIGNUM *DSA_get0_p(const DSA *d) -{ - return d->params.p; -} - -const BIGNUM *DSA_get0_q(const DSA *d) -{ - return d->params.q; -} - -const BIGNUM *DSA_get0_g(const DSA *d) -{ - return d->params.g; -} - -const BIGNUM *DSA_get0_pub_key(const DSA *d) -{ - return d->pub_key; -} - -const BIGNUM *DSA_get0_priv_key(const DSA *d) -{ - return d->priv_key; -} - void DSA_clear_flags(DSA *d, int flags) { d->flags &= ~flags; @@ -278,6 +253,31 @@ int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) return 1; } +const BIGNUM *DSA_get0_p(const DSA *d) +{ + return d->params.p; +} + +const BIGNUM *DSA_get0_q(const DSA *d) +{ + return d->params.q; +} + +const BIGNUM *DSA_get0_g(const DSA *d) +{ + return d->params.g; +} + +const BIGNUM *DSA_get0_pub_key(const DSA *d) +{ + return d->pub_key; +} + +const BIGNUM *DSA_get0_priv_key(const DSA *d) +{ + return d->priv_key; +} + void DSA_get0_key(const DSA *d, const BIGNUM **pub_key, const BIGNUM **priv_key) { diff --git a/crypto/evp/evp_local.h b/crypto/evp/evp_local.h index 5f34aaeb23..95dd1c036e 100644 --- a/crypto/evp/evp_local.h +++ b/crypto/evp/evp_local.h @@ -73,39 +73,24 @@ struct evp_keymgmt_st { CRYPTO_REF_COUNT refcnt; CRYPTO_RWLOCK *lock; - /* Domain parameter routines */ - OSSL_OP_keymgmt_importdomparams_fn *importdomparams; - OSSL_OP_keymgmt_gendomparams_fn *gendomparams; - OSSL_OP_keymgmt_freedomparams_fn *freedomparams; - OSSL_OP_keymgmt_exportdomparams_fn *exportdomparams; - OSSL_OP_keymgmt_importdomparam_types_fn *importdomparam_types; - OSSL_OP_keymgmt_exportdomparam_types_fn *exportdomparam_types; - OSSL_OP_keymgmt_get_domparam_params_fn *get_domparam_params; - OSSL_OP_keymgmt_gettable_domparam_params_fn *gettable_domparam_params; - OSSL_OP_keymgmt_validate_domparams_fn *validatedomparams; - - /* Key routines */ - OSSL_OP_keymgmt_importkey_fn *importkey; - OSSL_OP_keymgmt_genkey_fn *genkey; - OSSL_OP_keymgmt_loadkey_fn *loadkey; - OSSL_OP_keymgmt_freekey_fn *freekey; - OSSL_OP_keymgmt_exportkey_fn *exportkey; - OSSL_OP_keymgmt_importkey_types_fn *importkey_types; - OSSL_OP_keymgmt_exportkey_types_fn *exportkey_types; - OSSL_OP_keymgmt_get_key_params_fn *get_key_params; - OSSL_OP_keymgmt_gettable_key_params_fn *gettable_key_params; + /* Constructor(s), destructor, information */ + OSSL_OP_keymgmt_new_fn *new; + OSSL_OP_keymgmt_free_fn *free; + OSSL_OP_keymgmt_get_params_fn *get_params; + OSSL_OP_keymgmt_gettable_params_fn *gettable_params; + /* Key object checking */ OSSL_OP_keymgmt_query_operation_name_fn *query_operation_name; - OSSL_OP_keymgmt_validate_public_fn *validatepublic; - OSSL_OP_keymgmt_validate_private_fn *validateprivate; - OSSL_OP_keymgmt_validate_pairwise_fn *validatepairwise; + OSSL_OP_keymgmt_has_fn *has; + OSSL_OP_keymgmt_validate_fn *validate; + + /* Import and export routines */ + OSSL_OP_keymgmt_import_fn *import; + OSSL_OP_keymgmt_import_types_fn *import_types; + OSSL_OP_keymgmt_export_fn *export; + OSSL_OP_keymgmt_export_types_fn *export_types; } /* EVP_KEYMGMT */ ; -struct keymgmt_data_st { - OPENSSL_CTX *ctx; - const char *properties; -}; - struct evp_keyexch_st { int name_id; OSSL_PROVIDER *prov; @@ -286,5 +271,4 @@ void evp_names_do_all(OSSL_PROVIDER *prov, int number, void *data); int evp_cipher_cache_constants(EVP_CIPHER *cipher); void *evp_pkey_make_provided(EVP_PKEY *pk, OPENSSL_CTX *libctx, - EVP_KEYMGMT **keymgmt, const char *propquery, - int domainparams); + EVP_KEYMGMT **keymgmt, const char *propquery); diff --git a/crypto/evp/exchange.c b/crypto/evp/exchange.c index fa9367905f..14ed4dbe8e 100644 --- a/crypto/evp/exchange.c +++ b/crypto/evp/exchange.c @@ -187,7 +187,7 @@ int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx) /* Ensure that the key is provided. If not, go legacy */ tmp_keymgmt = ctx->keymgmt; provkey = evp_pkey_make_provided(ctx->pkey, ctx->libctx, - &tmp_keymgmt, ctx->propquery, 0); + &tmp_keymgmt, ctx->propquery); if (provkey == NULL) goto legacy; if (!EVP_KEYMGMT_up_ref(tmp_keymgmt)) { @@ -293,7 +293,7 @@ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) return -2; } - provkey = evp_keymgmt_util_export_to_provider(peer, ctx->keymgmt, 0); + provkey = evp_keymgmt_util_export_to_provider(peer, ctx->keymgmt); /* If export failed, legacy may be able to pick it up */ if (provkey == NULL) goto legacy; diff --git a/crypto/evp/keymgmt_lib.c b/crypto/evp/keymgmt_lib.c index a63e5cd6bf..812bdcb560 100644 --- a/crypto/evp/keymgmt_lib.c +++ b/crypto/evp/keymgmt_lib.c @@ -17,25 +17,23 @@ #include "evp_local.h" struct import_data_st { - void *provctx; - void *(*importfn)(const EVP_KEYMGMT *keymgmt, const OSSL_PARAM params[]); + EVP_KEYMGMT *keymgmt; + void *keydata; - /* Result */ - void *provdata; + int selection; }; static int try_import(const OSSL_PARAM params[], void *arg) { struct import_data_st *data = arg; - data->provdata = data->importfn(data->provctx, params); - return data->provdata != NULL; + return evp_keymgmt_import(data->keymgmt, data->keydata, data->selection, + params); } -void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt, - int want_domainparams) +void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt) { - void *provdata = NULL; + void *keydata = NULL; size_t i, j; /* @@ -61,25 +59,28 @@ void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt, for (i = 0; i < OSSL_NELEM(pk->pkeys) && pk->pkeys[i].keymgmt != NULL; i++) { - if (keymgmt == pk->pkeys[i].keymgmt - && want_domainparams == pk->pkeys[i].domainparams) - return pk->pkeys[i].provdata; + if (keymgmt == pk->pkeys[i].keymgmt) + return pk->pkeys[i].keydata; } + if ((keydata = evp_keymgmt_newdata(keymgmt)) == NULL) + return NULL; + if (pk->pkey.ptr != NULL) { /* There is a legacy key, try to export that one to the provider */ - /* If the legacy key doesn't have an export function, give up */ - if (pk->ameth->export_to == NULL) + /* + * If the legacy key doesn't have an export function or the export + * function fails, give up + */ + if (pk->ameth->export_to == NULL + || !pk->ameth->export_to(pk, keydata, keymgmt)) { + evp_keymgmt_freedata(keymgmt, keydata); return NULL; + } - /* Otherwise, simply use it. */ - provdata = pk->ameth->export_to(pk, keymgmt, want_domainparams); - - /* Synchronize the dirty count, but only if we exported successfully */ - if (provdata != NULL) - pk->dirty_cnt_copy = pk->ameth->dirty_cnt(pk); - + /* Synchronize the dirty count */ + pk->dirty_cnt_copy = pk->ameth->dirty_cnt(pk); } else { /* * Here, there is no legacy key, so we look at the already cached @@ -91,42 +92,33 @@ void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt, /* Setup for the export callback */ struct import_data_st import_data; - import_data.importfn = - want_domainparams - ? evp_keymgmt_importdomparams - : evp_keymgmt_importkey; - import_data.provdata = NULL; - - /* - * If the given keymgmt doesn't have an import function, give up - */ - if (import_data.importfn == NULL) - return NULL; + import_data.keydata = keydata; + import_data.keymgmt = keymgmt; + import_data.selection = OSSL_KEYMGMT_SELECT_ALL; for (j = 0; j < i && pk->pkeys[j].keymgmt != NULL; j++) { - int (*exportfn)(const EVP_KEYMGMT *keymgmt, void *provdata, - OSSL_CALLBACK *cb, void *cbarg) = - want_domainparams - ? evp_keymgmt_exportdomparams - : evp_keymgmt_exportkey; - - if (exportfn != NULL) { - import_data.provctx = - ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt)); - - /* - * The export function calls the callback (try_import), which - * does the import for us. - * Even though we got a success return, we double check that - * we actually got something, just in case some implementation - * forgets to check the return value. - - */ - if (exportfn(pk->pkeys[j].keymgmt, pk->pkeys[j].provdata, - &try_import, &import_data) - && (provdata = import_data.provdata) != NULL) - break; - } + EVP_KEYMGMT *exp_keymgmt = pk->pkeys[i].keymgmt; + void *exp_keydata = pk->pkeys[i].keydata; + + /* + * TODO(3.0) consider an evp_keymgmt_export() return value that + * indicates that the method is unsupported. + */ + if (exp_keymgmt->export == NULL) + continue; + + /* + * The export function calls the callback (try_import), which + * does the import for us. If successful, we're done. + */ + if (evp_keymgmt_export(exp_keymgmt, exp_keydata, + OSSL_KEYMGMT_SELECT_ALL, + &try_import, &import_data)) + break; + + /* If there was an error, bail out */ + evp_keymgmt_freedata(keymgmt, keydata); + return NULL; } } @@ -138,9 +130,9 @@ void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt, if (!ossl_assert(i < OSSL_NELEM(pk->pkeys))) return NULL; - evp_keymgmt_util_cache_pkey(pk, i, keymgmt, provdata, want_domainparams); + evp_keymgmt_util_cache_pkey(pk, i, keymgmt, keydata); - return provdata; + return keydata; } void evp_keymgmt_util_clear_pkey_cache(EVP_PKEY *pk) @@ -152,14 +144,11 @@ void evp_keymgmt_util_clear_pkey_cache(EVP_PKEY *pk) i < OSSL_NELEM(pk->pkeys) && pk->pkeys[i].keymgmt != NULL; i++) { EVP_KEYMGMT *keymgmt = pk->pkeys[i].keymgmt; - void *provdata = pk->pkeys[i].provdata; + void *keydata = pk->pkeys[i].keydata; pk->pkeys[i].keymgmt = NULL; - pk->pkeys[i].provdata = NULL; - if (pk->pkeys[i].domainparams) - evp_keymgmt_freedomparams(keymgmt, provdata); - else - evp_keymgmt_freekey(keymgmt, provdata); + pk->pkeys[i].keydata = NULL; + evp_keymgmt_freedata(keymgmt, keydata); EVP_KEYMGMT_free(keymgmt); } @@ -170,23 +159,20 @@ void evp_keymgmt_util_clear_pkey_cache(EVP_PKEY *pk) } void evp_keymgmt_util_cache_pkey(EVP_PKEY *pk, size_t index, - EVP_KEYMGMT *keymgmt, void *provdata, - int domainparams) + EVP_KEYMGMT *keymgmt, void *keydata) { - if (provdata != NULL) { + if (keydata != NULL) { EVP_KEYMGMT_up_ref(keymgmt); + pk->pkeys[index].keydata = keydata; pk->pkeys[index].keymgmt = keymgmt; - pk->pkeys[index].provdata = provdata; - pk->pkeys[index].domainparams = domainparams; /* - * Cache information about the domain parameters or key. Only needed - * for the "original" provider side key. + * Cache information about the key object. Only needed for the + * "original" provider side key. * * This services functions like EVP_PKEY_size, EVP_PKEY_bits, etc */ if (index == 0) { - int ok; int bits = 0; int security_bits = 0; int size = 0; @@ -198,10 +184,7 @@ void evp_keymgmt_util_cache_pkey(EVP_PKEY *pk, size_t index, params[2] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_MAX_SIZE, &size); params[3] = OSSL_PARAM_construct_end(); - ok = domainparams - ? evp_keymgmt_get_domparam_params(keymgmt, provdata, params) - : evp_keymgmt_get_key_params(keymgmt, provdata, params); - if (ok) { + if (evp_keymgmt_get_params(keymgmt, keydata, params)) { pk->cache.size = size; pk->cache.bits = bits; pk->cache.security_bits = security_bits; @@ -211,14 +194,20 @@ void evp_keymgmt_util_cache_pkey(EVP_PKEY *pk, size_t index, } void *evp_keymgmt_util_fromdata(EVP_PKEY *target, EVP_KEYMGMT *keymgmt, - const OSSL_PARAM params[], int domainparams) + int selection, const OSSL_PARAM params[]) { - void *provdata = domainparams - ? evp_keymgmt_importdomparams(keymgmt, params) - : evp_keymgmt_importkey(keymgmt, params); + void *keydata = evp_keymgmt_newdata(keymgmt); - evp_keymgmt_util_clear_pkey_cache(target); - evp_keymgmt_util_cache_pkey(target, 0, keymgmt, provdata, domainparams); + if (keydata != NULL) { + if (!evp_keymgmt_import(keymgmt, keydata, selection, params)) { + evp_keymgmt_freedata(keymgmt, keydata); + return NULL; + } + + + evp_keymgmt_util_clear_pkey_cache(target); + evp_keymgmt_util_cache_pkey(target, 0, keymgmt, keydata); + } - return provdata; + return keydata; } diff --git a/crypto/evp/keymgmt_meth.c b/crypto/evp/keymgmt_meth.c index ca5c9e8050..bb059140d3 100644 --- a/crypto/evp/keymgmt_meth.c +++ b/crypto/evp/keymgmt_meth.c @@ -47,154 +47,71 @@ static void *keymgmt_from_dispatch(int name_id, for (; fns->function_id != 0; fns++) { switch (fns->function_id) { - case OSSL_FUNC_KEYMGMT_IMPORTDOMPARAMS: - if (keymgmt->importdomparams != NULL) - break; - keymgmt->importdomparams = - OSSL_get_OP_keymgmt_importdomparams(fns); + case OSSL_FUNC_KEYMGMT_NEW: + if (keymgmt->new == NULL) + keymgmt->new = OSSL_get_OP_keymgmt_new(fns); break; - case OSSL_FUNC_KEYMGMT_GENDOMPARAMS: - if (keymgmt->gendomparams != NULL) - break; - keymgmt->gendomparams = OSSL_get_OP_keymgmt_gendomparams(fns); + case OSSL_FUNC_KEYMGMT_FREE: + if (keymgmt->free == NULL) + keymgmt->free = OSSL_get_OP_keymgmt_free(fns); break; - case OSSL_FUNC_KEYMGMT_FREEDOMPARAMS: - if (keymgmt->freedomparams != NULL) - break; - keymgmt->freedomparams = OSSL_get_OP_keymgmt_freedomparams(fns); + case OSSL_FUNC_KEYMGMT_GET_PARAMS: + if (keymgmt->get_params == NULL) + keymgmt->get_params = OSSL_get_OP_keymgmt_get_params(fns); break; - case OSSL_FUNC_KEYMGMT_EXPORTDOMPARAMS: - if (keymgmt->exportdomparams != NULL) - break; - keymgmt->exportdomparams = - OSSL_get_OP_keymgmt_exportdomparams(fns); + case OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS: + if (keymgmt->gettable_params == NULL) + keymgmt->gettable_params = + OSSL_get_OP_keymgmt_gettable_params(fns); break; - case OSSL_FUNC_KEYMGMT_IMPORTDOMPARAM_TYPES: - if (keymgmt->importdomparam_types != NULL) - break; - keymgmt->importdomparam_types = - OSSL_get_OP_keymgmt_importdomparam_types(fns); - break; - case OSSL_FUNC_KEYMGMT_EXPORTDOMPARAM_TYPES: - if (keymgmt->exportdomparam_types != NULL) - break; - keymgmt->exportdomparam_types = - OSSL_get_OP_keymgmt_exportdomparam_types(fns); - break; - case OSSL_FUNC_KEYMGMT_GET_DOMPARAM_PARAMS: - if (keymgmt->get_domparam_params == NULL) - keymgmt->get_domparam_params = - OSSL_get_OP_keymgmt_get_domparam_params(fns); - break; - case OSSL_FUNC_KEYMGMT_GETTABLE_DOMPARAM_PARAMS: - if (keymgmt->gettable_domparam_params == NULL) - keymgmt->gettable_domparam_params = - OSSL_get_OP_keymgmt_gettable_domparam_params(fns); - break; - case OSSL_FUNC_KEYMGMT_IMPORTKEY: - if (keymgmt->importkey != NULL) - break; - keymgmt->importkey = OSSL_get_OP_keymgmt_importkey(fns); - break; - case OSSL_FUNC_KEYMGMT_GENKEY: - if (keymgmt->genkey != NULL) - break; - keymgmt->genkey = OSSL_get_OP_keymgmt_genkey(fns); - break; - case OSSL_FUNC_KEYMGMT_LOADKEY: - if (keymgmt->loadkey != NULL) - break; - keymgmt->loadkey = OSSL_get_OP_keymgmt_loadkey(fns); - break; - case OSSL_FUNC_KEYMGMT_FREEKEY: - if (keymgmt->freekey != NULL) - break; - keymgmt->freekey = OSSL_get_OP_keymgmt_freekey(fns); - break; - case OSSL_FUNC_KEYMGMT_EXPORTKEY: - if (keymgmt->exportkey != NULL) - break; - keymgmt->exportkey = OSSL_get_OP_keymgmt_exportkey(fns); - break; - case OSSL_FUNC_KEYMGMT_IMPORTKEY_TYPES: - if (keymgmt->importkey_types != NULL) - break; - keymgmt->importkey_types = - OSSL_get_OP_keymgmt_importkey_types(fns); - break; - case OSSL_FUNC_KEYMGMT_EXPORTKEY_TYPES: - if (keymgmt->exportkey_types != NULL) - break; - keymgmt->exportkey_types = - OSSL_get_OP_keymgmt_exportkey_types(fns); - break; - case OSSL_FUNC_KEYMGMT_GET_KEY_PARAMS: - if (keymgmt->get_key_params == NULL) - keymgmt->get_key_params = - OSSL_get_OP_keymgmt_get_key_params(fns); + case OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME: + if (keymgmt->query_operation_name == NULL) + keymgmt->query_operation_name = + OSSL_get_OP_keymgmt_query_operation_name(fns); break; - case OSSL_FUNC_KEYMGMT_GETTABLE_KEY_PARAMS: - if (keymgmt->gettable_key_params == NULL) - keymgmt->gettable_key_params = - OSSL_get_OP_keymgmt_gettable_key_params(fns); + case OSSL_FUNC_KEYMGMT_HAS: + if (keymgmt->has == NULL) + keymgmt->has = OSSL_get_OP_keymgmt_has(fns); break; - case OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME: - if (keymgmt->query_operation_name != NULL) - break; - keymgmt->query_operation_name = - OSSL_get_OP_keymgmt_query_operation_name(fns); + case OSSL_FUNC_KEYMGMT_VALIDATE: + if (keymgmt->validate == NULL) + keymgmt->validate = OSSL_get_OP_keymgmt_validate(fns); break; - case OSSL_FUNC_KEYMGMT_VALIDATE_DOMPARAMS: - if (keymgmt->validatedomparams != NULL) - break; - keymgmt->validatedomparams = - OSSL_get_OP_keymgmt_validate_domparams(fns); + case OSSL_FUNC_KEYMGMT_IMPORT: + if (keymgmt->import == NULL) + keymgmt->import = OSSL_get_OP_keymgmt_import(fns); break; - case OSSL_FUNC_KEYMGMT_VALIDATE_PUBLIC: - if (keymgmt->validatepublic != NULL) - break; - keymgmt->validatepublic = - OSSL_get_OP_keymgmt_validate_public(fns); + case OSSL_FUNC_KEYMGMT_IMPORT_TYPES: + if (keymgmt->import_types == NULL) + keymgmt->import_types = OSSL_get_OP_keymgmt_import_types(fns); break; - case OSSL_FUNC_KEYMGMT_VALIDATE_PRIVATE: - if (keymgmt->validateprivate != NULL) - break; - keymgmt->validateprivate = - OSSL_get_OP_keymgmt_validate_private(fns); + case OSSL_FUNC_KEYMGMT_EXPORT: + if (keymgmt->export == NULL) + keymgmt->export = OSSL_get_OP_keymgmt_export(fns); break; - case OSSL_FUNC_KEYMGMT_VALIDATE_PAIRWISE: - if (keymgmt->validatepairwise != NULL) - break; - keymgmt->validatepairwise = - OSSL_get_OP_keymgmt_validate_pairwise(fns); + case OSSL_FUNC_KEYMGMT_EXPORT_TYPES: + if (keymgmt->export_types == NULL) + keymgmt->export_types = OSSL_get_OP_keymgmt_export_types(fns); break; } } /* * Try to check that the method is sensible. + * At least one constructor and the destructor are MANDATORY + * The functions 'has' is MANDATORY * It makes no sense being able to free stuff if you can't create it. * It makes no sense providing OSSL_PARAM descriptors for import and * export if you can't import or export. */ - if ((keymgmt->freedomparams != NULL - && (keymgmt->importdomparams == NULL - && keymgmt->gendomparams == NULL)) - || (keymgmt->freekey != NULL - && (keymgmt->importkey == NULL - && keymgmt->genkey == NULL - && keymgmt->loadkey == NULL)) - || (keymgmt->importdomparam_types != NULL - && keymgmt->importdomparams == NULL) - || (keymgmt->exportdomparam_types != NULL - && keymgmt->exportdomparams == NULL) - || (keymgmt->gettable_domparam_params != NULL - && keymgmt->get_domparam_params == NULL) - || (keymgmt->importkey_types != NULL - && keymgmt->importkey == NULL) - || (keymgmt->exportkey_types != NULL - && keymgmt->exportkey == NULL) - || (keymgmt->gettable_key_params != NULL - && keymgmt->get_key_params == NULL)) { + if (keymgmt->free == NULL + || keymgmt->new == NULL + || keymgmt->has == NULL + || (keymgmt->gettable_params != NULL + && keymgmt->get_params == NULL) + || (keymgmt->import_types != NULL + && keymgmt->import == NULL) + || (keymgmt->export_types != NULL + && keymgmt->export == NULL)) { EVP_KEYMGMT_free(keymgmt); EVPerr(0, EVP_R_INVALID_PROVIDER_FUNCTIONS); return NULL; @@ -284,149 +201,84 @@ void EVP_KEYMGMT_names_do_all(const EVP_KEYMGMT *keymgmt, /* * Internal API that interfaces with the method function pointers */ -void *evp_keymgmt_importdomparams(const EVP_KEYMGMT *keymgmt, - const OSSL_PARAM params[]) +void *evp_keymgmt_newdata(const EVP_KEYMGMT *keymgmt) { void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt)); - return keymgmt->importdomparams(provctx, params); -} - -void *evp_keymgmt_gendomparams(const EVP_KEYMGMT *keymgmt, - const OSSL_PARAM params[]) -{ - void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt)); - - return keymgmt->gendomparams(provctx, params); -} - -void evp_keymgmt_freedomparams(const EVP_KEYMGMT *keymgmt, - void *provdomparams) -{ - keymgmt->freedomparams(provdomparams); -} - -int evp_keymgmt_exportdomparams(const EVP_KEYMGMT *keymgmt, - void *provdomparams, - OSSL_CALLBACK *param_cb, void *cbarg) -{ - return keymgmt->exportdomparams(provdomparams, param_cb, cbarg); -} - -const OSSL_PARAM *evp_keymgmt_importdomparam_types(const EVP_KEYMGMT *keymgmt) -{ - return keymgmt->importdomparam_types(); + /* + * TODO(3.0) 'new' is currently mandatory on its own, but when new + * constructors appear, it won't be quite as mandatory, so we have + * a check for future cases. + */ + if (keymgmt->new == NULL) + return NULL; + return keymgmt->new(provctx); } -/* - * TODO(v3.0) investigate if we need this function. 'openssl provider' may - * be a caller... - */ -const OSSL_PARAM *evp_keymgmt_exportdomparam_types(const EVP_KEYMGMT *keymgmt) +void evp_keymgmt_freedata(const EVP_KEYMGMT *keymgmt, void *keydata) { - return keymgmt->exportdomparam_types(); + /* This is mandatory, no need to check for its presence */ + keymgmt->free(keydata); } -int evp_keymgmt_get_domparam_params(const EVP_KEYMGMT *keymgmt, - void *provdomparams, OSSL_PARAM params[]) +int evp_keymgmt_get_params(const EVP_KEYMGMT *keymgmt, void *keydata, + OSSL_PARAM params[]) { - if (keymgmt->get_domparam_params == NULL) + if (keymgmt->get_params == NULL) return 1; - return keymgmt->get_domparam_params(provdomparams, params); + return keymgmt->get_params(keydata, params); } -const OSSL_PARAM * -evp_keymgmt_gettable_domparam_params(const EVP_KEYMGMT *keymgmt) +const OSSL_PARAM *evp_keymgmt_gettable_params(const EVP_KEYMGMT *keymgmt) { - if (keymgmt->gettable_domparam_params == NULL) + if (keymgmt->gettable_params == NULL) return NULL; - return keymgmt->gettable_domparam_params(); -} - - -void *evp_keymgmt_importkey(const EVP_KEYMGMT *keymgmt, - const OSSL_PARAM params[]) -{ - void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt)); - - return keymgmt->importkey(provctx, params); + return keymgmt->gettable_params(); } -void *evp_keymgmt_genkey(const EVP_KEYMGMT *keymgmt, void *domparams, - const OSSL_PARAM params[]) +int evp_keymgmt_has(const EVP_KEYMGMT *keymgmt, void *keydata, int selection) { - void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt)); - - return keymgmt->genkey(provctx, domparams, params); + /* This is mandatory, no need to check for its presence */ + return keymgmt->has(keydata, selection); } -void *evp_keymgmt_loadkey(const EVP_KEYMGMT *keymgmt, - void *id, size_t idlen) +int evp_keymgmt_validate(const EVP_KEYMGMT *keymgmt, void *keydata, + int selection) { - void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt)); - - return keymgmt->loadkey(provctx, id, idlen); -} - -void evp_keymgmt_freekey(const EVP_KEYMGMT *keymgmt, void *provkey) -{ - keymgmt->freekey(provkey); -} - -int evp_keymgmt_exportkey(const EVP_KEYMGMT *keymgmt, void *provkey, - OSSL_CALLBACK *param_cb, void *cbarg) -{ - return keymgmt->exportkey(provkey, param_cb, cbarg); -} - -const OSSL_PARAM *evp_keymgmt_importkey_types(const EVP_KEYMGMT *keymgmt) -{ - return keymgmt->importkey_types(); -} - -/* - * TODO(v3.0) investigate if we need this function. 'openssl provider' may - * be a caller... - */ -const OSSL_PARAM *evp_keymgmt_exportkey_types(const EVP_KEYMGMT *keymgmt) -{ - return keymgmt->exportkey_types(); -} - -int evp_keymgmt_get_key_params(const EVP_KEYMGMT *keymgmt, - void *provkey, OSSL_PARAM params[]) -{ - if (keymgmt->get_key_params == NULL) + /* We assume valid if the implementation doesn't have a function */ + if (keymgmt->validate == NULL) return 1; - return keymgmt->get_key_params(provkey, params); -} - -const OSSL_PARAM *evp_keymgmt_gettable_key_params(const EVP_KEYMGMT *keymgmt) -{ - if (keymgmt->gettable_key_params == NULL) - return NULL; - return keymgmt->gettable_key_params(); + return keymgmt->validate(keydata, selection); } -int evp_keymgmt_validate_domparams(const EVP_KEYMGMT *keymgmt, void *provkey) +int evp_keymgmt_import(const EVP_KEYMGMT *keymgmt, void *keydata, + int selection, const OSSL_PARAM params[]) { - /* if domainparams are not supported - then pass */ - if (keymgmt->validatedomparams == NULL) - return 1; - return keymgmt->validatedomparams(provkey); + if (keymgmt->import == NULL) + return 0; + return keymgmt->import(keydata, selection, params); } -int evp_keymgmt_validate_public(const EVP_KEYMGMT *keymgmt, void *provkey) +const OSSL_PARAM *evp_keymgmt_import_types(const EVP_KEYMGMT *keymgmt, + int selection) { - return keymgmt->validatepublic(provkey); + if (keymgmt->import_types == NULL) + return NULL; + return keymgmt->import_types(selection); } -int evp_keymgmt_validate_private(const EVP_KEYMGMT *keymgmt, void *provkey) +int evp_keymgmt_export(const EVP_KEYMGMT *keymgmt, void *keydata, + int selection, OSSL_CALLBACK *param_cb, void *cbarg) { - return keymgmt->validateprivate(provkey); + if (keymgmt->export == NULL) + return 0; + return keymgmt->export(keydata, selection, param_cb, cbarg); } -int evp_keymgmt_validate_pairwise(const EVP_KEYMGMT *keymgmt, void *provkey) +const OSSL_PARAM *evp_keymgmt_export_types(const EVP_KEYMGMT *keymgmt, + int selection) { - return keymgmt->validatepairwise(provkey); + if (keymgmt->export_types == NULL) + return NULL; + return keymgmt->export_types(selection); } diff --git a/crypto/evp/m_sigver.c b/crypto/evp/m_sigver.c index 05dc46e3b1..1ea5669c02 100644 --- a/crypto/evp/m_sigver.c +++ b/crypto/evp/m_sigver.c @@ -67,7 +67,7 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, /* Ensure that the key is provided. If not, go legacy */ tmp_keymgmt = locpctx->keymgmt; provkey = evp_pkey_make_provided(locpctx->pkey, locpctx->libctx, - &tmp_keymgmt, locpctx->propquery, 0); + &tmp_keymgmt, locpctx->propquery); if (provkey == NULL) goto legacy; if (!EVP_KEYMGMT_up_ref(tmp_keymgmt)) { diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index 2c0ee83048..95dd96e86b 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -760,9 +760,9 @@ int EVP_PKEY_get_default_digest_name(EVP_PKEY *pkey, mdmandatory, sizeof(mdmandatory)); params[2] = OSSL_PARAM_construct_end(); - if (!evp_keymgmt_get_key_params(pkey->pkeys[0].keymgmt, - pkey->pkeys[0].provdata, - params)) + if (!evp_keymgmt_get_params(pkey->pkeys[0].keymgmt, + pkey->pkeys[0].keydata, + params)) return 0; if (mdmandatory[0] != '\0') { OPENSSL_strlcpy(mdname, mdmandatory, mdname_sz); @@ -910,12 +910,11 @@ int EVP_PKEY_size(const EVP_PKEY *pkey) } void *evp_pkey_make_provided(EVP_PKEY *pk, OPENSSL_CTX *libctx, - EVP_KEYMGMT **keymgmt, const char *propquery, - int domainparams) + EVP_KEYMGMT **keymgmt, const char *propquery) { EVP_KEYMGMT *allocated_keymgmt = NULL; EVP_KEYMGMT *tmp_keymgmt = NULL; - void *provdata = NULL; + void *keydata = NULL; if (pk == NULL) return NULL; @@ -935,20 +934,20 @@ void *evp_pkey_make_provided(EVP_PKEY *pk, OPENSSL_CTX *libctx, } if (tmp_keymgmt != NULL) - provdata = - evp_keymgmt_util_export_to_provider(pk, tmp_keymgmt, domainparams); + keydata = + evp_keymgmt_util_export_to_provider(pk, tmp_keymgmt); /* * If nothing was exported, |tmp_keymgmt| might point at a freed * EVP_KEYMGMT, so we clear it to be safe. It shouldn't be useful for * the caller either way in that case. */ - if (provdata == NULL) + if (keydata == NULL) tmp_keymgmt = NULL; if (keymgmt != NULL) *keymgmt = tmp_keymgmt; EVP_KEYMGMT_free(allocated_keymgmt); - return provdata; + return keydata; } diff --git a/crypto/evp/pmeth_check.c b/crypto/evp/pmeth_check.c index 19f200a3ce..1186ad2b12 100644 --- a/crypto/evp/pmeth_check.c +++ b/crypto/evp/pmeth_check.c @@ -29,10 +29,11 @@ int EVP_PKEY_public_check(EVP_PKEY_CTX *ctx) } keymgmt = pkey->pkeys[0].keymgmt; - key = pkey->pkeys[0].provdata; + key = pkey->pkeys[0].keydata; if (key != NULL && keymgmt != NULL) - return evp_keymgmt_validate_public(keymgmt, key); + return evp_keymgmt_validate(keymgmt, key, + OSSL_KEYMGMT_SELECT_PUBLIC_KEY); /* legacy */ /* call customized public key check function first */ @@ -61,10 +62,11 @@ int EVP_PKEY_param_check(EVP_PKEY_CTX *ctx) } keymgmt = pkey->pkeys[0].keymgmt; - key = pkey->pkeys[0].provdata; + key = pkey->pkeys[0].keydata; if (key != NULL && keymgmt != NULL) - return evp_keymgmt_validate_domparams(keymgmt, key); + return evp_keymgmt_validate(keymgmt, key, + OSSL_KEYMGMT_SELECT_ALL_PARAMETERS); /* call customized param check function first */ if (ctx->pmeth->param_check != NULL) @@ -93,10 +95,11 @@ int EVP_PKEY_private_check(EVP_PKEY_CTX *ctx) } keymgmt = pkey->pkeys[0].keymgmt; - key = pkey->pkeys[0].provdata; + key = pkey->pkeys[0].keydata; if (key != NULL && keymgmt != NULL) - return evp_keymgmt_validate_private(keymgmt, key); + return evp_keymgmt_validate(keymgmt, key, + OSSL_KEYMGMT_SELECT_PRIVATE_KEY); /* not supported for legacy keys */ return -2; } @@ -113,10 +116,10 @@ int EVP_PKEY_pairwise_check(EVP_PKEY_CTX *ctx) } keymgmt = pkey->pkeys[0].keymgmt; - key = pkey->pkeys[0].provdata; + key = pkey->pkeys[0].keydata; if (key != NULL && keymgmt != NULL) - return evp_keymgmt_validate_pairwise(keymgmt, key); + return evp_keymgmt_validate(keymgmt, key, OSSL_KEYMGMT_SELECT_KEYPAIR); /* not supported for legacy keys */ return -2; } @@ -133,14 +136,11 @@ int EVP_PKEY_check(EVP_PKEY_CTX *ctx) } keymgmt = pkey->pkeys[0].keymgmt; - key = pkey->pkeys[0].provdata; + key = pkey->pkeys[0].keydata; + + if (key != NULL && keymgmt != NULL) + return evp_keymgmt_validate(keymgmt, key, OSSL_KEYMGMT_SELECT_ALL); - if (key != NULL && keymgmt != NULL) { - return evp_keymgmt_validate_domparams(keymgmt, key) - && evp_keymgmt_validate_public(keymgmt, key) - && evp_keymgmt_validate_private(keymgmt, key) - && evp_keymgmt_validate_pairwise(keymgmt, key); - } /* legacy */ /* call customized check function first */ if (ctx->pmeth->check != NULL) diff --git a/crypto/evp/pmeth_fn.c b/crypto/evp/pmeth_fn.c index 34cde67668..0b5af8e136 100644 --- a/crypto/evp/pmeth_fn.c +++ b/crypto/evp/pmeth_fn.c @@ -44,7 +44,7 @@ static int evp_pkey_asym_cipher_init(EVP_PKEY_CTX *ctx, int operation) /* Ensure that the key is provided. If not, go legacy */ tmp_keymgmt = ctx->keymgmt; provkey = evp_pkey_make_provided(ctx->pkey, ctx->libctx, - &tmp_keymgmt, ctx->propquery, 0); + &tmp_keymgmt, ctx->propquery); if (provkey == NULL) goto legacy; if (!EVP_KEYMGMT_up_ref(tmp_keymgmt)) { diff --git a/crypto/evp/pmeth_gn.c b/crypto/evp/pmeth_gn.c index 904b36e737..4bea1a1b86 100644 --- a/crypto/evp/pmeth_gn.c +++ b/crypto/evp/pmeth_gn.c @@ -208,7 +208,8 @@ int EVP_PKEY_key_fromdata_init(EVP_PKEY_CTX *ctx) int EVP_PKEY_fromdata(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey, OSSL_PARAM params[]) { - void *provdata = NULL; + void *keydata = NULL; + int selection; if (ctx == NULL || (ctx->operation & EVP_PKEY_OP_TYPE_FROMDATA) == 0) { ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); @@ -226,13 +227,16 @@ int EVP_PKEY_fromdata(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey, OSSL_PARAM params[]) return -1; } - provdata = - evp_keymgmt_util_fromdata(*ppkey, ctx->keymgmt, params, - ctx->operation == EVP_PKEY_OP_PARAMFROMDATA); + if (ctx->operation == EVP_PKEY_OP_PARAMFROMDATA) + selection = OSSL_KEYMGMT_SELECT_ALL_PARAMETERS; + else + selection = OSSL_KEYMGMT_SELECT_KEYPAIR; + keydata = evp_keymgmt_util_fromdata(*ppkey, ctx->keymgmt, selection, + params); - if (provdata == NULL) + if (keydata == NULL) return 0; - /* provdata is cached in *ppkey, so we need not bother with it further */ + /* keydata is cached in *ppkey, so we need not bother with it further */ return 1; } @@ -247,7 +251,8 @@ const OSSL_PARAM *EVP_PKEY_param_fromdata_settable(EVP_PKEY_CTX *ctx) { /* We call fromdata_init to get ctx->keymgmt populated */ if (fromdata_init(ctx, EVP_PKEY_OP_UNDEFINED)) - return evp_keymgmt_importdomparam_types(ctx->keymgmt); + return evp_keymgmt_import_types(ctx->keymgmt, + OSSL_KEYMGMT_SELECT_ALL_PARAMETERS); return NULL; } @@ -255,6 +260,7 @@ const OSSL_PARAM *EVP_PKEY_key_fromdata_settable(EVP_PKEY_CTX *ctx) { /* We call fromdata_init to get ctx->keymgmt populated */ if (fromdata_init(ctx, EVP_PKEY_OP_UNDEFINED)) - return evp_keymgmt_importdomparam_types(ctx->keymgmt); + return evp_keymgmt_import_types(ctx->keymgmt, + OSSL_KEYMGMT_SELECT_KEYPAIR); return NULL; } diff --git a/crypto/evp/signature.c b/crypto/evp/signature.c index 7c6828b3b3..ca9d91efc5 100644 --- a/crypto/evp/signature.c +++ b/crypto/evp/signature.c @@ -345,7 +345,7 @@ static int evp_pkey_signature_init(EVP_PKEY_CTX *ctx, int operation) /* Ensure that the key is provided. If not, go legacy */ tmp_keymgmt = ctx->keymgmt; provkey = evp_pkey_make_provided(ctx->pkey, ctx->libctx, - &tmp_keymgmt, ctx->propquery, 0); + &tmp_keymgmt, ctx->propquery); if (provkey == NULL) goto legacy; if (!EVP_KEYMGMT_up_ref(tmp_keymgmt)) { diff --git a/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c index 485ac35a6f..a94cb54b5e 100644 --- a/crypto/rsa/rsa_ameth.c +++ b/crypto/rsa/rsa_ameth.c @@ -1074,40 +1074,42 @@ static size_t rsa_pkey_dirty_cnt(const EVP_PKEY *pkey) DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM) -static void *rsa_pkey_export_to(const EVP_PKEY *pk, EVP_KEYMGMT *keymgmt, - int want_domainparams) +static int rsa_pkey_export_to(const EVP_PKEY *from, void *to_keydata, + EVP_KEYMGMT *to_keymgmt) { - RSA *rsa = pk->pkey.rsa; + RSA *rsa = from->pkey.rsa; OSSL_PARAM_BLD tmpl; const BIGNUM *n = RSA_get0_n(rsa), *e = RSA_get0_e(rsa); const BIGNUM *d = RSA_get0_d(rsa); STACK_OF(BIGNUM_const) *primes = NULL, *exps = NULL, *coeffs = NULL; int numprimes = 0, numexps = 0, numcoeffs = 0; OSSL_PARAM *params = NULL; - void *provkey = NULL; + int rv = 0; - /* - * There are no domain parameters for RSA keys, or rather, they are - * included in the key data itself. - */ - if (want_domainparams) + /* Public parameters must always be present */ + if (n == NULL || e == NULL) goto err; - /* Get all the primes and CRT params */ - if ((primes = sk_BIGNUM_const_new_null()) == NULL - || (exps = sk_BIGNUM_const_new_null()) == NULL - || (coeffs = sk_BIGNUM_const_new_null()) == NULL) - goto err; + ossl_param_bld_init(&tmpl); - if (!rsa_get0_all_params(rsa, primes, exps, coeffs)) + /* |e| and |n| are always present */ + if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_RSA_E, e)) goto err; - - /* Public parameters must always be present */ - if (n == NULL || e == NULL) + if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_RSA_N, n)) goto err; if (d != NULL) { - /* It's a private key, so we should have everything else too */ + int i; + + /* Get all the primes and CRT params */ + if ((primes = sk_BIGNUM_const_new_null()) == NULL + || (exps = sk_BIGNUM_const_new_null()) == NULL + || (coeffs = sk_BIGNUM_const_new_null()) == NULL) + goto err; + + if (!rsa_get0_all_params(rsa, primes, exps, coeffs)) + goto err; + numprimes = sk_BIGNUM_const_num(primes); numexps = sk_BIGNUM_const_num(exps); numcoeffs = sk_BIGNUM_const_num(coeffs); @@ -1120,15 +1122,6 @@ static void *rsa_pkey_export_to(const EVP_PKEY *pk, EVP_KEYMGMT *keymgmt, + numprimes + numexps + numcoeffs <= OSSL_PARAM_BLD_MAX)) goto err; - } - - ossl_param_bld_init(&tmpl); - if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_RSA_N, n) - || !ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_RSA_E, e)) - goto err; - - if (d != NULL) { - int i; if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_RSA_D, d)) goto err; @@ -1162,14 +1155,15 @@ static void *rsa_pkey_export_to(const EVP_PKEY *pk, EVP_KEYMGMT *keymgmt, goto err; /* We export, the provider imports */ - provkey = evp_keymgmt_importkey(keymgmt, params); + rv = evp_keymgmt_import(to_keymgmt, to_keydata, OSSL_KEYMGMT_SELECT_ALL, + params); err: sk_BIGNUM_const_free(primes); sk_BIGNUM_const_free(exps); sk_BIGNUM_const_free(coeffs); ossl_param_bld_free(params); - return provkey; + return rv; } const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[2] = { diff --git a/crypto/serializer/serializer_local.h b/crypto/serializer/serializer_local.h index 9ee0eb8244..7a66472f51 100644 --- a/crypto/serializer/serializer_local.h +++ b/crypto/serializer/serializer_local.h @@ -32,6 +32,8 @@ struct ossl_serializer_ctx_st { OSSL_SERIALIZER *ser; void *serctx; + int selection; + /* * |object| is the libcrypto object to handle. * |do_output| must have intimate knowledge of this object. diff --git a/crypto/serializer/serializer_pkey.c b/crypto/serializer/serializer_pkey.c index d3c3362f66..3b0cc3ac86 100644 --- a/crypto/serializer/serializer_pkey.c +++ b/crypto/serializer/serializer_pkey.c @@ -97,13 +97,6 @@ struct selected_serializer_st { const char *propquery; /* - * When selecting serializers, we need to check the intended use. - * This is governed by the |domainparams| flag in the EVP_PKEY, - * we must just make sure to filter on 'type=domainparams' accordingly. - */ - int want_domainparams; - - /* * Serializers offer two functions, one that handles object data in * the form of a OSSL_PARAM array, and one that directly handles a * provider side object. The latter requires that the serializer @@ -122,36 +115,12 @@ static void select_serializer(const char *name, void *data) { struct selected_serializer_st *d = data; OSSL_SERIALIZER *s = NULL; - OSSL_PROPERTY_LIST *check = - d->want_domainparams - ? ossl_parse_query(d->libctx, "type=domainparams") - : NULL; /* No need to look further if we already have the more desirable option */ if (d->desired != NULL) return; if ((s = OSSL_SERIALIZER_fetch(d->libctx, name, d->propquery)) != NULL) { - /* - * Extra check if domain parameters are explicitly specified: - * only accept serializers that have the "type=domainparams" - * property. - * - * For data that isn't marked as domain parameters, a domain - * parameters serializer is still acceptable, because a key - * may hold domain parameters too. - */ - if (d->want_domainparams) { - OSSL_PROPERTY_LIST *current_props = - ossl_parse_property(d->libctx, OSSL_SERIALIZER_properties(s)); - int check_cnt = ossl_property_match_count(check, current_props); - - if (check_cnt == 0) { - OSSL_SERIALIZER_free(s); - return; - } - } - if (d->first == NULL && s->serialize_data != NULL) { d->first = s; } else if (OSSL_SERIALIZER_provider(s) == d->desired_provider @@ -298,8 +267,7 @@ static int serializer_write_cb(const OSSL_PARAM params[], void *arg) static int serializer_EVP_PKEY_to_bio(OSSL_SERIALIZER_CTX *ctx, BIO *out) { const EVP_PKEY *pkey = ctx->object; - void *provdata = pkey->pkeys[0].provdata; - int domainparams = pkey->pkeys[0].domainparams; + void *keydata = pkey->pkeys[0].keydata; EVP_KEYMGMT *keymgmt = pkey->pkeys[0].keymgmt; /* @@ -319,15 +287,11 @@ static int serializer_EVP_PKEY_to_bio(OSSL_SERIALIZER_CTX *ctx, BIO *out) write_data.ctx = ctx; write_data.out = out; - if (domainparams) - return evp_keymgmt_exportdomparams(keymgmt, provdata, - serializer_write_cb, - &write_data); - return evp_keymgmt_exportkey(keymgmt, provdata, - serializer_write_cb, &write_data); + return evp_keymgmt_export(keymgmt, keydata, ctx->selection, + &serializer_write_cb, &write_data); } - return ctx->ser->serialize_object(ctx->serctx, provdata, out, + return ctx->ser->serialize_object(ctx->serctx, keydata, out, serializer_passphrase_out_cb, ctx); } @@ -343,6 +307,7 @@ OSSL_SERIALIZER_CTX *OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey, OSSL_SERIALIZER_CTX *ctx = NULL; OSSL_SERIALIZER *ser = NULL; EVP_KEYMGMT *keymgmt = pkey->pkeys[0].keymgmt; + int selection = OSSL_KEYMGMT_SELECT_ALL; if (!ossl_assert(pkey != NULL && propquery != NULL)) { ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER); @@ -353,12 +318,14 @@ OSSL_SERIALIZER_CTX *OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey, const OSSL_PROVIDER *desired_prov = EVP_KEYMGMT_provider(keymgmt); OPENSSL_CTX *libctx = ossl_provider_library_context(desired_prov); struct selected_serializer_st sel_data; + OSSL_PROPERTY_LIST *check = + ossl_parse_query(libctx, "type=parameters"); + OSSL_PROPERTY_LIST *current_props = NULL; memset(&sel_data, 0, sizeof(sel_data)); sel_data.libctx = libctx; sel_data.desired_provider = desired_prov; sel_data.propquery = propquery; - sel_data.want_domainparams = pkey->pkeys[0].domainparams; EVP_KEYMGMT_names_do_all(keymgmt, select_serializer, &sel_data); if (sel_data.desired != NULL) { @@ -370,6 +337,14 @@ OSSL_SERIALIZER_CTX *OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey, } OSSL_SERIALIZER_free(sel_data.first); OSSL_SERIALIZER_free(sel_data.desired); + + current_props = + ossl_parse_property(libctx, OSSL_SERIALIZER_properties(ser)); + if (ossl_property_match_count(check, current_props) > 0) + selection = OSSL_KEYMGMT_SELECT_ALL_PARAMETERS; + + ossl_property_free(current_props); + ossl_property_free(check); } ctx = OSSL_SERIALIZER_CTX_new(ser); /* refcnt(ser)++ */ @@ -377,6 +352,7 @@ OSSL_SERIALIZER_CTX *OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey, if (ctx != NULL) { /* Setup for OSSL_SERIALIZE_to_bio() */ + ctx->selection = selection; ctx->object = pkey; ctx->do_output = serializer_EVP_PKEY_to_bio; } |