1 /* $OpenBSD: dsa_ameth.c,v 1.59 2024/04/13 14:02:51 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 <stdio.h> 60 61 #include <openssl/opensslconf.h> 62 63 #include <openssl/asn1.h> 64 #include <openssl/bn.h> 65 #include <openssl/cms.h> 66 #include <openssl/dsa.h> 67 #include <openssl/err.h> 68 #include <openssl/x509.h> 69 70 #include "asn1_local.h" 71 #include "bn_local.h" 72 #include "dsa_local.h" 73 #include "evp_local.h" 74 #include "x509_local.h" 75 76 static int 77 dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) 78 { 79 X509_ALGOR *algor; 80 int ptype; 81 const void *pval; 82 const ASN1_STRING *astr; 83 const unsigned char *key, *params, *p; 84 int key_len, params_len; 85 ASN1_INTEGER *aint = NULL; 86 DSA *dsa = NULL; 87 int ret = 0; 88 89 if (!X509_PUBKEY_get0_param(NULL, &key, &key_len, &algor, pubkey)) 90 goto err; 91 X509_ALGOR_get0(NULL, &ptype, &pval, algor); 92 93 if (ptype == V_ASN1_SEQUENCE) { 94 astr = pval; 95 params = astr->data; 96 params_len = astr->length; 97 98 p = params; 99 if ((dsa = d2i_DSAparams(NULL, &p, params_len)) == NULL) { 100 DSAerror(DSA_R_DECODE_ERROR); 101 goto err; 102 } 103 } else if (ptype == V_ASN1_NULL || ptype == V_ASN1_UNDEF) { 104 if ((dsa = DSA_new()) == NULL) { 105 DSAerror(ERR_R_MALLOC_FAILURE); 106 goto err; 107 } 108 } else { 109 DSAerror(DSA_R_PARAMETER_ENCODING_ERROR); 110 goto err; 111 } 112 113 p = key; 114 if ((aint = d2i_ASN1_INTEGER(NULL, &p, key_len)) == NULL) { 115 DSAerror(DSA_R_DECODE_ERROR); 116 goto err; 117 } 118 BN_free(dsa->pub_key); 119 if ((dsa->pub_key = ASN1_INTEGER_to_BN(aint, NULL)) == NULL) { 120 DSAerror(DSA_R_BN_DECODE_ERROR); 121 goto err; 122 } 123 124 /* We can only check for key consistency if we have parameters. */ 125 if (ptype == V_ASN1_SEQUENCE) { 126 if (!dsa_check_key(dsa)) 127 goto err; 128 } 129 130 if (!EVP_PKEY_assign_DSA(pkey, dsa)) 131 goto err; 132 dsa = NULL; 133 134 ret = 1; 135 136 err: 137 ASN1_INTEGER_free(aint); 138 DSA_free(dsa); 139 140 return ret; 141 } 142 143 static int 144 dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) 145 { 146 const DSA *dsa = pkey->pkey.dsa; 147 ASN1_STRING *astr = NULL; 148 int ptype = V_ASN1_UNDEF; 149 ASN1_INTEGER *aint = NULL; 150 ASN1_OBJECT *aobj; 151 unsigned char *params = NULL, *key = NULL; 152 int params_len = 0, key_len = 0; 153 int ret = 0; 154 155 if (pkey->save_parameters > 0 && !EVP_PKEY_missing_parameters(pkey)) { 156 if ((params_len = i2d_DSAparams(dsa, ¶ms)) <= 0) { 157 DSAerror(ERR_R_MALLOC_FAILURE); 158 params_len = 0; 159 goto err; 160 } 161 if ((astr = ASN1_STRING_new()) == NULL) { 162 DSAerror(ERR_R_MALLOC_FAILURE); 163 goto err; 164 } 165 ASN1_STRING_set0(astr, params, params_len); 166 params = NULL; 167 params_len = 0; 168 ptype = V_ASN1_SEQUENCE; 169 } 170 171 if ((aint = BN_to_ASN1_INTEGER(dsa->pub_key, NULL)) == NULL) { 172 DSAerror(ERR_R_MALLOC_FAILURE); 173 goto err; 174 } 175 if ((key_len = i2d_ASN1_INTEGER(aint, &key)) <= 0) { 176 DSAerror(ERR_R_MALLOC_FAILURE); 177 key_len = 0; 178 goto err; 179 } 180 181 if ((aobj = OBJ_nid2obj(EVP_PKEY_DSA)) == NULL) 182 goto err; 183 if (!X509_PUBKEY_set0_param(pk, aobj, ptype, astr, key, key_len)) 184 goto err; 185 astr = NULL; 186 key = NULL; 187 key_len = 0; 188 189 ret = 1; 190 191 err: 192 ASN1_STRING_free(astr); 193 ASN1_INTEGER_free(aint); 194 freezero(params, params_len); 195 freezero(key, key_len); 196 197 return ret; 198 } 199 200 /* 201 * In PKCS#8 DSA: you just get a private key integer and parameters in the 202 * AlgorithmIdentifier the pubkey must be recalculated. 203 */ 204 static int 205 dsa_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8) 206 { 207 const X509_ALGOR *algor; 208 int ptype; 209 const void *pval; 210 const ASN1_STRING *astr; 211 const unsigned char *key, *params, *p; 212 int key_len, params_len; 213 ASN1_INTEGER *aint = NULL; 214 BN_CTX *ctx = NULL; 215 DSA *dsa = NULL; 216 int ret = 0; 217 218 if (!PKCS8_pkey_get0(NULL, &key, &key_len, &algor, p8)) 219 goto err; 220 X509_ALGOR_get0(NULL, &ptype, &pval, algor); 221 222 if (ptype != V_ASN1_SEQUENCE) { 223 DSAerror(DSA_R_PARAMETER_ENCODING_ERROR); 224 goto err; 225 } 226 227 astr = pval; 228 params = astr->data; 229 params_len = astr->length; 230 231 p = params; 232 if ((dsa = d2i_DSAparams(NULL, &p, params_len)) == NULL) { 233 DSAerror(DSA_R_DECODE_ERROR); 234 goto err; 235 } 236 p = key; 237 if ((aint = d2i_ASN1_INTEGER(NULL, &p, key_len)) == NULL) { 238 DSAerror(DSA_R_DECODE_ERROR); 239 goto err; 240 } 241 BN_free(dsa->priv_key); 242 if ((dsa->priv_key = ASN1_INTEGER_to_BN(aint, NULL)) == NULL) { 243 DSAerror(DSA_R_BN_DECODE_ERROR); 244 goto err; 245 } 246 247 /* Check the key for basic consistency before doing expensive things. */ 248 if (!dsa_check_key(dsa)) 249 goto err; 250 251 /* Calculate public key */ 252 BN_free(dsa->pub_key); 253 if ((dsa->pub_key = BN_new()) == NULL) { 254 DSAerror(ERR_R_MALLOC_FAILURE); 255 goto err; 256 } 257 258 if ((ctx = BN_CTX_new()) == NULL) { 259 DSAerror(ERR_R_MALLOC_FAILURE); 260 goto err; 261 } 262 263 BN_CTX_start(ctx); 264 265 if (!BN_mod_exp_ct(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) { 266 DSAerror(DSA_R_BN_ERROR); 267 goto err; 268 } 269 270 if (!EVP_PKEY_assign_DSA(pkey, dsa)) 271 goto err; 272 dsa = NULL; 273 274 ret = 1; 275 276 err: 277 DSA_free(dsa); 278 BN_CTX_end(ctx); 279 BN_CTX_free(ctx); 280 ASN1_INTEGER_free(aint); 281 282 return ret; 283 } 284 285 static int 286 dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) 287 { 288 const DSA *dsa = pkey->pkey.dsa; 289 ASN1_STRING *astr = NULL; 290 int ptype = V_ASN1_SEQUENCE; 291 ASN1_INTEGER *aint = NULL; 292 ASN1_OBJECT *aobj; 293 unsigned char *params = NULL, *key = NULL; 294 int params_len = 0, key_len = 0; 295 int ret = 0; 296 297 if ((params_len = i2d_DSAparams(dsa, ¶ms)) <= 0) { 298 DSAerror(ERR_R_MALLOC_FAILURE); 299 params_len = 0; 300 goto err; 301 } 302 if ((astr = ASN1_STRING_type_new(V_ASN1_SEQUENCE)) == NULL) { 303 DSAerror(ERR_R_MALLOC_FAILURE); 304 goto err; 305 } 306 ASN1_STRING_set0(astr, params, params_len); 307 params = NULL; 308 params_len = 0; 309 310 if ((aint = BN_to_ASN1_INTEGER(dsa->priv_key, NULL)) == NULL) { 311 DSAerror(DSA_R_BN_ERROR); 312 goto err; 313 } 314 if ((key_len = i2d_ASN1_INTEGER(aint, &key)) <= 0) { 315 DSAerror(ERR_R_MALLOC_FAILURE); 316 key_len = 0; 317 goto err; 318 } 319 320 if ((aobj = OBJ_nid2obj(NID_dsa)) == NULL) 321 goto err; 322 if (!PKCS8_pkey_set0(p8, aobj, 0, ptype, astr, key, key_len)) 323 goto err; 324 astr = NULL; 325 key = NULL; 326 key_len = 0; 327 328 ret = 1; 329 330 err: 331 ASN1_STRING_free(astr); 332 ASN1_INTEGER_free(aint); 333 freezero(params, params_len); 334 freezero(key, key_len); 335 336 return ret; 337 } 338 339 static int 340 dsa_size(const EVP_PKEY *pkey) 341 { 342 return DSA_size(pkey->pkey.dsa); 343 } 344 345 static int 346 dsa_bits(const EVP_PKEY *pkey) 347 { 348 return BN_num_bits(pkey->pkey.dsa->p); 349 } 350 351 static int 352 dsa_security_bits(const EVP_PKEY *pkey) 353 { 354 return DSA_security_bits(pkey->pkey.dsa); 355 } 356 357 static int 358 dsa_missing_parameters(const EVP_PKEY *pkey) 359 { 360 const DSA *dsa = pkey->pkey.dsa; 361 362 return dsa->p == NULL || dsa->q == NULL || dsa->g == NULL; 363 } 364 365 static int 366 dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) 367 { 368 BIGNUM *a; 369 370 if ((a = BN_dup(from->pkey.dsa->p)) == NULL) 371 return 0; 372 BN_free(to->pkey.dsa->p); 373 to->pkey.dsa->p = a; 374 375 if ((a = BN_dup(from->pkey.dsa->q)) == NULL) 376 return 0; 377 BN_free(to->pkey.dsa->q); 378 to->pkey.dsa->q = a; 379 380 if ((a = BN_dup(from->pkey.dsa->g)) == NULL) 381 return 0; 382 BN_free(to->pkey.dsa->g); 383 to->pkey.dsa->g = a; 384 return 1; 385 } 386 387 static int 388 dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) 389 { 390 if (BN_cmp(a->pkey.dsa->p, b->pkey.dsa->p) || 391 BN_cmp(a->pkey.dsa->q, b->pkey.dsa->q) || 392 BN_cmp(a->pkey.dsa->g, b->pkey.dsa->g)) 393 return 0; 394 else 395 return 1; 396 } 397 398 static int 399 dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) 400 { 401 if (BN_cmp(b->pkey.dsa->pub_key, a->pkey.dsa->pub_key) != 0) 402 return 0; 403 else 404 return 1; 405 } 406 407 static void 408 dsa_free(EVP_PKEY *pkey) 409 { 410 DSA_free(pkey->pkey.dsa); 411 } 412 413 static int 414 do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) 415 { 416 const char *ktype = NULL; 417 const BIGNUM *priv_key, *pub_key; 418 int ret = 0; 419 420 if (ptype == 2) 421 priv_key = x->priv_key; 422 else 423 priv_key = NULL; 424 425 if (ptype > 0) 426 pub_key = x->pub_key; 427 else 428 pub_key = NULL; 429 430 if (ptype == 2) 431 ktype = "Private-Key"; 432 else if (ptype == 1) 433 ktype = "Public-Key"; 434 else 435 ktype = "DSA-Parameters"; 436 437 if (priv_key) { 438 if (!BIO_indent(bp, off, 128)) 439 goto err; 440 if (BIO_printf(bp, "%s: (%d bit)\n", ktype, 441 BN_num_bits(x->p)) <= 0) 442 goto err; 443 } 444 445 if (!bn_printf(bp, priv_key, off, "priv:")) 446 goto err; 447 if (!bn_printf(bp, pub_key, off, "pub: ")) 448 goto err; 449 if (!bn_printf(bp, x->p, off, "P: ")) 450 goto err; 451 if (!bn_printf(bp, x->q, off, "Q: ")) 452 goto err; 453 if (!bn_printf(bp, x->g, off, "G: ")) 454 goto err; 455 456 ret = 1; 457 458 err: 459 return ret; 460 } 461 462 static int 463 dsa_param_decode(EVP_PKEY *pkey, const unsigned char **params, int params_len) 464 { 465 DSA *dsa = NULL; 466 int ret = 0; 467 468 if ((dsa = d2i_DSAparams(NULL, params, params_len)) == NULL) { 469 DSAerror(ERR_R_DSA_LIB); 470 goto err; 471 } 472 if (!dsa_check_key(dsa)) 473 goto err; 474 if (!EVP_PKEY_assign_DSA(pkey, dsa)) 475 goto err; 476 dsa = NULL; 477 478 ret = 1; 479 480 err: 481 DSA_free(dsa); 482 483 return ret; 484 } 485 486 static int 487 dsa_param_encode(const EVP_PKEY *pkey, unsigned char **params) 488 { 489 return i2d_DSAparams(pkey->pkey.dsa, params); 490 } 491 492 static int 493 dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx) 494 { 495 return do_dsa_print(bp, pkey->pkey.dsa, indent, 0); 496 } 497 498 static int 499 dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx) 500 { 501 return do_dsa_print(bp, pkey->pkey.dsa, indent, 1); 502 } 503 504 static int 505 dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx) 506 { 507 return do_dsa_print(bp, pkey->pkey.dsa, indent, 2); 508 } 509 510 static int 511 old_dsa_priv_decode(EVP_PKEY *pkey, const unsigned char **key, int key_len) 512 { 513 DSA *dsa = NULL; 514 BN_CTX *ctx = NULL; 515 BIGNUM *result; 516 int ret = 0; 517 518 if ((dsa = d2i_DSAPrivateKey(NULL, key, key_len)) == NULL) { 519 DSAerror(ERR_R_DSA_LIB); 520 goto err; 521 } 522 523 if (!dsa_check_key(dsa)) 524 goto err; 525 526 if ((ctx = BN_CTX_new()) == NULL) 527 goto err; 528 529 BN_CTX_start(ctx); 530 531 if ((result = BN_CTX_get(ctx)) == NULL) 532 goto err; 533 534 /* 535 * Check that p and q are consistent with each other. dsa_check_key() 536 * ensures that 1 < q < p. Now check that q divides p - 1. 537 */ 538 539 if (!BN_sub(result, dsa->p, BN_value_one())) 540 goto err; 541 if (!BN_mod_ct(result, result, dsa->q, ctx)) 542 goto err; 543 if (!BN_is_zero(result)) { 544 DSAerror(DSA_R_BAD_Q_VALUE); 545 goto err; 546 } 547 548 /* 549 * Check that g generates a multiplicative subgroup of order q. 550 * We only check that g^q == 1, so the order is a divisor of q. 551 * Once we know that q is prime, this is enough. 552 */ 553 554 if (!BN_mod_exp_ct(result, dsa->g, dsa->q, dsa->p, ctx)) 555 goto err; 556 if (BN_cmp(result, BN_value_one()) != 0) { 557 DSAerror(DSA_R_INVALID_PARAMETERS); 558 goto err; 559 } 560 561 /* 562 * Check that q is not a composite number. 563 */ 564 565 if (BN_is_prime_ex(dsa->q, BN_prime_checks, ctx, NULL) <= 0) { 566 DSAerror(DSA_R_BAD_Q_VALUE); 567 goto err; 568 } 569 570 if (!EVP_PKEY_assign_DSA(pkey, dsa)) 571 goto err; 572 dsa = NULL; 573 574 ret = 1; 575 576 err: 577 BN_CTX_end(ctx); 578 BN_CTX_free(ctx); 579 DSA_free(dsa); 580 581 return ret; 582 } 583 584 static int 585 old_dsa_priv_encode(const EVP_PKEY *pkey, unsigned char **key) 586 { 587 return i2d_DSAPrivateKey(pkey->pkey.dsa, key); 588 } 589 590 static int 591 dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, const ASN1_STRING *sig, 592 int indent, ASN1_PCTX *pctx) 593 { 594 DSA_SIG *dsa_sig; 595 const unsigned char *p; 596 597 if (!sig) { 598 if (BIO_puts(bp, "\n") <= 0) 599 return 0; 600 else 601 return 1; 602 } 603 p = sig->data; 604 dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length); 605 if (dsa_sig) { 606 int rv = 0; 607 608 if (BIO_write(bp, "\n", 1) != 1) 609 goto err; 610 611 if (!bn_printf(bp, dsa_sig->r, indent, "r: ")) 612 goto err; 613 if (!bn_printf(bp, dsa_sig->s, indent, "s: ")) 614 goto err; 615 rv = 1; 616 err: 617 DSA_SIG_free(dsa_sig); 618 return rv; 619 } 620 return X509_signature_dump(bp, sig, indent); 621 } 622 623 static int 624 dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) 625 { 626 switch (op) { 627 case ASN1_PKEY_CTRL_PKCS7_SIGN: 628 if (arg1 == 0) { 629 int snid, hnid; 630 X509_ALGOR *alg1, *alg2; 631 632 PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); 633 if (alg1 == NULL || alg1->algorithm == NULL) 634 return -1; 635 hnid = OBJ_obj2nid(alg1->algorithm); 636 if (hnid == NID_undef) 637 return -1; 638 if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) 639 return -1; 640 if (!X509_ALGOR_set0_by_nid(alg2, snid, V_ASN1_UNDEF, 641 NULL)) 642 return -1; 643 } 644 return 1; 645 646 #ifndef OPENSSL_NO_CMS 647 case ASN1_PKEY_CTRL_CMS_SIGN: 648 if (arg1 == 0) { 649 int snid, hnid; 650 X509_ALGOR *alg1, *alg2; 651 652 CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2); 653 if (alg1 == NULL || alg1->algorithm == NULL) 654 return -1; 655 hnid = OBJ_obj2nid(alg1->algorithm); 656 if (hnid == NID_undef) 657 return -1; 658 if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) 659 return -1; 660 if (!X509_ALGOR_set0_by_nid(alg2, snid, V_ASN1_UNDEF, 661 NULL)) 662 return -1; 663 } 664 return 1; 665 666 case ASN1_PKEY_CTRL_CMS_RI_TYPE: 667 *(int *)arg2 = CMS_RECIPINFO_NONE; 668 return 1; 669 #endif 670 671 case ASN1_PKEY_CTRL_DEFAULT_MD_NID: 672 *(int *)arg2 = NID_sha1; 673 return 2; 674 675 default: 676 return -2; 677 } 678 } 679 680 const EVP_PKEY_ASN1_METHOD dsa_asn1_meth = { 681 .base_method = &dsa_asn1_meth, 682 .pkey_id = EVP_PKEY_DSA, 683 684 .pem_str = "DSA", 685 .info = "OpenSSL DSA method", 686 687 .pub_decode = dsa_pub_decode, 688 .pub_encode = dsa_pub_encode, 689 .pub_cmp = dsa_pub_cmp, 690 .pub_print = dsa_pub_print, 691 692 .priv_decode = dsa_priv_decode, 693 .priv_encode = dsa_priv_encode, 694 .priv_print = dsa_priv_print, 695 696 .pkey_size = dsa_size, 697 .pkey_bits = dsa_bits, 698 .pkey_security_bits = dsa_security_bits, 699 700 .param_decode = dsa_param_decode, 701 .param_encode = dsa_param_encode, 702 .param_missing = dsa_missing_parameters, 703 .param_copy = dsa_copy_parameters, 704 .param_cmp = dsa_cmp_parameters, 705 .param_print = dsa_param_print, 706 .sig_print = dsa_sig_print, 707 708 .pkey_free = dsa_free, 709 .pkey_ctrl = dsa_pkey_ctrl, 710 .old_priv_decode = old_dsa_priv_decode, 711 .old_priv_encode = old_dsa_priv_encode 712 }; 713 714 const EVP_PKEY_ASN1_METHOD dsa1_asn1_meth = { 715 .base_method = &dsa_asn1_meth, 716 .pkey_id = EVP_PKEY_DSA1, 717 .pkey_flags = ASN1_PKEY_ALIAS, 718 }; 719 720 const EVP_PKEY_ASN1_METHOD dsa2_asn1_meth = { 721 .base_method = &dsa_asn1_meth, 722 .pkey_id = EVP_PKEY_DSA2, 723 .pkey_flags = ASN1_PKEY_ALIAS, 724 }; 725 726 const EVP_PKEY_ASN1_METHOD dsa3_asn1_meth = { 727 .base_method = &dsa_asn1_meth, 728 .pkey_id = EVP_PKEY_DSA3, 729 .pkey_flags = ASN1_PKEY_ALIAS, 730 }; 731 732 const EVP_PKEY_ASN1_METHOD dsa4_asn1_meth = { 733 .base_method = &dsa_asn1_meth, 734 .pkey_id = EVP_PKEY_DSA4, 735 .pkey_flags = ASN1_PKEY_ALIAS, 736 }; 737