EVP: Add the internal convenience function evp_keymgmt_util_export()
[openssl.git] / crypto / evp / keymgmt_lib.c
1 /*
2  * Copyright 2019-2020 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/core_names.h>
11 #include "internal/cryptlib.h"
12 #include "internal/nelem.h"
13 #include "crypto/evp.h"
14 #include "crypto/asn1.h"
15 #include "internal/core.h"
16 #include "internal/provider.h"
17 #include "evp_local.h"
18
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  */
23 static 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
31 int evp_keymgmt_util_try_import(const OSSL_PARAM params[], void *arg)
32 {
33     struct evp_keymgmt_util_try_import_data_st *data = arg;
34
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
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
49     return evp_keymgmt_import(data->keymgmt, data->keydata, data->selection,
50                               params);
51 }
52
53 int 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
66 EVP_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
80 int 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
87 void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
88 {
89     struct evp_keymgmt_util_try_import_data_st import_data;
90     size_t i = 0;
91
92     /* Export to where? */
93     if (keymgmt == NULL)
94         return NULL;
95
96     /* If we have an unassigned key, give up */
97     if (pk->keydata == NULL)
98         return NULL;
99
100     /* If |keymgmt| matches the "origin" |keymgmt|, no more to do */
101     if (pk->keymgmt == keymgmt)
102         return pk->keydata;
103
104     /* If this key is already exported to |keymgmt|, no more to do */
105     i = evp_keymgmt_util_find_operation_cache_index(pk, keymgmt);
106     if (i < OSSL_NELEM(pk->operation_cache)
107         && pk->operation_cache[i].keymgmt != NULL)
108         return pk->operation_cache[i].keydata;
109
110     /* If the "origin" |keymgmt| doesn't support exporting, give up */
111     /*
112      * TODO(3.0) consider an evp_keymgmt_export() return value that indicates
113      * that the method is unsupported.
114      */
115     if (pk->keymgmt->export == NULL)
116         return NULL;
117
118     /* Check that we have found an empty slot in the export cache */
119     /*
120      * TODO(3.0) Right now, we assume we have ample space.  We will have to
121      * think about a cache aging scheme, though, if |i| indexes outside the
122      * array.
123      */
124     if (!ossl_assert(i < OSSL_NELEM(pk->operation_cache)))
125         return NULL;
126
127     /*
128      * Make sure that the type of the keymgmt to export to matches the type
129      * of the "origin"
130      */
131     if (!ossl_assert(match_type(pk->keymgmt, keymgmt)))
132         return NULL;
133
134     /*
135      * We look at the already cached provider keys, and import from the
136      * first that supports it (i.e. use its export function), and export
137      * the imported data to the new provider.
138      */
139
140     /* Setup for the export callback */
141     import_data.keydata = NULL;  /* evp_keymgmt_util_try_import will create it */
142     import_data.keymgmt = keymgmt;
143     import_data.selection = OSSL_KEYMGMT_SELECT_ALL;
144
145     /*
146      * The export function calls the callback (evp_keymgmt_util_try_import),
147      * which does the import for us.  If successful, we're done.
148      */
149     if (!evp_keymgmt_util_export(pk, OSSL_KEYMGMT_SELECT_ALL,
150                                  &evp_keymgmt_util_try_import, &import_data)) {
151         /* If there was an error, bail out */
152         evp_keymgmt_freedata(keymgmt, import_data.keydata);
153         return NULL;
154     }
155
156     /* Add the new export to the operation cache */
157     if (!evp_keymgmt_util_cache_keydata(pk, i, keymgmt, import_data.keydata)) {
158         evp_keymgmt_freedata(keymgmt, import_data.keydata);
159         return NULL;
160     }
161
162     return import_data.keydata;
163 }
164
165 void evp_keymgmt_util_clear_operation_cache(EVP_PKEY *pk)
166 {
167     size_t i, end = OSSL_NELEM(pk->operation_cache);
168
169     if (pk != NULL) {
170         for (i = 0; i < end && pk->operation_cache[i].keymgmt != NULL; i++) {
171             EVP_KEYMGMT *keymgmt = pk->operation_cache[i].keymgmt;
172             void *keydata = pk->operation_cache[i].keydata;
173
174             pk->operation_cache[i].keymgmt = NULL;
175             pk->operation_cache[i].keydata = NULL;
176             evp_keymgmt_freedata(keymgmt, keydata);
177             EVP_KEYMGMT_free(keymgmt);
178         }
179     }
180 }
181
182 size_t evp_keymgmt_util_find_operation_cache_index(EVP_PKEY *pk,
183                                                    EVP_KEYMGMT *keymgmt)
184 {
185     size_t i, end = OSSL_NELEM(pk->operation_cache);
186
187     for (i = 0; i < end && pk->operation_cache[i].keymgmt != NULL; i++) {
188         if (keymgmt == pk->operation_cache[i].keymgmt)
189             break;
190     }
191
192     return i;
193 }
194
195 int evp_keymgmt_util_cache_keydata(EVP_PKEY *pk, size_t index,
196                                    EVP_KEYMGMT *keymgmt, void *keydata)
197 {
198     if (keydata != NULL) {
199         if (!EVP_KEYMGMT_up_ref(keymgmt))
200             return 0;
201         pk->operation_cache[index].keydata = keydata;
202         pk->operation_cache[index].keymgmt = keymgmt;
203     }
204     return 1;
205 }
206
207 void evp_keymgmt_util_cache_keyinfo(EVP_PKEY *pk)
208 {
209     /*
210      * Cache information about the provider "origin" key.
211      *
212      * This services functions like EVP_PKEY_size, EVP_PKEY_bits, etc
213      */
214     if (pk->keydata != NULL) {
215         int bits = 0;
216         int security_bits = 0;
217         int size = 0;
218         OSSL_PARAM params[4];
219
220         params[0] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_BITS, &bits);
221         params[1] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_SECURITY_BITS,
222                                              &security_bits);
223         params[2] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_MAX_SIZE, &size);
224         params[3] = OSSL_PARAM_construct_end();
225         if (evp_keymgmt_get_params(pk->keymgmt, pk->keydata, params)) {
226             pk->cache.size = size;
227             pk->cache.bits = bits;
228             pk->cache.security_bits = security_bits;
229         }
230     }
231 }
232
233 void *evp_keymgmt_util_fromdata(EVP_PKEY *target, EVP_KEYMGMT *keymgmt,
234                                 int selection, const OSSL_PARAM params[])
235 {
236     void *keydata = NULL;
237
238     if ((keydata = evp_keymgmt_newdata(keymgmt)) == NULL
239         || !evp_keymgmt_import(keymgmt, keydata, selection, params)
240         || !evp_keymgmt_util_assign_pkey(target, keymgmt, keydata)) {
241         evp_keymgmt_freedata(keymgmt, keydata);
242         keydata = NULL;
243     }
244     return keydata;
245 }
246
247 int evp_keymgmt_util_has(EVP_PKEY *pk, int selection)
248 {
249     /* Check if key is even assigned */
250     if (pk->keymgmt == NULL)
251         return 0;
252
253     return evp_keymgmt_has(pk->keymgmt, pk->keydata, selection);
254 }
255
256 /*
257  * evp_keymgmt_util_match() doesn't just look at the provider side "origin",
258  * but also in the operation cache to see if there's any common keymgmt that
259  * supplies OP_keymgmt_match.
260  *
261  * evp_keymgmt_util_match() adheres to the return values that EVP_PKEY_eq()
262  * and EVP_PKEY_parameters_eq() return, i.e.:
263  *
264  *  1   same key
265  *  0   not same key
266  * -1   not same key type
267  * -2   unsupported operation
268  */
269 int evp_keymgmt_util_match(EVP_PKEY *pk1, EVP_PKEY *pk2, int selection)
270 {
271     EVP_KEYMGMT *keymgmt1 = NULL, *keymgmt2 = NULL;
272     void *keydata1 = NULL, *keydata2 = NULL;
273
274     if (pk1 == NULL || pk2 == NULL) {
275         if (pk1 == NULL && pk2 == NULL)
276             return 1;
277         return 0;
278     }
279
280     keymgmt1 = pk1->keymgmt;
281     keydata1 = pk1->keydata;
282     keymgmt2 = pk2->keymgmt;
283     keydata2 = pk2->keydata;
284
285     if (keymgmt1 != keymgmt2) {
286         /*
287          * The condition for a successful cross export is that the
288          * keydata to be exported is NULL (typed, but otherwise empty
289          * EVP_PKEY), or that it was possible to export it with
290          * evp_keymgmt_util_export_to_provider().
291          *
292          * We use |ok| to determine if it's ok to cross export one way,
293          * but also to determine if we should attempt a cross export
294          * the other way.  There's no point doing it both ways.
295          */
296         int ok = 1;
297
298         /* Complex case, where the keymgmt differ */
299         if (keymgmt1 != NULL
300             && keymgmt2 != NULL
301             && !match_type(keymgmt1, keymgmt2)) {
302             ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES);
303             return -1;           /* Not the same type */
304         }
305
306         /*
307          * The key types are determined to match, so we try cross export,
308          * but only to keymgmt's that supply a matching function.
309          */
310         if (keymgmt2 != NULL
311             && keymgmt2->match != NULL) {
312             void *tmp_keydata = NULL;
313
314             ok = 1;
315             if (keydata1 != NULL) {
316                 tmp_keydata =
317                     evp_keymgmt_util_export_to_provider(pk1, keymgmt2);
318                 ok = (tmp_keydata != NULL);
319             }
320             if (ok) {
321                 keymgmt1 = keymgmt2;
322                 keydata1 = tmp_keydata;
323             }
324         }
325         /*
326          * If we've successfully cross exported one way, there's no point
327          * doing it the other way, hence the |!ok| check.
328          */
329         if (!ok
330             && keymgmt1 != NULL
331             && keymgmt1->match != NULL) {
332             void *tmp_keydata = NULL;
333
334             ok = 1;
335             if (keydata2 != NULL) {
336                 tmp_keydata =
337                     evp_keymgmt_util_export_to_provider(pk2, keymgmt1);
338                 ok = (tmp_keydata != NULL);
339             }
340             if (ok) {
341                 keymgmt2 = keymgmt1;
342                 keydata2 = tmp_keydata;
343             }
344         }
345     }
346
347     /* If we still don't have matching keymgmt implementations, we give up */
348     if (keymgmt1 != keymgmt2)
349         return -2;
350
351     /* If both keydata are NULL, then they're the same key */
352     if (keydata1 == NULL && keydata2 == NULL)
353         return 1;
354     /* If only one of the keydata is NULL, then they're different keys */
355     if (keydata1 == NULL || keydata2 == NULL)
356         return 0;
357     /* If both keydata are non-NULL, we let the backend decide */
358     return evp_keymgmt_match(keymgmt1, keydata1, keydata2, selection);
359 }
360
361 int evp_keymgmt_util_copy(EVP_PKEY *to, EVP_PKEY *from, int selection)
362 {
363     /* Save copies of pointers we want to play with without affecting |to| */
364     EVP_KEYMGMT *to_keymgmt = to->keymgmt;
365     void *to_keydata = to->keydata, *alloc_keydata = NULL;
366
367     /* An unassigned key can't be copied */
368     if (from == NULL || from->keydata == NULL)
369         return 0;
370
371     /*
372      * If |to| is unassigned, ensure it gets the same KEYMGMT as |from|,
373      * Note that the final setting of KEYMGMT is done further down, with
374      * EVP_PKEY_set_type_by_keymgmt(); we don't want to do that prematurely.
375      */
376     if (to_keymgmt == NULL)
377         to_keymgmt = from->keymgmt;
378
379     if (to_keymgmt == from->keymgmt && to_keymgmt->copy != NULL) {
380         /* Make sure there's somewhere to copy to */
381         if (to_keydata == NULL
382             && ((to_keydata = alloc_keydata = evp_keymgmt_newdata(to_keymgmt))
383                 == NULL)) {
384             ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
385             return 0;
386         }
387
388         /*
389          * |to| and |from| have the same keymgmt, and the copy function is
390          * implemented, so just copy and be done
391          */
392         if (!evp_keymgmt_copy(to_keymgmt, to_keydata, from->keydata,
393                               selection))
394             return 0;
395     } else if (match_type(to_keymgmt, from->keymgmt)) {
396         struct evp_keymgmt_util_try_import_data_st import_data;
397
398         import_data.keymgmt = to_keymgmt;
399         import_data.keydata = to_keydata;
400         import_data.selection = selection;
401
402         if (!evp_keymgmt_util_export(from, selection,
403                                      &evp_keymgmt_util_try_import,
404                                      &import_data)) {
405             evp_keymgmt_freedata(to_keymgmt, alloc_keydata);
406             return 0;
407         }
408
409         /*
410          * In case to_keydata was previously unallocated,
411          * evp_keymgmt_util_try_import() may have created it for us.
412          */
413         if (to_keydata == NULL)
414             to_keydata = alloc_keydata = import_data.keydata;
415     } else {
416         ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES);
417         return 0;
418     }
419
420     /*
421      * We only need to set the |to| type when its |keymgmt| isn't set.
422      * We can then just set its |keydata| to what we have, which might
423      * be exactly what it had when entering this function.
424      * This is a bit different from using evp_keymgmt_util_assign_pkey(),
425      * which isn't as careful with |to|'s original |keymgmt|, since it's
426      * meant to forcibly reassign an EVP_PKEY no matter what, which is
427      * why we don't use that one here.
428      */
429     if (to->keymgmt == NULL
430         && !EVP_PKEY_set_type_by_keymgmt(to, to_keymgmt)) {
431         evp_keymgmt_freedata(to_keymgmt, alloc_keydata);
432         return 0;
433     }
434     to->keydata = to_keydata;
435     evp_keymgmt_util_cache_keyinfo(to);
436
437     return 1;
438 }
439
440 void *evp_keymgmt_util_gen(EVP_PKEY *target, EVP_KEYMGMT *keymgmt,
441                            void *genctx, OSSL_CALLBACK *cb, void *cbarg)
442 {
443     void *keydata = NULL;
444
445     if ((keydata = evp_keymgmt_gen(keymgmt, genctx, cb, cbarg)) == NULL
446         || !evp_keymgmt_util_assign_pkey(target, keymgmt, keydata)) {
447         evp_keymgmt_freedata(keymgmt, keydata);
448         keydata = NULL;
449     }
450
451     return keydata;
452 }
453
454 /*
455  * Returns the same numbers as EVP_PKEY_get_default_digest_name()
456  * When the string from the EVP_KEYMGMT implementation is "", we use
457  * SN_undef, since that corresponds to what EVP_PKEY_get_default_nid()
458  * returns for no digest.
459  */
460 int evp_keymgmt_util_get_deflt_digest_name(EVP_KEYMGMT *keymgmt,
461                                            void *keydata,
462                                            char *mdname, size_t mdname_sz)
463 {
464     OSSL_PARAM params[3];
465     char mddefault[100] = "";
466     char mdmandatory[100] = "";
467     char *result = NULL;
468     int rv = -2;
469
470     params[0] =
471         OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_DEFAULT_DIGEST,
472                                          mddefault, sizeof(mddefault));
473     params[1] =
474         OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_MANDATORY_DIGEST,
475                                          mdmandatory,
476                                          sizeof(mdmandatory));
477     params[2] = OSSL_PARAM_construct_end();
478
479     if (!evp_keymgmt_get_params(keymgmt, keydata, params))
480         return 0;
481
482     if (OSSL_PARAM_modified(params + 1)) {
483         if (params[1].return_size <= 1) /* Only a NUL byte */
484             result = SN_undef;
485         else
486             result = mdmandatory;
487         rv = 2;
488     } else if (OSSL_PARAM_modified(params)) {
489         if (params[0].return_size <= 1) /* Only a NUL byte */
490             result = SN_undef;
491         else
492             result = mddefault;
493         rv = 1;
494     }
495     if (rv > 0)
496         OPENSSL_strlcpy(mdname, result, mdname_sz);
497     return rv;
498 }