pmeth_lib.c revision 306195
1/* pmeth_lib.c */
2/*
3 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
4 * 2006.
5 */
6/* ====================================================================
7 * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in
18 *    the documentation and/or other materials provided with the
19 *    distribution.
20 *
21 * 3. All advertising materials mentioning features or use of this
22 *    software must display the following acknowledgment:
23 *    "This product includes software developed by the OpenSSL Project
24 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25 *
26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 *    endorse or promote products derived from this software without
28 *    prior written permission. For written permission, please contact
29 *    licensing@OpenSSL.org.
30 *
31 * 5. Products derived from this software may not be called "OpenSSL"
32 *    nor may "OpenSSL" appear in their names without prior written
33 *    permission of the OpenSSL Project.
34 *
35 * 6. Redistributions of any form whatsoever must retain the following
36 *    acknowledgment:
37 *    "This product includes software developed by the OpenSSL Project
38 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 * OF THE POSSIBILITY OF SUCH DAMAGE.
52 * ====================================================================
53 *
54 * This product includes cryptographic software written by Eric Young
55 * (eay@cryptsoft.com).  This product includes software written by Tim
56 * Hudson (tjh@cryptsoft.com).
57 *
58 */
59
60#include <stdio.h>
61#include <stdlib.h>
62#include "cryptlib.h"
63#include <openssl/objects.h>
64#include <openssl/evp.h>
65#ifndef OPENSSL_NO_ENGINE
66# include <openssl/engine.h>
67#endif
68#include "asn1_locl.h"
69#include "evp_locl.h"
70
71typedef int sk_cmp_fn_type(const char *const *a, const char *const *b);
72
73DECLARE_STACK_OF(EVP_PKEY_METHOD)
74STACK_OF(EVP_PKEY_METHOD) *app_pkey_methods = NULL;
75
76extern const EVP_PKEY_METHOD rsa_pkey_meth, dh_pkey_meth, dsa_pkey_meth;
77extern const EVP_PKEY_METHOD ec_pkey_meth, hmac_pkey_meth, cmac_pkey_meth;
78extern const EVP_PKEY_METHOD dhx_pkey_meth;
79
80static const EVP_PKEY_METHOD *standard_methods[] = {
81#ifndef OPENSSL_NO_RSA
82    &rsa_pkey_meth,
83#endif
84#ifndef OPENSSL_NO_DH
85    &dh_pkey_meth,
86#endif
87#ifndef OPENSSL_NO_DSA
88    &dsa_pkey_meth,
89#endif
90#ifndef OPENSSL_NO_EC
91    &ec_pkey_meth,
92#endif
93    &hmac_pkey_meth,
94#ifndef OPENSSL_NO_CMAC
95    &cmac_pkey_meth,
96#endif
97#ifndef OPENSSL_NO_DH
98    &dhx_pkey_meth
99#endif
100};
101
102DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *,
103                           pmeth);
104
105static int pmeth_cmp(const EVP_PKEY_METHOD *const *a,
106                     const EVP_PKEY_METHOD *const *b)
107{
108    return ((*a)->pkey_id - (*b)->pkey_id);
109}
110
111IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *,
112                             pmeth);
113
114const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type)
115{
116    EVP_PKEY_METHOD tmp;
117    const EVP_PKEY_METHOD *t = &tmp, **ret;
118    tmp.pkey_id = type;
119    if (app_pkey_methods) {
120        int idx;
121        idx = sk_EVP_PKEY_METHOD_find(app_pkey_methods, &tmp);
122        if (idx >= 0)
123            return sk_EVP_PKEY_METHOD_value(app_pkey_methods, idx);
124    }
125    ret = OBJ_bsearch_pmeth(&t, standard_methods,
126                            sizeof(standard_methods) /
127                            sizeof(EVP_PKEY_METHOD *));
128    if (!ret || !*ret)
129        return NULL;
130    return *ret;
131}
132
133static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)
134{
135    EVP_PKEY_CTX *ret;
136    const EVP_PKEY_METHOD *pmeth;
137    if (id == -1) {
138        if (!pkey || !pkey->ameth)
139            return NULL;
140        id = pkey->ameth->pkey_id;
141    }
142#ifndef OPENSSL_NO_ENGINE
143    if (pkey && pkey->engine)
144        e = pkey->engine;
145    /* Try to find an ENGINE which implements this method */
146    if (e) {
147        if (!ENGINE_init(e)) {
148            EVPerr(EVP_F_INT_CTX_NEW, ERR_R_ENGINE_LIB);
149            return NULL;
150        }
151    } else
152        e = ENGINE_get_pkey_meth_engine(id);
153
154    /*
155     * If an ENGINE handled this method look it up. Othewise use internal
156     * tables.
157     */
158
159    if (e)
160        pmeth = ENGINE_get_pkey_meth(e, id);
161    else
162#endif
163        pmeth = EVP_PKEY_meth_find(id);
164
165    if (pmeth == NULL) {
166        EVPerr(EVP_F_INT_CTX_NEW, EVP_R_UNSUPPORTED_ALGORITHM);
167        return NULL;
168    }
169
170    ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX));
171    if (!ret) {
172#ifndef OPENSSL_NO_ENGINE
173        if (e)
174            ENGINE_finish(e);
175#endif
176        EVPerr(EVP_F_INT_CTX_NEW, ERR_R_MALLOC_FAILURE);
177        return NULL;
178    }
179    ret->engine = e;
180    ret->pmeth = pmeth;
181    ret->operation = EVP_PKEY_OP_UNDEFINED;
182    ret->pkey = pkey;
183    ret->peerkey = NULL;
184    ret->pkey_gencb = 0;
185    if (pkey)
186        CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
187    ret->data = NULL;
188
189    if (pmeth->init) {
190        if (pmeth->init(ret) <= 0) {
191            EVP_PKEY_CTX_free(ret);
192            return NULL;
193        }
194    }
195
196    return ret;
197}
198
199EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags)
200{
201    EVP_PKEY_METHOD *pmeth;
202    pmeth = OPENSSL_malloc(sizeof(EVP_PKEY_METHOD));
203    if (!pmeth)
204        return NULL;
205
206    memset(pmeth, 0, sizeof(EVP_PKEY_METHOD));
207
208    pmeth->pkey_id = id;
209    pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC;
210
211    pmeth->init = 0;
212    pmeth->copy = 0;
213    pmeth->cleanup = 0;
214    pmeth->paramgen_init = 0;
215    pmeth->paramgen = 0;
216    pmeth->keygen_init = 0;
217    pmeth->keygen = 0;
218    pmeth->sign_init = 0;
219    pmeth->sign = 0;
220    pmeth->verify_init = 0;
221    pmeth->verify = 0;
222    pmeth->verify_recover_init = 0;
223    pmeth->verify_recover = 0;
224    pmeth->signctx_init = 0;
225    pmeth->signctx = 0;
226    pmeth->verifyctx_init = 0;
227    pmeth->verifyctx = 0;
228    pmeth->encrypt_init = 0;
229    pmeth->encrypt = 0;
230    pmeth->decrypt_init = 0;
231    pmeth->decrypt = 0;
232    pmeth->derive_init = 0;
233    pmeth->derive = 0;
234    pmeth->ctrl = 0;
235    pmeth->ctrl_str = 0;
236
237    return pmeth;
238}
239
240void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags,
241                             const EVP_PKEY_METHOD *meth)
242{
243    if (ppkey_id)
244        *ppkey_id = meth->pkey_id;
245    if (pflags)
246        *pflags = meth->flags;
247}
248
249void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src)
250{
251
252    dst->init = src->init;
253    dst->copy = src->copy;
254    dst->cleanup = src->cleanup;
255
256    dst->paramgen_init = src->paramgen_init;
257    dst->paramgen = src->paramgen;
258
259    dst->keygen_init = src->keygen_init;
260    dst->keygen = src->keygen;
261
262    dst->sign_init = src->sign_init;
263    dst->sign = src->sign;
264
265    dst->verify_init = src->verify_init;
266    dst->verify = src->verify;
267
268    dst->verify_recover_init = src->verify_recover_init;
269    dst->verify_recover = src->verify_recover;
270
271    dst->signctx_init = src->signctx_init;
272    dst->signctx = src->signctx;
273
274    dst->verifyctx_init = src->verifyctx_init;
275    dst->verifyctx = src->verifyctx;
276
277    dst->encrypt_init = src->encrypt_init;
278    dst->encrypt = src->encrypt;
279
280    dst->decrypt_init = src->decrypt_init;
281    dst->decrypt = src->decrypt;
282
283    dst->derive_init = src->derive_init;
284    dst->derive = src->derive;
285
286    dst->ctrl = src->ctrl;
287    dst->ctrl_str = src->ctrl_str;
288}
289
290void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth)
291{
292    if (pmeth && (pmeth->flags & EVP_PKEY_FLAG_DYNAMIC))
293        OPENSSL_free(pmeth);
294}
295
296EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e)
297{
298    return int_ctx_new(pkey, e, -1);
299}
300
301EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e)
302{
303    return int_ctx_new(NULL, e, id);
304}
305
306EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx)
307{
308    EVP_PKEY_CTX *rctx;
309    if (!pctx->pmeth || !pctx->pmeth->copy)
310        return NULL;
311#ifndef OPENSSL_NO_ENGINE
312    /* Make sure it's safe to copy a pkey context using an ENGINE */
313    if (pctx->engine && !ENGINE_init(pctx->engine)) {
314        EVPerr(EVP_F_EVP_PKEY_CTX_DUP, ERR_R_ENGINE_LIB);
315        return 0;
316    }
317#endif
318    rctx = OPENSSL_malloc(sizeof(EVP_PKEY_CTX));
319    if (!rctx)
320        return NULL;
321
322    rctx->pmeth = pctx->pmeth;
323#ifndef OPENSSL_NO_ENGINE
324    rctx->engine = pctx->engine;
325#endif
326
327    if (pctx->pkey)
328        CRYPTO_add(&pctx->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
329
330    rctx->pkey = pctx->pkey;
331
332    if (pctx->peerkey)
333        CRYPTO_add(&pctx->peerkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
334
335    rctx->peerkey = pctx->peerkey;
336
337    rctx->data = NULL;
338    rctx->app_data = NULL;
339    rctx->operation = pctx->operation;
340
341    if (pctx->pmeth->copy(rctx, pctx) > 0)
342        return rctx;
343
344    EVP_PKEY_CTX_free(rctx);
345    return NULL;
346
347}
348
349int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth)
350{
351    if (app_pkey_methods == NULL) {
352        app_pkey_methods = sk_EVP_PKEY_METHOD_new(pmeth_cmp);
353        if (!app_pkey_methods)
354            return 0;
355    }
356    if (!sk_EVP_PKEY_METHOD_push(app_pkey_methods, pmeth))
357        return 0;
358    sk_EVP_PKEY_METHOD_sort(app_pkey_methods);
359    return 1;
360}
361
362void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx)
363{
364    if (ctx == NULL)
365        return;
366    if (ctx->pmeth && ctx->pmeth->cleanup)
367        ctx->pmeth->cleanup(ctx);
368    if (ctx->pkey)
369        EVP_PKEY_free(ctx->pkey);
370    if (ctx->peerkey)
371        EVP_PKEY_free(ctx->peerkey);
372#ifndef OPENSSL_NO_ENGINE
373    if (ctx->engine)
374        /*
375         * The EVP_PKEY_CTX we used belongs to an ENGINE, release the
376         * functional reference we held for this reason.
377         */
378        ENGINE_finish(ctx->engine);
379#endif
380    OPENSSL_free(ctx);
381}
382
383int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
384                      int cmd, int p1, void *p2)
385{
386    int ret;
387    if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) {
388        EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
389        return -2;
390    }
391    if ((keytype != -1) && (ctx->pmeth->pkey_id != keytype))
392        return -1;
393
394    if (ctx->operation == EVP_PKEY_OP_UNDEFINED) {
395        EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_NO_OPERATION_SET);
396        return -1;
397    }
398
399    if ((optype != -1) && !(ctx->operation & optype)) {
400        EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_INVALID_OPERATION);
401        return -1;
402    }
403
404    ret = ctx->pmeth->ctrl(ctx, cmd, p1, p2);
405
406    if (ret == -2)
407        EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
408
409    return ret;
410
411}
412
413int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx,
414                          const char *name, const char *value)
415{
416    if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl_str) {
417        EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED);
418        return -2;
419    }
420    if (!strcmp(name, "digest")) {
421        const EVP_MD *md;
422        if (!value || !(md = EVP_get_digestbyname(value))) {
423            EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR, EVP_R_INVALID_DIGEST);
424            return 0;
425        }
426        return EVP_PKEY_CTX_set_signature_md(ctx, md);
427    }
428    return ctx->pmeth->ctrl_str(ctx, name, value);
429}
430
431int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx)
432{
433    return ctx->operation;
434}
435
436void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen)
437{
438    ctx->keygen_info = dat;
439    ctx->keygen_info_count = datlen;
440}
441
442void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data)
443{
444    ctx->data = data;
445}
446
447void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx)
448{
449    return ctx->data;
450}
451
452EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx)
453{
454    return ctx->pkey;
455}
456
457EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx)
458{
459    return ctx->peerkey;
460}
461
462void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data)
463{
464    ctx->app_data = data;
465}
466
467void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx)
468{
469    return ctx->app_data;
470}
471
472void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth,
473                            int (*init) (EVP_PKEY_CTX *ctx))
474{
475    pmeth->init = init;
476}
477
478void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth,
479                            int (*copy) (EVP_PKEY_CTX *dst,
480                                         EVP_PKEY_CTX *src))
481{
482    pmeth->copy = copy;
483}
484
485void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth,
486                               void (*cleanup) (EVP_PKEY_CTX *ctx))
487{
488    pmeth->cleanup = cleanup;
489}
490
491void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth,
492                                int (*paramgen_init) (EVP_PKEY_CTX *ctx),
493                                int (*paramgen) (EVP_PKEY_CTX *ctx,
494                                                 EVP_PKEY *pkey))
495{
496    pmeth->paramgen_init = paramgen_init;
497    pmeth->paramgen = paramgen;
498}
499
500void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth,
501                              int (*keygen_init) (EVP_PKEY_CTX *ctx),
502                              int (*keygen) (EVP_PKEY_CTX *ctx,
503                                             EVP_PKEY *pkey))
504{
505    pmeth->keygen_init = keygen_init;
506    pmeth->keygen = keygen;
507}
508
509void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth,
510                            int (*sign_init) (EVP_PKEY_CTX *ctx),
511                            int (*sign) (EVP_PKEY_CTX *ctx,
512                                         unsigned char *sig, size_t *siglen,
513                                         const unsigned char *tbs,
514                                         size_t tbslen))
515{
516    pmeth->sign_init = sign_init;
517    pmeth->sign = sign;
518}
519
520void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth,
521                              int (*verify_init) (EVP_PKEY_CTX *ctx),
522                              int (*verify) (EVP_PKEY_CTX *ctx,
523                                             const unsigned char *sig,
524                                             size_t siglen,
525                                             const unsigned char *tbs,
526                                             size_t tbslen))
527{
528    pmeth->verify_init = verify_init;
529    pmeth->verify = verify;
530}
531
532void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth,
533                                      int (*verify_recover_init) (EVP_PKEY_CTX
534                                                                  *ctx),
535                                      int (*verify_recover) (EVP_PKEY_CTX
536                                                             *ctx,
537                                                             unsigned char
538                                                             *sig,
539                                                             size_t *siglen,
540                                                             const unsigned
541                                                             char *tbs,
542                                                             size_t tbslen))
543{
544    pmeth->verify_recover_init = verify_recover_init;
545    pmeth->verify_recover = verify_recover;
546}
547
548void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth,
549                               int (*signctx_init) (EVP_PKEY_CTX *ctx,
550                                                    EVP_MD_CTX *mctx),
551                               int (*signctx) (EVP_PKEY_CTX *ctx,
552                                               unsigned char *sig,
553                                               size_t *siglen,
554                                               EVP_MD_CTX *mctx))
555{
556    pmeth->signctx_init = signctx_init;
557    pmeth->signctx = signctx;
558}
559
560void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth,
561                                 int (*verifyctx_init) (EVP_PKEY_CTX *ctx,
562                                                        EVP_MD_CTX *mctx),
563                                 int (*verifyctx) (EVP_PKEY_CTX *ctx,
564                                                   const unsigned char *sig,
565                                                   int siglen,
566                                                   EVP_MD_CTX *mctx))
567{
568    pmeth->verifyctx_init = verifyctx_init;
569    pmeth->verifyctx = verifyctx;
570}
571
572void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth,
573                               int (*encrypt_init) (EVP_PKEY_CTX *ctx),
574                               int (*encryptfn) (EVP_PKEY_CTX *ctx,
575                                                 unsigned char *out,
576                                                 size_t *outlen,
577                                                 const unsigned char *in,
578                                                 size_t inlen))
579{
580    pmeth->encrypt_init = encrypt_init;
581    pmeth->encrypt = encryptfn;
582}
583
584void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth,
585                               int (*decrypt_init) (EVP_PKEY_CTX *ctx),
586                               int (*decrypt) (EVP_PKEY_CTX *ctx,
587                                               unsigned char *out,
588                                               size_t *outlen,
589                                               const unsigned char *in,
590                                               size_t inlen))
591{
592    pmeth->decrypt_init = decrypt_init;
593    pmeth->decrypt = decrypt;
594}
595
596void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth,
597                              int (*derive_init) (EVP_PKEY_CTX *ctx),
598                              int (*derive) (EVP_PKEY_CTX *ctx,
599                                             unsigned char *key,
600                                             size_t *keylen))
601{
602    pmeth->derive_init = derive_init;
603    pmeth->derive = derive;
604}
605
606void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
607                            int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1,
608                                         void *p2),
609                            int (*ctrl_str) (EVP_PKEY_CTX *ctx,
610                                             const char *type,
611                                             const char *value))
612{
613    pmeth->ctrl = ctrl;
614    pmeth->ctrl_str = ctrl_str;
615}
616