Coverage Report

Created: 2025-06-13 06:55

/src/openssl/crypto/dsa/dsa_ameth.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2006-2024 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
0
{
31
0
    const unsigned char *p, *pm;
32
0
    int pklen, pmlen;
33
0
    int ptype;
34
0
    const void *pval;
35
0
    const ASN1_STRING *pstr;
36
0
    X509_ALGOR *palg;
37
0
    ASN1_INTEGER *public_key = NULL;
38
39
0
    DSA *dsa = NULL;
40
41
0
    if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
42
0
        return 0;
43
0
    X509_ALGOR_get0(NULL, &ptype, &pval, palg);
44
45
0
    if (ptype == V_ASN1_SEQUENCE) {
46
0
        pstr = pval;
47
0
        pm = pstr->data;
48
0
        pmlen = pstr->length;
49
50
0
        if ((dsa = d2i_DSAparams(NULL, &pm, pmlen)) == NULL) {
51
0
            ERR_raise(ERR_LIB_DSA, DSA_R_DECODE_ERROR);
52
0
            goto err;
53
0
        }
54
55
0
    } else if ((ptype == V_ASN1_NULL) || (ptype == V_ASN1_UNDEF)) {
56
0
        if ((dsa = DSA_new()) == NULL) {
57
0
            ERR_raise(ERR_LIB_DSA, ERR_R_DSA_LIB);
58
0
            goto err;
59
0
        }
60
0
    } else {
61
0
        ERR_raise(ERR_LIB_DSA, DSA_R_PARAMETER_ENCODING_ERROR);
62
0
        goto err;
63
0
    }
64
65
0
    if ((public_key = d2i_ASN1_INTEGER(NULL, &p, pklen)) == NULL) {
66
0
        ERR_raise(ERR_LIB_DSA, DSA_R_DECODE_ERROR);
67
0
        goto err;
68
0
    }
69
70
0
    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
0
    dsa->dirty_cnt++;
76
0
    ASN1_INTEGER_free(public_key);
77
0
    EVP_PKEY_assign_DSA(pkey, dsa);
78
0
    return 1;
79
80
0
 err:
81
0
    ASN1_INTEGER_free(public_key);
82
0
    DSA_free(dsa);
83
0
    return 0;
84
85
0
}
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_ASN1_LIB);
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_ASN1_LIB);
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_ASN1_LIB);
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_ASN1_LIB);
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
0
{
152
0
    int ret = 0;
153
0
    DSA *dsa = ossl_dsa_key_from_pkcs8(p8, NULL, NULL);
154
155
0
    if (dsa != NULL) {
156
0
        ret = 1;
157
0
        EVP_PKEY_assign_DSA(pkey, dsa);
158
0
    }
159
160
0
    return ret;
161
0
}
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_ASN1_LIB);
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_ASN1_LIB);
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
0
{
235
0
    DSA *dsa;
236
0
    dsa = pkey->pkey.dsa;
237
0
    return dsa == NULL
238
0
        || dsa->params.p == NULL
239
0
        || dsa->params.q == NULL
240
0
        || dsa->params.g == NULL;
241
0
}
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
0
{
269
0
    DSA_free(pkey->pkey.dsa);
270
0
}
271
272
static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype)
273
0
{
274
0
    int ret = 0;
275
0
    const char *ktype = NULL;
276
0
    const BIGNUM *priv_key, *pub_key;
277
0
    int mod_len = 0;
278
279
0
    if (x->params.p != NULL)
280
0
        mod_len = DSA_bits(x);
281
282
0
    if (ptype == 2)
283
0
        priv_key = x->priv_key;
284
0
    else
285
0
        priv_key = NULL;
286
287
0
    if (ptype > 0)
288
0
        pub_key = x->pub_key;
289
0
    else
290
0
        pub_key = NULL;
291
292
0
    if (ptype == 2)
293
0
        ktype = "Private-Key";
294
0
    else if (ptype == 1)
295
0
        ktype = "Public-Key";
296
0
    else
297
0
        ktype = "DSA-Parameters";
298
299
0
    if (priv_key != NULL) {
300
0
        if (!BIO_indent(bp, off, 128))
301
0
            goto err;
302
0
        if (BIO_printf(bp, "%s: (%d bit)\n", ktype, mod_len) <= 0)
303
0
            goto err;
304
0
    } else {
305
0
        if (BIO_printf(bp, "Public-Key: (%d bit)\n", mod_len) <= 0)
306
0
            goto err;
307
0
    }
308
309
0
    if (!ASN1_bn_print(bp, "priv:", priv_key, NULL, off))
310
0
        goto err;
311
0
    if (!ASN1_bn_print(bp, "pub: ", pub_key, NULL, off))
312
0
        goto err;
313
0
    if (!ossl_ffc_params_print(bp, &x->params, off))
314
0
        goto err;
315
0
    ret = 1;
316
0
 err:
317
0
    return ret;
318
0
}
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
0
{
353
0
    return do_dsa_print(bp, pkey->pkey.dsa, indent, 2);
354
0
}
355
356
static int old_dsa_priv_decode(EVP_PKEY *pkey,
357
                               const unsigned char **pder, int derlen)
358
0
{
359
0
    DSA *dsa;
360
361
0
    if ((dsa = d2i_DSAPrivateKey(NULL, pder, derlen)) == NULL) {
362
0
        ERR_raise(ERR_LIB_DSA, ERR_R_DSA_LIB);
363
0
        return 0;
364
0
    }
365
0
    dsa->dirty_cnt++;
366
0
    EVP_PKEY_assign_DSA(pkey, dsa);
367
0
    return 1;
368
0
}
369
370
static int old_dsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
371
0
{
372
0
    return i2d_DSAPrivateKey(pkey->pkey.dsa, pder);
373
0
}
374
375
static int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
376
                         const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx)
377
0
{
378
0
    DSA_SIG *dsa_sig;
379
0
    const unsigned char *p;
380
381
0
    if (sig == NULL) {
382
0
        if (BIO_puts(bp, "\n") <= 0)
383
0
            return 0;
384
0
        else
385
0
            return 1;
386
0
    }
387
0
    p = sig->data;
388
0
    dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length);
389
0
    if (dsa_sig != NULL) {
390
0
        int rv = 0;
391
0
        const BIGNUM *r, *s;
392
393
0
        DSA_SIG_get0(dsa_sig, &r, &s);
394
395
0
        if (BIO_write(bp, "\n", 1) != 1)
396
0
            goto err;
397
398
0
        if (!ASN1_bn_print(bp, "r:   ", r, NULL, indent))
399
0
            goto err;
400
0
        if (!ASN1_bn_print(bp, "s:   ", s, NULL, indent))
401
0
            goto err;
402
0
        rv = 1;
403
0
 err:
404
0
        DSA_SIG_free(dsa_sig);
405
0
        return rv;
406
0
    }
407
0
    if (BIO_puts(bp, "\n") <= 0)
408
0
        return 0;
409
0
    return X509_signature_dump(bp, sig, indent);
410
0
}
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
0
{
426
0
    return pkey->pkey.dsa->dirty_cnt;
427
0
}
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
0
{
433
0
    DSA *dsa = from->pkey.dsa;
434
0
    OSSL_PARAM_BLD *tmpl;
435
0
    const BIGNUM *p = DSA_get0_p(dsa), *g = DSA_get0_g(dsa);
436
0
    const BIGNUM *q = DSA_get0_q(dsa), *pub_key = DSA_get0_pub_key(dsa);
437
0
    const BIGNUM *priv_key = DSA_get0_priv_key(dsa);
438
0
    OSSL_PARAM *params;
439
0
    int selection = 0;
440
0
    int rv = 0;
441
442
0
    if (p == NULL || q == NULL || g == NULL)
443
0
        return 0;
444
445
0
    tmpl = OSSL_PARAM_BLD_new();
446
0
    if (tmpl == NULL)
447
0
        return 0;
448
449
0
    if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_P, p)
450
0
        || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_Q, q)
451
0
        || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_G, g))
452
0
        goto err;
453
0
    selection |= OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS;
454
0
    if (pub_key != NULL) {
455
0
        if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PUB_KEY,
456
0
                                    pub_key))
457
0
            goto err;
458
0
        selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
459
0
    }
460
0
    if (priv_key != NULL) {
461
0
        if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PRIV_KEY,
462
0
                                    priv_key))
463
0
            goto err;
464
0
        selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
465
0
    }
466
467
0
    if ((params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL)
468
0
        goto err;
469
470
    /* We export, the provider imports */
471
0
    rv = importer(to_keydata, selection, params);
472
473
0
    OSSL_PARAM_free(params);
474
0
 err:
475
0
    OSSL_PARAM_BLD_free(tmpl);
476
0
    return rv;
477
0
}
478
479
static int dsa_pkey_import_from(const OSSL_PARAM params[], void *vpctx)
480
0
{
481
0
    EVP_PKEY_CTX *pctx = vpctx;
482
0
    EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx);
483
0
    DSA *dsa = ossl_dsa_new(pctx->libctx);
484
485
0
    if (dsa == NULL) {
486
0
        ERR_raise(ERR_LIB_DSA, ERR_R_DSA_LIB);
487
0
        return 0;
488
0
    }
489
490
0
    if (!ossl_dsa_ffc_params_fromdata(dsa, params)
491
0
        || !ossl_dsa_key_fromdata(dsa, params, 1)
492
0
        || !EVP_PKEY_assign_DSA(pkey, dsa)) {
493
0
        DSA_free(dsa);
494
0
        return 0;
495
0
    }
496
0
    return 1;
497
0
}
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[4] = {
520
521
    /* This aliases NID_dsa with NID_dsa_2 */
522
    {
523
     EVP_PKEY_DSA1,
524
     EVP_PKEY_DSA,
525
     ASN1_PKEY_ALIAS},
526
527
    /* This aliases NID_dsaWithSHA with NID_dsaWithSHA_2 */
528
    {
529
     EVP_PKEY_DSA4,
530
     EVP_PKEY_DSA2,
531
     ASN1_PKEY_ALIAS},
532
533
    /* This aliases NID_dsaWithSHA with NID_dsaWithSHA1 */
534
    {
535
     EVP_PKEY_DSA3,
536
     EVP_PKEY_DSA2,
537
     ASN1_PKEY_ALIAS},
538
539
    {
540
     EVP_PKEY_DSA,
541
     EVP_PKEY_DSA,
542
     0,
543
544
     "DSA",
545
     "OpenSSL DSA method",
546
547
     dsa_pub_decode,
548
     dsa_pub_encode,
549
     dsa_pub_cmp,
550
     dsa_pub_print,
551
552
     dsa_priv_decode,
553
     dsa_priv_encode,
554
     dsa_priv_print,
555
556
     int_dsa_size,
557
     dsa_bits,
558
     dsa_security_bits,
559
560
     dsa_param_decode,
561
     dsa_param_encode,
562
     dsa_missing_parameters,
563
     dsa_copy_parameters,
564
     dsa_cmp_parameters,
565
     dsa_param_print,
566
     dsa_sig_print,
567
568
     int_dsa_free,
569
     dsa_pkey_ctrl,
570
     old_dsa_priv_decode,
571
     old_dsa_priv_encode,
572
573
     NULL, NULL, NULL,
574
     NULL, NULL, NULL,
575
     NULL, NULL, NULL, NULL,
576
577
     dsa_pkey_dirty_cnt,
578
     dsa_pkey_export_to,
579
     dsa_pkey_import_from,
580
     dsa_pkey_copy
581
    }
582
};