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