xref: /openbsd-src/lib/libcrypto/evp/p_lib.c (revision 7dfcc577e117c768d3f181dea4abefc8e2801e22)
1 /* $OpenBSD: p_lib.c,v 1.40 2023/12/25 21:25:24 tb Exp $ */
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3  * All rights reserved.
4  *
5  * This package is an SSL implementation written
6  * by Eric Young (eay@cryptsoft.com).
7  * The implementation was written so as to conform with Netscapes SSL.
8  *
9  * This library is free for commercial and non-commercial use as long as
10  * the following conditions are aheared to.  The following conditions
11  * apply to all code found in this distribution, be it the RC4, RSA,
12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13  * included with this distribution is covered by the same copyright terms
14  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15  *
16  * Copyright remains Eric Young's, and as such any Copyright notices in
17  * the code are not to be removed.
18  * If this package is used in a product, Eric Young should be given attribution
19  * as the author of the parts of the library used.
20  * This can be in the form of a textual message at program startup or
21  * in documentation (online or textual) provided with the package.
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  *    notice, this list of conditions and the following disclaimer in the
30  *    documentation and/or other materials provided with the distribution.
31  * 3. All advertising materials mentioning features or use of this software
32  *    must display the following acknowledgement:
33  *    "This product includes cryptographic software written by
34  *     Eric Young (eay@cryptsoft.com)"
35  *    The word 'cryptographic' can be left out if the rouines from the library
36  *    being used are not cryptographic related :-).
37  * 4. If you include any Windows specific code (or a derivative thereof) from
38  *    the apps directory (application code) you must include an acknowledgement:
39  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40  *
41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  *
53  * The licence and distribution terms for any publically available version or
54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55  * copied and put under another distribution licence
56  * [including the GNU Public Licence.]
57  */
58 
59 #include <stdio.h>
60 
61 #include <openssl/opensslconf.h>
62 
63 #include <openssl/bn.h>
64 #include <openssl/cmac.h>
65 #include <openssl/err.h>
66 #include <openssl/evp.h>
67 #include <openssl/objects.h>
68 #include <openssl/x509.h>
69 
70 #ifndef OPENSSL_NO_DH
71 #include <openssl/dh.h>
72 #endif
73 #ifndef OPENSSL_NO_DSA
74 #include <openssl/dsa.h>
75 #endif
76 #ifndef OPENSSL_NO_RSA
77 #include <openssl/rsa.h>
78 #endif
79 
80 #include "asn1_local.h"
81 #include "evp_local.h"
82 
83 static void EVP_PKEY_free_it(EVP_PKEY *x);
84 
85 int
86 EVP_PKEY_bits(const EVP_PKEY *pkey)
87 {
88 	if (pkey && pkey->ameth && pkey->ameth->pkey_bits)
89 		return pkey->ameth->pkey_bits(pkey);
90 	return 0;
91 }
92 
93 int
94 EVP_PKEY_security_bits(const EVP_PKEY *pkey)
95 {
96 	if (pkey == NULL)
97 		return 0;
98 	if (pkey->ameth == NULL || pkey->ameth->pkey_security_bits == NULL)
99 		return -2;
100 
101 	return pkey->ameth->pkey_security_bits(pkey);
102 }
103 
104 int
105 EVP_PKEY_size(const EVP_PKEY *pkey)
106 {
107 	if (pkey && pkey->ameth && pkey->ameth->pkey_size)
108 		return pkey->ameth->pkey_size(pkey);
109 	return 0;
110 }
111 
112 int
113 EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode)
114 {
115 #ifndef OPENSSL_NO_DSA
116 	if (pkey->type == EVP_PKEY_DSA) {
117 		int ret = pkey->save_parameters;
118 
119 		if (mode >= 0)
120 			pkey->save_parameters = mode;
121 		return (ret);
122 	}
123 #endif
124 #ifndef OPENSSL_NO_EC
125 	if (pkey->type == EVP_PKEY_EC) {
126 		int ret = pkey->save_parameters;
127 
128 		if (mode >= 0)
129 			pkey->save_parameters = mode;
130 		return (ret);
131 	}
132 #endif
133 	return (0);
134 }
135 
136 int
137 EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
138 {
139 	if (to->type != from->type) {
140 		EVPerror(EVP_R_DIFFERENT_KEY_TYPES);
141 		goto err;
142 	}
143 
144 	if (EVP_PKEY_missing_parameters(from)) {
145 		EVPerror(EVP_R_MISSING_PARAMETERS);
146 		goto err;
147 	}
148 	if (from->ameth && from->ameth->param_copy)
149 		return from->ameth->param_copy(to, from);
150 
151 err:
152 	return 0;
153 }
154 
155 int
156 EVP_PKEY_missing_parameters(const EVP_PKEY *pkey)
157 {
158 	if (pkey->ameth && pkey->ameth->param_missing)
159 		return pkey->ameth->param_missing(pkey);
160 	return 0;
161 }
162 
163 int
164 EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
165 {
166 	if (a->type != b->type)
167 		return -1;
168 	if (a->ameth && a->ameth->param_cmp)
169 		return a->ameth->param_cmp(a, b);
170 	return -2;
171 }
172 
173 int
174 EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
175 {
176 	if (a->type != b->type)
177 		return -1;
178 
179 	if (a->ameth) {
180 		int ret;
181 		/* Compare parameters if the algorithm has them */
182 		if (a->ameth->param_cmp) {
183 			ret = a->ameth->param_cmp(a, b);
184 			if (ret <= 0)
185 				return ret;
186 		}
187 
188 		if (a->ameth->pub_cmp)
189 			return a->ameth->pub_cmp(a, b);
190 	}
191 
192 	return -2;
193 }
194 
195 EVP_PKEY *
196 EVP_PKEY_new(void)
197 {
198 	EVP_PKEY *ret;
199 
200 	if ((ret = calloc(1, sizeof(*ret))) == NULL) {
201 		EVPerror(ERR_R_MALLOC_FAILURE);
202 		return NULL;
203 	}
204 
205 	ret->type = EVP_PKEY_NONE;
206 	ret->save_type = EVP_PKEY_NONE;
207 	ret->references = 1;
208 	ret->save_parameters = 1;
209 
210 	return ret;
211 }
212 
213 int
214 EVP_PKEY_up_ref(EVP_PKEY *pkey)
215 {
216 	int refs = CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
217 	return ((refs > 1) ? 1 : 0);
218 }
219 
220 /* Setup a public key ASN1 method from a NID or a string.
221  * If pkey is NULL just return 1 or 0 if the algorithm exists.
222  */
223 
224 static int
225 pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len)
226 {
227 	const EVP_PKEY_ASN1_METHOD *ameth;
228 
229 	if (pkey) {
230 		if (pkey->pkey.ptr)
231 			EVP_PKEY_free_it(pkey);
232 		/* If key type matches and a method exists then this
233 		 * lookup has succeeded once so just indicate success.
234 		 */
235 		if ((type == pkey->save_type) && pkey->ameth)
236 			return 1;
237 	}
238 	if (str != NULL)
239 		ameth = EVP_PKEY_asn1_find_str(NULL, str, len);
240 	else
241 		ameth = EVP_PKEY_asn1_find(NULL, type);
242 	if (!ameth) {
243 		EVPerror(EVP_R_UNSUPPORTED_ALGORITHM);
244 		return 0;
245 	}
246 	if (pkey) {
247 		pkey->ameth = ameth;
248 
249 		pkey->type = pkey->ameth->pkey_id;
250 		pkey->save_type = type;
251 	}
252 	return 1;
253 }
254 
255 int
256 EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
257 {
258 	return pkey_set_type(pkey, type, NULL, -1);
259 }
260 
261 EVP_PKEY *
262 EVP_PKEY_new_raw_private_key(int type, ENGINE *engine,
263     const unsigned char *private_key, size_t len)
264 {
265 	EVP_PKEY *ret;
266 
267 	if ((ret = EVP_PKEY_new()) == NULL)
268 		goto err;
269 
270 	if (!pkey_set_type(ret, type, NULL, -1))
271 		goto err;
272 
273 	if (ret->ameth->set_priv_key == NULL) {
274 		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
275 		goto err;
276 	}
277 	if (!ret->ameth->set_priv_key(ret, private_key, len)) {
278 		EVPerror(EVP_R_KEY_SETUP_FAILED);
279 		goto err;
280 	}
281 
282 	return ret;
283 
284  err:
285 	EVP_PKEY_free(ret);
286 
287 	return NULL;
288 }
289 
290 EVP_PKEY *
291 EVP_PKEY_new_raw_public_key(int type, ENGINE *engine,
292     const unsigned char *public_key, size_t len)
293 {
294 	EVP_PKEY *ret;
295 
296 	if ((ret = EVP_PKEY_new()) == NULL)
297 		goto err;
298 
299 	if (!pkey_set_type(ret, type, NULL, -1))
300 		goto err;
301 
302 	if (ret->ameth->set_pub_key == NULL) {
303 		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
304 		goto err;
305 	}
306 	if (!ret->ameth->set_pub_key(ret, public_key, len)) {
307 		EVPerror(EVP_R_KEY_SETUP_FAILED);
308 		goto err;
309 	}
310 
311 	return ret;
312 
313  err:
314 	EVP_PKEY_free(ret);
315 
316 	return NULL;
317 }
318 
319 int
320 EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey,
321     unsigned char *out_private_key, size_t *out_len)
322 {
323 	if (pkey->ameth->get_priv_key == NULL) {
324 		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
325 		return 0;
326 	}
327 	if (!pkey->ameth->get_priv_key(pkey, out_private_key, out_len)) {
328 		EVPerror(EVP_R_GET_RAW_KEY_FAILED);
329 		return 0;
330 	}
331 
332 	return 1;
333 }
334 
335 int
336 EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey,
337     unsigned char *out_public_key, size_t *out_len)
338 {
339 	if (pkey->ameth->get_pub_key == NULL) {
340 		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
341 		return 0;
342 	}
343 	if (!pkey->ameth->get_pub_key(pkey, out_public_key, out_len)) {
344 		EVPerror(EVP_R_GET_RAW_KEY_FAILED);
345 		return 0;
346 	}
347 
348 	return 1;
349 }
350 
351 EVP_PKEY *
352 EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv, size_t len,
353     const EVP_CIPHER *cipher)
354 {
355 	EVP_PKEY *ret = NULL;
356 	CMAC_CTX *cmctx = NULL;
357 
358 	if ((ret = EVP_PKEY_new()) == NULL)
359 		goto err;
360 	if ((cmctx = CMAC_CTX_new()) == NULL)
361 		goto err;
362 
363 	if (!pkey_set_type(ret, EVP_PKEY_CMAC, NULL, -1))
364 		goto err;
365 
366 	if (!CMAC_Init(cmctx, priv, len, cipher, NULL)) {
367 		EVPerror(EVP_R_KEY_SETUP_FAILED);
368 		goto err;
369 	}
370 
371 	ret->pkey.ptr = cmctx;
372 
373 	return ret;
374 
375  err:
376 	EVP_PKEY_free(ret);
377 	CMAC_CTX_free(cmctx);
378 	return NULL;
379 }
380 
381 int
382 EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len)
383 {
384 	return pkey_set_type(pkey, EVP_PKEY_NONE, str, len);
385 }
386 
387 int
388 EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
389 {
390 	if (!EVP_PKEY_set_type(pkey, type))
391 		return 0;
392 	pkey->pkey.ptr = key;
393 	return (key != NULL);
394 }
395 
396 void *
397 EVP_PKEY_get0(const EVP_PKEY *pkey)
398 {
399 	return pkey->pkey.ptr;
400 }
401 
402 const unsigned char *
403 EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len)
404 {
405 	ASN1_OCTET_STRING *os;
406 
407 	if (pkey->type != EVP_PKEY_HMAC) {
408 		EVPerror(EVP_R_EXPECTING_AN_HMAC_KEY);
409 		return NULL;
410 	}
411 
412 	os = EVP_PKEY_get0(pkey);
413 	*len = os->length;
414 
415 	return os->data;
416 }
417 
418 #ifndef OPENSSL_NO_RSA
419 RSA *
420 EVP_PKEY_get0_RSA(EVP_PKEY *pkey)
421 {
422 	if (pkey->type == EVP_PKEY_RSA || pkey->type == EVP_PKEY_RSA_PSS)
423 		return pkey->pkey.rsa;
424 
425 	EVPerror(EVP_R_EXPECTING_AN_RSA_KEY);
426 	return NULL;
427 }
428 
429 RSA *
430 EVP_PKEY_get1_RSA(EVP_PKEY *pkey)
431 {
432 	RSA *rsa;
433 
434 	if ((rsa = EVP_PKEY_get0_RSA(pkey)) == NULL)
435 		return NULL;
436 
437 	RSA_up_ref(rsa);
438 
439 	return rsa;
440 }
441 
442 int
443 EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key)
444 {
445 	int ret = EVP_PKEY_assign_RSA(pkey, key);
446 	if (ret != 0)
447 		RSA_up_ref(key);
448 	return ret;
449 }
450 #endif
451 
452 #ifndef OPENSSL_NO_DSA
453 DSA *
454 EVP_PKEY_get0_DSA(EVP_PKEY *pkey)
455 {
456 	if (pkey->type != EVP_PKEY_DSA) {
457 		EVPerror(EVP_R_EXPECTING_A_DSA_KEY);
458 		return NULL;
459 	}
460 	return pkey->pkey.dsa;
461 }
462 
463 DSA *
464 EVP_PKEY_get1_DSA(EVP_PKEY *pkey)
465 {
466 	DSA *dsa;
467 
468 	if ((dsa = EVP_PKEY_get0_DSA(pkey)) == NULL)
469 		return NULL;
470 
471 	DSA_up_ref(dsa);
472 
473 	return dsa;
474 }
475 
476 int
477 EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
478 {
479 	int ret = EVP_PKEY_assign_DSA(pkey, key);
480 	if (ret != 0)
481 		DSA_up_ref(key);
482 	return ret;
483 }
484 #endif
485 
486 #ifndef OPENSSL_NO_EC
487 EC_KEY *
488 EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey)
489 {
490 	if (pkey->type != EVP_PKEY_EC) {
491 		EVPerror(EVP_R_EXPECTING_A_EC_KEY);
492 		return NULL;
493 	}
494 	return pkey->pkey.ec;
495 }
496 
497 EC_KEY *
498 EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey)
499 {
500 	EC_KEY *key;
501 
502 	if ((key = EVP_PKEY_get0_EC_KEY(pkey)) == NULL)
503 		return NULL;
504 
505 	EC_KEY_up_ref(key);
506 
507 	return key;
508 }
509 
510 int
511 EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key)
512 {
513 	int ret = EVP_PKEY_assign_EC_KEY(pkey, key);
514 	if (ret != 0)
515 		EC_KEY_up_ref(key);
516 	return ret;
517 }
518 #endif
519 
520 
521 #ifndef OPENSSL_NO_DH
522 DH *
523 EVP_PKEY_get0_DH(EVP_PKEY *pkey)
524 {
525 	if (pkey->type != EVP_PKEY_DH) {
526 		EVPerror(EVP_R_EXPECTING_A_DH_KEY);
527 		return NULL;
528 	}
529 	return pkey->pkey.dh;
530 }
531 
532 DH *
533 EVP_PKEY_get1_DH(EVP_PKEY *pkey)
534 {
535 	DH *dh;
536 
537 	if ((dh = EVP_PKEY_get0_DH(pkey)) == NULL)
538 		return NULL;
539 
540 	DH_up_ref(dh);
541 
542 	return dh;
543 }
544 
545 int
546 EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key)
547 {
548 	int ret = EVP_PKEY_assign_DH(pkey, key);
549 	if (ret != 0)
550 		DH_up_ref(key);
551 	return ret;
552 }
553 #endif
554 
555 int
556 EVP_PKEY_type(int type)
557 {
558 	const EVP_PKEY_ASN1_METHOD *ameth;
559 
560 	if ((ameth = EVP_PKEY_asn1_find(NULL, type)) != NULL)
561 		return ameth->pkey_id;
562 
563 	return NID_undef;
564 }
565 
566 int
567 EVP_PKEY_id(const EVP_PKEY *pkey)
568 {
569 	return pkey->type;
570 }
571 
572 int
573 EVP_PKEY_base_id(const EVP_PKEY *pkey)
574 {
575 	return EVP_PKEY_type(pkey->type);
576 }
577 
578 void
579 EVP_PKEY_free(EVP_PKEY *x)
580 {
581 	int i;
582 
583 	if (x == NULL)
584 		return;
585 
586 	i = CRYPTO_add(&x->references, -1, CRYPTO_LOCK_EVP_PKEY);
587 	if (i > 0)
588 		return;
589 
590 	EVP_PKEY_free_it(x);
591 	if (x->attributes)
592 		sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);
593 	free(x);
594 }
595 
596 static void
597 EVP_PKEY_free_it(EVP_PKEY *x)
598 {
599 	if (x->ameth && x->ameth->pkey_free) {
600 		x->ameth->pkey_free(x);
601 		x->pkey.ptr = NULL;
602 	}
603 }
604 
605 static int
606 unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent, const char *kstr)
607 {
608 	if (!BIO_indent(out, indent, 128))
609 		return 0;
610 	BIO_printf(out, "%s algorithm \"%s\" unsupported\n",
611 	    kstr, OBJ_nid2ln(pkey->type));
612 	return 1;
613 }
614 
615 int
616 EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent,
617     ASN1_PCTX *pctx)
618 {
619 	if (pkey->ameth && pkey->ameth->pub_print)
620 		return pkey->ameth->pub_print(out, pkey, indent, pctx);
621 
622 	return unsup_alg(out, pkey, indent, "Public Key");
623 }
624 
625 int
626 EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent,
627     ASN1_PCTX *pctx)
628 {
629 	if (pkey->ameth && pkey->ameth->priv_print)
630 		return pkey->ameth->priv_print(out, pkey, indent, pctx);
631 
632 	return unsup_alg(out, pkey, indent, "Private Key");
633 }
634 
635 int
636 EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent,
637     ASN1_PCTX *pctx)
638 {
639 	if (pkey->ameth && pkey->ameth->param_print)
640 		return pkey->ameth->param_print(out, pkey, indent, pctx);
641 	return unsup_alg(out, pkey, indent, "Parameters");
642 }
643 
644 int
645 EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid)
646 {
647 	if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
648 		return -2;
649 	return pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID,
650 	    0, pnid);
651 }
652