d5a024776ff7525aca4964dea97a9cfcc1524659
[openssl.git] / crypto / asn1 / ameth_lib.c
1 /*
2  * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include <stdio.h>
11 #include "internal/cryptlib.h"
12 #include <openssl/asn1t.h>
13 #include <openssl/x509.h>
14 #include <openssl/engine.h>
15 #include "internal/asn1_int.h"
16 #include "internal/evp_int.h"
17
18 /* Keep this sorted in type order !! */
19 static const EVP_PKEY_ASN1_METHOD *standard_methods[] = {
20 #ifndef OPENSSL_NO_RSA
21     &rsa_asn1_meths[0],
22     &rsa_asn1_meths[1],
23 #endif
24 #ifndef OPENSSL_NO_DH
25     &dh_asn1_meth,
26 #endif
27 #ifndef OPENSSL_NO_DSA
28     &dsa_asn1_meths[0],
29     &dsa_asn1_meths[1],
30     &dsa_asn1_meths[2],
31     &dsa_asn1_meths[3],
32     &dsa_asn1_meths[4],
33 #endif
34 #ifndef OPENSSL_NO_EC
35     &eckey_asn1_meth,
36 #endif
37     &hmac_asn1_meth,
38 #ifndef OPENSSL_NO_CMAC
39     &cmac_asn1_meth,
40 #endif
41 #ifndef OPENSSL_NO_DH
42     &dhx_asn1_meth,
43 #endif
44 #ifndef OPENSSL_NO_EC
45     &ecx25519_asn1_meth
46 #endif
47 };
48
49 typedef int sk_cmp_fn_type(const char *const *a, const char *const *b);
50 static STACK_OF(EVP_PKEY_ASN1_METHOD) *app_methods = NULL;
51
52 #ifdef TEST
53 void main()
54 {
55     int i;
56     for (i = 0; i < OSSL_NELEM(standard_methods); i++)
57         fprintf(stderr, "Number %d id=%d (%s)\n", i,
58                 standard_methods[i]->pkey_id,
59                 OBJ_nid2sn(standard_methods[i]->pkey_id));
60 }
61 #endif
62
63 DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
64                            const EVP_PKEY_ASN1_METHOD *, ameth);
65
66 static int ameth_cmp(const EVP_PKEY_ASN1_METHOD *const *a,
67                      const EVP_PKEY_ASN1_METHOD *const *b)
68 {
69     return ((*a)->pkey_id - (*b)->pkey_id);
70 }
71
72 IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
73                              const EVP_PKEY_ASN1_METHOD *, ameth);
74
75 int EVP_PKEY_asn1_get_count(void)
76 {
77     int num = OSSL_NELEM(standard_methods);
78     if (app_methods)
79         num += sk_EVP_PKEY_ASN1_METHOD_num(app_methods);
80     return num;
81 }
82
83 const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx)
84 {
85     int num = OSSL_NELEM(standard_methods);
86     if (idx < 0)
87         return NULL;
88     if (idx < num)
89         return standard_methods[idx];
90     idx -= num;
91     return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
92 }
93
94 static const EVP_PKEY_ASN1_METHOD *pkey_asn1_find(int type)
95 {
96     EVP_PKEY_ASN1_METHOD tmp;
97     const EVP_PKEY_ASN1_METHOD *t = &tmp, **ret;
98     tmp.pkey_id = type;
99     if (app_methods) {
100         int idx;
101         idx = sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp);
102         if (idx >= 0)
103             return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
104     }
105     ret = OBJ_bsearch_ameth(&t, standard_methods, OSSL_NELEM(standard_methods));
106     if (!ret || !*ret)
107         return NULL;
108     return *ret;
109 }
110
111 /*
112  * Find an implementation of an ASN1 algorithm. If 'pe' is not NULL also
113  * search through engines and set *pe to a functional reference to the engine
114  * implementing 'type' or NULL if no engine implements it.
115  */
116
117 const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type)
118 {
119     const EVP_PKEY_ASN1_METHOD *t;
120
121     for (;;) {
122         t = pkey_asn1_find(type);
123         if (!t || !(t->pkey_flags & ASN1_PKEY_ALIAS))
124             break;
125         type = t->pkey_base_id;
126     }
127     if (pe) {
128 #ifndef OPENSSL_NO_ENGINE
129         ENGINE *e;
130         /* type will contain the final unaliased type */
131         e = ENGINE_get_pkey_asn1_meth_engine(type);
132         if (e) {
133             *pe = e;
134             return ENGINE_get_pkey_asn1_meth(e, type);
135         }
136 #endif
137         *pe = NULL;
138     }
139     return t;
140 }
141
142 const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
143                                                    const char *str, int len)
144 {
145     int i;
146     const EVP_PKEY_ASN1_METHOD *ameth;
147     if (len == -1)
148         len = strlen(str);
149     if (pe) {
150 #ifndef OPENSSL_NO_ENGINE
151         ENGINE *e;
152         ameth = ENGINE_pkey_asn1_find_str(&e, str, len);
153         if (ameth) {
154             /*
155              * Convert structural into functional reference
156              */
157             if (!ENGINE_init(e))
158                 ameth = NULL;
159             ENGINE_free(e);
160             *pe = e;
161             return ameth;
162         }
163 #endif
164         *pe = NULL;
165     }
166     for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) {
167         ameth = EVP_PKEY_asn1_get0(i);
168         if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
169             continue;
170         if (((int)strlen(ameth->pem_str) == len)
171             && (strncasecmp(ameth->pem_str, str, len) == 0))
172             return ameth;
173     }
174     return NULL;
175 }
176
177 int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth)
178 {
179     if (app_methods == NULL) {
180         app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp);
181         if (app_methods == NULL)
182             return 0;
183     }
184     if (!sk_EVP_PKEY_ASN1_METHOD_push(app_methods, ameth))
185         return 0;
186     sk_EVP_PKEY_ASN1_METHOD_sort(app_methods);
187     return 1;
188 }
189
190 int EVP_PKEY_asn1_add_alias(int to, int from)
191 {
192     EVP_PKEY_ASN1_METHOD *ameth;
193     ameth = EVP_PKEY_asn1_new(from, ASN1_PKEY_ALIAS, NULL, NULL);
194     if (ameth == NULL)
195         return 0;
196     ameth->pkey_base_id = to;
197     if (!EVP_PKEY_asn1_add0(ameth)) {
198         EVP_PKEY_asn1_free(ameth);
199         return 0;
200     }
201     return 1;
202 }
203
204 int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *ppkey_base_id,
205                             int *ppkey_flags, const char **pinfo,
206                             const char **ppem_str,
207                             const EVP_PKEY_ASN1_METHOD *ameth)
208 {
209     if (!ameth)
210         return 0;
211     if (ppkey_id)
212         *ppkey_id = ameth->pkey_id;
213     if (ppkey_base_id)
214         *ppkey_base_id = ameth->pkey_base_id;
215     if (ppkey_flags)
216         *ppkey_flags = ameth->pkey_flags;
217     if (pinfo)
218         *pinfo = ameth->info;
219     if (ppem_str)
220         *ppem_str = ameth->pem_str;
221     return 1;
222 }
223
224 const EVP_PKEY_ASN1_METHOD *EVP_PKEY_get0_asn1(EVP_PKEY *pkey)
225 {
226     return pkey->ameth;
227 }
228
229 EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags,
230                                         const char *pem_str, const char *info)
231 {
232     EVP_PKEY_ASN1_METHOD *ameth = OPENSSL_zalloc(sizeof(*ameth));
233
234     if (ameth == NULL)
235         return NULL;
236
237     ameth->pkey_id = id;
238     ameth->pkey_base_id = id;
239     ameth->pkey_flags = flags | ASN1_PKEY_DYNAMIC;
240
241     if (info) {
242         ameth->info = OPENSSL_strdup(info);
243         if (!ameth->info)
244             goto err;
245     }
246
247     if (pem_str) {
248         ameth->pem_str = OPENSSL_strdup(pem_str);
249         if (!ameth->pem_str)
250             goto err;
251     }
252
253     return ameth;
254
255  err:
256     EVP_PKEY_asn1_free(ameth);
257     return NULL;
258
259 }
260
261 void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst,
262                         const EVP_PKEY_ASN1_METHOD *src)
263 {
264
265     dst->pub_decode = src->pub_decode;
266     dst->pub_encode = src->pub_encode;
267     dst->pub_cmp = src->pub_cmp;
268     dst->pub_print = src->pub_print;
269
270     dst->priv_decode = src->priv_decode;
271     dst->priv_encode = src->priv_encode;
272     dst->priv_print = src->priv_print;
273
274     dst->old_priv_encode = src->old_priv_encode;
275     dst->old_priv_decode = src->old_priv_decode;
276
277     dst->pkey_size = src->pkey_size;
278     dst->pkey_bits = src->pkey_bits;
279
280     dst->param_decode = src->param_decode;
281     dst->param_encode = src->param_encode;
282     dst->param_missing = src->param_missing;
283     dst->param_copy = src->param_copy;
284     dst->param_cmp = src->param_cmp;
285     dst->param_print = src->param_print;
286
287     dst->pkey_free = src->pkey_free;
288     dst->pkey_ctrl = src->pkey_ctrl;
289
290     dst->item_sign = src->item_sign;
291     dst->item_verify = src->item_verify;
292
293 }
294
295 void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth)
296 {
297     if (ameth && (ameth->pkey_flags & ASN1_PKEY_DYNAMIC)) {
298         OPENSSL_free(ameth->pem_str);
299         OPENSSL_free(ameth->info);
300         OPENSSL_free(ameth);
301     }
302 }
303
304 void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth,
305                               int (*pub_decode) (EVP_PKEY *pk,
306                                                  X509_PUBKEY *pub),
307                               int (*pub_encode) (X509_PUBKEY *pub,
308                                                  const EVP_PKEY *pk),
309                               int (*pub_cmp) (const EVP_PKEY *a,
310                                               const EVP_PKEY *b),
311                               int (*pub_print) (BIO *out,
312                                                 const EVP_PKEY *pkey,
313                                                 int indent, ASN1_PCTX *pctx),
314                               int (*pkey_size) (const EVP_PKEY *pk),
315                               int (*pkey_bits) (const EVP_PKEY *pk))
316 {
317     ameth->pub_decode = pub_decode;
318     ameth->pub_encode = pub_encode;
319     ameth->pub_cmp = pub_cmp;
320     ameth->pub_print = pub_print;
321     ameth->pkey_size = pkey_size;
322     ameth->pkey_bits = pkey_bits;
323 }
324
325 void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth,
326                                int (*priv_decode) (EVP_PKEY *pk,
327                                                    PKCS8_PRIV_KEY_INFO
328                                                    *p8inf),
329                                int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8,
330                                                    const EVP_PKEY *pk),
331                                int (*priv_print) (BIO *out,
332                                                   const EVP_PKEY *pkey,
333                                                   int indent,
334                                                   ASN1_PCTX *pctx))
335 {
336     ameth->priv_decode = priv_decode;
337     ameth->priv_encode = priv_encode;
338     ameth->priv_print = priv_print;
339 }
340
341 void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth,
342                              int (*param_decode) (EVP_PKEY *pkey,
343                                                   const unsigned char **pder,
344                                                   int derlen),
345                              int (*param_encode) (const EVP_PKEY *pkey,
346                                                   unsigned char **pder),
347                              int (*param_missing) (const EVP_PKEY *pk),
348                              int (*param_copy) (EVP_PKEY *to,
349                                                 const EVP_PKEY *from),
350                              int (*param_cmp) (const EVP_PKEY *a,
351                                                const EVP_PKEY *b),
352                              int (*param_print) (BIO *out,
353                                                  const EVP_PKEY *pkey,
354                                                  int indent, ASN1_PCTX *pctx))
355 {
356     ameth->param_decode = param_decode;
357     ameth->param_encode = param_encode;
358     ameth->param_missing = param_missing;
359     ameth->param_copy = param_copy;
360     ameth->param_cmp = param_cmp;
361     ameth->param_print = param_print;
362 }
363
364 void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth,
365                             void (*pkey_free) (EVP_PKEY *pkey))
366 {
367     ameth->pkey_free = pkey_free;
368 }
369
370 void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
371                             int (*pkey_ctrl) (EVP_PKEY *pkey, int op,
372                                               long arg1, void *arg2))
373 {
374     ameth->pkey_ctrl = pkey_ctrl;
375 }
376
377 void EVP_PKEY_asn1_set_security_bits(EVP_PKEY_ASN1_METHOD *ameth,
378                                      int (*pkey_security_bits) (const EVP_PKEY
379                                                                 *pk))
380 {
381     ameth->pkey_security_bits = pkey_security_bits;
382 }
383
384 void EVP_PKEY_asn1_set_item(EVP_PKEY_ASN1_METHOD *ameth,
385                             int (*item_verify) (EVP_MD_CTX *ctx,
386                                                 const ASN1_ITEM *it,
387                                                 void *asn,
388                                                 X509_ALGOR *a,
389                                                 ASN1_BIT_STRING *sig,
390                                                 EVP_PKEY *pkey),
391                             int (*item_sign) (EVP_MD_CTX *ctx,
392                                               const ASN1_ITEM *it,
393                                               void *asn,
394                                               X509_ALGOR *alg1,
395                                               X509_ALGOR *alg2,
396                                               ASN1_BIT_STRING *sig))
397 {
398     ameth->item_sign = item_sign;
399     ameth->item_verify = item_verify;
400 }