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