Skip to content

Commit 90f915b

Browse files
committed
Add additional EVP_SKEY helpers
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 <[email protected]>
1 parent 2cf8274 commit 90f915b

File tree

5 files changed

+119
-6
lines changed

5 files changed

+119
-6
lines changed

crypto/evp/kdf_lib.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,11 +178,24 @@ int EVP_KDF_CTX_set_SKEY(EVP_KDF_CTX *ctx, EVP_SKEY *key, const char *paramname)
178178
ckey.name = (paramname != NULL) ? paramname : OSSL_KDF_PARAM_KEY;
179179

180180
if (ctx->meth->set_skey != NULL) {
181+
EVP_SKEY *tmp_key = NULL;
182+
int ret;
183+
const char *pname = (paramname != NULL) ? paramname : OSSL_KDF_PARAM_KEY;
184+
185+
/* Transfer key to meth provider if different from key's */
181186
if (ctx->meth->prov != key->skeymgmt->prov) {
182-
/* TODO: export/import dance */
183-
return 0;
187+
/* FIXME: no libctx, no propquery */
188+
tmp_key = EVP_SKEY_to_provider(key, NULL, ctx->meth->prov, NULL);
189+
if (tmp_key == NULL)
190+
return 0;
191+
} else {
192+
tmp_key = key;
184193
}
185-
return ctx->meth->set_skey(ctx->algctx, key->keydata, ckey.name);
194+
ret = ctx->meth->set_skey(ctx->algctx, key->keydata, ckey.name);
195+
if (tmp_key != key)
196+
EVP_SKEY_free(tmp_key);
197+
198+
return ret;
186199
} else {
187200
/*
188201
* Provider does not support opaque keys, try to export and

crypto/evp/s_lib.c

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,3 +233,79 @@ const char *EVP_SKEY_get0_provider_name(const EVP_SKEY *skey)
233233

234234
return ossl_provider_name(skey->skeymgmt->prov);
235235
}
236+
237+
int EVP_SKEY_is_a(const EVP_SKEY *skey, const char *name)
238+
{
239+
if (skey == NULL)
240+
return 0;
241+
242+
if (skey->skeymgmt == NULL)
243+
return 0;
244+
245+
return EVP_SKEYMGMT_is_a(skey->skeymgmt, name);
246+
}
247+
248+
struct transfer_cb_ctx {
249+
int selection;
250+
EVP_SKEYMGMT *skeymgmt;
251+
void *keydata;
252+
};
253+
254+
static int transfer_cb(const OSSL_PARAM params[], void *arg)
255+
{
256+
struct transfer_cb_ctx *ctx = arg;
257+
258+
ctx->keydata = evp_skeymgmt_import(ctx->skeymgmt, ctx->selection, params);
259+
return 1;
260+
}
261+
262+
EVP_SKEY *EVP_SKEY_to_provider(EVP_SKEY *skey, OSSL_LIB_CTX *libctx,
263+
OSSL_PROVIDER *prov, const char *propquery)
264+
{
265+
struct transfer_cb_ctx ctx = { 0 };
266+
EVP_SKEYMGMT *skeymgmt = NULL;
267+
EVP_SKEY *ret = NULL;
268+
269+
if (prov) {
270+
skeymgmt = evp_skeymgmt_fetch_from_prov(prov,
271+
skey->skeymgmt->type_name,
272+
propquery);
273+
274+
} else {
275+
/* If no provider, get the default skeymgmt */
276+
skeymgmt = EVP_SKEYMGMT_fetch(libctx, skey->skeymgmt->type_name,
277+
propquery);
278+
}
279+
280+
/* Short-circuit if destination provider is the same as origin */
281+
if (skey->skeymgmt->name_id == skeymgmt->name_id
282+
&& skey->skeymgmt->prov == skeymgmt->prov) {
283+
if (!EVP_SKEY_up_ref(skey))
284+
goto err;
285+
EVP_SKEYMGMT_free(skeymgmt);
286+
return skey;
287+
}
288+
289+
ctx.selection = OSSL_SKEYMGMT_SELECT_ALL;
290+
ctx.skeymgmt = skeymgmt;
291+
292+
if (!EVP_SKEY_export(skey, ctx.selection, transfer_cb, &ctx))
293+
goto err;
294+
295+
if (ctx.keydata == NULL)
296+
goto err;
297+
298+
ret = evp_skey_int();
299+
if (ret == NULL)
300+
goto err;
301+
302+
ret->keydata = ctx.keydata;
303+
ret->skeymgmt = skeymgmt;
304+
305+
return ret;
306+
307+
err:
308+
EVP_SKEYMGMT_free(skeymgmt);
309+
EVP_SKEY_free(ret);
310+
return NULL;
311+
}

doc/man3/EVP_SKEY.pod

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ EVP_SKEY, EVP_SKEY_generate,
66
EVP_SKEY_import, EVP_SKEY_import_raw_key, EVP_SKEY_up_ref,
77
EVP_SKEY_export, EVP_SKEY_get_raw_key, EVP_SKEY_get0_key_id,
88
EVP_SKEY_get0_skeymgmt_name, EVP_SKEY_get0_provider_name,
9-
EVP_SKEY_free
9+
EVP_SKEY_free, EVP_SKEY_is_a, EVP_SKEY_to_provider
1010
- opaque symmetric key allocation and handling functions
1111

1212
=head1 SYNOPSIS
@@ -34,6 +34,10 @@ EVP_SKEY_free
3434

3535
int EVP_SKEY_up_ref(EVP_SKEY *key);
3636
void EVP_SKEY_free(EVP_SKEY *key);
37+
int EVP_SKEY_is_a(const EVP_SKEY *skey, const char *name);
38+
EVP_SKEY *EVP_SKEY_to_provider(EVP_SKEY *skey, OSSL_LIB_CTX *libctx,
39+
OSSL_PROVIDER *prov, const char *propquery);
40+
3741

3842
=head1 DESCRIPTION
3943

@@ -80,6 +84,12 @@ EVP_SKEY_up_ref() increments the reference count of I<key>.
8084
EVP_SKEY_free() decrements the reference count of I<key> and, if the reference
8185
count is zero, frees it. If I<key> is NULL, nothing is done.
8286

87+
EVP_SKEY_is_a() checks if the key type of I<skey> is I<name>.
88+
89+
EVP_SKEY_to_provider() simplifies the task of importing a I<skey> into a
90+
different provider identified by I<prov>. If I<prov> is NULL, the default
91+
provider for the key type identified via I<skey> is used.
92+
8393
=head2 Selections
8494

8595
The following constants can be used for I<selection>:
@@ -106,6 +116,9 @@ All parameters will be selected.
106116
The B<EVP_SKEY> structure is used by various OpenSSL functions which require a
107117
general symmetric key without reference to any particular algorithm.
108118

119+
The EVP_SKEY_to_provider() function will fail and return NULL if the origin
120+
key I<skey> cannot be exported from its provider.
121+
109122
=head1 RETURN VALUES
110123

111124
EVP_SKEY_generate(), EVP_SKEY_import() and EVP_SKEY_import_raw_key() return
@@ -120,6 +133,12 @@ EVP_SKEY_export() and EVP_SKEY_get_raw_key() return 1 for success and 0 on failu
120133
EVP_SKEY_get0_skeymgmt_name() and EVP_SKEY_get0_provider_name() return the
121134
names of the associated EVP_SKEYMGMT object and its provider correspondigly.
122135

136+
EVP_SKEY_is_a() returns 1 if I<skey> has the key type I<name>,
137+
otherwise 0.
138+
139+
EVP_SKEY_to_provider() returns a new B<EVP_SKEY> suitable for operations with
140+
the I<prov> provider or NULL in case of failure.
141+
123142
=head1 SEE ALSO
124143

125144
L<EVP_SKEYMGMT(3)>, L<provider(7)>, L<OSSL_PARAM(3)>
@@ -129,8 +148,8 @@ L<EVP_SKEYMGMT(3)>, L<provider(7)>, L<OSSL_PARAM(3)>
129148
The B<EVP_SKEY> API and functions EVP_SKEY_export(),
130149
EVP_SKEY_free(), EVP_SKEY_get_raw_key(), EVP_SKEY_import(),
131150
EVP_SKEY_import_raw_key(), EVP_SKEY_up_ref(), EVP_SKEY_generate(),
132-
EVP_SKEY_get0_key_id(), EVP_SKEY_get0_provider_name(), and
133-
EVP_SKEY_get0_skeymgmt_name()
151+
EVP_SKEY_get0_key_id(), EVP_SKEY_get0_provider_name(),
152+
EVP_SKEY_get0_skeymgmt_name(), EVP_SKEY_is_a(), EVP_SKEY_to_provider()
134153
were introduced in OpenSSL 3.5.
135154

136155
=head1 COPYRIGHT

include/openssl/evp.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2270,6 +2270,7 @@ OSSL_LIB_CTX *EVP_PKEY_CTX_get0_libctx(EVP_PKEY_CTX *ctx);
22702270
const char *EVP_PKEY_CTX_get0_propq(const EVP_PKEY_CTX *ctx);
22712271
const OSSL_PROVIDER *EVP_PKEY_CTX_get0_provider(const EVP_PKEY_CTX *ctx);
22722272

2273+
int EVP_SKEY_is_a(const EVP_SKEY *skey, const char *name);
22732274
EVP_SKEY *EVP_SKEY_import(OSSL_LIB_CTX *libctx, const char *skeymgmtname, const char *propquery,
22742275
int selection, const OSSL_PARAM *params);
22752276
EVP_SKEY *EVP_SKEY_generate(OSSL_LIB_CTX *libctx, const char *skeymgmtname,
@@ -2286,6 +2287,8 @@ int EVP_SKEY_up_ref(EVP_SKEY *skey);
22862287
void EVP_SKEY_free(EVP_SKEY *skey);
22872288
const char *EVP_SKEY_get0_skeymgmt_name(const EVP_SKEY *skey);
22882289
const char *EVP_SKEY_get0_provider_name(const EVP_SKEY *skey);
2290+
EVP_SKEY *EVP_SKEY_to_provider(EVP_SKEY *skey, OSSL_LIB_CTX *libctx,
2291+
OSSL_PROVIDER *prov, const char *propquery);
22892292

22902293
# ifdef __cplusplus
22912294
}

util/libcrypto.num

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5902,3 +5902,5 @@ EVP_SKEY_get0_provider_name ? 3_5_0 EXIST::FUNCTION:
59025902
EVP_SKEYMGMT_get0_gen_settable_params ? 3_5_0 EXIST::FUNCTION:
59035903
EVP_SKEYMGMT_get0_imp_settable_params ? 3_5_0 EXIST::FUNCTION:
59045904
EVP_KDF_CTX_set_SKEY ? 3_5_0 EXIST::FUNCTION:
5905+
EVP_SKEY_is_a ? 3_5_0 EXIST::FUNCTION:
5906+
EVP_SKEY_to_provider ? 3_5_0 EXIST::FUNCTION:

0 commit comments

Comments
 (0)