1480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* ====================================================================
2480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
3480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *
4480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * Redistribution and use in source and binary forms, with or without
5480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * modification, are permitted provided that the following conditions
6480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * are met:
7480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *
8480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * 1. Redistributions of source code must retain the above copyright
9480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *    notice, this list of conditions and the following disclaimer.
10480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *
11480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * 2. Redistributions in binary form must reproduce the above copyright
12480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *    notice, this list of conditions and the following disclaimer in
13480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *    the documentation and/or other materials provided with the
14480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *    distribution.
15480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *
16480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * 3. All advertising materials mentioning features or use of this
17480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *    software must display the following acknowledgment:
18480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *    "This product includes software developed by the OpenSSL Project
19480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *
21480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *    endorse or promote products derived from this software without
23480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *    prior written permission. For written permission, please contact
24480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *    licensing@OpenSSL.org.
25480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *
26480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * 5. Products derived from this software may not be called "OpenSSL"
27480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *    nor may "OpenSSL" appear in their names without prior written
28480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *    permission of the OpenSSL Project.
29480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *
30480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * 6. Redistributions of any form whatsoever must retain the following
31480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *    acknowledgment:
32480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *    "This product includes software developed by the OpenSSL Project
33480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *
35480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
39480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * OF THE POSSIBILITY OF SUCH DAMAGE.
47480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * ====================================================================
48480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *
49480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * This product includes cryptographic software written by Eric Young
50480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * (eay@cryptsoft.com).  This product includes software written by Tim
51480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * Hudson (tjh@cryptsoft.com).
52480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *
53480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org */
54480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
55480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#include "eng_int.h"
56480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#include <openssl/evp.h>
57480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
58480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* If this symbol is defined then ENGINE_get_pkey_meth_engine(), the function
59480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * that is used by EVP to hook in pkey_meth code and cache defaults (etc), will
60480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * display brief debugging summaries to stderr with the 'nid'. */
61480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* #define ENGINE_PKEY_METH_DEBUG */
62480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
63480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic ENGINE_TABLE *pkey_meth_table = NULL;
64480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
65480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgvoid ENGINE_unregister_pkey_meths(ENGINE *e)
66480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
67480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	engine_table_unregister(&pkey_meth_table, e);
68480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
69480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
70480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic void engine_unregister_all_pkey_meths(void)
71480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
72480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	engine_table_cleanup(&pkey_meth_table);
73480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
74480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
75480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgint ENGINE_register_pkey_meths(ENGINE *e)
76480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
77480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if(e->pkey_meths)
78480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
79480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		const int *nids;
80480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		int num_nids = e->pkey_meths(e, NULL, &nids, 0);
81480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if(num_nids > 0)
82480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return engine_table_register(&pkey_meth_table,
83480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				engine_unregister_all_pkey_meths, e, nids,
84480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org					num_nids, 0);
85480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
86480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return 1;
87480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
88480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
89480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgvoid ENGINE_register_all_pkey_meths()
90480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
91480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	ENGINE *e;
92480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
93480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
94480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		ENGINE_register_pkey_meths(e);
95480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
96480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
97480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgint ENGINE_set_default_pkey_meths(ENGINE *e)
98480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
99480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if(e->pkey_meths)
100480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
101480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		const int *nids;
102480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		int num_nids = e->pkey_meths(e, NULL, &nids, 0);
103480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if(num_nids > 0)
104480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return engine_table_register(&pkey_meth_table,
105480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				engine_unregister_all_pkey_meths, e, nids,
106480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org					num_nids, 1);
107480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
108480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return 1;
109480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
110480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
111480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* Exposed API function to get a functional reference from the implementation
112480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * table (ie. try to get a functional reference from the tabled structural
113480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * references) for a given pkey_meth 'nid' */
114480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgENGINE *ENGINE_get_pkey_meth_engine(int nid)
115480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
116480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return engine_table_select(&pkey_meth_table, nid);
117480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
118480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
119480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* Obtains a pkey_meth implementation from an ENGINE functional reference */
120480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgconst EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid)
121480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
122480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	EVP_PKEY_METHOD *ret;
123480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	ENGINE_PKEY_METHS_PTR fn = ENGINE_get_pkey_meths(e);
124480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if(!fn || !fn(e, &ret, NULL, nid))
125480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
126480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_METH,
127480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD);
128480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return NULL;
129480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
130480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return ret;
131480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
132480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
133480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* Gets the pkey_meth callback from an ENGINE structure */
134480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e)
135480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
136480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return e->pkey_meths;
137480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
138480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
139480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* Sets the pkey_meth callback in an ENGINE structure */
140480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgint ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f)
141480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
142480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	e->pkey_meths = f;
143480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return 1;
144480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
145480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
146480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* Internal function to free up EVP_PKEY_METHOD structures before an
147480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * ENGINE is destroyed
148480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org */
149480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
150480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgvoid engine_pkey_meths_free(ENGINE *e)
151480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
152480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int i;
153480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	EVP_PKEY_METHOD *pkm;
154480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (e->pkey_meths)
155480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
156480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		const int *pknids;
157480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		int npknids;
158480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		npknids = e->pkey_meths(e, NULL, &pknids, 0);
159480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		for (i = 0; i < npknids; i++)
160480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
161480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (e->pkey_meths(e, &pkm, NULL, pknids[i]))
162480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				{
163480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				EVP_PKEY_meth_free(pkm);
164480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				}
165480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
166480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
167480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
168