Update copyright year
[oweals/openssl.git] / crypto / asn1 / ameth_lib.c
1 /*
2  * Copyright 2006-2018 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 = NULL;
147
148     if (len == -1)
149         len = strlen(str);
150     if (pe) {
151 #ifndef OPENSSL_NO_ENGINE
152         ENGINE *e;
153         ameth = ENGINE_pkey_asn1_find_str(&e, str, len);
154         if (ameth) {
155             /*
156              * Convert structural into functional reference
157              */
158             if (!ENGINE_init(e))
159                 ameth = NULL;
160             ENGINE_free(e);
161             *pe = e;
162             return ameth;
163         }
164 #endif
165         *pe = NULL;
166     }
167     for (i = EVP_PKEY_asn1_get_count(); i-- > 0; ) {
168         ameth = EVP_PKEY_asn1_get0(i);
169         if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
170             continue;
171         if ((int)strlen(ameth->pem_str) == len
172             && strncasecmp(ameth->pem_str, str, len) == 0)
173             return ameth;
174     }
175     return NULL;
176 }
177
178 int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth)
179 {
180     EVP_PKEY_ASN1_METHOD tmp = { 0, };
181
182     if (app_methods == NULL) {
183         app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp);
184         if (app_methods == NULL)
185             return 0;
186     }
187
188     tmp.pkey_id = ameth->pkey_id;
189     if (sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp) >= 0) {
190         EVPerr(EVP_F_EVP_PKEY_ASN1_ADD0,
191                EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED);
192         return 0;
193     }
194
195     if (!sk_EVP_PKEY_ASN1_METHOD_push(app_methods, ameth))
196         return 0;
197     sk_EVP_PKEY_ASN1_METHOD_sort(app_methods);
198     return 1;
199 }
200
201 int EVP_PKEY_asn1_add_alias(int to, int from)
202 {
203     EVP_PKEY_ASN1_METHOD *ameth;
204     ameth = EVP_PKEY_asn1_new(from, ASN1_PKEY_ALIAS, NULL, NULL);
205     if (ameth == NULL)
206         return 0;
207     ameth->pkey_base_id = to;
208     if (!EVP_PKEY_asn1_add0(ameth)) {
209         EVP_PKEY_asn1_free(ameth);
210         return 0;
211     }
212     return 1;
213 }
214
215 int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *ppkey_base_id,
216                             int *ppkey_flags, const char **pinfo,
217                             const char **ppem_str,
218                             const EVP_PKEY_ASN1_METHOD *ameth)
219 {
220     if (!ameth)
221         return 0;
222     if (ppkey_id)
223         *ppkey_id = ameth->pkey_id;
224     if (ppkey_base_id)
225         *ppkey_base_id = ameth->pkey_base_id;
226     if (ppkey_flags)
227         *ppkey_flags = ameth->pkey_flags;
228     if (pinfo)
229         *pinfo = ameth->info;
230     if (ppem_str)
231         *ppem_str = ameth->pem_str;
232     return 1;
233 }
234
235 const EVP_PKEY_ASN1_METHOD *EVP_PKEY_get0_asn1(const EVP_PKEY *pkey)
236 {
237     return pkey->ameth;
238 }
239
240 EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags,
241                                         const char *pem_str, const char *info)
242 {
243     EVP_PKEY_ASN1_METHOD *ameth = OPENSSL_zalloc(sizeof(*ameth));
244
245     if (ameth == NULL)
246         return NULL;
247
248     ameth->pkey_id = id;
249     ameth->pkey_base_id = id;
250     ameth->pkey_flags = flags | ASN1_PKEY_DYNAMIC;
251
252     if (info) {
253         ameth->info = OPENSSL_strdup(info);
254         if (!ameth->info)
255             goto err;
256     }
257
258     if (pem_str) {
259         ameth->pem_str = OPENSSL_strdup(pem_str);
260         if (!ameth->pem_str)
261             goto err;
262     }
263
264     return ameth;
265
266  err:
267     EVP_PKEY_asn1_free(ameth);
268     return NULL;
269
270 }
271
272 void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst,
273                         const EVP_PKEY_ASN1_METHOD *src)
274 {
275
276     dst->pub_decode = src->pub_decode;
277     dst->pub_encode = src->pub_encode;
278     dst->pub_cmp = src->pub_cmp;
279     dst->pub_print = src->pub_print;
280
281     dst->priv_decode = src->priv_decode;
282     dst->priv_encode = src->priv_encode;
283     dst->priv_print = src->priv_print;
284
285     dst->old_priv_encode = src->old_priv_encode;
286     dst->old_priv_decode = src->old_priv_decode;
287
288     dst->pkey_size = src->pkey_size;
289     dst->pkey_bits = src->pkey_bits;
290
291     dst->param_decode = src->param_decode;
292     dst->param_encode = src->param_encode;
293     dst->param_missing = src->param_missing;
294     dst->param_copy = src->param_copy;
295     dst->param_cmp = src->param_cmp;
296     dst->param_print = src->param_print;
297
298     dst->pkey_free = src->pkey_free;
299     dst->pkey_ctrl = src->pkey_ctrl;
300
301     dst->item_sign = src->item_sign;
302     dst->item_verify = src->item_verify;
303
304 }
305
306 void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth)
307 {
308     if (ameth && (ameth->pkey_flags & ASN1_PKEY_DYNAMIC)) {
309         OPENSSL_free(ameth->pem_str);
310         OPENSSL_free(ameth->info);
311         OPENSSL_free(ameth);
312     }
313 }
314
315 void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth,
316                               int (*pub_decode) (EVP_PKEY *pk,
317                                                  X509_PUBKEY *pub),
318                               int (*pub_encode) (X509_PUBKEY *pub,
319                                                  const EVP_PKEY *pk),
320                               int (*pub_cmp) (const EVP_PKEY *a,
321                                               const EVP_PKEY *b),
322                               int (*pub_print) (BIO *out,
323                                                 const EVP_PKEY *pkey,
324                                                 int indent, ASN1_PCTX *pctx),
325                               int (*pkey_size) (const EVP_PKEY *pk),
326                               int (*pkey_bits) (const EVP_PKEY *pk))
327 {
328     ameth->pub_decode = pub_decode;
329     ameth->pub_encode = pub_encode;
330     ameth->pub_cmp = pub_cmp;
331     ameth->pub_print = pub_print;
332     ameth->pkey_size = pkey_size;
333     ameth->pkey_bits = pkey_bits;
334 }
335
336 void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth,
337                                int (*priv_decode) (EVP_PKEY *pk,
338                                                    const PKCS8_PRIV_KEY_INFO
339                                                    *p8inf),
340                                int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8,
341                                                    const EVP_PKEY *pk),
342                                int (*priv_print) (BIO *out,
343                                                   const EVP_PKEY *pkey,
344                                                   int indent,
345                                                   ASN1_PCTX *pctx))
346 {
347     ameth->priv_decode = priv_decode;
348     ameth->priv_encode = priv_encode;
349     ameth->priv_print = priv_print;
350 }
351
352 void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth,
353                              int (*param_decode) (EVP_PKEY *pkey,
354                                                   const unsigned char **pder,
355                                                   int derlen),
356                              int (*param_encode) (const EVP_PKEY *pkey,
357                                                   unsigned char **pder),
358                              int (*param_missing) (const EVP_PKEY *pk),
359                              int (*param_copy) (EVP_PKEY *to,
360                                                 const EVP_PKEY *from),
361                              int (*param_cmp) (const EVP_PKEY *a,
362                                                const EVP_PKEY *b),
363                              int (*param_print) (BIO *out,
364                                                  const EVP_PKEY *pkey,
365                                                  int indent, ASN1_PCTX *pctx))
366 {
367     ameth->param_decode = param_decode;
368     ameth->param_encode = param_encode;
369     ameth->param_missing = param_missing;
370     ameth->param_copy = param_copy;
371     ameth->param_cmp = param_cmp;
372     ameth->param_print = param_print;
373 }
374
375 void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth,
376                             void (*pkey_free) (EVP_PKEY *pkey))
377 {
378     ameth->pkey_free = pkey_free;
379 }
380
381 void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
382                             int (*pkey_ctrl) (EVP_PKEY *pkey, int op,
383                                               long arg1, void *arg2))
384 {
385     ameth->pkey_ctrl = pkey_ctrl;
386 }
387
388 void EVP_PKEY_asn1_set_security_bits(EVP_PKEY_ASN1_METHOD *ameth,
389                                      int (*pkey_security_bits) (const EVP_PKEY
390                                                                 *pk))
391 {
392     ameth->pkey_security_bits = pkey_security_bits;
393 }
394
395 void EVP_PKEY_asn1_set_item(EVP_PKEY_ASN1_METHOD *ameth,
396                             int (*item_verify) (EVP_MD_CTX *ctx,
397                                                 const ASN1_ITEM *it,
398                                                 void *asn,
399                                                 X509_ALGOR *a,
400                                                 ASN1_BIT_STRING *sig,
401                                                 EVP_PKEY *pkey),
402                             int (*item_sign) (EVP_MD_CTX *ctx,
403                                               const ASN1_ITEM *it,
404                                               void *asn,
405                                               X509_ALGOR *alg1,
406                                               X509_ALGOR *alg2,
407                                               ASN1_BIT_STRING *sig))
408 {
409     ameth->item_sign = item_sign;
410     ameth->item_verify = item_verify;
411 }