155714Skris/* crypto/evp/p_lib.c */
255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
355714Skris * All rights reserved.
455714Skris *
555714Skris * This package is an SSL implementation written
655714Skris * by Eric Young (eay@cryptsoft.com).
755714Skris * The implementation was written so as to conform with Netscapes SSL.
855714Skris *
955714Skris * This library is free for commercial and non-commercial use as long as
1055714Skris * the following conditions are aheared to.  The following conditions
1155714Skris * apply to all code found in this distribution, be it the RC4, RSA,
1255714Skris * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1355714Skris * included with this distribution is covered by the same copyright terms
1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1555714Skris *
1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in
1755714Skris * the code are not to be removed.
1855714Skris * If this package is used in a product, Eric Young should be given attribution
1955714Skris * as the author of the parts of the library used.
2055714Skris * This can be in the form of a textual message at program startup or
2155714Skris * in documentation (online or textual) provided with the package.
2255714Skris *
2355714Skris * Redistribution and use in source and binary forms, with or without
2455714Skris * modification, are permitted provided that the following conditions
2555714Skris * are met:
2655714Skris * 1. Redistributions of source code must retain the copyright
2755714Skris *    notice, this list of conditions and the following disclaimer.
2855714Skris * 2. Redistributions in binary form must reproduce the above copyright
2955714Skris *    notice, this list of conditions and the following disclaimer in the
3055714Skris *    documentation and/or other materials provided with the distribution.
3155714Skris * 3. All advertising materials mentioning features or use of this software
3255714Skris *    must display the following acknowledgement:
3355714Skris *    "This product includes cryptographic software written by
3455714Skris *     Eric Young (eay@cryptsoft.com)"
3555714Skris *    The word 'cryptographic' can be left out if the rouines from the library
3655714Skris *    being used are not cryptographic related :-).
3755714Skris * 4. If you include any Windows specific code (or a derivative thereof) from
3855714Skris *    the apps directory (application code) you must include an acknowledgement:
3955714Skris *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
4055714Skris *
4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4455714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5155714Skris * SUCH DAMAGE.
5255714Skris *
5355714Skris * The licence and distribution terms for any publically available version or
5455714Skris * derivative of this code cannot be changed.  i.e. this code cannot simply be
5555714Skris * copied and put under another distribution licence
5655714Skris * [including the GNU Public Licence.]
5755714Skris */
5855714Skris
5955714Skris#include <stdio.h>
6055714Skris#include "cryptlib.h"
61160814Ssimon#include <openssl/bn.h>
62160814Ssimon#include <openssl/err.h>
6355714Skris#include <openssl/objects.h>
6455714Skris#include <openssl/evp.h>
6555714Skris#include <openssl/asn1_mac.h>
6655714Skris#include <openssl/x509.h>
67160814Ssimon#ifndef OPENSSL_NO_RSA
68160814Ssimon#include <openssl/rsa.h>
69160814Ssimon#endif
70160814Ssimon#ifndef OPENSSL_NO_DSA
71160814Ssimon#include <openssl/dsa.h>
72160814Ssimon#endif
73160814Ssimon#ifndef OPENSSL_NO_DH
74160814Ssimon#include <openssl/dh.h>
75160814Ssimon#endif
7655714Skris
77238405Sjkim#ifndef OPENSSL_NO_ENGINE
78238405Sjkim#include <openssl/engine.h>
79238405Sjkim#endif
80238405Sjkim
81238405Sjkim#include "asn1_locl.h"
82238405Sjkim
8355714Skrisstatic void EVP_PKEY_free_it(EVP_PKEY *x);
84109998Smarkm
8555714Skrisint EVP_PKEY_bits(EVP_PKEY *pkey)
8655714Skris	{
87238405Sjkim	if (pkey && pkey->ameth && pkey->ameth->pkey_bits)
88238405Sjkim		return pkey->ameth->pkey_bits(pkey);
89238405Sjkim	return 0;
9055714Skris	}
9155714Skris
9255714Skrisint EVP_PKEY_size(EVP_PKEY *pkey)
9355714Skris	{
94238405Sjkim	if (pkey && pkey->ameth && pkey->ameth->pkey_size)
95238405Sjkim		return pkey->ameth->pkey_size(pkey);
96238405Sjkim	return 0;
9755714Skris	}
9855714Skris
9955714Skrisint EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode)
10055714Skris	{
101109998Smarkm#ifndef OPENSSL_NO_DSA
10255714Skris	if (pkey->type == EVP_PKEY_DSA)
10355714Skris		{
104109998Smarkm		int ret=pkey->save_parameters;
10555714Skris
10655714Skris		if (mode >= 0)
10755714Skris			pkey->save_parameters=mode;
10855714Skris		return(ret);
10955714Skris		}
11055714Skris#endif
111160814Ssimon#ifndef OPENSSL_NO_EC
112160814Ssimon	if (pkey->type == EVP_PKEY_EC)
113160814Ssimon		{
114160814Ssimon		int ret = pkey->save_parameters;
115160814Ssimon
116160814Ssimon		if (mode >= 0)
117160814Ssimon			pkey->save_parameters = mode;
118160814Ssimon		return(ret);
119160814Ssimon		}
120160814Ssimon#endif
12155714Skris	return(0);
12255714Skris	}
12355714Skris
124160814Ssimonint EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
12555714Skris	{
12655714Skris	if (to->type != from->type)
12755714Skris		{
12855714Skris		EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS,EVP_R_DIFFERENT_KEY_TYPES);
12955714Skris		goto err;
13055714Skris		}
13155714Skris
13255714Skris	if (EVP_PKEY_missing_parameters(from))
13355714Skris		{
13459191Skris		EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS,EVP_R_MISSING_PARAMETERS);
13555714Skris		goto err;
13655714Skris		}
137238405Sjkim	if (from->ameth && from->ameth->param_copy)
138238405Sjkim		return from->ameth->param_copy(to, from);
13955714Skriserr:
140238405Sjkim	return 0;
14155714Skris	}
14255714Skris
143160814Ssimonint EVP_PKEY_missing_parameters(const EVP_PKEY *pkey)
14455714Skris	{
145238405Sjkim	if (pkey->ameth && pkey->ameth->param_missing)
146238405Sjkim		return pkey->ameth->param_missing(pkey);
147238405Sjkim	return 0;
14855714Skris	}
14955714Skris
150160814Ssimonint EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
15155714Skris	{
152238405Sjkim	if (a->type != b->type)
153238405Sjkim		return -1;
154238405Sjkim	if (a->ameth && a->ameth->param_cmp)
155238405Sjkim		return a->ameth->param_cmp(a, b);
156238405Sjkim	return -2;
15755714Skris	}
15855714Skris
159160814Ssimonint EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
160160814Ssimon	{
161160814Ssimon	if (a->type != b->type)
162160814Ssimon		return -1;
163160814Ssimon
164238405Sjkim	if (a->ameth)
165160814Ssimon		{
166238405Sjkim		int ret;
167238405Sjkim		/* Compare parameters if the algorithm has them */
168238405Sjkim		if (a->ameth->param_cmp)
169160814Ssimon			{
170238405Sjkim			ret = a->ameth->param_cmp(a, b);
171238405Sjkim			if (ret <= 0)
172238405Sjkim				return ret;
173160814Ssimon			}
174238405Sjkim
175238405Sjkim		if (a->ameth->pub_cmp)
176238405Sjkim			return a->ameth->pub_cmp(a, b);
177160814Ssimon		}
178160814Ssimon
179238405Sjkim	return -2;
180160814Ssimon	}
181160814Ssimon
18255714SkrisEVP_PKEY *EVP_PKEY_new(void)
18355714Skris	{
18455714Skris	EVP_PKEY *ret;
18555714Skris
18668651Skris	ret=(EVP_PKEY *)OPENSSL_malloc(sizeof(EVP_PKEY));
18755714Skris	if (ret == NULL)
18855714Skris		{
18955714Skris		EVPerr(EVP_F_EVP_PKEY_NEW,ERR_R_MALLOC_FAILURE);
19055714Skris		return(NULL);
19155714Skris		}
19255714Skris	ret->type=EVP_PKEY_NONE;
193238405Sjkim	ret->save_type=EVP_PKEY_NONE;
19455714Skris	ret->references=1;
195238405Sjkim	ret->ameth=NULL;
196238405Sjkim	ret->engine=NULL;
19755714Skris	ret->pkey.ptr=NULL;
19855714Skris	ret->attributes=NULL;
19955714Skris	ret->save_parameters=1;
20055714Skris	return(ret);
20155714Skris	}
20255714Skris
203238405Sjkim/* Setup a public key ASN1 method and ENGINE from a NID or a string.
204238405Sjkim * If pkey is NULL just return 1 or 0 if the algorithm exists.
205238405Sjkim */
206238405Sjkim
207238405Sjkimstatic int pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len)
20855714Skris	{
209238405Sjkim	const EVP_PKEY_ASN1_METHOD *ameth;
210238405Sjkim	ENGINE *e = NULL;
211238405Sjkim	if (pkey)
212238405Sjkim		{
213238405Sjkim		if (pkey->pkey.ptr)
214238405Sjkim			EVP_PKEY_free_it(pkey);
215238405Sjkim		/* If key type matches and a method exists then this
216238405Sjkim		 * lookup has succeeded once so just indicate success.
217238405Sjkim		 */
218238405Sjkim		if ((type == pkey->save_type) && pkey->ameth)
219238405Sjkim			return 1;
220238405Sjkim#ifndef OPENSSL_NO_ENGINE
221238405Sjkim		/* If we have an ENGINE release it */
222238405Sjkim		if (pkey->engine)
223238405Sjkim			{
224238405Sjkim			ENGINE_finish(pkey->engine);
225238405Sjkim			pkey->engine = NULL;
226238405Sjkim			}
227238405Sjkim#endif
228238405Sjkim		}
229238405Sjkim	if (str)
230238405Sjkim		ameth = EVP_PKEY_asn1_find_str(&e, str, len);
231238405Sjkim	else
232238405Sjkim		ameth = EVP_PKEY_asn1_find(&e, type);
233238405Sjkim#ifndef OPENSSL_NO_ENGINE
234238405Sjkim	if (!pkey && e)
235238405Sjkim		ENGINE_finish(e);
236238405Sjkim#endif
237238405Sjkim	if (!ameth)
238238405Sjkim		{
239238405Sjkim		EVPerr(EVP_F_PKEY_SET_TYPE, EVP_R_UNSUPPORTED_ALGORITHM);
240238405Sjkim		return 0;
241238405Sjkim		}
242238405Sjkim	if (pkey)
243238405Sjkim		{
244238405Sjkim		pkey->ameth = ameth;
245238405Sjkim		pkey->engine = e;
246238405Sjkim
247238405Sjkim		pkey->type = pkey->ameth->pkey_id;
248238405Sjkim		pkey->save_type=type;
249238405Sjkim		}
250238405Sjkim	return 1;
251238405Sjkim	}
252238405Sjkim
253238405Sjkimint EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
254238405Sjkim	{
255238405Sjkim	return pkey_set_type(pkey, type, NULL, -1);
256238405Sjkim	}
257238405Sjkim
258238405Sjkimint EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len)
259238405Sjkim	{
260238405Sjkim	return pkey_set_type(pkey, EVP_PKEY_NONE, str, len);
261238405Sjkim	}
262238405Sjkim
263238405Sjkimint EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
264238405Sjkim	{
265238405Sjkim	if (!EVP_PKEY_set_type(pkey, type))
266238405Sjkim		return 0;
26755714Skris	pkey->pkey.ptr=key;
268238405Sjkim	return (key != NULL);
26955714Skris	}
27055714Skris
271238405Sjkimvoid *EVP_PKEY_get0(EVP_PKEY *pkey)
272238405Sjkim	{
273238405Sjkim	return pkey->pkey.ptr;
274238405Sjkim	}
275238405Sjkim
276109998Smarkm#ifndef OPENSSL_NO_RSA
27759191Skrisint EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key)
27859191Skris{
27959191Skris	int ret = EVP_PKEY_assign_RSA(pkey, key);
280109998Smarkm	if(ret)
281109998Smarkm		RSA_up_ref(key);
28259191Skris	return ret;
28359191Skris}
28459191Skris
28559191SkrisRSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey)
28659191Skris	{
28759191Skris	if(pkey->type != EVP_PKEY_RSA) {
28859191Skris		EVPerr(EVP_F_EVP_PKEY_GET1_RSA, EVP_R_EXPECTING_AN_RSA_KEY);
28959191Skris		return NULL;
29059191Skris	}
291109998Smarkm	RSA_up_ref(pkey->pkey.rsa);
29259191Skris	return pkey->pkey.rsa;
29359191Skris}
29459191Skris#endif
29559191Skris
296109998Smarkm#ifndef OPENSSL_NO_DSA
29759191Skrisint EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
29859191Skris{
29959191Skris	int ret = EVP_PKEY_assign_DSA(pkey, key);
300109998Smarkm	if(ret)
301109998Smarkm		DSA_up_ref(key);
30259191Skris	return ret;
30359191Skris}
30459191Skris
30559191SkrisDSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey)
30659191Skris	{
30759191Skris	if(pkey->type != EVP_PKEY_DSA) {
30859191Skris		EVPerr(EVP_F_EVP_PKEY_GET1_DSA, EVP_R_EXPECTING_A_DSA_KEY);
30959191Skris		return NULL;
31059191Skris	}
311109998Smarkm	DSA_up_ref(pkey->pkey.dsa);
31259191Skris	return pkey->pkey.dsa;
31359191Skris}
31459191Skris#endif
31559191Skris
316160814Ssimon#ifndef OPENSSL_NO_EC
317160814Ssimon
318160814Ssimonint EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key)
319160814Ssimon{
320160814Ssimon	int ret = EVP_PKEY_assign_EC_KEY(pkey,key);
321160814Ssimon	if (ret)
322160814Ssimon		EC_KEY_up_ref(key);
323160814Ssimon	return ret;
324160814Ssimon}
325160814Ssimon
326160814SsimonEC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey)
327160814Ssimon{
328160814Ssimon	if (pkey->type != EVP_PKEY_EC)
329160814Ssimon	{
330160814Ssimon		EVPerr(EVP_F_EVP_PKEY_GET1_EC_KEY, EVP_R_EXPECTING_A_EC_KEY);
331160814Ssimon		return NULL;
332160814Ssimon	}
333160814Ssimon	EC_KEY_up_ref(pkey->pkey.ec);
334160814Ssimon	return pkey->pkey.ec;
335160814Ssimon}
336160814Ssimon#endif
337160814Ssimon
338160814Ssimon
339109998Smarkm#ifndef OPENSSL_NO_DH
34059191Skris
34159191Skrisint EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key)
34259191Skris{
34359191Skris	int ret = EVP_PKEY_assign_DH(pkey, key);
344109998Smarkm	if(ret)
345109998Smarkm		DH_up_ref(key);
34659191Skris	return ret;
34759191Skris}
34859191Skris
34959191SkrisDH *EVP_PKEY_get1_DH(EVP_PKEY *pkey)
35059191Skris	{
35159191Skris	if(pkey->type != EVP_PKEY_DH) {
35259191Skris		EVPerr(EVP_F_EVP_PKEY_GET1_DH, EVP_R_EXPECTING_A_DH_KEY);
35359191Skris		return NULL;
35459191Skris	}
355109998Smarkm	DH_up_ref(pkey->pkey.dh);
35659191Skris	return pkey->pkey.dh;
35759191Skris}
35859191Skris#endif
35959191Skris
36055714Skrisint EVP_PKEY_type(int type)
36155714Skris	{
362238405Sjkim	int ret;
363238405Sjkim	const EVP_PKEY_ASN1_METHOD *ameth;
364238405Sjkim	ENGINE *e;
365238405Sjkim	ameth = EVP_PKEY_asn1_find(&e, type);
366238405Sjkim	if (ameth)
367238405Sjkim		ret = ameth->pkey_id;
368238405Sjkim	else
369238405Sjkim		ret = NID_undef;
370238405Sjkim#ifndef OPENSSL_NO_ENGINE
371238405Sjkim	if (e)
372238405Sjkim		ENGINE_finish(e);
373238405Sjkim#endif
374238405Sjkim	return ret;
37555714Skris	}
37655714Skris
377238405Sjkimint EVP_PKEY_id(const EVP_PKEY *pkey)
378238405Sjkim	{
379238405Sjkim	return pkey->type;
380238405Sjkim	}
381238405Sjkim
382238405Sjkimint EVP_PKEY_base_id(const EVP_PKEY *pkey)
383238405Sjkim	{
384238405Sjkim	return EVP_PKEY_type(pkey->type);
385238405Sjkim	}
386238405Sjkim
38755714Skrisvoid EVP_PKEY_free(EVP_PKEY *x)
38855714Skris	{
38955714Skris	int i;
39055714Skris
39155714Skris	if (x == NULL) return;
39255714Skris
39355714Skris	i=CRYPTO_add(&x->references,-1,CRYPTO_LOCK_EVP_PKEY);
39455714Skris#ifdef REF_PRINT
39555714Skris	REF_PRINT("EVP_PKEY",x);
39655714Skris#endif
39755714Skris	if (i > 0) return;
39855714Skris#ifdef REF_CHECK
39955714Skris	if (i < 0)
40055714Skris		{
40155714Skris		fprintf(stderr,"EVP_PKEY_free, bad reference count\n");
40255714Skris		abort();
40355714Skris		}
40455714Skris#endif
40555714Skris	EVP_PKEY_free_it(x);
406160814Ssimon	if (x->attributes)
407160814Ssimon		sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);
40868651Skris	OPENSSL_free(x);
40955714Skris	}
41055714Skris
41155714Skrisstatic void EVP_PKEY_free_it(EVP_PKEY *x)
41255714Skris	{
413238405Sjkim	if (x->ameth && x->ameth->pkey_free)
41455714Skris		{
415238405Sjkim		x->ameth->pkey_free(x);
416238405Sjkim		x->pkey.ptr = NULL;
417238405Sjkim		}
418238405Sjkim#ifndef OPENSSL_NO_ENGINE
419238405Sjkim	if (x->engine)
420238405Sjkim		{
421238405Sjkim		ENGINE_finish(x->engine);
422238405Sjkim		x->engine = NULL;
423238405Sjkim		}
42455714Skris#endif
42555714Skris	}
42655714Skris
427238405Sjkimstatic int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent,
428238405Sjkim				const char *kstr)
429238405Sjkim	{
430238405Sjkim	BIO_indent(out, indent, 128);
431238405Sjkim	BIO_printf(out, "%s algorithm \"%s\" unsupported\n",
432238405Sjkim						kstr, OBJ_nid2ln(pkey->type));
433238405Sjkim	return 1;
434238405Sjkim	}
435238405Sjkim
436238405Sjkimint EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
437238405Sjkim				int indent, ASN1_PCTX *pctx)
438238405Sjkim	{
439238405Sjkim	if (pkey->ameth && pkey->ameth->pub_print)
440238405Sjkim		return pkey->ameth->pub_print(out, pkey, indent, pctx);
441238405Sjkim
442238405Sjkim	return unsup_alg(out, pkey, indent, "Public Key");
443238405Sjkim	}
444238405Sjkim
445238405Sjkimint EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
446238405Sjkim				int indent, ASN1_PCTX *pctx)
447238405Sjkim	{
448238405Sjkim	if (pkey->ameth && pkey->ameth->priv_print)
449238405Sjkim		return pkey->ameth->priv_print(out, pkey, indent, pctx);
450238405Sjkim
451238405Sjkim	return unsup_alg(out, pkey, indent, "Private Key");
452238405Sjkim	}
453238405Sjkim
454238405Sjkimint EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
455238405Sjkim				int indent, ASN1_PCTX *pctx)
456238405Sjkim	{
457238405Sjkim	if (pkey->ameth && pkey->ameth->param_print)
458238405Sjkim		return pkey->ameth->param_print(out, pkey, indent, pctx);
459238405Sjkim	return unsup_alg(out, pkey, indent, "Parameters");
460238405Sjkim	}
461238405Sjkim
462238405Sjkimint EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid)
463238405Sjkim	{
464238405Sjkim	if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
465238405Sjkim		return -2;
466238405Sjkim	return pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID,
467238405Sjkim						0, pnid);
468238405Sjkim	}
469238405Sjkim
470