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