]> git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/evp/keymgmt_meth.c
Add OSSL_FUNC_keymgmt_im/export_types function that gets the provider context
[thirdparty/openssl.git] / crypto / evp / keymgmt_meth.c
1 /*
2 * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
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>
11 #include <openssl/core_dispatch.h>
12 #include <openssl/evp.h>
13 #include <openssl/err.h>
14 #include "internal/provider.h"
15 #include "internal/refcount.h"
16 #include "internal/core.h"
17 #include "crypto/evp.h"
18 #include "evp_local.h"
19
20 static void *keymgmt_new(void)
21 {
22 EVP_KEYMGMT *keymgmt = NULL;
23
24 if ((keymgmt = OPENSSL_zalloc(sizeof(*keymgmt))) == NULL)
25 return NULL;
26 if ((keymgmt->lock = CRYPTO_THREAD_lock_new()) == NULL) {
27 EVP_KEYMGMT_free(keymgmt);
28 ERR_raise(ERR_LIB_EVP, ERR_R_CRYPTO_LIB);
29 return NULL;
30 }
31
32 keymgmt->refcnt = 1;
33
34 return keymgmt;
35 }
36
37 static void *keymgmt_from_algorithm(int name_id,
38 const OSSL_ALGORITHM *algodef,
39 OSSL_PROVIDER *prov)
40 {
41 const OSSL_DISPATCH *fns = algodef->implementation;
42 EVP_KEYMGMT *keymgmt = NULL;
43 int setparamfncnt = 0, getparamfncnt = 0;
44 int setgenparamfncnt = 0;
45 int importfncnt = 0, exportfncnt = 0;
46 int importtypesfncnt = 0, exporttypesfncnt = 0;
47
48 if ((keymgmt = keymgmt_new()) == NULL)
49 return NULL;
50
51 keymgmt->name_id = name_id;
52 if ((keymgmt->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) {
53 EVP_KEYMGMT_free(keymgmt);
54 return NULL;
55 }
56 keymgmt->description = algodef->algorithm_description;
57
58 for (; fns->function_id != 0; fns++) {
59 switch (fns->function_id) {
60 case OSSL_FUNC_KEYMGMT_NEW:
61 if (keymgmt->new == NULL)
62 keymgmt->new = OSSL_FUNC_keymgmt_new(fns);
63 break;
64 case OSSL_FUNC_KEYMGMT_GEN_INIT:
65 if (keymgmt->gen_init == NULL)
66 keymgmt->gen_init = OSSL_FUNC_keymgmt_gen_init(fns);
67 break;
68 case OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE:
69 if (keymgmt->gen_set_template == NULL)
70 keymgmt->gen_set_template =
71 OSSL_FUNC_keymgmt_gen_set_template(fns);
72 break;
73 case OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS:
74 if (keymgmt->gen_set_params == NULL) {
75 setgenparamfncnt++;
76 keymgmt->gen_set_params =
77 OSSL_FUNC_keymgmt_gen_set_params(fns);
78 }
79 break;
80 case OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS:
81 if (keymgmt->gen_settable_params == NULL) {
82 setgenparamfncnt++;
83 keymgmt->gen_settable_params =
84 OSSL_FUNC_keymgmt_gen_settable_params(fns);
85 }
86 break;
87 case OSSL_FUNC_KEYMGMT_GEN:
88 if (keymgmt->gen == NULL)
89 keymgmt->gen = OSSL_FUNC_keymgmt_gen(fns);
90 break;
91 case OSSL_FUNC_KEYMGMT_GEN_CLEANUP:
92 if (keymgmt->gen_cleanup == NULL)
93 keymgmt->gen_cleanup = OSSL_FUNC_keymgmt_gen_cleanup(fns);
94 break;
95 case OSSL_FUNC_KEYMGMT_FREE:
96 if (keymgmt->free == NULL)
97 keymgmt->free = OSSL_FUNC_keymgmt_free(fns);
98 break;
99 case OSSL_FUNC_KEYMGMT_LOAD:
100 if (keymgmt->load == NULL)
101 keymgmt->load = OSSL_FUNC_keymgmt_load(fns);
102 break;
103 case OSSL_FUNC_KEYMGMT_GET_PARAMS:
104 if (keymgmt->get_params == NULL) {
105 getparamfncnt++;
106 keymgmt->get_params = OSSL_FUNC_keymgmt_get_params(fns);
107 }
108 break;
109 case OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS:
110 if (keymgmt->gettable_params == NULL) {
111 getparamfncnt++;
112 keymgmt->gettable_params =
113 OSSL_FUNC_keymgmt_gettable_params(fns);
114 }
115 break;
116 case OSSL_FUNC_KEYMGMT_SET_PARAMS:
117 if (keymgmt->set_params == NULL) {
118 setparamfncnt++;
119 keymgmt->set_params = OSSL_FUNC_keymgmt_set_params(fns);
120 }
121 break;
122 case OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS:
123 if (keymgmt->settable_params == NULL) {
124 setparamfncnt++;
125 keymgmt->settable_params =
126 OSSL_FUNC_keymgmt_settable_params(fns);
127 }
128 break;
129 case OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME:
130 if (keymgmt->query_operation_name == NULL)
131 keymgmt->query_operation_name =
132 OSSL_FUNC_keymgmt_query_operation_name(fns);
133 break;
134 case OSSL_FUNC_KEYMGMT_HAS:
135 if (keymgmt->has == NULL)
136 keymgmt->has = OSSL_FUNC_keymgmt_has(fns);
137 break;
138 case OSSL_FUNC_KEYMGMT_DUP:
139 if (keymgmt->dup == NULL)
140 keymgmt->dup = OSSL_FUNC_keymgmt_dup(fns);
141 break;
142 case OSSL_FUNC_KEYMGMT_VALIDATE:
143 if (keymgmt->validate == NULL)
144 keymgmt->validate = OSSL_FUNC_keymgmt_validate(fns);
145 break;
146 case OSSL_FUNC_KEYMGMT_MATCH:
147 if (keymgmt->match == NULL)
148 keymgmt->match = OSSL_FUNC_keymgmt_match(fns);
149 break;
150 case OSSL_FUNC_KEYMGMT_IMPORT:
151 if (keymgmt->import == NULL) {
152 importfncnt++;
153 keymgmt->import = OSSL_FUNC_keymgmt_import(fns);
154 }
155 break;
156 case OSSL_FUNC_KEYMGMT_IMPORT_TYPES:
157 if (keymgmt->import_types == NULL) {
158 if (importtypesfncnt == 0)
159 importfncnt++;
160 importtypesfncnt++;
161 keymgmt->import_types = OSSL_FUNC_keymgmt_import_types(fns);
162 }
163 break;
164 case OSSL_FUNC_KEYMGMT_IMPORT_TYPES_EX:
165 if (keymgmt->import_types_ex == NULL) {
166 if (importtypesfncnt == 0)
167 importfncnt++;
168 importtypesfncnt++;
169 keymgmt->import_types_ex = OSSL_FUNC_keymgmt_import_types_ex(fns);
170 }
171 break;
172 case OSSL_FUNC_KEYMGMT_EXPORT:
173 if (keymgmt->export == NULL) {
174 exportfncnt++;
175 keymgmt->export = OSSL_FUNC_keymgmt_export(fns);
176 }
177 break;
178 case OSSL_FUNC_KEYMGMT_EXPORT_TYPES:
179 if (keymgmt->export_types == NULL) {
180 if (exporttypesfncnt == 0)
181 exportfncnt++;
182 exporttypesfncnt++;
183 keymgmt->export_types = OSSL_FUNC_keymgmt_export_types(fns);
184 }
185 break;
186 case OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX:
187 if (keymgmt->export_types_ex == NULL) {
188 if (exporttypesfncnt == 0)
189 exportfncnt++;
190 exporttypesfncnt++;
191 keymgmt->export_types_ex = OSSL_FUNC_keymgmt_export_types_ex(fns);
192 }
193 break;
194 }
195 }
196 /*
197 * Try to check that the method is sensible.
198 * At least one constructor and the destructor are MANDATORY
199 * The functions 'has' is MANDATORY
200 * It makes no sense being able to free stuff if you can't create it.
201 * It makes no sense providing OSSL_PARAM descriptors for import and
202 * export if you can't import or export.
203 */
204 if (keymgmt->free == NULL
205 || (keymgmt->new == NULL
206 && keymgmt->gen == NULL
207 && keymgmt->load == NULL)
208 || keymgmt->has == NULL
209 || (getparamfncnt != 0 && getparamfncnt != 2)
210 || (setparamfncnt != 0 && setparamfncnt != 2)
211 || (setgenparamfncnt != 0 && setgenparamfncnt != 2)
212 || (importfncnt != 0 && importfncnt != 2)
213 || (exportfncnt != 0 && exportfncnt != 2)
214 || (keymgmt->gen != NULL
215 && (keymgmt->gen_init == NULL
216 || keymgmt->gen_cleanup == NULL))) {
217 EVP_KEYMGMT_free(keymgmt);
218 ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
219 return NULL;
220 }
221 keymgmt->prov = prov;
222 if (prov != NULL)
223 ossl_provider_up_ref(prov);
224
225 return keymgmt;
226 }
227
228 EVP_KEYMGMT *evp_keymgmt_fetch_from_prov(OSSL_PROVIDER *prov,
229 const char *name,
230 const char *properties)
231 {
232 return evp_generic_fetch_from_prov(prov, OSSL_OP_KEYMGMT,
233 name, properties,
234 keymgmt_from_algorithm,
235 (int (*)(void *))EVP_KEYMGMT_up_ref,
236 (void (*)(void *))EVP_KEYMGMT_free);
237 }
238
239 EVP_KEYMGMT *EVP_KEYMGMT_fetch(OSSL_LIB_CTX *ctx, const char *algorithm,
240 const char *properties)
241 {
242 return evp_generic_fetch(ctx, OSSL_OP_KEYMGMT, algorithm, properties,
243 keymgmt_from_algorithm,
244 (int (*)(void *))EVP_KEYMGMT_up_ref,
245 (void (*)(void *))EVP_KEYMGMT_free);
246 }
247
248 int EVP_KEYMGMT_up_ref(EVP_KEYMGMT *keymgmt)
249 {
250 int ref = 0;
251
252 CRYPTO_UP_REF(&keymgmt->refcnt, &ref, keymgmt->lock);
253 return 1;
254 }
255
256 void EVP_KEYMGMT_free(EVP_KEYMGMT *keymgmt)
257 {
258 int ref = 0;
259
260 if (keymgmt == NULL)
261 return;
262
263 CRYPTO_DOWN_REF(&keymgmt->refcnt, &ref, keymgmt->lock);
264 if (ref > 0)
265 return;
266 OPENSSL_free(keymgmt->type_name);
267 ossl_provider_free(keymgmt->prov);
268 CRYPTO_THREAD_lock_free(keymgmt->lock);
269 OPENSSL_free(keymgmt);
270 }
271
272 const OSSL_PROVIDER *EVP_KEYMGMT_get0_provider(const EVP_KEYMGMT *keymgmt)
273 {
274 return keymgmt->prov;
275 }
276
277 int evp_keymgmt_get_number(const EVP_KEYMGMT *keymgmt)
278 {
279 return keymgmt->name_id;
280 }
281
282 const char *EVP_KEYMGMT_get0_description(const EVP_KEYMGMT *keymgmt)
283 {
284 return keymgmt->description;
285 }
286
287 const char *EVP_KEYMGMT_get0_name(const EVP_KEYMGMT *keymgmt)
288 {
289 return keymgmt->type_name;
290 }
291
292 int EVP_KEYMGMT_is_a(const EVP_KEYMGMT *keymgmt, const char *name)
293 {
294 return keymgmt != NULL
295 && evp_is_a(keymgmt->prov, keymgmt->name_id, NULL, name);
296 }
297
298 void EVP_KEYMGMT_do_all_provided(OSSL_LIB_CTX *libctx,
299 void (*fn)(EVP_KEYMGMT *keymgmt, void *arg),
300 void *arg)
301 {
302 evp_generic_do_all(libctx, OSSL_OP_KEYMGMT,
303 (void (*)(void *, void *))fn, arg,
304 keymgmt_from_algorithm,
305 (int (*)(void *))EVP_KEYMGMT_up_ref,
306 (void (*)(void *))EVP_KEYMGMT_free);
307 }
308
309 int EVP_KEYMGMT_names_do_all(const EVP_KEYMGMT *keymgmt,
310 void (*fn)(const char *name, void *data),
311 void *data)
312 {
313 if (keymgmt->prov != NULL)
314 return evp_names_do_all(keymgmt->prov, keymgmt->name_id, fn, data);
315
316 return 1;
317 }
318
319 /*
320 * Internal API that interfaces with the method function pointers
321 */
322 void *evp_keymgmt_newdata(const EVP_KEYMGMT *keymgmt)
323 {
324 void *provctx = ossl_provider_ctx(EVP_KEYMGMT_get0_provider(keymgmt));
325
326 /*
327 * 'new' is currently mandatory on its own, but when new
328 * constructors appear, it won't be quite as mandatory,
329 * so we have a check for future cases.
330 */
331 if (keymgmt->new == NULL)
332 return NULL;
333 return keymgmt->new(provctx);
334 }
335
336 void evp_keymgmt_freedata(const EVP_KEYMGMT *keymgmt, void *keydata)
337 {
338 /* This is mandatory, no need to check for its presence */
339 keymgmt->free(keydata);
340 }
341
342 void *evp_keymgmt_gen_init(const EVP_KEYMGMT *keymgmt, int selection,
343 const OSSL_PARAM params[])
344 {
345 void *provctx = ossl_provider_ctx(EVP_KEYMGMT_get0_provider(keymgmt));
346
347 if (keymgmt->gen_init == NULL)
348 return NULL;
349 return keymgmt->gen_init(provctx, selection, params);
350 }
351
352 int evp_keymgmt_gen_set_template(const EVP_KEYMGMT *keymgmt, void *genctx,
353 void *template)
354 {
355 /*
356 * It's arguable if we actually should return success in this case, as
357 * it allows the caller to set a template key, which is then ignored.
358 * However, this is how the legacy methods (EVP_PKEY_METHOD) operate,
359 * so we do this in the interest of backward compatibility.
360 */
361 if (keymgmt->gen_set_template == NULL)
362 return 1;
363 return keymgmt->gen_set_template(genctx, template);
364 }
365
366 int evp_keymgmt_gen_set_params(const EVP_KEYMGMT *keymgmt, void *genctx,
367 const OSSL_PARAM params[])
368 {
369 if (keymgmt->gen_set_params == NULL)
370 return 0;
371 return keymgmt->gen_set_params(genctx, params);
372 }
373
374 const OSSL_PARAM *EVP_KEYMGMT_gen_settable_params(const EVP_KEYMGMT *keymgmt)
375 {
376 void *provctx = ossl_provider_ctx(EVP_KEYMGMT_get0_provider(keymgmt));
377
378 if (keymgmt->gen_settable_params == NULL)
379 return NULL;
380 return keymgmt->gen_settable_params(NULL, provctx);
381 }
382
383 void *evp_keymgmt_gen(const EVP_KEYMGMT *keymgmt, void *genctx,
384 OSSL_CALLBACK *cb, void *cbarg)
385 {
386 if (keymgmt->gen == NULL)
387 return NULL;
388 return keymgmt->gen(genctx, cb, cbarg);
389 }
390
391 void evp_keymgmt_gen_cleanup(const EVP_KEYMGMT *keymgmt, void *genctx)
392 {
393 if (keymgmt->gen != NULL)
394 keymgmt->gen_cleanup(genctx);
395 }
396
397 int evp_keymgmt_has_load(const EVP_KEYMGMT *keymgmt)
398 {
399 return keymgmt != NULL && keymgmt->load != NULL;
400 }
401
402 void *evp_keymgmt_load(const EVP_KEYMGMT *keymgmt,
403 const void *objref, size_t objref_sz)
404 {
405 if (evp_keymgmt_has_load(keymgmt))
406 return keymgmt->load(objref, objref_sz);
407 return NULL;
408 }
409
410 int evp_keymgmt_get_params(const EVP_KEYMGMT *keymgmt, void *keydata,
411 OSSL_PARAM params[])
412 {
413 if (keymgmt->get_params == NULL)
414 return 1;
415 return keymgmt->get_params(keydata, params);
416 }
417
418 const OSSL_PARAM *EVP_KEYMGMT_gettable_params(const EVP_KEYMGMT *keymgmt)
419 {
420 void *provctx = ossl_provider_ctx(EVP_KEYMGMT_get0_provider(keymgmt));
421
422 if (keymgmt->gettable_params == NULL)
423 return NULL;
424 return keymgmt->gettable_params(provctx);
425 }
426
427 int evp_keymgmt_set_params(const EVP_KEYMGMT *keymgmt, void *keydata,
428 const OSSL_PARAM params[])
429 {
430 if (keymgmt->set_params == NULL)
431 return 1;
432 return keymgmt->set_params(keydata, params);
433 }
434
435 const OSSL_PARAM *EVP_KEYMGMT_settable_params(const EVP_KEYMGMT *keymgmt)
436 {
437 void *provctx = ossl_provider_ctx(EVP_KEYMGMT_get0_provider(keymgmt));
438
439 if (keymgmt->settable_params == NULL)
440 return NULL;
441 return keymgmt->settable_params(provctx);
442 }
443
444 int evp_keymgmt_has(const EVP_KEYMGMT *keymgmt, void *keydata, int selection)
445 {
446 /* This is mandatory, no need to check for its presence */
447 return keymgmt->has(keydata, selection);
448 }
449
450 int evp_keymgmt_validate(const EVP_KEYMGMT *keymgmt, void *keydata,
451 int selection, int checktype)
452 {
453 /* We assume valid if the implementation doesn't have a function */
454 if (keymgmt->validate == NULL)
455 return 1;
456 return keymgmt->validate(keydata, selection, checktype);
457 }
458
459 int evp_keymgmt_match(const EVP_KEYMGMT *keymgmt,
460 const void *keydata1, const void *keydata2,
461 int selection)
462 {
463 /* We assume no match if the implementation doesn't have a function */
464 if (keymgmt->match == NULL)
465 return 0;
466 return keymgmt->match(keydata1, keydata2, selection);
467 }
468
469 int evp_keymgmt_import(const EVP_KEYMGMT *keymgmt, void *keydata,
470 int selection, const OSSL_PARAM params[])
471 {
472 if (keymgmt->import == NULL)
473 return 0;
474 return keymgmt->import(keydata, selection, params);
475 }
476
477 const OSSL_PARAM *evp_keymgmt_import_types(const EVP_KEYMGMT *keymgmt,
478 int selection)
479 {
480 void *provctx = ossl_provider_ctx(EVP_KEYMGMT_get0_provider(keymgmt));
481
482 if (keymgmt->import_types_ex != NULL)
483 return keymgmt->import_types_ex(provctx, selection);
484 if (keymgmt->import_types == NULL)
485 return NULL;
486 return keymgmt->import_types(selection);
487 }
488
489 int evp_keymgmt_export(const EVP_KEYMGMT *keymgmt, void *keydata,
490 int selection, OSSL_CALLBACK *param_cb, void *cbarg)
491 {
492 if (keymgmt->export == NULL)
493 return 0;
494 return keymgmt->export(keydata, selection, param_cb, cbarg);
495 }
496
497 const OSSL_PARAM *evp_keymgmt_export_types(const EVP_KEYMGMT *keymgmt,
498 int selection)
499 {
500 void *provctx = ossl_provider_ctx(EVP_KEYMGMT_get0_provider(keymgmt));
501
502 if (keymgmt->export_types_ex != NULL)
503 return keymgmt->export_types_ex(provctx, selection);
504 if (keymgmt->export_types == NULL)
505 return NULL;
506 return keymgmt->export_types(selection);
507 }
508
509 void *evp_keymgmt_dup(const EVP_KEYMGMT *keymgmt, const void *keydata_from,
510 int selection)
511 {
512 /* We assume no dup if the implementation doesn't have a function */
513 if (keymgmt->dup == NULL)
514 return NULL;
515 return keymgmt->dup(keydata_from, selection);
516 }