]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/evp/p_lib.c
Ensure EVP_PKEY_get_raw_[private|public]_key work with provider keys
[thirdparty/openssl.git] / crypto / evp / p_lib.c
CommitLineData
62867571 1/*
33388b44 2 * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
d02b48c6 3 *
4a8b0c55 4 * Licensed under the Apache License 2.0 (the "License"). You may not use
62867571
RS
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
d02b48c6
RE
8 */
9
f41ac0ee
P
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
d02b48c6 16#include <stdio.h>
b39fc560 17#include "internal/cryptlib.h"
cd420b0b 18#include "internal/refcount.h"
4d94ae00
BM
19#include <openssl/bn.h>
20#include <openssl/err.h>
ec577822
BM
21#include <openssl/objects.h>
22#include <openssl/evp.h>
ec577822 23#include <openssl/x509.h>
3c27208f
RS
24#include <openssl/rsa.h>
25#include <openssl/dsa.h>
26#include <openssl/dh.h>
4f76d62f 27#include <openssl/ec.h>
b3831fbb 28#include <openssl/cmac.h>
3c27208f 29#include <openssl/engine.h>
e74bd290 30#include <openssl/params.h>
1c4f340d 31#include <openssl/param_build.h>
54c1711f 32#include <openssl/serializer.h>
e74bd290 33#include <openssl/core_names.h>
01b8b3c7 34
25f2138b
DMSP
35#include "crypto/asn1.h"
36#include "crypto/evp.h"
c2041da8 37#include "internal/evp.h"
e74bd290 38#include "internal/provider.h"
f6aa5774 39#include "evp_local.h"
852c2ed2 40DEFINE_STACK_OF(X509_ATTRIBUTE)
18e377b4 41
4f76d62f
RL
42#include "crypto/ec.h"
43
44/* TODO remove this when the EVP_PKEY_is_a() #legacy support hack is removed */
45#include "e_os.h" /* strcasecmp on Windows */
46
8243d8d1
RL
47static int pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str,
48 int len, EVP_KEYMGMT *keymgmt);
e683582b
SL
49static void evp_pkey_free_it(EVP_PKEY *key);
50
f844f9eb 51#ifndef FIPS_MODULE
bb2297a4 52
8158cf20
RL
53/* The type of parameters selected in key parameter functions */
54# define SELECT_PARAMETERS OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
55
8900f3e3 56int EVP_PKEY_bits(const EVP_PKEY *pkey)
0f113f3e 57{
6508e858
RL
58 if (pkey != NULL) {
59 if (pkey->ameth == NULL)
60 return pkey->cache.bits;
61 else if (pkey->ameth->pkey_bits)
62 return pkey->ameth->pkey_bits(pkey);
63 }
0f113f3e
MC
64 return 0;
65}
58964a49 66
2514fa79 67int EVP_PKEY_security_bits(const EVP_PKEY *pkey)
0f113f3e
MC
68{
69 if (pkey == NULL)
70 return 0;
6508e858
RL
71 if (pkey->ameth == NULL)
72 return pkey->cache.security_bits;
73 if (pkey->ameth->pkey_security_bits == NULL)
0f113f3e
MC
74 return -2;
75 return pkey->ameth->pkey_security_bits(pkey);
76}
2514fa79 77
6b691a5c 78int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode)
0f113f3e 79{
e683582b 80# ifndef OPENSSL_NO_DSA
0f113f3e
MC
81 if (pkey->type == EVP_PKEY_DSA) {
82 int ret = pkey->save_parameters;
83
84 if (mode >= 0)
85 pkey->save_parameters = mode;
26a7d938 86 return ret;
0f113f3e 87 }
e683582b
SL
88# endif
89# ifndef OPENSSL_NO_EC
0f113f3e
MC
90 if (pkey->type == EVP_PKEY_EC) {
91 int ret = pkey->save_parameters;
92
93 if (mode >= 0)
94 pkey->save_parameters = mode;
26a7d938 95 return ret;
0f113f3e 96 }
e683582b 97# endif
26a7d938 98 return 0;
0f113f3e 99}
d02b48c6 100
ff1f7cde
AT
101int EVP_PKEY_set_ex_data(EVP_PKEY *key, int idx, void *arg)
102{
103 return CRYPTO_set_ex_data(&key->ex_data, idx, arg);
104}
105
106void *EVP_PKEY_get_ex_data(const EVP_PKEY *key, int idx)
107{
108 return CRYPTO_get_ex_data(&key->ex_data, idx);
109}
110
a8b72844 111int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
0f113f3e 112{
ff3b59e1
RL
113 /*
114 * TODO: clean up legacy stuff from this function when legacy support
115 * is gone.
116 */
117
118 /*
acb90ba8
RL
119 * If |to| is a legacy key and |from| isn't, we must downgrade |from|.
120 * If that fails, this function fails.
ff3b59e1 121 */
acb90ba8
RL
122 if (to->type != EVP_PKEY_NONE && from->keymgmt != NULL)
123 if (!evp_pkey_downgrade((EVP_PKEY *)from))
124 return 0;
125
126 /*
127 * Make sure |to| is typed. Content is less important at this early
128 * stage.
129 *
130 * 1. If |to| is untyped, assign |from|'s key type to it.
131 * 2. If |to| contains a legacy key, compare its |type| to |from|'s.
132 * (|from| was already downgraded above)
133 *
134 * If |to| is a provided key, there's nothing more to do here, functions
135 * like evp_keymgmt_util_copy() and evp_pkey_export_to_provider() called
136 * further down help us find out if they are the same or not.
137 */
138 if (to->type == EVP_PKEY_NONE && to->keymgmt == NULL) {
139 if (from->type != EVP_PKEY_NONE) {
ff3b59e1
RL
140 if (EVP_PKEY_set_type(to, from->type) == 0)
141 return 0;
acb90ba8
RL
142 } else {
143 if (EVP_PKEY_set_type_by_keymgmt(to, from->keymgmt) == 0)
144 return 0;
145 }
146 } else if (to->type != EVP_PKEY_NONE) {
147 if (to->type != from->type) {
ff3b59e1
RL
148 EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_DIFFERENT_KEY_TYPES);
149 goto err;
150 }
0f113f3e
MC
151 }
152
153 if (EVP_PKEY_missing_parameters(from)) {
154 EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_MISSING_PARAMETERS);
155 goto err;
156 }
f72f00d4
DSH
157
158 if (!EVP_PKEY_missing_parameters(to)) {
159 if (EVP_PKEY_cmp_parameters(to, from) == 1)
160 return 1;
161 EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_DIFFERENT_PARAMETERS);
162 return 0;
163 }
164
ff3b59e1
RL
165 /* For purely provided keys, we just call the keymgmt utility */
166 if (to->keymgmt != NULL && from->keymgmt != NULL)
8158cf20 167 return evp_keymgmt_util_copy(to, (EVP_PKEY *)from, SELECT_PARAMETERS);
ff3b59e1
RL
168
169 /*
170 * If |to| is provided, we know that |from| is legacy at this point.
171 * Try exporting |from| to |to|'s keymgmt, then use evp_keymgmt_copy()
172 * to copy the appropriate data to |to|'s keydata.
173 */
174 if (to->keymgmt != NULL) {
175 EVP_KEYMGMT *to_keymgmt = to->keymgmt;
176 void *from_keydata =
177 evp_pkey_export_to_provider((EVP_PKEY *)from, NULL, &to_keymgmt,
178 NULL);
179
acb90ba8
RL
180 /*
181 * If we get a NULL, it could be an internal error, or it could be
182 * that there's a key mismatch. We're pretending the latter...
183 */
ff3b59e1 184 if (from_keydata == NULL) {
acb90ba8 185 ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES);
ff3b59e1
RL
186 return 0;
187 }
188 return evp_keymgmt_copy(to->keymgmt, to->keydata, from_keydata,
8158cf20 189 SELECT_PARAMETERS);
ff3b59e1
RL
190 }
191
192 /* Both keys are legacy */
193 if (from->ameth != NULL && from->ameth->param_copy != NULL)
0f113f3e
MC
194 return from->ameth->param_copy(to, from);
195 err:
196 return 0;
197}
d02b48c6 198
af0f0f3e 199int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey)
0f113f3e 200{
157ded39
RL
201 if (pkey != NULL) {
202 if (pkey->keymgmt != NULL)
8158cf20 203 return !evp_keymgmt_util_has((EVP_PKEY *)pkey, SELECT_PARAMETERS);
157ded39
RL
204 else if (pkey->ameth != NULL && pkey->ameth->param_missing != NULL)
205 return pkey->ameth->param_missing(pkey);
206 }
0f113f3e
MC
207 return 0;
208}
d02b48c6 209
1e9101c4
RL
210/*
211 * This function is called for any mixture of keys except pure legacy pair.
212 * TODO When legacy keys are gone, we replace a call to this functions with
213 * a call to evp_keymgmt_util_match().
214 */
215static int evp_pkey_cmp_any(const EVP_PKEY *a, const EVP_PKEY *b,
216 int selection)
217{
218 EVP_KEYMGMT *keymgmt1 = NULL, *keymgmt2 = NULL;
219 void *keydata1 = NULL, *keydata2 = NULL, *tmp_keydata = NULL;
220
221 /* If none of them are provided, this function shouldn't have been called */
222 if (!ossl_assert(a->keymgmt != NULL || b->keymgmt != NULL))
223 return -2;
224
225 /* For purely provided keys, we just call the keymgmt utility */
226 if (a->keymgmt != NULL && b->keymgmt != NULL)
227 return evp_keymgmt_util_match((EVP_PKEY *)a, (EVP_PKEY *)b, selection);
228
229 /*
acb90ba8
RL
230 * At this point, one of them is provided, the other not. This allows
231 * us to compare types using legacy NIDs.
232 */
233 if ((a->type != EVP_PKEY_NONE
dc8908bf
P
234 && (b->keymgmt == NULL
235 || !EVP_KEYMGMT_is_a(b->keymgmt, OBJ_nid2sn(a->type))))
acb90ba8 236 || (b->type != EVP_PKEY_NONE
dc8908bf
P
237 && (a->keymgmt == NULL
238 || !EVP_KEYMGMT_is_a(a->keymgmt, OBJ_nid2sn(b->type)))))
acb90ba8
RL
239 return -1; /* not the same key type */
240
241 /*
242 * We've determined that they both are the same keytype, so the next
243 * step is to do a bit of cross export to ensure we have keydata for
244 * both keys in the same keymgmt.
1e9101c4
RL
245 */
246 keymgmt1 = a->keymgmt;
247 keydata1 = a->keydata;
248 keymgmt2 = b->keymgmt;
249 keydata2 = b->keydata;
250
1e9101c4
RL
251 if (keymgmt2 != NULL && keymgmt2->match != NULL) {
252 tmp_keydata =
253 evp_pkey_export_to_provider((EVP_PKEY *)a, NULL, &keymgmt2, NULL);
254 if (tmp_keydata != NULL) {
255 keymgmt1 = keymgmt2;
256 keydata1 = tmp_keydata;
257 }
258 }
259 if (tmp_keydata == NULL && keymgmt1 != NULL && keymgmt1->match != NULL) {
260 tmp_keydata =
261 evp_pkey_export_to_provider((EVP_PKEY *)b, NULL, &keymgmt1, NULL);
262 if (tmp_keydata != NULL) {
263 keymgmt2 = keymgmt1;
264 keydata2 = tmp_keydata;
265 }
266 }
267
268 /* If we still don't have matching keymgmt implementations, we give up */
269 if (keymgmt1 != keymgmt2)
270 return -2;
271
272 return evp_keymgmt_match(keymgmt1, keydata1, keydata2, selection);
273}
274
af0f0f3e 275int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
0f113f3e 276{
1e9101c4
RL
277 /*
278 * TODO: clean up legacy stuff from this function when legacy support
279 * is gone.
280 */
281
282 if (a->keymgmt != NULL || b->keymgmt != NULL)
8158cf20 283 return evp_pkey_cmp_any(a, b, SELECT_PARAMETERS);
1e9101c4
RL
284
285 /* All legacy keys */
0f113f3e
MC
286 if (a->type != b->type)
287 return -1;
1e9101c4 288 if (a->ameth != NULL && a->ameth->param_cmp != NULL)
0f113f3e
MC
289 return a->ameth->param_cmp(a, b);
290 return -2;
291}
58964a49 292
af0f0f3e 293int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
0f113f3e 294{
1e9101c4
RL
295 /*
296 * TODO: clean up legacy stuff from this function when legacy support
297 * is gone.
298 */
299
300 if (a->keymgmt != NULL || b->keymgmt != NULL)
8158cf20
RL
301 return evp_pkey_cmp_any(a, b, (SELECT_PARAMETERS
302 | OSSL_KEYMGMT_SELECT_PUBLIC_KEY));
1e9101c4
RL
303
304 /* All legacy keys */
0f113f3e
MC
305 if (a->type != b->type)
306 return -1;
307
1e9101c4 308 if (a->ameth != NULL) {
0f113f3e
MC
309 int ret;
310 /* Compare parameters if the algorithm has them */
1e9101c4 311 if (a->ameth->param_cmp != NULL) {
0f113f3e
MC
312 ret = a->ameth->param_cmp(a, b);
313 if (ret <= 0)
314 return ret;
315 }
316
1e9101c4 317 if (a->ameth->pub_cmp != NULL)
0f113f3e
MC
318 return a->ameth->pub_cmp(a, b);
319 }
320
321 return -2;
322}
e6526fbf 323
1c4f340d
MC
324
325static EVP_PKEY *new_raw_key_int(OPENSSL_CTX *libctx,
326 const char *strtype,
327 const char *propq,
328 int nidtype,
329 ENGINE *e,
330 const unsigned char *key,
331 size_t len,
332 int key_is_priv)
a08802ce 333{
1c4f340d
MC
334 EVP_PKEY *pkey = NULL;
335 EVP_PKEY_CTX *ctx = NULL;
336 const EVP_PKEY_ASN1_METHOD *ameth = NULL;
337 int result = 0;
338
339# ifndef OPENSSL_NO_ENGINE
340 /* Check if there is an Engine for this type */
341 if (e == NULL) {
342 ENGINE *tmpe = NULL;
343
344 if (strtype != NULL)
345 ameth = EVP_PKEY_asn1_find_str(&tmpe, strtype, -1);
346 else if (nidtype != EVP_PKEY_NONE)
347 ameth = EVP_PKEY_asn1_find(&tmpe, nidtype);
348
349 /* If tmpe is NULL then no engine is claiming to support this type */
350 if (tmpe == NULL)
351 ameth = NULL;
352
353 ENGINE_finish(tmpe);
354 }
355# endif
a08802ce 356
1c4f340d
MC
357 if (e == NULL && ameth == NULL) {
358 /*
359 * No engine is claiming to support this type, so lets see if we have
360 * a provider.
361 */
362 ctx = EVP_PKEY_CTX_new_from_name(libctx,
363 strtype != NULL ? strtype
364 : OBJ_nid2sn(nidtype),
365 propq);
366 if (ctx == NULL) {
367 EVPerr(0, ERR_R_MALLOC_FAILURE);
368 goto err;
369 }
370 /* May fail if no provider available */
371 ERR_set_mark();
372 if (EVP_PKEY_key_fromdata_init(ctx) == 1) {
373 OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
374
375 ERR_clear_last_mark();
376 params[0] = OSSL_PARAM_construct_octet_string(
377 key_is_priv ? OSSL_PKEY_PARAM_PRIV_KEY
378 : OSSL_PKEY_PARAM_PUB_KEY,
379 (void *)key, len);
380
381 if (EVP_PKEY_fromdata(ctx, &pkey, params) != 1) {
382 EVPerr(0, EVP_R_KEY_SETUP_FAILED);
383 goto err;
384 }
385
386 EVP_PKEY_CTX_free(ctx);
387
388 return pkey;
389 }
390 ERR_pop_to_mark();
391 /* else not supported so fallback to legacy */
a08802ce
MC
392 }
393
1c4f340d
MC
394 /* Legacy code path */
395
396 pkey = EVP_PKEY_new();
397 if (pkey == NULL) {
398 EVPerr(0, ERR_R_MALLOC_FAILURE);
a08802ce
MC
399 goto err;
400 }
401
1c4f340d
MC
402 if (!pkey_set_type(pkey, e, nidtype, strtype, -1, NULL)) {
403 /* EVPerr already called */
a08802ce
MC
404 goto err;
405 }
406
1c4f340d
MC
407 if (!ossl_assert(pkey->ameth != NULL))
408 goto err;
a08802ce 409
1c4f340d
MC
410 if (key_is_priv) {
411 if (pkey->ameth->set_priv_key == NULL) {
412 EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
413 goto err;
414 }
a08802ce 415
1c4f340d
MC
416 if (!pkey->ameth->set_priv_key(pkey, key, len)) {
417 EVPerr(0, EVP_R_KEY_SETUP_FAILED);
418 goto err;
419 }
420 } else {
421 if (pkey->ameth->set_pub_key == NULL) {
422 EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
423 goto err;
424 }
a08802ce 425
1c4f340d
MC
426 if (!pkey->ameth->set_pub_key(pkey, key, len)) {
427 EVPerr(0, EVP_R_KEY_SETUP_FAILED);
428 goto err;
429 }
a08802ce
MC
430 }
431
1c4f340d
MC
432 result = 1;
433 err:
434 if (!result) {
435 EVP_PKEY_free(pkey);
436 pkey = NULL;
a08802ce 437 }
1c4f340d
MC
438 EVP_PKEY_CTX_free(ctx);
439 return pkey;
440}
a08802ce 441
1c4f340d
MC
442EVP_PKEY *EVP_PKEY_new_raw_private_key_with_libctx(OPENSSL_CTX *libctx,
443 const char *keytype,
444 const char *propq,
445 const unsigned char *priv,
446 size_t len)
447{
448 return new_raw_key_int(libctx, keytype, propq, EVP_PKEY_NONE, NULL, priv,
449 len, 1);
450}
a08802ce 451
1c4f340d
MC
452EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *e,
453 const unsigned char *priv,
454 size_t len)
455{
456 return new_raw_key_int(NULL, NULL, NULL, type, e, priv, len, 1);
457}
a08802ce 458
1c4f340d
MC
459EVP_PKEY *EVP_PKEY_new_raw_public_key_with_libctx(OPENSSL_CTX *libctx,
460 const char *keytype,
461 const char *propq,
462 const unsigned char *pub,
463 size_t len)
464{
465 return new_raw_key_int(libctx, keytype, propq, EVP_PKEY_NONE, NULL, pub,
466 len, 0);
467}
468
469EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *e,
470 const unsigned char *pub,
471 size_t len)
472{
473 return new_raw_key_int(NULL, NULL, NULL, type, e, pub, len, 0);
a08802ce
MC
474}
475
c19d8978
MC
476struct raw_key_details_st
477{
478 unsigned char **key;
479 size_t *len;
480 int selection;
481};
482
483static OSSL_CALLBACK get_raw_key_details;
484static int get_raw_key_details(const OSSL_PARAM params[], void *arg)
485{
486 const OSSL_PARAM *p = NULL;
487 struct raw_key_details_st *raw_key = arg;
488
489 if (raw_key->selection == OSSL_KEYMGMT_SELECT_PRIVATE_KEY) {
490 if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY))
491 != NULL)
492 return OSSL_PARAM_get_octet_string(p, (void **)raw_key->key,
493 SIZE_MAX, raw_key->len);
494 } else if (raw_key->selection == OSSL_KEYMGMT_SELECT_PUBLIC_KEY) {
495 if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY))
496 != NULL)
497 return OSSL_PARAM_get_octet_string(p, (void **)raw_key->key,
498 SIZE_MAX, raw_key->len);
499 }
500
501 return 0;
502}
503
0d124b0a
MC
504int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, unsigned char *priv,
505 size_t *len)
506{
c19d8978
MC
507 if (pkey->keymgmt != NULL) {
508 struct raw_key_details_st raw_key;
509
510 raw_key.key = priv == NULL ? NULL : &priv;
511 raw_key.len = len;
512 raw_key.selection = OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
513
514 return evp_keymgmt_export(pkey->keymgmt, pkey->keydata,
515 OSSL_KEYMGMT_SELECT_PRIVATE_KEY,
516 get_raw_key_details, &raw_key);
517 }
518
519 if (pkey->ameth == NULL) {
520 EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
521 return 0;
522 }
523
524 if (pkey->ameth->get_priv_key == NULL) {
525 EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
0d124b0a
MC
526 return 0;
527 }
528
529 if (!pkey->ameth->get_priv_key(pkey, priv, len)) {
c19d8978 530 EVPerr(0, EVP_R_GET_RAW_KEY_FAILED);
0d124b0a
MC
531 return 0;
532 }
533
534 return 1;
535}
536
537int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub,
538 size_t *len)
539{
c19d8978
MC
540 if (pkey->keymgmt != NULL) {
541 struct raw_key_details_st raw_key;
542
543 raw_key.key = pub == NULL ? NULL : &pub;
544 raw_key.len = len;
545 raw_key.selection = OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
546
547 return evp_keymgmt_export(pkey->keymgmt, pkey->keydata,
548 OSSL_KEYMGMT_SELECT_PUBLIC_KEY,
549 get_raw_key_details, &raw_key);
550 }
551
552 if (pkey->ameth == NULL) {
553 EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
554 return 0;
555 }
556
0d124b0a
MC
557 if (pkey->ameth->get_pub_key == NULL) {
558 EVPerr(EVP_F_EVP_PKEY_GET_RAW_PUBLIC_KEY,
559 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
560 return 0;
561 }
562
563 if (!pkey->ameth->get_pub_key(pkey, pub, len)) {
564 EVPerr(EVP_F_EVP_PKEY_GET_RAW_PUBLIC_KEY, EVP_R_GET_RAW_KEY_FAILED);
565 return 0;
566 }
567
568 return 1;
569}
570
b3831fbb
MC
571EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
572 size_t len, const EVP_CIPHER *cipher)
573{
e683582b
SL
574# ifndef OPENSSL_NO_CMAC
575# ifndef OPENSSL_NO_ENGINE
9a7846df 576 const char *engine_id = e != NULL ? ENGINE_get_id(e) : NULL;
e683582b 577# endif
e74bd290
RL
578 const char *cipher_name = EVP_CIPHER_name(cipher);
579 const OSSL_PROVIDER *prov = EVP_CIPHER_provider(cipher);
580 OPENSSL_CTX *libctx =
581 prov == NULL ? NULL : ossl_provider_library_context(prov);
b3831fbb 582 EVP_PKEY *ret = EVP_PKEY_new();
81ff9eeb 583 EVP_MAC *cmac = EVP_MAC_fetch(libctx, OSSL_MAC_NAME_CMAC, NULL);
e74bd290
RL
584 EVP_MAC_CTX *cmctx = cmac != NULL ? EVP_MAC_CTX_new(cmac) : NULL;
585 OSSL_PARAM params[4];
586 size_t paramsn = 0;
b3831fbb
MC
587
588 if (ret == NULL
8243d8d1
RL
589 || cmctx == NULL
590 || !pkey_set_type(ret, e, EVP_PKEY_CMAC, NULL, -1, NULL)) {
b3831fbb
MC
591 /* EVPerr already called */
592 goto err;
593 }
594
e683582b 595# ifndef OPENSSL_NO_ENGINE
9a7846df 596 if (engine_id != NULL)
e74bd290 597 params[paramsn++] =
69db3044 598 OSSL_PARAM_construct_utf8_string("engine", (char *)engine_id, 0);
e683582b 599# endif
3be06e0d 600
e74bd290 601 params[paramsn++] =
703170d4 602 OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER,
7f588d20 603 (char *)cipher_name, 0);
e74bd290
RL
604 params[paramsn++] =
605 OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
606 (char *)priv, len);
607 params[paramsn] = OSSL_PARAM_construct_end();
608
609 if (!EVP_MAC_CTX_set_params(cmctx, params)) {
b3831fbb
MC
610 EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY, EVP_R_KEY_SETUP_FAILED);
611 goto err;
612 }
613
614 ret->pkey.ptr = cmctx;
615 return ret;
616
617 err:
618 EVP_PKEY_free(ret);
b8d77c9b 619 EVP_MAC_CTX_free(cmctx);
e74bd290 620 EVP_MAC_free(cmac);
b3831fbb 621 return NULL;
e683582b 622# else
df6d51e2
MC
623 EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY,
624 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
625 return NULL;
e683582b 626# endif
b3831fbb 627}
a08802ce 628
01b8b3c7 629int EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
0f113f3e 630{
8243d8d1 631 return pkey_set_type(pkey, NULL, type, NULL, -1, NULL);
0f113f3e 632}
01b8b3c7
DSH
633
634int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len)
0f113f3e 635{
8243d8d1 636 return pkey_set_type(pkey, NULL, EVP_PKEY_NONE, str, len, NULL);
0f113f3e 637}
2f2e6b62
JL
638
639int EVP_PKEY_set_alias_type(EVP_PKEY *pkey, int type)
640{
641 if (pkey->type == type) {
642 return 1; /* it already is that type */
643 }
644
645 /*
646 * The application is requesting to alias this to a different pkey type,
647 * but not one that resolves to the base type.
648 */
649 if (EVP_PKEY_type(type) != EVP_PKEY_base_id(pkey)) {
650 EVPerr(EVP_F_EVP_PKEY_SET_ALIAS_TYPE, EVP_R_UNSUPPORTED_ALGORITHM);
651 return 0;
652 }
653
654 pkey->type = type;
655 return 1;
656}
657
e683582b 658# ifndef OPENSSL_NO_ENGINE
d19b01ad
DSH
659int EVP_PKEY_set1_engine(EVP_PKEY *pkey, ENGINE *e)
660{
661 if (e != NULL) {
662 if (!ENGINE_init(e)) {
663 EVPerr(EVP_F_EVP_PKEY_SET1_ENGINE, ERR_R_ENGINE_LIB);
664 return 0;
665 }
666 if (ENGINE_get_pkey_meth(e, pkey->type) == NULL) {
667 ENGINE_finish(e);
668 EVPerr(EVP_F_EVP_PKEY_SET1_ENGINE, EVP_R_UNSUPPORTED_ALGORITHM);
669 return 0;
670 }
671 }
672 ENGINE_finish(pkey->pmeth_engine);
673 pkey->pmeth_engine = e;
674 return 1;
675}
229f7b38
DB
676
677ENGINE *EVP_PKEY_get0_engine(const EVP_PKEY *pkey)
678{
679 return pkey->engine;
680}
e683582b 681# endif
01b8b3c7 682int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
0f113f3e 683{
f4e4382c
RL
684 int alias = type;
685
ad5b71be 686#ifndef OPENSSL_NO_EC
f4e4382c
RL
687 if (EVP_PKEY_type(type) == EVP_PKEY_EC) {
688 const EC_GROUP *group = EC_KEY_get0_group(key);
689
690 if (group != NULL && EC_GROUP_get_curve_name(group) == NID_sm2)
691 alias = EVP_PKEY_SM2;
692 }
ad5b71be 693#endif
f4e4382c 694
e34c66c6 695 if (pkey == NULL || !EVP_PKEY_set_type(pkey, type))
0f113f3e 696 return 0;
f4e4382c
RL
697 if (!EVP_PKEY_set_alias_type(pkey, alias))
698 return 0;
0f113f3e
MC
699 pkey->pkey.ptr = key;
700 return (key != NULL);
701}
d02b48c6 702
3aeb9348 703void *EVP_PKEY_get0(const EVP_PKEY *pkey)
0f113f3e 704{
acb90ba8
RL
705 if (!evp_pkey_downgrade((EVP_PKEY *)pkey)) {
706 ERR_raise(ERR_LIB_EVP, EVP_R_INACCESSIBLE_KEY);
707 return NULL;
708 }
0f113f3e
MC
709 return pkey->pkey.ptr;
710}
db98bbc1 711
ebad0b0b
NM
712const unsigned char *EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len)
713{
714 ASN1_OCTET_STRING *os = NULL;
715 if (pkey->type != EVP_PKEY_HMAC) {
716 EVPerr(EVP_F_EVP_PKEY_GET0_HMAC, EVP_R_EXPECTING_AN_HMAC_KEY);
717 return NULL;
718 }
719 os = EVP_PKEY_get0(pkey);
720 *len = os->length;
721 return os->data;
722}
723
e683582b 724# ifndef OPENSSL_NO_POLY1305
52ad5b60
TS
725const unsigned char *EVP_PKEY_get0_poly1305(const EVP_PKEY *pkey, size_t *len)
726{
727 ASN1_OCTET_STRING *os = NULL;
728 if (pkey->type != EVP_PKEY_POLY1305) {
729 EVPerr(EVP_F_EVP_PKEY_GET0_POLY1305, EVP_R_EXPECTING_A_POLY1305_KEY);
730 return NULL;
731 }
732 os = EVP_PKEY_get0(pkey);
733 *len = os->length;
734 return os->data;
735}
e683582b 736# endif
52ad5b60 737
e683582b 738# ifndef OPENSSL_NO_SIPHASH
3f5616d7
TS
739const unsigned char *EVP_PKEY_get0_siphash(const EVP_PKEY *pkey, size_t *len)
740{
741 ASN1_OCTET_STRING *os = NULL;
742
743 if (pkey->type != EVP_PKEY_SIPHASH) {
744 EVPerr(EVP_F_EVP_PKEY_GET0_SIPHASH, EVP_R_EXPECTING_A_SIPHASH_KEY);
745 return NULL;
746 }
747 os = EVP_PKEY_get0(pkey);
748 *len = os->length;
749 return os->data;
750}
e683582b 751# endif
3f5616d7 752
e683582b 753# ifndef OPENSSL_NO_RSA
c7cb16a8 754int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key)
52664f50 755{
0f113f3e
MC
756 int ret = EVP_PKEY_assign_RSA(pkey, key);
757 if (ret)
758 RSA_up_ref(key);
759 return ret;
52664f50
DSH
760}
761
9fdcc21f 762RSA *EVP_PKEY_get0_RSA(const EVP_PKEY *pkey)
0f113f3e 763{
acb90ba8
RL
764 if (!evp_pkey_downgrade((EVP_PKEY *)pkey)) {
765 ERR_raise(ERR_LIB_EVP, EVP_R_INACCESSIBLE_KEY);
766 return NULL;
767 }
465a58b1 768 if (pkey->type != EVP_PKEY_RSA && pkey->type != EVP_PKEY_RSA_PSS) {
2872dbe1 769 EVPerr(EVP_F_EVP_PKEY_GET0_RSA, EVP_R_EXPECTING_AN_RSA_KEY);
0f113f3e
MC
770 return NULL;
771 }
0f113f3e 772 return pkey->pkey.rsa;
f769ce3e 773}
2872dbe1
DSH
774
775RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey)
776{
777 RSA *ret = EVP_PKEY_get0_RSA(pkey);
778 if (ret != NULL)
779 RSA_up_ref(ret);
780 return ret;
781}
e683582b 782# endif
f769ce3e 783
e683582b 784# ifndef OPENSSL_NO_DSA
9fdcc21f 785DSA *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey)
0f113f3e 786{
acb90ba8
RL
787 if (!evp_pkey_downgrade((EVP_PKEY *)pkey)) {
788 ERR_raise(ERR_LIB_EVP, EVP_R_INACCESSIBLE_KEY);
789 return NULL;
790 }
0f113f3e 791 if (pkey->type != EVP_PKEY_DSA) {
2872dbe1 792 EVPerr(EVP_F_EVP_PKEY_GET0_DSA, EVP_R_EXPECTING_A_DSA_KEY);
0f113f3e
MC
793 return NULL;
794 }
0f113f3e 795 return pkey->pkey.dsa;
f769ce3e 796}
2872dbe1 797
b03ec3b5
SL
798int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
799{
800 int ret = EVP_PKEY_assign_DSA(pkey, key);
801 if (ret)
802 DSA_up_ref(key);
803 return ret;
804}
2872dbe1
DSH
805DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey)
806{
807 DSA *ret = EVP_PKEY_get0_DSA(pkey);
808 if (ret != NULL)
809 DSA_up_ref(ret);
810 return ret;
811}
b03ec3b5 812# endif /* OPENSSL_NO_DSA */
f844f9eb 813#endif /* FIPS_MODULE */
f769ce3e 814
f844f9eb 815#ifndef FIPS_MODULE
e683582b 816# ifndef OPENSSL_NO_EC
14a7cfb3 817int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key)
4d94ae00 818{
0f113f3e
MC
819 int ret = EVP_PKEY_assign_EC_KEY(pkey, key);
820 if (ret)
821 EC_KEY_up_ref(key);
822 return ret;
4d94ae00
BM
823}
824
9fdcc21f 825EC_KEY *EVP_PKEY_get0_EC_KEY(const EVP_PKEY *pkey)
4d94ae00 826{
acb90ba8
RL
827 if (!evp_pkey_downgrade((EVP_PKEY *)pkey)) {
828 ERR_raise(ERR_LIB_EVP, EVP_R_INACCESSIBLE_KEY);
829 return NULL;
830 }
f4e4382c 831 if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC) {
2872dbe1 832 EVPerr(EVP_F_EVP_PKEY_GET0_EC_KEY, EVP_R_EXPECTING_A_EC_KEY);
0f113f3e
MC
833 return NULL;
834 }
0f113f3e 835 return pkey->pkey.ec;
4d94ae00 836}
2872dbe1
DSH
837
838EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey)
839{
840 EC_KEY *ret = EVP_PKEY_get0_EC_KEY(pkey);
841 if (ret != NULL)
842 EC_KEY_up_ref(ret);
843 return ret;
844}
e683582b 845# endif
4d94ae00 846
e683582b 847# ifndef OPENSSL_NO_DH
52664f50 848
c7cb16a8 849int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key)
52664f50 850{
32c869ff
MC
851 int type = DH_get0_q(key) == NULL ? EVP_PKEY_DH : EVP_PKEY_DHX;
852 int ret = EVP_PKEY_assign(pkey, type, key);
853
0f113f3e
MC
854 if (ret)
855 DH_up_ref(key);
856 return ret;
52664f50
DSH
857}
858
9fdcc21f 859DH *EVP_PKEY_get0_DH(const EVP_PKEY *pkey)
0f113f3e 860{
acb90ba8
RL
861 if (!evp_pkey_downgrade((EVP_PKEY *)pkey)) {
862 ERR_raise(ERR_LIB_EVP, EVP_R_INACCESSIBLE_KEY);
863 return NULL;
864 }
0f113f3e 865 if (pkey->type != EVP_PKEY_DH && pkey->type != EVP_PKEY_DHX) {
2872dbe1 866 EVPerr(EVP_F_EVP_PKEY_GET0_DH, EVP_R_EXPECTING_A_DH_KEY);
0f113f3e
MC
867 return NULL;
868 }
0f113f3e 869 return pkey->pkey.dh;
f769ce3e 870}
2872dbe1
DSH
871
872DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey)
873{
874 DH *ret = EVP_PKEY_get0_DH(pkey);
875 if (ret != NULL)
876 DH_up_ref(ret);
877 return ret;
878}
e683582b 879# endif
f769ce3e 880
6b691a5c 881int EVP_PKEY_type(int type)
0f113f3e
MC
882{
883 int ret;
884 const EVP_PKEY_ASN1_METHOD *ameth;
885 ENGINE *e;
886 ameth = EVP_PKEY_asn1_find(&e, type);
887 if (ameth)
888 ret = ameth->pkey_id;
889 else
890 ret = NID_undef;
e683582b 891# ifndef OPENSSL_NO_ENGINE
7c96dbcd 892 ENGINE_finish(e);
e683582b 893# endif
0f113f3e
MC
894 return ret;
895}
d02b48c6 896
7f57b076 897int EVP_PKEY_id(const EVP_PKEY *pkey)
0f113f3e
MC
898{
899 return pkey->type;
900}
7f57b076
DSH
901
902int EVP_PKEY_base_id(const EVP_PKEY *pkey)
0f113f3e
MC
903{
904 return EVP_PKEY_type(pkey->type);
905}
7f57b076 906
4f76d62f
RL
907int EVP_PKEY_is_a(const EVP_PKEY *pkey, const char *name)
908{
f844f9eb 909#ifndef FIPS_MODULE
4f76d62f
RL
910 if (pkey->keymgmt == NULL) {
911 /*
912 * These hard coded cases are pure hackery to get around the fact
913 * that names in crypto/objects/objects.txt are a mess. There is
914 * no "EC", and "RSA" leads to the NID for 2.5.8.1.1, an OID that's
915 * fallen out in favor of { pkcs-1 1 }, i.e. 1.2.840.113549.1.1.1,
916 * the NID of which is used for EVP_PKEY_RSA. Strangely enough,
917 * "DSA" is accurate... but still, better be safe and hard-code
918 * names that we know.
919 * TODO Clean this away along with all other #legacy support.
920 */
921 int type;
922
923 if (strcasecmp(name, "RSA") == 0)
924 type = EVP_PKEY_RSA;
925#ifndef OPENSSL_NO_EC
926 else if (strcasecmp(name, "EC") == 0)
927 type = EVP_PKEY_EC;
928#endif
929#ifndef OPENSSL_NO_DSA
930 else if (strcasecmp(name, "DSA") == 0)
931 type = EVP_PKEY_DSA;
932#endif
933 else
934 type = EVP_PKEY_type(OBJ_sn2nid(name));
935 return EVP_PKEY_type(pkey->type) == type;
936 }
937#endif
938 return EVP_KEYMGMT_is_a(pkey->keymgmt, name);
939}
940
941int EVP_PKEY_can_sign(const EVP_PKEY *pkey)
942{
943 if (pkey->keymgmt == NULL) {
944 switch (EVP_PKEY_base_id(pkey)) {
945 case EVP_PKEY_RSA:
946 return 1;
947#ifndef OPENSSL_NO_DSA
948 case EVP_PKEY_DSA:
949 return 1;
950#endif
951#ifndef OPENSSL_NO_EC
952 case EVP_PKEY_ED25519:
953 case EVP_PKEY_ED448:
954 return 1;
955 case EVP_PKEY_EC: /* Including SM2 */
956 return EC_KEY_can_sign(pkey->pkey.ec);
957#endif
958 default:
959 break;
960 }
961 } else {
962 const OSSL_PROVIDER *prov = EVP_KEYMGMT_provider(pkey->keymgmt);
963 OPENSSL_CTX *libctx = ossl_provider_library_context(prov);
964 const char *supported_sig =
965 pkey->keymgmt->query_operation_name != NULL
966 ? pkey->keymgmt->query_operation_name(OSSL_OP_SIGNATURE)
967 : evp_first_name(prov, pkey->keymgmt->name_id);
968 EVP_SIGNATURE *signature = NULL;
969
970 signature = EVP_SIGNATURE_fetch(libctx, supported_sig, NULL);
971 if (signature != NULL) {
972 EVP_SIGNATURE_free(signature);
973 return 1;
974 }
975 }
976 return 0;
977}
d02b48c6 978
c2041da8
RL
979#ifndef OPENSSL_NO_EC
980/*
981 * TODO rewrite when we have proper data extraction functions
982 * Note: an octet pointer would be desirable!
983 */
984static OSSL_CALLBACK get_ec_curve_name_cb;
985static int get_ec_curve_name_cb(const OSSL_PARAM params[], void *arg)
986{
987 const OSSL_PARAM *p = NULL;
988
989 if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_NAME)) != NULL)
990 return OSSL_PARAM_get_utf8_string(p, arg, 0);
991
992 /* If there is no curve name, this is not an EC key */
993 return 0;
994}
995
996int evp_pkey_get_EC_KEY_curve_nid(const EVP_PKEY *pkey)
997{
998 int ret = NID_undef;
999
1000 if (pkey->keymgmt == NULL) {
1001 if (EVP_PKEY_base_id(pkey) == EVP_PKEY_EC) {
1002 EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey);
1003
1004 ret = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
1005 }
1006 } else if (EVP_PKEY_is_a(pkey, "EC") || EVP_PKEY_is_a(pkey, "SM2")) {
1007 char *curve_name = NULL;
1008
1009 ret = evp_keymgmt_export(pkey->keymgmt, pkey->keydata,
1010 OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
1011 get_ec_curve_name_cb, &curve_name);
1012 if (ret)
1013 ret = ec_curve_name2nid(curve_name);
1014 OPENSSL_free(curve_name);
1015 }
1016
1017 return ret;
1018}
1019#endif
1020
f1299839
RL
1021static int print_reset_indent(BIO **out, int pop_f_prefix, long saved_indent)
1022{
1023 BIO_set_indent(*out, saved_indent);
1024 if (pop_f_prefix) {
1025 BIO *next = BIO_pop(*out);
1026
1027 BIO_free(*out);
1028 *out = next;
1029 }
1030 return 1;
1031}
1032
1033static int print_set_indent(BIO **out, int *pop_f_prefix, long *saved_indent,
1034 long indent)
1035{
1036 *pop_f_prefix = 0;
1037 *saved_indent = 0;
1038 if (indent > 0) {
1039 long i = BIO_get_indent(*out);
1040
1041 *saved_indent = (i < 0 ? 0 : i);
1042 if (BIO_set_indent(*out, indent) <= 0) {
1043 if ((*out = BIO_push(BIO_new(BIO_f_prefix()), *out)) == NULL)
1044 return 0;
1045 *pop_f_prefix = 1;
1046 }
1047 if (BIO_set_indent(*out, indent) <= 0) {
1048 print_reset_indent(out, *pop_f_prefix, *saved_indent);
1049 return 0;
1050 }
1051 }
1052 return 1;
1053}
1054
35208f36 1055static int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent,
0f113f3e
MC
1056 const char *kstr)
1057{
5310a4e6
P
1058 return BIO_indent(out, indent, 128)
1059 && BIO_printf(out, "%s algorithm \"%s\" unsupported\n",
1060 kstr, OBJ_nid2ln(pkey->type)) > 0;
0f113f3e 1061}
35208f36 1062
f1299839
RL
1063static int print_pkey(const EVP_PKEY *pkey, BIO *out, int indent,
1064 const char *propquery /* For provided serialization */,
1065 int (*legacy_print)(BIO *out, const EVP_PKEY *pkey,
1066 int indent, ASN1_PCTX *pctx),
1067 ASN1_PCTX *legacy_pctx /* For legacy print */)
0f113f3e 1068{
f1299839
RL
1069 int pop_f_prefix;
1070 long saved_indent;
1071 OSSL_SERIALIZER_CTX *ctx = NULL;
1072 int ret = -2; /* default to unsupported */
1073
1074 if (!print_set_indent(&out, &pop_f_prefix, &saved_indent, indent))
1075 return 0;
54c1711f 1076
f1299839 1077 ctx = OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(pkey, propquery);
54c1711f
RL
1078 if (OSSL_SERIALIZER_CTX_get_serializer(ctx) != NULL)
1079 ret = OSSL_SERIALIZER_to_bio(ctx, out);
1080 OSSL_SERIALIZER_CTX_free(ctx);
1081
1082 if (ret != -2)
f1299839 1083 goto end;
54c1711f
RL
1084
1085 /* legacy fallback */
f1299839
RL
1086 if (legacy_print != NULL)
1087 ret = legacy_print(out, pkey, 0, legacy_pctx);
1088 else
1089 ret = unsup_alg(out, pkey, 0, "Public Key");
0f113f3e 1090
f1299839
RL
1091 end:
1092 print_reset_indent(&out, pop_f_prefix, saved_indent);
1093 return ret;
1094}
1095
1096int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
1097 int indent, ASN1_PCTX *pctx)
1098{
1099 return print_pkey(pkey, out, indent, OSSL_SERIALIZER_PUBKEY_TO_TEXT_PQ,
1100 (pkey->ameth != NULL ? pkey->ameth->pub_print : NULL),
1101 pctx);
0f113f3e 1102}
35208f36
DSH
1103
1104int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
0f113f3e
MC
1105 int indent, ASN1_PCTX *pctx)
1106{
f1299839
RL
1107 return print_pkey(pkey, out, indent, OSSL_SERIALIZER_PrivateKey_TO_TEXT_PQ,
1108 (pkey->ameth != NULL ? pkey->ameth->priv_print : NULL),
1109 pctx);
0f113f3e 1110}
35208f36
DSH
1111
1112int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
0f113f3e
MC
1113 int indent, ASN1_PCTX *pctx)
1114{
f1299839
RL
1115 return print_pkey(pkey, out, indent, OSSL_SERIALIZER_Parameters_TO_TEXT_PQ,
1116 (pkey->ameth != NULL ? pkey->ameth->param_print : NULL),
1117 pctx);
0f113f3e 1118}
03919683 1119
ead0d234
RL
1120static int legacy_asn1_ctrl_to_param(EVP_PKEY *pkey, int op,
1121 int arg1, void *arg2)
1122{
3c6ed955 1123 if (pkey->keymgmt == NULL)
ead0d234
RL
1124 return 0;
1125 switch (op) {
1126 case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
1127 {
1128 char mdname[80] = "";
1129 int nid;
1130 int rv = EVP_PKEY_get_default_digest_name(pkey, mdname,
1131 sizeof(mdname));
1132
1133 if (rv <= 0)
1134 return rv;
1135 nid = OBJ_sn2nid(mdname);
1136 if (nid == NID_undef)
1137 nid = OBJ_ln2nid(mdname);
1138 if (nid == NID_undef)
1139 return 0;
1140 *(int *)arg2 = nid;
1141 return 1;
1142 }
1143 default:
1144 return -2;
1145 }
1146}
1147
5d6aaf8a 1148static int evp_pkey_asn1_ctrl(EVP_PKEY *pkey, int op, int arg1, void *arg2)
0f113f3e 1149{
ead0d234
RL
1150 if (pkey->ameth == NULL)
1151 return legacy_asn1_ctrl_to_param(pkey, op, arg1, arg2);
1152 if (pkey->ameth->pkey_ctrl == NULL)
0f113f3e 1153 return -2;
5d6aaf8a
DSH
1154 return pkey->ameth->pkey_ctrl(pkey, op, arg1, arg2);
1155}
1156
1157int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid)
1158{
1159 return evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID, 0, pnid);
1160}
1161
ead0d234
RL
1162int EVP_PKEY_get_default_digest_name(EVP_PKEY *pkey,
1163 char *mdname, size_t mdname_sz)
1164{
3b924da0
RL
1165 if (pkey->ameth == NULL)
1166 return evp_keymgmt_util_get_deflt_digest_name(pkey->keymgmt,
1167 pkey->keydata,
1168 mdname, mdname_sz);
ead0d234
RL
1169
1170 {
1171 int nid = NID_undef;
1172 int rv = EVP_PKEY_get_default_digest_nid(pkey, &nid);
1173 const char *name = rv > 0 ? OBJ_nid2sn(nid) : NULL;
1174
1175 if (rv > 0)
1176 OPENSSL_strlcpy(mdname, name, mdname_sz);
1177 return rv;
1178 }
1179}
1180
ecbb2fca
DW
1181int EVP_PKEY_supports_digest_nid(EVP_PKEY *pkey, int nid)
1182{
1183 int rv, default_nid;
1184
1185 rv = evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_SUPPORTS_MD_NID, nid, NULL);
1186 if (rv == -2) {
1187 /*
1188 * If there is a mandatory default digest and this isn't it, then
1189 * the answer is 'no'.
1190 */
1191 rv = EVP_PKEY_get_default_digest_nid(pkey, &default_nid);
1192 if (rv == 2)
1193 return (nid == default_nid);
1194 /* zero is an error from EVP_PKEY_get_default_digest_nid() */
1195 if (rv == 0)
1196 return -1;
1197 }
1198 return rv;
1199}
1200
5d6aaf8a
DSH
1201int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey,
1202 const unsigned char *pt, size_t ptlen)
1203{
1204 if (ptlen > INT_MAX)
1205 return 0;
1206 if (evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_SET1_TLS_ENCPT, ptlen,
1207 (void *)pt) <= 0)
1208 return 0;
1209 return 1;
1210}
1211
1212size_t EVP_PKEY_get1_tls_encodedpoint(EVP_PKEY *pkey, unsigned char **ppt)
1213{
1214 int rv;
1215 rv = evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_GET1_TLS_ENCPT, 0, ppt);
1216 if (rv <= 0)
1217 return 0;
1218 return rv;
0f113f3e 1219}
e683582b 1220
f844f9eb 1221#endif /* FIPS_MODULE */
e683582b 1222
f844f9eb 1223/*- All methods below can also be used in FIPS_MODULE */
e683582b
SL
1224
1225EVP_PKEY *EVP_PKEY_new(void)
1226{
1227 EVP_PKEY *ret = OPENSSL_zalloc(sizeof(*ret));
1228
1229 if (ret == NULL) {
1230 EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE);
1231 return NULL;
1232 }
1233 ret->type = EVP_PKEY_NONE;
1234 ret->save_type = EVP_PKEY_NONE;
1235 ret->references = 1;
1236 ret->save_parameters = 1;
1237 ret->lock = CRYPTO_THREAD_lock_new();
1238 if (ret->lock == NULL) {
1239 EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE);
ff1f7cde
AT
1240 goto err;
1241 }
f844f9eb 1242#ifndef FIPS_MODULE
ff1f7cde
AT
1243 if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_EVP_PKEY, ret, &ret->ex_data)) {
1244 EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE);
1245 goto err;
e683582b 1246 }
ff1f7cde 1247#endif
e683582b 1248 return ret;
ff1f7cde
AT
1249
1250 err:
1251 CRYPTO_THREAD_lock_free(ret->lock);
1252 OPENSSL_free(ret);
1253 return NULL;
e683582b
SL
1254}
1255
8243d8d1
RL
1256/*
1257 * Setup a public key management method.
1258 *
1259 * For legacy keys, either |type| or |str| is expected to have the type
1260 * information. In this case, the setup consists of finding an ASN1 method
1261 * and potentially an ENGINE, and setting those fields in |pkey|.
1262 *
1263 * For provider side keys, |keymgmt| is expected to be non-NULL. In this
1264 * case, the setup consists of setting the |keymgmt| field in |pkey|.
1265 *
1266 * If pkey is NULL just return 1 or 0 if the key management method exists.
1267 */
1268
1269static int pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str,
1270 int len, EVP_KEYMGMT *keymgmt)
1271{
f844f9eb 1272#ifndef FIPS_MODULE
8243d8d1
RL
1273 const EVP_PKEY_ASN1_METHOD *ameth = NULL;
1274 ENGINE **eptr = (e == NULL) ? &e : NULL;
1275#endif
1276
1277 /*
1278 * The setups can't set both legacy and provider side methods.
1279 * It is forbidden
1280 */
1281 if (!ossl_assert(type == EVP_PKEY_NONE || keymgmt == NULL)
1282 || !ossl_assert(e == NULL || keymgmt == NULL)) {
1283 ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
1284 return 0;
1285 }
1286
1287 if (pkey != NULL) {
1288 int free_it = 0;
1289
f844f9eb 1290#ifndef FIPS_MODULE
8243d8d1
RL
1291 free_it = free_it || pkey->pkey.ptr != NULL;
1292#endif
1293 free_it = free_it || pkey->keydata != NULL;
1294 if (free_it)
1295 evp_pkey_free_it(pkey);
f844f9eb 1296#ifndef FIPS_MODULE
8243d8d1
RL
1297 /*
1298 * If key type matches and a method exists then this lookup has
1299 * succeeded once so just indicate success.
1300 */
1301 if (pkey->type != EVP_PKEY_NONE
1302 && type == pkey->save_type
1303 && pkey->ameth != NULL)
1304 return 1;
1305# ifndef OPENSSL_NO_ENGINE
1306 /* If we have ENGINEs release them */
1307 ENGINE_finish(pkey->engine);
1308 pkey->engine = NULL;
1309 ENGINE_finish(pkey->pmeth_engine);
1310 pkey->pmeth_engine = NULL;
1311# endif
1312#endif
1313 }
f844f9eb 1314#ifndef FIPS_MODULE
8243d8d1
RL
1315 if (str != NULL)
1316 ameth = EVP_PKEY_asn1_find_str(eptr, str, len);
1317 else if (type != EVP_PKEY_NONE)
1318 ameth = EVP_PKEY_asn1_find(eptr, type);
1319# ifndef OPENSSL_NO_ENGINE
1320 if (pkey == NULL && eptr != NULL)
1321 ENGINE_finish(e);
1322# endif
1323#endif
1324
1325
1326 {
1327 int check = 1;
1328
f844f9eb 1329#ifndef FIPS_MODULE
8243d8d1
RL
1330 check = check && ameth == NULL;
1331#endif
1332 check = check && keymgmt == NULL;
1333 if (check) {
1334 EVPerr(EVP_F_PKEY_SET_TYPE, EVP_R_UNSUPPORTED_ALGORITHM);
1335 return 0;
1336 }
1337 }
1338 if (pkey != NULL) {
1339 if (keymgmt != NULL && !EVP_KEYMGMT_up_ref(keymgmt)) {
1340 ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
1341 return 0;
1342 }
1343
1344 pkey->keymgmt = keymgmt;
1345
1346 pkey->save_type = type;
1347 pkey->type = type;
1348
f844f9eb 1349#ifndef FIPS_MODULE
8243d8d1
RL
1350 /*
1351 * If the internal "origin" key is provider side, don't save |ameth|.
1352 * The main reason is that |ameth| is one factor to detect that the
1353 * internal "origin" key is a legacy one.
1354 */
1355 if (keymgmt == NULL)
1356 pkey->ameth = ameth;
1357 pkey->engine = e;
1358
1359 /*
1360 * The EVP_PKEY_ASN1_METHOD |pkey_id| serves different purposes,
1361 * depending on if we're setting this key to contain a legacy or
1362 * a provider side "origin" key. For a legacy key, we assign it
1363 * to the |type| field, but for a provider side key, we assign it
1364 * to the |save_type| field, because |type| is supposed to be set
1365 * to EVP_PKEY_NONE in that case.
1366 */
9dbfb11d
P
1367 if (ameth != NULL) {
1368 if (keymgmt != NULL)
1369 pkey->save_type = ameth->pkey_id;
1370 else if (pkey->ameth != NULL)
1371 pkey->type = ameth->pkey_id;
1372 }
8243d8d1
RL
1373#endif
1374 }
1375 return 1;
1376}
1377
f844f9eb 1378#ifndef FIPS_MODULE
8243d8d1
RL
1379static void find_ameth(const char *name, void *data)
1380{
1381 const char **str = data;
1382
1383 /*
1384 * The error messages from pkey_set_type() are uninteresting here,
1385 * and misleading.
1386 */
1387 ERR_set_mark();
1388
1389 if (pkey_set_type(NULL, NULL, EVP_PKEY_NONE, name, strlen(name),
1390 NULL)) {
1391 if (str[0] == NULL)
1392 str[0] = name;
1393 else if (str[1] == NULL)
1394 str[1] = name;
1395 }
1396
1397 ERR_pop_to_mark();
1398}
1399#endif
1400
1401int EVP_PKEY_set_type_by_keymgmt(EVP_PKEY *pkey, EVP_KEYMGMT *keymgmt)
1402{
f844f9eb 1403#ifndef FIPS_MODULE
8243d8d1
RL
1404# define EVP_PKEY_TYPE_STR str[0]
1405# define EVP_PKEY_TYPE_STRLEN (str[0] == NULL ? -1 : (int)strlen(str[0]))
1406 /*
1407 * Find at most two strings that have an associated EVP_PKEY_ASN1_METHOD
1408 * Ideally, only one should be found. If two (or more) are found, the
1409 * match is ambiguous. This should never happen, but...
1410 */
1411 const char *str[2] = { NULL, NULL };
1412
1413 EVP_KEYMGMT_names_do_all(keymgmt, find_ameth, &str);
1414 if (str[1] != NULL) {
1415 ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
1416 return 0;
1417 }
1418#else
1419# define EVP_PKEY_TYPE_STR NULL
1420# define EVP_PKEY_TYPE_STRLEN -1
1421#endif
1422 return pkey_set_type(pkey, NULL, EVP_PKEY_NONE,
1423 EVP_PKEY_TYPE_STR, EVP_PKEY_TYPE_STRLEN,
1424 keymgmt);
1425
1426#undef EVP_PKEY_TYPE_STR
1427#undef EVP_PKEY_TYPE_STRLEN
1428}
1429
e683582b
SL
1430int EVP_PKEY_up_ref(EVP_PKEY *pkey)
1431{
1432 int i;
1433
1434 if (CRYPTO_UP_REF(&pkey->references, &i, pkey->lock) <= 0)
1435 return 0;
1436
1437 REF_PRINT_COUNT("EVP_PKEY", pkey);
1438 REF_ASSERT_ISNT(i < 2);
1439 return ((i > 1) ? 1 : 0);
1440}
1441
f844f9eb 1442#ifndef FIPS_MODULE
62924755 1443void evp_pkey_free_legacy(EVP_PKEY *x)
badf51c8
RL
1444{
1445 if (x->ameth != NULL) {
ff3b59e1 1446 if (x->ameth->pkey_free != NULL)
badf51c8
RL
1447 x->ameth->pkey_free(x);
1448 x->pkey.ptr = NULL;
badf51c8
RL
1449 }
1450# ifndef OPENSSL_NO_ENGINE
1451 ENGINE_finish(x->engine);
1452 x->engine = NULL;
1453 ENGINE_finish(x->pmeth_engine);
1454 x->pmeth_engine = NULL;
1455# endif
8243d8d1 1456 x->type = EVP_PKEY_NONE;
badf51c8 1457}
f844f9eb 1458#endif /* FIPS_MODULE */
badf51c8 1459
e683582b
SL
1460static void evp_pkey_free_it(EVP_PKEY *x)
1461{
1462 /* internal function; x is never NULL */
1463
3c6ed955 1464 evp_keymgmt_util_clear_operation_cache(x);
f844f9eb 1465#ifndef FIPS_MODULE
badf51c8
RL
1466 evp_pkey_free_legacy(x);
1467#endif
e683582b 1468
3c6ed955
RL
1469 if (x->keymgmt != NULL) {
1470 evp_keymgmt_freedata(x->keymgmt, x->keydata);
1471 EVP_KEYMGMT_free(x->keymgmt);
1472 x->keymgmt = NULL;
1473 x->keydata = NULL;
1474 }
e683582b
SL
1475}
1476
1477void EVP_PKEY_free(EVP_PKEY *x)
1478{
1479 int i;
1480
1481 if (x == NULL)
1482 return;
1483
1484 CRYPTO_DOWN_REF(&x->references, &i, x->lock);
1485 REF_PRINT_COUNT("EVP_PKEY", x);
1486 if (i > 0)
1487 return;
1488 REF_ASSERT_ISNT(i < 0);
1489 evp_pkey_free_it(x);
f844f9eb 1490#ifndef FIPS_MODULE
ff1f7cde
AT
1491 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EVP_PKEY, x, &x->ex_data);
1492#endif
e683582b 1493 CRYPTO_THREAD_lock_free(x->lock);
f844f9eb 1494#ifndef FIPS_MODULE
e683582b
SL
1495 sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);
1496#endif
1497 OPENSSL_free(x);
1498}
1499
e683582b
SL
1500int EVP_PKEY_size(const EVP_PKEY *pkey)
1501{
adc9f731
RL
1502 int size = 0;
1503
6508e858 1504 if (pkey != NULL) {
adc9f731 1505 size = pkey->cache.size;
f844f9eb 1506#ifndef FIPS_MODULE
adc9f731
RL
1507 if (pkey->ameth != NULL && pkey->ameth->pkey_size != NULL)
1508 size = pkey->ameth->pkey_size(pkey);
1509#endif
6508e858 1510 }
adc9f731 1511 return size;
e683582b 1512}
f6aa5774 1513
3c6ed955
RL
1514void *evp_pkey_export_to_provider(EVP_PKEY *pk, OPENSSL_CTX *libctx,
1515 EVP_KEYMGMT **keymgmt,
1516 const char *propquery)
f6aa5774
RL
1517{
1518 EVP_KEYMGMT *allocated_keymgmt = NULL;
1519 EVP_KEYMGMT *tmp_keymgmt = NULL;
b305452f 1520 void *keydata = NULL;
adc9f731 1521 int check;
f6aa5774
RL
1522
1523 if (pk == NULL)
1524 return NULL;
1525
adc9f731
RL
1526 /* No key data => nothing to export */
1527 check = 1;
f844f9eb 1528#ifndef FIPS_MODULE
adc9f731
RL
1529 check = check && pk->pkey.ptr == NULL;
1530#endif
1531 check = check && pk->keydata == NULL;
1532 if (check)
1533 return NULL;
1534
f844f9eb 1535#ifndef FIPS_MODULE
3f7ce7f1 1536 if (pk->pkey.ptr != NULL) {
3f7ce7f1 1537 /*
3c6ed955
RL
1538 * If the legacy key doesn't have an dirty counter or export function,
1539 * give up
3f7ce7f1 1540 */
3c6ed955
RL
1541 if (pk->ameth->dirty_cnt == NULL || pk->ameth->export_to == NULL)
1542 return NULL;
3f7ce7f1
RL
1543 }
1544#endif
1545
3c6ed955
RL
1546 if (keymgmt != NULL) {
1547 tmp_keymgmt = *keymgmt;
1548 *keymgmt = NULL;
1549 }
1550
4b9e90f4
RL
1551 /*
1552 * If no keymgmt was given or found, get a default keymgmt. We do so by
1553 * letting EVP_PKEY_CTX_new_from_pkey() do it for us, then we steal it.
1554 */
f6aa5774 1555 if (tmp_keymgmt == NULL) {
2ee4a50a 1556 EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pk, propquery);
f6aa5774 1557
4b9e90f4
RL
1558 tmp_keymgmt = ctx->keymgmt;
1559 ctx->keymgmt = NULL;
f6aa5774
RL
1560 EVP_PKEY_CTX_free(ctx);
1561 }
1562
3c6ed955 1563 /* If there's still no keymgmt to be had, give up */
3f7ce7f1
RL
1564 if (tmp_keymgmt == NULL)
1565 goto end;
f6aa5774 1566
f844f9eb 1567#ifndef FIPS_MODULE
3f7ce7f1 1568 if (pk->pkey.ptr != NULL) {
3c6ed955 1569 size_t i = 0;
3f7ce7f1
RL
1570
1571 /*
3c6ed955
RL
1572 * If the legacy "origin" hasn't changed since last time, we try
1573 * to find our keymgmt in the operation cache. If it has changed,
1574 * |i| remains zero, and we will clear the cache further down.
3f7ce7f1 1575 */
3c6ed955
RL
1576 if (pk->ameth->dirty_cnt(pk) == pk->dirty_cnt_copy) {
1577 i = evp_keymgmt_util_find_operation_cache_index(pk, tmp_keymgmt);
1578
1579 /*
1580 * If |tmp_keymgmt| is present in the operation cache, it means
1581 * that export doesn't need to be redone. In that case, we take
1582 * token copies of the cached pointers, to have token success
1583 * values to return.
1584 */
1585 if (i < OSSL_NELEM(pk->operation_cache)
1586 && pk->operation_cache[i].keymgmt != NULL) {
1587 keydata = pk->operation_cache[i].keydata;
1588 goto end;
1589 }
3f7ce7f1
RL
1590 }
1591
1592 /*
3c6ed955
RL
1593 * TODO(3.0) Right now, we assume we have ample space. We will have
1594 * to think about a cache aging scheme, though, if |i| indexes outside
1595 * the array.
3f7ce7f1 1596 */
3c6ed955 1597 if (!ossl_assert(i < OSSL_NELEM(pk->operation_cache)))
3f7ce7f1
RL
1598 goto end;
1599
1600 /* Make sure that the keymgmt key type matches the legacy NID */
1601 if (!ossl_assert(EVP_KEYMGMT_is_a(tmp_keymgmt, OBJ_nid2sn(pk->type))))
1602 goto end;
1603
1604 if ((keydata = evp_keymgmt_newdata(tmp_keymgmt)) == NULL)
1605 goto end;
1606
76e23fc5 1607 if (!pk->ameth->export_to(pk, keydata, tmp_keymgmt, libctx, propquery)) {
3f7ce7f1
RL
1608 evp_keymgmt_freedata(tmp_keymgmt, keydata);
1609 keydata = NULL;
1610 goto end;
1611 }
1612
3c6ed955
RL
1613 /*
1614 * If the dirty counter changed since last time, then clear the
1615 * operation cache. In that case, we know that |i| is zero. Just
1616 * in case this is a re-export, we increment then decrement the
1617 * keymgmt reference counter.
1618 */
1619 if (!EVP_KEYMGMT_up_ref(tmp_keymgmt)) { /* refcnt++ */
1620 evp_keymgmt_freedata(tmp_keymgmt, keydata);
1621 keydata = NULL;
1622 goto end;
1623 }
1624 if (pk->ameth->dirty_cnt(pk) != pk->dirty_cnt_copy)
1625 evp_keymgmt_util_clear_operation_cache(pk);
1626 EVP_KEYMGMT_free(tmp_keymgmt); /* refcnt-- */
1627
1628 /* Add the new export to the operation cache */
1629 if (!evp_keymgmt_util_cache_keydata(pk, i, tmp_keymgmt, keydata)) {
1630 evp_keymgmt_freedata(tmp_keymgmt, keydata);
1631 keydata = NULL;
1632 goto end;
1633 }
3f7ce7f1
RL
1634
1635 /* Synchronize the dirty count */
1636 pk->dirty_cnt_copy = pk->ameth->dirty_cnt(pk);
1637 goto end;
1638 }
f844f9eb 1639#endif /* FIPS_MODULE */
3f7ce7f1
RL
1640
1641 keydata = evp_keymgmt_util_export_to_provider(pk, tmp_keymgmt);
1642
1643 end:
f6aa5774
RL
1644 /*
1645 * If nothing was exported, |tmp_keymgmt| might point at a freed
1646 * EVP_KEYMGMT, so we clear it to be safe. It shouldn't be useful for
1647 * the caller either way in that case.
1648 */
b305452f 1649 if (keydata == NULL)
f6aa5774
RL
1650 tmp_keymgmt = NULL;
1651
1652 if (keymgmt != NULL)
1653 *keymgmt = tmp_keymgmt;
1654
1655 EVP_KEYMGMT_free(allocated_keymgmt);
b305452f 1656 return keydata;
f6aa5774 1657}
badf51c8 1658
f844f9eb 1659#ifndef FIPS_MODULE
acb90ba8 1660int evp_pkey_downgrade(EVP_PKEY *pk)
badf51c8 1661{
acb90ba8
RL
1662 EVP_KEYMGMT *keymgmt = pk->keymgmt;
1663 void *keydata = pk->keydata;
1664 int type = pk->save_type;
1665 const char *keytype = NULL;
badf51c8 1666
acb90ba8
RL
1667 /* If this isn't a provider side key, we're done */
1668 if (keymgmt == NULL)
1669 return 1;
1670
1671 /* Get the key type name for error reporting */
1672 if (type != EVP_PKEY_NONE)
1673 keytype = OBJ_nid2sn(type);
1674 else
1675 keytype =
1676 evp_first_name(EVP_KEYMGMT_provider(keymgmt), keymgmt->name_id);
badf51c8
RL
1677
1678 /*
acb90ba8
RL
1679 * |save_type| was set when any of the EVP_PKEY_set_type functions
1680 * was called. It was set to EVP_PKEY_NONE if the key type wasn't
1681 * recognised to be any of the legacy key types, and the downgrade
1682 * isn't possible.
badf51c8 1683 */
acb90ba8
RL
1684 if (type == EVP_PKEY_NONE) {
1685 ERR_raise_data(ERR_LIB_EVP, EVP_R_UNKNOWN_KEY_TYPE,
1686 "key type = %s, can't downgrade", keytype);
1687 return 0;
badf51c8
RL
1688 }
1689
acb90ba8
RL
1690 /*
1691 * To be able to downgrade, we steal the provider side "origin" keymgmt
1692 * and keydata. We've already grabbed the pointers, so all we need to
1693 * do is clear those pointers in |pk| and then call evp_pkey_free_it().
1694 * That way, we can restore |pk| if we need to.
1695 */
1696 pk->keymgmt = NULL;
1697 pk->keydata = NULL;
1698 evp_pkey_free_it(pk);
1699 if (EVP_PKEY_set_type(pk, type)) {
1700 /* If the key is typed but empty, we're done */
49276c35
RL
1701 if (keydata == NULL) {
1702 /* We're dropping the EVP_KEYMGMT */
1703 EVP_KEYMGMT_free(keymgmt);
acb90ba8 1704 return 1;
49276c35 1705 }
badf51c8 1706
acb90ba8
RL
1707 if (pk->ameth->import_from == NULL) {
1708 ERR_raise_data(ERR_LIB_EVP, EVP_R_NO_IMPORT_FUNCTION,
1709 "key type = %s", keytype);
629c72db 1710 } else {
acb90ba8 1711 /*
629c72db
MC
1712 * We perform the export in the same libctx as the keymgmt that we
1713 * are using.
acb90ba8 1714 */
629c72db
MC
1715 OPENSSL_CTX *libctx = ossl_provider_library_context(keymgmt->prov);
1716 EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_from_pkey(libctx, pk, NULL);
1717 if (pctx == NULL)
1718 ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
1719
1720 if (pctx != NULL
1721 && evp_keymgmt_export(keymgmt, keydata,
1722 OSSL_KEYMGMT_SELECT_ALL,
1723 pk->ameth->import_from, pctx)) {
1724 /*
1725 * Save the provider side data in the operation cache, so they'll
1726 * find it again. evp_pkey_free_it() cleared the cache, so it's
1727 * safe to assume slot zero is free.
1728 * Note that evp_keymgmt_util_cache_keydata() increments keymgmt's
1729 * reference count.
1730 */
1731 evp_keymgmt_util_cache_keydata(pk, 0, keymgmt, keydata);
1732 EVP_PKEY_CTX_free(pctx);
1733
1734 /* Synchronize the dirty count */
1735 pk->dirty_cnt_copy = pk->ameth->dirty_cnt(pk);
1736
1737 /* evp_keymgmt_export() increased the refcount... */
1738 EVP_KEYMGMT_free(keymgmt);
1739 return 1;
1740 }
1741 EVP_PKEY_CTX_free(pctx);
badf51c8
RL
1742 }
1743
acb90ba8
RL
1744 ERR_raise_data(ERR_LIB_EVP, EVP_R_KEYMGMT_EXPORT_FAILURE,
1745 "key type = %s", keytype);
badf51c8
RL
1746 }
1747
badf51c8 1748 /*
acb90ba8
RL
1749 * Something went wrong. This could for example happen if the keymgmt
1750 * turns out to be an HSM implementation that refuses to let go of some
1751 * of the key data, typically the private bits. In this case, we restore
1752 * the provider side internal "origin" and leave it at that.
badf51c8 1753 */
acb90ba8
RL
1754 if (!ossl_assert(EVP_PKEY_set_type_by_keymgmt(pk, keymgmt))) {
1755 /* This should not be impossible */
1756 ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
1757 return 0;
1758 }
49276c35
RL
1759 /* EVP_PKEY_set_type_by_keymgmt() increased the refcount... */
1760 EVP_KEYMGMT_free(keymgmt);
acb90ba8
RL
1761 pk->keydata = keydata;
1762 evp_keymgmt_util_cache_keyinfo(pk);
1763 return 0; /* No downgrade, but at least the key is restored */
badf51c8 1764}
f844f9eb 1765#endif /* FIPS_MODULE */
96ebe52e
SL
1766
1767const OSSL_PARAM *EVP_PKEY_gettable_params(EVP_PKEY *pkey)
1768{
1769 if (pkey == NULL
1770 || pkey->keymgmt == NULL
1771 || pkey->keydata == NULL)
1772 return 0;
1773 return evp_keymgmt_gettable_params(pkey->keymgmt);
1774}
1775
96ebe52e
SL
1776int EVP_PKEY_get_bn_param(EVP_PKEY *pkey, const char *key_name, BIGNUM **bn)
1777{
1778 int ret = 0;
1779 OSSL_PARAM params[2];
1780 unsigned char buffer[2048];
96ebe52e
SL
1781 unsigned char *buf = NULL;
1782 size_t buf_sz = 0;
1783
1784 if (pkey == NULL
1785 || pkey->keymgmt == NULL
1786 || pkey->keydata == NULL
1787 || key_name == NULL
1788 || bn == NULL)
1789 return 0;
1790
1791 memset(buffer, 0, sizeof(buffer));
1792 params[0] = OSSL_PARAM_construct_BN(key_name, buffer, sizeof(buffer));
96ebe52e
SL
1793 params[1] = OSSL_PARAM_construct_end();
1794 if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params)) {
99ea4f02 1795 if (!OSSL_PARAM_modified(params) || params[0].return_size == 0)
96ebe52e
SL
1796 return 0;
1797 buf_sz = params[0].return_size;
1798 /*
1799 * If it failed because the buffer was too small then allocate the
1800 * required buffer size and retry.
1801 */
1802 buf = OPENSSL_zalloc(buf_sz);
1803 if (buf == NULL)
1804 return 0;
1805 params[0].data = buf;
1806 params[0].data_size = buf_sz;
1807
1808 if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params))
1809 goto err;
1810 }
1811 /* Fail if the param was not found */
99ea4f02 1812 if (!OSSL_PARAM_modified(params))
96ebe52e
SL
1813 goto err;
1814 ret = OSSL_PARAM_get_BN(params, bn);
1815err:
1816 OPENSSL_free(buf);
1817 return ret;
1818}
1819
1820int EVP_PKEY_get_octet_string_param(EVP_PKEY *pkey, const char *key_name,
1821 unsigned char *buf, size_t max_buf_sz,
1822 size_t *out_sz)
1823{
1824 OSSL_PARAM params[2];
96ebe52e
SL
1825
1826 if (pkey == NULL
1827 || pkey->keymgmt == NULL
1828 || pkey->keydata == NULL
1829 || key_name == NULL)
1830 return 0;
1831
1832 params[0] = OSSL_PARAM_construct_octet_string(key_name, buf, max_buf_sz);
96ebe52e 1833 params[1] = OSSL_PARAM_construct_end();
99ea4f02
P
1834 if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params)
1835 || !OSSL_PARAM_modified(params))
96ebe52e
SL
1836 return 0;
1837 if (out_sz != NULL)
1838 *out_sz = params[0].return_size;
1839 return 1;
1840}
1841
1842int EVP_PKEY_get_utf8_string_param(EVP_PKEY *pkey, const char *key_name,
1843 char *str, size_t max_buf_sz,
1844 size_t *out_sz)
1845{
1846 OSSL_PARAM params[2];
96ebe52e
SL
1847
1848 if (pkey == NULL
1849 || pkey->keymgmt == NULL
1850 || pkey->keydata == NULL
1851 || key_name == NULL)
1852 return 0;
1853
1854 params[0] = OSSL_PARAM_construct_utf8_string(key_name, str, max_buf_sz);
96ebe52e 1855 params[1] = OSSL_PARAM_construct_end();
99ea4f02
P
1856 if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params)
1857 || !OSSL_PARAM_modified(params))
96ebe52e
SL
1858 return 0;
1859 if (out_sz != NULL)
1860 *out_sz = params[0].return_size;
1861 return 1;
1862}
1863
1864int EVP_PKEY_get_int_param(EVP_PKEY *pkey, const char *key_name, int *out)
1865{
1866 OSSL_PARAM params[2];
96ebe52e
SL
1867
1868 if (pkey == NULL
1869 || pkey->keymgmt == NULL
1870 || pkey->keydata == NULL
1871 || key_name == NULL)
1872 return 0;
1873
1874 params[0] = OSSL_PARAM_construct_int(key_name, out);
96ebe52e 1875 params[1] = OSSL_PARAM_construct_end();
99ea4f02
P
1876 if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params)
1877 || !OSSL_PARAM_modified(params))
96ebe52e
SL
1878 return 0;
1879 return 1;
1880}
1881
1882int EVP_PKEY_get_size_t_param(EVP_PKEY *pkey, const char *key_name, size_t *out)
1883{
1884 OSSL_PARAM params[2];
96ebe52e
SL
1885
1886 if (pkey == NULL
1887 || pkey->keymgmt == NULL
1888 || pkey->keydata == NULL
1889 || key_name == NULL)
1890 return 0;
1891
1892 params[0] = OSSL_PARAM_construct_size_t(key_name, out);
96ebe52e 1893 params[1] = OSSL_PARAM_construct_end();
99ea4f02
P
1894 if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params)
1895 || !OSSL_PARAM_modified(params))
96ebe52e
SL
1896 return 0;
1897 return 1;
1898}