]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/evp/keymgmt_lib.c
Update copyright year
[thirdparty/openssl.git] / crypto / evp / keymgmt_lib.c
CommitLineData
70a1f7b4 1/*
a28d06f3 2 * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
70a1f7b4
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
6508e858 10#include <openssl/core_names.h>
70a1f7b4
RL
11#include "internal/cryptlib.h"
12#include "internal/nelem.h"
25f2138b
DMSP
13#include "crypto/evp.h"
14#include "crypto/asn1.h"
1640d48c 15#include "internal/core.h"
70a1f7b4 16#include "internal/provider.h"
706457b7 17#include "evp_local.h"
70a1f7b4 18
3f7ce7f1
RL
19/*
20 * match_type() checks if two EVP_KEYMGMT are matching key types. This
21 * function assumes that the caller has made all the necessary NULL checks.
22 */
23static int match_type(const EVP_KEYMGMT *keymgmt1, const EVP_KEYMGMT *keymgmt2)
24{
25 const OSSL_PROVIDER *prov2 = EVP_KEYMGMT_provider(keymgmt2);
26 const char *name2 = evp_first_name(prov2, EVP_KEYMGMT_number(keymgmt2));
27
28 return EVP_KEYMGMT_is_a(keymgmt1, name2);
29}
30
af836c22 31int evp_keymgmt_util_try_import(const OSSL_PARAM params[], void *arg)
651101e1 32{
af836c22 33 struct evp_keymgmt_util_try_import_data_st *data = arg;
70a1f7b4 34
11391da2
MC
35 /* Just in time creation of keydata */
36 if (data->keydata == NULL
37 && (data->keydata = evp_keymgmt_newdata(data->keymgmt)) == NULL) {
38 ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
39 return 0;
40 }
41
adc9f731
RL
42 /*
43 * It's fine if there was no data to transfer, we just end up with an
44 * empty destination key.
45 */
46 if (params[0].key == NULL)
47 return 1;
48
b305452f
RL
49 return evp_keymgmt_import(data->keymgmt, data->keydata, data->selection,
50 params);
70a1f7b4
RL
51}
52
af836c22
RL
53int evp_keymgmt_util_assign_pkey(EVP_PKEY *pkey, EVP_KEYMGMT *keymgmt,
54 void *keydata)
55{
56 if (pkey == NULL || keymgmt == NULL || keydata == NULL
57 || !EVP_PKEY_set_type_by_keymgmt(pkey, keymgmt)) {
58 ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
59 return 0;
60 }
61 pkey->keydata = keydata;
62 evp_keymgmt_util_cache_keyinfo(pkey);
63 return 1;
64}
65
66EVP_PKEY *evp_keymgmt_util_make_pkey(EVP_KEYMGMT *keymgmt, void *keydata)
67{
68 EVP_PKEY *pkey = NULL;
69
70 if (keymgmt == NULL
71 || keydata == NULL
72 || (pkey = EVP_PKEY_new()) == NULL
73 || !evp_keymgmt_util_assign_pkey(pkey, keymgmt, keydata)) {
74 EVP_PKEY_free(pkey);
75 return NULL;
76 }
77 return pkey;
78}
79
655f73ce
RL
80int evp_keymgmt_util_export(const EVP_PKEY *pk, int selection,
81 OSSL_CALLBACK *export_cb, void *export_cbarg)
82{
83 return evp_keymgmt_export(pk->keymgmt, pk->keydata, selection,
84 export_cb, export_cbarg);
85}
86
b305452f 87void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
70a1f7b4 88{
af836c22 89 struct evp_keymgmt_util_try_import_data_st import_data;
64954e2f 90 OP_CACHE_ELEM *op;
70a1f7b4 91
3f7ce7f1
RL
92 /* Export to where? */
93 if (keymgmt == NULL)
94 return NULL;
70a1f7b4 95
3f7ce7f1 96 /* If we have an unassigned key, give up */
adc9f731 97 if (pk->keydata == NULL)
3f7ce7f1 98 return NULL;
70a1f7b4 99
3c6ed955
RL
100 /* If |keymgmt| matches the "origin" |keymgmt|, no more to do */
101 if (pk->keymgmt == keymgmt)
102 return pk->keydata;
103
0b07db6f 104 CRYPTO_THREAD_read_lock(pk->lock);
f4a3799c
RL
105 /*
106 * If the provider native "origin" hasn't changed since last time, we
64954e2f
P
107 * try to find our keymgmt in the operation cache. If it has changed
108 * and our keymgmt isn't found, we will clear the cache further down.
f4a3799c
RL
109 */
110 if (pk->dirty_cnt == pk->dirty_cnt_copy) {
111 /* If this key is already exported to |keymgmt|, no more to do */
64954e2f
P
112 op = evp_keymgmt_util_find_operation_cache(pk, keymgmt);
113 if (op != NULL && op->keymgmt != NULL) {
114 void *ret = op->keydata;
f4a3799c
RL
115
116 CRYPTO_THREAD_unlock(pk->lock);
117 return ret;
118 }
0b07db6f
MC
119 }
120 CRYPTO_THREAD_unlock(pk->lock);
3c6ed955
RL
121
122 /* If the "origin" |keymgmt| doesn't support exporting, give up */
70a1f7b4 123 /*
3c6ed955
RL
124 * TODO(3.0) consider an evp_keymgmt_export() return value that indicates
125 * that the method is unsupported.
70a1f7b4 126 */
3c6ed955
RL
127 if (pk->keymgmt->export == NULL)
128 return NULL;
3f7ce7f1 129
3f7ce7f1
RL
130 /*
131 * Make sure that the type of the keymgmt to export to matches the type
3c6ed955 132 * of the "origin"
3f7ce7f1 133 */
3c6ed955 134 if (!ossl_assert(match_type(pk->keymgmt, keymgmt)))
3f7ce7f1 135 return NULL;
70a1f7b4 136
3f7ce7f1
RL
137 /*
138 * We look at the already cached provider keys, and import from the
139 * first that supports it (i.e. use its export function), and export
140 * the imported data to the new provider.
141 */
142
143 /* Setup for the export callback */
af836c22 144 import_data.keydata = NULL; /* evp_keymgmt_util_try_import will create it */
3f7ce7f1
RL
145 import_data.keymgmt = keymgmt;
146 import_data.selection = OSSL_KEYMGMT_SELECT_ALL;
147
3c6ed955 148 /*
af836c22
RL
149 * The export function calls the callback (evp_keymgmt_util_try_import),
150 * which does the import for us. If successful, we're done.
3c6ed955 151 */
655f73ce
RL
152 if (!evp_keymgmt_util_export(pk, OSSL_KEYMGMT_SELECT_ALL,
153 &evp_keymgmt_util_try_import, &import_data)) {
3f7ce7f1 154 /* If there was an error, bail out */
adc9f731 155 evp_keymgmt_freedata(keymgmt, import_data.keydata);
3f7ce7f1 156 return NULL;
70a1f7b4
RL
157 }
158
0b07db6f
MC
159 CRYPTO_THREAD_write_lock(pk->lock);
160 /* Check to make sure some other thread didn't get there first */
64954e2f
P
161 op = evp_keymgmt_util_find_operation_cache(pk, keymgmt);
162 if (op != NULL && op->keydata != NULL) {
163 void *ret = op->keydata;
0b07db6f
MC
164
165 CRYPTO_THREAD_unlock(pk->lock);
166
167 /*
168 * Another thread seemms to have already exported this so we abandon
169 * all the work we just did.
170 */
171 evp_keymgmt_freedata(keymgmt, import_data.keydata);
172
173 return ret;
174 }
175
f4a3799c
RL
176 /*
177 * If the dirty counter changed since last time, then clear the
178 * operation cache. In that case, we know that |i| is zero.
179 */
180 if (pk->dirty_cnt != pk->dirty_cnt_copy)
181 evp_keymgmt_util_clear_operation_cache(pk, 0);
182
3c6ed955 183 /* Add the new export to the operation cache */
64954e2f 184 if (!evp_keymgmt_util_cache_keydata(pk, keymgmt, import_data.keydata)) {
adc9f731 185 evp_keymgmt_freedata(keymgmt, import_data.keydata);
d5e66eab 186 return NULL;
3c6ed955 187 }
02f060d1 188
f4a3799c
RL
189 /* Synchronize the dirty count */
190 pk->dirty_cnt_copy = pk->dirty_cnt;
191
0b07db6f
MC
192 CRYPTO_THREAD_unlock(pk->lock);
193
adc9f731 194 return import_data.keydata;
70a1f7b4 195}
4cae07fe 196
64954e2f 197static void op_cache_free(OP_CACHE_ELEM *e)
4cae07fe 198{
64954e2f
P
199 evp_keymgmt_freedata(e->keymgmt, e->keydata);
200 EVP_KEYMGMT_free(e->keymgmt);
201 OPENSSL_free(e);
202}
4cae07fe 203
64954e2f
P
204int evp_keymgmt_util_clear_operation_cache(EVP_PKEY *pk, int locking)
205{
4cae07fe 206 if (pk != NULL) {
0b07db6f
MC
207 if (locking && pk->lock != NULL && !CRYPTO_THREAD_write_lock(pk->lock))
208 return 0;
64954e2f
P
209 sk_OP_CACHE_ELEM_pop_free(pk->operation_cache, op_cache_free);
210 pk->operation_cache = NULL;
0b07db6f
MC
211 if (locking && pk->lock != NULL)
212 CRYPTO_THREAD_unlock(pk->lock);
6508e858 213 }
0b07db6f
MC
214
215 return 1;
6508e858
RL
216}
217
64954e2f
P
218OP_CACHE_ELEM *evp_keymgmt_util_find_operation_cache(EVP_PKEY *pk,
219 EVP_KEYMGMT *keymgmt)
3f7ce7f1 220{
64954e2f
P
221 int i, end = sk_OP_CACHE_ELEM_num(pk->operation_cache);
222 OP_CACHE_ELEM *p;
3f7ce7f1 223
64954e2f
P
224 /*
225 * A comparison and sk_P_CACHE_ELEM_find() are avoided to not cause
226 * problems when we've only a read lock.
227 */
228 for (i = 0; i < end; i++) {
229 p = sk_OP_CACHE_ELEM_value(pk->operation_cache, i);
230 if (keymgmt == p->keymgmt)
231 return p;
3f7ce7f1 232 }
64954e2f 233 return NULL;
3f7ce7f1
RL
234}
235
64954e2f 236int evp_keymgmt_util_cache_keydata(EVP_PKEY *pk,
3c6ed955 237 EVP_KEYMGMT *keymgmt, void *keydata)
6508e858 238{
64954e2f
P
239 OP_CACHE_ELEM *p = NULL;
240
b305452f 241 if (keydata != NULL) {
64954e2f
P
242 if (pk->operation_cache == NULL) {
243 pk->operation_cache = sk_OP_CACHE_ELEM_new_null();
244 if (pk->operation_cache == NULL)
245 return 0;
246 }
247
248 p = OPENSSL_malloc(sizeof(*p));
249 if (p == NULL)
3c6ed955 250 return 0;
64954e2f
P
251 p->keydata = keydata;
252 p->keymgmt = keymgmt;
0b07db6f 253
64954e2f
P
254 if (!EVP_KEYMGMT_up_ref(keymgmt)) {
255 OPENSSL_free(p);
256 return 0;
257 }
258
259 if (!sk_OP_CACHE_ELEM_push(pk->operation_cache, p)) {
260 EVP_KEYMGMT_free(keymgmt);
261 OPENSSL_free(p);
262 return 0;
263 }
3c6ed955
RL
264 }
265 return 1;
266}
267
268void evp_keymgmt_util_cache_keyinfo(EVP_PKEY *pk)
269{
270 /*
271 * Cache information about the provider "origin" key.
272 *
273 * This services functions like EVP_PKEY_size, EVP_PKEY_bits, etc
274 */
adc9f731 275 if (pk->keydata != NULL) {
3c6ed955
RL
276 int bits = 0;
277 int security_bits = 0;
278 int size = 0;
279 OSSL_PARAM params[4];
280
281 params[0] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_BITS, &bits);
282 params[1] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_SECURITY_BITS,
283 &security_bits);
284 params[2] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_MAX_SIZE, &size);
285 params[3] = OSSL_PARAM_construct_end();
286 if (evp_keymgmt_get_params(pk->keymgmt, pk->keydata, params)) {
287 pk->cache.size = size;
288 pk->cache.bits = bits;
289 pk->cache.security_bits = security_bits;
6508e858 290 }
4cae07fe
RL
291 }
292}
fa9faf01 293
68552cde 294void *evp_keymgmt_util_fromdata(EVP_PKEY *target, EVP_KEYMGMT *keymgmt,
b305452f 295 int selection, const OSSL_PARAM params[])
46e2dd05 296{
8243d8d1 297 void *keydata = NULL;
46e2dd05 298
8243d8d1
RL
299 if ((keydata = evp_keymgmt_newdata(keymgmt)) == NULL
300 || !evp_keymgmt_import(keymgmt, keydata, selection, params)
af836c22 301 || !evp_keymgmt_util_assign_pkey(target, keymgmt, keydata)) {
8243d8d1
RL
302 evp_keymgmt_freedata(keymgmt, keydata);
303 keydata = NULL;
304 }
b305452f 305 return keydata;
46e2dd05 306}
157ded39
RL
307
308int evp_keymgmt_util_has(EVP_PKEY *pk, int selection)
309{
310 /* Check if key is even assigned */
311 if (pk->keymgmt == NULL)
312 return 0;
313
314 return evp_keymgmt_has(pk->keymgmt, pk->keydata, selection);
315}
1e9101c4
RL
316
317/*
318 * evp_keymgmt_util_match() doesn't just look at the provider side "origin",
319 * but also in the operation cache to see if there's any common keymgmt that
320 * supplies OP_keymgmt_match.
321 *
c74aaa39
DDO
322 * evp_keymgmt_util_match() adheres to the return values that EVP_PKEY_eq()
323 * and EVP_PKEY_parameters_eq() return, i.e.:
1e9101c4
RL
324 *
325 * 1 same key
326 * 0 not same key
327 * -1 not same key type
328 * -2 unsupported operation
329 */
330int evp_keymgmt_util_match(EVP_PKEY *pk1, EVP_PKEY *pk2, int selection)
331{
332 EVP_KEYMGMT *keymgmt1 = NULL, *keymgmt2 = NULL;
333 void *keydata1 = NULL, *keydata2 = NULL;
334
335 if (pk1 == NULL || pk2 == NULL) {
336 if (pk1 == NULL && pk2 == NULL)
337 return 1;
338 return 0;
339 }
340
341 keymgmt1 = pk1->keymgmt;
342 keydata1 = pk1->keydata;
343 keymgmt2 = pk2->keymgmt;
344 keydata2 = pk2->keydata;
345
346 if (keymgmt1 != keymgmt2) {
adc9f731
RL
347 /*
348 * The condition for a successful cross export is that the
349 * keydata to be exported is NULL (typed, but otherwise empty
350 * EVP_PKEY), or that it was possible to export it with
351 * evp_keymgmt_util_export_to_provider().
352 *
353 * We use |ok| to determine if it's ok to cross export one way,
354 * but also to determine if we should attempt a cross export
355 * the other way. There's no point doing it both ways.
356 */
357 int ok = 1;
1e9101c4
RL
358
359 /* Complex case, where the keymgmt differ */
360 if (keymgmt1 != NULL
361 && keymgmt2 != NULL
362 && !match_type(keymgmt1, keymgmt2)) {
363 ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES);
364 return -1; /* Not the same type */
365 }
366
367 /*
368 * The key types are determined to match, so we try cross export,
369 * but only to keymgmt's that supply a matching function.
370 */
371 if (keymgmt2 != NULL
372 && keymgmt2->match != NULL) {
adc9f731
RL
373 void *tmp_keydata = NULL;
374
375 ok = 1;
376 if (keydata1 != NULL) {
377 tmp_keydata =
378 evp_keymgmt_util_export_to_provider(pk1, keymgmt2);
379 ok = (tmp_keydata != NULL);
380 }
381 if (ok) {
1e9101c4
RL
382 keymgmt1 = keymgmt2;
383 keydata1 = tmp_keydata;
384 }
385 }
adc9f731 386 /*
8243d8d1 387 * If we've successfully cross exported one way, there's no point
adc9f731
RL
388 * doing it the other way, hence the |!ok| check.
389 */
390 if (!ok
1e9101c4
RL
391 && keymgmt1 != NULL
392 && keymgmt1->match != NULL) {
adc9f731
RL
393 void *tmp_keydata = NULL;
394
395 ok = 1;
396 if (keydata2 != NULL) {
397 tmp_keydata =
398 evp_keymgmt_util_export_to_provider(pk2, keymgmt1);
399 ok = (tmp_keydata != NULL);
400 }
401 if (ok) {
1e9101c4
RL
402 keymgmt2 = keymgmt1;
403 keydata2 = tmp_keydata;
404 }
405 }
406 }
407
408 /* If we still don't have matching keymgmt implementations, we give up */
409 if (keymgmt1 != keymgmt2)
410 return -2;
411
adc9f731
RL
412 /* If both keydata are NULL, then they're the same key */
413 if (keydata1 == NULL && keydata2 == NULL)
414 return 1;
415 /* If only one of the keydata is NULL, then they're different keys */
416 if (keydata1 == NULL || keydata2 == NULL)
417 return 0;
418 /* If both keydata are non-NULL, we let the backend decide */
1e9101c4
RL
419 return evp_keymgmt_match(keymgmt1, keydata1, keydata2, selection);
420}
ff3b59e1
RL
421
422int evp_keymgmt_util_copy(EVP_PKEY *to, EVP_PKEY *from, int selection)
423{
424 /* Save copies of pointers we want to play with without affecting |to| */
425 EVP_KEYMGMT *to_keymgmt = to->keymgmt;
426 void *to_keydata = to->keydata, *alloc_keydata = NULL;
427
428 /* An unassigned key can't be copied */
adc9f731 429 if (from == NULL || from->keydata == NULL)
ff3b59e1
RL
430 return 0;
431
036ee370
RL
432 /*
433 * If |to| is unassigned, ensure it gets the same KEYMGMT as |from|,
434 * Note that the final setting of KEYMGMT is done further down, with
435 * EVP_PKEY_set_type_by_keymgmt(); we don't want to do that prematurely.
436 */
437 if (to_keymgmt == NULL)
438 to_keymgmt = from->keymgmt;
439
adc9f731
RL
440 if (to_keymgmt == from->keymgmt && to_keymgmt->copy != NULL) {
441 /* Make sure there's somewhere to copy to */
442 if (to_keydata == NULL
036ee370
RL
443 && ((to_keydata = alloc_keydata = evp_keymgmt_newdata(to_keymgmt))
444 == NULL)) {
adc9f731 445 ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
ff3b59e1 446 return 0;
adc9f731 447 }
ff3b59e1 448
adc9f731
RL
449 /*
450 * |to| and |from| have the same keymgmt, and the copy function is
451 * implemented, so just copy and be done
452 */
ff3b59e1
RL
453 if (!evp_keymgmt_copy(to_keymgmt, to_keydata, from->keydata,
454 selection))
455 return 0;
456 } else if (match_type(to_keymgmt, from->keymgmt)) {
af836c22 457 struct evp_keymgmt_util_try_import_data_st import_data;
ff3b59e1
RL
458
459 import_data.keymgmt = to_keymgmt;
460 import_data.keydata = to_keydata;
461 import_data.selection = selection;
462
655f73ce
RL
463 if (!evp_keymgmt_util_export(from, selection,
464 &evp_keymgmt_util_try_import,
465 &import_data)) {
ff3b59e1
RL
466 evp_keymgmt_freedata(to_keymgmt, alloc_keydata);
467 return 0;
468 }
adc9f731
RL
469
470 /*
af836c22
RL
471 * In case to_keydata was previously unallocated,
472 * evp_keymgmt_util_try_import() may have created it for us.
adc9f731 473 */
036ee370
RL
474 if (to_keydata == NULL)
475 to_keydata = alloc_keydata = import_data.keydata;
ff3b59e1
RL
476 } else {
477 ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES);
478 return 0;
479 }
480
af836c22
RL
481 /*
482 * We only need to set the |to| type when its |keymgmt| isn't set.
483 * We can then just set its |keydata| to what we have, which might
484 * be exactly what it had when entering this function.
485 * This is a bit different from using evp_keymgmt_util_assign_pkey(),
486 * which isn't as careful with |to|'s original |keymgmt|, since it's
487 * meant to forcibly reassign an EVP_PKEY no matter what, which is
488 * why we don't use that one here.
489 */
ff3b59e1 490 if (to->keymgmt == NULL
8243d8d1 491 && !EVP_PKEY_set_type_by_keymgmt(to, to_keymgmt)) {
ff3b59e1
RL
492 evp_keymgmt_freedata(to_keymgmt, alloc_keydata);
493 return 0;
494 }
ff3b59e1
RL
495 to->keydata = to_keydata;
496 evp_keymgmt_util_cache_keyinfo(to);
497
498 return 1;
499}
62924755
RL
500
501void *evp_keymgmt_util_gen(EVP_PKEY *target, EVP_KEYMGMT *keymgmt,
502 void *genctx, OSSL_CALLBACK *cb, void *cbarg)
503{
8243d8d1 504 void *keydata = NULL;
62924755 505
8243d8d1 506 if ((keydata = evp_keymgmt_gen(keymgmt, genctx, cb, cbarg)) == NULL
af836c22 507 || !evp_keymgmt_util_assign_pkey(target, keymgmt, keydata)) {
8243d8d1
RL
508 evp_keymgmt_freedata(keymgmt, keydata);
509 keydata = NULL;
510 }
62924755
RL
511
512 return keydata;
513}
3b924da0
RL
514
515/*
516 * Returns the same numbers as EVP_PKEY_get_default_digest_name()
517 * When the string from the EVP_KEYMGMT implementation is "", we use
518 * SN_undef, since that corresponds to what EVP_PKEY_get_default_nid()
519 * returns for no digest.
520 */
521int evp_keymgmt_util_get_deflt_digest_name(EVP_KEYMGMT *keymgmt,
522 void *keydata,
523 char *mdname, size_t mdname_sz)
524{
525 OSSL_PARAM params[3];
526 char mddefault[100] = "";
527 char mdmandatory[100] = "";
528 char *result = NULL;
529 int rv = -2;
530
531 params[0] =
532 OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_DEFAULT_DIGEST,
533 mddefault, sizeof(mddefault));
3b924da0
RL
534 params[1] =
535 OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_MANDATORY_DIGEST,
536 mdmandatory,
537 sizeof(mdmandatory));
3b924da0
RL
538 params[2] = OSSL_PARAM_construct_end();
539
540 if (!evp_keymgmt_get_params(keymgmt, keydata, params))
541 return 0;
542
54b47afe
P
543 if (OSSL_PARAM_modified(params + 1)) {
544 if (params[1].return_size <= 1) /* Only a NUL byte */
3b924da0
RL
545 result = SN_undef;
546 else
547 result = mdmandatory;
548 rv = 2;
54b47afe
P
549 } else if (OSSL_PARAM_modified(params)) {
550 if (params[0].return_size <= 1) /* Only a NUL byte */
3b924da0
RL
551 result = SN_undef;
552 else
553 result = mddefault;
554 rv = 1;
555 }
556 if (rv > 0)
557 OPENSSL_strlcpy(mdname, result, mdname_sz);
558 return rv;
559}