Coverage Report

Created: 2022-08-24 06:30

/src/libressl/crypto/dsa/dsa_pmeth.c
Line
Count
Source (jump to first uncovered line)
1
/* $OpenBSD: dsa_pmeth.c,v 1.13 2021/12/04 16:08:32 tb Exp $ */
2
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3
 * project 2006.
4
 */
5
/* ====================================================================
6
 * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 *
12
 * 1. Redistributions of source code must retain the above copyright
13
 *    notice, this list of conditions and the following disclaimer. 
14
 *
15
 * 2. Redistributions in binary form must reproduce the above copyright
16
 *    notice, this list of conditions and the following disclaimer in
17
 *    the documentation and/or other materials provided with the
18
 *    distribution.
19
 *
20
 * 3. All advertising materials mentioning features or use of this
21
 *    software must display the following acknowledgment:
22
 *    "This product includes software developed by the OpenSSL Project
23
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24
 *
25
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26
 *    endorse or promote products derived from this software without
27
 *    prior written permission. For written permission, please contact
28
 *    licensing@OpenSSL.org.
29
 *
30
 * 5. Products derived from this software may not be called "OpenSSL"
31
 *    nor may "OpenSSL" appear in their names without prior written
32
 *    permission of the OpenSSL Project.
33
 *
34
 * 6. Redistributions of any form whatsoever must retain the following
35
 *    acknowledgment:
36
 *    "This product includes software developed by the OpenSSL Project
37
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38
 *
39
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50
 * OF THE POSSIBILITY OF SUCH DAMAGE.
51
 * ====================================================================
52
 *
53
 * This product includes cryptographic software written by Eric Young
54
 * (eay@cryptsoft.com).  This product includes software written by Tim
55
 * Hudson (tjh@cryptsoft.com).
56
 *
57
 */
58
59
#include <limits.h>
60
#include <stdio.h>
61
#include <string.h>
62
63
#include <openssl/asn1t.h>
64
#include <openssl/bn.h>
65
#include <openssl/err.h>
66
#include <openssl/evp.h>
67
#include <openssl/x509.h>
68
69
#include "bn_lcl.h"
70
#include "dsa_locl.h"
71
#include "evp_locl.h"
72
73
/* DSA pkey context structure */
74
75
typedef struct {
76
  /* Parameter gen parameters */
77
  int nbits;    /* size of p in bits (default: 1024) */
78
  int qbits;    /* size of q in bits (default: 160)  */
79
  const EVP_MD *pmd;  /* MD for parameter generation */
80
  /* Keygen callback info */
81
  int gentmp[2];
82
  /* message digest */
83
  const EVP_MD *md; /* MD for the signature */
84
} DSA_PKEY_CTX;
85
86
static int
87
pkey_dsa_init(EVP_PKEY_CTX *ctx)
88
0
{
89
0
  DSA_PKEY_CTX *dctx;
90
91
0
  dctx = malloc(sizeof(DSA_PKEY_CTX));
92
0
  if (!dctx)
93
0
    return 0;
94
0
  dctx->nbits = 1024;
95
0
  dctx->qbits = 160;
96
0
  dctx->pmd = NULL;
97
0
  dctx->md = NULL;
98
99
0
  ctx->data = dctx;
100
0
  ctx->keygen_info = dctx->gentmp;
101
0
  ctx->keygen_info_count = 2;
102
  
103
0
  return 1;
104
0
}
105
106
static int
107
pkey_dsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
108
0
{
109
0
  DSA_PKEY_CTX *dctx, *sctx;
110
111
0
  if (!pkey_dsa_init(dst))
112
0
    return 0;
113
0
        sctx = src->data;
114
0
  dctx = dst->data;
115
0
  dctx->nbits = sctx->nbits;
116
0
  dctx->qbits = sctx->qbits;
117
0
  dctx->pmd = sctx->pmd;
118
0
  dctx->md  = sctx->md;
119
0
  return 1;
120
0
}
121
122
static void
123
pkey_dsa_cleanup(EVP_PKEY_CTX *ctx)
124
0
{
125
0
  DSA_PKEY_CTX *dctx = ctx->data;
126
127
0
  free(dctx);
128
0
}
129
130
static int
131
pkey_dsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
132
    const unsigned char *tbs, size_t tbslen)
133
0
{
134
0
  int ret, type;
135
0
  unsigned int sltmp;
136
0
  DSA_PKEY_CTX *dctx = ctx->data;
137
0
  DSA *dsa = ctx->pkey->pkey.dsa;
138
139
0
  if (dctx->md)
140
0
    type = EVP_MD_type(dctx->md);
141
0
  else
142
0
    type = NID_sha1;
143
144
0
  ret = DSA_sign(type, tbs, tbslen, sig, &sltmp, dsa);
145
146
0
  if (ret <= 0)
147
0
    return ret;
148
0
  *siglen = sltmp;
149
0
  return 1;
150
0
}
151
152
static int
153
pkey_dsa_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen,
154
    const unsigned char *tbs, size_t tbslen)
155
0
{
156
0
  int ret, type;
157
0
  DSA_PKEY_CTX *dctx = ctx->data;
158
0
  DSA *dsa = ctx->pkey->pkey.dsa;
159
160
0
  if (dctx->md)
161
0
    type = EVP_MD_type(dctx->md);
162
0
  else
163
0
    type = NID_sha1;
164
165
0
  ret = DSA_verify(type, tbs, tbslen, sig, siglen, dsa);
166
167
0
  return ret;
168
0
}
169
170
static int
171
pkey_dsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
172
0
{
173
0
  DSA_PKEY_CTX *dctx = ctx->data;
174
175
0
  switch (type) {
176
0
  case EVP_PKEY_CTRL_DSA_PARAMGEN_BITS:
177
0
    if (p1 < 256)
178
0
      return -2;
179
0
    dctx->nbits = p1;
180
0
    return 1;
181
182
0
  case EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS:
183
0
    if (p1 != 160 && p1 != 224 && p1 && p1 != 256)
184
0
      return -2;
185
0
    dctx->qbits = p1;
186
0
    return 1;
187
188
0
  case EVP_PKEY_CTRL_DSA_PARAMGEN_MD:
189
0
    switch (EVP_MD_type((const EVP_MD *)p2)) {
190
0
    case NID_sha1:
191
0
    case NID_sha224:
192
0
    case NID_sha256:
193
0
      break;
194
0
    default:
195
0
      DSAerror(DSA_R_INVALID_DIGEST_TYPE);
196
0
      return 0;
197
0
    }
198
0
    dctx->md = p2;
199
0
    return 1;
200
201
0
  case EVP_PKEY_CTRL_MD:
202
0
    switch (EVP_MD_type((const EVP_MD *)p2)) {
203
0
    case NID_sha1:
204
0
    case NID_dsa:
205
0
    case NID_dsaWithSHA:
206
0
    case NID_sha224:
207
0
    case NID_sha256:
208
0
    case NID_sha384:
209
0
    case NID_sha512:
210
0
      break;
211
0
    default:
212
0
      DSAerror(DSA_R_INVALID_DIGEST_TYPE);
213
0
      return 0;
214
0
    }
215
0
    dctx->md = p2;
216
0
    return 1;
217
218
0
  case EVP_PKEY_CTRL_GET_MD:
219
0
    *(const EVP_MD **)p2 = dctx->md;
220
0
    return 1;
221
222
0
  case EVP_PKEY_CTRL_DIGESTINIT:
223
0
  case EVP_PKEY_CTRL_PKCS7_SIGN:
224
0
  case EVP_PKEY_CTRL_CMS_SIGN:
225
0
    return 1;
226
    
227
0
  case EVP_PKEY_CTRL_PEER_KEY:
228
0
    DSAerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
229
0
    return -2;  
230
0
  default:
231
0
    return -2;
232
0
  }
233
0
}
234
      
235
static int
236
pkey_dsa_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value)
237
0
{
238
0
  long lval;
239
0
  char *ep;
240
241
0
  if (!strcmp(type, "dsa_paramgen_bits")) {
242
0
    int nbits;
243
244
0
    errno = 0;
245
0
    lval = strtol(value, &ep, 10);
246
0
    if (value[0] == '\0' || *ep != '\0')
247
0
      goto not_a_number;
248
0
    if ((errno == ERANGE &&
249
0
        (lval == LONG_MAX || lval == LONG_MIN)) ||
250
0
        (lval > INT_MAX || lval < INT_MIN))
251
0
      goto out_of_range;
252
0
    nbits = lval;
253
0
    return EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits);
254
0
  } else if (!strcmp(type, "dsa_paramgen_q_bits")) {
255
0
    int qbits;
256
257
0
    errno = 0;
258
0
    lval = strtol(value, &ep, 10);
259
0
    if (value[0] == '\0' || *ep != '\0')
260
0
      goto not_a_number;
261
0
    if ((errno == ERANGE &&
262
0
        (lval == LONG_MAX || lval == LONG_MIN)) ||
263
0
        (lval > INT_MAX || lval < INT_MIN))
264
0
      goto out_of_range;
265
0
    qbits = lval;
266
0
    return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA,
267
0
        EVP_PKEY_OP_PARAMGEN, EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS,
268
0
        qbits, NULL);
269
0
  } else if (!strcmp(type, "dsa_paramgen_md")) {
270
0
    return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA,
271
0
        EVP_PKEY_OP_PARAMGEN, EVP_PKEY_CTRL_DSA_PARAMGEN_MD, 0, 
272
0
        (void *)EVP_get_digestbyname(value));
273
0
  }
274
0
not_a_number:
275
0
out_of_range:
276
0
  return -2;
277
0
}
278
279
static int
280
pkey_dsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
281
0
{
282
0
  DSA *dsa = NULL;
283
0
  DSA_PKEY_CTX *dctx = ctx->data;
284
0
  BN_GENCB *pcb, cb;
285
0
  int ret;
286
287
0
  if (ctx->pkey_gencb) {
288
0
    pcb = &cb;
289
0
    evp_pkey_set_cb_translate(pcb, ctx);
290
0
  } else
291
0
    pcb = NULL;
292
0
  dsa = DSA_new();
293
0
  if (!dsa)
294
0
    return 0;
295
0
  ret = dsa_builtin_paramgen(dsa, dctx->nbits, dctx->qbits, dctx->pmd,
296
0
      NULL, 0, NULL, NULL, NULL, pcb);
297
0
  if (ret)
298
0
    EVP_PKEY_assign_DSA(pkey, dsa);
299
0
  else
300
0
    DSA_free(dsa);
301
0
  return ret;
302
0
}
303
304
static int
305
pkey_dsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
306
0
{
307
0
  DSA *dsa = NULL;
308
309
0
  if (ctx->pkey == NULL) {
310
0
    DSAerror(DSA_R_NO_PARAMETERS_SET);
311
0
    return 0;
312
0
  }
313
0
  dsa = DSA_new();
314
0
  if (!dsa)
315
0
    return 0;
316
0
  EVP_PKEY_assign_DSA(pkey, dsa);
317
  /* Note: if error return, pkey is freed by parent routine */
318
0
  if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
319
0
    return 0;
320
0
  return DSA_generate_key(pkey->pkey.dsa);
321
0
}
322
323
const EVP_PKEY_METHOD dsa_pkey_meth = {
324
  .pkey_id = EVP_PKEY_DSA,
325
  .flags = EVP_PKEY_FLAG_AUTOARGLEN,
326
327
  .init = pkey_dsa_init,
328
  .copy = pkey_dsa_copy,
329
  .cleanup = pkey_dsa_cleanup,
330
331
  .paramgen = pkey_dsa_paramgen,
332
333
  .keygen = pkey_dsa_keygen,
334
335
  .sign = pkey_dsa_sign,
336
337
  .verify = pkey_dsa_verify,
338
339
  .ctrl = pkey_dsa_ctrl,
340
  .ctrl_str = pkey_dsa_ctrl_str
341
};