xref: /openbsd-src/lib/libcrypto/evp/p_lib.c (revision 87978dd930e6b6b96a9730bd9a446d7529f677fc)
1 /* $OpenBSD: p_lib.c,v 1.38 2023/11/19 15:46:10 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 	ret = malloc(sizeof(EVP_PKEY));
201 	if (ret == NULL) {
202 		EVPerror(ERR_R_MALLOC_FAILURE);
203 		return (NULL);
204 	}
205 	ret->type = EVP_PKEY_NONE;
206 	ret->save_type = EVP_PKEY_NONE;
207 	ret->references = 1;
208 	ret->ameth = NULL;
209 	ret->engine = NULL;
210 	ret->pkey.ptr = NULL;
211 	ret->attributes = NULL;
212 	ret->save_parameters = 1;
213 	return (ret);
214 }
215 
216 int
217 EVP_PKEY_up_ref(EVP_PKEY *pkey)
218 {
219 	int refs = CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
220 	return ((refs > 1) ? 1 : 0);
221 }
222 
223 /* Setup a public key ASN1 method and ENGINE from a NID or a string.
224  * If pkey is NULL just return 1 or 0 if the algorithm exists.
225  */
226 
227 static int
228 pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str, int len)
229 {
230 	const EVP_PKEY_ASN1_METHOD *ameth;
231 	ENGINE **eptr = NULL;
232 
233 	if (e == NULL)
234 		eptr = &e;
235 
236 	if (pkey) {
237 		if (pkey->pkey.ptr)
238 			EVP_PKEY_free_it(pkey);
239 		/* If key type matches and a method exists then this
240 		 * lookup has succeeded once so just indicate success.
241 		 */
242 		if ((type == pkey->save_type) && pkey->ameth)
243 			return 1;
244 	}
245 	if (str)
246 		ameth = EVP_PKEY_asn1_find_str(eptr, str, len);
247 	else
248 		ameth = EVP_PKEY_asn1_find(eptr, type);
249 	if (!ameth) {
250 		EVPerror(EVP_R_UNSUPPORTED_ALGORITHM);
251 		return 0;
252 	}
253 	if (pkey) {
254 		pkey->ameth = ameth;
255 		pkey->engine = e;
256 
257 		pkey->type = pkey->ameth->pkey_id;
258 		pkey->save_type = type;
259 	}
260 	return 1;
261 }
262 
263 int
264 EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
265 {
266 	return pkey_set_type(pkey, NULL, type, NULL, -1);
267 }
268 
269 EVP_PKEY *
270 EVP_PKEY_new_raw_private_key(int type, ENGINE *engine,
271     const unsigned char *private_key, size_t len)
272 {
273 	EVP_PKEY *ret;
274 
275 	if ((ret = EVP_PKEY_new()) == NULL)
276 		goto err;
277 
278 	if (!pkey_set_type(ret, engine, type, NULL, -1))
279 		goto err;
280 
281 	if (ret->ameth->set_priv_key == NULL) {
282 		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
283 		goto err;
284 	}
285 	if (!ret->ameth->set_priv_key(ret, private_key, len)) {
286 		EVPerror(EVP_R_KEY_SETUP_FAILED);
287 		goto err;
288 	}
289 
290 	return ret;
291 
292  err:
293 	EVP_PKEY_free(ret);
294 
295 	return NULL;
296 }
297 
298 EVP_PKEY *
299 EVP_PKEY_new_raw_public_key(int type, ENGINE *engine,
300     const unsigned char *public_key, size_t len)
301 {
302 	EVP_PKEY *ret;
303 
304 	if ((ret = EVP_PKEY_new()) == NULL)
305 		goto err;
306 
307 	if (!pkey_set_type(ret, engine, type, NULL, -1))
308 		goto err;
309 
310 	if (ret->ameth->set_pub_key == NULL) {
311 		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
312 		goto err;
313 	}
314 	if (!ret->ameth->set_pub_key(ret, public_key, len)) {
315 		EVPerror(EVP_R_KEY_SETUP_FAILED);
316 		goto err;
317 	}
318 
319 	return ret;
320 
321  err:
322 	EVP_PKEY_free(ret);
323 
324 	return NULL;
325 }
326 
327 int
328 EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey,
329     unsigned char *out_private_key, size_t *out_len)
330 {
331 	if (pkey->ameth->get_priv_key == NULL) {
332 		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
333 		return 0;
334 	}
335 	if (!pkey->ameth->get_priv_key(pkey, out_private_key, out_len)) {
336 		EVPerror(EVP_R_GET_RAW_KEY_FAILED);
337 		return 0;
338 	}
339 
340 	return 1;
341 }
342 
343 int
344 EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey,
345     unsigned char *out_public_key, size_t *out_len)
346 {
347 	if (pkey->ameth->get_pub_key == NULL) {
348 		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
349 		return 0;
350 	}
351 	if (!pkey->ameth->get_pub_key(pkey, out_public_key, out_len)) {
352 		EVPerror(EVP_R_GET_RAW_KEY_FAILED);
353 		return 0;
354 	}
355 
356 	return 1;
357 }
358 
359 EVP_PKEY *
360 EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv, size_t len,
361     const EVP_CIPHER *cipher)
362 {
363 	EVP_PKEY *ret = NULL;
364 	CMAC_CTX *cmctx = NULL;
365 
366 	if ((ret = EVP_PKEY_new()) == NULL)
367 		goto err;
368 	if ((cmctx = CMAC_CTX_new()) == NULL)
369 		goto err;
370 
371 	if (!pkey_set_type(ret, e, EVP_PKEY_CMAC, NULL, -1))
372 		goto err;
373 
374 	if (!CMAC_Init(cmctx, priv, len, cipher, e)) {
375 		EVPerror(EVP_R_KEY_SETUP_FAILED);
376 		goto err;
377 	}
378 
379 	ret->pkey.ptr = cmctx;
380 
381 	return ret;
382 
383  err:
384 	EVP_PKEY_free(ret);
385 	CMAC_CTX_free(cmctx);
386 	return NULL;
387 }
388 
389 int
390 EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len)
391 {
392 	return pkey_set_type(pkey, NULL, EVP_PKEY_NONE, str, len);
393 }
394 
395 int
396 EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
397 {
398 	if (!EVP_PKEY_set_type(pkey, type))
399 		return 0;
400 	pkey->pkey.ptr = key;
401 	return (key != NULL);
402 }
403 
404 void *
405 EVP_PKEY_get0(const EVP_PKEY *pkey)
406 {
407 	return pkey->pkey.ptr;
408 }
409 
410 const unsigned char *
411 EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len)
412 {
413 	ASN1_OCTET_STRING *os;
414 
415 	if (pkey->type != EVP_PKEY_HMAC) {
416 		EVPerror(EVP_R_EXPECTING_AN_HMAC_KEY);
417 		return NULL;
418 	}
419 
420 	os = EVP_PKEY_get0(pkey);
421 	*len = os->length;
422 
423 	return os->data;
424 }
425 
426 #ifndef OPENSSL_NO_RSA
427 RSA *
428 EVP_PKEY_get0_RSA(EVP_PKEY *pkey)
429 {
430 	if (pkey->type == EVP_PKEY_RSA || pkey->type == EVP_PKEY_RSA_PSS)
431 		return pkey->pkey.rsa;
432 
433 	EVPerror(EVP_R_EXPECTING_AN_RSA_KEY);
434 	return NULL;
435 }
436 
437 RSA *
438 EVP_PKEY_get1_RSA(EVP_PKEY *pkey)
439 {
440 	RSA *rsa;
441 
442 	if ((rsa = EVP_PKEY_get0_RSA(pkey)) == NULL)
443 		return NULL;
444 
445 	RSA_up_ref(rsa);
446 
447 	return rsa;
448 }
449 
450 int
451 EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key)
452 {
453 	int ret = EVP_PKEY_assign_RSA(pkey, key);
454 	if (ret != 0)
455 		RSA_up_ref(key);
456 	return ret;
457 }
458 #endif
459 
460 #ifndef OPENSSL_NO_DSA
461 DSA *
462 EVP_PKEY_get0_DSA(EVP_PKEY *pkey)
463 {
464 	if (pkey->type != EVP_PKEY_DSA) {
465 		EVPerror(EVP_R_EXPECTING_A_DSA_KEY);
466 		return NULL;
467 	}
468 	return pkey->pkey.dsa;
469 }
470 
471 DSA *
472 EVP_PKEY_get1_DSA(EVP_PKEY *pkey)
473 {
474 	DSA *dsa;
475 
476 	if ((dsa = EVP_PKEY_get0_DSA(pkey)) == NULL)
477 		return NULL;
478 
479 	DSA_up_ref(dsa);
480 
481 	return dsa;
482 }
483 
484 int
485 EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
486 {
487 	int ret = EVP_PKEY_assign_DSA(pkey, key);
488 	if (ret != 0)
489 		DSA_up_ref(key);
490 	return ret;
491 }
492 #endif
493 
494 #ifndef OPENSSL_NO_EC
495 EC_KEY *
496 EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey)
497 {
498 	if (pkey->type != EVP_PKEY_EC) {
499 		EVPerror(EVP_R_EXPECTING_A_EC_KEY);
500 		return NULL;
501 	}
502 	return pkey->pkey.ec;
503 }
504 
505 EC_KEY *
506 EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey)
507 {
508 	EC_KEY *key;
509 
510 	if ((key = EVP_PKEY_get0_EC_KEY(pkey)) == NULL)
511 		return NULL;
512 
513 	EC_KEY_up_ref(key);
514 
515 	return key;
516 }
517 
518 int
519 EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key)
520 {
521 	int ret = EVP_PKEY_assign_EC_KEY(pkey, key);
522 	if (ret != 0)
523 		EC_KEY_up_ref(key);
524 	return ret;
525 }
526 #endif
527 
528 
529 #ifndef OPENSSL_NO_DH
530 DH *
531 EVP_PKEY_get0_DH(EVP_PKEY *pkey)
532 {
533 	if (pkey->type != EVP_PKEY_DH) {
534 		EVPerror(EVP_R_EXPECTING_A_DH_KEY);
535 		return NULL;
536 	}
537 	return pkey->pkey.dh;
538 }
539 
540 DH *
541 EVP_PKEY_get1_DH(EVP_PKEY *pkey)
542 {
543 	DH *dh;
544 
545 	if ((dh = EVP_PKEY_get0_DH(pkey)) == NULL)
546 		return NULL;
547 
548 	DH_up_ref(dh);
549 
550 	return dh;
551 }
552 
553 int
554 EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key)
555 {
556 	int ret = EVP_PKEY_assign_DH(pkey, key);
557 	if (ret != 0)
558 		DH_up_ref(key);
559 	return ret;
560 }
561 #endif
562 
563 int
564 EVP_PKEY_type(int type)
565 {
566 	int ret;
567 	const EVP_PKEY_ASN1_METHOD *ameth;
568 	ENGINE *e;
569 	ameth = EVP_PKEY_asn1_find(&e, type);
570 	if (ameth)
571 		ret = ameth->pkey_id;
572 	else
573 		ret = NID_undef;
574 	return ret;
575 }
576 
577 int
578 EVP_PKEY_id(const EVP_PKEY *pkey)
579 {
580 	return pkey->type;
581 }
582 
583 int
584 EVP_PKEY_base_id(const EVP_PKEY *pkey)
585 {
586 	return EVP_PKEY_type(pkey->type);
587 }
588 
589 void
590 EVP_PKEY_free(EVP_PKEY *x)
591 {
592 	int i;
593 
594 	if (x == NULL)
595 		return;
596 
597 	i = CRYPTO_add(&x->references, -1, CRYPTO_LOCK_EVP_PKEY);
598 	if (i > 0)
599 		return;
600 
601 	EVP_PKEY_free_it(x);
602 	if (x->attributes)
603 		sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);
604 	free(x);
605 }
606 
607 static void
608 EVP_PKEY_free_it(EVP_PKEY *x)
609 {
610 	if (x->ameth && x->ameth->pkey_free) {
611 		x->ameth->pkey_free(x);
612 		x->pkey.ptr = NULL;
613 	}
614 }
615 
616 static int
617 unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent, const char *kstr)
618 {
619 	if (!BIO_indent(out, indent, 128))
620 		return 0;
621 	BIO_printf(out, "%s algorithm \"%s\" unsupported\n",
622 	    kstr, OBJ_nid2ln(pkey->type));
623 	return 1;
624 }
625 
626 int
627 EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent,
628     ASN1_PCTX *pctx)
629 {
630 	if (pkey->ameth && pkey->ameth->pub_print)
631 		return pkey->ameth->pub_print(out, pkey, indent, pctx);
632 
633 	return unsup_alg(out, pkey, indent, "Public Key");
634 }
635 
636 int
637 EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent,
638     ASN1_PCTX *pctx)
639 {
640 	if (pkey->ameth && pkey->ameth->priv_print)
641 		return pkey->ameth->priv_print(out, pkey, indent, pctx);
642 
643 	return unsup_alg(out, pkey, indent, "Private Key");
644 }
645 
646 int
647 EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent,
648     ASN1_PCTX *pctx)
649 {
650 	if (pkey->ameth && pkey->ameth->param_print)
651 		return pkey->ameth->param_print(out, pkey, indent, pctx);
652 	return unsup_alg(out, pkey, indent, "Parameters");
653 }
654 
655 int
656 EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid)
657 {
658 	if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
659 		return -2;
660 	return pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID,
661 	    0, pnid);
662 }
663