xref: /dragonfly/crypto/libressl/crypto/evp/p_lib.c (revision de0e0e4d)
1*de0e0e4dSAntonio Huete Jimenez /* $OpenBSD: p_lib.c,v 1.29 2022/06/27 12:36:05 tb Exp $ */
2f5b1c8a1SJohn Marino /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3f5b1c8a1SJohn Marino  * All rights reserved.
4f5b1c8a1SJohn Marino  *
5f5b1c8a1SJohn Marino  * This package is an SSL implementation written
6f5b1c8a1SJohn Marino  * by Eric Young (eay@cryptsoft.com).
7f5b1c8a1SJohn Marino  * The implementation was written so as to conform with Netscapes SSL.
8f5b1c8a1SJohn Marino  *
9f5b1c8a1SJohn Marino  * This library is free for commercial and non-commercial use as long as
10f5b1c8a1SJohn Marino  * the following conditions are aheared to.  The following conditions
11f5b1c8a1SJohn Marino  * apply to all code found in this distribution, be it the RC4, RSA,
12f5b1c8a1SJohn Marino  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13f5b1c8a1SJohn Marino  * included with this distribution is covered by the same copyright terms
14f5b1c8a1SJohn Marino  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15f5b1c8a1SJohn Marino  *
16f5b1c8a1SJohn Marino  * Copyright remains Eric Young's, and as such any Copyright notices in
17f5b1c8a1SJohn Marino  * the code are not to be removed.
18f5b1c8a1SJohn Marino  * If this package is used in a product, Eric Young should be given attribution
19f5b1c8a1SJohn Marino  * as the author of the parts of the library used.
20f5b1c8a1SJohn Marino  * This can be in the form of a textual message at program startup or
21f5b1c8a1SJohn Marino  * in documentation (online or textual) provided with the package.
22f5b1c8a1SJohn Marino  *
23f5b1c8a1SJohn Marino  * Redistribution and use in source and binary forms, with or without
24f5b1c8a1SJohn Marino  * modification, are permitted provided that the following conditions
25f5b1c8a1SJohn Marino  * are met:
26f5b1c8a1SJohn Marino  * 1. Redistributions of source code must retain the copyright
27f5b1c8a1SJohn Marino  *    notice, this list of conditions and the following disclaimer.
28f5b1c8a1SJohn Marino  * 2. Redistributions in binary form must reproduce the above copyright
29f5b1c8a1SJohn Marino  *    notice, this list of conditions and the following disclaimer in the
30f5b1c8a1SJohn Marino  *    documentation and/or other materials provided with the distribution.
31f5b1c8a1SJohn Marino  * 3. All advertising materials mentioning features or use of this software
32f5b1c8a1SJohn Marino  *    must display the following acknowledgement:
33f5b1c8a1SJohn Marino  *    "This product includes cryptographic software written by
34f5b1c8a1SJohn Marino  *     Eric Young (eay@cryptsoft.com)"
35f5b1c8a1SJohn Marino  *    The word 'cryptographic' can be left out if the rouines from the library
36f5b1c8a1SJohn Marino  *    being used are not cryptographic related :-).
37f5b1c8a1SJohn Marino  * 4. If you include any Windows specific code (or a derivative thereof) from
38f5b1c8a1SJohn Marino  *    the apps directory (application code) you must include an acknowledgement:
39f5b1c8a1SJohn Marino  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40f5b1c8a1SJohn Marino  *
41f5b1c8a1SJohn Marino  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42f5b1c8a1SJohn Marino  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43f5b1c8a1SJohn Marino  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44f5b1c8a1SJohn Marino  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45f5b1c8a1SJohn Marino  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46f5b1c8a1SJohn Marino  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47f5b1c8a1SJohn Marino  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48f5b1c8a1SJohn Marino  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49f5b1c8a1SJohn Marino  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50f5b1c8a1SJohn Marino  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51f5b1c8a1SJohn Marino  * SUCH DAMAGE.
52f5b1c8a1SJohn Marino  *
53f5b1c8a1SJohn Marino  * The licence and distribution terms for any publically available version or
54f5b1c8a1SJohn Marino  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55f5b1c8a1SJohn Marino  * copied and put under another distribution licence
56f5b1c8a1SJohn Marino  * [including the GNU Public Licence.]
57f5b1c8a1SJohn Marino  */
58f5b1c8a1SJohn Marino 
59f5b1c8a1SJohn Marino #include <stdio.h>
60f5b1c8a1SJohn Marino 
61f5b1c8a1SJohn Marino #include <openssl/opensslconf.h>
62f5b1c8a1SJohn Marino 
63f5b1c8a1SJohn Marino #include <openssl/bn.h>
64*de0e0e4dSAntonio Huete Jimenez #include <openssl/cmac.h>
65f5b1c8a1SJohn Marino #include <openssl/err.h>
66f5b1c8a1SJohn Marino #include <openssl/evp.h>
67f5b1c8a1SJohn Marino #include <openssl/objects.h>
68f5b1c8a1SJohn Marino #include <openssl/x509.h>
69f5b1c8a1SJohn Marino 
70f5b1c8a1SJohn Marino #ifndef OPENSSL_NO_DH
71f5b1c8a1SJohn Marino #include <openssl/dh.h>
72f5b1c8a1SJohn Marino #endif
73f5b1c8a1SJohn Marino #ifndef OPENSSL_NO_DSA
74f5b1c8a1SJohn Marino #include <openssl/dsa.h>
75f5b1c8a1SJohn Marino #endif
76f5b1c8a1SJohn Marino #ifndef OPENSSL_NO_RSA
77f5b1c8a1SJohn Marino #include <openssl/rsa.h>
78f5b1c8a1SJohn Marino #endif
79f5b1c8a1SJohn Marino 
80f5b1c8a1SJohn Marino #ifndef OPENSSL_NO_ENGINE
81f5b1c8a1SJohn Marino #include <openssl/engine.h>
82f5b1c8a1SJohn Marino #endif
83f5b1c8a1SJohn Marino 
84f5b1c8a1SJohn Marino #include "asn1_locl.h"
85*de0e0e4dSAntonio Huete Jimenez #include "evp_locl.h"
86f5b1c8a1SJohn Marino 
87f5b1c8a1SJohn Marino static void EVP_PKEY_free_it(EVP_PKEY *x);
88f5b1c8a1SJohn Marino 
89f5b1c8a1SJohn Marino int
EVP_PKEY_bits(const EVP_PKEY * pkey)9072c33676SMaxim Ag EVP_PKEY_bits(const EVP_PKEY *pkey)
91f5b1c8a1SJohn Marino {
92f5b1c8a1SJohn Marino 	if (pkey && pkey->ameth && pkey->ameth->pkey_bits)
93f5b1c8a1SJohn Marino 		return pkey->ameth->pkey_bits(pkey);
94f5b1c8a1SJohn Marino 	return 0;
95f5b1c8a1SJohn Marino }
96f5b1c8a1SJohn Marino 
97f5b1c8a1SJohn Marino int
EVP_PKEY_security_bits(const EVP_PKEY * pkey)98*de0e0e4dSAntonio Huete Jimenez EVP_PKEY_security_bits(const EVP_PKEY *pkey)
99*de0e0e4dSAntonio Huete Jimenez {
100*de0e0e4dSAntonio Huete Jimenez 	if (pkey == NULL)
101*de0e0e4dSAntonio Huete Jimenez 		return 0;
102*de0e0e4dSAntonio Huete Jimenez 	if (pkey->ameth == NULL || pkey->ameth->pkey_security_bits == NULL)
103*de0e0e4dSAntonio Huete Jimenez 		return -2;
104*de0e0e4dSAntonio Huete Jimenez 
105*de0e0e4dSAntonio Huete Jimenez 	return pkey->ameth->pkey_security_bits(pkey);
106*de0e0e4dSAntonio Huete Jimenez }
107*de0e0e4dSAntonio Huete Jimenez 
108*de0e0e4dSAntonio Huete Jimenez int
EVP_PKEY_size(const EVP_PKEY * pkey)10972c33676SMaxim Ag EVP_PKEY_size(const EVP_PKEY *pkey)
110f5b1c8a1SJohn Marino {
111f5b1c8a1SJohn Marino 	if (pkey && pkey->ameth && pkey->ameth->pkey_size)
112f5b1c8a1SJohn Marino 		return pkey->ameth->pkey_size(pkey);
113f5b1c8a1SJohn Marino 	return 0;
114f5b1c8a1SJohn Marino }
115f5b1c8a1SJohn Marino 
116f5b1c8a1SJohn Marino int
EVP_PKEY_save_parameters(EVP_PKEY * pkey,int mode)117f5b1c8a1SJohn Marino EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode)
118f5b1c8a1SJohn Marino {
119f5b1c8a1SJohn Marino #ifndef OPENSSL_NO_DSA
120f5b1c8a1SJohn Marino 	if (pkey->type == EVP_PKEY_DSA) {
121f5b1c8a1SJohn Marino 		int ret = pkey->save_parameters;
122f5b1c8a1SJohn Marino 
123f5b1c8a1SJohn Marino 		if (mode >= 0)
124f5b1c8a1SJohn Marino 			pkey->save_parameters = mode;
125f5b1c8a1SJohn Marino 		return (ret);
126f5b1c8a1SJohn Marino 	}
127f5b1c8a1SJohn Marino #endif
128f5b1c8a1SJohn Marino #ifndef OPENSSL_NO_EC
129f5b1c8a1SJohn Marino 	if (pkey->type == EVP_PKEY_EC) {
130f5b1c8a1SJohn Marino 		int ret = pkey->save_parameters;
131f5b1c8a1SJohn Marino 
132f5b1c8a1SJohn Marino 		if (mode >= 0)
133f5b1c8a1SJohn Marino 			pkey->save_parameters = mode;
134f5b1c8a1SJohn Marino 		return (ret);
135f5b1c8a1SJohn Marino 	}
136f5b1c8a1SJohn Marino #endif
137f5b1c8a1SJohn Marino 	return (0);
138f5b1c8a1SJohn Marino }
139f5b1c8a1SJohn Marino 
140f5b1c8a1SJohn Marino int
EVP_PKEY_copy_parameters(EVP_PKEY * to,const EVP_PKEY * from)141f5b1c8a1SJohn Marino EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
142f5b1c8a1SJohn Marino {
143f5b1c8a1SJohn Marino 	if (to->type != from->type) {
14472c33676SMaxim Ag 		EVPerror(EVP_R_DIFFERENT_KEY_TYPES);
145f5b1c8a1SJohn Marino 		goto err;
146f5b1c8a1SJohn Marino 	}
147f5b1c8a1SJohn Marino 
148f5b1c8a1SJohn Marino 	if (EVP_PKEY_missing_parameters(from)) {
14972c33676SMaxim Ag 		EVPerror(EVP_R_MISSING_PARAMETERS);
150f5b1c8a1SJohn Marino 		goto err;
151f5b1c8a1SJohn Marino 	}
152f5b1c8a1SJohn Marino 	if (from->ameth && from->ameth->param_copy)
153f5b1c8a1SJohn Marino 		return from->ameth->param_copy(to, from);
154f5b1c8a1SJohn Marino 
155f5b1c8a1SJohn Marino err:
156f5b1c8a1SJohn Marino 	return 0;
157f5b1c8a1SJohn Marino }
158f5b1c8a1SJohn Marino 
159f5b1c8a1SJohn Marino int
EVP_PKEY_missing_parameters(const EVP_PKEY * pkey)160f5b1c8a1SJohn Marino EVP_PKEY_missing_parameters(const EVP_PKEY *pkey)
161f5b1c8a1SJohn Marino {
162f5b1c8a1SJohn Marino 	if (pkey->ameth && pkey->ameth->param_missing)
163f5b1c8a1SJohn Marino 		return pkey->ameth->param_missing(pkey);
164f5b1c8a1SJohn Marino 	return 0;
165f5b1c8a1SJohn Marino }
166f5b1c8a1SJohn Marino 
167f5b1c8a1SJohn Marino int
EVP_PKEY_cmp_parameters(const EVP_PKEY * a,const EVP_PKEY * b)168f5b1c8a1SJohn Marino EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
169f5b1c8a1SJohn Marino {
170f5b1c8a1SJohn Marino 	if (a->type != b->type)
171f5b1c8a1SJohn Marino 		return -1;
172f5b1c8a1SJohn Marino 	if (a->ameth && a->ameth->param_cmp)
173f5b1c8a1SJohn Marino 		return a->ameth->param_cmp(a, b);
174f5b1c8a1SJohn Marino 	return -2;
175f5b1c8a1SJohn Marino }
176f5b1c8a1SJohn Marino 
177f5b1c8a1SJohn Marino int
EVP_PKEY_cmp(const EVP_PKEY * a,const EVP_PKEY * b)178f5b1c8a1SJohn Marino EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
179f5b1c8a1SJohn Marino {
180f5b1c8a1SJohn Marino 	if (a->type != b->type)
181f5b1c8a1SJohn Marino 		return -1;
182f5b1c8a1SJohn Marino 
183f5b1c8a1SJohn Marino 	if (a->ameth) {
184f5b1c8a1SJohn Marino 		int ret;
185f5b1c8a1SJohn Marino 		/* Compare parameters if the algorithm has them */
186f5b1c8a1SJohn Marino 		if (a->ameth->param_cmp) {
187f5b1c8a1SJohn Marino 			ret = a->ameth->param_cmp(a, b);
188f5b1c8a1SJohn Marino 			if (ret <= 0)
189f5b1c8a1SJohn Marino 				return ret;
190f5b1c8a1SJohn Marino 		}
191f5b1c8a1SJohn Marino 
192f5b1c8a1SJohn Marino 		if (a->ameth->pub_cmp)
193f5b1c8a1SJohn Marino 			return a->ameth->pub_cmp(a, b);
194f5b1c8a1SJohn Marino 	}
195f5b1c8a1SJohn Marino 
196f5b1c8a1SJohn Marino 	return -2;
197f5b1c8a1SJohn Marino }
198f5b1c8a1SJohn Marino 
199f5b1c8a1SJohn Marino EVP_PKEY *
EVP_PKEY_new(void)200f5b1c8a1SJohn Marino EVP_PKEY_new(void)
201f5b1c8a1SJohn Marino {
202f5b1c8a1SJohn Marino 	EVP_PKEY *ret;
203f5b1c8a1SJohn Marino 
204f5b1c8a1SJohn Marino 	ret = malloc(sizeof(EVP_PKEY));
205f5b1c8a1SJohn Marino 	if (ret == NULL) {
20672c33676SMaxim Ag 		EVPerror(ERR_R_MALLOC_FAILURE);
207f5b1c8a1SJohn Marino 		return (NULL);
208f5b1c8a1SJohn Marino 	}
209f5b1c8a1SJohn Marino 	ret->type = EVP_PKEY_NONE;
210f5b1c8a1SJohn Marino 	ret->save_type = EVP_PKEY_NONE;
211f5b1c8a1SJohn Marino 	ret->references = 1;
212f5b1c8a1SJohn Marino 	ret->ameth = NULL;
213f5b1c8a1SJohn Marino 	ret->engine = NULL;
214f5b1c8a1SJohn Marino 	ret->pkey.ptr = NULL;
215f5b1c8a1SJohn Marino 	ret->attributes = NULL;
216f5b1c8a1SJohn Marino 	ret->save_parameters = 1;
217f5b1c8a1SJohn Marino 	return (ret);
218f5b1c8a1SJohn Marino }
219f5b1c8a1SJohn Marino 
22072c33676SMaxim Ag int
EVP_PKEY_up_ref(EVP_PKEY * pkey)22172c33676SMaxim Ag EVP_PKEY_up_ref(EVP_PKEY *pkey)
22272c33676SMaxim Ag {
22372c33676SMaxim Ag 	int refs = CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
22472c33676SMaxim Ag 	return ((refs > 1) ? 1 : 0);
22572c33676SMaxim Ag }
22672c33676SMaxim Ag 
227f5b1c8a1SJohn Marino /* Setup a public key ASN1 method and ENGINE from a NID or a string.
228f5b1c8a1SJohn Marino  * If pkey is NULL just return 1 or 0 if the algorithm exists.
229f5b1c8a1SJohn Marino  */
230f5b1c8a1SJohn Marino 
231f5b1c8a1SJohn Marino static int
pkey_set_type(EVP_PKEY * pkey,ENGINE * e,int type,const char * str,int len)232*de0e0e4dSAntonio Huete Jimenez pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str, int len)
233f5b1c8a1SJohn Marino {
234f5b1c8a1SJohn Marino 	const EVP_PKEY_ASN1_METHOD *ameth;
235*de0e0e4dSAntonio Huete Jimenez 	ENGINE **eptr = NULL;
236*de0e0e4dSAntonio Huete Jimenez 
237*de0e0e4dSAntonio Huete Jimenez 	if (e == NULL)
238*de0e0e4dSAntonio Huete Jimenez 		eptr = &e;
239*de0e0e4dSAntonio Huete Jimenez 
240f5b1c8a1SJohn Marino 	if (pkey) {
241f5b1c8a1SJohn Marino 		if (pkey->pkey.ptr)
242f5b1c8a1SJohn Marino 			EVP_PKEY_free_it(pkey);
243f5b1c8a1SJohn Marino 		/* If key type matches and a method exists then this
244f5b1c8a1SJohn Marino 		 * lookup has succeeded once so just indicate success.
245f5b1c8a1SJohn Marino 		 */
246f5b1c8a1SJohn Marino 		if ((type == pkey->save_type) && pkey->ameth)
247f5b1c8a1SJohn Marino 			return 1;
248f5b1c8a1SJohn Marino #ifndef OPENSSL_NO_ENGINE
249f5b1c8a1SJohn Marino 		ENGINE_finish(pkey->engine);
250f5b1c8a1SJohn Marino 		pkey->engine = NULL;
251f5b1c8a1SJohn Marino #endif
252f5b1c8a1SJohn Marino 	}
253f5b1c8a1SJohn Marino 	if (str)
254*de0e0e4dSAntonio Huete Jimenez 		ameth = EVP_PKEY_asn1_find_str(eptr, str, len);
255f5b1c8a1SJohn Marino 	else
256*de0e0e4dSAntonio Huete Jimenez 		ameth = EVP_PKEY_asn1_find(eptr, type);
257f5b1c8a1SJohn Marino #ifndef OPENSSL_NO_ENGINE
258*de0e0e4dSAntonio Huete Jimenez 	if (pkey == NULL && eptr != NULL)
259f5b1c8a1SJohn Marino 		ENGINE_finish(e);
260f5b1c8a1SJohn Marino #endif
261f5b1c8a1SJohn Marino 	if (!ameth) {
26272c33676SMaxim Ag 		EVPerror(EVP_R_UNSUPPORTED_ALGORITHM);
263f5b1c8a1SJohn Marino 		return 0;
264f5b1c8a1SJohn Marino 	}
265f5b1c8a1SJohn Marino 	if (pkey) {
266f5b1c8a1SJohn Marino 		pkey->ameth = ameth;
267f5b1c8a1SJohn Marino 		pkey->engine = e;
268f5b1c8a1SJohn Marino 
269f5b1c8a1SJohn Marino 		pkey->type = pkey->ameth->pkey_id;
270f5b1c8a1SJohn Marino 		pkey->save_type = type;
271f5b1c8a1SJohn Marino 	}
272f5b1c8a1SJohn Marino 	return 1;
273f5b1c8a1SJohn Marino }
274f5b1c8a1SJohn Marino 
275f5b1c8a1SJohn Marino int
EVP_PKEY_set_type(EVP_PKEY * pkey,int type)276f5b1c8a1SJohn Marino EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
277f5b1c8a1SJohn Marino {
278*de0e0e4dSAntonio Huete Jimenez 	return pkey_set_type(pkey, NULL, type, NULL, -1);
279*de0e0e4dSAntonio Huete Jimenez }
280*de0e0e4dSAntonio Huete Jimenez 
281*de0e0e4dSAntonio Huete Jimenez EVP_PKEY *
EVP_PKEY_new_CMAC_key(ENGINE * e,const unsigned char * priv,size_t len,const EVP_CIPHER * cipher)282*de0e0e4dSAntonio Huete Jimenez EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv, size_t len,
283*de0e0e4dSAntonio Huete Jimenez     const EVP_CIPHER *cipher)
284*de0e0e4dSAntonio Huete Jimenez {
285*de0e0e4dSAntonio Huete Jimenez 	EVP_PKEY *ret = NULL;
286*de0e0e4dSAntonio Huete Jimenez 	CMAC_CTX *cmctx = NULL;
287*de0e0e4dSAntonio Huete Jimenez 
288*de0e0e4dSAntonio Huete Jimenez 	if ((ret = EVP_PKEY_new()) == NULL)
289*de0e0e4dSAntonio Huete Jimenez 		goto err;
290*de0e0e4dSAntonio Huete Jimenez 	if ((cmctx = CMAC_CTX_new()) == NULL)
291*de0e0e4dSAntonio Huete Jimenez 		goto err;
292*de0e0e4dSAntonio Huete Jimenez 
293*de0e0e4dSAntonio Huete Jimenez 	if (!pkey_set_type(ret, e, EVP_PKEY_CMAC, NULL, -1))
294*de0e0e4dSAntonio Huete Jimenez 		goto err;
295*de0e0e4dSAntonio Huete Jimenez 
296*de0e0e4dSAntonio Huete Jimenez 	if (!CMAC_Init(cmctx, priv, len, cipher, e)) {
297*de0e0e4dSAntonio Huete Jimenez 		EVPerror(EVP_R_KEY_SETUP_FAILED);
298*de0e0e4dSAntonio Huete Jimenez 		goto err;
299*de0e0e4dSAntonio Huete Jimenez 	}
300*de0e0e4dSAntonio Huete Jimenez 
301*de0e0e4dSAntonio Huete Jimenez 	ret->pkey.ptr = (char *)cmctx;
302*de0e0e4dSAntonio Huete Jimenez 
303*de0e0e4dSAntonio Huete Jimenez 	return ret;
304*de0e0e4dSAntonio Huete Jimenez 
305*de0e0e4dSAntonio Huete Jimenez  err:
306*de0e0e4dSAntonio Huete Jimenez 	EVP_PKEY_free(ret);
307*de0e0e4dSAntonio Huete Jimenez 	CMAC_CTX_free(cmctx);
308*de0e0e4dSAntonio Huete Jimenez 	return NULL;
309f5b1c8a1SJohn Marino }
310f5b1c8a1SJohn Marino 
311f5b1c8a1SJohn Marino int
EVP_PKEY_set_type_str(EVP_PKEY * pkey,const char * str,int len)312f5b1c8a1SJohn Marino EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len)
313f5b1c8a1SJohn Marino {
314*de0e0e4dSAntonio Huete Jimenez 	return pkey_set_type(pkey, NULL, EVP_PKEY_NONE, str, len);
315f5b1c8a1SJohn Marino }
316f5b1c8a1SJohn Marino 
317f5b1c8a1SJohn Marino int
EVP_PKEY_assign(EVP_PKEY * pkey,int type,void * key)318f5b1c8a1SJohn Marino EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
319f5b1c8a1SJohn Marino {
320f5b1c8a1SJohn Marino 	if (!EVP_PKEY_set_type(pkey, type))
321f5b1c8a1SJohn Marino 		return 0;
322f5b1c8a1SJohn Marino 	pkey->pkey.ptr = key;
323f5b1c8a1SJohn Marino 	return (key != NULL);
324f5b1c8a1SJohn Marino }
325f5b1c8a1SJohn Marino 
326f5b1c8a1SJohn Marino void *
EVP_PKEY_get0(const EVP_PKEY * pkey)32772c33676SMaxim Ag EVP_PKEY_get0(const EVP_PKEY *pkey)
328f5b1c8a1SJohn Marino {
329f5b1c8a1SJohn Marino 	return pkey->pkey.ptr;
330f5b1c8a1SJohn Marino }
331f5b1c8a1SJohn Marino 
33272c33676SMaxim Ag const unsigned char *
EVP_PKEY_get0_hmac(const EVP_PKEY * pkey,size_t * len)33372c33676SMaxim Ag EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len)
334f5b1c8a1SJohn Marino {
33572c33676SMaxim Ag 	ASN1_OCTET_STRING *os;
33672c33676SMaxim Ag 
33772c33676SMaxim Ag 	if (pkey->type != EVP_PKEY_HMAC) {
33872c33676SMaxim Ag 		EVPerror(EVP_R_EXPECTING_AN_HMAC_KEY);
33972c33676SMaxim Ag 		return NULL;
34072c33676SMaxim Ag 	}
34172c33676SMaxim Ag 
34272c33676SMaxim Ag 	os = EVP_PKEY_get0(pkey);
34372c33676SMaxim Ag 	*len = os->length;
34472c33676SMaxim Ag 
34572c33676SMaxim Ag 	return os->data;
34672c33676SMaxim Ag }
34772c33676SMaxim Ag 
34872c33676SMaxim Ag #ifndef OPENSSL_NO_RSA
34972c33676SMaxim Ag RSA *
EVP_PKEY_get0_RSA(EVP_PKEY * pkey)35072c33676SMaxim Ag EVP_PKEY_get0_RSA(EVP_PKEY *pkey)
35172c33676SMaxim Ag {
35272c33676SMaxim Ag 	if (pkey->type != EVP_PKEY_RSA) {
35372c33676SMaxim Ag 		EVPerror(EVP_R_EXPECTING_AN_RSA_KEY);
35472c33676SMaxim Ag 		return NULL;
35572c33676SMaxim Ag 	}
35672c33676SMaxim Ag 	return pkey->pkey.rsa;
357f5b1c8a1SJohn Marino }
358f5b1c8a1SJohn Marino 
359f5b1c8a1SJohn Marino RSA *
EVP_PKEY_get1_RSA(EVP_PKEY * pkey)360f5b1c8a1SJohn Marino EVP_PKEY_get1_RSA(EVP_PKEY *pkey)
361f5b1c8a1SJohn Marino {
362f5b1c8a1SJohn Marino 	if (pkey->type != EVP_PKEY_RSA) {
36372c33676SMaxim Ag 		EVPerror(EVP_R_EXPECTING_AN_RSA_KEY);
364f5b1c8a1SJohn Marino 		return NULL;
365f5b1c8a1SJohn Marino 	}
366f5b1c8a1SJohn Marino 	RSA_up_ref(pkey->pkey.rsa);
367f5b1c8a1SJohn Marino 	return pkey->pkey.rsa;
368f5b1c8a1SJohn Marino }
36972c33676SMaxim Ag 
37072c33676SMaxim Ag int
EVP_PKEY_set1_RSA(EVP_PKEY * pkey,RSA * key)37172c33676SMaxim Ag EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key)
37272c33676SMaxim Ag {
37372c33676SMaxim Ag 	int ret = EVP_PKEY_assign_RSA(pkey, key);
37472c33676SMaxim Ag 	if (ret != 0)
37572c33676SMaxim Ag 		RSA_up_ref(key);
37672c33676SMaxim Ag 	return ret;
37772c33676SMaxim Ag }
378f5b1c8a1SJohn Marino #endif
379f5b1c8a1SJohn Marino 
380f5b1c8a1SJohn Marino #ifndef OPENSSL_NO_DSA
38172c33676SMaxim Ag DSA *
EVP_PKEY_get0_DSA(EVP_PKEY * pkey)38272c33676SMaxim Ag EVP_PKEY_get0_DSA(EVP_PKEY *pkey)
383f5b1c8a1SJohn Marino {
38472c33676SMaxim Ag 	if (pkey->type != EVP_PKEY_DSA) {
38572c33676SMaxim Ag 		EVPerror(EVP_R_EXPECTING_A_DSA_KEY);
38672c33676SMaxim Ag 		return NULL;
38772c33676SMaxim Ag 	}
38872c33676SMaxim Ag 	return pkey->pkey.dsa;
389f5b1c8a1SJohn Marino }
390f5b1c8a1SJohn Marino 
391f5b1c8a1SJohn Marino DSA *
EVP_PKEY_get1_DSA(EVP_PKEY * pkey)392f5b1c8a1SJohn Marino EVP_PKEY_get1_DSA(EVP_PKEY *pkey)
393f5b1c8a1SJohn Marino {
394f5b1c8a1SJohn Marino 	if (pkey->type != EVP_PKEY_DSA) {
39572c33676SMaxim Ag 		EVPerror(EVP_R_EXPECTING_A_DSA_KEY);
396f5b1c8a1SJohn Marino 		return NULL;
397f5b1c8a1SJohn Marino 	}
398f5b1c8a1SJohn Marino 	DSA_up_ref(pkey->pkey.dsa);
399f5b1c8a1SJohn Marino 	return pkey->pkey.dsa;
400f5b1c8a1SJohn Marino }
40172c33676SMaxim Ag 
40272c33676SMaxim Ag int
EVP_PKEY_set1_DSA(EVP_PKEY * pkey,DSA * key)40372c33676SMaxim Ag EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
40472c33676SMaxim Ag {
40572c33676SMaxim Ag 	int ret = EVP_PKEY_assign_DSA(pkey, key);
40672c33676SMaxim Ag 	if (ret != 0)
40772c33676SMaxim Ag 		DSA_up_ref(key);
40872c33676SMaxim Ag 	return ret;
40972c33676SMaxim Ag }
410f5b1c8a1SJohn Marino #endif
411f5b1c8a1SJohn Marino 
412f5b1c8a1SJohn Marino #ifndef OPENSSL_NO_EC
41372c33676SMaxim Ag EC_KEY *
EVP_PKEY_get0_EC_KEY(EVP_PKEY * pkey)41472c33676SMaxim Ag EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey)
415f5b1c8a1SJohn Marino {
41672c33676SMaxim Ag 	if (pkey->type != EVP_PKEY_EC) {
41772c33676SMaxim Ag 		EVPerror(EVP_R_EXPECTING_A_EC_KEY);
41872c33676SMaxim Ag 		return NULL;
41972c33676SMaxim Ag 	}
42072c33676SMaxim Ag 	return pkey->pkey.ec;
421f5b1c8a1SJohn Marino }
422f5b1c8a1SJohn Marino 
423f5b1c8a1SJohn Marino EC_KEY *
EVP_PKEY_get1_EC_KEY(EVP_PKEY * pkey)424f5b1c8a1SJohn Marino EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey)
425f5b1c8a1SJohn Marino {
426f5b1c8a1SJohn Marino 	if (pkey->type != EVP_PKEY_EC) {
42772c33676SMaxim Ag 		EVPerror(EVP_R_EXPECTING_A_EC_KEY);
428f5b1c8a1SJohn Marino 		return NULL;
429f5b1c8a1SJohn Marino 	}
430f5b1c8a1SJohn Marino 	EC_KEY_up_ref(pkey->pkey.ec);
431f5b1c8a1SJohn Marino 	return pkey->pkey.ec;
432f5b1c8a1SJohn Marino }
43372c33676SMaxim Ag 
43472c33676SMaxim Ag int
EVP_PKEY_set1_EC_KEY(EVP_PKEY * pkey,EC_KEY * key)43572c33676SMaxim Ag EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key)
43672c33676SMaxim Ag {
43772c33676SMaxim Ag 	int ret = EVP_PKEY_assign_EC_KEY(pkey, key);
43872c33676SMaxim Ag 	if (ret != 0)
43972c33676SMaxim Ag 		EC_KEY_up_ref(key);
44072c33676SMaxim Ag 	return ret;
44172c33676SMaxim Ag }
442f5b1c8a1SJohn Marino #endif
443f5b1c8a1SJohn Marino 
444f5b1c8a1SJohn Marino 
445f5b1c8a1SJohn Marino #ifndef OPENSSL_NO_DH
44672c33676SMaxim Ag DH *
EVP_PKEY_get0_DH(EVP_PKEY * pkey)44772c33676SMaxim Ag EVP_PKEY_get0_DH(EVP_PKEY *pkey)
448f5b1c8a1SJohn Marino {
44972c33676SMaxim Ag 	if (pkey->type != EVP_PKEY_DH) {
45072c33676SMaxim Ag 		EVPerror(EVP_R_EXPECTING_A_DH_KEY);
45172c33676SMaxim Ag 		return NULL;
45272c33676SMaxim Ag 	}
45372c33676SMaxim Ag 	return pkey->pkey.dh;
454f5b1c8a1SJohn Marino }
455f5b1c8a1SJohn Marino 
456f5b1c8a1SJohn Marino DH *
EVP_PKEY_get1_DH(EVP_PKEY * pkey)457f5b1c8a1SJohn Marino EVP_PKEY_get1_DH(EVP_PKEY *pkey)
458f5b1c8a1SJohn Marino {
459f5b1c8a1SJohn Marino 	if (pkey->type != EVP_PKEY_DH) {
46072c33676SMaxim Ag 		EVPerror(EVP_R_EXPECTING_A_DH_KEY);
461f5b1c8a1SJohn Marino 		return NULL;
462f5b1c8a1SJohn Marino 	}
463f5b1c8a1SJohn Marino 	DH_up_ref(pkey->pkey.dh);
464f5b1c8a1SJohn Marino 	return pkey->pkey.dh;
465f5b1c8a1SJohn Marino }
46672c33676SMaxim Ag 
46772c33676SMaxim Ag int
EVP_PKEY_set1_DH(EVP_PKEY * pkey,DH * key)46872c33676SMaxim Ag EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key)
46972c33676SMaxim Ag {
47072c33676SMaxim Ag 	int ret = EVP_PKEY_assign_DH(pkey, key);
47172c33676SMaxim Ag 	if (ret != 0)
47272c33676SMaxim Ag 		DH_up_ref(key);
47372c33676SMaxim Ag 	return ret;
47472c33676SMaxim Ag }
475f5b1c8a1SJohn Marino #endif
476f5b1c8a1SJohn Marino 
477f5b1c8a1SJohn Marino int
EVP_PKEY_type(int type)478f5b1c8a1SJohn Marino EVP_PKEY_type(int type)
479f5b1c8a1SJohn Marino {
480f5b1c8a1SJohn Marino 	int ret;
481f5b1c8a1SJohn Marino 	const EVP_PKEY_ASN1_METHOD *ameth;
482f5b1c8a1SJohn Marino 	ENGINE *e;
483f5b1c8a1SJohn Marino 	ameth = EVP_PKEY_asn1_find(&e, type);
484f5b1c8a1SJohn Marino 	if (ameth)
485f5b1c8a1SJohn Marino 		ret = ameth->pkey_id;
486f5b1c8a1SJohn Marino 	else
487f5b1c8a1SJohn Marino 		ret = NID_undef;
488f5b1c8a1SJohn Marino #ifndef OPENSSL_NO_ENGINE
489f5b1c8a1SJohn Marino 	ENGINE_finish(e);
490f5b1c8a1SJohn Marino #endif
491f5b1c8a1SJohn Marino 	return ret;
492f5b1c8a1SJohn Marino }
493f5b1c8a1SJohn Marino 
494f5b1c8a1SJohn Marino int
EVP_PKEY_id(const EVP_PKEY * pkey)495f5b1c8a1SJohn Marino EVP_PKEY_id(const EVP_PKEY *pkey)
496f5b1c8a1SJohn Marino {
497f5b1c8a1SJohn Marino 	return pkey->type;
498f5b1c8a1SJohn Marino }
499f5b1c8a1SJohn Marino 
500f5b1c8a1SJohn Marino int
EVP_PKEY_base_id(const EVP_PKEY * pkey)501f5b1c8a1SJohn Marino EVP_PKEY_base_id(const EVP_PKEY *pkey)
502f5b1c8a1SJohn Marino {
503f5b1c8a1SJohn Marino 	return EVP_PKEY_type(pkey->type);
504f5b1c8a1SJohn Marino }
505f5b1c8a1SJohn Marino 
506f5b1c8a1SJohn Marino void
EVP_PKEY_free(EVP_PKEY * x)507f5b1c8a1SJohn Marino EVP_PKEY_free(EVP_PKEY *x)
508f5b1c8a1SJohn Marino {
509f5b1c8a1SJohn Marino 	int i;
510f5b1c8a1SJohn Marino 
511f5b1c8a1SJohn Marino 	if (x == NULL)
512f5b1c8a1SJohn Marino 		return;
513f5b1c8a1SJohn Marino 
514f5b1c8a1SJohn Marino 	i = CRYPTO_add(&x->references, -1, CRYPTO_LOCK_EVP_PKEY);
515f5b1c8a1SJohn Marino 	if (i > 0)
516f5b1c8a1SJohn Marino 		return;
517f5b1c8a1SJohn Marino 
518f5b1c8a1SJohn Marino 	EVP_PKEY_free_it(x);
519f5b1c8a1SJohn Marino 	if (x->attributes)
520f5b1c8a1SJohn Marino 		sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);
521f5b1c8a1SJohn Marino 	free(x);
522f5b1c8a1SJohn Marino }
523f5b1c8a1SJohn Marino 
524f5b1c8a1SJohn Marino static void
EVP_PKEY_free_it(EVP_PKEY * x)525f5b1c8a1SJohn Marino EVP_PKEY_free_it(EVP_PKEY *x)
526f5b1c8a1SJohn Marino {
527f5b1c8a1SJohn Marino 	if (x->ameth && x->ameth->pkey_free) {
528f5b1c8a1SJohn Marino 		x->ameth->pkey_free(x);
529f5b1c8a1SJohn Marino 		x->pkey.ptr = NULL;
530f5b1c8a1SJohn Marino 	}
531f5b1c8a1SJohn Marino #ifndef OPENSSL_NO_ENGINE
532f5b1c8a1SJohn Marino 	ENGINE_finish(x->engine);
533f5b1c8a1SJohn Marino 	x->engine = NULL;
534f5b1c8a1SJohn Marino #endif
535f5b1c8a1SJohn Marino }
536f5b1c8a1SJohn Marino 
537f5b1c8a1SJohn Marino static int
unsup_alg(BIO * out,const EVP_PKEY * pkey,int indent,const char * kstr)538f5b1c8a1SJohn Marino unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent, const char *kstr)
539f5b1c8a1SJohn Marino {
540*de0e0e4dSAntonio Huete Jimenez 	if (!BIO_indent(out, indent, 128))
541*de0e0e4dSAntonio Huete Jimenez 		return 0;
542f5b1c8a1SJohn Marino 	BIO_printf(out, "%s algorithm \"%s\" unsupported\n",
543f5b1c8a1SJohn Marino 	    kstr, OBJ_nid2ln(pkey->type));
544f5b1c8a1SJohn Marino 	return 1;
545f5b1c8a1SJohn Marino }
546f5b1c8a1SJohn Marino 
547f5b1c8a1SJohn Marino int
EVP_PKEY_print_public(BIO * out,const EVP_PKEY * pkey,int indent,ASN1_PCTX * pctx)548f5b1c8a1SJohn Marino EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent,
549f5b1c8a1SJohn Marino     ASN1_PCTX *pctx)
550f5b1c8a1SJohn Marino {
551f5b1c8a1SJohn Marino 	if (pkey->ameth && pkey->ameth->pub_print)
552f5b1c8a1SJohn Marino 		return pkey->ameth->pub_print(out, pkey, indent, pctx);
553f5b1c8a1SJohn Marino 
554f5b1c8a1SJohn Marino 	return unsup_alg(out, pkey, indent, "Public Key");
555f5b1c8a1SJohn Marino }
556f5b1c8a1SJohn Marino 
557f5b1c8a1SJohn Marino int
EVP_PKEY_print_private(BIO * out,const EVP_PKEY * pkey,int indent,ASN1_PCTX * pctx)558f5b1c8a1SJohn Marino EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent,
559f5b1c8a1SJohn Marino     ASN1_PCTX *pctx)
560f5b1c8a1SJohn Marino {
561f5b1c8a1SJohn Marino 	if (pkey->ameth && pkey->ameth->priv_print)
562f5b1c8a1SJohn Marino 		return pkey->ameth->priv_print(out, pkey, indent, pctx);
563f5b1c8a1SJohn Marino 
564f5b1c8a1SJohn Marino 	return unsup_alg(out, pkey, indent, "Private Key");
565f5b1c8a1SJohn Marino }
566f5b1c8a1SJohn Marino 
567f5b1c8a1SJohn Marino int
EVP_PKEY_print_params(BIO * out,const EVP_PKEY * pkey,int indent,ASN1_PCTX * pctx)568f5b1c8a1SJohn Marino EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent,
569f5b1c8a1SJohn Marino     ASN1_PCTX *pctx)
570f5b1c8a1SJohn Marino {
571f5b1c8a1SJohn Marino 	if (pkey->ameth && pkey->ameth->param_print)
572f5b1c8a1SJohn Marino 		return pkey->ameth->param_print(out, pkey, indent, pctx);
573f5b1c8a1SJohn Marino 	return unsup_alg(out, pkey, indent, "Parameters");
574f5b1c8a1SJohn Marino }
575f5b1c8a1SJohn Marino 
576f5b1c8a1SJohn Marino int
EVP_PKEY_get_default_digest_nid(EVP_PKEY * pkey,int * pnid)577f5b1c8a1SJohn Marino EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid)
578f5b1c8a1SJohn Marino {
579f5b1c8a1SJohn Marino 	if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
580f5b1c8a1SJohn Marino 		return -2;
581f5b1c8a1SJohn Marino 	return pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID,
582f5b1c8a1SJohn Marino 	    0, pnid);
583f5b1c8a1SJohn Marino }
584f5b1c8a1SJohn Marino 
585