1 /* $OpenBSD: dsa_ameth.c,v 1.14 2014/07/13 12:45:01 miod 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/dsa.h> 66 #include <openssl/err.h> 67 #include <openssl/x509.h> 68 69 #ifndef OPENSSL_NO_CMS 70 #include <openssl/cms.h> 71 #endif 72 73 #include "asn1_locl.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 void *pval; 82 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 DSAerr(DSA_F_DSA_PUB_DECODE, 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 DSAerr(DSA_F_DSA_PUB_DECODE, ERR_R_MALLOC_FAILURE); 104 goto err; 105 } 106 } else { 107 DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_PARAMETER_ENCODING_ERROR); 108 goto err; 109 } 110 111 if (!(public_key=d2i_ASN1_INTEGER(NULL, &p, pklen))) { 112 DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR); 113 goto err; 114 } 115 116 if (!(dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL))) { 117 DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_BN_DECODE_ERROR); 118 goto err; 119 } 120 121 ASN1_INTEGER_free(public_key); 122 EVP_PKEY_assign_DSA(pkey, dsa); 123 return 1; 124 125 err: 126 if (public_key) 127 ASN1_INTEGER_free(public_key); 128 DSA_free(dsa); 129 return 0; 130 } 131 132 static int 133 dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) 134 { 135 DSA *dsa; 136 void *pval = NULL; 137 int ptype; 138 unsigned char *penc = NULL; 139 int penclen; 140 141 dsa = pkey->pkey.dsa; 142 if (pkey->save_parameters && dsa->p && dsa->q && dsa->g) { 143 ASN1_STRING *str; 144 145 str = ASN1_STRING_new(); 146 str->length = i2d_DSAparams(dsa, &str->data); 147 if (str->length <= 0) { 148 DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE); 149 goto err; 150 } 151 pval = str; 152 ptype = V_ASN1_SEQUENCE; 153 } else 154 ptype = V_ASN1_UNDEF; 155 156 dsa->write_params = 0; 157 158 penclen = i2d_DSAPublicKey(dsa, &penc); 159 160 if (penclen <= 0) { 161 DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE); 162 goto err; 163 } 164 165 if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA), ptype, pval, 166 penc, penclen)) 167 return 1; 168 169 err: 170 free(penc); 171 ASN1_STRING_free(pval); 172 173 return 0; 174 } 175 176 /* In PKCS#8 DSA: you just get a private key integer and parameters in the 177 * AlgorithmIdentifier the pubkey must be recalculated. 178 */ 179 180 static int 181 dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) 182 { 183 const unsigned char *p, *pm; 184 int pklen, pmlen; 185 int ptype; 186 void *pval; 187 ASN1_STRING *pstr; 188 X509_ALGOR *palg; 189 ASN1_INTEGER *privkey = NULL; 190 BN_CTX *ctx = NULL; 191 STACK_OF(ASN1_TYPE) *ndsa = NULL; 192 DSA *dsa = NULL; 193 194 if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) 195 return 0; 196 X509_ALGOR_get0(NULL, &ptype, &pval, palg); 197 198 /* Check for broken DSA PKCS#8, UGH! */ 199 if (*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED)) { 200 ASN1_TYPE *t1, *t2; 201 if (!(ndsa = d2i_ASN1_SEQUENCE_ANY(NULL, &p, pklen))) 202 goto decerr; 203 if (sk_ASN1_TYPE_num(ndsa) != 2) 204 goto decerr; 205 /* 206 * Handle Two broken types: 207 * SEQUENCE {parameters, priv_key} 208 * SEQUENCE {pub_key, priv_key} 209 */ 210 211 t1 = sk_ASN1_TYPE_value(ndsa, 0); 212 t2 = sk_ASN1_TYPE_value(ndsa, 1); 213 if (t1->type == V_ASN1_SEQUENCE) { 214 p8->broken = PKCS8_EMBEDDED_PARAM; 215 pval = t1->value.ptr; 216 } else if (ptype == V_ASN1_SEQUENCE) 217 p8->broken = PKCS8_NS_DB; 218 else 219 goto decerr; 220 221 if (t2->type != V_ASN1_INTEGER) 222 goto decerr; 223 224 privkey = t2->value.integer; 225 } else { 226 const unsigned char *q = p; 227 228 if (!(privkey=d2i_ASN1_INTEGER(NULL, &p, pklen))) 229 goto decerr; 230 if (privkey->type == V_ASN1_NEG_INTEGER) { 231 p8->broken = PKCS8_NEG_PRIVKEY; 232 ASN1_INTEGER_free(privkey); 233 if (!(privkey = d2i_ASN1_UINTEGER(NULL, &q, pklen))) 234 goto decerr; 235 } 236 if (ptype != V_ASN1_SEQUENCE) 237 goto decerr; 238 } 239 240 pstr = pval; 241 pm = pstr->data; 242 pmlen = pstr->length; 243 if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen))) 244 goto decerr; 245 /* We have parameters now set private key */ 246 if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) { 247 DSAerr(DSA_F_DSA_PRIV_DECODE,DSA_R_BN_ERROR); 248 goto dsaerr; 249 } 250 /* Calculate public key */ 251 if (!(dsa->pub_key = BN_new())) { 252 DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE); 253 goto dsaerr; 254 } 255 if (!(ctx = BN_CTX_new())) { 256 DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE); 257 goto dsaerr; 258 } 259 260 if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) { 261 DSAerr(DSA_F_DSA_PRIV_DECODE,DSA_R_BN_ERROR); 262 goto dsaerr; 263 } 264 265 EVP_PKEY_assign_DSA(pkey, dsa); 266 BN_CTX_free(ctx); 267 if (ndsa) 268 sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); 269 else 270 ASN1_INTEGER_free(privkey); 271 272 return 1; 273 274 decerr: 275 DSAerr(DSA_F_DSA_PRIV_DECODE, EVP_R_DECODE_ERROR); 276 dsaerr: 277 BN_CTX_free(ctx); 278 if (ndsa) 279 sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); 280 else 281 ASN1_INTEGER_free(privkey); 282 DSA_free(dsa); 283 return 0; 284 } 285 286 static int 287 dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) 288 { 289 ASN1_STRING *params = NULL; 290 ASN1_INTEGER *prkey = NULL; 291 unsigned char *dp = NULL; 292 int dplen; 293 294 params = ASN1_STRING_new(); 295 if (!params) { 296 DSAerr(DSA_F_DSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); 297 goto err; 298 } 299 300 params->length = i2d_DSAparams(pkey->pkey.dsa, ¶ms->data); 301 if (params->length <= 0) { 302 DSAerr(DSA_F_DSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); 303 goto err; 304 } 305 params->type = V_ASN1_SEQUENCE; 306 307 /* Get private key into integer */ 308 prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL); 309 if (!prkey) { 310 DSAerr(DSA_F_DSA_PRIV_ENCODE, DSA_R_BN_ERROR); 311 goto err; 312 } 313 314 dplen = i2d_ASN1_INTEGER(prkey, &dp); 315 316 ASN1_INTEGER_free(prkey); 317 prkey = NULL; 318 319 if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dsa), 0, V_ASN1_SEQUENCE, 320 params, dp, dplen)) 321 goto err; 322 323 return 1; 324 325 err: 326 free(dp); 327 ASN1_STRING_free(params); 328 ASN1_INTEGER_free(prkey); 329 return 0; 330 } 331 332 static int 333 int_dsa_size(const EVP_PKEY *pkey) 334 { 335 return DSA_size(pkey->pkey.dsa); 336 } 337 338 static int 339 dsa_bits(const EVP_PKEY *pkey) 340 { 341 return BN_num_bits(pkey->pkey.dsa->p); 342 } 343 344 static int 345 dsa_missing_parameters(const EVP_PKEY *pkey) 346 { 347 DSA *dsa; 348 349 dsa = pkey->pkey.dsa; 350 if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) 351 return 1; 352 return 0; 353 } 354 355 static int 356 dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) 357 { 358 BIGNUM *a; 359 360 if ((a = BN_dup(from->pkey.dsa->p)) == NULL) 361 return 0; 362 BN_free(to->pkey.dsa->p); 363 to->pkey.dsa->p = a; 364 365 if ((a = BN_dup(from->pkey.dsa->q)) == NULL) 366 return 0; 367 BN_free(to->pkey.dsa->q); 368 to->pkey.dsa->q = a; 369 370 if ((a = BN_dup(from->pkey.dsa->g)) == NULL) 371 return 0; 372 BN_free(to->pkey.dsa->g); 373 to->pkey.dsa->g = a; 374 return 1; 375 } 376 377 static int 378 dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) 379 { 380 if (BN_cmp(a->pkey.dsa->p, b->pkey.dsa->p) || 381 BN_cmp(a->pkey.dsa->q, b->pkey.dsa->q) || 382 BN_cmp(a->pkey.dsa->g, b->pkey.dsa->g)) 383 return 0; 384 else 385 return 1; 386 } 387 388 static int 389 dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) 390 { 391 if (BN_cmp(b->pkey.dsa->pub_key, a->pkey.dsa->pub_key) != 0) 392 return 0; 393 else 394 return 1; 395 } 396 397 static void 398 int_dsa_free(EVP_PKEY *pkey) 399 { 400 DSA_free(pkey->pkey.dsa); 401 } 402 403 static void 404 update_buflen(const BIGNUM *b, size_t *pbuflen) 405 { 406 size_t i; 407 408 if (!b) 409 return; 410 if (*pbuflen < (i = (size_t)BN_num_bytes(b))) 411 *pbuflen = i; 412 } 413 414 static int 415 do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) 416 { 417 unsigned char *m = NULL; 418 int ret = 0; 419 size_t buf_len = 0; 420 const char *ktype = NULL; 421 const BIGNUM *priv_key, *pub_key; 422 423 if (ptype == 2) 424 priv_key = x->priv_key; 425 else 426 priv_key = NULL; 427 428 if (ptype > 0) 429 pub_key = x->pub_key; 430 else 431 pub_key = NULL; 432 433 if (ptype == 2) 434 ktype = "Private-Key"; 435 else if (ptype == 1) 436 ktype = "Public-Key"; 437 else 438 ktype = "DSA-Parameters"; 439 440 update_buflen(x->p, &buf_len); 441 update_buflen(x->q, &buf_len); 442 update_buflen(x->g, &buf_len); 443 update_buflen(priv_key, &buf_len); 444 update_buflen(pub_key, &buf_len); 445 446 m = malloc(buf_len + 10); 447 if (m == NULL) { 448 DSAerr(DSA_F_DO_DSA_PRINT, ERR_R_MALLOC_FAILURE); 449 goto err; 450 } 451 452 if (priv_key) { 453 if (!BIO_indent(bp, off, 128)) 454 goto err; 455 if (BIO_printf(bp, "%s: (%d bit)\n", ktype, 456 BN_num_bits(x->p)) <= 0) 457 goto err; 458 } 459 460 if (!ASN1_bn_print(bp, "priv:", priv_key, m, off)) 461 goto err; 462 if (!ASN1_bn_print(bp, "pub: ", pub_key, m, off)) 463 goto err; 464 if (!ASN1_bn_print(bp, "P: ", x->p, m, off)) 465 goto err; 466 if (!ASN1_bn_print(bp, "Q: ", x->q, m, off)) 467 goto err; 468 if (!ASN1_bn_print(bp, "G: ", x->g, m, off)) 469 goto err; 470 ret = 1; 471 err: 472 free(m); 473 return(ret); 474 } 475 476 static int 477 dsa_param_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen) 478 { 479 DSA *dsa; 480 481 if (!(dsa = d2i_DSAparams(NULL, pder, derlen))) { 482 DSAerr(DSA_F_DSA_PARAM_DECODE, ERR_R_DSA_LIB); 483 return 0; 484 } 485 EVP_PKEY_assign_DSA(pkey, dsa); 486 return 1; 487 } 488 489 static int 490 dsa_param_encode(const EVP_PKEY *pkey, unsigned char **pder) 491 { 492 return i2d_DSAparams(pkey->pkey.dsa, pder); 493 } 494 495 static int 496 dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx) 497 { 498 return do_dsa_print(bp, pkey->pkey.dsa, indent, 0); 499 } 500 501 static int 502 dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx) 503 { 504 return do_dsa_print(bp, pkey->pkey.dsa, indent, 1); 505 } 506 507 static int 508 dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx) 509 { 510 return do_dsa_print(bp, pkey->pkey.dsa, indent, 2); 511 } 512 513 static int 514 old_dsa_priv_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen) 515 { 516 DSA *dsa; 517 518 if (!(dsa = d2i_DSAPrivateKey (NULL, pder, derlen))) { 519 DSAerr(DSA_F_OLD_DSA_PRIV_DECODE, ERR_R_DSA_LIB); 520 return 0; 521 } 522 EVP_PKEY_assign_DSA(pkey, dsa); 523 return 1; 524 } 525 526 static int 527 old_dsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) 528 { 529 return i2d_DSAPrivateKey(pkey->pkey.dsa, pder); 530 } 531 532 static int 533 dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, const ASN1_STRING *sig, 534 int indent, ASN1_PCTX *pctx) 535 { 536 DSA_SIG *dsa_sig; 537 const unsigned char *p; 538 539 if (!sig) { 540 if (BIO_puts(bp, "\n") <= 0) 541 return 0; 542 else 543 return 1; 544 } 545 p = sig->data; 546 dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length); 547 if (dsa_sig) { 548 int rv = 0; 549 size_t buf_len = 0; 550 unsigned char *m = NULL; 551 552 update_buflen(dsa_sig->r, &buf_len); 553 update_buflen(dsa_sig->s, &buf_len); 554 m = malloc(buf_len + 10); 555 if (m == NULL) { 556 DSAerr(DSA_F_DSA_SIG_PRINT, ERR_R_MALLOC_FAILURE); 557 goto err; 558 } 559 560 if (BIO_write(bp, "\n", 1) != 1) 561 goto err; 562 563 if (!ASN1_bn_print(bp, "r: ", dsa_sig->r, m, indent)) 564 goto err; 565 if (!ASN1_bn_print(bp, "s: ", dsa_sig->s, m, indent)) 566 goto err; 567 rv = 1; 568 err: 569 free(m); 570 DSA_SIG_free(dsa_sig); 571 return rv; 572 } 573 return X509_signature_dump(bp, sig, indent); 574 } 575 576 static int 577 dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) 578 { 579 switch (op) { 580 case ASN1_PKEY_CTRL_PKCS7_SIGN: 581 if (arg1 == 0) { 582 int snid, hnid; 583 X509_ALGOR *alg1, *alg2; 584 585 PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); 586 if (alg1 == NULL || alg1->algorithm == NULL) 587 return -1; 588 hnid = OBJ_obj2nid(alg1->algorithm); 589 if (hnid == NID_undef) 590 return -1; 591 if (!OBJ_find_sigid_by_algs(&snid, hnid, 592 EVP_PKEY_id(pkey))) 593 return -1; 594 X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 595 0); 596 } 597 return 1; 598 #ifndef OPENSSL_NO_CMS 599 case ASN1_PKEY_CTRL_CMS_SIGN: 600 if (arg1 == 0) { 601 int snid, hnid; 602 X509_ALGOR *alg1, *alg2; 603 604 CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2); 605 if (alg1 == NULL || alg1->algorithm == NULL) 606 return -1; 607 hnid = OBJ_obj2nid(alg1->algorithm); 608 if (hnid == NID_undef) 609 return -1; 610 if (!OBJ_find_sigid_by_algs(&snid, hnid, 611 EVP_PKEY_id(pkey))) 612 return -1; 613 X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 614 0); 615 } 616 return 1; 617 #endif 618 619 case ASN1_PKEY_CTRL_DEFAULT_MD_NID: 620 *(int *)arg2 = NID_sha1; 621 return 2; 622 623 default: 624 return -2; 625 } 626 } 627 628 /* NB these are sorted in pkey_id order, lowest first */ 629 630 const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] = { 631 { 632 .pkey_id = EVP_PKEY_DSA2, 633 .pkey_base_id = EVP_PKEY_DSA, 634 .pkey_flags = ASN1_PKEY_ALIAS 635 }, 636 637 { 638 .pkey_id = EVP_PKEY_DSA1, 639 .pkey_base_id = EVP_PKEY_DSA, 640 .pkey_flags = ASN1_PKEY_ALIAS 641 }, 642 643 { 644 .pkey_id = EVP_PKEY_DSA4, 645 .pkey_base_id = EVP_PKEY_DSA, 646 .pkey_flags = ASN1_PKEY_ALIAS 647 }, 648 649 { 650 .pkey_id = EVP_PKEY_DSA3, 651 .pkey_base_id = EVP_PKEY_DSA, 652 .pkey_flags = ASN1_PKEY_ALIAS 653 }, 654 655 { 656 .pkey_id = EVP_PKEY_DSA, 657 .pkey_base_id = EVP_PKEY_DSA, 658 659 .pem_str = "DSA", 660 .info = "OpenSSL DSA method", 661 662 .pub_decode = dsa_pub_decode, 663 .pub_encode = dsa_pub_encode, 664 .pub_cmp = dsa_pub_cmp, 665 .pub_print = dsa_pub_print, 666 667 .priv_decode = dsa_priv_decode, 668 .priv_encode = dsa_priv_encode, 669 .priv_print = dsa_priv_print, 670 671 .pkey_size = int_dsa_size, 672 .pkey_bits = dsa_bits, 673 674 .param_decode = dsa_param_decode, 675 .param_encode = dsa_param_encode, 676 .param_missing = dsa_missing_parameters, 677 .param_copy = dsa_copy_parameters, 678 .param_cmp = dsa_cmp_parameters, 679 .param_print = dsa_param_print, 680 .sig_print = dsa_sig_print, 681 682 .pkey_free = int_dsa_free, 683 .pkey_ctrl = dsa_pkey_ctrl, 684 .old_priv_decode = old_dsa_priv_decode, 685 .old_priv_encode = old_dsa_priv_encode 686 } 687 }; 688