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