Coverage Report

Created: 2025-06-13 06:58

/src/openssl31/crypto/dsa/dsa_ameth.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved.
3
 *
4
 * Licensed under the Apache License 2.0 (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
/*
11
 * DSA low level APIs are deprecated for public use, but still ok for
12
 * internal use.
13
 */
14
#include "internal/deprecated.h"
15
16
#include <stdio.h>
17
#include <openssl/x509.h>
18
#include <openssl/asn1.h>
19
#include <openssl/bn.h>
20
#include <openssl/core_names.h>
21
#include <openssl/param_build.h>
22
#include "internal/cryptlib.h"
23
#include "crypto/asn1.h"
24
#include "crypto/dsa.h"
25
#include "crypto/evp.h"
26
#include "internal/ffc.h"
27
#include "dsa_local.h"
28
29
static int dsa_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey)
30
98.9k
{
31
98.9k
    const unsigned char *p, *pm;
32
98.9k
    int pklen, pmlen;
33
98.9k
    int ptype;
34
98.9k
    const void *pval;
35
98.9k
    const ASN1_STRING *pstr;
36
98.9k
    X509_ALGOR *palg;
37
98.9k
    ASN1_INTEGER *public_key = NULL;
38
39
98.9k
    DSA *dsa = NULL;
40
41
98.9k
    if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
42
0
        return 0;
43
98.9k
    X509_ALGOR_get0(NULL, &ptype, &pval, palg);
44
45
98.9k
    if (ptype == V_ASN1_SEQUENCE) {
46
47.1k
        pstr = pval;
47
47.1k
        pm = pstr->data;
48
47.1k
        pmlen = pstr->length;
49
50
47.1k
        if ((dsa = d2i_DSAparams(NULL, &pm, pmlen)) == NULL) {
51
9.85k
            ERR_raise(ERR_LIB_DSA, DSA_R_DECODE_ERROR);
52
9.85k
            goto err;
53
9.85k
        }
54
55
51.7k
    } else if ((ptype == V_ASN1_NULL) || (ptype == V_ASN1_UNDEF)) {
56
21.8k
        if ((dsa = DSA_new()) == NULL) {
57
0
            ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE);
58
0
            goto err;
59
0
        }
60
29.9k
    } else {
61
29.9k
        ERR_raise(ERR_LIB_DSA, DSA_R_PARAMETER_ENCODING_ERROR);
62
29.9k
        goto err;
63
29.9k
    }
64
65
59.1k
    if ((public_key = d2i_ASN1_INTEGER(NULL, &p, pklen)) == NULL) {
66
20.9k
        ERR_raise(ERR_LIB_DSA, DSA_R_DECODE_ERROR);
67
20.9k
        goto err;
68
20.9k
    }
69
70
38.2k
    if ((dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)) == NULL) {
71
0
        ERR_raise(ERR_LIB_DSA, DSA_R_BN_DECODE_ERROR);
72
0
        goto err;
73
0
    }
74
75
38.2k
    dsa->dirty_cnt++;
76
38.2k
    ASN1_INTEGER_free(public_key);
77
38.2k
    EVP_PKEY_assign_DSA(pkey, dsa);
78
38.2k
    return 1;
79
80
60.7k
 err:
81
60.7k
    ASN1_INTEGER_free(public_key);
82
60.7k
    DSA_free(dsa);
83
60.7k
    return 0;
84
85
38.2k
}
86
87
static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
88
0
{
89
0
    DSA *dsa;
90
0
    int ptype;
91
0
    unsigned char *penc = NULL;
92
0
    int penclen;
93
0
    ASN1_STRING *str = NULL;
94
0
    ASN1_INTEGER *pubint = NULL;
95
0
    ASN1_OBJECT *aobj;
96
97
0
    dsa = pkey->pkey.dsa;
98
0
    if (pkey->save_parameters
99
0
        && dsa->params.p != NULL
100
0
        && dsa->params.q != NULL
101
0
        && dsa->params.g != NULL) {
102
0
        str = ASN1_STRING_new();
103
0
        if (str == NULL) {
104
0
            ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE);
105
0
            goto err;
106
0
        }
107
0
        str->length = i2d_DSAparams(dsa, &str->data);
108
0
        if (str->length <= 0) {
109
0
            ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE);
110
0
            goto err;
111
0
        }
112
0
        ptype = V_ASN1_SEQUENCE;
113
0
    } else
114
0
        ptype = V_ASN1_UNDEF;
115
116
0
    pubint = BN_to_ASN1_INTEGER(dsa->pub_key, NULL);
117
118
0
    if (pubint == NULL) {
119
0
        ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE);
120
0
        goto err;
121
0
    }
122
123
0
    penclen = i2d_ASN1_INTEGER(pubint, &penc);
124
0
    ASN1_INTEGER_free(pubint);
125
126
0
    if (penclen <= 0) {
127
0
        ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE);
128
0
        goto err;
129
0
    }
130
131
0
    aobj = OBJ_nid2obj(EVP_PKEY_DSA);
132
0
    if (aobj == NULL)
133
0
        goto err;
134
135
0
    if (X509_PUBKEY_set0_param(pk, aobj, ptype, str, penc, penclen))
136
0
        return 1;
137
138
0
 err:
139
0
    OPENSSL_free(penc);
140
0
    ASN1_STRING_free(str);
141
142
0
    return 0;
143
0
}
144
145
/*
146
 * In PKCS#8 DSA: you just get a private key integer and parameters in the
147
 * AlgorithmIdentifier the pubkey must be recalculated.
148
 */
149
150
static int dsa_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
151
395
{
152
395
    int ret = 0;
153
395
    DSA *dsa = ossl_dsa_key_from_pkcs8(p8, NULL, NULL);
154
155
395
    if (dsa != NULL) {
156
341
        ret = 1;
157
341
        EVP_PKEY_assign_DSA(pkey, dsa);
158
341
    }
159
160
395
    return ret;
161
395
}
162
163
static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
164
0
{
165
0
    ASN1_STRING *params = NULL;
166
0
    ASN1_INTEGER *prkey = NULL;
167
0
    unsigned char *dp = NULL;
168
0
    int dplen;
169
170
0
    if (pkey->pkey.dsa  == NULL|| pkey->pkey.dsa->priv_key == NULL) {
171
0
        ERR_raise(ERR_LIB_DSA, DSA_R_MISSING_PARAMETERS);
172
0
        goto err;
173
0
    }
174
175
0
    params = ASN1_STRING_new();
176
177
0
    if (params == NULL) {
178
0
        ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE);
179
0
        goto err;
180
0
    }
181
182
0
    params->length = i2d_DSAparams(pkey->pkey.dsa, &params->data);
183
0
    if (params->length <= 0) {
184
0
        ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE);
185
0
        goto err;
186
0
    }
187
0
    params->type = V_ASN1_SEQUENCE;
188
189
    /* Get private key into integer */
190
0
    prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL);
191
192
0
    if (prkey == NULL) {
193
0
        ERR_raise(ERR_LIB_DSA, DSA_R_BN_ERROR);
194
0
        goto err;
195
0
    }
196
197
0
    dplen = i2d_ASN1_INTEGER(prkey, &dp);
198
199
0
    ASN1_STRING_clear_free(prkey);
200
201
0
    if (dplen <= 0) {
202
0
        ERR_raise(ERR_LIB_DSA, DSA_R_BN_ERROR);
203
0
        goto err;
204
0
    }
205
206
0
    if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dsa), 0,
207
0
                         V_ASN1_SEQUENCE, params, dp, dplen)) {
208
0
        OPENSSL_clear_free(dp, dplen);
209
0
        goto err;
210
0
    }
211
0
    return 1;
212
213
0
 err:
214
0
    ASN1_STRING_free(params);
215
0
    return 0;
216
0
}
217
218
static int int_dsa_size(const EVP_PKEY *pkey)
219
0
{
220
0
    return DSA_size(pkey->pkey.dsa);
221
0
}
222
223
static int dsa_bits(const EVP_PKEY *pkey)
224
0
{
225
0
    return DSA_bits(pkey->pkey.dsa);
226
0
}
227
228
static int dsa_security_bits(const EVP_PKEY *pkey)
229
0
{
230
0
    return DSA_security_bits(pkey->pkey.dsa);
231
0
}
232
233
static int dsa_missing_parameters(const EVP_PKEY *pkey)
234
25.4k
{
235
25.4k
    DSA *dsa;
236
25.4k
    dsa = pkey->pkey.dsa;
237
25.4k
    return dsa == NULL
238
25.4k
        || dsa->params.p == NULL
239
25.4k
        || dsa->params.q == NULL
240
25.4k
        || dsa->params.g == NULL;
241
25.4k
}
242
243
static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
244
0
{
245
0
    if (to->pkey.dsa == NULL) {
246
0
        to->pkey.dsa = DSA_new();
247
0
        if (to->pkey.dsa == NULL)
248
0
            return 0;
249
0
    }
250
0
    if (!ossl_ffc_params_copy(&to->pkey.dsa->params, &from->pkey.dsa->params))
251
0
        return 0;
252
253
0
    to->pkey.dsa->dirty_cnt++;
254
0
    return 1;
255
0
}
256
257
static int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
258
0
{
259
0
    return ossl_ffc_params_cmp(&a->pkey.dsa->params, &b->pkey.dsa->params, 1);
260
0
}
261
262
static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
263
0
{
264
0
    return BN_cmp(b->pkey.dsa->pub_key, a->pkey.dsa->pub_key) == 0;
265
0
}
266
267
static void int_dsa_free(EVP_PKEY *pkey)
268
256k
{
269
256k
    DSA_free(pkey->pkey.dsa);
270
256k
}
271
272
static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype)
273
355
{
274
355
    int ret = 0;
275
355
    const char *ktype = NULL;
276
355
    const BIGNUM *priv_key, *pub_key;
277
355
    int mod_len = 0;
278
279
355
    if (x->params.p != NULL)
280
355
        mod_len = DSA_bits(x);
281
282
355
    if (ptype == 2)
283
355
        priv_key = x->priv_key;
284
0
    else
285
0
        priv_key = NULL;
286
287
355
    if (ptype > 0)
288
355
        pub_key = x->pub_key;
289
0
    else
290
0
        pub_key = NULL;
291
292
355
    if (ptype == 2)
293
355
        ktype = "Private-Key";
294
0
    else if (ptype == 1)
295
0
        ktype = "Public-Key";
296
0
    else
297
0
        ktype = "DSA-Parameters";
298
299
355
    if (priv_key != NULL) {
300
355
        if (!BIO_indent(bp, off, 128))
301
0
            goto err;
302
355
        if (BIO_printf(bp, "%s: (%d bit)\n", ktype, mod_len) <= 0)
303
0
            goto err;
304
355
    } else {
305
0
        if (BIO_printf(bp, "Public-Key: (%d bit)\n", mod_len) <= 0)
306
0
            goto err;
307
0
    }
308
309
355
    if (!ASN1_bn_print(bp, "priv:", priv_key, NULL, off))
310
0
        goto err;
311
355
    if (!ASN1_bn_print(bp, "pub: ", pub_key, NULL, off))
312
0
        goto err;
313
355
    if (!ossl_ffc_params_print(bp, &x->params, off))
314
0
        goto err;
315
355
    ret = 1;
316
355
 err:
317
355
    return ret;
318
355
}
319
320
static int dsa_param_decode(EVP_PKEY *pkey,
321
                            const unsigned char **pder, int derlen)
322
0
{
323
0
    DSA *dsa;
324
325
0
    if ((dsa = d2i_DSAparams(NULL, pder, derlen)) == NULL)
326
0
        return 0;
327
328
0
    dsa->dirty_cnt++;
329
0
    EVP_PKEY_assign_DSA(pkey, dsa);
330
0
    return 1;
331
0
}
332
333
static int dsa_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
334
0
{
335
0
    return i2d_DSAparams(pkey->pkey.dsa, pder);
336
0
}
337
338
static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
339
                           ASN1_PCTX *ctx)
340
0
{
341
0
    return do_dsa_print(bp, pkey->pkey.dsa, indent, 0);
342
0
}
343
344
static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
345
                         ASN1_PCTX *ctx)
346
0
{
347
0
    return do_dsa_print(bp, pkey->pkey.dsa, indent, 1);
348
0
}
349
350
static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
351
                          ASN1_PCTX *ctx)
352
355
{
353
355
    return do_dsa_print(bp, pkey->pkey.dsa, indent, 2);
354
355
}
355
356
static int old_dsa_priv_decode(EVP_PKEY *pkey,
357
                               const unsigned char **pder, int derlen)
358
1.07k
{
359
1.07k
    DSA *dsa;
360
361
1.07k
    if ((dsa = d2i_DSAPrivateKey(NULL, pder, derlen)) == NULL) {
362
1.06k
        ERR_raise(ERR_LIB_DSA, ERR_R_DSA_LIB);
363
1.06k
        return 0;
364
1.06k
    }
365
14
    dsa->dirty_cnt++;
366
14
    EVP_PKEY_assign_DSA(pkey, dsa);
367
14
    return 1;
368
1.07k
}
369
370
static int old_dsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
371
355
{
372
355
    return i2d_DSAPrivateKey(pkey->pkey.dsa, pder);
373
355
}
374
375
static int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
376
                         const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx)
377
5.67k
{
378
5.67k
    DSA_SIG *dsa_sig;
379
5.67k
    const unsigned char *p;
380
381
5.67k
    if (sig == NULL) {
382
2.10k
        if (BIO_puts(bp, "\n") <= 0)
383
0
            return 0;
384
2.10k
        else
385
2.10k
            return 1;
386
2.10k
    }
387
3.56k
    p = sig->data;
388
3.56k
    dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length);
389
3.56k
    if (dsa_sig != NULL) {
390
438
        int rv = 0;
391
438
        const BIGNUM *r, *s;
392
393
438
        DSA_SIG_get0(dsa_sig, &r, &s);
394
395
438
        if (BIO_write(bp, "\n", 1) != 1)
396
0
            goto err;
397
398
438
        if (!ASN1_bn_print(bp, "r:   ", r, NULL, indent))
399
0
            goto err;
400
438
        if (!ASN1_bn_print(bp, "s:   ", s, NULL, indent))
401
0
            goto err;
402
438
        rv = 1;
403
438
 err:
404
438
        DSA_SIG_free(dsa_sig);
405
438
        return rv;
406
438
    }
407
3.12k
    if (BIO_puts(bp, "\n") <= 0)
408
0
        return 0;
409
3.12k
    return X509_signature_dump(bp, sig, indent);
410
3.12k
}
411
412
static int dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
413
0
{
414
0
    switch (op) {
415
0
    case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
416
0
        *(int *)arg2 = NID_sha256;
417
0
        return 1;
418
419
0
    default:
420
0
        return -2;
421
0
    }
422
0
}
423
424
static size_t dsa_pkey_dirty_cnt(const EVP_PKEY *pkey)
425
127k
{
426
127k
    return pkey->pkey.dsa->dirty_cnt;
427
127k
}
428
429
static int dsa_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
430
                              OSSL_FUNC_keymgmt_import_fn *importer,
431
                              OSSL_LIB_CTX *libctx, const char *propq)
432
25.4k
{
433
25.4k
    DSA *dsa = from->pkey.dsa;
434
25.4k
    OSSL_PARAM_BLD *tmpl;
435
25.4k
    const BIGNUM *p = DSA_get0_p(dsa), *g = DSA_get0_g(dsa);
436
25.4k
    const BIGNUM *q = DSA_get0_q(dsa), *pub_key = DSA_get0_pub_key(dsa);
437
25.4k
    const BIGNUM *priv_key = DSA_get0_priv_key(dsa);
438
25.4k
    OSSL_PARAM *params;
439
25.4k
    int selection = 0;
440
25.4k
    int rv = 0;
441
442
25.4k
    if (p == NULL || q == NULL || g == NULL)
443
0
        return 0;
444
445
25.4k
    tmpl = OSSL_PARAM_BLD_new();
446
25.4k
    if (tmpl == NULL)
447
0
        return 0;
448
449
25.4k
    if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_P, p)
450
25.4k
        || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_Q, q)
451
25.4k
        || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_G, g))
452
0
        goto err;
453
25.4k
    selection |= OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS;
454
25.4k
    if (pub_key != NULL) {
455
25.4k
        if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PUB_KEY,
456
25.4k
                                    pub_key))
457
0
            goto err;
458
25.4k
        selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
459
25.4k
    }
460
25.4k
    if (priv_key != NULL) {
461
25.4k
        if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PRIV_KEY,
462
25.4k
                                    priv_key))
463
0
            goto err;
464
25.4k
        selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
465
25.4k
    }
466
467
25.4k
    if ((params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL)
468
0
        goto err;
469
470
    /* We export, the provider imports */
471
25.4k
    rv = importer(to_keydata, selection, params);
472
473
25.4k
    OSSL_PARAM_free(params);
474
25.4k
 err:
475
25.4k
    OSSL_PARAM_BLD_free(tmpl);
476
25.4k
    return rv;
477
25.4k
}
478
479
static int dsa_pkey_import_from(const OSSL_PARAM params[], void *vpctx)
480
25.4k
{
481
25.4k
    EVP_PKEY_CTX *pctx = vpctx;
482
25.4k
    EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx);
483
25.4k
    DSA *dsa = ossl_dsa_new(pctx->libctx);
484
485
25.4k
    if (dsa == NULL) {
486
0
        ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE);
487
0
        return 0;
488
0
    }
489
490
25.4k
    if (!ossl_dsa_ffc_params_fromdata(dsa, params)
491
25.4k
        || !ossl_dsa_key_fromdata(dsa, params, 1)
492
25.4k
        || !EVP_PKEY_assign_DSA(pkey, dsa)) {
493
0
        DSA_free(dsa);
494
0
        return 0;
495
0
    }
496
25.4k
    return 1;
497
25.4k
}
498
499
static int dsa_pkey_copy(EVP_PKEY *to, EVP_PKEY *from)
500
0
{
501
0
    DSA *dsa = from->pkey.dsa;
502
0
    DSA *dupkey = NULL;
503
0
    int ret;
504
505
0
    if (dsa != NULL) {
506
0
        dupkey = ossl_dsa_dup(dsa, OSSL_KEYMGMT_SELECT_ALL);
507
0
        if (dupkey == NULL)
508
0
            return 0;
509
0
    }
510
511
0
    ret = EVP_PKEY_assign_DSA(to, dupkey);
512
0
    if (!ret)
513
0
        DSA_free(dupkey);
514
0
    return ret;
515
0
}
516
517
/* NB these are sorted in pkey_id order, lowest first */
518
519
const EVP_PKEY_ASN1_METHOD ossl_dsa_asn1_meths[5] = {
520
521
    {
522
     EVP_PKEY_DSA2,
523
     EVP_PKEY_DSA,
524
     ASN1_PKEY_ALIAS},
525
526
    {
527
     EVP_PKEY_DSA1,
528
     EVP_PKEY_DSA,
529
     ASN1_PKEY_ALIAS},
530
531
    {
532
     EVP_PKEY_DSA4,
533
     EVP_PKEY_DSA,
534
     ASN1_PKEY_ALIAS},
535
536
    {
537
     EVP_PKEY_DSA3,
538
     EVP_PKEY_DSA,
539
     ASN1_PKEY_ALIAS},
540
541
    {
542
     EVP_PKEY_DSA,
543
     EVP_PKEY_DSA,
544
     0,
545
546
     "DSA",
547
     "OpenSSL DSA method",
548
549
     dsa_pub_decode,
550
     dsa_pub_encode,
551
     dsa_pub_cmp,
552
     dsa_pub_print,
553
554
     dsa_priv_decode,
555
     dsa_priv_encode,
556
     dsa_priv_print,
557
558
     int_dsa_size,
559
     dsa_bits,
560
     dsa_security_bits,
561
562
     dsa_param_decode,
563
     dsa_param_encode,
564
     dsa_missing_parameters,
565
     dsa_copy_parameters,
566
     dsa_cmp_parameters,
567
     dsa_param_print,
568
     dsa_sig_print,
569
570
     int_dsa_free,
571
     dsa_pkey_ctrl,
572
     old_dsa_priv_decode,
573
     old_dsa_priv_encode,
574
575
     NULL, NULL, NULL,
576
     NULL, NULL, NULL,
577
     NULL, NULL, NULL, NULL,
578
579
     dsa_pkey_dirty_cnt,
580
     dsa_pkey_export_to,
581
     dsa_pkey_import_from,
582
     dsa_pkey_copy
583
    }
584
};