xref: /src/crypto/openssl/crypto/evp/p_lib.c (revision f25b8c9fb4f58cf61adb47d7570abe7caa6d385d)
1 /*
2  * Copyright 1995-2025 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 /*
11  * DSA low level APIs are deprecated for public use, but still ok for
12  * internal use.
13  */
14 #include "internal/deprecated.h"
15 
16 #include <assert.h>
17 #include <stdio.h>
18 #include "internal/cryptlib.h"
19 #include "internal/refcount.h"
20 #include "internal/namemap.h"
21 #include <openssl/bn.h>
22 #include <openssl/err.h>
23 #include <openssl/objects.h>
24 #include <openssl/evp.h>
25 #include <openssl/rsa.h>
26 #include <openssl/dsa.h>
27 #include <openssl/dh.h>
28 #include <openssl/ec.h>
29 #include <openssl/cmac.h>
30 #ifndef FIPS_MODULE
31 #include <openssl/engine.h>
32 #endif
33 #include <openssl/params.h>
34 #include <openssl/param_build.h>
35 #include <openssl/encoder.h>
36 #include <openssl/core_names.h>
37 
38 #include "internal/numbers.h" /* includes SIZE_MAX */
39 #include "internal/ffc.h"
40 #include "crypto/evp.h"
41 #include "crypto/dh.h"
42 #include "crypto/dsa.h"
43 #include "crypto/ec.h"
44 #include "crypto/ecx.h"
45 #include "crypto/rsa.h"
46 #ifndef FIPS_MODULE
47 #include "crypto/asn1.h"
48 #include "crypto/x509.h"
49 #endif
50 #include "internal/provider.h"
51 #include "evp_local.h"
52 
53 static int pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str,
54     int len, EVP_KEYMGMT *keymgmt);
55 static void evp_pkey_free_it(EVP_PKEY *key);
56 
57 /* The type of parameters selected in key parameter functions */
58 #define SELECT_PARAMETERS OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
59 
60 #ifndef FIPS_MODULE
EVP_PKEY_get_bits(const EVP_PKEY * pkey)61 int EVP_PKEY_get_bits(const EVP_PKEY *pkey)
62 {
63     int size = 0;
64 
65     if (pkey != NULL) {
66         size = pkey->cache.bits;
67         if (pkey->ameth != NULL && pkey->ameth->pkey_bits != NULL)
68             size = pkey->ameth->pkey_bits(pkey);
69     }
70     if (size <= 0) {
71         ERR_raise(ERR_LIB_EVP, EVP_R_UNKNOWN_BITS);
72         return 0;
73     }
74     return size;
75 }
76 
EVP_PKEY_get_security_bits(const EVP_PKEY * pkey)77 int EVP_PKEY_get_security_bits(const EVP_PKEY *pkey)
78 {
79     int size = 0;
80 
81     if (pkey != NULL) {
82         size = pkey->cache.security_bits;
83         if (pkey->ameth != NULL && pkey->ameth->pkey_security_bits != NULL)
84             size = pkey->ameth->pkey_security_bits(pkey);
85     }
86     if (size <= 0) {
87         ERR_raise(ERR_LIB_EVP, EVP_R_UNKNOWN_SECURITY_BITS);
88         return 0;
89     }
90     return size;
91 }
92 
EVP_PKEY_save_parameters(EVP_PKEY * pkey,int mode)93 int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode)
94 {
95 #ifndef OPENSSL_NO_DSA
96     if (pkey->type == EVP_PKEY_DSA) {
97         int ret = pkey->save_parameters;
98 
99         if (mode >= 0)
100             pkey->save_parameters = mode;
101         return ret;
102     }
103 #endif
104 #ifndef OPENSSL_NO_EC
105     if (pkey->type == EVP_PKEY_EC) {
106         int ret = pkey->save_parameters;
107 
108         if (mode >= 0)
109             pkey->save_parameters = mode;
110         return ret;
111     }
112 #endif
113     return 0;
114 }
115 
EVP_PKEY_set_ex_data(EVP_PKEY * key,int idx,void * arg)116 int EVP_PKEY_set_ex_data(EVP_PKEY *key, int idx, void *arg)
117 {
118     return CRYPTO_set_ex_data(&key->ex_data, idx, arg);
119 }
120 
EVP_PKEY_get_ex_data(const EVP_PKEY * key,int idx)121 void *EVP_PKEY_get_ex_data(const EVP_PKEY *key, int idx)
122 {
123     return CRYPTO_get_ex_data(&key->ex_data, idx);
124 }
125 #endif /* !FIPS_MODULE */
126 
EVP_PKEY_copy_parameters(EVP_PKEY * to,const EVP_PKEY * from)127 int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
128 {
129     /*
130      * Clean up legacy stuff from this function when legacy support is gone.
131      */
132 
133     EVP_PKEY *downgraded_from = NULL;
134     int ok = 0;
135 
136 #ifndef FIPS_MODULE
137     /*
138      * If |to| is a legacy key and |from| isn't, we must make a downgraded
139      * copy of |from|.  If that fails, this function fails.
140      */
141     if (evp_pkey_is_legacy(to) && evp_pkey_is_provided(from)) {
142         if (!evp_pkey_copy_downgraded(&downgraded_from, from))
143             goto end;
144         from = downgraded_from;
145     }
146 #endif /* !FIPS_MODULE */
147 
148     /*
149      * Make sure |to| is typed.  Content is less important at this early
150      * stage.
151      *
152      * 1.  If |to| is untyped, assign |from|'s key type to it.
153      * 2.  If |to| contains a legacy key, compare its |type| to |from|'s.
154      *     (|from| was already downgraded above)
155      *
156      * If |to| is a provided key, there's nothing more to do here, functions
157      * like evp_keymgmt_util_copy() and evp_pkey_export_to_provider() called
158      * further down help us find out if they are the same or not.
159      */
160     if (evp_pkey_is_blank(to)) {
161 #ifndef FIPS_MODULE
162         if (evp_pkey_is_legacy(from)) {
163             if (EVP_PKEY_set_type(to, from->type) == 0)
164                 goto end;
165         } else
166 #endif /* !FIPS_MODULE */
167         {
168             if (EVP_PKEY_set_type_by_keymgmt(to, from->keymgmt) == 0)
169                 goto end;
170         }
171     }
172 #ifndef FIPS_MODULE
173     else if (evp_pkey_is_legacy(to)) {
174         if (to->type != from->type) {
175             ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES);
176             goto end;
177         }
178     }
179 #endif /* !FIPS_MODULE */
180 
181     if (EVP_PKEY_missing_parameters(from)) {
182         ERR_raise(ERR_LIB_EVP, EVP_R_MISSING_PARAMETERS);
183         goto end;
184     }
185 
186     if (!EVP_PKEY_missing_parameters(to)) {
187         if (EVP_PKEY_parameters_eq(to, from) == 1)
188             ok = 1;
189         else
190             ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_PARAMETERS);
191         goto end;
192     }
193 
194     /* For purely provided keys, we just call the keymgmt utility */
195     if (to->keymgmt != NULL && from->keymgmt != NULL) {
196         ok = evp_keymgmt_util_copy(to, (EVP_PKEY *)from, SELECT_PARAMETERS);
197         goto end;
198     }
199 
200 #ifndef FIPS_MODULE
201     /*
202      * If |to| is provided, we know that |from| is legacy at this point.
203      * Try exporting |from| to |to|'s keymgmt, then use evp_keymgmt_dup()
204      * to copy the appropriate data to |to|'s keydata.
205      * We cannot override existing data so do it only if there is no keydata
206      * in |to| yet.
207      */
208     if (to->keymgmt != NULL && to->keydata == NULL) {
209         EVP_KEYMGMT *to_keymgmt = to->keymgmt;
210         void *from_keydata = evp_pkey_export_to_provider((EVP_PKEY *)from, NULL, &to_keymgmt,
211             NULL);
212 
213         /*
214          * If we get a NULL, it could be an internal error, or it could be
215          * that there's a key mismatch.  We're pretending the latter...
216          */
217         if (from_keydata == NULL)
218             ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES);
219         else
220             ok = (to->keydata = evp_keymgmt_dup(to->keymgmt,
221                       from_keydata,
222                       SELECT_PARAMETERS))
223                 != NULL;
224         goto end;
225     }
226 
227     /* Both keys are legacy */
228     if (from->ameth != NULL && from->ameth->param_copy != NULL)
229         ok = from->ameth->param_copy(to, from);
230 #endif /* !FIPS_MODULE */
231 end:
232     EVP_PKEY_free(downgraded_from);
233     return ok;
234 }
235 
EVP_PKEY_missing_parameters(const EVP_PKEY * pkey)236 int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey)
237 {
238     if (pkey != NULL) {
239 #ifdef FIPS_MODULE
240         return !evp_keymgmt_util_has((EVP_PKEY *)pkey, SELECT_PARAMETERS);
241 #else
242         if (pkey->keymgmt != NULL)
243             return !evp_keymgmt_util_has((EVP_PKEY *)pkey, SELECT_PARAMETERS);
244         if (pkey->ameth != NULL && pkey->ameth->param_missing != NULL)
245             return pkey->ameth->param_missing(pkey);
246 #endif /* FIPS_MODULE */
247     }
248     return 0;
249 }
250 
251 /*
252  * This function is called for any mixture of keys except pure legacy pair.
253  * When legacy keys are gone, we replace a call to this functions with
254  * a call to evp_keymgmt_util_match().
255  */
evp_pkey_cmp_any(const EVP_PKEY * a,const EVP_PKEY * b,int selection)256 static int evp_pkey_cmp_any(const EVP_PKEY *a, const EVP_PKEY *b,
257     int selection)
258 {
259 #ifdef FIPS_MODULE
260     return evp_keymgmt_util_match((EVP_PKEY *)a, (EVP_PKEY *)b, selection);
261 #else
262     EVP_KEYMGMT *keymgmt1 = NULL, *keymgmt2 = NULL;
263     void *keydata1 = NULL, *keydata2 = NULL, *tmp_keydata = NULL;
264 
265     /* If none of them are provided, this function shouldn't have been called */
266     if (!ossl_assert(evp_pkey_is_provided(a) || evp_pkey_is_provided(b)))
267         return -2;
268 
269     /* For purely provided keys, we just call the keymgmt utility */
270     if (evp_pkey_is_provided(a) && evp_pkey_is_provided(b))
271         return evp_keymgmt_util_match((EVP_PKEY *)a, (EVP_PKEY *)b, selection);
272 
273     /*
274      * At this point, one of them is provided, the other not.  This allows
275      * us to compare types using legacy NIDs.
276      */
277     if (evp_pkey_is_legacy(a)
278         && !EVP_KEYMGMT_is_a(b->keymgmt, OBJ_nid2sn(a->type)))
279         return -1; /* not the same key type */
280     if (evp_pkey_is_legacy(b)
281         && !EVP_KEYMGMT_is_a(a->keymgmt, OBJ_nid2sn(b->type)))
282         return -1; /* not the same key type */
283 
284     /*
285      * We've determined that they both are the same keytype, so the next
286      * step is to do a bit of cross export to ensure we have keydata for
287      * both keys in the same keymgmt.
288      */
289     keymgmt1 = a->keymgmt;
290     keydata1 = a->keydata;
291     keymgmt2 = b->keymgmt;
292     keydata2 = b->keydata;
293 
294     if (keymgmt2 != NULL && keymgmt2->match != NULL) {
295         tmp_keydata = evp_pkey_export_to_provider((EVP_PKEY *)a, NULL, &keymgmt2, NULL);
296         if (tmp_keydata != NULL) {
297             keymgmt1 = keymgmt2;
298             keydata1 = tmp_keydata;
299         }
300     }
301     if (tmp_keydata == NULL && keymgmt1 != NULL && keymgmt1->match != NULL) {
302         tmp_keydata = evp_pkey_export_to_provider((EVP_PKEY *)b, NULL, &keymgmt1, NULL);
303         if (tmp_keydata != NULL) {
304             keymgmt2 = keymgmt1;
305             keydata2 = tmp_keydata;
306         }
307     }
308 
309     /* If we still don't have matching keymgmt implementations, we give up */
310     if (keymgmt1 != keymgmt2)
311         return -2;
312 
313     /* If the keymgmt implementations are NULL, the export failed */
314     if (keymgmt1 == NULL)
315         return -2;
316 
317     return evp_keymgmt_match(keymgmt1, keydata1, keydata2, selection);
318 #endif /* FIPS_MODULE */
319 }
320 
321 #ifndef FIPS_MODULE
322 #ifndef OPENSSL_NO_DEPRECATED_3_0
EVP_PKEY_cmp_parameters(const EVP_PKEY * a,const EVP_PKEY * b)323 int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
324 {
325     return EVP_PKEY_parameters_eq(a, b);
326 }
327 #endif
328 #endif /* FIPS_MODULE */
329 
EVP_PKEY_parameters_eq(const EVP_PKEY * a,const EVP_PKEY * b)330 int EVP_PKEY_parameters_eq(const EVP_PKEY *a, const EVP_PKEY *b)
331 {
332 #ifdef FIPS_MODULE
333     return evp_pkey_cmp_any(a, b, SELECT_PARAMETERS);
334 #else
335     /*
336      * This will just call evp_keymgmt_util_match when legacy support
337      * is gone.
338      */
339 
340     if (a->keymgmt != NULL || b->keymgmt != NULL)
341         return evp_pkey_cmp_any(a, b, SELECT_PARAMETERS);
342 
343     /* All legacy keys */
344     if (a->type != b->type)
345         return -1;
346     if (a->ameth != NULL && a->ameth->param_cmp != NULL)
347         return a->ameth->param_cmp(a, b);
348     return -2;
349 #endif /* !FIPS_MODULE */
350 }
351 
352 #ifndef FIPS_MODULE
353 #ifndef OPENSSL_NO_DEPRECATED_3_0
EVP_PKEY_cmp(const EVP_PKEY * a,const EVP_PKEY * b)354 int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
355 {
356     return EVP_PKEY_eq(a, b);
357 }
358 #endif
359 #endif /* !FIPS_MODULE */
360 
EVP_PKEY_eq(const EVP_PKEY * a,const EVP_PKEY * b)361 int EVP_PKEY_eq(const EVP_PKEY *a, const EVP_PKEY *b)
362 {
363     /*
364      * This will just call evp_keymgmt_util_match when legacy support
365      * is gone.
366      */
367 
368     /* Trivial shortcuts */
369     if (a == b)
370         return 1;
371     if (a == NULL || b == NULL)
372         return 0;
373 
374 #ifndef FIPS_MODULE
375     if (a->keymgmt != NULL || b->keymgmt != NULL)
376 #endif /* !FIPS_MODULE */
377     {
378         int selection = SELECT_PARAMETERS;
379 
380         if (evp_keymgmt_util_has((EVP_PKEY *)a, OSSL_KEYMGMT_SELECT_PUBLIC_KEY)
381             && evp_keymgmt_util_has((EVP_PKEY *)b, OSSL_KEYMGMT_SELECT_PUBLIC_KEY))
382             selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
383         else
384             selection |= OSSL_KEYMGMT_SELECT_KEYPAIR;
385         return evp_pkey_cmp_any(a, b, selection);
386     }
387 
388 #ifndef FIPS_MODULE
389     /* All legacy keys */
390     if (a->type != b->type)
391         return -1;
392 
393     if (a->ameth != NULL) {
394         int ret;
395         /* Compare parameters if the algorithm has them */
396         if (a->ameth->param_cmp != NULL) {
397             ret = a->ameth->param_cmp(a, b);
398             if (ret <= 0)
399                 return ret;
400         }
401 
402         if (a->ameth->pub_cmp != NULL)
403             return a->ameth->pub_cmp(a, b);
404     }
405 
406     return -2;
407 #endif /* !FIPS_MODULE */
408 }
409 
410 #ifndef FIPS_MODULE
new_raw_key_int(OSSL_LIB_CTX * libctx,const char * strtype,const char * propq,int nidtype,ENGINE * e,const unsigned char * key,size_t len,int key_is_priv)411 static EVP_PKEY *new_raw_key_int(OSSL_LIB_CTX *libctx,
412     const char *strtype,
413     const char *propq,
414     int nidtype,
415     ENGINE *e,
416     const unsigned char *key,
417     size_t len,
418     int key_is_priv)
419 {
420     EVP_PKEY *pkey = NULL;
421     EVP_PKEY_CTX *ctx = NULL;
422     const EVP_PKEY_ASN1_METHOD *ameth = NULL;
423     int result = 0;
424 
425 #ifndef OPENSSL_NO_ENGINE
426     /* Check if there is an Engine for this type */
427     if (e == NULL) {
428         ENGINE *tmpe = NULL;
429 
430         if (strtype != NULL)
431             ameth = EVP_PKEY_asn1_find_str(&tmpe, strtype, -1);
432         else if (nidtype != EVP_PKEY_NONE)
433             ameth = EVP_PKEY_asn1_find(&tmpe, nidtype);
434 
435         /* If tmpe is NULL then no engine is claiming to support this type */
436         if (tmpe == NULL)
437             ameth = NULL;
438 
439         ENGINE_finish(tmpe);
440     }
441 #endif
442 
443     if (e == NULL && ameth == NULL) {
444         /*
445          * No engine is claiming to support this type, so lets see if we have
446          * a provider.
447          */
448         ctx = EVP_PKEY_CTX_new_from_name(libctx,
449             strtype != NULL ? strtype
450                             : OBJ_nid2sn(nidtype),
451             propq);
452         if (ctx == NULL)
453             goto err;
454         /* May fail if no provider available */
455         ERR_set_mark();
456         if (EVP_PKEY_fromdata_init(ctx) == 1) {
457             OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
458 
459             ERR_clear_last_mark();
460             params[0] = OSSL_PARAM_construct_octet_string(
461                 key_is_priv ? OSSL_PKEY_PARAM_PRIV_KEY
462                             : OSSL_PKEY_PARAM_PUB_KEY,
463                 (void *)key, len);
464 
465             if (EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_KEYPAIR, params) != 1) {
466                 ERR_raise(ERR_LIB_EVP, EVP_R_KEY_SETUP_FAILED);
467                 goto err;
468             }
469 
470             EVP_PKEY_CTX_free(ctx);
471 
472             return pkey;
473         }
474         ERR_pop_to_mark();
475         /* else not supported so fallback to legacy */
476     }
477 
478     /* Legacy code path */
479 
480     pkey = EVP_PKEY_new();
481     if (pkey == NULL) {
482         ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB);
483         goto err;
484     }
485 
486     if (!pkey_set_type(pkey, e, nidtype, strtype, -1, NULL)) {
487         /* ERR_raise(ERR_LIB_EVP, ...) already called */
488         goto err;
489     }
490 
491     if (!ossl_assert(pkey->ameth != NULL))
492         goto err;
493 
494     if (key_is_priv) {
495         if (pkey->ameth->set_priv_key == NULL) {
496             ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
497             goto err;
498         }
499 
500         if (!pkey->ameth->set_priv_key(pkey, key, len)) {
501             ERR_raise(ERR_LIB_EVP, EVP_R_KEY_SETUP_FAILED);
502             goto err;
503         }
504     } else {
505         if (pkey->ameth->set_pub_key == NULL) {
506             ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
507             goto err;
508         }
509 
510         if (!pkey->ameth->set_pub_key(pkey, key, len)) {
511             ERR_raise(ERR_LIB_EVP, EVP_R_KEY_SETUP_FAILED);
512             goto err;
513         }
514     }
515 
516     result = 1;
517 err:
518     if (!result) {
519         EVP_PKEY_free(pkey);
520         pkey = NULL;
521     }
522     EVP_PKEY_CTX_free(ctx);
523     return pkey;
524 }
525 
EVP_PKEY_new_raw_private_key_ex(OSSL_LIB_CTX * libctx,const char * keytype,const char * propq,const unsigned char * priv,size_t len)526 EVP_PKEY *EVP_PKEY_new_raw_private_key_ex(OSSL_LIB_CTX *libctx,
527     const char *keytype,
528     const char *propq,
529     const unsigned char *priv, size_t len)
530 {
531     return new_raw_key_int(libctx, keytype, propq, EVP_PKEY_NONE, NULL, priv,
532         len, 1);
533 }
534 
EVP_PKEY_new_raw_private_key(int type,ENGINE * e,const unsigned char * priv,size_t len)535 EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *e,
536     const unsigned char *priv,
537     size_t len)
538 {
539     return new_raw_key_int(NULL, NULL, NULL, type, e, priv, len, 1);
540 }
541 
EVP_PKEY_new_raw_public_key_ex(OSSL_LIB_CTX * libctx,const char * keytype,const char * propq,const unsigned char * pub,size_t len)542 EVP_PKEY *EVP_PKEY_new_raw_public_key_ex(OSSL_LIB_CTX *libctx,
543     const char *keytype, const char *propq,
544     const unsigned char *pub, size_t len)
545 {
546     return new_raw_key_int(libctx, keytype, propq, EVP_PKEY_NONE, NULL, pub,
547         len, 0);
548 }
549 
EVP_PKEY_new_raw_public_key(int type,ENGINE * e,const unsigned char * pub,size_t len)550 EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *e,
551     const unsigned char *pub,
552     size_t len)
553 {
554     return new_raw_key_int(NULL, NULL, NULL, type, e, pub, len, 0);
555 }
556 
557 struct raw_key_details_st {
558     unsigned char **key;
559     size_t *len;
560     int selection;
561 };
562 
563 static OSSL_CALLBACK get_raw_key_details;
get_raw_key_details(const OSSL_PARAM params[],void * arg)564 static int get_raw_key_details(const OSSL_PARAM params[], void *arg)
565 {
566     const OSSL_PARAM *p = NULL;
567     struct raw_key_details_st *raw_key = arg;
568 
569     if (raw_key->selection == OSSL_KEYMGMT_SELECT_PRIVATE_KEY) {
570         if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY))
571             != NULL)
572             return OSSL_PARAM_get_octet_string(p, (void **)raw_key->key,
573                 raw_key->key == NULL ? 0 : *raw_key->len,
574                 raw_key->len);
575     } else if (raw_key->selection == OSSL_KEYMGMT_SELECT_PUBLIC_KEY) {
576         if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY))
577             != NULL)
578             return OSSL_PARAM_get_octet_string(p, (void **)raw_key->key,
579                 raw_key->key == NULL ? 0 : *raw_key->len,
580                 raw_key->len);
581     }
582 
583     return 0;
584 }
585 
EVP_PKEY_get_raw_private_key(const EVP_PKEY * pkey,unsigned char * priv,size_t * len)586 int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, unsigned char *priv,
587     size_t *len)
588 {
589     if (pkey->keymgmt != NULL) {
590         struct raw_key_details_st raw_key;
591 
592         raw_key.key = priv == NULL ? NULL : &priv;
593         raw_key.len = len;
594         raw_key.selection = OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
595 
596         return evp_keymgmt_util_export(pkey, OSSL_KEYMGMT_SELECT_PRIVATE_KEY,
597             get_raw_key_details, &raw_key);
598     }
599 
600     if (pkey->ameth == NULL) {
601         ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
602         return 0;
603     }
604 
605     if (pkey->ameth->get_priv_key == NULL) {
606         ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
607         return 0;
608     }
609 
610     if (!pkey->ameth->get_priv_key(pkey, priv, len)) {
611         ERR_raise(ERR_LIB_EVP, EVP_R_GET_RAW_KEY_FAILED);
612         return 0;
613     }
614 
615     return 1;
616 }
617 
EVP_PKEY_get_raw_public_key(const EVP_PKEY * pkey,unsigned char * pub,size_t * len)618 int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub,
619     size_t *len)
620 {
621     if (pkey->keymgmt != NULL) {
622         struct raw_key_details_st raw_key;
623 
624         raw_key.key = pub == NULL ? NULL : &pub;
625         raw_key.len = len;
626         raw_key.selection = OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
627 
628         return evp_keymgmt_util_export(pkey, OSSL_KEYMGMT_SELECT_PUBLIC_KEY,
629             get_raw_key_details, &raw_key);
630     }
631 
632     if (pkey->ameth == NULL) {
633         ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
634         return 0;
635     }
636 
637     if (pkey->ameth->get_pub_key == NULL) {
638         ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
639         return 0;
640     }
641 
642     if (!pkey->ameth->get_pub_key(pkey, pub, len)) {
643         ERR_raise(ERR_LIB_EVP, EVP_R_GET_RAW_KEY_FAILED);
644         return 0;
645     }
646 
647     return 1;
648 }
649 
new_cmac_key_int(const unsigned char * priv,size_t len,const char * cipher_name,const EVP_CIPHER * cipher,OSSL_LIB_CTX * libctx,const char * propq,ENGINE * e)650 static EVP_PKEY *new_cmac_key_int(const unsigned char *priv, size_t len,
651     const char *cipher_name,
652     const EVP_CIPHER *cipher,
653     OSSL_LIB_CTX *libctx,
654     const char *propq, ENGINE *e)
655 {
656 #ifndef OPENSSL_NO_CMAC
657 #ifndef OPENSSL_NO_ENGINE
658     const char *engine_id = e != NULL ? ENGINE_get_id(e) : NULL;
659 #endif
660     OSSL_PARAM params[5], *p = params;
661     EVP_PKEY *pkey = NULL;
662     EVP_PKEY_CTX *ctx;
663 
664     if (cipher != NULL)
665         cipher_name = EVP_CIPHER_get0_name(cipher);
666 
667     if (cipher_name == NULL) {
668         ERR_raise(ERR_LIB_EVP, EVP_R_KEY_SETUP_FAILED);
669         return NULL;
670     }
671 
672     ctx = EVP_PKEY_CTX_new_from_name(libctx, "CMAC", propq);
673     if (ctx == NULL)
674         goto err;
675 
676     if (EVP_PKEY_fromdata_init(ctx) <= 0) {
677         ERR_raise(ERR_LIB_EVP, EVP_R_KEY_SETUP_FAILED);
678         goto err;
679     }
680 
681     *p++ = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PRIV_KEY,
682         (void *)priv, len);
683     *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_CIPHER,
684         (char *)cipher_name, 0);
685     if (propq != NULL)
686         *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_PROPERTIES,
687             (char *)propq, 0);
688 #ifndef OPENSSL_NO_ENGINE
689     if (engine_id != NULL)
690         *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_ENGINE,
691             (char *)engine_id, 0);
692 #endif
693     *p = OSSL_PARAM_construct_end();
694 
695     if (EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0) {
696         ERR_raise(ERR_LIB_EVP, EVP_R_KEY_SETUP_FAILED);
697         goto err;
698     }
699 
700 err:
701     EVP_PKEY_CTX_free(ctx);
702 
703     return pkey;
704 #else
705     ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
706     return NULL;
707 #endif
708 }
709 
EVP_PKEY_new_CMAC_key(ENGINE * e,const unsigned char * priv,size_t len,const EVP_CIPHER * cipher)710 EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
711     size_t len, const EVP_CIPHER *cipher)
712 {
713     return new_cmac_key_int(priv, len, NULL, cipher, NULL, NULL, e);
714 }
715 
EVP_PKEY_set_type(EVP_PKEY * pkey,int type)716 int EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
717 {
718     return pkey_set_type(pkey, NULL, type, NULL, -1, NULL);
719 }
720 
EVP_PKEY_set_type_str(EVP_PKEY * pkey,const char * str,int len)721 int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len)
722 {
723     return pkey_set_type(pkey, NULL, EVP_PKEY_NONE, str, len, NULL);
724 }
725 
726 #ifndef OPENSSL_NO_ENGINE
EVP_PKEY_set1_engine(EVP_PKEY * pkey,ENGINE * e)727 int EVP_PKEY_set1_engine(EVP_PKEY *pkey, ENGINE *e)
728 {
729     if (e != NULL) {
730         if (!ENGINE_init(e)) {
731             ERR_raise(ERR_LIB_EVP, ERR_R_ENGINE_LIB);
732             return 0;
733         }
734         if (ENGINE_get_pkey_meth(e, pkey->type) == NULL) {
735             ENGINE_finish(e);
736             ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_ALGORITHM);
737             return 0;
738         }
739     }
740     ENGINE_finish(pkey->pmeth_engine);
741     pkey->pmeth_engine = e;
742     return 1;
743 }
744 
EVP_PKEY_get0_engine(const EVP_PKEY * pkey)745 ENGINE *EVP_PKEY_get0_engine(const EVP_PKEY *pkey)
746 {
747     return pkey->engine;
748 }
749 #endif
750 
751 #ifndef OPENSSL_NO_DEPRECATED_3_0
detect_foreign_key(EVP_PKEY * pkey)752 static void detect_foreign_key(EVP_PKEY *pkey)
753 {
754     switch (pkey->type) {
755     case EVP_PKEY_RSA:
756     case EVP_PKEY_RSA_PSS:
757         pkey->foreign = pkey->pkey.rsa != NULL
758             && ossl_rsa_is_foreign(pkey->pkey.rsa);
759         break;
760 #ifndef OPENSSL_NO_EC
761     case EVP_PKEY_SM2:
762         break;
763     case EVP_PKEY_EC:
764         pkey->foreign = pkey->pkey.ec != NULL
765             && ossl_ec_key_is_foreign(pkey->pkey.ec);
766         break;
767 #endif
768 #ifndef OPENSSL_NO_DSA
769     case EVP_PKEY_DSA:
770         pkey->foreign = pkey->pkey.dsa != NULL
771             && ossl_dsa_is_foreign(pkey->pkey.dsa);
772         break;
773 #endif
774 #ifndef OPENSSL_NO_DH
775     case EVP_PKEY_DH:
776         pkey->foreign = pkey->pkey.dh != NULL
777             && ossl_dh_is_foreign(pkey->pkey.dh);
778         break;
779 #endif
780     default:
781         pkey->foreign = 0;
782         break;
783     }
784 }
785 
EVP_PKEY_assign(EVP_PKEY * pkey,int type,void * key)786 int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
787 {
788 #ifndef OPENSSL_NO_EC
789     int pktype;
790 
791     pktype = EVP_PKEY_type(type);
792     if ((key != NULL) && (pktype == EVP_PKEY_EC || pktype == EVP_PKEY_SM2)) {
793         const EC_GROUP *group = EC_KEY_get0_group(key);
794 
795         if (group != NULL) {
796             int curve = EC_GROUP_get_curve_name(group);
797 
798             /*
799              * Regardless of what is requested the SM2 curve must be SM2 type,
800              * and non SM2 curves are EC type.
801              */
802             if (curve == NID_sm2 && pktype == EVP_PKEY_EC)
803                 type = EVP_PKEY_SM2;
804             else if (curve != NID_sm2 && pktype == EVP_PKEY_SM2)
805                 type = EVP_PKEY_EC;
806         }
807     }
808 #endif
809 
810     if (pkey == NULL || !EVP_PKEY_set_type(pkey, type))
811         return 0;
812 
813     pkey->pkey.ptr = key;
814     detect_foreign_key(pkey);
815 
816     return (key != NULL);
817 }
818 #endif
819 
EVP_PKEY_get0(const EVP_PKEY * pkey)820 void *EVP_PKEY_get0(const EVP_PKEY *pkey)
821 {
822     if (pkey == NULL)
823         return NULL;
824 
825     if (!evp_pkey_is_provided(pkey))
826         return pkey->pkey.ptr;
827 
828     return NULL;
829 }
830 
EVP_PKEY_get0_hmac(const EVP_PKEY * pkey,size_t * len)831 const unsigned char *EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len)
832 {
833     const ASN1_OCTET_STRING *os = NULL;
834     if (pkey->type != EVP_PKEY_HMAC) {
835         ERR_raise(ERR_LIB_EVP, EVP_R_EXPECTING_AN_HMAC_KEY);
836         return NULL;
837     }
838     os = evp_pkey_get_legacy((EVP_PKEY *)pkey);
839     if (os != NULL) {
840         *len = os->length;
841         return os->data;
842     }
843     return NULL;
844 }
845 
846 #ifndef OPENSSL_NO_POLY1305
EVP_PKEY_get0_poly1305(const EVP_PKEY * pkey,size_t * len)847 const unsigned char *EVP_PKEY_get0_poly1305(const EVP_PKEY *pkey, size_t *len)
848 {
849     const ASN1_OCTET_STRING *os = NULL;
850     if (pkey->type != EVP_PKEY_POLY1305) {
851         ERR_raise(ERR_LIB_EVP, EVP_R_EXPECTING_A_POLY1305_KEY);
852         return NULL;
853     }
854     os = evp_pkey_get_legacy((EVP_PKEY *)pkey);
855     if (os != NULL) {
856         *len = os->length;
857         return os->data;
858     }
859     return NULL;
860 }
861 #endif
862 
863 #ifndef OPENSSL_NO_SIPHASH
EVP_PKEY_get0_siphash(const EVP_PKEY * pkey,size_t * len)864 const unsigned char *EVP_PKEY_get0_siphash(const EVP_PKEY *pkey, size_t *len)
865 {
866     const ASN1_OCTET_STRING *os = NULL;
867 
868     if (pkey->type != EVP_PKEY_SIPHASH) {
869         ERR_raise(ERR_LIB_EVP, EVP_R_EXPECTING_A_SIPHASH_KEY);
870         return NULL;
871     }
872     os = evp_pkey_get_legacy((EVP_PKEY *)pkey);
873     if (os != NULL) {
874         *len = os->length;
875         return os->data;
876     }
877     return NULL;
878 }
879 #endif
880 
881 #ifndef OPENSSL_NO_DSA
evp_pkey_get0_DSA_int(const EVP_PKEY * pkey)882 static DSA *evp_pkey_get0_DSA_int(const EVP_PKEY *pkey)
883 {
884     if (pkey->type != EVP_PKEY_DSA) {
885         ERR_raise(ERR_LIB_EVP, EVP_R_EXPECTING_A_DSA_KEY);
886         return NULL;
887     }
888     return evp_pkey_get_legacy((EVP_PKEY *)pkey);
889 }
890 
EVP_PKEY_get0_DSA(const EVP_PKEY * pkey)891 const DSA *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey)
892 {
893     return evp_pkey_get0_DSA_int(pkey);
894 }
895 
EVP_PKEY_set1_DSA(EVP_PKEY * pkey,DSA * key)896 int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
897 {
898     int ret;
899 
900     if (!DSA_up_ref(key))
901         return 0;
902 
903     ret = EVP_PKEY_assign_DSA(pkey, key);
904 
905     if (!ret)
906         DSA_free(key);
907 
908     return ret;
909 }
EVP_PKEY_get1_DSA(EVP_PKEY * pkey)910 DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey)
911 {
912     DSA *ret = evp_pkey_get0_DSA_int(pkey);
913 
914     if (ret != NULL && !DSA_up_ref(ret))
915         return NULL;
916 
917     return ret;
918 }
919 #endif /*  OPENSSL_NO_DSA */
920 
921 #ifndef OPENSSL_NO_ECX
evp_pkey_get0_ECX_KEY(const EVP_PKEY * pkey,int type)922 static const ECX_KEY *evp_pkey_get0_ECX_KEY(const EVP_PKEY *pkey, int type)
923 {
924     if (EVP_PKEY_get_base_id(pkey) != type) {
925         ERR_raise(ERR_LIB_EVP, EVP_R_EXPECTING_A_ECX_KEY);
926         return NULL;
927     }
928     return evp_pkey_get_legacy((EVP_PKEY *)pkey);
929 }
930 
evp_pkey_get1_ECX_KEY(EVP_PKEY * pkey,int type)931 static ECX_KEY *evp_pkey_get1_ECX_KEY(EVP_PKEY *pkey, int type)
932 {
933     ECX_KEY *ret = (ECX_KEY *)evp_pkey_get0_ECX_KEY(pkey, type);
934 
935     if (ret != NULL && !ossl_ecx_key_up_ref(ret))
936         ret = NULL;
937     return ret;
938 }
939 
940 #define IMPLEMENT_ECX_VARIANT(NAME)                          \
941     ECX_KEY *ossl_evp_pkey_get1_##NAME(EVP_PKEY *pkey)       \
942     {                                                        \
943         return evp_pkey_get1_ECX_KEY(pkey, EVP_PKEY_##NAME); \
944     }
945 IMPLEMENT_ECX_VARIANT(X25519)
IMPLEMENT_ECX_VARIANT(X448)946 IMPLEMENT_ECX_VARIANT(X448)
947 IMPLEMENT_ECX_VARIANT(ED25519)
948 IMPLEMENT_ECX_VARIANT(ED448)
949 
950 #endif /* OPENSSL_NO_ECX */
951 
952 #if !defined(OPENSSL_NO_DH) && !defined(OPENSSL_NO_DEPRECATED_3_0)
953 
954 int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *dhkey)
955 {
956     int ret, type;
957 
958     /*
959      * ossl_dh_is_named_safe_prime_group() returns 1 for named safe prime groups
960      * related to ffdhe and modp (which cache q = (p - 1) / 2),
961      * and returns 0 for all other dh parameter generation types including
962      * RFC5114 named groups.
963      *
964      * The EVP_PKEY_DH type is used for dh parameter generation types:
965      *  - named safe prime groups related to ffdhe and modp
966      *  - safe prime generator
967      *
968      * The type EVP_PKEY_DHX is used for dh parameter generation types
969      *  - fips186-4 and fips186-2
970      *  - rfc5114 named groups.
971      *
972      * The EVP_PKEY_DH type is used to save PKCS#3 data than can be stored
973      * without a q value.
974      * The EVP_PKEY_DHX type is used to save X9.42 data that requires the
975      * q value to be stored.
976      */
977     if (ossl_dh_is_named_safe_prime_group(dhkey))
978         type = EVP_PKEY_DH;
979     else
980         type = DH_get0_q(dhkey) == NULL ? EVP_PKEY_DH : EVP_PKEY_DHX;
981 
982     if (!DH_up_ref(dhkey))
983         return 0;
984 
985     ret = EVP_PKEY_assign(pkey, type, dhkey);
986 
987     if (!ret)
988         DH_free(dhkey);
989 
990     return ret;
991 }
992 
evp_pkey_get0_DH_int(const EVP_PKEY * pkey)993 DH *evp_pkey_get0_DH_int(const EVP_PKEY *pkey)
994 {
995     if (pkey->type != EVP_PKEY_DH && pkey->type != EVP_PKEY_DHX) {
996         ERR_raise(ERR_LIB_EVP, EVP_R_EXPECTING_A_DH_KEY);
997         return NULL;
998     }
999     return evp_pkey_get_legacy((EVP_PKEY *)pkey);
1000 }
1001 
EVP_PKEY_get0_DH(const EVP_PKEY * pkey)1002 const DH *EVP_PKEY_get0_DH(const EVP_PKEY *pkey)
1003 {
1004     return evp_pkey_get0_DH_int(pkey);
1005 }
1006 
EVP_PKEY_get1_DH(EVP_PKEY * pkey)1007 DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey)
1008 {
1009     DH *ret = evp_pkey_get0_DH_int(pkey);
1010 
1011     if (ret != NULL && !DH_up_ref(ret))
1012         ret = NULL;
1013 
1014     return ret;
1015 }
1016 #endif
1017 
EVP_PKEY_type(int type)1018 int EVP_PKEY_type(int type)
1019 {
1020     int ret;
1021     const EVP_PKEY_ASN1_METHOD *ameth;
1022     ENGINE *e;
1023     ameth = EVP_PKEY_asn1_find(&e, type);
1024     if (ameth)
1025         ret = ameth->pkey_id;
1026     else
1027         ret = NID_undef;
1028 #ifndef OPENSSL_NO_ENGINE
1029     ENGINE_finish(e);
1030 #endif
1031     return ret;
1032 }
1033 
EVP_PKEY_get_id(const EVP_PKEY * pkey)1034 int EVP_PKEY_get_id(const EVP_PKEY *pkey)
1035 {
1036     return pkey->type;
1037 }
1038 
EVP_PKEY_get_base_id(const EVP_PKEY * pkey)1039 int EVP_PKEY_get_base_id(const EVP_PKEY *pkey)
1040 {
1041     return EVP_PKEY_type(pkey->type);
1042 }
1043 
1044 /*
1045  * These hard coded cases are pure hackery to get around the fact
1046  * that names in crypto/objects/objects.txt are a mess.  There is
1047  * no "EC", and "RSA" leads to the NID for 2.5.8.1.1, an OID that's
1048  * fallen out in favor of { pkcs-1 1 }, i.e. 1.2.840.113549.1.1.1,
1049  * the NID of which is used for EVP_PKEY_RSA.  Strangely enough,
1050  * "DSA" is accurate...  but still, better be safe and hard-code
1051  * names that we know.
1052  * On a similar topic, EVP_PKEY_type(EVP_PKEY_SM2) will result in
1053  * EVP_PKEY_EC, because of aliasing.
1054  * This should be cleaned away along with all other #legacy support.
1055  */
1056 static const OSSL_ITEM standard_name2type[] = {
1057     { EVP_PKEY_RSA, "RSA" },
1058     { EVP_PKEY_RSA_PSS, "RSA-PSS" },
1059     { EVP_PKEY_EC, "EC" },
1060     { EVP_PKEY_ED25519, "ED25519" },
1061     { EVP_PKEY_ED448, "ED448" },
1062     { EVP_PKEY_X25519, "X25519" },
1063     { EVP_PKEY_X448, "X448" },
1064     { EVP_PKEY_SM2, "SM2" },
1065     { EVP_PKEY_DH, "DH" },
1066     { EVP_PKEY_DHX, "X9.42 DH" },
1067     { EVP_PKEY_DHX, "DHX" },
1068     { EVP_PKEY_DSA, "DSA" },
1069 };
1070 
evp_pkey_name2type(const char * name)1071 int evp_pkey_name2type(const char *name)
1072 {
1073     int type;
1074     size_t i;
1075 
1076     for (i = 0; i < OSSL_NELEM(standard_name2type); i++) {
1077         if (OPENSSL_strcasecmp(name, standard_name2type[i].ptr) == 0)
1078             return (int)standard_name2type[i].id;
1079     }
1080 
1081     if ((type = EVP_PKEY_type(OBJ_sn2nid(name))) != NID_undef)
1082         return type;
1083     return EVP_PKEY_type(OBJ_ln2nid(name));
1084 }
1085 
evp_pkey_type2name(int type)1086 const char *evp_pkey_type2name(int type)
1087 {
1088     size_t i;
1089 
1090     for (i = 0; i < OSSL_NELEM(standard_name2type); i++) {
1091         if (type == (int)standard_name2type[i].id)
1092             return standard_name2type[i].ptr;
1093     }
1094 
1095     return OBJ_nid2sn(type);
1096 }
1097 
EVP_PKEY_is_a(const EVP_PKEY * pkey,const char * name)1098 int EVP_PKEY_is_a(const EVP_PKEY *pkey, const char *name)
1099 {
1100     if (pkey == NULL)
1101         return 0;
1102     if (pkey->keymgmt == NULL)
1103         return pkey->type == evp_pkey_name2type(name);
1104     return EVP_KEYMGMT_is_a(pkey->keymgmt, name);
1105 }
1106 
EVP_PKEY_type_names_do_all(const EVP_PKEY * pkey,void (* fn)(const char * name,void * data),void * data)1107 int EVP_PKEY_type_names_do_all(const EVP_PKEY *pkey,
1108     void (*fn)(const char *name, void *data),
1109     void *data)
1110 {
1111     if (!evp_pkey_is_typed(pkey))
1112         return 0;
1113 
1114     if (!evp_pkey_is_provided(pkey)) {
1115         const char *name = OBJ_nid2sn(EVP_PKEY_get_id(pkey));
1116 
1117         fn(name, data);
1118         return 1;
1119     }
1120     return EVP_KEYMGMT_names_do_all(pkey->keymgmt, fn, data);
1121 }
1122 
EVP_PKEY_can_sign(const EVP_PKEY * pkey)1123 int EVP_PKEY_can_sign(const EVP_PKEY *pkey)
1124 {
1125     if (pkey->keymgmt == NULL) {
1126         switch (EVP_PKEY_get_base_id(pkey)) {
1127         case EVP_PKEY_RSA:
1128         case EVP_PKEY_RSA_PSS:
1129             return 1;
1130 #ifndef OPENSSL_NO_DSA
1131         case EVP_PKEY_DSA:
1132             return 1;
1133 #endif
1134 #ifndef OPENSSL_NO_EC
1135         case EVP_PKEY_ED25519:
1136         case EVP_PKEY_ED448:
1137             return 1;
1138         case EVP_PKEY_EC: /* Including SM2 */
1139             return EC_KEY_can_sign(pkey->pkey.ec);
1140 #endif
1141         default:
1142             break;
1143         }
1144     } else {
1145         const OSSL_PROVIDER *prov = EVP_KEYMGMT_get0_provider(pkey->keymgmt);
1146         OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov);
1147         EVP_SIGNATURE *sig;
1148         const char *name;
1149 
1150         name = evp_keymgmt_util_query_operation_name(pkey->keymgmt,
1151             OSSL_OP_SIGNATURE);
1152         sig = EVP_SIGNATURE_fetch(libctx, name, NULL);
1153         if (sig != NULL) {
1154             EVP_SIGNATURE_free(sig);
1155             return 1;
1156         }
1157     }
1158     return 0;
1159 }
1160 
print_reset_indent(BIO ** out,int pop_f_prefix,long saved_indent)1161 static int print_reset_indent(BIO **out, int pop_f_prefix, long saved_indent)
1162 {
1163     BIO_set_indent(*out, saved_indent);
1164     if (pop_f_prefix) {
1165         BIO *next = BIO_pop(*out);
1166 
1167         BIO_free(*out);
1168         *out = next;
1169     }
1170     return 1;
1171 }
1172 
print_set_indent(BIO ** out,int * pop_f_prefix,long * saved_indent,long indent)1173 static int print_set_indent(BIO **out, int *pop_f_prefix, long *saved_indent,
1174     long indent)
1175 {
1176     *pop_f_prefix = 0;
1177     *saved_indent = 0;
1178     if (indent > 0) {
1179         long i = BIO_get_indent(*out);
1180 
1181         *saved_indent = (i < 0 ? 0 : i);
1182         if (BIO_set_indent(*out, indent) <= 0) {
1183             BIO *prefbio = BIO_new(BIO_f_prefix());
1184 
1185             if (prefbio == NULL)
1186                 return 0;
1187             *out = BIO_push(prefbio, *out);
1188             *pop_f_prefix = 1;
1189         }
1190         if (BIO_set_indent(*out, indent) <= 0) {
1191             print_reset_indent(out, *pop_f_prefix, *saved_indent);
1192             return 0;
1193         }
1194     }
1195     return 1;
1196 }
1197 
unsup_alg(BIO * out,const EVP_PKEY * pkey,int indent,const char * kstr)1198 static int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent,
1199     const char *kstr)
1200 {
1201     return BIO_indent(out, indent, 128)
1202         && BIO_printf(out, "%s algorithm \"%s\" unsupported\n",
1203                kstr, OBJ_nid2ln(pkey->type))
1204         > 0;
1205 }
1206 
print_pkey(const EVP_PKEY * pkey,BIO * out,int indent,int selection,const char * propquery,int (* legacy_print)(BIO * out,const EVP_PKEY * pkey,int indent,ASN1_PCTX * pctx),ASN1_PCTX * legacy_pctx)1207 static int print_pkey(const EVP_PKEY *pkey, BIO *out, int indent,
1208     int selection /* For provided encoding */,
1209     const char *propquery /* For provided encoding */,
1210     int (*legacy_print)(BIO *out, const EVP_PKEY *pkey,
1211         int indent, ASN1_PCTX *pctx),
1212     ASN1_PCTX *legacy_pctx /* For legacy print */)
1213 {
1214     int pop_f_prefix;
1215     long saved_indent;
1216     OSSL_ENCODER_CTX *ctx = NULL;
1217     int ret = -2; /* default to unsupported */
1218 
1219     if (!print_set_indent(&out, &pop_f_prefix, &saved_indent, indent))
1220         return 0;
1221 
1222     ctx = OSSL_ENCODER_CTX_new_for_pkey(pkey, selection, "TEXT", NULL,
1223         propquery);
1224     if (OSSL_ENCODER_CTX_get_num_encoders(ctx) != 0)
1225         ret = OSSL_ENCODER_to_bio(ctx, out);
1226     OSSL_ENCODER_CTX_free(ctx);
1227 
1228     if (ret != -2)
1229         goto end;
1230 
1231     /* legacy fallback */
1232     if (legacy_print != NULL)
1233         ret = legacy_print(out, pkey, 0, legacy_pctx);
1234     else
1235         ret = unsup_alg(out, pkey, 0, "Public Key");
1236 
1237 end:
1238     print_reset_indent(&out, pop_f_prefix, saved_indent);
1239     return ret;
1240 }
1241 
EVP_PKEY_print_public(BIO * out,const EVP_PKEY * pkey,int indent,ASN1_PCTX * pctx)1242 int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
1243     int indent, ASN1_PCTX *pctx)
1244 {
1245     return print_pkey(pkey, out, indent, EVP_PKEY_PUBLIC_KEY, NULL,
1246         (pkey->ameth != NULL ? pkey->ameth->pub_print : NULL),
1247         pctx);
1248 }
1249 
EVP_PKEY_print_private(BIO * out,const EVP_PKEY * pkey,int indent,ASN1_PCTX * pctx)1250 int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
1251     int indent, ASN1_PCTX *pctx)
1252 {
1253     return print_pkey(pkey, out, indent, EVP_PKEY_PRIVATE_KEY, NULL,
1254         (pkey->ameth != NULL ? pkey->ameth->priv_print : NULL),
1255         pctx);
1256 }
1257 
EVP_PKEY_print_params(BIO * out,const EVP_PKEY * pkey,int indent,ASN1_PCTX * pctx)1258 int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
1259     int indent, ASN1_PCTX *pctx)
1260 {
1261     return print_pkey(pkey, out, indent, EVP_PKEY_KEY_PARAMETERS, NULL,
1262         (pkey->ameth != NULL ? pkey->ameth->param_print : NULL),
1263         pctx);
1264 }
1265 
1266 #ifndef OPENSSL_NO_STDIO
EVP_PKEY_print_public_fp(FILE * fp,const EVP_PKEY * pkey,int indent,ASN1_PCTX * pctx)1267 int EVP_PKEY_print_public_fp(FILE *fp, const EVP_PKEY *pkey,
1268     int indent, ASN1_PCTX *pctx)
1269 {
1270     int ret;
1271     BIO *b = BIO_new_fp(fp, BIO_NOCLOSE);
1272 
1273     if (b == NULL)
1274         return 0;
1275     ret = EVP_PKEY_print_public(b, pkey, indent, pctx);
1276     BIO_free(b);
1277     return ret;
1278 }
1279 
EVP_PKEY_print_private_fp(FILE * fp,const EVP_PKEY * pkey,int indent,ASN1_PCTX * pctx)1280 int EVP_PKEY_print_private_fp(FILE *fp, const EVP_PKEY *pkey,
1281     int indent, ASN1_PCTX *pctx)
1282 {
1283     int ret;
1284     BIO *b = BIO_new_fp(fp, BIO_NOCLOSE);
1285 
1286     if (b == NULL)
1287         return 0;
1288     ret = EVP_PKEY_print_private(b, pkey, indent, pctx);
1289     BIO_free(b);
1290     return ret;
1291 }
1292 
EVP_PKEY_print_params_fp(FILE * fp,const EVP_PKEY * pkey,int indent,ASN1_PCTX * pctx)1293 int EVP_PKEY_print_params_fp(FILE *fp, const EVP_PKEY *pkey,
1294     int indent, ASN1_PCTX *pctx)
1295 {
1296     int ret;
1297     BIO *b = BIO_new_fp(fp, BIO_NOCLOSE);
1298 
1299     if (b == NULL)
1300         return 0;
1301     ret = EVP_PKEY_print_params(b, pkey, indent, pctx);
1302     BIO_free(b);
1303     return ret;
1304 }
1305 #endif
1306 
mdname2nid(const char * mdname,void * data)1307 static void mdname2nid(const char *mdname, void *data)
1308 {
1309     int *nid = (int *)data;
1310 
1311     if (*nid != NID_undef)
1312         return;
1313 
1314     *nid = OBJ_sn2nid(mdname);
1315     if (*nid == NID_undef)
1316         *nid = OBJ_ln2nid(mdname);
1317 }
1318 
legacy_asn1_ctrl_to_param(EVP_PKEY * pkey,int op,int arg1,void * arg2)1319 static int legacy_asn1_ctrl_to_param(EVP_PKEY *pkey, int op,
1320     int arg1, void *arg2)
1321 {
1322     if (pkey->keymgmt == NULL)
1323         return 0;
1324     switch (op) {
1325     case ASN1_PKEY_CTRL_DEFAULT_MD_NID: {
1326         char mdname[80] = "";
1327         int rv = EVP_PKEY_get_default_digest_name(pkey, mdname,
1328             sizeof(mdname));
1329 
1330         if (rv > 0) {
1331             int mdnum;
1332             OSSL_LIB_CTX *libctx = ossl_provider_libctx(pkey->keymgmt->prov);
1333             /* Make sure the MD is in the namemap if available */
1334             EVP_MD *md;
1335             OSSL_NAMEMAP *namemap;
1336             int nid = NID_undef;
1337 
1338             (void)ERR_set_mark();
1339             md = EVP_MD_fetch(libctx, mdname, NULL);
1340             (void)ERR_pop_to_mark();
1341             namemap = ossl_namemap_stored(libctx);
1342 
1343             /*
1344              * The only reason to fetch the MD was to make sure it is in the
1345              * namemap. We can immediately free it.
1346              */
1347             EVP_MD_free(md);
1348             mdnum = ossl_namemap_name2num(namemap, mdname);
1349             if (mdnum == 0)
1350                 return 0;
1351 
1352             /*
1353              * We have the namemap number - now we need to find the
1354              * associated nid
1355              */
1356             if (!ossl_namemap_doall_names(namemap, mdnum, mdname2nid, &nid))
1357                 return 0;
1358             *(int *)arg2 = nid;
1359         }
1360         return rv;
1361     }
1362     default:
1363         return -2;
1364     }
1365 }
1366 
evp_pkey_asn1_ctrl(EVP_PKEY * pkey,int op,int arg1,void * arg2)1367 static int evp_pkey_asn1_ctrl(EVP_PKEY *pkey, int op, int arg1, void *arg2)
1368 {
1369     if (pkey->ameth == NULL)
1370         return legacy_asn1_ctrl_to_param(pkey, op, arg1, arg2);
1371     if (pkey->ameth->pkey_ctrl == NULL)
1372         return -2;
1373     return pkey->ameth->pkey_ctrl(pkey, op, arg1, arg2);
1374 }
1375 
EVP_PKEY_get_default_digest_nid(EVP_PKEY * pkey,int * pnid)1376 int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid)
1377 {
1378     if (pkey == NULL)
1379         return 0;
1380     return evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID, 0, pnid);
1381 }
1382 
EVP_PKEY_get_default_digest_name(EVP_PKEY * pkey,char * mdname,size_t mdname_sz)1383 int EVP_PKEY_get_default_digest_name(EVP_PKEY *pkey,
1384     char *mdname, size_t mdname_sz)
1385 {
1386     if (pkey->ameth == NULL)
1387         return evp_keymgmt_util_get_deflt_digest_name(pkey->keymgmt,
1388             pkey->keydata,
1389             mdname, mdname_sz);
1390 
1391     {
1392         int nid = NID_undef;
1393         int rv = EVP_PKEY_get_default_digest_nid(pkey, &nid);
1394         const char *name = rv > 0 ? OBJ_nid2sn(nid) : NULL;
1395 
1396         if (rv > 0)
1397             OPENSSL_strlcpy(mdname, name, mdname_sz);
1398         return rv;
1399     }
1400 }
1401 
EVP_PKEY_get_group_name(const EVP_PKEY * pkey,char * gname,size_t gname_sz,size_t * gname_len)1402 int EVP_PKEY_get_group_name(const EVP_PKEY *pkey, char *gname, size_t gname_sz,
1403     size_t *gname_len)
1404 {
1405     return EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME,
1406         gname, gname_sz, gname_len);
1407 }
1408 
EVP_PKEY_digestsign_supports_digest(EVP_PKEY * pkey,OSSL_LIB_CTX * libctx,const char * name,const char * propq)1409 int EVP_PKEY_digestsign_supports_digest(EVP_PKEY *pkey, OSSL_LIB_CTX *libctx,
1410     const char *name, const char *propq)
1411 {
1412     int rv;
1413     EVP_MD_CTX *ctx = NULL;
1414 
1415     if ((ctx = EVP_MD_CTX_new()) == NULL)
1416         return -1;
1417 
1418     ERR_set_mark();
1419     rv = EVP_DigestSignInit_ex(ctx, NULL, name, libctx,
1420         propq, pkey, NULL);
1421     ERR_pop_to_mark();
1422 
1423     EVP_MD_CTX_free(ctx);
1424     return rv;
1425 }
1426 #endif /* !FIPS_MODULE */
1427 
EVP_PKEY_set1_encoded_public_key(EVP_PKEY * pkey,const unsigned char * pub,size_t publen)1428 int EVP_PKEY_set1_encoded_public_key(EVP_PKEY *pkey, const unsigned char *pub,
1429     size_t publen)
1430 {
1431     if (pkey == NULL)
1432         return 0;
1433 #ifndef FIPS_MODULE
1434     if (evp_pkey_is_provided(pkey))
1435 #endif /* !FIPS_MODULE */
1436         return EVP_PKEY_set_octet_string_param(pkey,
1437             OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY,
1438             (unsigned char *)pub, publen);
1439 
1440 #ifndef FIPS_MODULE
1441     if (publen > INT_MAX)
1442         return 0;
1443     /* Historically this function was EVP_PKEY_set1_tls_encodedpoint */
1444     if (evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_SET1_TLS_ENCPT, publen,
1445             (void *)pub)
1446         <= 0)
1447         return 0;
1448     return 1;
1449 #endif /* !FIPS_MODULE */
1450 }
1451 
EVP_PKEY_get1_encoded_public_key(EVP_PKEY * pkey,unsigned char ** ppub)1452 size_t EVP_PKEY_get1_encoded_public_key(EVP_PKEY *pkey, unsigned char **ppub)
1453 {
1454     if (pkey == NULL)
1455         return 0;
1456 #ifndef FIPS_MODULE
1457     if (evp_pkey_is_provided(pkey))
1458 #endif
1459     {
1460         size_t return_size = OSSL_PARAM_UNMODIFIED;
1461         unsigned char *buf;
1462 
1463         /*
1464          * We know that this is going to fail, but it will give us a size
1465          * to allocate.
1466          */
1467         EVP_PKEY_get_octet_string_param(pkey,
1468             OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY,
1469             NULL, 0, &return_size);
1470         if (return_size == OSSL_PARAM_UNMODIFIED)
1471             return 0;
1472 
1473         *ppub = NULL;
1474         buf = OPENSSL_malloc(return_size);
1475         if (buf == NULL)
1476             return 0;
1477 
1478         if (!EVP_PKEY_get_octet_string_param(pkey,
1479                 OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY,
1480                 buf, return_size, NULL)) {
1481             OPENSSL_free(buf);
1482             return 0;
1483         }
1484         *ppub = buf;
1485         return return_size;
1486     }
1487 
1488 #ifndef FIPS_MODULE
1489     {
1490         int rv = evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_GET1_TLS_ENCPT, 0, ppub);
1491         if (rv <= 0)
1492             return 0;
1493         return rv;
1494     }
1495 #endif /* !FIPS_MODULE */
1496 }
1497 
1498 /*- All methods below can also be used in FIPS_MODULE */
1499 
EVP_PKEY_new(void)1500 EVP_PKEY *EVP_PKEY_new(void)
1501 {
1502     EVP_PKEY *ret = OPENSSL_zalloc(sizeof(*ret));
1503 
1504     if (ret == NULL)
1505         return NULL;
1506 
1507     ret->type = EVP_PKEY_NONE;
1508     ret->save_type = EVP_PKEY_NONE;
1509 
1510     if (!CRYPTO_NEW_REF(&ret->references, 1))
1511         goto err;
1512 
1513     ret->lock = CRYPTO_THREAD_lock_new();
1514     if (ret->lock == NULL) {
1515         ERR_raise(ERR_LIB_EVP, ERR_R_CRYPTO_LIB);
1516         goto err;
1517     }
1518 
1519 #ifndef FIPS_MODULE
1520     ret->save_parameters = 1;
1521     if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_EVP_PKEY, ret, &ret->ex_data)) {
1522         ERR_raise(ERR_LIB_EVP, ERR_R_CRYPTO_LIB);
1523         goto err;
1524     }
1525 #endif
1526     return ret;
1527 
1528 err:
1529     CRYPTO_FREE_REF(&ret->references);
1530     CRYPTO_THREAD_lock_free(ret->lock);
1531     OPENSSL_free(ret);
1532     return NULL;
1533 }
1534 
1535 /*
1536  * Setup a public key management method.
1537  *
1538  * For legacy keys, either |type| or |str| is expected to have the type
1539  * information.  In this case, the setup consists of finding an ASN1 method
1540  * and potentially an ENGINE, and setting those fields in |pkey|.
1541  *
1542  * For provider side keys, |keymgmt| is expected to be non-NULL.  In this
1543  * case, the setup consists of setting the |keymgmt| field in |pkey|.
1544  *
1545  * If pkey is NULL just return 1 or 0 if the key management method exists.
1546  */
1547 
pkey_set_type(EVP_PKEY * pkey,ENGINE * e,int type,const char * str,int len,EVP_KEYMGMT * keymgmt)1548 static int pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str,
1549     int len, EVP_KEYMGMT *keymgmt)
1550 {
1551 #ifndef FIPS_MODULE
1552     const EVP_PKEY_ASN1_METHOD *ameth = NULL;
1553     ENGINE **eptr = (e == NULL) ? &e : NULL;
1554 #endif
1555 
1556     /*
1557      * The setups can't set both legacy and provider side methods.
1558      * It is forbidden
1559      */
1560     if (!ossl_assert(type == EVP_PKEY_NONE || keymgmt == NULL)
1561         || !ossl_assert(e == NULL || keymgmt == NULL)) {
1562         ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
1563         return 0;
1564     }
1565 
1566     if (pkey != NULL) {
1567         int free_it = 0;
1568 
1569 #ifndef FIPS_MODULE
1570         free_it = free_it || pkey->pkey.ptr != NULL;
1571 #endif
1572         free_it = free_it || pkey->keydata != NULL;
1573         if (free_it)
1574             evp_pkey_free_it(pkey);
1575 #ifndef FIPS_MODULE
1576         /*
1577          * If key type matches and a method exists then this lookup has
1578          * succeeded once so just indicate success.
1579          */
1580         if (pkey->type != EVP_PKEY_NONE
1581             && type == pkey->save_type
1582             && pkey->ameth != NULL)
1583             return 1;
1584 #ifndef OPENSSL_NO_ENGINE
1585         /* If we have ENGINEs release them */
1586         ENGINE_finish(pkey->engine);
1587         pkey->engine = NULL;
1588         ENGINE_finish(pkey->pmeth_engine);
1589         pkey->pmeth_engine = NULL;
1590 #endif
1591 #endif
1592     }
1593 #ifndef FIPS_MODULE
1594     if (str != NULL)
1595         ameth = EVP_PKEY_asn1_find_str(eptr, str, len);
1596     else if (type != EVP_PKEY_NONE)
1597         ameth = EVP_PKEY_asn1_find(eptr, type);
1598 #ifndef OPENSSL_NO_ENGINE
1599     if (pkey == NULL && eptr != NULL)
1600         ENGINE_finish(e);
1601 #endif
1602 #endif
1603 
1604     {
1605         int check = 1;
1606 
1607 #ifndef FIPS_MODULE
1608         check = check && ameth == NULL;
1609 #endif
1610         check = check && keymgmt == NULL;
1611         if (check) {
1612             ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_ALGORITHM);
1613             return 0;
1614         }
1615     }
1616     if (pkey != NULL) {
1617         if (keymgmt != NULL && !EVP_KEYMGMT_up_ref(keymgmt)) {
1618             ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
1619             return 0;
1620         }
1621 
1622         pkey->keymgmt = keymgmt;
1623 
1624         pkey->save_type = type;
1625         pkey->type = type;
1626 
1627 #ifndef FIPS_MODULE
1628         /*
1629          * If the internal "origin" key is provider side, don't save |ameth|.
1630          * The main reason is that |ameth| is one factor to detect that the
1631          * internal "origin" key is a legacy one.
1632          */
1633         if (keymgmt == NULL)
1634             pkey->ameth = ameth;
1635 
1636         /*
1637          * The EVP_PKEY_ASN1_METHOD |pkey_id| retains its legacy key purpose
1638          * for any key type that has a legacy implementation, regardless of
1639          * if the internal key is a legacy or a provider side one.  When
1640          * there is no legacy implementation for the key, the type becomes
1641          * EVP_PKEY_KEYMGMT, which indicates that one should be cautious
1642          * with functions that expect legacy internal keys.
1643          */
1644         if (ameth != NULL) {
1645             if (type == EVP_PKEY_NONE)
1646                 pkey->type = ameth->pkey_id;
1647         } else {
1648             pkey->type = EVP_PKEY_KEYMGMT;
1649         }
1650 #ifndef OPENSSL_NO_ENGINE
1651         if (eptr == NULL && e != NULL && !ENGINE_init(e)) {
1652             ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
1653             return 0;
1654         }
1655 #endif
1656         pkey->engine = e;
1657 #endif
1658     }
1659     return 1;
1660 }
1661 
1662 #ifndef FIPS_MODULE
find_ameth(const char * name,void * data)1663 static void find_ameth(const char *name, void *data)
1664 {
1665     const char **str = data;
1666 
1667     /*
1668      * The error messages from pkey_set_type() are uninteresting here,
1669      * and misleading.
1670      */
1671     ERR_set_mark();
1672 
1673     if (pkey_set_type(NULL, NULL, EVP_PKEY_NONE, name, strlen(name),
1674             NULL)) {
1675         if (str[0] == NULL)
1676             str[0] = name;
1677         else if (str[1] == NULL)
1678             str[1] = name;
1679     }
1680 
1681     ERR_pop_to_mark();
1682 }
1683 #endif
1684 
EVP_PKEY_set_type_by_keymgmt(EVP_PKEY * pkey,EVP_KEYMGMT * keymgmt)1685 int EVP_PKEY_set_type_by_keymgmt(EVP_PKEY *pkey, EVP_KEYMGMT *keymgmt)
1686 {
1687 #ifndef FIPS_MODULE
1688 #define EVP_PKEY_TYPE_STR str[0]
1689 #define EVP_PKEY_TYPE_STRLEN (str[0] == NULL ? -1 : (int)strlen(str[0]))
1690     /*
1691      * Find at most two strings that have an associated EVP_PKEY_ASN1_METHOD
1692      * Ideally, only one should be found.  If two (or more) are found, the
1693      * match is ambiguous.  This should never happen, but...
1694      */
1695     const char *str[2] = { NULL, NULL };
1696 
1697     if (!EVP_KEYMGMT_names_do_all(keymgmt, find_ameth, &str)
1698         || str[1] != NULL) {
1699         ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
1700         return 0;
1701     }
1702 #else
1703 #define EVP_PKEY_TYPE_STR NULL
1704 #define EVP_PKEY_TYPE_STRLEN -1
1705 #endif
1706     return pkey_set_type(pkey, NULL, EVP_PKEY_NONE,
1707         EVP_PKEY_TYPE_STR, EVP_PKEY_TYPE_STRLEN,
1708         keymgmt);
1709 
1710 #undef EVP_PKEY_TYPE_STR
1711 #undef EVP_PKEY_TYPE_STRLEN
1712 }
1713 
EVP_PKEY_up_ref(EVP_PKEY * pkey)1714 int EVP_PKEY_up_ref(EVP_PKEY *pkey)
1715 {
1716     int i;
1717 
1718     if (CRYPTO_UP_REF(&pkey->references, &i) <= 0)
1719         return 0;
1720 
1721     REF_PRINT_COUNT("EVP_PKEY", i, pkey);
1722     REF_ASSERT_ISNT(i < 2);
1723     return ((i > 1) ? 1 : 0);
1724 }
1725 
EVP_PKEY_dup(EVP_PKEY * pkey)1726 EVP_PKEY *EVP_PKEY_dup(EVP_PKEY *pkey)
1727 {
1728     EVP_PKEY *dup_pk;
1729 
1730     if (pkey == NULL) {
1731         ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER);
1732         return NULL;
1733     }
1734 
1735     if ((dup_pk = EVP_PKEY_new()) == NULL)
1736         return NULL;
1737 
1738     if (evp_pkey_is_blank(pkey))
1739         goto done;
1740 
1741 #ifndef FIPS_MODULE
1742     if (evp_pkey_is_provided(pkey))
1743 #endif /* !FIPS_MODULE */
1744     {
1745         if (!evp_keymgmt_util_copy(dup_pk, pkey,
1746                 OSSL_KEYMGMT_SELECT_ALL))
1747             goto err;
1748         goto done;
1749     }
1750 
1751 #ifndef FIPS_MODULE
1752     if (evp_pkey_is_legacy(pkey)) {
1753         const EVP_PKEY_ASN1_METHOD *ameth = pkey->ameth;
1754 
1755         if (ameth == NULL || ameth->copy == NULL) {
1756             if (pkey->pkey.ptr == NULL /* empty key, just set type */
1757                 && EVP_PKEY_set_type(dup_pk, pkey->type) != 0)
1758                 goto done;
1759             ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEY_TYPE);
1760             goto err;
1761         }
1762         if (!ameth->copy(dup_pk, pkey))
1763             goto err;
1764         goto done;
1765     }
1766 #endif /* !FIPS_MODULE */
1767 
1768     goto err;
1769 done:
1770 #ifndef FIPS_MODULE
1771     /* copy auxiliary data */
1772     if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_EVP_PKEY,
1773             &dup_pk->ex_data, &pkey->ex_data))
1774         goto err;
1775 
1776     if (pkey->attributes != NULL) {
1777         if ((dup_pk->attributes = ossl_x509at_dup(pkey->attributes)) == NULL)
1778             goto err;
1779     }
1780 #endif /* !FIPS_MODULE */
1781     return dup_pk;
1782 err:
1783     EVP_PKEY_free(dup_pk);
1784     return NULL;
1785 }
1786 
1787 #ifndef FIPS_MODULE
evp_pkey_free_legacy(EVP_PKEY * x)1788 void evp_pkey_free_legacy(EVP_PKEY *x)
1789 {
1790     const EVP_PKEY_ASN1_METHOD *ameth = x->ameth;
1791     ENGINE *tmpe = NULL;
1792 
1793     if (ameth == NULL && x->legacy_cache_pkey.ptr != NULL)
1794         ameth = EVP_PKEY_asn1_find(&tmpe, x->type);
1795 
1796     if (ameth != NULL) {
1797         if (x->legacy_cache_pkey.ptr != NULL) {
1798             /*
1799              * We should never have both a legacy origin key, and a key in the
1800              * legacy cache.
1801              */
1802             assert(x->pkey.ptr == NULL);
1803             /*
1804              * For the purposes of freeing we make the legacy cache look like
1805              * a legacy origin key.
1806              */
1807             x->pkey = x->legacy_cache_pkey;
1808             x->legacy_cache_pkey.ptr = NULL;
1809         }
1810         if (ameth->pkey_free != NULL)
1811             ameth->pkey_free(x);
1812         x->pkey.ptr = NULL;
1813     }
1814 #ifndef OPENSSL_NO_ENGINE
1815     ENGINE_finish(tmpe);
1816     ENGINE_finish(x->engine);
1817     x->engine = NULL;
1818     ENGINE_finish(x->pmeth_engine);
1819     x->pmeth_engine = NULL;
1820 #endif
1821 }
1822 #endif /* FIPS_MODULE */
1823 
evp_pkey_free_it(EVP_PKEY * x)1824 static void evp_pkey_free_it(EVP_PKEY *x)
1825 {
1826     /* internal function; x is never NULL */
1827     evp_keymgmt_util_clear_operation_cache(x);
1828 #ifndef FIPS_MODULE
1829     evp_pkey_free_legacy(x);
1830 #endif
1831 
1832     if (x->keymgmt != NULL) {
1833         evp_keymgmt_freedata(x->keymgmt, x->keydata);
1834         EVP_KEYMGMT_free(x->keymgmt);
1835         x->keymgmt = NULL;
1836         x->keydata = NULL;
1837     }
1838     x->type = EVP_PKEY_NONE;
1839 }
1840 
EVP_PKEY_free(EVP_PKEY * x)1841 void EVP_PKEY_free(EVP_PKEY *x)
1842 {
1843     int i;
1844 
1845     if (x == NULL)
1846         return;
1847 
1848     CRYPTO_DOWN_REF(&x->references, &i);
1849     REF_PRINT_COUNT("EVP_PKEY", i, x);
1850     if (i > 0)
1851         return;
1852     REF_ASSERT_ISNT(i < 0);
1853     evp_pkey_free_it(x);
1854 #ifndef FIPS_MODULE
1855     CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EVP_PKEY, x, &x->ex_data);
1856 #endif
1857     CRYPTO_THREAD_lock_free(x->lock);
1858     CRYPTO_FREE_REF(&x->references);
1859 #ifndef FIPS_MODULE
1860     sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);
1861 #endif
1862     OPENSSL_free(x);
1863 }
1864 
EVP_PKEY_get_size(const EVP_PKEY * pkey)1865 int EVP_PKEY_get_size(const EVP_PKEY *pkey)
1866 {
1867     int size = 0;
1868 
1869     if (pkey != NULL) {
1870         size = pkey->cache.size;
1871 #ifndef FIPS_MODULE
1872         if (pkey->ameth != NULL && pkey->ameth->pkey_size != NULL)
1873             size = pkey->ameth->pkey_size(pkey);
1874 #endif
1875     }
1876     if (size <= 0) {
1877         ERR_raise(ERR_LIB_EVP, EVP_R_UNKNOWN_MAX_SIZE);
1878         return 0;
1879     }
1880     return size;
1881 }
1882 
EVP_PKEY_get0_description(const EVP_PKEY * pkey)1883 const char *EVP_PKEY_get0_description(const EVP_PKEY *pkey)
1884 {
1885     if (!evp_pkey_is_assigned(pkey))
1886         return NULL;
1887 
1888     if (evp_pkey_is_provided(pkey) && pkey->keymgmt->description != NULL)
1889         return pkey->keymgmt->description;
1890 #ifndef FIPS_MODULE
1891     if (pkey->ameth != NULL)
1892         return pkey->ameth->info;
1893 #endif
1894     return NULL;
1895 }
1896 
evp_pkey_export_to_provider(EVP_PKEY * pk,OSSL_LIB_CTX * libctx,EVP_KEYMGMT ** keymgmt,const char * propquery)1897 void *evp_pkey_export_to_provider(EVP_PKEY *pk, OSSL_LIB_CTX *libctx,
1898     EVP_KEYMGMT **keymgmt,
1899     const char *propquery)
1900 {
1901     EVP_KEYMGMT *allocated_keymgmt = NULL;
1902     EVP_KEYMGMT *tmp_keymgmt = NULL;
1903     int selection = OSSL_KEYMGMT_SELECT_ALL;
1904     void *keydata = NULL;
1905     int check;
1906 
1907     if (pk == NULL)
1908         return NULL;
1909 
1910     /* No key data => nothing to export */
1911     check = 1;
1912 #ifndef FIPS_MODULE
1913     check = check && pk->pkey.ptr == NULL;
1914 #endif
1915     check = check && pk->keydata == NULL;
1916     if (check)
1917         return NULL;
1918 
1919 #ifndef FIPS_MODULE
1920     if (pk->pkey.ptr != NULL) {
1921         /*
1922          * If the legacy key doesn't have an dirty counter or export function,
1923          * give up
1924          */
1925         if (pk->ameth->dirty_cnt == NULL || pk->ameth->export_to == NULL)
1926             return NULL;
1927     }
1928 #endif
1929 
1930     if (keymgmt != NULL) {
1931         tmp_keymgmt = *keymgmt;
1932         *keymgmt = NULL;
1933     }
1934 
1935     /*
1936      * If no keymgmt was given or found, get a default keymgmt.  We do so by
1937      * letting EVP_PKEY_CTX_new_from_pkey() do it for us, then we steal it.
1938      */
1939     if (tmp_keymgmt == NULL) {
1940         EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pk, propquery);
1941 
1942         if (ctx == NULL)
1943             goto end;
1944         allocated_keymgmt = tmp_keymgmt = ctx->keymgmt;
1945         ctx->keymgmt = NULL;
1946         EVP_PKEY_CTX_free(ctx);
1947     }
1948 
1949     /* If there's still no keymgmt to be had, give up */
1950     if (tmp_keymgmt == NULL)
1951         goto end;
1952 
1953 #ifndef FIPS_MODULE
1954     if (pk->pkey.ptr != NULL) {
1955         OP_CACHE_ELEM *op;
1956 
1957         /*
1958          * If the legacy "origin" hasn't changed since last time, we try
1959          * to find our keymgmt in the operation cache.  If it has changed,
1960          * |i| remains zero, and we will clear the cache further down.
1961          */
1962         if (pk->ameth->dirty_cnt(pk) == pk->dirty_cnt_copy) {
1963             if (!CRYPTO_THREAD_read_lock(pk->lock))
1964                 goto end;
1965             op = evp_keymgmt_util_find_operation_cache(pk, tmp_keymgmt,
1966                 selection);
1967 
1968             /*
1969              * If |tmp_keymgmt| is present in the operation cache, it means
1970              * that export doesn't need to be redone.  In that case, we take
1971              * token copies of the cached pointers, to have token success
1972              * values to return. It is possible (e.g. in a no-cached-fetch
1973              * build), for op->keymgmt to be a different pointer to tmp_keymgmt
1974              * even though the name/provider must be the same. In other words
1975              * the keymgmt instance may be different but still equivalent, i.e.
1976              * same algorithm/provider instance - but we make the simplifying
1977              * assumption that the keydata can be used with either keymgmt
1978              * instance. Not doing so introduces significant complexity and
1979              * probably requires refactoring - since we would have to ripple
1980              * the change in keymgmt instance up the call chain.
1981              */
1982             if (op != NULL && op->keymgmt != NULL) {
1983                 keydata = op->keydata;
1984                 CRYPTO_THREAD_unlock(pk->lock);
1985                 goto end;
1986             }
1987             CRYPTO_THREAD_unlock(pk->lock);
1988         }
1989 
1990         /* Make sure that the keymgmt key type matches the legacy NID */
1991         if (!EVP_KEYMGMT_is_a(tmp_keymgmt, OBJ_nid2sn(pk->type)))
1992             goto end;
1993 
1994         if ((keydata = evp_keymgmt_newdata(tmp_keymgmt)) == NULL)
1995             goto end;
1996 
1997         if (!pk->ameth->export_to(pk, keydata, tmp_keymgmt->import,
1998                 libctx, propquery)) {
1999             evp_keymgmt_freedata(tmp_keymgmt, keydata);
2000             keydata = NULL;
2001             goto end;
2002         }
2003 
2004         /*
2005          * If the dirty counter changed since last time, then clear the
2006          * operation cache.  In that case, we know that |i| is zero.  Just
2007          * in case this is a re-export, we increment then decrement the
2008          * keymgmt reference counter.
2009          */
2010         if (!EVP_KEYMGMT_up_ref(tmp_keymgmt)) { /* refcnt++ */
2011             evp_keymgmt_freedata(tmp_keymgmt, keydata);
2012             keydata = NULL;
2013             goto end;
2014         }
2015 
2016         if (!CRYPTO_THREAD_write_lock(pk->lock))
2017             goto end;
2018         if (pk->ameth->dirty_cnt(pk) != pk->dirty_cnt_copy
2019             && !evp_keymgmt_util_clear_operation_cache(pk)) {
2020             CRYPTO_THREAD_unlock(pk->lock);
2021             evp_keymgmt_freedata(tmp_keymgmt, keydata);
2022             keydata = NULL;
2023             EVP_KEYMGMT_free(tmp_keymgmt);
2024             goto end;
2025         }
2026         EVP_KEYMGMT_free(tmp_keymgmt); /* refcnt-- */
2027 
2028         /* Check to make sure some other thread didn't get there first */
2029         op = evp_keymgmt_util_find_operation_cache(pk, tmp_keymgmt, selection);
2030         if (op != NULL && op->keymgmt != NULL) {
2031             void *tmp_keydata = op->keydata;
2032 
2033             CRYPTO_THREAD_unlock(pk->lock);
2034             evp_keymgmt_freedata(tmp_keymgmt, keydata);
2035             keydata = tmp_keydata;
2036             goto end;
2037         }
2038 
2039         /* Add the new export to the operation cache */
2040         if (!evp_keymgmt_util_cache_keydata(pk, tmp_keymgmt, keydata,
2041                 selection)) {
2042             CRYPTO_THREAD_unlock(pk->lock);
2043             evp_keymgmt_freedata(tmp_keymgmt, keydata);
2044             keydata = NULL;
2045             goto end;
2046         }
2047 
2048         /* Synchronize the dirty count */
2049         pk->dirty_cnt_copy = pk->ameth->dirty_cnt(pk);
2050 
2051         CRYPTO_THREAD_unlock(pk->lock);
2052         goto end;
2053     }
2054 #endif /* FIPS_MODULE */
2055 
2056     keydata = evp_keymgmt_util_export_to_provider(pk, tmp_keymgmt, selection);
2057 
2058 end:
2059     /*
2060      * If nothing was exported, |tmp_keymgmt| might point at a freed
2061      * EVP_KEYMGMT, so we clear it to be safe.  It shouldn't be useful for
2062      * the caller either way in that case.
2063      */
2064     if (keydata == NULL)
2065         tmp_keymgmt = NULL;
2066 
2067     if (keymgmt != NULL && tmp_keymgmt != NULL) {
2068         *keymgmt = tmp_keymgmt;
2069         allocated_keymgmt = NULL;
2070     }
2071 
2072     EVP_KEYMGMT_free(allocated_keymgmt);
2073     return keydata;
2074 }
2075 
2076 #ifndef FIPS_MODULE
evp_pkey_copy_downgraded(EVP_PKEY ** dest,const EVP_PKEY * src)2077 int evp_pkey_copy_downgraded(EVP_PKEY **dest, const EVP_PKEY *src)
2078 {
2079     EVP_PKEY *allocpkey = NULL;
2080 
2081     if (!ossl_assert(dest != NULL))
2082         return 0;
2083 
2084     if (evp_pkey_is_assigned(src) && evp_pkey_is_provided(src)) {
2085         EVP_KEYMGMT *keymgmt = src->keymgmt;
2086         void *keydata = src->keydata;
2087         int type = src->type;
2088         const char *keytype = NULL;
2089 
2090         keytype = EVP_KEYMGMT_get0_name(keymgmt);
2091 
2092         /*
2093          * If the type is EVP_PKEY_NONE, then we have a problem somewhere
2094          * else in our code.  If it's not one of the well known EVP_PKEY_xxx
2095          * values, it should at least be EVP_PKEY_KEYMGMT at this point.
2096          * The check is kept as a safety measure.
2097          */
2098         if (!ossl_assert(type != EVP_PKEY_NONE)) {
2099             ERR_raise_data(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR,
2100                 "keymgmt key type = %s but legacy type = EVP_PKEY_NONE",
2101                 keytype);
2102             return 0;
2103         }
2104 
2105         /* Prefer the legacy key type name for error reporting */
2106         if (type != EVP_PKEY_KEYMGMT)
2107             keytype = OBJ_nid2sn(type);
2108 
2109         /* Make sure we have a clean slate to copy into */
2110         if (*dest == NULL) {
2111             allocpkey = *dest = EVP_PKEY_new();
2112             if (*dest == NULL) {
2113                 ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB);
2114                 return 0;
2115             }
2116         } else {
2117             evp_pkey_free_it(*dest);
2118         }
2119 
2120         if (EVP_PKEY_set_type(*dest, type)) {
2121             /* If the key is typed but empty, we're done */
2122             if (keydata == NULL)
2123                 return 1;
2124 
2125             if ((*dest)->ameth->import_from == NULL) {
2126                 ERR_raise_data(ERR_LIB_EVP, EVP_R_NO_IMPORT_FUNCTION,
2127                     "key type = %s", keytype);
2128             } else {
2129                 /*
2130                  * We perform the export in the same libctx as the keymgmt
2131                  * that we are using.
2132                  */
2133                 OSSL_LIB_CTX *libctx = ossl_provider_libctx(keymgmt->prov);
2134                 EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_from_pkey(libctx, *dest, NULL);
2135 
2136                 if (pctx == NULL)
2137                     ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB);
2138 
2139                 if (pctx != NULL
2140                     && evp_keymgmt_export(keymgmt, keydata,
2141                         OSSL_KEYMGMT_SELECT_ALL,
2142                         (*dest)->ameth->import_from,
2143                         pctx)) {
2144                     /* Synchronize the dirty count */
2145                     (*dest)->dirty_cnt_copy = (*dest)->ameth->dirty_cnt(*dest);
2146 
2147                     EVP_PKEY_CTX_free(pctx);
2148                     return 1;
2149                 }
2150                 EVP_PKEY_CTX_free(pctx);
2151             }
2152 
2153             ERR_raise_data(ERR_LIB_EVP, EVP_R_KEYMGMT_EXPORT_FAILURE,
2154                 "key type = %s", keytype);
2155         }
2156     }
2157 
2158     if (allocpkey != NULL) {
2159         EVP_PKEY_free(allocpkey);
2160         *dest = NULL;
2161     }
2162     return 0;
2163 }
2164 
evp_pkey_get_legacy(EVP_PKEY * pk)2165 void *evp_pkey_get_legacy(EVP_PKEY *pk)
2166 {
2167     EVP_PKEY *tmp_copy = NULL;
2168     void *ret = NULL;
2169 
2170     if (!ossl_assert(pk != NULL))
2171         return NULL;
2172 
2173     /*
2174      * If this isn't an assigned provider side key, we just use any existing
2175      * origin legacy key.
2176      */
2177     if (!evp_pkey_is_assigned(pk))
2178         return NULL;
2179     if (!evp_pkey_is_provided(pk))
2180         return pk->pkey.ptr;
2181 
2182     if (!CRYPTO_THREAD_read_lock(pk->lock))
2183         return NULL;
2184 
2185     ret = pk->legacy_cache_pkey.ptr;
2186 
2187     if (!CRYPTO_THREAD_unlock(pk->lock))
2188         return NULL;
2189 
2190     if (ret != NULL)
2191         return ret;
2192 
2193     if (!evp_pkey_copy_downgraded(&tmp_copy, pk))
2194         goto err;
2195 
2196     if (!CRYPTO_THREAD_write_lock(pk->lock))
2197         goto err;
2198 
2199     /* Check again in case some other thread has updated it in the meantime */
2200     ret = pk->legacy_cache_pkey.ptr;
2201     if (ret == NULL) {
2202         /* Steal the legacy key reference from the temporary copy */
2203         ret = pk->legacy_cache_pkey.ptr = tmp_copy->pkey.ptr;
2204         tmp_copy->pkey.ptr = NULL;
2205     }
2206 
2207     if (!CRYPTO_THREAD_unlock(pk->lock)) {
2208         ret = NULL;
2209         goto err;
2210     }
2211 
2212 err:
2213     EVP_PKEY_free(tmp_copy);
2214 
2215     return ret;
2216 }
2217 #endif /* FIPS_MODULE */
2218 
EVP_PKEY_get_bn_param(const EVP_PKEY * pkey,const char * key_name,BIGNUM ** bn)2219 int EVP_PKEY_get_bn_param(const EVP_PKEY *pkey, const char *key_name,
2220     BIGNUM **bn)
2221 {
2222     int ret = 0;
2223     OSSL_PARAM params[2];
2224     unsigned char buffer[2048];
2225     unsigned char *buf = NULL;
2226     size_t buf_sz = 0;
2227 
2228     if (key_name == NULL
2229         || bn == NULL)
2230         return 0;
2231 
2232     memset(buffer, 0, sizeof(buffer));
2233     params[0] = OSSL_PARAM_construct_BN(key_name, buffer, sizeof(buffer));
2234     params[1] = OSSL_PARAM_construct_end();
2235     if (!EVP_PKEY_get_params(pkey, params)) {
2236         if (!OSSL_PARAM_modified(params) || params[0].return_size == 0)
2237             return 0;
2238         buf_sz = params[0].return_size;
2239         /*
2240          * If it failed because the buffer was too small then allocate the
2241          * required buffer size and retry.
2242          */
2243         buf = OPENSSL_zalloc(buf_sz);
2244         if (buf == NULL)
2245             return 0;
2246         params[0].data = buf;
2247         params[0].data_size = buf_sz;
2248 
2249         if (!EVP_PKEY_get_params(pkey, params))
2250             goto err;
2251     }
2252     /* Fail if the param was not found */
2253     if (!OSSL_PARAM_modified(params))
2254         goto err;
2255     ret = OSSL_PARAM_get_BN(params, bn);
2256 err:
2257     if (buf != NULL) {
2258         if (OSSL_PARAM_modified(params))
2259             OPENSSL_clear_free(buf, buf_sz);
2260         else
2261             OPENSSL_free(buf);
2262     } else if (OSSL_PARAM_modified(params)) {
2263         OPENSSL_cleanse(buffer, params[0].data_size);
2264     }
2265     return ret;
2266 }
2267 
EVP_PKEY_get_octet_string_param(const EVP_PKEY * pkey,const char * key_name,unsigned char * buf,size_t max_buf_sz,size_t * out_len)2268 int EVP_PKEY_get_octet_string_param(const EVP_PKEY *pkey, const char *key_name,
2269     unsigned char *buf, size_t max_buf_sz,
2270     size_t *out_len)
2271 {
2272     OSSL_PARAM params[2];
2273     int ret1 = 0, ret2 = 0;
2274 
2275     if (key_name == NULL)
2276         return 0;
2277 
2278     params[0] = OSSL_PARAM_construct_octet_string(key_name, buf, max_buf_sz);
2279     params[1] = OSSL_PARAM_construct_end();
2280     if ((ret1 = EVP_PKEY_get_params(pkey, params)))
2281         ret2 = OSSL_PARAM_modified(params);
2282     if (ret2 && out_len != NULL)
2283         *out_len = params[0].return_size;
2284     return ret1 && ret2;
2285 }
2286 
EVP_PKEY_get_utf8_string_param(const EVP_PKEY * pkey,const char * key_name,char * str,size_t max_buf_sz,size_t * out_len)2287 int EVP_PKEY_get_utf8_string_param(const EVP_PKEY *pkey, const char *key_name,
2288     char *str, size_t max_buf_sz,
2289     size_t *out_len)
2290 {
2291     OSSL_PARAM params[2];
2292     int ret1 = 0, ret2 = 0;
2293 
2294     if (key_name == NULL)
2295         return 0;
2296 
2297     params[0] = OSSL_PARAM_construct_utf8_string(key_name, str, max_buf_sz);
2298     params[1] = OSSL_PARAM_construct_end();
2299     if ((ret1 = EVP_PKEY_get_params(pkey, params)))
2300         ret2 = OSSL_PARAM_modified(params);
2301     if (ret2 && out_len != NULL)
2302         *out_len = params[0].return_size;
2303 
2304     if (ret2 && params[0].return_size == max_buf_sz)
2305         /* There was no space for a NUL byte */
2306         return 0;
2307     /* Add a terminating NUL byte for good measure */
2308     if (ret2 && str != NULL)
2309         str[params[0].return_size] = '\0';
2310 
2311     return ret1 && ret2;
2312 }
2313 
EVP_PKEY_get_int_param(const EVP_PKEY * pkey,const char * key_name,int * out)2314 int EVP_PKEY_get_int_param(const EVP_PKEY *pkey, const char *key_name,
2315     int *out)
2316 {
2317     OSSL_PARAM params[2];
2318 
2319     if (key_name == NULL)
2320         return 0;
2321 
2322     params[0] = OSSL_PARAM_construct_int(key_name, out);
2323     params[1] = OSSL_PARAM_construct_end();
2324     return EVP_PKEY_get_params(pkey, params)
2325         && OSSL_PARAM_modified(params);
2326 }
2327 
EVP_PKEY_get_size_t_param(const EVP_PKEY * pkey,const char * key_name,size_t * out)2328 int EVP_PKEY_get_size_t_param(const EVP_PKEY *pkey, const char *key_name,
2329     size_t *out)
2330 {
2331     OSSL_PARAM params[2];
2332 
2333     if (key_name == NULL)
2334         return 0;
2335 
2336     params[0] = OSSL_PARAM_construct_size_t(key_name, out);
2337     params[1] = OSSL_PARAM_construct_end();
2338     return EVP_PKEY_get_params(pkey, params)
2339         && OSSL_PARAM_modified(params);
2340 }
2341 
EVP_PKEY_set_int_param(EVP_PKEY * pkey,const char * key_name,int in)2342 int EVP_PKEY_set_int_param(EVP_PKEY *pkey, const char *key_name, int in)
2343 {
2344     OSSL_PARAM params[2];
2345 
2346     if (key_name == NULL)
2347         return 0;
2348 
2349     params[0] = OSSL_PARAM_construct_int(key_name, &in);
2350     params[1] = OSSL_PARAM_construct_end();
2351     return EVP_PKEY_set_params(pkey, params);
2352 }
2353 
EVP_PKEY_set_size_t_param(EVP_PKEY * pkey,const char * key_name,size_t in)2354 int EVP_PKEY_set_size_t_param(EVP_PKEY *pkey, const char *key_name, size_t in)
2355 {
2356     OSSL_PARAM params[2];
2357 
2358     if (key_name == NULL)
2359         return 0;
2360 
2361     params[0] = OSSL_PARAM_construct_size_t(key_name, &in);
2362     params[1] = OSSL_PARAM_construct_end();
2363     return EVP_PKEY_set_params(pkey, params);
2364 }
2365 
EVP_PKEY_set_bn_param(EVP_PKEY * pkey,const char * key_name,const BIGNUM * bn)2366 int EVP_PKEY_set_bn_param(EVP_PKEY *pkey, const char *key_name,
2367     const BIGNUM *bn)
2368 {
2369     OSSL_PARAM params[2];
2370     unsigned char buffer[2048];
2371     int bsize = 0;
2372 
2373     if (key_name == NULL
2374         || bn == NULL
2375         || pkey == NULL
2376         || !evp_pkey_is_assigned(pkey))
2377         return 0;
2378 
2379     bsize = BN_num_bytes(bn);
2380     if (!ossl_assert(bsize <= (int)sizeof(buffer)))
2381         return 0;
2382 
2383     if (BN_bn2nativepad(bn, buffer, bsize) < 0)
2384         return 0;
2385     params[0] = OSSL_PARAM_construct_BN(key_name, buffer, bsize);
2386     params[1] = OSSL_PARAM_construct_end();
2387     return EVP_PKEY_set_params(pkey, params);
2388 }
2389 
EVP_PKEY_set_utf8_string_param(EVP_PKEY * pkey,const char * key_name,const char * str)2390 int EVP_PKEY_set_utf8_string_param(EVP_PKEY *pkey, const char *key_name,
2391     const char *str)
2392 {
2393     OSSL_PARAM params[2];
2394 
2395     if (key_name == NULL)
2396         return 0;
2397 
2398     params[0] = OSSL_PARAM_construct_utf8_string(key_name, (char *)str, 0);
2399     params[1] = OSSL_PARAM_construct_end();
2400     return EVP_PKEY_set_params(pkey, params);
2401 }
2402 
EVP_PKEY_set_octet_string_param(EVP_PKEY * pkey,const char * key_name,const unsigned char * buf,size_t bsize)2403 int EVP_PKEY_set_octet_string_param(EVP_PKEY *pkey, const char *key_name,
2404     const unsigned char *buf, size_t bsize)
2405 {
2406     OSSL_PARAM params[2];
2407 
2408     if (key_name == NULL)
2409         return 0;
2410 
2411     params[0] = OSSL_PARAM_construct_octet_string(key_name,
2412         (unsigned char *)buf, bsize);
2413     params[1] = OSSL_PARAM_construct_end();
2414     return EVP_PKEY_set_params(pkey, params);
2415 }
2416 
EVP_PKEY_settable_params(const EVP_PKEY * pkey)2417 const OSSL_PARAM *EVP_PKEY_settable_params(const EVP_PKEY *pkey)
2418 {
2419     return (pkey != NULL && evp_pkey_is_provided(pkey))
2420         ? EVP_KEYMGMT_settable_params(pkey->keymgmt)
2421         : NULL;
2422 }
2423 
EVP_PKEY_set_params(EVP_PKEY * pkey,OSSL_PARAM params[])2424 int EVP_PKEY_set_params(EVP_PKEY *pkey, OSSL_PARAM params[])
2425 {
2426     if (pkey != NULL) {
2427         if (evp_pkey_is_provided(pkey)) {
2428             pkey->dirty_cnt++;
2429             return evp_keymgmt_set_params(pkey->keymgmt, pkey->keydata, params);
2430         }
2431 #ifndef FIPS_MODULE
2432         /*
2433          * We will hopefully never find the need to set individual data in
2434          * EVP_PKEYs with a legacy internal key, but we can't be entirely
2435          * sure.  This bit of code can be enabled if we find the need.  If
2436          * not, it can safely be removed when #legacy support is removed.
2437          */
2438 #if 0
2439         else if (evp_pkey_is_legacy(pkey)) {
2440             return evp_pkey_set_params_to_ctrl(pkey, params);
2441         }
2442 #endif
2443 #endif
2444     }
2445     ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_KEY);
2446     return 0;
2447 }
2448 
EVP_PKEY_gettable_params(const EVP_PKEY * pkey)2449 const OSSL_PARAM *EVP_PKEY_gettable_params(const EVP_PKEY *pkey)
2450 {
2451     return (pkey != NULL && evp_pkey_is_provided(pkey))
2452         ? EVP_KEYMGMT_gettable_params(pkey->keymgmt)
2453         : NULL;
2454 }
2455 
EVP_PKEY_get_params(const EVP_PKEY * pkey,OSSL_PARAM params[])2456 int EVP_PKEY_get_params(const EVP_PKEY *pkey, OSSL_PARAM params[])
2457 {
2458     if (pkey != NULL) {
2459         if (evp_pkey_is_provided(pkey))
2460             return evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params) > 0;
2461 #ifndef FIPS_MODULE
2462         else if (evp_pkey_is_legacy(pkey))
2463             return evp_pkey_get_params_to_ctrl(pkey, params) > 0;
2464 #endif
2465     }
2466     ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_KEY);
2467     return 0;
2468 }
2469 
2470 #ifndef FIPS_MODULE
EVP_PKEY_get_ec_point_conv_form(const EVP_PKEY * pkey)2471 int EVP_PKEY_get_ec_point_conv_form(const EVP_PKEY *pkey)
2472 {
2473     char name[80];
2474     size_t name_len;
2475 
2476     if (pkey == NULL)
2477         return 0;
2478 
2479     if (pkey->keymgmt == NULL
2480         || pkey->keydata == NULL) {
2481 #ifndef OPENSSL_NO_EC
2482         /* Might work through the legacy route */
2483         const EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey);
2484 
2485         if (ec == NULL)
2486             return 0;
2487 
2488         return EC_KEY_get_conv_form(ec);
2489 #else
2490         return 0;
2491 #endif
2492     }
2493 
2494     if (!EVP_PKEY_get_utf8_string_param(pkey,
2495             OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT,
2496             name, sizeof(name), &name_len))
2497         return 0;
2498 
2499     if (strcmp(name, "uncompressed") == 0)
2500         return POINT_CONVERSION_UNCOMPRESSED;
2501 
2502     if (strcmp(name, "compressed") == 0)
2503         return POINT_CONVERSION_COMPRESSED;
2504 
2505     if (strcmp(name, "hybrid") == 0)
2506         return POINT_CONVERSION_HYBRID;
2507 
2508     return 0;
2509 }
2510 
EVP_PKEY_get_field_type(const EVP_PKEY * pkey)2511 int EVP_PKEY_get_field_type(const EVP_PKEY *pkey)
2512 {
2513     char fstr[80];
2514     size_t fstrlen;
2515 
2516     if (pkey == NULL)
2517         return 0;
2518 
2519     if (pkey->keymgmt == NULL
2520         || pkey->keydata == NULL) {
2521 #ifndef OPENSSL_NO_EC
2522         /* Might work through the legacy route */
2523         const EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey);
2524         const EC_GROUP *grp;
2525 
2526         if (ec == NULL)
2527             return 0;
2528         grp = EC_KEY_get0_group(ec);
2529         if (grp == NULL)
2530             return 0;
2531 
2532         return EC_GROUP_get_field_type(grp);
2533 #else
2534         return 0;
2535 #endif
2536     }
2537 
2538     if (!EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_EC_FIELD_TYPE,
2539             fstr, sizeof(fstr), &fstrlen))
2540         return 0;
2541 
2542     if (strcmp(fstr, SN_X9_62_prime_field) == 0)
2543         return NID_X9_62_prime_field;
2544     else if (strcmp(fstr, SN_X9_62_characteristic_two_field))
2545         return NID_X9_62_characteristic_two_field;
2546 
2547     return 0;
2548 }
2549 #endif
2550