]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/evp/keymgmt_meth.c
Rename <openssl/core_numbers.h> -> <openssl/core_dispatch.h>
[thirdparty/openssl.git] / crypto / evp / keymgmt_meth.c
CommitLineData
a94a3e0d 1/*
33388b44 2 * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
a94a3e0d
RL
3 *
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include <openssl/crypto.h>
23c48d94 11#include <openssl/core_dispatch.h>
a94a3e0d
RL
12#include <openssl/evp.h>
13#include <openssl/err.h>
14#include "internal/provider.h"
15#include "internal/refcount.h"
25f2138b 16#include "crypto/evp.h"
706457b7 17#include "evp_local.h"
a94a3e0d
RL
18
19
20static void *keymgmt_new(void)
21{
22 EVP_KEYMGMT *keymgmt = NULL;
23
24 if ((keymgmt = OPENSSL_zalloc(sizeof(*keymgmt))) == NULL
25 || (keymgmt->lock = CRYPTO_THREAD_lock_new()) == NULL) {
26 EVP_KEYMGMT_free(keymgmt);
6b9e3724 27 EVPerr(0, ERR_R_MALLOC_FAILURE);
a94a3e0d
RL
28 return NULL;
29 }
30
31 keymgmt->refcnt = 1;
32
33 return keymgmt;
34}
35
f7c16d48
RL
36static void *keymgmt_from_dispatch(int name_id,
37 const OSSL_DISPATCH *fns,
0ddf74bf 38 OSSL_PROVIDER *prov)
a94a3e0d
RL
39{
40 EVP_KEYMGMT *keymgmt = NULL;
2b9add69 41 int setparamfncnt = 0, getparamfncnt = 0;
5e77b79a 42 int setgenparamfncnt = 0;
1a5632e0 43 int importfncnt = 0, exportfncnt = 0;
a94a3e0d 44
f7c16d48 45 if ((keymgmt = keymgmt_new()) == NULL) {
6b9e3724 46 EVP_KEYMGMT_free(keymgmt);
a94a3e0d 47 return NULL;
6b9e3724 48 }
f7c16d48 49 keymgmt->name_id = name_id;
a94a3e0d
RL
50
51 for (; fns->function_id != 0; fns++) {
52 switch (fns->function_id) {
b305452f
RL
53 case OSSL_FUNC_KEYMGMT_NEW:
54 if (keymgmt->new == NULL)
55 keymgmt->new = OSSL_get_OP_keymgmt_new(fns);
a94a3e0d 56 break;
1a5632e0
RL
57 case OSSL_FUNC_KEYMGMT_GEN_INIT:
58 if (keymgmt->gen_init == NULL)
59 keymgmt->gen_init = OSSL_get_OP_keymgmt_gen_init(fns);
60 break;
61 case OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE:
62 if (keymgmt->gen_set_template == NULL)
63 keymgmt->gen_set_template =
64 OSSL_get_OP_keymgmt_gen_set_template(fns);
65 break;
66 case OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS:
67 if (keymgmt->gen_set_params == NULL) {
68 setgenparamfncnt++;
69 keymgmt->gen_set_params =
70 OSSL_get_OP_keymgmt_gen_set_params(fns);
71 }
72 break;
73 case OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS:
74 if (keymgmt->gen_settable_params == NULL) {
75 setgenparamfncnt++;
76 keymgmt->gen_settable_params =
77 OSSL_get_OP_keymgmt_gen_settable_params(fns);
78 }
79 break;
80 case OSSL_FUNC_KEYMGMT_GEN:
81 if (keymgmt->gen == NULL)
82 keymgmt->gen = OSSL_get_OP_keymgmt_gen(fns);
83 break;
84 case OSSL_FUNC_KEYMGMT_GEN_CLEANUP:
85 if (keymgmt->gen_cleanup == NULL)
86 keymgmt->gen_cleanup = OSSL_get_OP_keymgmt_gen_cleanup(fns);
87 break;
b305452f
RL
88 case OSSL_FUNC_KEYMGMT_FREE:
89 if (keymgmt->free == NULL)
90 keymgmt->free = OSSL_get_OP_keymgmt_free(fns);
a94a3e0d 91 break;
b305452f 92 case OSSL_FUNC_KEYMGMT_GET_PARAMS:
273a67e3 93 if (keymgmt->get_params == NULL) {
4fe54d67 94 getparamfncnt++;
b305452f 95 keymgmt->get_params = OSSL_get_OP_keymgmt_get_params(fns);
273a67e3 96 }
a94a3e0d 97 break;
b305452f 98 case OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS:
273a67e3 99 if (keymgmt->gettable_params == NULL) {
4fe54d67 100 getparamfncnt++;
b305452f
RL
101 keymgmt->gettable_params =
102 OSSL_get_OP_keymgmt_gettable_params(fns);
273a67e3 103 }
a94a3e0d 104 break;
4fe54d67
NT
105 case OSSL_FUNC_KEYMGMT_SET_PARAMS:
106 if (keymgmt->set_params == NULL) {
107 setparamfncnt++;
108 keymgmt->set_params = OSSL_get_OP_keymgmt_set_params(fns);
109 }
110 break;
111 case OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS:
112 if (keymgmt->settable_params == NULL) {
113 setparamfncnt++;
114 keymgmt->settable_params =
115 OSSL_get_OP_keymgmt_settable_params(fns);
116 }
117 break;
b305452f
RL
118 case OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME:
119 if (keymgmt->query_operation_name == NULL)
120 keymgmt->query_operation_name =
121 OSSL_get_OP_keymgmt_query_operation_name(fns);
6508e858 122 break;
b305452f
RL
123 case OSSL_FUNC_KEYMGMT_HAS:
124 if (keymgmt->has == NULL)
125 keymgmt->has = OSSL_get_OP_keymgmt_has(fns);
6508e858 126 break;
6136ecaa
MC
127 case OSSL_FUNC_KEYMGMT_COPY:
128 if (keymgmt->copy == NULL)
129 keymgmt->copy = OSSL_get_OP_keymgmt_copy(fns);
130 break;
b305452f
RL
131 case OSSL_FUNC_KEYMGMT_VALIDATE:
132 if (keymgmt->validate == NULL)
133 keymgmt->validate = OSSL_get_OP_keymgmt_validate(fns);
e62a45b6 134 break;
bee5d6cd
RL
135 case OSSL_FUNC_KEYMGMT_MATCH:
136 if (keymgmt->match == NULL)
137 keymgmt->match = OSSL_get_OP_keymgmt_match(fns);
138 break;
b305452f 139 case OSSL_FUNC_KEYMGMT_IMPORT:
273a67e3
RL
140 if (keymgmt->import == NULL) {
141 importfncnt++;
b305452f 142 keymgmt->import = OSSL_get_OP_keymgmt_import(fns);
273a67e3 143 }
12603de6 144 break;
b305452f 145 case OSSL_FUNC_KEYMGMT_IMPORT_TYPES:
273a67e3
RL
146 if (keymgmt->import_types == NULL) {
147 importfncnt++;
b305452f 148 keymgmt->import_types = OSSL_get_OP_keymgmt_import_types(fns);
273a67e3 149 }
12603de6 150 break;
b305452f 151 case OSSL_FUNC_KEYMGMT_EXPORT:
273a67e3
RL
152 if (keymgmt->export == NULL) {
153 exportfncnt++;
b305452f 154 keymgmt->export = OSSL_get_OP_keymgmt_export(fns);
273a67e3 155 }
12603de6 156 break;
b305452f 157 case OSSL_FUNC_KEYMGMT_EXPORT_TYPES:
273a67e3
RL
158 if (keymgmt->export_types == NULL) {
159 exportfncnt++;
b305452f 160 keymgmt->export_types = OSSL_get_OP_keymgmt_export_types(fns);
273a67e3 161 }
12603de6 162 break;
a94a3e0d
RL
163 }
164 }
165 /*
166 * Try to check that the method is sensible.
b305452f
RL
167 * At least one constructor and the destructor are MANDATORY
168 * The functions 'has' is MANDATORY
a94a3e0d
RL
169 * It makes no sense being able to free stuff if you can't create it.
170 * It makes no sense providing OSSL_PARAM descriptors for import and
171 * export if you can't import or export.
172 */
b305452f 173 if (keymgmt->free == NULL
1a5632e0 174 || (keymgmt->new == NULL && keymgmt->gen == NULL)
b305452f 175 || keymgmt->has == NULL
4fe54d67
NT
176 || (getparamfncnt != 0 && getparamfncnt != 2)
177 || (setparamfncnt != 0 && setparamfncnt != 2)
1a5632e0 178 || (setgenparamfncnt != 0 && setgenparamfncnt != 2)
273a67e3 179 || (importfncnt != 0 && importfncnt != 2)
1a5632e0
RL
180 || (exportfncnt != 0 && exportfncnt != 2)
181 || (keymgmt->gen != NULL
182 && (keymgmt->gen_init == NULL
183 || keymgmt->gen_cleanup == NULL))) {
a94a3e0d
RL
184 EVP_KEYMGMT_free(keymgmt);
185 EVPerr(0, EVP_R_INVALID_PROVIDER_FUNCTIONS);
186 return NULL;
187 }
188 keymgmt->prov = prov;
189 if (prov != NULL)
190 ossl_provider_up_ref(prov);
191
192 return keymgmt;
193}
194
f7c16d48
RL
195EVP_KEYMGMT *evp_keymgmt_fetch_by_number(OPENSSL_CTX *ctx, int name_id,
196 const char *properties)
197{
198 return evp_generic_fetch_by_number(ctx,
199 OSSL_OP_KEYMGMT, name_id, properties,
0ddf74bf 200 keymgmt_from_dispatch,
f7c16d48
RL
201 (int (*)(void *))EVP_KEYMGMT_up_ref,
202 (void (*)(void *))EVP_KEYMGMT_free);
203}
204
a94a3e0d
RL
205EVP_KEYMGMT *EVP_KEYMGMT_fetch(OPENSSL_CTX *ctx, const char *algorithm,
206 const char *properties)
207{
f7c16d48 208 return evp_generic_fetch(ctx, OSSL_OP_KEYMGMT, algorithm, properties,
0ddf74bf 209 keymgmt_from_dispatch,
f7c16d48
RL
210 (int (*)(void *))EVP_KEYMGMT_up_ref,
211 (void (*)(void *))EVP_KEYMGMT_free);
a94a3e0d
RL
212}
213
214int EVP_KEYMGMT_up_ref(EVP_KEYMGMT *keymgmt)
215{
216 int ref = 0;
217
218 CRYPTO_UP_REF(&keymgmt->refcnt, &ref, keymgmt->lock);
219 return 1;
220}
221
222void EVP_KEYMGMT_free(EVP_KEYMGMT *keymgmt)
223{
224 int ref = 0;
225
226 if (keymgmt == NULL)
227 return;
228
229 CRYPTO_DOWN_REF(&keymgmt->refcnt, &ref, keymgmt->lock);
230 if (ref > 0)
231 return;
232 ossl_provider_free(keymgmt->prov);
233 CRYPTO_THREAD_lock_free(keymgmt->lock);
234 OPENSSL_free(keymgmt);
235}
236
237const OSSL_PROVIDER *EVP_KEYMGMT_provider(const EVP_KEYMGMT *keymgmt)
238{
239 return keymgmt->prov;
240}
241
506cb0f6
RL
242int EVP_KEYMGMT_number(const EVP_KEYMGMT *keymgmt)
243{
244 return keymgmt->name_id;
245}
246
251e610c
RL
247int EVP_KEYMGMT_is_a(const EVP_KEYMGMT *keymgmt, const char *name)
248{
e4a1d023 249 return evp_is_a(keymgmt->prov, keymgmt->name_id, NULL, name);
251e610c
RL
250}
251
252void EVP_KEYMGMT_do_all_provided(OPENSSL_CTX *libctx,
253 void (*fn)(EVP_KEYMGMT *keymgmt, void *arg),
254 void *arg)
255{
256 evp_generic_do_all(libctx, OSSL_OP_KEYMGMT,
257 (void (*)(void *, void *))fn, arg,
0ddf74bf 258 keymgmt_from_dispatch,
251e610c
RL
259 (void (*)(void *))EVP_KEYMGMT_free);
260}
f651c727
RL
261
262void EVP_KEYMGMT_names_do_all(const EVP_KEYMGMT *keymgmt,
263 void (*fn)(const char *name, void *data),
264 void *data)
265{
266 if (keymgmt->prov != NULL)
267 evp_names_do_all(keymgmt->prov, keymgmt->name_id, fn, data);
268}
68552cde
RL
269
270/*
271 * Internal API that interfaces with the method function pointers
272 */
b305452f 273void *evp_keymgmt_newdata(const EVP_KEYMGMT *keymgmt)
68552cde
RL
274{
275 void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt));
276
b305452f
RL
277 /*
278 * TODO(3.0) 'new' is currently mandatory on its own, but when new
279 * constructors appear, it won't be quite as mandatory, so we have
280 * a check for future cases.
281 */
282 if (keymgmt->new == NULL)
283 return NULL;
284 return keymgmt->new(provctx);
68552cde
RL
285}
286
b305452f 287void evp_keymgmt_freedata(const EVP_KEYMGMT *keymgmt, void *keydata)
68552cde 288{
b305452f
RL
289 /* This is mandatory, no need to check for its presence */
290 keymgmt->free(keydata);
68552cde
RL
291}
292
1a5632e0
RL
293void *evp_keymgmt_gen_init(const EVP_KEYMGMT *keymgmt, int selection)
294{
295 void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt));
296
297 if (keymgmt->gen_init == NULL)
298 return NULL;
299 return keymgmt->gen_init(provctx, selection);
300}
301
302int evp_keymgmt_gen_set_template(const EVP_KEYMGMT *keymgmt, void *genctx,
303 void *template)
304{
d0ddf9b4
RL
305 /*
306 * It's arguable if we actually should return success in this case, as
307 * it allows the caller to set a template key, which is then ignored.
308 * However, this is how the legacy methods (EVP_PKEY_METHOD) operate,
309 * so we do this in the interest of backward compatibility.
310 * TODO(3.0) Investigate if we should change this behaviour.
311 */
1a5632e0 312 if (keymgmt->gen_set_template == NULL)
d0ddf9b4 313 return 1;
1a5632e0
RL
314 return keymgmt->gen_set_template(genctx, template);
315}
316
317int evp_keymgmt_gen_set_params(const EVP_KEYMGMT *keymgmt, void *genctx,
318 const OSSL_PARAM params[])
319{
320 if (keymgmt->gen_set_params == NULL)
321 return 0;
322 return keymgmt->gen_set_params(genctx, params);
323}
324
325const OSSL_PARAM *evp_keymgmt_gen_settable_params(const EVP_KEYMGMT *keymgmt)
326{
327 void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt));
328
329 if (keymgmt->gen_settable_params == NULL)
330 return NULL;
331 return keymgmt->gen_settable_params(provctx);
332}
333
334void *evp_keymgmt_gen(const EVP_KEYMGMT *keymgmt, void *genctx,
335 OSSL_CALLBACK *cb, void *cbarg)
336{
337 if (keymgmt->gen == NULL)
338 return NULL;
339 return keymgmt->gen(genctx, cb, cbarg);
340}
341
342void evp_keymgmt_gen_cleanup(const EVP_KEYMGMT *keymgmt, void *genctx)
343{
344 if (keymgmt->gen != NULL)
345 keymgmt->gen_cleanup(genctx);
346}
347
b305452f
RL
348int evp_keymgmt_get_params(const EVP_KEYMGMT *keymgmt, void *keydata,
349 OSSL_PARAM params[])
68552cde 350{
b305452f 351 if (keymgmt->get_params == NULL)
68552cde 352 return 1;
b305452f 353 return keymgmt->get_params(keydata, params);
68552cde
RL
354}
355
b305452f 356const OSSL_PARAM *evp_keymgmt_gettable_params(const EVP_KEYMGMT *keymgmt)
68552cde 357{
b305452f 358 if (keymgmt->gettable_params == NULL)
68552cde 359 return NULL;
b305452f 360 return keymgmt->gettable_params();
68552cde
RL
361}
362
4fe54d67
NT
363int evp_keymgmt_set_params(const EVP_KEYMGMT *keymgmt, void *keydata,
364 const OSSL_PARAM params[])
365{
366 if (keymgmt->set_params == NULL)
367 return 1;
368 return keymgmt->set_params(keydata, params);
369}
370
371const OSSL_PARAM *evp_keymgmt_settable_params(const EVP_KEYMGMT *keymgmt)
372{
373 if (keymgmt->settable_params == NULL)
374 return NULL;
375 return keymgmt->settable_params();
376}
377
b305452f 378int evp_keymgmt_has(const EVP_KEYMGMT *keymgmt, void *keydata, int selection)
68552cde 379{
b305452f
RL
380 /* This is mandatory, no need to check for its presence */
381 return keymgmt->has(keydata, selection);
68552cde
RL
382}
383
b305452f
RL
384int evp_keymgmt_validate(const EVP_KEYMGMT *keymgmt, void *keydata,
385 int selection)
68552cde 386{
b305452f
RL
387 /* We assume valid if the implementation doesn't have a function */
388 if (keymgmt->validate == NULL)
68552cde 389 return 1;
b305452f 390 return keymgmt->validate(keydata, selection);
68552cde
RL
391}
392
bee5d6cd
RL
393int evp_keymgmt_match(const EVP_KEYMGMT *keymgmt,
394 const void *keydata1, const void *keydata2,
395 int selection)
396{
397 /* We assume no match if the implementation doesn't have a function */
398 if (keymgmt->match == NULL)
399 return 0;
400 return keymgmt->match(keydata1, keydata2, selection);
401}
402
b305452f
RL
403int evp_keymgmt_import(const EVP_KEYMGMT *keymgmt, void *keydata,
404 int selection, const OSSL_PARAM params[])
68552cde 405{
b305452f
RL
406 if (keymgmt->import == NULL)
407 return 0;
408 return keymgmt->import(keydata, selection, params);
68552cde
RL
409}
410
b305452f
RL
411const OSSL_PARAM *evp_keymgmt_import_types(const EVP_KEYMGMT *keymgmt,
412 int selection)
68552cde 413{
b305452f
RL
414 if (keymgmt->import_types == NULL)
415 return NULL;
416 return keymgmt->import_types(selection);
68552cde
RL
417}
418
b305452f
RL
419int evp_keymgmt_export(const EVP_KEYMGMT *keymgmt, void *keydata,
420 int selection, OSSL_CALLBACK *param_cb, void *cbarg)
68552cde 421{
b305452f
RL
422 if (keymgmt->export == NULL)
423 return 0;
424 return keymgmt->export(keydata, selection, param_cb, cbarg);
68552cde
RL
425}
426
b305452f
RL
427const OSSL_PARAM *evp_keymgmt_export_types(const EVP_KEYMGMT *keymgmt,
428 int selection)
68552cde 429{
b305452f
RL
430 if (keymgmt->export_types == NULL)
431 return NULL;
432 return keymgmt->export_types(selection);
68552cde 433}
13697f1c
RL
434
435int evp_keymgmt_copy(const EVP_KEYMGMT *keymgmt,
436 void *keydata_to, const void *keydata_from,
437 int selection)
438{
439 /* We assume no copy if the implementation doesn't have a function */
440 if (keymgmt->copy == NULL)
441 return 0;
442 return keymgmt->copy(keydata_to, keydata_from, selection);
443}