Copyright consolidation 04/10
[openssl.git] / crypto / evp / m_sigver.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/evp.h>
13 #include <openssl/objects.h>
14 #include <openssl/x509.h>
15 #include "internal/evp_int.h"
16 #include "evp_locl.h"
17
18 static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
19                           const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey,
20                           int ver)
21 {
22     if (ctx->pctx == NULL)
23         ctx->pctx = EVP_PKEY_CTX_new(pkey, e);
24     if (ctx->pctx == NULL)
25         return 0;
26
27     if (!(ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)) {
28
29         if (type == NULL) {
30             int def_nid;
31             if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0)
32                 type = EVP_get_digestbynid(def_nid);
33         }
34
35         if (type == NULL) {
36             EVPerr(EVP_F_DO_SIGVER_INIT, EVP_R_NO_DEFAULT_DIGEST);
37             return 0;
38         }
39     }
40
41     if (ver) {
42         if (ctx->pctx->pmeth->verifyctx_init) {
43             if (ctx->pctx->pmeth->verifyctx_init(ctx->pctx, ctx) <= 0)
44                 return 0;
45             ctx->pctx->operation = EVP_PKEY_OP_VERIFYCTX;
46         } else if (EVP_PKEY_verify_init(ctx->pctx) <= 0)
47             return 0;
48     } else {
49         if (ctx->pctx->pmeth->signctx_init) {
50             if (ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx) <= 0)
51                 return 0;
52             ctx->pctx->operation = EVP_PKEY_OP_SIGNCTX;
53         } else if (EVP_PKEY_sign_init(ctx->pctx) <= 0)
54             return 0;
55     }
56     if (EVP_PKEY_CTX_set_signature_md(ctx->pctx, type) <= 0)
57         return 0;
58     if (pctx)
59         *pctx = ctx->pctx;
60     if (ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)
61         return 1;
62     if (!EVP_DigestInit_ex(ctx, type, e))
63         return 0;
64     return 1;
65 }
66
67 int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
68                        const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey)
69 {
70     return do_sigver_init(ctx, pctx, type, e, pkey, 0);
71 }
72
73 int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
74                          const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey)
75 {
76     return do_sigver_init(ctx, pctx, type, e, pkey, 1);
77 }
78
79 int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
80                         size_t *siglen)
81 {
82     int sctx = 0, r = 0;
83     EVP_PKEY_CTX *pctx = ctx->pctx;
84     if (pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) {
85         if (!sigret)
86             return pctx->pmeth->signctx(pctx, sigret, siglen, ctx);
87         if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE)
88             r = pctx->pmeth->signctx(pctx, sigret, siglen, ctx);
89         else {
90             EVP_PKEY_CTX *dctx = EVP_PKEY_CTX_dup(ctx->pctx);
91             if (!dctx)
92                 return 0;
93             r = dctx->pmeth->signctx(dctx, sigret, siglen, ctx);
94             EVP_PKEY_CTX_free(dctx);
95         }
96         return r;
97     }
98     if (pctx->pmeth->signctx)
99         sctx = 1;
100     else
101         sctx = 0;
102     if (sigret) {
103         unsigned char md[EVP_MAX_MD_SIZE];
104         unsigned int mdlen = 0;
105         if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) {
106             if (sctx)
107                 r = ctx->pctx->pmeth->signctx(ctx->pctx, sigret, siglen, ctx);
108             else
109                 r = EVP_DigestFinal_ex(ctx, md, &mdlen);
110         } else {
111             EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new();
112             if (tmp_ctx == NULL || !EVP_MD_CTX_copy_ex(tmp_ctx, ctx))
113                 return 0;
114             if (sctx)
115                 r = tmp_ctx->pctx->pmeth->signctx(tmp_ctx->pctx,
116                                                   sigret, siglen, tmp_ctx);
117             else
118                 r = EVP_DigestFinal_ex(tmp_ctx, md, &mdlen);
119             EVP_MD_CTX_free(tmp_ctx);
120         }
121         if (sctx || !r)
122             return r;
123         if (EVP_PKEY_sign(ctx->pctx, sigret, siglen, md, mdlen) <= 0)
124             return 0;
125     } else {
126         if (sctx) {
127             if (pctx->pmeth->signctx(pctx, sigret, siglen, ctx) <= 0)
128                 return 0;
129         } else {
130             int s = EVP_MD_size(ctx->digest);
131             if (s < 0 || EVP_PKEY_sign(pctx, sigret, siglen, NULL, s) <= 0)
132                 return 0;
133         }
134     }
135     return 1;
136 }
137
138 int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
139                           size_t siglen)
140 {
141     unsigned char md[EVP_MAX_MD_SIZE];
142     int r = 0;
143     unsigned int mdlen = 0;
144     int vctx = 0;
145
146     if (ctx->pctx->pmeth->verifyctx)
147         vctx = 1;
148     else
149         vctx = 0;
150     if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) {
151         if (vctx) {
152             r = ctx->pctx->pmeth->verifyctx(ctx->pctx, sig, siglen, ctx);
153         } else
154             r = EVP_DigestFinal_ex(ctx, md, &mdlen);
155     } else {
156         EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new();
157         if (tmp_ctx == NULL || !EVP_MD_CTX_copy_ex(tmp_ctx, ctx))
158             return -1;
159         if (vctx) {
160             r = tmp_ctx->pctx->pmeth->verifyctx(tmp_ctx->pctx,
161                                                 sig, siglen, tmp_ctx);
162         } else
163             r = EVP_DigestFinal_ex(tmp_ctx, md, &mdlen);
164         EVP_MD_CTX_free(tmp_ctx);
165     }
166     if (vctx || !r)
167         return r;
168     return EVP_PKEY_verify(ctx->pctx, sig, siglen, md, mdlen);
169 }