dsa_ameth.c 13.5 KB
Newer Older
1
/*
R
Rich Salz 已提交
2
 * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
3
 *
R
Rich Salz 已提交
4 5 6 7
 * Licensed under the OpenSSL license (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
8 9 10
 */

#include <stdio.h>
11
#include "internal/cryptlib.h"
12 13
#include <openssl/x509.h>
#include <openssl/asn1.h>
M
Matt Caswell 已提交
14
#include "dsa_locl.h"
15
#include <openssl/bn.h>
R
Rich Salz 已提交
16
#include <openssl/cms.h>
17
#include "internal/asn1_int.h"
D
Dr. Stephen Henson 已提交
18
#include "internal/evp_int.h"
19 20

static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
{
    const unsigned char *p, *pm;
    int pklen, pmlen;
    int ptype;
    void *pval;
    ASN1_STRING *pstr;
    X509_ALGOR *palg;
    ASN1_INTEGER *public_key = NULL;

    DSA *dsa = NULL;

    if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
        return 0;
    X509_ALGOR_get0(NULL, &ptype, &pval, palg);

    if (ptype == V_ASN1_SEQUENCE) {
        pstr = pval;
        pm = pstr->data;
        pmlen = pstr->length;

41
        if ((dsa = d2i_DSAparams(NULL, &pm, pmlen)) == NULL) {
42 43 44 45 46
            DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR);
            goto err;
        }

    } else if ((ptype == V_ASN1_NULL) || (ptype == V_ASN1_UNDEF)) {
47
        if ((dsa = DSA_new()) == NULL) {
48 49 50 51 52 53 54 55
            DSAerr(DSA_F_DSA_PUB_DECODE, ERR_R_MALLOC_FAILURE);
            goto err;
        }
    } else {
        DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_PARAMETER_ENCODING_ERROR);
        goto err;
    }

56
    if ((public_key = d2i_ASN1_INTEGER(NULL, &p, pklen)) == NULL) {
57 58 59 60
        DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR);
        goto err;
    }

61
    if ((dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)) == NULL) {
62 63 64 65 66 67 68 69 70
        DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_BN_DECODE_ERROR);
        goto err;
    }

    ASN1_INTEGER_free(public_key);
    EVP_PKEY_assign_DSA(pkey, dsa);
    return 1;

 err:
R
Rich Salz 已提交
71
    ASN1_INTEGER_free(public_key);
R
Rich Salz 已提交
72
    DSA_free(dsa);
73 74 75
    return 0;

}
76

77
static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
78 79 80 81 82
{
    DSA *dsa;
    int ptype;
    unsigned char *penc = NULL;
    int penclen;
M
Matt Caswell 已提交
83
    ASN1_STRING *str = NULL;
84
    ASN1_INTEGER *pubint = NULL;
85 86 87 88

    dsa = pkey->pkey.dsa;
    if (pkey->save_parameters && dsa->p && dsa->q && dsa->g) {
        str = ASN1_STRING_new();
89
        if (str == NULL) {
M
Matt Caswell 已提交
90 91 92
            DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
            goto err;
        }
93 94 95 96 97 98 99 100 101
        str->length = i2d_DSAparams(dsa, &str->data);
        if (str->length <= 0) {
            DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
            goto err;
        }
        ptype = V_ASN1_SEQUENCE;
    } else
        ptype = V_ASN1_UNDEF;

102
    pubint = BN_to_ASN1_INTEGER(dsa->pub_key, NULL);
103

104 105 106 107 108 109 110
    if (pubint == NULL) {
        DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    penclen = i2d_ASN1_INTEGER(pubint, &penc);
    ASN1_INTEGER_free(pubint);
111 112 113 114 115 116 117

    if (penclen <= 0) {
        DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA),
M
Matt Caswell 已提交
118
                               ptype, str, penc, penclen))
119 120 121
        return 1;

 err:
R
Rich Salz 已提交
122
    OPENSSL_free(penc);
R
Rich Salz 已提交
123
    ASN1_STRING_free(str);
124 125 126 127 128 129

    return 0;
}

/*
 * In PKCS#8 DSA: you just get a private key integer and parameters in the
130 131
 * AlgorithmIdentifier the pubkey must be recalculated.
 */
132

133
static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
134
{
135
    const unsigned char *p, *pm;
136 137 138 139 140 141 142 143 144 145
    int pklen, pmlen;
    int ptype;
    void *pval;
    ASN1_STRING *pstr;
    X509_ALGOR *palg;
    ASN1_INTEGER *privkey = NULL;
    BN_CTX *ctx = NULL;

    DSA *dsa = NULL;

146 147
    int ret = 0;

148 149 150 151
    if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
        return 0;
    X509_ALGOR_get0(NULL, &ptype, &pval, palg);

152 153
    if ((privkey = d2i_ASN1_INTEGER(NULL, &p, pklen)) == NULL)
        goto decerr;
154
    if (privkey->type == V_ASN1_NEG_INTEGER || ptype != V_ASN1_SEQUENCE)
155
        goto decerr;
156 157 158 159

    pstr = pval;
    pm = pstr->data;
    pmlen = pstr->length;
160
    if ((dsa = d2i_DSAparams(NULL, &pm, pmlen)) == NULL)
161 162
        goto decerr;
    /* We have parameters now set private key */
R
Rich Salz 已提交
163 164
    if ((dsa->priv_key = BN_secure_new()) == NULL
        || !ASN1_INTEGER_to_BN(privkey, dsa->priv_key)) {
165 166 167 168
        DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_BN_ERROR);
        goto dsaerr;
    }
    /* Calculate public key */
169
    if ((dsa->pub_key = BN_new()) == NULL) {
170 171 172
        DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE);
        goto dsaerr;
    }
173
    if ((ctx = BN_CTX_new()) == NULL) {
174 175 176 177 178 179 180 181 182 183 184
        DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE);
        goto dsaerr;
    }

    if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) {
        DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_BN_ERROR);
        goto dsaerr;
    }

    EVP_PKEY_assign_DSA(pkey, dsa);

185 186
    ret = 1;
    goto done;
187 188

 decerr:
D
typo  
Dr. Stephen Henson 已提交
189
    DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_DECODE_ERROR);
190
 dsaerr:
191 192
    DSA_free(dsa);
 done:
193
    BN_CTX_free(ctx);
R
Rich Salz 已提交
194
    ASN1_STRING_clear_free(privkey);
195
    return ret;
196
}
197

198
static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
199
{
200 201 202 203 204 205 206 207 208 209 210 211
    ASN1_STRING *params = NULL;
    ASN1_INTEGER *prkey = NULL;
    unsigned char *dp = NULL;
    int dplen;

    if (!pkey->pkey.dsa || !pkey->pkey.dsa->priv_key) {
        DSAerr(DSA_F_DSA_PRIV_ENCODE, DSA_R_MISSING_PARAMETERS);
        goto err;
    }

    params = ASN1_STRING_new();

212
    if (params == NULL) {
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
        DSAerr(DSA_F_DSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    params->length = i2d_DSAparams(pkey->pkey.dsa, &params->data);
    if (params->length <= 0) {
        DSAerr(DSA_F_DSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    params->type = V_ASN1_SEQUENCE;

    /* Get private key into integer */
    prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL);

    if (!prkey) {
        DSAerr(DSA_F_DSA_PRIV_ENCODE, DSA_R_BN_ERROR);
        goto err;
    }

    dplen = i2d_ASN1_INTEGER(prkey, &dp);

234
    ASN1_STRING_clear_free(prkey);
M
Martin Vejnar 已提交
235
    prkey = NULL;
236 237 238 239 240 241 242 243

    if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dsa), 0,
                         V_ASN1_SEQUENCE, params, dp, dplen))
        goto err;

    return 1;

 err:
R
Rich Salz 已提交
244
    OPENSSL_free(dp);
R
Rich Salz 已提交
245
    ASN1_STRING_free(params);
R
Rich Salz 已提交
246
    ASN1_STRING_clear_free(prkey);
247
    return 0;
248 249
}

250
static int int_dsa_size(const EVP_PKEY *pkey)
251 252 253
{
    return (DSA_size(pkey->pkey.dsa));
}
254 255

static int dsa_bits(const EVP_PKEY *pkey)
256 257 258
{
    return BN_num_bits(pkey->pkey.dsa->p);
}
259

260
static int dsa_security_bits(const EVP_PKEY *pkey)
261 262 263
{
    return DSA_security_bits(pkey->pkey.dsa);
}
264

265
static int dsa_missing_parameters(const EVP_PKEY *pkey)
266 267 268
{
    DSA *dsa;
    dsa = pkey->pkey.dsa;
269
    if (dsa == NULL || dsa->p == NULL || dsa->q == NULL || dsa->g == NULL)
270 271 272
        return 1;
    return 0;
}
273 274

static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
275 276 277
{
    BIGNUM *a;

278 279 280 281 282 283
    if (to->pkey.dsa == NULL) {
        to->pkey.dsa = DSA_new();
        if (to->pkey.dsa == NULL)
            return 0;
    }

284 285
    if ((a = BN_dup(from->pkey.dsa->p)) == NULL)
        return 0;
R
Rich Salz 已提交
286
    BN_free(to->pkey.dsa->p);
287 288 289 290
    to->pkey.dsa->p = a;

    if ((a = BN_dup(from->pkey.dsa->q)) == NULL)
        return 0;
R
Rich Salz 已提交
291
    BN_free(to->pkey.dsa->q);
292 293 294 295
    to->pkey.dsa->q = a;

    if ((a = BN_dup(from->pkey.dsa->g)) == NULL)
        return 0;
R
Rich Salz 已提交
296
    BN_free(to->pkey.dsa->g);
297 298 299
    to->pkey.dsa->g = a;
    return 1;
}
300 301

static int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
302 303 304 305 306 307 308 309
{
    if (BN_cmp(a->pkey.dsa->p, b->pkey.dsa->p) ||
        BN_cmp(a->pkey.dsa->q, b->pkey.dsa->q) ||
        BN_cmp(a->pkey.dsa->g, b->pkey.dsa->g))
        return 0;
    else
        return 1;
}
310

311
static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
312 313 314 315 316 317
{
    if (BN_cmp(b->pkey.dsa->pub_key, a->pkey.dsa->pub_key) != 0)
        return 0;
    else
        return 1;
}
318

319
static void int_dsa_free(EVP_PKEY *pkey)
320 321 322
{
    DSA_free(pkey->pkey.dsa);
}
323

324
static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype)
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354
{
    int ret = 0;
    const char *ktype = NULL;
    const BIGNUM *priv_key, *pub_key;

    if (ptype == 2)
        priv_key = x->priv_key;
    else
        priv_key = NULL;

    if (ptype > 0)
        pub_key = x->pub_key;
    else
        pub_key = NULL;

    if (ptype == 2)
        ktype = "Private-Key";
    else if (ptype == 1)
        ktype = "Public-Key";
    else
        ktype = "DSA-Parameters";

    if (priv_key) {
        if (!BIO_indent(bp, off, 128))
            goto err;
        if (BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p))
            <= 0)
            goto err;
    }

355
    if (!ASN1_bn_print(bp, "priv:", priv_key, NULL, off))
356
        goto err;
357
    if (!ASN1_bn_print(bp, "pub: ", pub_key, NULL, off))
358
        goto err;
359
    if (!ASN1_bn_print(bp, "P:   ", x->p, NULL, off))
360
        goto err;
361
    if (!ASN1_bn_print(bp, "Q:   ", x->q, NULL, off))
362
        goto err;
363
    if (!ASN1_bn_print(bp, "G:   ", x->g, NULL, off))
364 365 366 367 368
        goto err;
    ret = 1;
 err:
    return (ret);
}
369

370
static int dsa_param_decode(EVP_PKEY *pkey,
371 372 373
                            const unsigned char **pder, int derlen)
{
    DSA *dsa;
374 375

    if ((dsa = d2i_DSAparams(NULL, pder, derlen)) == NULL) {
376 377 378 379 380 381
        DSAerr(DSA_F_DSA_PARAM_DECODE, ERR_R_DSA_LIB);
        return 0;
    }
    EVP_PKEY_assign_DSA(pkey, dsa);
    return 1;
}
382 383

static int dsa_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
384 385 386
{
    return i2d_DSAparams(pkey->pkey.dsa, pder);
}
387 388

static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
389 390 391 392
                           ASN1_PCTX *ctx)
{
    return do_dsa_print(bp, pkey->pkey.dsa, indent, 0);
}
393 394

static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
395 396 397 398
                         ASN1_PCTX *ctx)
{
    return do_dsa_print(bp, pkey->pkey.dsa, indent, 1);
}
399 400

static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
401 402 403 404
                          ASN1_PCTX *ctx)
{
    return do_dsa_print(bp, pkey->pkey.dsa, indent, 2);
}
405

406
static int old_dsa_priv_decode(EVP_PKEY *pkey,
407 408 409
                               const unsigned char **pder, int derlen)
{
    DSA *dsa;
410 411

    if ((dsa = d2i_DSAPrivateKey(NULL, pder, derlen)) == NULL) {
412 413 414 415 416 417
        DSAerr(DSA_F_OLD_DSA_PRIV_DECODE, ERR_R_DSA_LIB);
        return 0;
    }
    EVP_PKEY_assign_DSA(pkey, dsa);
    return 1;
}
418 419

static int old_dsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
420 421 422
{
    return i2d_DSAPrivateKey(pkey->pkey.dsa, pder);
}
423

424
static int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
425 426 427 428
                         const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx)
{
    DSA_SIG *dsa_sig;
    const unsigned char *p;
429

430 431 432 433 434 435 436 437 438 439
    if (!sig) {
        if (BIO_puts(bp, "\n") <= 0)
            return 0;
        else
            return 1;
    }
    p = sig->data;
    dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length);
    if (dsa_sig) {
        int rv = 0;
440
        const BIGNUM *r, *s;
D
Dr. Stephen Henson 已提交
441

442
        DSA_SIG_get0(dsa_sig, &r, &s);
443 444 445 446

        if (BIO_write(bp, "\n", 1) != 1)
            goto err;

D
Dr. Stephen Henson 已提交
447
        if (!ASN1_bn_print(bp, "r:   ", r, NULL, indent))
448
            goto err;
D
Dr. Stephen Henson 已提交
449
        if (!ASN1_bn_print(bp, "s:   ", s, NULL, indent))
450 451 452 453 454 455 456 457
            goto err;
        rv = 1;
 err:
        DSA_SIG_free(dsa_sig);
        return rv;
    }
    return X509_signature_dump(bp, sig, indent);
}
458

459
static int dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476
{
    switch (op) {
    case ASN1_PKEY_CTRL_PKCS7_SIGN:
        if (arg1 == 0) {
            int snid, hnid;
            X509_ALGOR *alg1, *alg2;
            PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
            if (alg1 == NULL || alg1->algorithm == NULL)
                return -1;
            hnid = OBJ_obj2nid(alg1->algorithm);
            if (hnid == NID_undef)
                return -1;
            if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
                return -1;
            X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
        }
        return 1;
D
Dr. Stephen Henson 已提交
477
#ifndef OPENSSL_NO_CMS
478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496
    case ASN1_PKEY_CTRL_CMS_SIGN:
        if (arg1 == 0) {
            int snid, hnid;
            X509_ALGOR *alg1, *alg2;
            CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2);
            if (alg1 == NULL || alg1->algorithm == NULL)
                return -1;
            hnid = OBJ_obj2nid(alg1->algorithm);
            if (hnid == NID_undef)
                return -1;
            if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
                return -1;
            X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
        }
        return 1;

    case ASN1_PKEY_CTRL_CMS_RI_TYPE:
        *(int *)arg2 = CMS_RECIPINFO_NONE;
        return 1;
D
Dr. Stephen Henson 已提交
497
#endif
498

499 500 501
    case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
        *(int *)arg2 = NID_sha256;
        return 2;
502

503 504
    default:
        return -2;
505

506
    }
507

508
}
509

510 511
/* NB these are sorted in pkey_id order, lowest first */

K
Kurt Roeckx 已提交
512
const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[5] = {
513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567

    {
     EVP_PKEY_DSA2,
     EVP_PKEY_DSA,
     ASN1_PKEY_ALIAS},

    {
     EVP_PKEY_DSA1,
     EVP_PKEY_DSA,
     ASN1_PKEY_ALIAS},

    {
     EVP_PKEY_DSA4,
     EVP_PKEY_DSA,
     ASN1_PKEY_ALIAS},

    {
     EVP_PKEY_DSA3,
     EVP_PKEY_DSA,
     ASN1_PKEY_ALIAS},

    {
     EVP_PKEY_DSA,
     EVP_PKEY_DSA,
     0,

     "DSA",
     "OpenSSL DSA method",

     dsa_pub_decode,
     dsa_pub_encode,
     dsa_pub_cmp,
     dsa_pub_print,

     dsa_priv_decode,
     dsa_priv_encode,
     dsa_priv_print,

     int_dsa_size,
     dsa_bits,
     dsa_security_bits,

     dsa_param_decode,
     dsa_param_encode,
     dsa_missing_parameters,
     dsa_copy_parameters,
     dsa_cmp_parameters,
     dsa_param_print,
     dsa_sig_print,

     int_dsa_free,
     dsa_pkey_ctrl,
     old_dsa_priv_decode,
     old_dsa_priv_encode}
};