EVP_SKEY_is_a() allows to check if a key is of a specific type.
EVP_SKEY_to_provider() provides an easy way to move a key to a
different provider.
Signed-off-by: Simo Sorce <simo@redhat.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
(Merged from https://github.com/openssl/openssl/pull/26753)
return ossl_provider_name(skey->skeymgmt->prov);
}
+
+int EVP_SKEY_is_a(const EVP_SKEY *skey, const char *name)
+{
+ if (skey == NULL)
+ return 0;
+
+ if (skey->skeymgmt == NULL)
+ return 0;
+
+ return EVP_SKEYMGMT_is_a(skey->skeymgmt, name);
+}
+
+struct transfer_cb_ctx {
+ int selection;
+ EVP_SKEYMGMT *skeymgmt;
+ void *keydata;
+};
+
+static int transfer_cb(const OSSL_PARAM params[], void *arg)
+{
+ struct transfer_cb_ctx *ctx = arg;
+
+ ctx->keydata = evp_skeymgmt_import(ctx->skeymgmt, ctx->selection, params);
+ return 1;
+}
+
+EVP_SKEY *EVP_SKEY_to_provider(EVP_SKEY *skey, OSSL_LIB_CTX *libctx,
+ OSSL_PROVIDER *prov, const char *propquery)
+{
+ struct transfer_cb_ctx ctx = { 0 };
+ EVP_SKEYMGMT *skeymgmt = NULL;
+ EVP_SKEY *ret = NULL;
+
+ if (prov != NULL) {
+ skeymgmt = evp_skeymgmt_fetch_from_prov(prov, skey->skeymgmt->type_name,
+ propquery);
+
+ } else {
+ /* If no provider, get the default skeymgmt */
+ skeymgmt = EVP_SKEYMGMT_fetch(libctx, skey->skeymgmt->type_name,
+ propquery);
+ }
+
+ /* Short-circuit if destination provider is the same as origin */
+ if (skey->skeymgmt->name_id == skeymgmt->name_id
+ && skey->skeymgmt->prov == skeymgmt->prov) {
+ if (!EVP_SKEY_up_ref(skey))
+ goto err;
+ EVP_SKEYMGMT_free(skeymgmt);
+ return skey;
+ }
+
+ ctx.selection = OSSL_SKEYMGMT_SELECT_ALL;
+ ctx.skeymgmt = skeymgmt;
+
+ if (!EVP_SKEY_export(skey, ctx.selection, transfer_cb, &ctx))
+ goto err;
+
+ if (ctx.keydata == NULL)
+ goto err;
+
+ ret = evp_skey_alloc();
+ if (ret == NULL)
+ goto err;
+
+ ret->keydata = ctx.keydata;
+ ret->skeymgmt = skeymgmt;
+
+ return ret;
+
+ err:
+ EVP_SKEYMGMT_free(skeymgmt);
+ EVP_SKEY_free(ret);
+ return NULL;
+}
EVP_SKEY_import, EVP_SKEY_import_raw_key, EVP_SKEY_up_ref,
EVP_SKEY_export, EVP_SKEY_get_raw_key, EVP_SKEY_get0_key_id,
EVP_SKEY_get0_skeymgmt_name, EVP_SKEY_get0_provider_name,
-EVP_SKEY_free
+EVP_SKEY_free, EVP_SKEY_is_a, EVP_SKEY_to_provider
- opaque symmetric key allocation and handling functions
=head1 SYNOPSIS
int EVP_SKEY_up_ref(EVP_SKEY *key);
void EVP_SKEY_free(EVP_SKEY *key);
+ int EVP_SKEY_is_a(const EVP_SKEY *skey, const char *name);
+ EVP_SKEY *EVP_SKEY_to_provider(EVP_SKEY *skey, OSSL_LIB_CTX *libctx,
+ OSSL_PROVIDER *prov, const char *propquery);
+
=head1 DESCRIPTION
EVP_SKEY_free() decrements the reference count of I<key> and, if the reference
count is zero, frees it. If I<key> is NULL, nothing is done.
+EVP_SKEY_is_a() checks if the key type of I<skey> is I<name>.
+
+EVP_SKEY_to_provider() simplifies the task of importing a I<skey> into a
+different provider identified by I<prov>. If I<prov> is NULL, the default
+provider for the key type identified via I<skey> is used.
+
=head2 Selections
The following constants can be used for I<selection>:
The B<EVP_SKEY> structure is used by various OpenSSL functions which require a
general symmetric key without reference to any particular algorithm.
+The EVP_SKEY_to_provider() function will fail and return NULL if the origin
+key I<skey> cannot be exported from its provider.
+
=head1 RETURN VALUES
EVP_SKEY_generate(), EVP_SKEY_import() and EVP_SKEY_import_raw_key() return
EVP_SKEY_get0_skeymgmt_name() and EVP_SKEY_get0_provider_name() return the
names of the associated EVP_SKEYMGMT object and its provider correspondigly.
+EVP_SKEY_is_a() returns 1 if I<skey> has the key type I<name>,
+otherwise 0.
+
+EVP_SKEY_to_provider() returns a new B<EVP_SKEY> suitable for operations with
+the I<prov> provider or NULL in case of failure.
+
=head1 SEE ALSO
L<EVP_SKEYMGMT(3)>, L<provider(7)>, L<OSSL_PARAM(3)>
The B<EVP_SKEY> API and functions EVP_SKEY_export(),
EVP_SKEY_free(), EVP_SKEY_get_raw_key(), EVP_SKEY_import(),
EVP_SKEY_import_raw_key(), EVP_SKEY_up_ref(), EVP_SKEY_generate(),
-EVP_SKEY_get0_key_id(), EVP_SKEY_get0_provider_name(), and
-EVP_SKEY_get0_skeymgmt_name()
+EVP_SKEY_get0_key_id(), EVP_SKEY_get0_provider_name(),
+EVP_SKEY_get0_skeymgmt_name(), EVP_SKEY_is_a(), EVP_SKEY_to_provider()
were introduced in OpenSSL 3.5.
=head1 COPYRIGHT
const char *EVP_PKEY_CTX_get0_propq(const EVP_PKEY_CTX *ctx);
const OSSL_PROVIDER *EVP_PKEY_CTX_get0_provider(const EVP_PKEY_CTX *ctx);
+int EVP_SKEY_is_a(const EVP_SKEY *skey, const char *name);
EVP_SKEY *EVP_SKEY_import(OSSL_LIB_CTX *libctx, const char *skeymgmtname, const char *propquery,
int selection, const OSSL_PARAM *params);
EVP_SKEY *EVP_SKEY_generate(OSSL_LIB_CTX *libctx, const char *skeymgmtname,
void EVP_SKEY_free(EVP_SKEY *skey);
const char *EVP_SKEY_get0_skeymgmt_name(const EVP_SKEY *skey);
const char *EVP_SKEY_get0_provider_name(const EVP_SKEY *skey);
+EVP_SKEY *EVP_SKEY_to_provider(EVP_SKEY *skey, OSSL_LIB_CTX *libctx,
+ OSSL_PROVIDER *prov, const char *propquery);
# ifdef __cplusplus
}
EVP_SKEY_get0_provider_name ? 3_5_0 EXIST::FUNCTION:
EVP_SKEYMGMT_get0_gen_settable_params ? 3_5_0 EXIST::FUNCTION:
EVP_SKEYMGMT_get0_imp_settable_params ? 3_5_0 EXIST::FUNCTION:
+EVP_SKEY_is_a ? 3_5_0 EXIST::FUNCTION:
+EVP_SKEY_to_provider ? 3_5_0 EXIST::FUNCTION:
OSSL_PROVIDER_add_conf_parameter ? 3_5_0 EXIST::FUNCTION:
OSSL_PROVIDER_get_conf_parameters ? 3_5_0 EXIST::FUNCTION:
OSSL_PROVIDER_conf_get_bool ? 3_5_0 EXIST::FUNCTION: