1280304Sjkim/*
2280304Sjkim * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
3280304Sjkim * 2006.
4238384Sjkim */
5238384Sjkim/* ====================================================================
6238384Sjkim * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
7238384Sjkim *
8238384Sjkim * Redistribution and use in source and binary forms, with or without
9238384Sjkim * modification, are permitted provided that the following conditions
10238384Sjkim * are met:
11238384Sjkim *
12238384Sjkim * 1. Redistributions of source code must retain the above copyright
13280304Sjkim *    notice, this list of conditions and the following disclaimer.
14238384Sjkim *
15238384Sjkim * 2. Redistributions in binary form must reproduce the above copyright
16238384Sjkim *    notice, this list of conditions and the following disclaimer in
17238384Sjkim *    the documentation and/or other materials provided with the
18238384Sjkim *    distribution.
19238384Sjkim *
20238384Sjkim * 3. All advertising materials mentioning features or use of this
21238384Sjkim *    software must display the following acknowledgment:
22238384Sjkim *    "This product includes software developed by the OpenSSL Project
23238384Sjkim *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24238384Sjkim *
25238384Sjkim * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26238384Sjkim *    endorse or promote products derived from this software without
27238384Sjkim *    prior written permission. For written permission, please contact
28238384Sjkim *    licensing@OpenSSL.org.
29238384Sjkim *
30238384Sjkim * 5. Products derived from this software may not be called "OpenSSL"
31238384Sjkim *    nor may "OpenSSL" appear in their names without prior written
32238384Sjkim *    permission of the OpenSSL Project.
33238384Sjkim *
34238384Sjkim * 6. Redistributions of any form whatsoever must retain the following
35238384Sjkim *    acknowledgment:
36238384Sjkim *    "This product includes software developed by the OpenSSL Project
37238384Sjkim *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38238384Sjkim *
39238384Sjkim * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40238384Sjkim * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41238384Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42238384Sjkim * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43238384Sjkim * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44238384Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45238384Sjkim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46238384Sjkim * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47238384Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48238384Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49238384Sjkim * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50238384Sjkim * OF THE POSSIBILITY OF SUCH DAMAGE.
51238384Sjkim * ====================================================================
52238384Sjkim *
53238384Sjkim * This product includes cryptographic software written by Eric Young
54238384Sjkim * (eay@cryptsoft.com).  This product includes software written by Tim
55238384Sjkim * Hudson (tjh@cryptsoft.com).
56238384Sjkim *
57238384Sjkim */
58238384Sjkim
59238384Sjkim#include <stdio.h>
60238384Sjkim#include "cryptlib.h"
61238384Sjkim#include <openssl/asn1t.h>
62238384Sjkim#include <openssl/x509.h>
63238384Sjkim#ifndef OPENSSL_NO_ENGINE
64280304Sjkim# include <openssl/engine.h>
65238384Sjkim#endif
66238384Sjkim#include "asn1_locl.h"
67238384Sjkim
68238384Sjkimextern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[];
69238384Sjkimextern const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[];
70238384Sjkimextern const EVP_PKEY_ASN1_METHOD dh_asn1_meth;
71238384Sjkimextern const EVP_PKEY_ASN1_METHOD eckey_asn1_meth;
72238384Sjkimextern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth;
73238384Sjkimextern const EVP_PKEY_ASN1_METHOD cmac_asn1_meth;
74238384Sjkim
75238384Sjkim/* Keep this sorted in type order !! */
76280304Sjkimstatic const EVP_PKEY_ASN1_METHOD *standard_methods[] = {
77238384Sjkim#ifndef OPENSSL_NO_RSA
78280304Sjkim    &rsa_asn1_meths[0],
79280304Sjkim    &rsa_asn1_meths[1],
80238384Sjkim#endif
81238384Sjkim#ifndef OPENSSL_NO_DH
82280304Sjkim    &dh_asn1_meth,
83238384Sjkim#endif
84238384Sjkim#ifndef OPENSSL_NO_DSA
85280304Sjkim    &dsa_asn1_meths[0],
86280304Sjkim    &dsa_asn1_meths[1],
87280304Sjkim    &dsa_asn1_meths[2],
88280304Sjkim    &dsa_asn1_meths[3],
89280304Sjkim    &dsa_asn1_meths[4],
90238384Sjkim#endif
91238384Sjkim#ifndef OPENSSL_NO_EC
92280304Sjkim    &eckey_asn1_meth,
93238384Sjkim#endif
94280304Sjkim    &hmac_asn1_meth,
95280304Sjkim    &cmac_asn1_meth
96280304Sjkim};
97238384Sjkim
98280304Sjkimtypedef int sk_cmp_fn_type(const char *const *a, const char *const *b);
99238384SjkimDECLARE_STACK_OF(EVP_PKEY_ASN1_METHOD)
100238384Sjkimstatic STACK_OF(EVP_PKEY_ASN1_METHOD) *app_methods = NULL;
101238384Sjkim
102238384Sjkim#ifdef TEST
103238384Sjkimvoid main()
104280304Sjkim{
105280304Sjkim    int i;
106280304Sjkim    for (i = 0;
107280304Sjkim         i < sizeof(standard_methods) / sizeof(EVP_PKEY_ASN1_METHOD *); i++)
108280304Sjkim        fprintf(stderr, "Number %d id=%d (%s)\n", i,
109280304Sjkim                standard_methods[i]->pkey_id,
110280304Sjkim                OBJ_nid2sn(standard_methods[i]->pkey_id));
111280304Sjkim}
112238384Sjkim#endif
113238384Sjkim
114238384SjkimDECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
115280304Sjkim                           const EVP_PKEY_ASN1_METHOD *, ameth);
116238384Sjkim
117280304Sjkimstatic int ameth_cmp(const EVP_PKEY_ASN1_METHOD *const *a,
118280304Sjkim                     const EVP_PKEY_ASN1_METHOD *const *b)
119280304Sjkim{
120280304Sjkim    return ((*a)->pkey_id - (*b)->pkey_id);
121280304Sjkim}
122238384Sjkim
123238384SjkimIMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
124280304Sjkim                             const EVP_PKEY_ASN1_METHOD *, ameth);
125238384Sjkim
126238384Sjkimint EVP_PKEY_asn1_get_count(void)
127280304Sjkim{
128280304Sjkim    int num = sizeof(standard_methods) / sizeof(EVP_PKEY_ASN1_METHOD *);
129280304Sjkim    if (app_methods)
130280304Sjkim        num += sk_EVP_PKEY_ASN1_METHOD_num(app_methods);
131280304Sjkim    return num;
132280304Sjkim}
133238384Sjkim
134238384Sjkimconst EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx)
135280304Sjkim{
136280304Sjkim    int num = sizeof(standard_methods) / sizeof(EVP_PKEY_ASN1_METHOD *);
137280304Sjkim    if (idx < 0)
138280304Sjkim        return NULL;
139280304Sjkim    if (idx < num)
140280304Sjkim        return standard_methods[idx];
141280304Sjkim    idx -= num;
142280304Sjkim    return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
143280304Sjkim}
144238384Sjkim
145238384Sjkimstatic const EVP_PKEY_ASN1_METHOD *pkey_asn1_find(int type)
146280304Sjkim{
147280304Sjkim    EVP_PKEY_ASN1_METHOD tmp;
148280304Sjkim    const EVP_PKEY_ASN1_METHOD *t = &tmp, **ret;
149280304Sjkim    tmp.pkey_id = type;
150280304Sjkim    if (app_methods) {
151280304Sjkim        int idx;
152280304Sjkim        idx = sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp);
153280304Sjkim        if (idx >= 0)
154280304Sjkim            return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
155280304Sjkim    }
156280304Sjkim    ret = OBJ_bsearch_ameth(&t, standard_methods, sizeof(standard_methods)
157280304Sjkim                            / sizeof(EVP_PKEY_ASN1_METHOD *));
158280304Sjkim    if (!ret || !*ret)
159280304Sjkim        return NULL;
160280304Sjkim    return *ret;
161280304Sjkim}
162238384Sjkim
163280304Sjkim/*
164280304Sjkim * Find an implementation of an ASN1 algorithm. If 'pe' is not NULL also
165280304Sjkim * search through engines and set *pe to a functional reference to the engine
166280304Sjkim * implementing 'type' or NULL if no engine implements it.
167238384Sjkim */
168238384Sjkim
169238384Sjkimconst EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type)
170280304Sjkim{
171280304Sjkim    const EVP_PKEY_ASN1_METHOD *t;
172238384Sjkim
173280304Sjkim    for (;;) {
174280304Sjkim        t = pkey_asn1_find(type);
175280304Sjkim        if (!t || !(t->pkey_flags & ASN1_PKEY_ALIAS))
176280304Sjkim            break;
177280304Sjkim        type = t->pkey_base_id;
178280304Sjkim    }
179280304Sjkim    if (pe) {
180238384Sjkim#ifndef OPENSSL_NO_ENGINE
181280304Sjkim        ENGINE *e;
182280304Sjkim        /* type will contain the final unaliased type */
183280304Sjkim        e = ENGINE_get_pkey_asn1_meth_engine(type);
184280304Sjkim        if (e) {
185280304Sjkim            *pe = e;
186280304Sjkim            return ENGINE_get_pkey_asn1_meth(e, type);
187280304Sjkim        }
188238384Sjkim#endif
189280304Sjkim        *pe = NULL;
190280304Sjkim    }
191280304Sjkim    return t;
192280304Sjkim}
193238384Sjkim
194238384Sjkimconst EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
195280304Sjkim                                                   const char *str, int len)
196280304Sjkim{
197280304Sjkim    int i;
198280304Sjkim    const EVP_PKEY_ASN1_METHOD *ameth;
199280304Sjkim    if (len == -1)
200280304Sjkim        len = strlen(str);
201280304Sjkim    if (pe) {
202238384Sjkim#ifndef OPENSSL_NO_ENGINE
203280304Sjkim        ENGINE *e;
204280304Sjkim        ameth = ENGINE_pkey_asn1_find_str(&e, str, len);
205280304Sjkim        if (ameth) {
206280304Sjkim            /*
207280304Sjkim             * Convert structural into functional reference
208280304Sjkim             */
209280304Sjkim            if (!ENGINE_init(e))
210280304Sjkim                ameth = NULL;
211280304Sjkim            ENGINE_free(e);
212280304Sjkim            *pe = e;
213280304Sjkim            return ameth;
214280304Sjkim        }
215238384Sjkim#endif
216280304Sjkim        *pe = NULL;
217280304Sjkim    }
218280304Sjkim    for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) {
219280304Sjkim        ameth = EVP_PKEY_asn1_get0(i);
220280304Sjkim        if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
221280304Sjkim            continue;
222280304Sjkim        if (((int)strlen(ameth->pem_str) == len) &&
223280304Sjkim            !strncasecmp(ameth->pem_str, str, len))
224280304Sjkim            return ameth;
225280304Sjkim    }
226280304Sjkim    return NULL;
227280304Sjkim}
228238384Sjkim
229238384Sjkimint EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth)
230280304Sjkim{
231280304Sjkim    if (app_methods == NULL) {
232280304Sjkim        app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp);
233280304Sjkim        if (!app_methods)
234280304Sjkim            return 0;
235280304Sjkim    }
236280304Sjkim    if (!sk_EVP_PKEY_ASN1_METHOD_push(app_methods, ameth))
237280304Sjkim        return 0;
238280304Sjkim    sk_EVP_PKEY_ASN1_METHOD_sort(app_methods);
239280304Sjkim    return 1;
240280304Sjkim}
241238384Sjkim
242238384Sjkimint EVP_PKEY_asn1_add_alias(int to, int from)
243280304Sjkim{
244280304Sjkim    EVP_PKEY_ASN1_METHOD *ameth;
245280304Sjkim    ameth = EVP_PKEY_asn1_new(from, ASN1_PKEY_ALIAS, NULL, NULL);
246280304Sjkim    if (!ameth)
247280304Sjkim        return 0;
248280304Sjkim    ameth->pkey_base_id = to;
249280304Sjkim    if (!EVP_PKEY_asn1_add0(ameth)) {
250280304Sjkim        EVP_PKEY_asn1_free(ameth);
251280304Sjkim        return 0;
252280304Sjkim    }
253280304Sjkim    return 1;
254280304Sjkim}
255238384Sjkim
256280304Sjkimint EVP_PKEY_asn1_get0_info(int *ppkey_id, int *ppkey_base_id,
257280304Sjkim                            int *ppkey_flags, const char **pinfo,
258280304Sjkim                            const char **ppem_str,
259280304Sjkim                            const EVP_PKEY_ASN1_METHOD *ameth)
260280304Sjkim{
261280304Sjkim    if (!ameth)
262280304Sjkim        return 0;
263280304Sjkim    if (ppkey_id)
264280304Sjkim        *ppkey_id = ameth->pkey_id;
265280304Sjkim    if (ppkey_base_id)
266280304Sjkim        *ppkey_base_id = ameth->pkey_base_id;
267280304Sjkim    if (ppkey_flags)
268280304Sjkim        *ppkey_flags = ameth->pkey_flags;
269280304Sjkim    if (pinfo)
270280304Sjkim        *pinfo = ameth->info;
271280304Sjkim    if (ppem_str)
272280304Sjkim        *ppem_str = ameth->pem_str;
273280304Sjkim    return 1;
274280304Sjkim}
275238384Sjkim
276280304Sjkimconst EVP_PKEY_ASN1_METHOD *EVP_PKEY_get0_asn1(EVP_PKEY *pkey)
277280304Sjkim{
278280304Sjkim    return pkey->ameth;
279280304Sjkim}
280238384Sjkim
281280304SjkimEVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags,
282280304Sjkim                                        const char *pem_str, const char *info)
283280304Sjkim{
284280304Sjkim    EVP_PKEY_ASN1_METHOD *ameth;
285280304Sjkim    ameth = OPENSSL_malloc(sizeof(EVP_PKEY_ASN1_METHOD));
286280304Sjkim    if (!ameth)
287280304Sjkim        return NULL;
288238384Sjkim
289280304Sjkim    memset(ameth, 0, sizeof(EVP_PKEY_ASN1_METHOD));
290238384Sjkim
291280304Sjkim    ameth->pkey_id = id;
292280304Sjkim    ameth->pkey_base_id = id;
293280304Sjkim    ameth->pkey_flags = flags | ASN1_PKEY_DYNAMIC;
294238384Sjkim
295280304Sjkim    if (info) {
296280304Sjkim        ameth->info = BUF_strdup(info);
297280304Sjkim        if (!ameth->info)
298280304Sjkim            goto err;
299280304Sjkim    } else
300280304Sjkim        ameth->info = NULL;
301238384Sjkim
302280304Sjkim    if (pem_str) {
303280304Sjkim        ameth->pem_str = BUF_strdup(pem_str);
304280304Sjkim        if (!ameth->pem_str)
305280304Sjkim            goto err;
306280304Sjkim    } else
307280304Sjkim        ameth->pem_str = NULL;
308238384Sjkim
309280304Sjkim    ameth->pub_decode = 0;
310280304Sjkim    ameth->pub_encode = 0;
311280304Sjkim    ameth->pub_cmp = 0;
312280304Sjkim    ameth->pub_print = 0;
313238384Sjkim
314280304Sjkim    ameth->priv_decode = 0;
315280304Sjkim    ameth->priv_encode = 0;
316280304Sjkim    ameth->priv_print = 0;
317238384Sjkim
318280304Sjkim    ameth->old_priv_encode = 0;
319280304Sjkim    ameth->old_priv_decode = 0;
320238384Sjkim
321280304Sjkim    ameth->item_verify = 0;
322280304Sjkim    ameth->item_sign = 0;
323238384Sjkim
324280304Sjkim    ameth->pkey_size = 0;
325280304Sjkim    ameth->pkey_bits = 0;
326238384Sjkim
327280304Sjkim    ameth->param_decode = 0;
328280304Sjkim    ameth->param_encode = 0;
329280304Sjkim    ameth->param_missing = 0;
330280304Sjkim    ameth->param_copy = 0;
331280304Sjkim    ameth->param_cmp = 0;
332280304Sjkim    ameth->param_print = 0;
333238384Sjkim
334280304Sjkim    ameth->pkey_free = 0;
335280304Sjkim    ameth->pkey_ctrl = 0;
336238384Sjkim
337280304Sjkim    return ameth;
338238384Sjkim
339280304Sjkim err:
340238384Sjkim
341280304Sjkim    EVP_PKEY_asn1_free(ameth);
342280304Sjkim    return NULL;
343238384Sjkim
344280304Sjkim}
345238384Sjkim
346280304Sjkimvoid EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst,
347280304Sjkim                        const EVP_PKEY_ASN1_METHOD *src)
348280304Sjkim{
349238384Sjkim
350280304Sjkim    dst->pub_decode = src->pub_decode;
351280304Sjkim    dst->pub_encode = src->pub_encode;
352280304Sjkim    dst->pub_cmp = src->pub_cmp;
353280304Sjkim    dst->pub_print = src->pub_print;
354238384Sjkim
355280304Sjkim    dst->priv_decode = src->priv_decode;
356280304Sjkim    dst->priv_encode = src->priv_encode;
357280304Sjkim    dst->priv_print = src->priv_print;
358238384Sjkim
359280304Sjkim    dst->old_priv_encode = src->old_priv_encode;
360280304Sjkim    dst->old_priv_decode = src->old_priv_decode;
361238384Sjkim
362280304Sjkim    dst->pkey_size = src->pkey_size;
363280304Sjkim    dst->pkey_bits = src->pkey_bits;
364238384Sjkim
365280304Sjkim    dst->param_decode = src->param_decode;
366280304Sjkim    dst->param_encode = src->param_encode;
367280304Sjkim    dst->param_missing = src->param_missing;
368280304Sjkim    dst->param_copy = src->param_copy;
369280304Sjkim    dst->param_cmp = src->param_cmp;
370280304Sjkim    dst->param_print = src->param_print;
371238384Sjkim
372280304Sjkim    dst->pkey_free = src->pkey_free;
373280304Sjkim    dst->pkey_ctrl = src->pkey_ctrl;
374238384Sjkim
375280304Sjkim    dst->item_sign = src->item_sign;
376280304Sjkim    dst->item_verify = src->item_verify;
377238384Sjkim
378280304Sjkim}
379238384Sjkim
380238384Sjkimvoid EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth)
381280304Sjkim{
382280304Sjkim    if (ameth && (ameth->pkey_flags & ASN1_PKEY_DYNAMIC)) {
383280304Sjkim        if (ameth->pem_str)
384280304Sjkim            OPENSSL_free(ameth->pem_str);
385280304Sjkim        if (ameth->info)
386280304Sjkim            OPENSSL_free(ameth->info);
387280304Sjkim        OPENSSL_free(ameth);
388280304Sjkim    }
389280304Sjkim}
390238384Sjkim
391238384Sjkimvoid EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth,
392280304Sjkim                              int (*pub_decode) (EVP_PKEY *pk,
393280304Sjkim                                                 X509_PUBKEY *pub),
394280304Sjkim                              int (*pub_encode) (X509_PUBKEY *pub,
395280304Sjkim                                                 const EVP_PKEY *pk),
396280304Sjkim                              int (*pub_cmp) (const EVP_PKEY *a,
397280304Sjkim                                              const EVP_PKEY *b),
398280304Sjkim                              int (*pub_print) (BIO *out,
399280304Sjkim                                                const EVP_PKEY *pkey,
400280304Sjkim                                                int indent, ASN1_PCTX *pctx),
401280304Sjkim                              int (*pkey_size) (const EVP_PKEY *pk),
402280304Sjkim                              int (*pkey_bits) (const EVP_PKEY *pk))
403280304Sjkim{
404280304Sjkim    ameth->pub_decode = pub_decode;
405280304Sjkim    ameth->pub_encode = pub_encode;
406280304Sjkim    ameth->pub_cmp = pub_cmp;
407280304Sjkim    ameth->pub_print = pub_print;
408280304Sjkim    ameth->pkey_size = pkey_size;
409280304Sjkim    ameth->pkey_bits = pkey_bits;
410280304Sjkim}
411238384Sjkim
412238384Sjkimvoid EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth,
413280304Sjkim                               int (*priv_decode) (EVP_PKEY *pk,
414280304Sjkim                                                   PKCS8_PRIV_KEY_INFO
415280304Sjkim                                                   *p8inf),
416280304Sjkim                               int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8,
417280304Sjkim                                                   const EVP_PKEY *pk),
418280304Sjkim                               int (*priv_print) (BIO *out,
419280304Sjkim                                                  const EVP_PKEY *pkey,
420280304Sjkim                                                  int indent,
421280304Sjkim                                                  ASN1_PCTX *pctx))
422280304Sjkim{
423280304Sjkim    ameth->priv_decode = priv_decode;
424280304Sjkim    ameth->priv_encode = priv_encode;
425280304Sjkim    ameth->priv_print = priv_print;
426280304Sjkim}
427238384Sjkim
428238384Sjkimvoid EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth,
429280304Sjkim                             int (*param_decode) (EVP_PKEY *pkey,
430280304Sjkim                                                  const unsigned char **pder,
431280304Sjkim                                                  int derlen),
432280304Sjkim                             int (*param_encode) (const EVP_PKEY *pkey,
433280304Sjkim                                                  unsigned char **pder),
434280304Sjkim                             int (*param_missing) (const EVP_PKEY *pk),
435280304Sjkim                             int (*param_copy) (EVP_PKEY *to,
436280304Sjkim                                                const EVP_PKEY *from),
437280304Sjkim                             int (*param_cmp) (const EVP_PKEY *a,
438280304Sjkim                                               const EVP_PKEY *b),
439280304Sjkim                             int (*param_print) (BIO *out,
440280304Sjkim                                                 const EVP_PKEY *pkey,
441280304Sjkim                                                 int indent, ASN1_PCTX *pctx))
442280304Sjkim{
443280304Sjkim    ameth->param_decode = param_decode;
444280304Sjkim    ameth->param_encode = param_encode;
445280304Sjkim    ameth->param_missing = param_missing;
446280304Sjkim    ameth->param_copy = param_copy;
447280304Sjkim    ameth->param_cmp = param_cmp;
448280304Sjkim    ameth->param_print = param_print;
449280304Sjkim}
450238384Sjkim
451238384Sjkimvoid EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth,
452280304Sjkim                            void (*pkey_free) (EVP_PKEY *pkey))
453280304Sjkim{
454280304Sjkim    ameth->pkey_free = pkey_free;
455280304Sjkim}
456238384Sjkim
457238384Sjkimvoid EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
458280304Sjkim                            int (*pkey_ctrl) (EVP_PKEY *pkey, int op,
459280304Sjkim                                              long arg1, void *arg2))
460280304Sjkim{
461280304Sjkim    ameth->pkey_ctrl = pkey_ctrl;
462280304Sjkim}
463