]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/evp/p_lib.c
Add the library ctx into an ECX_KEY
[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
0d124b0a
MC
476int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, unsigned char *priv,
477 size_t *len)
478{
acb90ba8 479 /* TODO(3.0) Do we need to do anything about provider side keys? */
0d124b0a
MC
480 if (pkey->ameth->get_priv_key == NULL) {
481 EVPerr(EVP_F_EVP_PKEY_GET_RAW_PRIVATE_KEY,
482 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
483 return 0;
484 }
485
486 if (!pkey->ameth->get_priv_key(pkey, priv, len)) {
487 EVPerr(EVP_F_EVP_PKEY_GET_RAW_PRIVATE_KEY, EVP_R_GET_RAW_KEY_FAILED);
488 return 0;
489 }
490
491 return 1;
492}
493
494int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub,
495 size_t *len)
496{
acb90ba8 497 /* TODO(3.0) Do we need to do anything about provider side keys? */
0d124b0a
MC
498 if (pkey->ameth->get_pub_key == NULL) {
499 EVPerr(EVP_F_EVP_PKEY_GET_RAW_PUBLIC_KEY,
500 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
501 return 0;
502 }
503
504 if (!pkey->ameth->get_pub_key(pkey, pub, len)) {
505 EVPerr(EVP_F_EVP_PKEY_GET_RAW_PUBLIC_KEY, EVP_R_GET_RAW_KEY_FAILED);
506 return 0;
507 }
508
509 return 1;
510}
511
b3831fbb
MC
512EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
513 size_t len, const EVP_CIPHER *cipher)
514{
e683582b
SL
515# ifndef OPENSSL_NO_CMAC
516# ifndef OPENSSL_NO_ENGINE
9a7846df 517 const char *engine_id = e != NULL ? ENGINE_get_id(e) : NULL;
e683582b 518# endif
e74bd290
RL
519 const char *cipher_name = EVP_CIPHER_name(cipher);
520 const OSSL_PROVIDER *prov = EVP_CIPHER_provider(cipher);
521 OPENSSL_CTX *libctx =
522 prov == NULL ? NULL : ossl_provider_library_context(prov);
b3831fbb 523 EVP_PKEY *ret = EVP_PKEY_new();
81ff9eeb 524 EVP_MAC *cmac = EVP_MAC_fetch(libctx, OSSL_MAC_NAME_CMAC, NULL);
e74bd290
RL
525 EVP_MAC_CTX *cmctx = cmac != NULL ? EVP_MAC_CTX_new(cmac) : NULL;
526 OSSL_PARAM params[4];
527 size_t paramsn = 0;
b3831fbb
MC
528
529 if (ret == NULL
8243d8d1
RL
530 || cmctx == NULL
531 || !pkey_set_type(ret, e, EVP_PKEY_CMAC, NULL, -1, NULL)) {
b3831fbb
MC
532 /* EVPerr already called */
533 goto err;
534 }
535
e683582b 536# ifndef OPENSSL_NO_ENGINE
9a7846df 537 if (engine_id != NULL)
e74bd290 538 params[paramsn++] =
69db3044 539 OSSL_PARAM_construct_utf8_string("engine", (char *)engine_id, 0);
e683582b 540# endif
3be06e0d 541
e74bd290 542 params[paramsn++] =
703170d4 543 OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER,
7f588d20 544 (char *)cipher_name, 0);
e74bd290
RL
545 params[paramsn++] =
546 OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
547 (char *)priv, len);
548 params[paramsn] = OSSL_PARAM_construct_end();
549
550 if (!EVP_MAC_CTX_set_params(cmctx, params)) {
b3831fbb
MC
551 EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY, EVP_R_KEY_SETUP_FAILED);
552 goto err;
553 }
554
555 ret->pkey.ptr = cmctx;
556 return ret;
557
558 err:
559 EVP_PKEY_free(ret);
b8d77c9b 560 EVP_MAC_CTX_free(cmctx);
e74bd290 561 EVP_MAC_free(cmac);
b3831fbb 562 return NULL;
e683582b 563# else
df6d51e2
MC
564 EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY,
565 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
566 return NULL;
e683582b 567# endif
b3831fbb 568}
a08802ce 569
01b8b3c7 570int EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
0f113f3e 571{
8243d8d1 572 return pkey_set_type(pkey, NULL, type, NULL, -1, NULL);
0f113f3e 573}
01b8b3c7
DSH
574
575int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len)
0f113f3e 576{
8243d8d1 577 return pkey_set_type(pkey, NULL, EVP_PKEY_NONE, str, len, NULL);
0f113f3e 578}
2f2e6b62
JL
579
580int EVP_PKEY_set_alias_type(EVP_PKEY *pkey, int type)
581{
582 if (pkey->type == type) {
583 return 1; /* it already is that type */
584 }
585
586 /*
587 * The application is requesting to alias this to a different pkey type,
588 * but not one that resolves to the base type.
589 */
590 if (EVP_PKEY_type(type) != EVP_PKEY_base_id(pkey)) {
591 EVPerr(EVP_F_EVP_PKEY_SET_ALIAS_TYPE, EVP_R_UNSUPPORTED_ALGORITHM);
592 return 0;
593 }
594
595 pkey->type = type;
596 return 1;
597}
598
e683582b 599# ifndef OPENSSL_NO_ENGINE
d19b01ad
DSH
600int EVP_PKEY_set1_engine(EVP_PKEY *pkey, ENGINE *e)
601{
602 if (e != NULL) {
603 if (!ENGINE_init(e)) {
604 EVPerr(EVP_F_EVP_PKEY_SET1_ENGINE, ERR_R_ENGINE_LIB);
605 return 0;
606 }
607 if (ENGINE_get_pkey_meth(e, pkey->type) == NULL) {
608 ENGINE_finish(e);
609 EVPerr(EVP_F_EVP_PKEY_SET1_ENGINE, EVP_R_UNSUPPORTED_ALGORITHM);
610 return 0;
611 }
612 }
613 ENGINE_finish(pkey->pmeth_engine);
614 pkey->pmeth_engine = e;
615 return 1;
616}
229f7b38
DB
617
618ENGINE *EVP_PKEY_get0_engine(const EVP_PKEY *pkey)
619{
620 return pkey->engine;
621}
e683582b 622# endif
01b8b3c7 623int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
0f113f3e 624{
f4e4382c
RL
625 int alias = type;
626
ad5b71be 627#ifndef OPENSSL_NO_EC
f4e4382c
RL
628 if (EVP_PKEY_type(type) == EVP_PKEY_EC) {
629 const EC_GROUP *group = EC_KEY_get0_group(key);
630
631 if (group != NULL && EC_GROUP_get_curve_name(group) == NID_sm2)
632 alias = EVP_PKEY_SM2;
633 }
ad5b71be 634#endif
f4e4382c 635
e34c66c6 636 if (pkey == NULL || !EVP_PKEY_set_type(pkey, type))
0f113f3e 637 return 0;
f4e4382c
RL
638 if (!EVP_PKEY_set_alias_type(pkey, alias))
639 return 0;
0f113f3e
MC
640 pkey->pkey.ptr = key;
641 return (key != NULL);
642}
d02b48c6 643
3aeb9348 644void *EVP_PKEY_get0(const EVP_PKEY *pkey)
0f113f3e 645{
acb90ba8
RL
646 if (!evp_pkey_downgrade((EVP_PKEY *)pkey)) {
647 ERR_raise(ERR_LIB_EVP, EVP_R_INACCESSIBLE_KEY);
648 return NULL;
649 }
0f113f3e
MC
650 return pkey->pkey.ptr;
651}
db98bbc1 652
ebad0b0b
NM
653const unsigned char *EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len)
654{
655 ASN1_OCTET_STRING *os = NULL;
656 if (pkey->type != EVP_PKEY_HMAC) {
657 EVPerr(EVP_F_EVP_PKEY_GET0_HMAC, EVP_R_EXPECTING_AN_HMAC_KEY);
658 return NULL;
659 }
660 os = EVP_PKEY_get0(pkey);
661 *len = os->length;
662 return os->data;
663}
664
e683582b 665# ifndef OPENSSL_NO_POLY1305
52ad5b60
TS
666const unsigned char *EVP_PKEY_get0_poly1305(const EVP_PKEY *pkey, size_t *len)
667{
668 ASN1_OCTET_STRING *os = NULL;
669 if (pkey->type != EVP_PKEY_POLY1305) {
670 EVPerr(EVP_F_EVP_PKEY_GET0_POLY1305, EVP_R_EXPECTING_A_POLY1305_KEY);
671 return NULL;
672 }
673 os = EVP_PKEY_get0(pkey);
674 *len = os->length;
675 return os->data;
676}
e683582b 677# endif
52ad5b60 678
e683582b 679# ifndef OPENSSL_NO_SIPHASH
3f5616d7
TS
680const unsigned char *EVP_PKEY_get0_siphash(const EVP_PKEY *pkey, size_t *len)
681{
682 ASN1_OCTET_STRING *os = NULL;
683
684 if (pkey->type != EVP_PKEY_SIPHASH) {
685 EVPerr(EVP_F_EVP_PKEY_GET0_SIPHASH, EVP_R_EXPECTING_A_SIPHASH_KEY);
686 return NULL;
687 }
688 os = EVP_PKEY_get0(pkey);
689 *len = os->length;
690 return os->data;
691}
e683582b 692# endif
3f5616d7 693
e683582b 694# ifndef OPENSSL_NO_RSA
c7cb16a8 695int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key)
52664f50 696{
0f113f3e
MC
697 int ret = EVP_PKEY_assign_RSA(pkey, key);
698 if (ret)
699 RSA_up_ref(key);
700 return ret;
52664f50
DSH
701}
702
9fdcc21f 703RSA *EVP_PKEY_get0_RSA(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 }
465a58b1 709 if (pkey->type != EVP_PKEY_RSA && pkey->type != EVP_PKEY_RSA_PSS) {
2872dbe1 710 EVPerr(EVP_F_EVP_PKEY_GET0_RSA, EVP_R_EXPECTING_AN_RSA_KEY);
0f113f3e
MC
711 return NULL;
712 }
0f113f3e 713 return pkey->pkey.rsa;
f769ce3e 714}
2872dbe1
DSH
715
716RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey)
717{
718 RSA *ret = EVP_PKEY_get0_RSA(pkey);
719 if (ret != NULL)
720 RSA_up_ref(ret);
721 return ret;
722}
e683582b 723# endif
f769ce3e 724
e683582b 725# ifndef OPENSSL_NO_DSA
9fdcc21f 726DSA *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey)
0f113f3e 727{
acb90ba8
RL
728 if (!evp_pkey_downgrade((EVP_PKEY *)pkey)) {
729 ERR_raise(ERR_LIB_EVP, EVP_R_INACCESSIBLE_KEY);
730 return NULL;
731 }
0f113f3e 732 if (pkey->type != EVP_PKEY_DSA) {
2872dbe1 733 EVPerr(EVP_F_EVP_PKEY_GET0_DSA, EVP_R_EXPECTING_A_DSA_KEY);
0f113f3e
MC
734 return NULL;
735 }
0f113f3e 736 return pkey->pkey.dsa;
f769ce3e 737}
2872dbe1 738
b03ec3b5
SL
739int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
740{
741 int ret = EVP_PKEY_assign_DSA(pkey, key);
742 if (ret)
743 DSA_up_ref(key);
744 return ret;
745}
2872dbe1
DSH
746DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey)
747{
748 DSA *ret = EVP_PKEY_get0_DSA(pkey);
749 if (ret != NULL)
750 DSA_up_ref(ret);
751 return ret;
752}
b03ec3b5 753# endif /* OPENSSL_NO_DSA */
f844f9eb 754#endif /* FIPS_MODULE */
f769ce3e 755
f844f9eb 756#ifndef FIPS_MODULE
e683582b 757# ifndef OPENSSL_NO_EC
14a7cfb3 758int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key)
4d94ae00 759{
0f113f3e
MC
760 int ret = EVP_PKEY_assign_EC_KEY(pkey, key);
761 if (ret)
762 EC_KEY_up_ref(key);
763 return ret;
4d94ae00
BM
764}
765
9fdcc21f 766EC_KEY *EVP_PKEY_get0_EC_KEY(const EVP_PKEY *pkey)
4d94ae00 767{
acb90ba8
RL
768 if (!evp_pkey_downgrade((EVP_PKEY *)pkey)) {
769 ERR_raise(ERR_LIB_EVP, EVP_R_INACCESSIBLE_KEY);
770 return NULL;
771 }
f4e4382c 772 if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC) {
2872dbe1 773 EVPerr(EVP_F_EVP_PKEY_GET0_EC_KEY, EVP_R_EXPECTING_A_EC_KEY);
0f113f3e
MC
774 return NULL;
775 }
0f113f3e 776 return pkey->pkey.ec;
4d94ae00 777}
2872dbe1
DSH
778
779EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey)
780{
781 EC_KEY *ret = EVP_PKEY_get0_EC_KEY(pkey);
782 if (ret != NULL)
783 EC_KEY_up_ref(ret);
784 return ret;
785}
e683582b 786# endif
4d94ae00 787
e683582b 788# ifndef OPENSSL_NO_DH
52664f50 789
c7cb16a8 790int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key)
52664f50 791{
32c869ff
MC
792 int type = DH_get0_q(key) == NULL ? EVP_PKEY_DH : EVP_PKEY_DHX;
793 int ret = EVP_PKEY_assign(pkey, type, key);
794
0f113f3e
MC
795 if (ret)
796 DH_up_ref(key);
797 return ret;
52664f50
DSH
798}
799
9fdcc21f 800DH *EVP_PKEY_get0_DH(const EVP_PKEY *pkey)
0f113f3e 801{
acb90ba8
RL
802 if (!evp_pkey_downgrade((EVP_PKEY *)pkey)) {
803 ERR_raise(ERR_LIB_EVP, EVP_R_INACCESSIBLE_KEY);
804 return NULL;
805 }
0f113f3e 806 if (pkey->type != EVP_PKEY_DH && pkey->type != EVP_PKEY_DHX) {
2872dbe1 807 EVPerr(EVP_F_EVP_PKEY_GET0_DH, EVP_R_EXPECTING_A_DH_KEY);
0f113f3e
MC
808 return NULL;
809 }
0f113f3e 810 return pkey->pkey.dh;
f769ce3e 811}
2872dbe1
DSH
812
813DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey)
814{
815 DH *ret = EVP_PKEY_get0_DH(pkey);
816 if (ret != NULL)
817 DH_up_ref(ret);
818 return ret;
819}
e683582b 820# endif
f769ce3e 821
6b691a5c 822int EVP_PKEY_type(int type)
0f113f3e
MC
823{
824 int ret;
825 const EVP_PKEY_ASN1_METHOD *ameth;
826 ENGINE *e;
827 ameth = EVP_PKEY_asn1_find(&e, type);
828 if (ameth)
829 ret = ameth->pkey_id;
830 else
831 ret = NID_undef;
e683582b 832# ifndef OPENSSL_NO_ENGINE
7c96dbcd 833 ENGINE_finish(e);
e683582b 834# endif
0f113f3e
MC
835 return ret;
836}
d02b48c6 837
7f57b076 838int EVP_PKEY_id(const EVP_PKEY *pkey)
0f113f3e
MC
839{
840 return pkey->type;
841}
7f57b076
DSH
842
843int EVP_PKEY_base_id(const EVP_PKEY *pkey)
0f113f3e
MC
844{
845 return EVP_PKEY_type(pkey->type);
846}
7f57b076 847
4f76d62f
RL
848int EVP_PKEY_is_a(const EVP_PKEY *pkey, const char *name)
849{
f844f9eb 850#ifndef FIPS_MODULE
4f76d62f
RL
851 if (pkey->keymgmt == NULL) {
852 /*
853 * These hard coded cases are pure hackery to get around the fact
854 * that names in crypto/objects/objects.txt are a mess. There is
855 * no "EC", and "RSA" leads to the NID for 2.5.8.1.1, an OID that's
856 * fallen out in favor of { pkcs-1 1 }, i.e. 1.2.840.113549.1.1.1,
857 * the NID of which is used for EVP_PKEY_RSA. Strangely enough,
858 * "DSA" is accurate... but still, better be safe and hard-code
859 * names that we know.
860 * TODO Clean this away along with all other #legacy support.
861 */
862 int type;
863
864 if (strcasecmp(name, "RSA") == 0)
865 type = EVP_PKEY_RSA;
866#ifndef OPENSSL_NO_EC
867 else if (strcasecmp(name, "EC") == 0)
868 type = EVP_PKEY_EC;
869#endif
870#ifndef OPENSSL_NO_DSA
871 else if (strcasecmp(name, "DSA") == 0)
872 type = EVP_PKEY_DSA;
873#endif
874 else
875 type = EVP_PKEY_type(OBJ_sn2nid(name));
876 return EVP_PKEY_type(pkey->type) == type;
877 }
878#endif
879 return EVP_KEYMGMT_is_a(pkey->keymgmt, name);
880}
881
882int EVP_PKEY_can_sign(const EVP_PKEY *pkey)
883{
884 if (pkey->keymgmt == NULL) {
885 switch (EVP_PKEY_base_id(pkey)) {
886 case EVP_PKEY_RSA:
887 return 1;
888#ifndef OPENSSL_NO_DSA
889 case EVP_PKEY_DSA:
890 return 1;
891#endif
892#ifndef OPENSSL_NO_EC
893 case EVP_PKEY_ED25519:
894 case EVP_PKEY_ED448:
895 return 1;
896 case EVP_PKEY_EC: /* Including SM2 */
897 return EC_KEY_can_sign(pkey->pkey.ec);
898#endif
899 default:
900 break;
901 }
902 } else {
903 const OSSL_PROVIDER *prov = EVP_KEYMGMT_provider(pkey->keymgmt);
904 OPENSSL_CTX *libctx = ossl_provider_library_context(prov);
905 const char *supported_sig =
906 pkey->keymgmt->query_operation_name != NULL
907 ? pkey->keymgmt->query_operation_name(OSSL_OP_SIGNATURE)
908 : evp_first_name(prov, pkey->keymgmt->name_id);
909 EVP_SIGNATURE *signature = NULL;
910
911 signature = EVP_SIGNATURE_fetch(libctx, supported_sig, NULL);
912 if (signature != NULL) {
913 EVP_SIGNATURE_free(signature);
914 return 1;
915 }
916 }
917 return 0;
918}
d02b48c6 919
c2041da8
RL
920#ifndef OPENSSL_NO_EC
921/*
922 * TODO rewrite when we have proper data extraction functions
923 * Note: an octet pointer would be desirable!
924 */
925static OSSL_CALLBACK get_ec_curve_name_cb;
926static int get_ec_curve_name_cb(const OSSL_PARAM params[], void *arg)
927{
928 const OSSL_PARAM *p = NULL;
929
930 if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_NAME)) != NULL)
931 return OSSL_PARAM_get_utf8_string(p, arg, 0);
932
933 /* If there is no curve name, this is not an EC key */
934 return 0;
935}
936
937int evp_pkey_get_EC_KEY_curve_nid(const EVP_PKEY *pkey)
938{
939 int ret = NID_undef;
940
941 if (pkey->keymgmt == NULL) {
942 if (EVP_PKEY_base_id(pkey) == EVP_PKEY_EC) {
943 EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey);
944
945 ret = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
946 }
947 } else if (EVP_PKEY_is_a(pkey, "EC") || EVP_PKEY_is_a(pkey, "SM2")) {
948 char *curve_name = NULL;
949
950 ret = evp_keymgmt_export(pkey->keymgmt, pkey->keydata,
951 OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
952 get_ec_curve_name_cb, &curve_name);
953 if (ret)
954 ret = ec_curve_name2nid(curve_name);
955 OPENSSL_free(curve_name);
956 }
957
958 return ret;
959}
960#endif
961
f1299839
RL
962static int print_reset_indent(BIO **out, int pop_f_prefix, long saved_indent)
963{
964 BIO_set_indent(*out, saved_indent);
965 if (pop_f_prefix) {
966 BIO *next = BIO_pop(*out);
967
968 BIO_free(*out);
969 *out = next;
970 }
971 return 1;
972}
973
974static int print_set_indent(BIO **out, int *pop_f_prefix, long *saved_indent,
975 long indent)
976{
977 *pop_f_prefix = 0;
978 *saved_indent = 0;
979 if (indent > 0) {
980 long i = BIO_get_indent(*out);
981
982 *saved_indent = (i < 0 ? 0 : i);
983 if (BIO_set_indent(*out, indent) <= 0) {
984 if ((*out = BIO_push(BIO_new(BIO_f_prefix()), *out)) == NULL)
985 return 0;
986 *pop_f_prefix = 1;
987 }
988 if (BIO_set_indent(*out, indent) <= 0) {
989 print_reset_indent(out, *pop_f_prefix, *saved_indent);
990 return 0;
991 }
992 }
993 return 1;
994}
995
35208f36 996static int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent,
0f113f3e
MC
997 const char *kstr)
998{
5310a4e6
P
999 return BIO_indent(out, indent, 128)
1000 && BIO_printf(out, "%s algorithm \"%s\" unsupported\n",
1001 kstr, OBJ_nid2ln(pkey->type)) > 0;
0f113f3e 1002}
35208f36 1003
f1299839
RL
1004static int print_pkey(const EVP_PKEY *pkey, BIO *out, int indent,
1005 const char *propquery /* For provided serialization */,
1006 int (*legacy_print)(BIO *out, const EVP_PKEY *pkey,
1007 int indent, ASN1_PCTX *pctx),
1008 ASN1_PCTX *legacy_pctx /* For legacy print */)
0f113f3e 1009{
f1299839
RL
1010 int pop_f_prefix;
1011 long saved_indent;
1012 OSSL_SERIALIZER_CTX *ctx = NULL;
1013 int ret = -2; /* default to unsupported */
1014
1015 if (!print_set_indent(&out, &pop_f_prefix, &saved_indent, indent))
1016 return 0;
54c1711f 1017
f1299839 1018 ctx = OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(pkey, propquery);
54c1711f
RL
1019 if (OSSL_SERIALIZER_CTX_get_serializer(ctx) != NULL)
1020 ret = OSSL_SERIALIZER_to_bio(ctx, out);
1021 OSSL_SERIALIZER_CTX_free(ctx);
1022
1023 if (ret != -2)
f1299839 1024 goto end;
54c1711f
RL
1025
1026 /* legacy fallback */
f1299839
RL
1027 if (legacy_print != NULL)
1028 ret = legacy_print(out, pkey, 0, legacy_pctx);
1029 else
1030 ret = unsup_alg(out, pkey, 0, "Public Key");
0f113f3e 1031
f1299839
RL
1032 end:
1033 print_reset_indent(&out, pop_f_prefix, saved_indent);
1034 return ret;
1035}
1036
1037int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
1038 int indent, ASN1_PCTX *pctx)
1039{
1040 return print_pkey(pkey, out, indent, OSSL_SERIALIZER_PUBKEY_TO_TEXT_PQ,
1041 (pkey->ameth != NULL ? pkey->ameth->pub_print : NULL),
1042 pctx);
0f113f3e 1043}
35208f36
DSH
1044
1045int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
0f113f3e
MC
1046 int indent, ASN1_PCTX *pctx)
1047{
f1299839
RL
1048 return print_pkey(pkey, out, indent, OSSL_SERIALIZER_PrivateKey_TO_TEXT_PQ,
1049 (pkey->ameth != NULL ? pkey->ameth->priv_print : NULL),
1050 pctx);
0f113f3e 1051}
35208f36
DSH
1052
1053int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
0f113f3e
MC
1054 int indent, ASN1_PCTX *pctx)
1055{
f1299839
RL
1056 return print_pkey(pkey, out, indent, OSSL_SERIALIZER_Parameters_TO_TEXT_PQ,
1057 (pkey->ameth != NULL ? pkey->ameth->param_print : NULL),
1058 pctx);
0f113f3e 1059}
03919683 1060
ead0d234
RL
1061static int legacy_asn1_ctrl_to_param(EVP_PKEY *pkey, int op,
1062 int arg1, void *arg2)
1063{
3c6ed955 1064 if (pkey->keymgmt == NULL)
ead0d234
RL
1065 return 0;
1066 switch (op) {
1067 case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
1068 {
1069 char mdname[80] = "";
1070 int nid;
1071 int rv = EVP_PKEY_get_default_digest_name(pkey, mdname,
1072 sizeof(mdname));
1073
1074 if (rv <= 0)
1075 return rv;
1076 nid = OBJ_sn2nid(mdname);
1077 if (nid == NID_undef)
1078 nid = OBJ_ln2nid(mdname);
1079 if (nid == NID_undef)
1080 return 0;
1081 *(int *)arg2 = nid;
1082 return 1;
1083 }
1084 default:
1085 return -2;
1086 }
1087}
1088
5d6aaf8a 1089static int evp_pkey_asn1_ctrl(EVP_PKEY *pkey, int op, int arg1, void *arg2)
0f113f3e 1090{
ead0d234
RL
1091 if (pkey->ameth == NULL)
1092 return legacy_asn1_ctrl_to_param(pkey, op, arg1, arg2);
1093 if (pkey->ameth->pkey_ctrl == NULL)
0f113f3e 1094 return -2;
5d6aaf8a
DSH
1095 return pkey->ameth->pkey_ctrl(pkey, op, arg1, arg2);
1096}
1097
1098int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid)
1099{
1100 return evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID, 0, pnid);
1101}
1102
ead0d234
RL
1103int EVP_PKEY_get_default_digest_name(EVP_PKEY *pkey,
1104 char *mdname, size_t mdname_sz)
1105{
3b924da0
RL
1106 if (pkey->ameth == NULL)
1107 return evp_keymgmt_util_get_deflt_digest_name(pkey->keymgmt,
1108 pkey->keydata,
1109 mdname, mdname_sz);
ead0d234
RL
1110
1111 {
1112 int nid = NID_undef;
1113 int rv = EVP_PKEY_get_default_digest_nid(pkey, &nid);
1114 const char *name = rv > 0 ? OBJ_nid2sn(nid) : NULL;
1115
1116 if (rv > 0)
1117 OPENSSL_strlcpy(mdname, name, mdname_sz);
1118 return rv;
1119 }
1120}
1121
ecbb2fca
DW
1122int EVP_PKEY_supports_digest_nid(EVP_PKEY *pkey, int nid)
1123{
1124 int rv, default_nid;
1125
1126 rv = evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_SUPPORTS_MD_NID, nid, NULL);
1127 if (rv == -2) {
1128 /*
1129 * If there is a mandatory default digest and this isn't it, then
1130 * the answer is 'no'.
1131 */
1132 rv = EVP_PKEY_get_default_digest_nid(pkey, &default_nid);
1133 if (rv == 2)
1134 return (nid == default_nid);
1135 /* zero is an error from EVP_PKEY_get_default_digest_nid() */
1136 if (rv == 0)
1137 return -1;
1138 }
1139 return rv;
1140}
1141
5d6aaf8a
DSH
1142int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey,
1143 const unsigned char *pt, size_t ptlen)
1144{
1145 if (ptlen > INT_MAX)
1146 return 0;
1147 if (evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_SET1_TLS_ENCPT, ptlen,
1148 (void *)pt) <= 0)
1149 return 0;
1150 return 1;
1151}
1152
1153size_t EVP_PKEY_get1_tls_encodedpoint(EVP_PKEY *pkey, unsigned char **ppt)
1154{
1155 int rv;
1156 rv = evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_GET1_TLS_ENCPT, 0, ppt);
1157 if (rv <= 0)
1158 return 0;
1159 return rv;
0f113f3e 1160}
e683582b 1161
f844f9eb 1162#endif /* FIPS_MODULE */
e683582b 1163
f844f9eb 1164/*- All methods below can also be used in FIPS_MODULE */
e683582b
SL
1165
1166EVP_PKEY *EVP_PKEY_new(void)
1167{
1168 EVP_PKEY *ret = OPENSSL_zalloc(sizeof(*ret));
1169
1170 if (ret == NULL) {
1171 EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE);
1172 return NULL;
1173 }
1174 ret->type = EVP_PKEY_NONE;
1175 ret->save_type = EVP_PKEY_NONE;
1176 ret->references = 1;
1177 ret->save_parameters = 1;
1178 ret->lock = CRYPTO_THREAD_lock_new();
1179 if (ret->lock == NULL) {
1180 EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE);
ff1f7cde
AT
1181 goto err;
1182 }
f844f9eb 1183#ifndef FIPS_MODULE
ff1f7cde
AT
1184 if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_EVP_PKEY, ret, &ret->ex_data)) {
1185 EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE);
1186 goto err;
e683582b 1187 }
ff1f7cde 1188#endif
e683582b 1189 return ret;
ff1f7cde
AT
1190
1191 err:
1192 CRYPTO_THREAD_lock_free(ret->lock);
1193 OPENSSL_free(ret);
1194 return NULL;
e683582b
SL
1195}
1196
8243d8d1
RL
1197/*
1198 * Setup a public key management method.
1199 *
1200 * For legacy keys, either |type| or |str| is expected to have the type
1201 * information. In this case, the setup consists of finding an ASN1 method
1202 * and potentially an ENGINE, and setting those fields in |pkey|.
1203 *
1204 * For provider side keys, |keymgmt| is expected to be non-NULL. In this
1205 * case, the setup consists of setting the |keymgmt| field in |pkey|.
1206 *
1207 * If pkey is NULL just return 1 or 0 if the key management method exists.
1208 */
1209
1210static int pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str,
1211 int len, EVP_KEYMGMT *keymgmt)
1212{
f844f9eb 1213#ifndef FIPS_MODULE
8243d8d1
RL
1214 const EVP_PKEY_ASN1_METHOD *ameth = NULL;
1215 ENGINE **eptr = (e == NULL) ? &e : NULL;
1216#endif
1217
1218 /*
1219 * The setups can't set both legacy and provider side methods.
1220 * It is forbidden
1221 */
1222 if (!ossl_assert(type == EVP_PKEY_NONE || keymgmt == NULL)
1223 || !ossl_assert(e == NULL || keymgmt == NULL)) {
1224 ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
1225 return 0;
1226 }
1227
1228 if (pkey != NULL) {
1229 int free_it = 0;
1230
f844f9eb 1231#ifndef FIPS_MODULE
8243d8d1
RL
1232 free_it = free_it || pkey->pkey.ptr != NULL;
1233#endif
1234 free_it = free_it || pkey->keydata != NULL;
1235 if (free_it)
1236 evp_pkey_free_it(pkey);
f844f9eb 1237#ifndef FIPS_MODULE
8243d8d1
RL
1238 /*
1239 * If key type matches and a method exists then this lookup has
1240 * succeeded once so just indicate success.
1241 */
1242 if (pkey->type != EVP_PKEY_NONE
1243 && type == pkey->save_type
1244 && pkey->ameth != NULL)
1245 return 1;
1246# ifndef OPENSSL_NO_ENGINE
1247 /* If we have ENGINEs release them */
1248 ENGINE_finish(pkey->engine);
1249 pkey->engine = NULL;
1250 ENGINE_finish(pkey->pmeth_engine);
1251 pkey->pmeth_engine = NULL;
1252# endif
1253#endif
1254 }
f844f9eb 1255#ifndef FIPS_MODULE
8243d8d1
RL
1256 if (str != NULL)
1257 ameth = EVP_PKEY_asn1_find_str(eptr, str, len);
1258 else if (type != EVP_PKEY_NONE)
1259 ameth = EVP_PKEY_asn1_find(eptr, type);
1260# ifndef OPENSSL_NO_ENGINE
1261 if (pkey == NULL && eptr != NULL)
1262 ENGINE_finish(e);
1263# endif
1264#endif
1265
1266
1267 {
1268 int check = 1;
1269
f844f9eb 1270#ifndef FIPS_MODULE
8243d8d1
RL
1271 check = check && ameth == NULL;
1272#endif
1273 check = check && keymgmt == NULL;
1274 if (check) {
1275 EVPerr(EVP_F_PKEY_SET_TYPE, EVP_R_UNSUPPORTED_ALGORITHM);
1276 return 0;
1277 }
1278 }
1279 if (pkey != NULL) {
1280 if (keymgmt != NULL && !EVP_KEYMGMT_up_ref(keymgmt)) {
1281 ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
1282 return 0;
1283 }
1284
1285 pkey->keymgmt = keymgmt;
1286
1287 pkey->save_type = type;
1288 pkey->type = type;
1289
f844f9eb 1290#ifndef FIPS_MODULE
8243d8d1
RL
1291 /*
1292 * If the internal "origin" key is provider side, don't save |ameth|.
1293 * The main reason is that |ameth| is one factor to detect that the
1294 * internal "origin" key is a legacy one.
1295 */
1296 if (keymgmt == NULL)
1297 pkey->ameth = ameth;
1298 pkey->engine = e;
1299
1300 /*
1301 * The EVP_PKEY_ASN1_METHOD |pkey_id| serves different purposes,
1302 * depending on if we're setting this key to contain a legacy or
1303 * a provider side "origin" key. For a legacy key, we assign it
1304 * to the |type| field, but for a provider side key, we assign it
1305 * to the |save_type| field, because |type| is supposed to be set
1306 * to EVP_PKEY_NONE in that case.
1307 */
9dbfb11d
P
1308 if (ameth != NULL) {
1309 if (keymgmt != NULL)
1310 pkey->save_type = ameth->pkey_id;
1311 else if (pkey->ameth != NULL)
1312 pkey->type = ameth->pkey_id;
1313 }
8243d8d1
RL
1314#endif
1315 }
1316 return 1;
1317}
1318
f844f9eb 1319#ifndef FIPS_MODULE
8243d8d1
RL
1320static void find_ameth(const char *name, void *data)
1321{
1322 const char **str = data;
1323
1324 /*
1325 * The error messages from pkey_set_type() are uninteresting here,
1326 * and misleading.
1327 */
1328 ERR_set_mark();
1329
1330 if (pkey_set_type(NULL, NULL, EVP_PKEY_NONE, name, strlen(name),
1331 NULL)) {
1332 if (str[0] == NULL)
1333 str[0] = name;
1334 else if (str[1] == NULL)
1335 str[1] = name;
1336 }
1337
1338 ERR_pop_to_mark();
1339}
1340#endif
1341
1342int EVP_PKEY_set_type_by_keymgmt(EVP_PKEY *pkey, EVP_KEYMGMT *keymgmt)
1343{
f844f9eb 1344#ifndef FIPS_MODULE
8243d8d1
RL
1345# define EVP_PKEY_TYPE_STR str[0]
1346# define EVP_PKEY_TYPE_STRLEN (str[0] == NULL ? -1 : (int)strlen(str[0]))
1347 /*
1348 * Find at most two strings that have an associated EVP_PKEY_ASN1_METHOD
1349 * Ideally, only one should be found. If two (or more) are found, the
1350 * match is ambiguous. This should never happen, but...
1351 */
1352 const char *str[2] = { NULL, NULL };
1353
1354 EVP_KEYMGMT_names_do_all(keymgmt, find_ameth, &str);
1355 if (str[1] != NULL) {
1356 ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
1357 return 0;
1358 }
1359#else
1360# define EVP_PKEY_TYPE_STR NULL
1361# define EVP_PKEY_TYPE_STRLEN -1
1362#endif
1363 return pkey_set_type(pkey, NULL, EVP_PKEY_NONE,
1364 EVP_PKEY_TYPE_STR, EVP_PKEY_TYPE_STRLEN,
1365 keymgmt);
1366
1367#undef EVP_PKEY_TYPE_STR
1368#undef EVP_PKEY_TYPE_STRLEN
1369}
1370
e683582b
SL
1371int EVP_PKEY_up_ref(EVP_PKEY *pkey)
1372{
1373 int i;
1374
1375 if (CRYPTO_UP_REF(&pkey->references, &i, pkey->lock) <= 0)
1376 return 0;
1377
1378 REF_PRINT_COUNT("EVP_PKEY", pkey);
1379 REF_ASSERT_ISNT(i < 2);
1380 return ((i > 1) ? 1 : 0);
1381}
1382
f844f9eb 1383#ifndef FIPS_MODULE
62924755 1384void evp_pkey_free_legacy(EVP_PKEY *x)
badf51c8
RL
1385{
1386 if (x->ameth != NULL) {
ff3b59e1 1387 if (x->ameth->pkey_free != NULL)
badf51c8
RL
1388 x->ameth->pkey_free(x);
1389 x->pkey.ptr = NULL;
badf51c8
RL
1390 }
1391# ifndef OPENSSL_NO_ENGINE
1392 ENGINE_finish(x->engine);
1393 x->engine = NULL;
1394 ENGINE_finish(x->pmeth_engine);
1395 x->pmeth_engine = NULL;
1396# endif
8243d8d1 1397 x->type = EVP_PKEY_NONE;
badf51c8 1398}
f844f9eb 1399#endif /* FIPS_MODULE */
badf51c8 1400
e683582b
SL
1401static void evp_pkey_free_it(EVP_PKEY *x)
1402{
1403 /* internal function; x is never NULL */
1404
3c6ed955 1405 evp_keymgmt_util_clear_operation_cache(x);
f844f9eb 1406#ifndef FIPS_MODULE
badf51c8
RL
1407 evp_pkey_free_legacy(x);
1408#endif
e683582b 1409
3c6ed955
RL
1410 if (x->keymgmt != NULL) {
1411 evp_keymgmt_freedata(x->keymgmt, x->keydata);
1412 EVP_KEYMGMT_free(x->keymgmt);
1413 x->keymgmt = NULL;
1414 x->keydata = NULL;
1415 }
e683582b
SL
1416}
1417
1418void EVP_PKEY_free(EVP_PKEY *x)
1419{
1420 int i;
1421
1422 if (x == NULL)
1423 return;
1424
1425 CRYPTO_DOWN_REF(&x->references, &i, x->lock);
1426 REF_PRINT_COUNT("EVP_PKEY", x);
1427 if (i > 0)
1428 return;
1429 REF_ASSERT_ISNT(i < 0);
1430 evp_pkey_free_it(x);
f844f9eb 1431#ifndef FIPS_MODULE
ff1f7cde
AT
1432 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EVP_PKEY, x, &x->ex_data);
1433#endif
e683582b 1434 CRYPTO_THREAD_lock_free(x->lock);
f844f9eb 1435#ifndef FIPS_MODULE
e683582b
SL
1436 sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);
1437#endif
1438 OPENSSL_free(x);
1439}
1440
e683582b
SL
1441int EVP_PKEY_size(const EVP_PKEY *pkey)
1442{
adc9f731
RL
1443 int size = 0;
1444
6508e858 1445 if (pkey != NULL) {
adc9f731 1446 size = pkey->cache.size;
f844f9eb 1447#ifndef FIPS_MODULE
adc9f731
RL
1448 if (pkey->ameth != NULL && pkey->ameth->pkey_size != NULL)
1449 size = pkey->ameth->pkey_size(pkey);
1450#endif
6508e858 1451 }
adc9f731 1452 return size;
e683582b 1453}
f6aa5774 1454
3c6ed955
RL
1455void *evp_pkey_export_to_provider(EVP_PKEY *pk, OPENSSL_CTX *libctx,
1456 EVP_KEYMGMT **keymgmt,
1457 const char *propquery)
f6aa5774
RL
1458{
1459 EVP_KEYMGMT *allocated_keymgmt = NULL;
1460 EVP_KEYMGMT *tmp_keymgmt = NULL;
b305452f 1461 void *keydata = NULL;
adc9f731 1462 int check;
f6aa5774
RL
1463
1464 if (pk == NULL)
1465 return NULL;
1466
adc9f731
RL
1467 /* No key data => nothing to export */
1468 check = 1;
f844f9eb 1469#ifndef FIPS_MODULE
adc9f731
RL
1470 check = check && pk->pkey.ptr == NULL;
1471#endif
1472 check = check && pk->keydata == NULL;
1473 if (check)
1474 return NULL;
1475
f844f9eb 1476#ifndef FIPS_MODULE
3f7ce7f1 1477 if (pk->pkey.ptr != NULL) {
3f7ce7f1 1478 /*
3c6ed955
RL
1479 * If the legacy key doesn't have an dirty counter or export function,
1480 * give up
3f7ce7f1 1481 */
3c6ed955
RL
1482 if (pk->ameth->dirty_cnt == NULL || pk->ameth->export_to == NULL)
1483 return NULL;
3f7ce7f1
RL
1484 }
1485#endif
1486
3c6ed955
RL
1487 if (keymgmt != NULL) {
1488 tmp_keymgmt = *keymgmt;
1489 *keymgmt = NULL;
1490 }
1491
4b9e90f4
RL
1492 /*
1493 * If no keymgmt was given or found, get a default keymgmt. We do so by
1494 * letting EVP_PKEY_CTX_new_from_pkey() do it for us, then we steal it.
1495 */
f6aa5774 1496 if (tmp_keymgmt == NULL) {
2ee4a50a 1497 EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pk, propquery);
f6aa5774 1498
4b9e90f4
RL
1499 tmp_keymgmt = ctx->keymgmt;
1500 ctx->keymgmt = NULL;
f6aa5774
RL
1501 EVP_PKEY_CTX_free(ctx);
1502 }
1503
3c6ed955 1504 /* If there's still no keymgmt to be had, give up */
3f7ce7f1
RL
1505 if (tmp_keymgmt == NULL)
1506 goto end;
f6aa5774 1507
f844f9eb 1508#ifndef FIPS_MODULE
3f7ce7f1 1509 if (pk->pkey.ptr != NULL) {
3c6ed955 1510 size_t i = 0;
3f7ce7f1
RL
1511
1512 /*
3c6ed955
RL
1513 * If the legacy "origin" hasn't changed since last time, we try
1514 * to find our keymgmt in the operation cache. If it has changed,
1515 * |i| remains zero, and we will clear the cache further down.
3f7ce7f1 1516 */
3c6ed955
RL
1517 if (pk->ameth->dirty_cnt(pk) == pk->dirty_cnt_copy) {
1518 i = evp_keymgmt_util_find_operation_cache_index(pk, tmp_keymgmt);
1519
1520 /*
1521 * If |tmp_keymgmt| is present in the operation cache, it means
1522 * that export doesn't need to be redone. In that case, we take
1523 * token copies of the cached pointers, to have token success
1524 * values to return.
1525 */
1526 if (i < OSSL_NELEM(pk->operation_cache)
1527 && pk->operation_cache[i].keymgmt != NULL) {
1528 keydata = pk->operation_cache[i].keydata;
1529 goto end;
1530 }
3f7ce7f1
RL
1531 }
1532
1533 /*
3c6ed955
RL
1534 * TODO(3.0) Right now, we assume we have ample space. We will have
1535 * to think about a cache aging scheme, though, if |i| indexes outside
1536 * the array.
3f7ce7f1 1537 */
3c6ed955 1538 if (!ossl_assert(i < OSSL_NELEM(pk->operation_cache)))
3f7ce7f1
RL
1539 goto end;
1540
1541 /* Make sure that the keymgmt key type matches the legacy NID */
1542 if (!ossl_assert(EVP_KEYMGMT_is_a(tmp_keymgmt, OBJ_nid2sn(pk->type))))
1543 goto end;
1544
1545 if ((keydata = evp_keymgmt_newdata(tmp_keymgmt)) == NULL)
1546 goto end;
1547
76e23fc5 1548 if (!pk->ameth->export_to(pk, keydata, tmp_keymgmt, libctx, propquery)) {
3f7ce7f1
RL
1549 evp_keymgmt_freedata(tmp_keymgmt, keydata);
1550 keydata = NULL;
1551 goto end;
1552 }
1553
3c6ed955
RL
1554 /*
1555 * If the dirty counter changed since last time, then clear the
1556 * operation cache. In that case, we know that |i| is zero. Just
1557 * in case this is a re-export, we increment then decrement the
1558 * keymgmt reference counter.
1559 */
1560 if (!EVP_KEYMGMT_up_ref(tmp_keymgmt)) { /* refcnt++ */
1561 evp_keymgmt_freedata(tmp_keymgmt, keydata);
1562 keydata = NULL;
1563 goto end;
1564 }
1565 if (pk->ameth->dirty_cnt(pk) != pk->dirty_cnt_copy)
1566 evp_keymgmt_util_clear_operation_cache(pk);
1567 EVP_KEYMGMT_free(tmp_keymgmt); /* refcnt-- */
1568
1569 /* Add the new export to the operation cache */
1570 if (!evp_keymgmt_util_cache_keydata(pk, i, tmp_keymgmt, keydata)) {
1571 evp_keymgmt_freedata(tmp_keymgmt, keydata);
1572 keydata = NULL;
1573 goto end;
1574 }
3f7ce7f1
RL
1575
1576 /* Synchronize the dirty count */
1577 pk->dirty_cnt_copy = pk->ameth->dirty_cnt(pk);
1578 goto end;
1579 }
f844f9eb 1580#endif /* FIPS_MODULE */
3f7ce7f1
RL
1581
1582 keydata = evp_keymgmt_util_export_to_provider(pk, tmp_keymgmt);
1583
1584 end:
f6aa5774
RL
1585 /*
1586 * If nothing was exported, |tmp_keymgmt| might point at a freed
1587 * EVP_KEYMGMT, so we clear it to be safe. It shouldn't be useful for
1588 * the caller either way in that case.
1589 */
b305452f 1590 if (keydata == NULL)
f6aa5774
RL
1591 tmp_keymgmt = NULL;
1592
1593 if (keymgmt != NULL)
1594 *keymgmt = tmp_keymgmt;
1595
1596 EVP_KEYMGMT_free(allocated_keymgmt);
b305452f 1597 return keydata;
f6aa5774 1598}
badf51c8 1599
f844f9eb 1600#ifndef FIPS_MODULE
acb90ba8 1601int evp_pkey_downgrade(EVP_PKEY *pk)
badf51c8 1602{
acb90ba8
RL
1603 EVP_KEYMGMT *keymgmt = pk->keymgmt;
1604 void *keydata = pk->keydata;
1605 int type = pk->save_type;
1606 const char *keytype = NULL;
badf51c8 1607
acb90ba8
RL
1608 /* If this isn't a provider side key, we're done */
1609 if (keymgmt == NULL)
1610 return 1;
1611
1612 /* Get the key type name for error reporting */
1613 if (type != EVP_PKEY_NONE)
1614 keytype = OBJ_nid2sn(type);
1615 else
1616 keytype =
1617 evp_first_name(EVP_KEYMGMT_provider(keymgmt), keymgmt->name_id);
badf51c8
RL
1618
1619 /*
acb90ba8
RL
1620 * |save_type| was set when any of the EVP_PKEY_set_type functions
1621 * was called. It was set to EVP_PKEY_NONE if the key type wasn't
1622 * recognised to be any of the legacy key types, and the downgrade
1623 * isn't possible.
badf51c8 1624 */
acb90ba8
RL
1625 if (type == EVP_PKEY_NONE) {
1626 ERR_raise_data(ERR_LIB_EVP, EVP_R_UNKNOWN_KEY_TYPE,
1627 "key type = %s, can't downgrade", keytype);
1628 return 0;
badf51c8
RL
1629 }
1630
acb90ba8
RL
1631 /*
1632 * To be able to downgrade, we steal the provider side "origin" keymgmt
1633 * and keydata. We've already grabbed the pointers, so all we need to
1634 * do is clear those pointers in |pk| and then call evp_pkey_free_it().
1635 * That way, we can restore |pk| if we need to.
1636 */
1637 pk->keymgmt = NULL;
1638 pk->keydata = NULL;
1639 evp_pkey_free_it(pk);
1640 if (EVP_PKEY_set_type(pk, type)) {
1641 /* If the key is typed but empty, we're done */
49276c35
RL
1642 if (keydata == NULL) {
1643 /* We're dropping the EVP_KEYMGMT */
1644 EVP_KEYMGMT_free(keymgmt);
acb90ba8 1645 return 1;
49276c35 1646 }
badf51c8 1647
acb90ba8
RL
1648 if (pk->ameth->import_from == NULL) {
1649 ERR_raise_data(ERR_LIB_EVP, EVP_R_NO_IMPORT_FUNCTION,
1650 "key type = %s", keytype);
629c72db 1651 } else {
acb90ba8 1652 /*
629c72db
MC
1653 * We perform the export in the same libctx as the keymgmt that we
1654 * are using.
acb90ba8 1655 */
629c72db
MC
1656 OPENSSL_CTX *libctx = ossl_provider_library_context(keymgmt->prov);
1657 EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_from_pkey(libctx, pk, NULL);
1658 if (pctx == NULL)
1659 ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
1660
1661 if (pctx != NULL
1662 && evp_keymgmt_export(keymgmt, keydata,
1663 OSSL_KEYMGMT_SELECT_ALL,
1664 pk->ameth->import_from, pctx)) {
1665 /*
1666 * Save the provider side data in the operation cache, so they'll
1667 * find it again. evp_pkey_free_it() cleared the cache, so it's
1668 * safe to assume slot zero is free.
1669 * Note that evp_keymgmt_util_cache_keydata() increments keymgmt's
1670 * reference count.
1671 */
1672 evp_keymgmt_util_cache_keydata(pk, 0, keymgmt, keydata);
1673 EVP_PKEY_CTX_free(pctx);
1674
1675 /* Synchronize the dirty count */
1676 pk->dirty_cnt_copy = pk->ameth->dirty_cnt(pk);
1677
1678 /* evp_keymgmt_export() increased the refcount... */
1679 EVP_KEYMGMT_free(keymgmt);
1680 return 1;
1681 }
1682 EVP_PKEY_CTX_free(pctx);
badf51c8
RL
1683 }
1684
acb90ba8
RL
1685 ERR_raise_data(ERR_LIB_EVP, EVP_R_KEYMGMT_EXPORT_FAILURE,
1686 "key type = %s", keytype);
badf51c8
RL
1687 }
1688
badf51c8 1689 /*
acb90ba8
RL
1690 * Something went wrong. This could for example happen if the keymgmt
1691 * turns out to be an HSM implementation that refuses to let go of some
1692 * of the key data, typically the private bits. In this case, we restore
1693 * the provider side internal "origin" and leave it at that.
badf51c8 1694 */
acb90ba8
RL
1695 if (!ossl_assert(EVP_PKEY_set_type_by_keymgmt(pk, keymgmt))) {
1696 /* This should not be impossible */
1697 ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
1698 return 0;
1699 }
49276c35
RL
1700 /* EVP_PKEY_set_type_by_keymgmt() increased the refcount... */
1701 EVP_KEYMGMT_free(keymgmt);
acb90ba8
RL
1702 pk->keydata = keydata;
1703 evp_keymgmt_util_cache_keyinfo(pk);
1704 return 0; /* No downgrade, but at least the key is restored */
badf51c8 1705}
f844f9eb 1706#endif /* FIPS_MODULE */
96ebe52e
SL
1707
1708const OSSL_PARAM *EVP_PKEY_gettable_params(EVP_PKEY *pkey)
1709{
1710 if (pkey == NULL
1711 || pkey->keymgmt == NULL
1712 || pkey->keydata == NULL)
1713 return 0;
1714 return evp_keymgmt_gettable_params(pkey->keymgmt);
1715}
1716
96ebe52e
SL
1717int EVP_PKEY_get_bn_param(EVP_PKEY *pkey, const char *key_name, BIGNUM **bn)
1718{
1719 int ret = 0;
1720 OSSL_PARAM params[2];
1721 unsigned char buffer[2048];
96ebe52e
SL
1722 unsigned char *buf = NULL;
1723 size_t buf_sz = 0;
1724
1725 if (pkey == NULL
1726 || pkey->keymgmt == NULL
1727 || pkey->keydata == NULL
1728 || key_name == NULL
1729 || bn == NULL)
1730 return 0;
1731
1732 memset(buffer, 0, sizeof(buffer));
1733 params[0] = OSSL_PARAM_construct_BN(key_name, buffer, sizeof(buffer));
96ebe52e
SL
1734 params[1] = OSSL_PARAM_construct_end();
1735 if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params)) {
99ea4f02 1736 if (!OSSL_PARAM_modified(params) || params[0].return_size == 0)
96ebe52e
SL
1737 return 0;
1738 buf_sz = params[0].return_size;
1739 /*
1740 * If it failed because the buffer was too small then allocate the
1741 * required buffer size and retry.
1742 */
1743 buf = OPENSSL_zalloc(buf_sz);
1744 if (buf == NULL)
1745 return 0;
1746 params[0].data = buf;
1747 params[0].data_size = buf_sz;
1748
1749 if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params))
1750 goto err;
1751 }
1752 /* Fail if the param was not found */
99ea4f02 1753 if (!OSSL_PARAM_modified(params))
96ebe52e
SL
1754 goto err;
1755 ret = OSSL_PARAM_get_BN(params, bn);
1756err:
1757 OPENSSL_free(buf);
1758 return ret;
1759}
1760
1761int EVP_PKEY_get_octet_string_param(EVP_PKEY *pkey, const char *key_name,
1762 unsigned char *buf, size_t max_buf_sz,
1763 size_t *out_sz)
1764{
1765 OSSL_PARAM params[2];
96ebe52e
SL
1766
1767 if (pkey == NULL
1768 || pkey->keymgmt == NULL
1769 || pkey->keydata == NULL
1770 || key_name == NULL)
1771 return 0;
1772
1773 params[0] = OSSL_PARAM_construct_octet_string(key_name, buf, max_buf_sz);
96ebe52e 1774 params[1] = OSSL_PARAM_construct_end();
99ea4f02
P
1775 if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params)
1776 || !OSSL_PARAM_modified(params))
96ebe52e
SL
1777 return 0;
1778 if (out_sz != NULL)
1779 *out_sz = params[0].return_size;
1780 return 1;
1781}
1782
1783int EVP_PKEY_get_utf8_string_param(EVP_PKEY *pkey, const char *key_name,
1784 char *str, size_t max_buf_sz,
1785 size_t *out_sz)
1786{
1787 OSSL_PARAM params[2];
96ebe52e
SL
1788
1789 if (pkey == NULL
1790 || pkey->keymgmt == NULL
1791 || pkey->keydata == NULL
1792 || key_name == NULL)
1793 return 0;
1794
1795 params[0] = OSSL_PARAM_construct_utf8_string(key_name, str, max_buf_sz);
96ebe52e 1796 params[1] = OSSL_PARAM_construct_end();
99ea4f02
P
1797 if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params)
1798 || !OSSL_PARAM_modified(params))
96ebe52e
SL
1799 return 0;
1800 if (out_sz != NULL)
1801 *out_sz = params[0].return_size;
1802 return 1;
1803}
1804
1805int EVP_PKEY_get_int_param(EVP_PKEY *pkey, const char *key_name, int *out)
1806{
1807 OSSL_PARAM params[2];
96ebe52e
SL
1808
1809 if (pkey == NULL
1810 || pkey->keymgmt == NULL
1811 || pkey->keydata == NULL
1812 || key_name == NULL)
1813 return 0;
1814
1815 params[0] = OSSL_PARAM_construct_int(key_name, out);
96ebe52e 1816 params[1] = OSSL_PARAM_construct_end();
99ea4f02
P
1817 if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params)
1818 || !OSSL_PARAM_modified(params))
96ebe52e
SL
1819 return 0;
1820 return 1;
1821}
1822
1823int EVP_PKEY_get_size_t_param(EVP_PKEY *pkey, const char *key_name, size_t *out)
1824{
1825 OSSL_PARAM params[2];
96ebe52e
SL
1826
1827 if (pkey == NULL
1828 || pkey->keymgmt == NULL
1829 || pkey->keydata == NULL
1830 || key_name == NULL)
1831 return 0;
1832
1833 params[0] = OSSL_PARAM_construct_size_t(key_name, out);
96ebe52e 1834 params[1] = OSSL_PARAM_construct_end();
99ea4f02
P
1835 if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params)
1836 || !OSSL_PARAM_modified(params))
96ebe52e
SL
1837 return 0;
1838 return 1;
1839}