1 /* 2 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project 3 * 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 #include "cryptlib.h" 61 #include <openssl/x509.h> 62 #include <openssl/asn1.h> 63 #include <openssl/dh.h> 64 #include <openssl/bn.h> 65 #include "asn1_locl.h" 66 #ifndef OPENSSL_NO_CMS 67 # include <openssl/cms.h> 68 #endif 69 70 extern const EVP_PKEY_ASN1_METHOD dhx_asn1_meth; 71 72 /* 73 * i2d/d2i like DH parameter functions which use the appropriate routine for 74 * PKCS#3 DH or X9.42 DH. 75 */ 76 77 static DH *d2i_dhp(const EVP_PKEY *pkey, const unsigned char **pp, 78 long length) 79 { 80 if (pkey->ameth == &dhx_asn1_meth) 81 return d2i_DHxparams(NULL, pp, length); 82 return d2i_DHparams(NULL, pp, length); 83 } 84 85 static int i2d_dhp(const EVP_PKEY *pkey, const DH *a, unsigned char **pp) 86 { 87 if (pkey->ameth == &dhx_asn1_meth) 88 return i2d_DHxparams(a, pp); 89 return i2d_DHparams(a, pp); 90 } 91 92 static void int_dh_free(EVP_PKEY *pkey) 93 { 94 DH_free(pkey->pkey.dh); 95 } 96 97 static int dh_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) 98 { 99 const unsigned char *p, *pm; 100 int pklen, pmlen; 101 int ptype; 102 void *pval; 103 ASN1_STRING *pstr; 104 X509_ALGOR *palg; 105 ASN1_INTEGER *public_key = NULL; 106 107 DH *dh = NULL; 108 109 if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) 110 return 0; 111 X509_ALGOR_get0(NULL, &ptype, &pval, palg); 112 113 if (ptype != V_ASN1_SEQUENCE) { 114 DHerr(DH_F_DH_PUB_DECODE, DH_R_PARAMETER_ENCODING_ERROR); 115 goto err; 116 } 117 118 pstr = pval; 119 pm = pstr->data; 120 pmlen = pstr->length; 121 122 if (!(dh = d2i_dhp(pkey, &pm, pmlen))) { 123 DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR); 124 goto err; 125 } 126 127 if (!(public_key = d2i_ASN1_INTEGER(NULL, &p, pklen))) { 128 DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR); 129 goto err; 130 } 131 132 /* We have parameters now set public key */ 133 if (!(dh->pub_key = ASN1_INTEGER_to_BN(public_key, NULL))) { 134 DHerr(DH_F_DH_PUB_DECODE, DH_R_BN_DECODE_ERROR); 135 goto err; 136 } 137 138 ASN1_INTEGER_free(public_key); 139 EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh); 140 return 1; 141 142 err: 143 if (public_key) 144 ASN1_INTEGER_free(public_key); 145 if (dh) 146 DH_free(dh); 147 return 0; 148 149 } 150 151 static int dh_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) 152 { 153 DH *dh; 154 int ptype; 155 unsigned char *penc = NULL; 156 int penclen; 157 ASN1_STRING *str; 158 ASN1_INTEGER *pub_key = NULL; 159 160 dh = pkey->pkey.dh; 161 162 str = ASN1_STRING_new(); 163 if (!str) { 164 DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE); 165 goto err; 166 } 167 str->length = i2d_dhp(pkey, dh, &str->data); 168 if (str->length <= 0) { 169 DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE); 170 goto err; 171 } 172 ptype = V_ASN1_SEQUENCE; 173 174 pub_key = BN_to_ASN1_INTEGER(dh->pub_key, NULL); 175 if (!pub_key) 176 goto err; 177 178 penclen = i2d_ASN1_INTEGER(pub_key, &penc); 179 180 ASN1_INTEGER_free(pub_key); 181 182 if (penclen <= 0) { 183 DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE); 184 goto err; 185 } 186 187 if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id), 188 ptype, str, penc, penclen)) 189 return 1; 190 191 err: 192 if (penc) 193 OPENSSL_free(penc); 194 if (str) 195 ASN1_STRING_free(str); 196 197 return 0; 198 } 199 200 /* 201 * PKCS#8 DH is defined in PKCS#11 of all places. It is similar to DH in that 202 * the AlgorithmIdentifier contains the paramaters, the private key is 203 * explcitly included and the pubkey must be recalculated. 204 */ 205 206 static int dh_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) 207 { 208 const unsigned char *p, *pm; 209 int pklen, pmlen; 210 int ptype; 211 void *pval; 212 ASN1_STRING *pstr; 213 X509_ALGOR *palg; 214 ASN1_INTEGER *privkey = NULL; 215 216 DH *dh = NULL; 217 218 if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) 219 return 0; 220 221 X509_ALGOR_get0(NULL, &ptype, &pval, palg); 222 223 if (ptype != V_ASN1_SEQUENCE) 224 goto decerr; 225 226 if (!(privkey = d2i_ASN1_INTEGER(NULL, &p, pklen))) 227 goto decerr; 228 229 pstr = pval; 230 pm = pstr->data; 231 pmlen = pstr->length; 232 if (!(dh = d2i_dhp(pkey, &pm, pmlen))) 233 goto decerr; 234 /* We have parameters now set private key */ 235 if (!(dh->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) { 236 DHerr(DH_F_DH_PRIV_DECODE, DH_R_BN_ERROR); 237 goto dherr; 238 } 239 /* Calculate public key */ 240 if (!DH_generate_key(dh)) 241 goto dherr; 242 243 EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh); 244 245 ASN1_STRING_clear_free(privkey); 246 247 return 1; 248 249 decerr: 250 DHerr(DH_F_DH_PRIV_DECODE, EVP_R_DECODE_ERROR); 251 dherr: 252 DH_free(dh); 253 ASN1_STRING_clear_free(privkey); 254 return 0; 255 } 256 257 static int dh_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) 258 { 259 ASN1_STRING *params = NULL; 260 ASN1_INTEGER *prkey = NULL; 261 unsigned char *dp = NULL; 262 int dplen; 263 264 params = ASN1_STRING_new(); 265 266 if (!params) { 267 DHerr(DH_F_DH_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); 268 goto err; 269 } 270 271 params->length = i2d_dhp(pkey, pkey->pkey.dh, ¶ms->data); 272 if (params->length <= 0) { 273 DHerr(DH_F_DH_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); 274 goto err; 275 } 276 params->type = V_ASN1_SEQUENCE; 277 278 /* Get private key into integer */ 279 prkey = BN_to_ASN1_INTEGER(pkey->pkey.dh->priv_key, NULL); 280 281 if (!prkey) { 282 DHerr(DH_F_DH_PRIV_ENCODE, DH_R_BN_ERROR); 283 goto err; 284 } 285 286 dplen = i2d_ASN1_INTEGER(prkey, &dp); 287 288 ASN1_STRING_clear_free(prkey); 289 prkey = NULL; 290 291 if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0, 292 V_ASN1_SEQUENCE, params, dp, dplen)) 293 goto err; 294 295 return 1; 296 297 err: 298 if (dp != NULL) 299 OPENSSL_free(dp); 300 if (params != NULL) 301 ASN1_STRING_free(params); 302 if (prkey != NULL) 303 ASN1_STRING_clear_free(prkey); 304 return 0; 305 } 306 307 static void update_buflen(const BIGNUM *b, size_t *pbuflen) 308 { 309 size_t i; 310 if (!b) 311 return; 312 if (*pbuflen < (i = (size_t)BN_num_bytes(b))) 313 *pbuflen = i; 314 } 315 316 static int dh_param_decode(EVP_PKEY *pkey, 317 const unsigned char **pder, int derlen) 318 { 319 DH *dh; 320 if (!(dh = d2i_dhp(pkey, pder, derlen))) { 321 DHerr(DH_F_DH_PARAM_DECODE, ERR_R_DH_LIB); 322 return 0; 323 } 324 EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh); 325 return 1; 326 } 327 328 static int dh_param_encode(const EVP_PKEY *pkey, unsigned char **pder) 329 { 330 return i2d_dhp(pkey, pkey->pkey.dh, pder); 331 } 332 333 static int do_dh_print(BIO *bp, const DH *x, int indent, 334 ASN1_PCTX *ctx, int ptype) 335 { 336 unsigned char *m = NULL; 337 int reason = ERR_R_BUF_LIB, ret = 0; 338 size_t buf_len = 0; 339 340 const char *ktype = NULL; 341 342 BIGNUM *priv_key, *pub_key; 343 344 if (ptype == 2) 345 priv_key = x->priv_key; 346 else 347 priv_key = NULL; 348 349 if (ptype > 0) 350 pub_key = x->pub_key; 351 else 352 pub_key = NULL; 353 354 update_buflen(x->p, &buf_len); 355 356 if (buf_len == 0) { 357 reason = ERR_R_PASSED_NULL_PARAMETER; 358 goto err; 359 } 360 361 update_buflen(x->g, &buf_len); 362 update_buflen(x->q, &buf_len); 363 update_buflen(x->j, &buf_len); 364 update_buflen(x->counter, &buf_len); 365 update_buflen(pub_key, &buf_len); 366 update_buflen(priv_key, &buf_len); 367 368 if (ptype == 2) 369 ktype = "DH Private-Key"; 370 else if (ptype == 1) 371 ktype = "DH Public-Key"; 372 else 373 ktype = "DH Parameters"; 374 375 m = OPENSSL_malloc(buf_len + 10); 376 if (m == NULL) { 377 reason = ERR_R_MALLOC_FAILURE; 378 goto err; 379 } 380 381 BIO_indent(bp, indent, 128); 382 if (BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0) 383 goto err; 384 indent += 4; 385 386 if (!ASN1_bn_print(bp, "private-key:", priv_key, m, indent)) 387 goto err; 388 if (!ASN1_bn_print(bp, "public-key:", pub_key, m, indent)) 389 goto err; 390 391 if (!ASN1_bn_print(bp, "prime:", x->p, m, indent)) 392 goto err; 393 if (!ASN1_bn_print(bp, "generator:", x->g, m, indent)) 394 goto err; 395 if (x->q && !ASN1_bn_print(bp, "subgroup order:", x->q, m, indent)) 396 goto err; 397 if (x->j && !ASN1_bn_print(bp, "subgroup factor:", x->j, m, indent)) 398 goto err; 399 if (x->seed) { 400 int i; 401 BIO_indent(bp, indent, 128); 402 BIO_puts(bp, "seed:"); 403 for (i = 0; i < x->seedlen; i++) { 404 if ((i % 15) == 0) { 405 if (BIO_puts(bp, "\n") <= 0 406 || !BIO_indent(bp, indent + 4, 128)) 407 goto err; 408 } 409 if (BIO_printf(bp, "%02x%s", x->seed[i], 410 ((i + 1) == x->seedlen) ? "" : ":") <= 0) 411 goto err; 412 } 413 if (BIO_write(bp, "\n", 1) <= 0) 414 return (0); 415 } 416 if (x->counter && !ASN1_bn_print(bp, "counter:", x->counter, m, indent)) 417 goto err; 418 if (x->length != 0) { 419 BIO_indent(bp, indent, 128); 420 if (BIO_printf(bp, "recommended-private-length: %d bits\n", 421 (int)x->length) <= 0) 422 goto err; 423 } 424 425 ret = 1; 426 if (0) { 427 err: 428 DHerr(DH_F_DO_DH_PRINT, reason); 429 } 430 if (m != NULL) 431 OPENSSL_free(m); 432 return (ret); 433 } 434 435 static int int_dh_size(const EVP_PKEY *pkey) 436 { 437 return (DH_size(pkey->pkey.dh)); 438 } 439 440 static int dh_bits(const EVP_PKEY *pkey) 441 { 442 return BN_num_bits(pkey->pkey.dh->p); 443 } 444 445 static int dh_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) 446 { 447 if (BN_cmp(a->pkey.dh->p, b->pkey.dh->p) || 448 BN_cmp(a->pkey.dh->g, b->pkey.dh->g)) 449 return 0; 450 else if (a->ameth == &dhx_asn1_meth) { 451 if (BN_cmp(a->pkey.dh->q, b->pkey.dh->q)) 452 return 0; 453 } 454 return 1; 455 } 456 457 static int int_dh_bn_cpy(BIGNUM **dst, const BIGNUM *src) 458 { 459 BIGNUM *a; 460 if (src) { 461 a = BN_dup(src); 462 if (!a) 463 return 0; 464 } else 465 a = NULL; 466 if (*dst) 467 BN_free(*dst); 468 *dst = a; 469 return 1; 470 } 471 472 static int int_dh_param_copy(DH *to, const DH *from, int is_x942) 473 { 474 if (is_x942 == -1) 475 is_x942 = ! !from->q; 476 if (!int_dh_bn_cpy(&to->p, from->p)) 477 return 0; 478 if (!int_dh_bn_cpy(&to->g, from->g)) 479 return 0; 480 if (is_x942) { 481 if (!int_dh_bn_cpy(&to->q, from->q)) 482 return 0; 483 if (!int_dh_bn_cpy(&to->j, from->j)) 484 return 0; 485 if (to->seed) { 486 OPENSSL_free(to->seed); 487 to->seed = NULL; 488 to->seedlen = 0; 489 } 490 if (from->seed) { 491 to->seed = BUF_memdup(from->seed, from->seedlen); 492 if (!to->seed) 493 return 0; 494 to->seedlen = from->seedlen; 495 } 496 } else 497 to->length = from->length; 498 return 1; 499 } 500 501 DH *DHparams_dup(DH *dh) 502 { 503 DH *ret; 504 ret = DH_new(); 505 if (!ret) 506 return NULL; 507 if (!int_dh_param_copy(ret, dh, -1)) { 508 DH_free(ret); 509 return NULL; 510 } 511 return ret; 512 } 513 514 static int dh_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) 515 { 516 return int_dh_param_copy(to->pkey.dh, from->pkey.dh, 517 from->ameth == &dhx_asn1_meth); 518 } 519 520 static int dh_missing_parameters(const EVP_PKEY *a) 521 { 522 if (a->pkey.dh == NULL || a->pkey.dh->p == NULL || a->pkey.dh->g == NULL) 523 return 1; 524 return 0; 525 } 526 527 static int dh_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) 528 { 529 if (dh_cmp_parameters(a, b) == 0) 530 return 0; 531 if (BN_cmp(b->pkey.dh->pub_key, a->pkey.dh->pub_key) != 0) 532 return 0; 533 else 534 return 1; 535 } 536 537 static int dh_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, 538 ASN1_PCTX *ctx) 539 { 540 return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 0); 541 } 542 543 static int dh_public_print(BIO *bp, const EVP_PKEY *pkey, int indent, 544 ASN1_PCTX *ctx) 545 { 546 return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 1); 547 } 548 549 static int dh_private_print(BIO *bp, const EVP_PKEY *pkey, int indent, 550 ASN1_PCTX *ctx) 551 { 552 return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 2); 553 } 554 555 int DHparams_print(BIO *bp, const DH *x) 556 { 557 return do_dh_print(bp, x, 4, NULL, 0); 558 } 559 560 #ifndef OPENSSL_NO_CMS 561 static int dh_cms_decrypt(CMS_RecipientInfo *ri); 562 static int dh_cms_encrypt(CMS_RecipientInfo *ri); 563 #endif 564 565 static int dh_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) 566 { 567 switch (op) { 568 #ifndef OPENSSL_NO_CMS 569 570 case ASN1_PKEY_CTRL_CMS_ENVELOPE: 571 if (arg1 == 1) 572 return dh_cms_decrypt(arg2); 573 else if (arg1 == 0) 574 return dh_cms_encrypt(arg2); 575 return -2; 576 577 case ASN1_PKEY_CTRL_CMS_RI_TYPE: 578 *(int *)arg2 = CMS_RECIPINFO_AGREE; 579 return 1; 580 #endif 581 default: 582 return -2; 583 } 584 585 } 586 587 const EVP_PKEY_ASN1_METHOD dh_asn1_meth = { 588 EVP_PKEY_DH, 589 EVP_PKEY_DH, 590 0, 591 592 "DH", 593 "OpenSSL PKCS#3 DH method", 594 595 dh_pub_decode, 596 dh_pub_encode, 597 dh_pub_cmp, 598 dh_public_print, 599 600 dh_priv_decode, 601 dh_priv_encode, 602 dh_private_print, 603 604 int_dh_size, 605 dh_bits, 606 607 dh_param_decode, 608 dh_param_encode, 609 dh_missing_parameters, 610 dh_copy_parameters, 611 dh_cmp_parameters, 612 dh_param_print, 613 0, 614 615 int_dh_free, 616 0 617 }; 618 619 const EVP_PKEY_ASN1_METHOD dhx_asn1_meth = { 620 EVP_PKEY_DHX, 621 EVP_PKEY_DHX, 622 0, 623 624 "X9.42 DH", 625 "OpenSSL X9.42 DH method", 626 627 dh_pub_decode, 628 dh_pub_encode, 629 dh_pub_cmp, 630 dh_public_print, 631 632 dh_priv_decode, 633 dh_priv_encode, 634 dh_private_print, 635 636 int_dh_size, 637 dh_bits, 638 639 dh_param_decode, 640 dh_param_encode, 641 dh_missing_parameters, 642 dh_copy_parameters, 643 dh_cmp_parameters, 644 dh_param_print, 645 0, 646 647 int_dh_free, 648 dh_pkey_ctrl 649 }; 650 651 #ifndef OPENSSL_NO_CMS 652 653 static int dh_cms_set_peerkey(EVP_PKEY_CTX *pctx, 654 X509_ALGOR *alg, ASN1_BIT_STRING *pubkey) 655 { 656 ASN1_OBJECT *aoid; 657 int atype; 658 void *aval; 659 ASN1_INTEGER *public_key = NULL; 660 int rv = 0; 661 EVP_PKEY *pkpeer = NULL, *pk = NULL; 662 DH *dhpeer = NULL; 663 const unsigned char *p; 664 int plen; 665 666 X509_ALGOR_get0(&aoid, &atype, &aval, alg); 667 if (OBJ_obj2nid(aoid) != NID_dhpublicnumber) 668 goto err; 669 /* Only absent parameters allowed in RFC XXXX */ 670 if (atype != V_ASN1_UNDEF && atype == V_ASN1_NULL) 671 goto err; 672 673 pk = EVP_PKEY_CTX_get0_pkey(pctx); 674 if (!pk) 675 goto err; 676 if (pk->type != EVP_PKEY_DHX) 677 goto err; 678 /* Get parameters from parent key */ 679 dhpeer = DHparams_dup(pk->pkey.dh); 680 /* We have parameters now set public key */ 681 plen = ASN1_STRING_length(pubkey); 682 p = ASN1_STRING_data(pubkey); 683 if (!p || !plen) 684 goto err; 685 686 if (!(public_key = d2i_ASN1_INTEGER(NULL, &p, plen))) { 687 DHerr(DH_F_DH_CMS_SET_PEERKEY, DH_R_DECODE_ERROR); 688 goto err; 689 } 690 691 /* We have parameters now set public key */ 692 if (!(dhpeer->pub_key = ASN1_INTEGER_to_BN(public_key, NULL))) { 693 DHerr(DH_F_DH_CMS_SET_PEERKEY, DH_R_BN_DECODE_ERROR); 694 goto err; 695 } 696 697 pkpeer = EVP_PKEY_new(); 698 if (!pkpeer) 699 goto err; 700 EVP_PKEY_assign(pkpeer, pk->ameth->pkey_id, dhpeer); 701 dhpeer = NULL; 702 if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0) 703 rv = 1; 704 err: 705 if (public_key) 706 ASN1_INTEGER_free(public_key); 707 if (pkpeer) 708 EVP_PKEY_free(pkpeer); 709 if (dhpeer) 710 DH_free(dhpeer); 711 return rv; 712 } 713 714 static int dh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri) 715 { 716 int rv = 0; 717 718 X509_ALGOR *alg, *kekalg = NULL; 719 ASN1_OCTET_STRING *ukm; 720 const unsigned char *p; 721 unsigned char *dukm = NULL; 722 size_t dukmlen = 0; 723 int keylen, plen; 724 const EVP_CIPHER *kekcipher; 725 EVP_CIPHER_CTX *kekctx; 726 727 if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm)) 728 goto err; 729 730 /* 731 * For DH we only have one OID permissible. If ever any more get defined 732 * we will need something cleverer. 733 */ 734 if (OBJ_obj2nid(alg->algorithm) != NID_id_smime_alg_ESDH) { 735 DHerr(DH_F_DH_CMS_SET_SHARED_INFO, DH_R_KDF_PARAMETER_ERROR); 736 goto err; 737 } 738 739 if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, EVP_PKEY_DH_KDF_X9_42) <= 0) 740 goto err; 741 742 if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, EVP_sha1()) <= 0) 743 goto err; 744 745 if (alg->parameter->type != V_ASN1_SEQUENCE) 746 goto err; 747 748 p = alg->parameter->value.sequence->data; 749 plen = alg->parameter->value.sequence->length; 750 kekalg = d2i_X509_ALGOR(NULL, &p, plen); 751 if (!kekalg) 752 goto err; 753 kekctx = CMS_RecipientInfo_kari_get0_ctx(ri); 754 if (!kekctx) 755 goto err; 756 kekcipher = EVP_get_cipherbyobj(kekalg->algorithm); 757 if (!kekcipher || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE) 758 goto err; 759 if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL)) 760 goto err; 761 if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0) 762 goto err; 763 764 keylen = EVP_CIPHER_CTX_key_length(kekctx); 765 if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0) 766 goto err; 767 /* Use OBJ_nid2obj to ensure we use built in OID that isn't freed */ 768 if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx, 769 OBJ_nid2obj(EVP_CIPHER_type(kekcipher))) 770 <= 0) 771 goto err; 772 773 if (ukm) { 774 dukmlen = ASN1_STRING_length(ukm); 775 dukm = BUF_memdup(ASN1_STRING_data(ukm), dukmlen); 776 if (!dukm) 777 goto err; 778 } 779 780 if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0) 781 goto err; 782 dukm = NULL; 783 784 rv = 1; 785 err: 786 if (kekalg) 787 X509_ALGOR_free(kekalg); 788 if (dukm) 789 OPENSSL_free(dukm); 790 return rv; 791 } 792 793 static int dh_cms_decrypt(CMS_RecipientInfo *ri) 794 { 795 EVP_PKEY_CTX *pctx; 796 pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); 797 if (!pctx) 798 return 0; 799 /* See if we need to set peer key */ 800 if (!EVP_PKEY_CTX_get0_peerkey(pctx)) { 801 X509_ALGOR *alg; 802 ASN1_BIT_STRING *pubkey; 803 if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey, 804 NULL, NULL, NULL)) 805 return 0; 806 if (!alg || !pubkey) 807 return 0; 808 if (!dh_cms_set_peerkey(pctx, alg, pubkey)) { 809 DHerr(DH_F_DH_CMS_DECRYPT, DH_R_PEER_KEY_ERROR); 810 return 0; 811 } 812 } 813 /* Set DH derivation parameters and initialise unwrap context */ 814 if (!dh_cms_set_shared_info(pctx, ri)) { 815 DHerr(DH_F_DH_CMS_DECRYPT, DH_R_SHARED_INFO_ERROR); 816 return 0; 817 } 818 return 1; 819 } 820 821 static int dh_cms_encrypt(CMS_RecipientInfo *ri) 822 { 823 EVP_PKEY_CTX *pctx; 824 EVP_PKEY *pkey; 825 EVP_CIPHER_CTX *ctx; 826 int keylen; 827 X509_ALGOR *talg, *wrap_alg = NULL; 828 ASN1_OBJECT *aoid; 829 ASN1_BIT_STRING *pubkey; 830 ASN1_STRING *wrap_str; 831 ASN1_OCTET_STRING *ukm; 832 unsigned char *penc = NULL, *dukm = NULL; 833 int penclen; 834 size_t dukmlen = 0; 835 int rv = 0; 836 int kdf_type, wrap_nid; 837 const EVP_MD *kdf_md; 838 pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); 839 if (!pctx) 840 return 0; 841 /* Get ephemeral key */ 842 pkey = EVP_PKEY_CTX_get0_pkey(pctx); 843 if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey, 844 NULL, NULL, NULL)) 845 goto err; 846 X509_ALGOR_get0(&aoid, NULL, NULL, talg); 847 /* Is everything uninitialised? */ 848 if (aoid == OBJ_nid2obj(NID_undef)) { 849 ASN1_INTEGER *pubk; 850 pubk = BN_to_ASN1_INTEGER(pkey->pkey.dh->pub_key, NULL); 851 if (!pubk) 852 goto err; 853 /* Set the key */ 854 855 penclen = i2d_ASN1_INTEGER(pubk, &penc); 856 ASN1_INTEGER_free(pubk); 857 if (penclen <= 0) 858 goto err; 859 ASN1_STRING_set0(pubkey, penc, penclen); 860 pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); 861 pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT; 862 863 penc = NULL; 864 X509_ALGOR_set0(talg, OBJ_nid2obj(NID_dhpublicnumber), 865 V_ASN1_UNDEF, NULL); 866 } 867 868 /* See if custom paraneters set */ 869 kdf_type = EVP_PKEY_CTX_get_dh_kdf_type(pctx); 870 if (kdf_type <= 0) 871 goto err; 872 if (!EVP_PKEY_CTX_get_dh_kdf_md(pctx, &kdf_md)) 873 goto err; 874 875 if (kdf_type == EVP_PKEY_DH_KDF_NONE) { 876 kdf_type = EVP_PKEY_DH_KDF_X9_42; 877 if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, kdf_type) <= 0) 878 goto err; 879 } else if (kdf_type != EVP_PKEY_DH_KDF_X9_42) 880 /* Unknown KDF */ 881 goto err; 882 if (kdf_md == NULL) { 883 /* Only SHA1 supported */ 884 kdf_md = EVP_sha1(); 885 if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, kdf_md) <= 0) 886 goto err; 887 } else if (EVP_MD_type(kdf_md) != NID_sha1) 888 /* Unsupported digest */ 889 goto err; 890 891 if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm)) 892 goto err; 893 894 /* Get wrap NID */ 895 ctx = CMS_RecipientInfo_kari_get0_ctx(ri); 896 wrap_nid = EVP_CIPHER_CTX_type(ctx); 897 if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx, OBJ_nid2obj(wrap_nid)) <= 0) 898 goto err; 899 keylen = EVP_CIPHER_CTX_key_length(ctx); 900 901 /* Package wrap algorithm in an AlgorithmIdentifier */ 902 903 wrap_alg = X509_ALGOR_new(); 904 if (!wrap_alg) 905 goto err; 906 wrap_alg->algorithm = OBJ_nid2obj(wrap_nid); 907 wrap_alg->parameter = ASN1_TYPE_new(); 908 if (!wrap_alg->parameter) 909 goto err; 910 if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0) 911 goto err; 912 if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) { 913 ASN1_TYPE_free(wrap_alg->parameter); 914 wrap_alg->parameter = NULL; 915 } 916 917 if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0) 918 goto err; 919 920 if (ukm) { 921 dukmlen = ASN1_STRING_length(ukm); 922 dukm = BUF_memdup(ASN1_STRING_data(ukm), dukmlen); 923 if (!dukm) 924 goto err; 925 } 926 927 if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0) 928 goto err; 929 dukm = NULL; 930 931 /* 932 * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter 933 * of another AlgorithmIdentifier. 934 */ 935 penc = NULL; 936 penclen = i2d_X509_ALGOR(wrap_alg, &penc); 937 if (!penc || !penclen) 938 goto err; 939 wrap_str = ASN1_STRING_new(); 940 if (!wrap_str) 941 goto err; 942 ASN1_STRING_set0(wrap_str, penc, penclen); 943 penc = NULL; 944 X509_ALGOR_set0(talg, OBJ_nid2obj(NID_id_smime_alg_ESDH), 945 V_ASN1_SEQUENCE, wrap_str); 946 947 rv = 1; 948 949 err: 950 if (penc) 951 OPENSSL_free(penc); 952 if (wrap_alg) 953 X509_ALGOR_free(wrap_alg); 954 return rv; 955 } 956 957 #endif 958