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