1 /* $OpenBSD: p_lib.c,v 1.29 2022/06/27 12:36:05 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 #ifndef OPENSSL_NO_ENGINE
81 #include <openssl/engine.h>
82 #endif
83
84 #include "asn1_locl.h"
85 #include "evp_locl.h"
86
87 static void EVP_PKEY_free_it(EVP_PKEY *x);
88
89 int
EVP_PKEY_bits(const EVP_PKEY * pkey)90 EVP_PKEY_bits(const EVP_PKEY *pkey)
91 {
92 if (pkey && pkey->ameth && pkey->ameth->pkey_bits)
93 return pkey->ameth->pkey_bits(pkey);
94 return 0;
95 }
96
97 int
EVP_PKEY_security_bits(const EVP_PKEY * pkey)98 EVP_PKEY_security_bits(const EVP_PKEY *pkey)
99 {
100 if (pkey == NULL)
101 return 0;
102 if (pkey->ameth == NULL || pkey->ameth->pkey_security_bits == NULL)
103 return -2;
104
105 return pkey->ameth->pkey_security_bits(pkey);
106 }
107
108 int
EVP_PKEY_size(const EVP_PKEY * pkey)109 EVP_PKEY_size(const EVP_PKEY *pkey)
110 {
111 if (pkey && pkey->ameth && pkey->ameth->pkey_size)
112 return pkey->ameth->pkey_size(pkey);
113 return 0;
114 }
115
116 int
EVP_PKEY_save_parameters(EVP_PKEY * pkey,int mode)117 EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode)
118 {
119 #ifndef OPENSSL_NO_DSA
120 if (pkey->type == EVP_PKEY_DSA) {
121 int ret = pkey->save_parameters;
122
123 if (mode >= 0)
124 pkey->save_parameters = mode;
125 return (ret);
126 }
127 #endif
128 #ifndef OPENSSL_NO_EC
129 if (pkey->type == EVP_PKEY_EC) {
130 int ret = pkey->save_parameters;
131
132 if (mode >= 0)
133 pkey->save_parameters = mode;
134 return (ret);
135 }
136 #endif
137 return (0);
138 }
139
140 int
EVP_PKEY_copy_parameters(EVP_PKEY * to,const EVP_PKEY * from)141 EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
142 {
143 if (to->type != from->type) {
144 EVPerror(EVP_R_DIFFERENT_KEY_TYPES);
145 goto err;
146 }
147
148 if (EVP_PKEY_missing_parameters(from)) {
149 EVPerror(EVP_R_MISSING_PARAMETERS);
150 goto err;
151 }
152 if (from->ameth && from->ameth->param_copy)
153 return from->ameth->param_copy(to, from);
154
155 err:
156 return 0;
157 }
158
159 int
EVP_PKEY_missing_parameters(const EVP_PKEY * pkey)160 EVP_PKEY_missing_parameters(const EVP_PKEY *pkey)
161 {
162 if (pkey->ameth && pkey->ameth->param_missing)
163 return pkey->ameth->param_missing(pkey);
164 return 0;
165 }
166
167 int
EVP_PKEY_cmp_parameters(const EVP_PKEY * a,const EVP_PKEY * b)168 EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
169 {
170 if (a->type != b->type)
171 return -1;
172 if (a->ameth && a->ameth->param_cmp)
173 return a->ameth->param_cmp(a, b);
174 return -2;
175 }
176
177 int
EVP_PKEY_cmp(const EVP_PKEY * a,const EVP_PKEY * b)178 EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
179 {
180 if (a->type != b->type)
181 return -1;
182
183 if (a->ameth) {
184 int ret;
185 /* Compare parameters if the algorithm has them */
186 if (a->ameth->param_cmp) {
187 ret = a->ameth->param_cmp(a, b);
188 if (ret <= 0)
189 return ret;
190 }
191
192 if (a->ameth->pub_cmp)
193 return a->ameth->pub_cmp(a, b);
194 }
195
196 return -2;
197 }
198
199 EVP_PKEY *
EVP_PKEY_new(void)200 EVP_PKEY_new(void)
201 {
202 EVP_PKEY *ret;
203
204 ret = malloc(sizeof(EVP_PKEY));
205 if (ret == NULL) {
206 EVPerror(ERR_R_MALLOC_FAILURE);
207 return (NULL);
208 }
209 ret->type = EVP_PKEY_NONE;
210 ret->save_type = EVP_PKEY_NONE;
211 ret->references = 1;
212 ret->ameth = NULL;
213 ret->engine = NULL;
214 ret->pkey.ptr = NULL;
215 ret->attributes = NULL;
216 ret->save_parameters = 1;
217 return (ret);
218 }
219
220 int
EVP_PKEY_up_ref(EVP_PKEY * pkey)221 EVP_PKEY_up_ref(EVP_PKEY *pkey)
222 {
223 int refs = CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
224 return ((refs > 1) ? 1 : 0);
225 }
226
227 /* Setup a public key ASN1 method and ENGINE from a NID or a string.
228 * If pkey is NULL just return 1 or 0 if the algorithm exists.
229 */
230
231 static int
pkey_set_type(EVP_PKEY * pkey,ENGINE * e,int type,const char * str,int len)232 pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str, int len)
233 {
234 const EVP_PKEY_ASN1_METHOD *ameth;
235 ENGINE **eptr = NULL;
236
237 if (e == NULL)
238 eptr = &e;
239
240 if (pkey) {
241 if (pkey->pkey.ptr)
242 EVP_PKEY_free_it(pkey);
243 /* If key type matches and a method exists then this
244 * lookup has succeeded once so just indicate success.
245 */
246 if ((type == pkey->save_type) && pkey->ameth)
247 return 1;
248 #ifndef OPENSSL_NO_ENGINE
249 ENGINE_finish(pkey->engine);
250 pkey->engine = NULL;
251 #endif
252 }
253 if (str)
254 ameth = EVP_PKEY_asn1_find_str(eptr, str, len);
255 else
256 ameth = EVP_PKEY_asn1_find(eptr, type);
257 #ifndef OPENSSL_NO_ENGINE
258 if (pkey == NULL && eptr != NULL)
259 ENGINE_finish(e);
260 #endif
261 if (!ameth) {
262 EVPerror(EVP_R_UNSUPPORTED_ALGORITHM);
263 return 0;
264 }
265 if (pkey) {
266 pkey->ameth = ameth;
267 pkey->engine = e;
268
269 pkey->type = pkey->ameth->pkey_id;
270 pkey->save_type = type;
271 }
272 return 1;
273 }
274
275 int
EVP_PKEY_set_type(EVP_PKEY * pkey,int type)276 EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
277 {
278 return pkey_set_type(pkey, NULL, type, NULL, -1);
279 }
280
281 EVP_PKEY *
EVP_PKEY_new_CMAC_key(ENGINE * e,const unsigned char * priv,size_t len,const EVP_CIPHER * cipher)282 EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv, size_t len,
283 const EVP_CIPHER *cipher)
284 {
285 EVP_PKEY *ret = NULL;
286 CMAC_CTX *cmctx = NULL;
287
288 if ((ret = EVP_PKEY_new()) == NULL)
289 goto err;
290 if ((cmctx = CMAC_CTX_new()) == NULL)
291 goto err;
292
293 if (!pkey_set_type(ret, e, EVP_PKEY_CMAC, NULL, -1))
294 goto err;
295
296 if (!CMAC_Init(cmctx, priv, len, cipher, e)) {
297 EVPerror(EVP_R_KEY_SETUP_FAILED);
298 goto err;
299 }
300
301 ret->pkey.ptr = (char *)cmctx;
302
303 return ret;
304
305 err:
306 EVP_PKEY_free(ret);
307 CMAC_CTX_free(cmctx);
308 return NULL;
309 }
310
311 int
EVP_PKEY_set_type_str(EVP_PKEY * pkey,const char * str,int len)312 EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len)
313 {
314 return pkey_set_type(pkey, NULL, EVP_PKEY_NONE, str, len);
315 }
316
317 int
EVP_PKEY_assign(EVP_PKEY * pkey,int type,void * key)318 EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
319 {
320 if (!EVP_PKEY_set_type(pkey, type))
321 return 0;
322 pkey->pkey.ptr = key;
323 return (key != NULL);
324 }
325
326 void *
EVP_PKEY_get0(const EVP_PKEY * pkey)327 EVP_PKEY_get0(const EVP_PKEY *pkey)
328 {
329 return pkey->pkey.ptr;
330 }
331
332 const unsigned char *
EVP_PKEY_get0_hmac(const EVP_PKEY * pkey,size_t * len)333 EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len)
334 {
335 ASN1_OCTET_STRING *os;
336
337 if (pkey->type != EVP_PKEY_HMAC) {
338 EVPerror(EVP_R_EXPECTING_AN_HMAC_KEY);
339 return NULL;
340 }
341
342 os = EVP_PKEY_get0(pkey);
343 *len = os->length;
344
345 return os->data;
346 }
347
348 #ifndef OPENSSL_NO_RSA
349 RSA *
EVP_PKEY_get0_RSA(EVP_PKEY * pkey)350 EVP_PKEY_get0_RSA(EVP_PKEY *pkey)
351 {
352 if (pkey->type != EVP_PKEY_RSA) {
353 EVPerror(EVP_R_EXPECTING_AN_RSA_KEY);
354 return NULL;
355 }
356 return pkey->pkey.rsa;
357 }
358
359 RSA *
EVP_PKEY_get1_RSA(EVP_PKEY * pkey)360 EVP_PKEY_get1_RSA(EVP_PKEY *pkey)
361 {
362 if (pkey->type != EVP_PKEY_RSA) {
363 EVPerror(EVP_R_EXPECTING_AN_RSA_KEY);
364 return NULL;
365 }
366 RSA_up_ref(pkey->pkey.rsa);
367 return pkey->pkey.rsa;
368 }
369
370 int
EVP_PKEY_set1_RSA(EVP_PKEY * pkey,RSA * key)371 EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key)
372 {
373 int ret = EVP_PKEY_assign_RSA(pkey, key);
374 if (ret != 0)
375 RSA_up_ref(key);
376 return ret;
377 }
378 #endif
379
380 #ifndef OPENSSL_NO_DSA
381 DSA *
EVP_PKEY_get0_DSA(EVP_PKEY * pkey)382 EVP_PKEY_get0_DSA(EVP_PKEY *pkey)
383 {
384 if (pkey->type != EVP_PKEY_DSA) {
385 EVPerror(EVP_R_EXPECTING_A_DSA_KEY);
386 return NULL;
387 }
388 return pkey->pkey.dsa;
389 }
390
391 DSA *
EVP_PKEY_get1_DSA(EVP_PKEY * pkey)392 EVP_PKEY_get1_DSA(EVP_PKEY *pkey)
393 {
394 if (pkey->type != EVP_PKEY_DSA) {
395 EVPerror(EVP_R_EXPECTING_A_DSA_KEY);
396 return NULL;
397 }
398 DSA_up_ref(pkey->pkey.dsa);
399 return pkey->pkey.dsa;
400 }
401
402 int
EVP_PKEY_set1_DSA(EVP_PKEY * pkey,DSA * key)403 EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
404 {
405 int ret = EVP_PKEY_assign_DSA(pkey, key);
406 if (ret != 0)
407 DSA_up_ref(key);
408 return ret;
409 }
410 #endif
411
412 #ifndef OPENSSL_NO_EC
413 EC_KEY *
EVP_PKEY_get0_EC_KEY(EVP_PKEY * pkey)414 EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey)
415 {
416 if (pkey->type != EVP_PKEY_EC) {
417 EVPerror(EVP_R_EXPECTING_A_EC_KEY);
418 return NULL;
419 }
420 return pkey->pkey.ec;
421 }
422
423 EC_KEY *
EVP_PKEY_get1_EC_KEY(EVP_PKEY * pkey)424 EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey)
425 {
426 if (pkey->type != EVP_PKEY_EC) {
427 EVPerror(EVP_R_EXPECTING_A_EC_KEY);
428 return NULL;
429 }
430 EC_KEY_up_ref(pkey->pkey.ec);
431 return pkey->pkey.ec;
432 }
433
434 int
EVP_PKEY_set1_EC_KEY(EVP_PKEY * pkey,EC_KEY * key)435 EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key)
436 {
437 int ret = EVP_PKEY_assign_EC_KEY(pkey, key);
438 if (ret != 0)
439 EC_KEY_up_ref(key);
440 return ret;
441 }
442 #endif
443
444
445 #ifndef OPENSSL_NO_DH
446 DH *
EVP_PKEY_get0_DH(EVP_PKEY * pkey)447 EVP_PKEY_get0_DH(EVP_PKEY *pkey)
448 {
449 if (pkey->type != EVP_PKEY_DH) {
450 EVPerror(EVP_R_EXPECTING_A_DH_KEY);
451 return NULL;
452 }
453 return pkey->pkey.dh;
454 }
455
456 DH *
EVP_PKEY_get1_DH(EVP_PKEY * pkey)457 EVP_PKEY_get1_DH(EVP_PKEY *pkey)
458 {
459 if (pkey->type != EVP_PKEY_DH) {
460 EVPerror(EVP_R_EXPECTING_A_DH_KEY);
461 return NULL;
462 }
463 DH_up_ref(pkey->pkey.dh);
464 return pkey->pkey.dh;
465 }
466
467 int
EVP_PKEY_set1_DH(EVP_PKEY * pkey,DH * key)468 EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key)
469 {
470 int ret = EVP_PKEY_assign_DH(pkey, key);
471 if (ret != 0)
472 DH_up_ref(key);
473 return ret;
474 }
475 #endif
476
477 int
EVP_PKEY_type(int type)478 EVP_PKEY_type(int type)
479 {
480 int ret;
481 const EVP_PKEY_ASN1_METHOD *ameth;
482 ENGINE *e;
483 ameth = EVP_PKEY_asn1_find(&e, type);
484 if (ameth)
485 ret = ameth->pkey_id;
486 else
487 ret = NID_undef;
488 #ifndef OPENSSL_NO_ENGINE
489 ENGINE_finish(e);
490 #endif
491 return ret;
492 }
493
494 int
EVP_PKEY_id(const EVP_PKEY * pkey)495 EVP_PKEY_id(const EVP_PKEY *pkey)
496 {
497 return pkey->type;
498 }
499
500 int
EVP_PKEY_base_id(const EVP_PKEY * pkey)501 EVP_PKEY_base_id(const EVP_PKEY *pkey)
502 {
503 return EVP_PKEY_type(pkey->type);
504 }
505
506 void
EVP_PKEY_free(EVP_PKEY * x)507 EVP_PKEY_free(EVP_PKEY *x)
508 {
509 int i;
510
511 if (x == NULL)
512 return;
513
514 i = CRYPTO_add(&x->references, -1, CRYPTO_LOCK_EVP_PKEY);
515 if (i > 0)
516 return;
517
518 EVP_PKEY_free_it(x);
519 if (x->attributes)
520 sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);
521 free(x);
522 }
523
524 static void
EVP_PKEY_free_it(EVP_PKEY * x)525 EVP_PKEY_free_it(EVP_PKEY *x)
526 {
527 if (x->ameth && x->ameth->pkey_free) {
528 x->ameth->pkey_free(x);
529 x->pkey.ptr = NULL;
530 }
531 #ifndef OPENSSL_NO_ENGINE
532 ENGINE_finish(x->engine);
533 x->engine = NULL;
534 #endif
535 }
536
537 static int
unsup_alg(BIO * out,const EVP_PKEY * pkey,int indent,const char * kstr)538 unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent, const char *kstr)
539 {
540 if (!BIO_indent(out, indent, 128))
541 return 0;
542 BIO_printf(out, "%s algorithm \"%s\" unsupported\n",
543 kstr, OBJ_nid2ln(pkey->type));
544 return 1;
545 }
546
547 int
EVP_PKEY_print_public(BIO * out,const EVP_PKEY * pkey,int indent,ASN1_PCTX * pctx)548 EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent,
549 ASN1_PCTX *pctx)
550 {
551 if (pkey->ameth && pkey->ameth->pub_print)
552 return pkey->ameth->pub_print(out, pkey, indent, pctx);
553
554 return unsup_alg(out, pkey, indent, "Public Key");
555 }
556
557 int
EVP_PKEY_print_private(BIO * out,const EVP_PKEY * pkey,int indent,ASN1_PCTX * pctx)558 EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent,
559 ASN1_PCTX *pctx)
560 {
561 if (pkey->ameth && pkey->ameth->priv_print)
562 return pkey->ameth->priv_print(out, pkey, indent, pctx);
563
564 return unsup_alg(out, pkey, indent, "Private Key");
565 }
566
567 int
EVP_PKEY_print_params(BIO * out,const EVP_PKEY * pkey,int indent,ASN1_PCTX * pctx)568 EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent,
569 ASN1_PCTX *pctx)
570 {
571 if (pkey->ameth && pkey->ameth->param_print)
572 return pkey->ameth->param_print(out, pkey, indent, pctx);
573 return unsup_alg(out, pkey, indent, "Parameters");
574 }
575
576 int
EVP_PKEY_get_default_digest_nid(EVP_PKEY * pkey,int * pnid)577 EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid)
578 {
579 if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
580 return -2;
581 return pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID,
582 0, pnid);
583 }
584
585