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