Coverage Report

Created: 2018-08-29 13:53

/src/openssl/crypto/evp/m_sigver.c
Line
Count
Source (jump to first uncovered line)
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 update(EVP_MD_CTX *ctx, const void *data, size_t datalen)
19
0
{
20
0
    EVPerr(EVP_F_UPDATE, EVP_R_ONLY_ONESHOT_SUPPORTED);
21
0
    return 0;
22
0
}
23
24
static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
25
                          const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey,
26
                          int ver)
27
0
{
28
0
    if (ctx->pctx == NULL)
29
0
        ctx->pctx = EVP_PKEY_CTX_new(pkey, e);
30
0
    if (ctx->pctx == NULL)
31
0
        return 0;
32
0
33
0
    if (!(ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)) {
34
0
35
0
        if (type == NULL) {
36
0
            int def_nid;
37
0
            if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0)
38
0
                type = EVP_get_digestbynid(def_nid);
39
0
        }
40
0
41
0
        if (type == NULL) {
42
0
            EVPerr(EVP_F_DO_SIGVER_INIT, EVP_R_NO_DEFAULT_DIGEST);
43
0
            return 0;
44
0
        }
45
0
    }
46
0
47
0
    if (ver) {
48
0
        if (ctx->pctx->pmeth->verifyctx_init) {
49
0
            if (ctx->pctx->pmeth->verifyctx_init(ctx->pctx, ctx) <= 0)
50
0
                return 0;
51
0
            ctx->pctx->operation = EVP_PKEY_OP_VERIFYCTX;
52
0
        } else if (ctx->pctx->pmeth->digestverify != 0) {
53
0
            ctx->pctx->operation = EVP_PKEY_OP_VERIFY;
54
0
            ctx->update = update;
55
0
        } else if (EVP_PKEY_verify_init(ctx->pctx) <= 0) {
56
0
            return 0;
57
0
        }
58
0
    } else {
59
0
        if (ctx->pctx->pmeth->signctx_init) {
60
0
            if (ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx) <= 0)
61
0
                return 0;
62
0
            ctx->pctx->operation = EVP_PKEY_OP_SIGNCTX;
63
0
        } else if (ctx->pctx->pmeth->digestsign != 0) {
64
0
            ctx->pctx->operation = EVP_PKEY_OP_SIGN;
65
0
            ctx->update = update;
66
0
        } else if (EVP_PKEY_sign_init(ctx->pctx) <= 0) {
67
0
            return 0;
68
0
        }
69
0
    }
70
0
    if (EVP_PKEY_CTX_set_signature_md(ctx->pctx, type) <= 0)
71
0
        return 0;
72
0
    if (pctx)
73
0
        *pctx = ctx->pctx;
74
0
    if (ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)
75
0
        return 1;
76
0
    if (!EVP_DigestInit_ex(ctx, type, e))
77
0
        return 0;
78
0
    return 1;
79
0
}
80
81
int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
82
                       const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey)
83
0
{
84
0
    return do_sigver_init(ctx, pctx, type, e, pkey, 0);
85
0
}
86
87
int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
88
                         const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey)
89
0
{
90
0
    return do_sigver_init(ctx, pctx, type, e, pkey, 1);
91
0
}
92
93
int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
94
                        size_t *siglen)
95
0
{
96
0
    int sctx = 0, r = 0;
97
0
    EVP_PKEY_CTX *pctx = ctx->pctx;
98
0
    if (pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) {
99
0
        if (!sigret)
100
0
            return pctx->pmeth->signctx(pctx, sigret, siglen, ctx);
101
0
        if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE)
102
0
            r = pctx->pmeth->signctx(pctx, sigret, siglen, ctx);
103
0
        else {
104
0
            EVP_PKEY_CTX *dctx = EVP_PKEY_CTX_dup(ctx->pctx);
105
0
            if (!dctx)
106
0
                return 0;
107
0
            r = dctx->pmeth->signctx(dctx, sigret, siglen, ctx);
108
0
            EVP_PKEY_CTX_free(dctx);
109
0
        }
110
0
        return r;
111
0
    }
112
0
    if (pctx->pmeth->signctx)
113
0
        sctx = 1;
114
0
    else
115
0
        sctx = 0;
116
0
    if (sigret) {
117
0
        unsigned char md[EVP_MAX_MD_SIZE];
118
0
        unsigned int mdlen = 0;
119
0
        if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) {
120
0
            if (sctx)
121
0
                r = ctx->pctx->pmeth->signctx(ctx->pctx, sigret, siglen, ctx);
122
0
            else
123
0
                r = EVP_DigestFinal_ex(ctx, md, &mdlen);
124
0
        } else {
125
0
            EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new();
126
0
            if (tmp_ctx == NULL)
127
0
                return 0;
128
0
            if (!EVP_MD_CTX_copy_ex(tmp_ctx, ctx)) {
129
0
                EVP_MD_CTX_free(tmp_ctx);
130
0
                return 0;
131
0
            }
132
0
            if (sctx)
133
0
                r = tmp_ctx->pctx->pmeth->signctx(tmp_ctx->pctx,
134
0
                                                  sigret, siglen, tmp_ctx);
135
0
            else
136
0
                r = EVP_DigestFinal_ex(tmp_ctx, md, &mdlen);
137
0
            EVP_MD_CTX_free(tmp_ctx);
138
0
        }
139
0
        if (sctx || !r)
140
0
            return r;
141
0
        if (EVP_PKEY_sign(ctx->pctx, sigret, siglen, md, mdlen) <= 0)
142
0
            return 0;
143
0
    } else {
144
0
        if (sctx) {
145
0
            if (pctx->pmeth->signctx(pctx, sigret, siglen, ctx) <= 0)
146
0
                return 0;
147
0
        } else {
148
0
            int s = EVP_MD_size(ctx->digest);
149
0
            if (s < 0 || EVP_PKEY_sign(pctx, sigret, siglen, NULL, s) <= 0)
150
0
                return 0;
151
0
        }
152
0
    }
153
0
    return 1;
154
0
}
155
156
int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen,
157
                   const unsigned char *tbs, size_t tbslen)
158
0
{
159
0
    if (ctx->pctx->pmeth->digestsign != NULL)
160
0
        return ctx->pctx->pmeth->digestsign(ctx, sigret, siglen, tbs, tbslen);
161
0
    if (sigret != NULL && EVP_DigestSignUpdate(ctx, tbs, tbslen) <= 0)
162
0
        return 0;
163
0
    return EVP_DigestSignFinal(ctx, sigret, siglen);
164
0
}
165
166
int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
167
                          size_t siglen)
168
0
{
169
0
    unsigned char md[EVP_MAX_MD_SIZE];
170
0
    int r = 0;
171
0
    unsigned int mdlen = 0;
172
0
    int vctx = 0;
173
0
174
0
    if (ctx->pctx->pmeth->verifyctx)
175
0
        vctx = 1;
176
0
    else
177
0
        vctx = 0;
178
0
    if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) {
179
0
        if (vctx) {
180
0
            r = ctx->pctx->pmeth->verifyctx(ctx->pctx, sig, siglen, ctx);
181
0
        } else
182
0
            r = EVP_DigestFinal_ex(ctx, md, &mdlen);
183
0
    } else {
184
0
        EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new();
185
0
        if (tmp_ctx == NULL)
186
0
            return -1;
187
0
        if (!EVP_MD_CTX_copy_ex(tmp_ctx, ctx)) {
188
0
            EVP_MD_CTX_free(tmp_ctx);
189
0
            return -1;
190
0
        }
191
0
        if (vctx) {
192
0
            r = tmp_ctx->pctx->pmeth->verifyctx(tmp_ctx->pctx,
193
0
                                                sig, siglen, tmp_ctx);
194
0
        } else
195
0
            r = EVP_DigestFinal_ex(tmp_ctx, md, &mdlen);
196
0
        EVP_MD_CTX_free(tmp_ctx);
197
0
    }
198
0
    if (vctx || !r)
199
0
        return r;
200
0
    return EVP_PKEY_verify(ctx->pctx, sig, siglen, md, mdlen);
201
0
}
202
203
int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret,
204
                     size_t siglen, const unsigned char *tbs, size_t tbslen)
205
0
{
206
0
    if (ctx->pctx->pmeth->digestverify != NULL)
207
0
        return ctx->pctx->pmeth->digestverify(ctx, sigret, siglen, tbs, tbslen);
208
0
    if (EVP_DigestVerifyUpdate(ctx, tbs, tbslen) <= 0)
209
0
        return -1;
210
0
    return EVP_DigestVerifyFinal(ctx, sigret, siglen);
211
0
}