1 /* $NetBSD: openssldh_link.c,v 1.1 2024/02/18 20:57:32 christos Exp $ */ 2 3 /* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * SPDX-License-Identifier: MPL-2.0 AND ISC 7 * 8 * This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 * 12 * See the COPYRIGHT file distributed with this work for additional 13 * information regarding copyright ownership. 14 */ 15 16 /* 17 * Copyright (C) Network Associates, Inc. 18 * 19 * Permission to use, copy, modify, and/or distribute this software for any 20 * purpose with or without fee is hereby granted, provided that the above 21 * copyright notice and this permission notice appear in all copies. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS 24 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 25 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE 26 * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 27 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 28 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR 29 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 30 */ 31 32 /*! \file */ 33 34 #include <ctype.h> 35 #include <inttypes.h> 36 #include <stdbool.h> 37 38 #include <openssl/opensslv.h> 39 40 #include <isc/mem.h> 41 #include <isc/safe.h> 42 #include <isc/string.h> 43 #include <isc/util.h> 44 45 #include <pk11/site.h> 46 47 #include <dst/result.h> 48 49 #include "dst_internal.h" 50 #include "dst_openssl.h" 51 #include "dst_parse.h" 52 53 #define PRIME2 "02" 54 55 #define PRIME768 \ 56 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088" \ 57 "A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25" \ 58 "F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFF" \ 59 "F" 60 61 #define PRIME1024 \ 62 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08" \ 63 "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF2" \ 64 "5F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406" \ 65 "B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF" 66 67 #define PRIME1536 \ 68 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \ 69 "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ 70 "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \ 71 "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ 72 "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \ 73 "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \ 74 "83655D23DCA3AD961C62F356208552BB9ED529077096966D" \ 75 "670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF" 76 77 static BIGNUM *bn2 = NULL, *bn768 = NULL, *bn1024 = NULL, *bn1536 = NULL; 78 79 #if !HAVE_DH_GET0_KEY 80 /* 81 * DH_get0_key, DH_set0_key, DH_get0_pqg and DH_set0_pqg 82 * are from OpenSSL 1.1.0. 83 */ 84 static void 85 DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key) { 86 if (pub_key != NULL) { 87 *pub_key = dh->pub_key; 88 } 89 if (priv_key != NULL) { 90 *priv_key = dh->priv_key; 91 } 92 } 93 94 static int 95 DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) { 96 if (pub_key != NULL) { 97 BN_free(dh->pub_key); 98 dh->pub_key = pub_key; 99 } 100 101 if (priv_key != NULL) { 102 BN_free(dh->priv_key); 103 dh->priv_key = priv_key; 104 } 105 106 return (1); 107 } 108 109 static void 110 DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, 111 const BIGNUM **g) { 112 if (p != NULL) { 113 *p = dh->p; 114 } 115 if (q != NULL) { 116 *q = dh->q; 117 } 118 if (g != NULL) { 119 *g = dh->g; 120 } 121 } 122 123 static int 124 DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) { 125 /* If the fields p and g in d are NULL, the corresponding input 126 * parameters MUST be non-NULL. q may remain NULL. 127 */ 128 if ((dh->p == NULL && p == NULL) || (dh->g == NULL && g == NULL)) { 129 return (0); 130 } 131 132 if (p != NULL) { 133 BN_free(dh->p); 134 dh->p = p; 135 } 136 if (q != NULL) { 137 BN_free(dh->q); 138 dh->q = q; 139 } 140 if (g != NULL) { 141 BN_free(dh->g); 142 dh->g = g; 143 } 144 145 if (q != NULL) { 146 dh->length = BN_num_bits(q); 147 } 148 149 return (1); 150 } 151 152 #define DH_clear_flags(d, f) (d)->flags &= ~(f) 153 154 #endif /* !HAVE_DH_GET0_KEY */ 155 156 static isc_result_t 157 openssldh_computesecret(const dst_key_t *pub, const dst_key_t *priv, 158 isc_buffer_t *secret) { 159 DH *dhpub, *dhpriv; 160 const BIGNUM *pub_key = NULL; 161 int ret; 162 isc_region_t r; 163 unsigned int len; 164 165 REQUIRE(pub->keydata.dh != NULL); 166 REQUIRE(priv->keydata.dh != NULL); 167 168 dhpub = pub->keydata.dh; 169 dhpriv = priv->keydata.dh; 170 171 len = DH_size(dhpriv); 172 isc_buffer_availableregion(secret, &r); 173 if (r.length < len) { 174 return (ISC_R_NOSPACE); 175 } 176 177 DH_get0_key(dhpub, &pub_key, NULL); 178 ret = DH_compute_key(r.base, pub_key, dhpriv); 179 if (ret <= 0) { 180 return (dst__openssl_toresult2("DH_compute_key", 181 DST_R_COMPUTESECRETFAILURE)); 182 } 183 isc_buffer_add(secret, len); 184 return (ISC_R_SUCCESS); 185 } 186 187 static bool 188 openssldh_compare(const dst_key_t *key1, const dst_key_t *key2) { 189 DH *dh1, *dh2; 190 const BIGNUM *pub_key1 = NULL, *pub_key2 = NULL; 191 const BIGNUM *priv_key1 = NULL, *priv_key2 = NULL; 192 const BIGNUM *p1 = NULL, *g1 = NULL, *p2 = NULL, *g2 = NULL; 193 194 dh1 = key1->keydata.dh; 195 dh2 = key2->keydata.dh; 196 197 if (dh1 == NULL && dh2 == NULL) { 198 return (true); 199 } else if (dh1 == NULL || dh2 == NULL) { 200 return (false); 201 } 202 203 DH_get0_key(dh1, &pub_key1, &priv_key1); 204 DH_get0_key(dh2, &pub_key2, &priv_key2); 205 DH_get0_pqg(dh1, &p1, NULL, &g1); 206 DH_get0_pqg(dh2, &p2, NULL, &g2); 207 208 if (BN_cmp(p1, p2) != 0 || BN_cmp(g1, g2) != 0 || 209 BN_cmp(pub_key1, pub_key2) != 0) 210 { 211 return (false); 212 } 213 214 if (priv_key1 != NULL || priv_key2 != NULL) { 215 if (priv_key1 == NULL || priv_key2 == NULL) { 216 return (false); 217 } 218 if (BN_cmp(priv_key1, priv_key2) != 0) { 219 return (false); 220 } 221 } 222 return (true); 223 } 224 225 static bool 226 openssldh_paramcompare(const dst_key_t *key1, const dst_key_t *key2) { 227 DH *dh1, *dh2; 228 const BIGNUM *p1 = NULL, *g1 = NULL, *p2 = NULL, *g2 = NULL; 229 230 dh1 = key1->keydata.dh; 231 dh2 = key2->keydata.dh; 232 233 if (dh1 == NULL && dh2 == NULL) { 234 return (true); 235 } else if (dh1 == NULL || dh2 == NULL) { 236 return (false); 237 } 238 239 DH_get0_pqg(dh1, &p1, NULL, &g1); 240 DH_get0_pqg(dh2, &p2, NULL, &g2); 241 242 if (BN_cmp(p1, p2) != 0 || BN_cmp(g1, g2) != 0) { 243 return (false); 244 } 245 return (true); 246 } 247 248 static int 249 progress_cb(int p, int n, BN_GENCB *cb) { 250 union { 251 void *dptr; 252 void (*fptr)(int); 253 } u; 254 255 UNUSED(n); 256 257 u.dptr = BN_GENCB_get_arg(cb); 258 if (u.fptr != NULL) { 259 u.fptr(p); 260 } 261 return (1); 262 } 263 264 static isc_result_t 265 openssldh_generate(dst_key_t *key, int generator, void (*callback)(int)) { 266 DH *dh = NULL; 267 BN_GENCB *cb; 268 #if !HAVE_BN_GENCB_NEW 269 BN_GENCB _cb; 270 #endif /* !HAVE_BN_GENCB_NEW */ 271 union { 272 void *dptr; 273 void (*fptr)(int); 274 } u; 275 276 if (generator == 0) { 277 if (key->key_size == 768 || key->key_size == 1024 || 278 key->key_size == 1536) 279 { 280 BIGNUM *p, *g; 281 dh = DH_new(); 282 if (key->key_size == 768) { 283 p = BN_dup(bn768); 284 } else if (key->key_size == 1024) { 285 p = BN_dup(bn1024); 286 } else { 287 p = BN_dup(bn1536); 288 } 289 g = BN_dup(bn2); 290 if (dh == NULL || p == NULL || g == NULL) { 291 if (dh != NULL) { 292 DH_free(dh); 293 } 294 if (p != NULL) { 295 BN_free(p); 296 } 297 if (g != NULL) { 298 BN_free(g); 299 } 300 return (dst__openssl_toresult(ISC_R_NOMEMORY)); 301 } 302 DH_set0_pqg(dh, p, NULL, g); 303 } else { 304 generator = 2; 305 } 306 } 307 308 if (generator != 0) { 309 dh = DH_new(); 310 if (dh == NULL) { 311 return (dst__openssl_toresult(ISC_R_NOMEMORY)); 312 } 313 cb = BN_GENCB_new(); 314 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) 315 if (cb == NULL) { 316 DH_free(dh); 317 return (dst__openssl_toresult(ISC_R_NOMEMORY)); 318 } 319 #endif /* if OPENSSL_VERSION_NUMBER >= 0x10100000L && \ 320 * !defined(LIBRESSL_VERSION_NUMBER) */ 321 if (callback == NULL) { 322 BN_GENCB_set_old(cb, NULL, NULL); 323 } else { 324 u.fptr = callback; 325 BN_GENCB_set(cb, progress_cb, u.dptr); 326 } 327 328 if (!DH_generate_parameters_ex(dh, key->key_size, generator, 329 cb)) 330 { 331 DH_free(dh); 332 BN_GENCB_free(cb); 333 return (dst__openssl_toresult2("DH_generate_parameters_" 334 "ex", 335 DST_R_OPENSSLFAILURE)); 336 } 337 BN_GENCB_free(cb); 338 cb = NULL; 339 } 340 341 if (DH_generate_key(dh) == 0) { 342 DH_free(dh); 343 return (dst__openssl_toresult2("DH_generate_key", 344 DST_R_OPENSSLFAILURE)); 345 } 346 DH_clear_flags(dh, DH_FLAG_CACHE_MONT_P); 347 key->keydata.dh = dh; 348 349 return (ISC_R_SUCCESS); 350 } 351 352 static bool 353 openssldh_isprivate(const dst_key_t *key) { 354 DH *dh = key->keydata.dh; 355 const BIGNUM *priv_key = NULL; 356 357 DH_get0_key(dh, NULL, &priv_key); 358 return (dh != NULL && priv_key != NULL); 359 } 360 361 static void 362 openssldh_destroy(dst_key_t *key) { 363 DH *dh = key->keydata.dh; 364 365 if (dh == NULL) { 366 return; 367 } 368 369 DH_free(dh); 370 key->keydata.dh = NULL; 371 } 372 373 static void 374 uint16_toregion(uint16_t val, isc_region_t *region) { 375 *region->base = (val & 0xff00) >> 8; 376 isc_region_consume(region, 1); 377 *region->base = (val & 0x00ff); 378 isc_region_consume(region, 1); 379 } 380 381 static uint16_t 382 uint16_fromregion(isc_region_t *region) { 383 uint16_t val; 384 unsigned char *cp = region->base; 385 386 val = ((unsigned int)(cp[0])) << 8; 387 val |= ((unsigned int)(cp[1])); 388 389 isc_region_consume(region, 2); 390 391 return (val); 392 } 393 394 static isc_result_t 395 openssldh_todns(const dst_key_t *key, isc_buffer_t *data) { 396 DH *dh; 397 const BIGNUM *pub_key = NULL, *p = NULL, *g = NULL; 398 isc_region_t r; 399 uint16_t dnslen, plen, glen, publen; 400 401 REQUIRE(key->keydata.dh != NULL); 402 403 dh = key->keydata.dh; 404 405 isc_buffer_availableregion(data, &r); 406 407 DH_get0_pqg(dh, &p, NULL, &g); 408 if (BN_cmp(g, bn2) == 0 && 409 (BN_cmp(p, bn768) == 0 || BN_cmp(p, bn1024) == 0 || 410 BN_cmp(p, bn1536) == 0)) 411 { 412 plen = 1; 413 glen = 0; 414 } else { 415 plen = BN_num_bytes(p); 416 glen = BN_num_bytes(g); 417 } 418 DH_get0_key(dh, &pub_key, NULL); 419 publen = BN_num_bytes(pub_key); 420 dnslen = plen + glen + publen + 6; 421 if (r.length < (unsigned int)dnslen) { 422 return (ISC_R_NOSPACE); 423 } 424 425 uint16_toregion(plen, &r); 426 if (plen == 1) { 427 if (BN_cmp(p, bn768) == 0) { 428 *r.base = 1; 429 } else if (BN_cmp(p, bn1024) == 0) { 430 *r.base = 2; 431 } else { 432 *r.base = 3; 433 } 434 } else { 435 BN_bn2bin(p, r.base); 436 } 437 isc_region_consume(&r, plen); 438 439 uint16_toregion(glen, &r); 440 if (glen > 0) { 441 BN_bn2bin(g, r.base); 442 } 443 isc_region_consume(&r, glen); 444 445 uint16_toregion(publen, &r); 446 BN_bn2bin(pub_key, r.base); 447 isc_region_consume(&r, publen); 448 449 isc_buffer_add(data, dnslen); 450 451 return (ISC_R_SUCCESS); 452 } 453 454 static isc_result_t 455 openssldh_fromdns(dst_key_t *key, isc_buffer_t *data) { 456 DH *dh; 457 BIGNUM *pub_key = NULL, *p = NULL, *g = NULL; 458 isc_region_t r; 459 uint16_t plen, glen, publen; 460 int special = 0; 461 462 isc_buffer_remainingregion(data, &r); 463 if (r.length == 0) { 464 return (ISC_R_SUCCESS); 465 } 466 467 dh = DH_new(); 468 if (dh == NULL) { 469 return (dst__openssl_toresult(ISC_R_NOMEMORY)); 470 } 471 DH_clear_flags(dh, DH_FLAG_CACHE_MONT_P); 472 473 /* 474 * Read the prime length. 1 & 2 are table entries, > 16 means a 475 * prime follows, otherwise an error. 476 */ 477 if (r.length < 2) { 478 DH_free(dh); 479 return (DST_R_INVALIDPUBLICKEY); 480 } 481 plen = uint16_fromregion(&r); 482 if (plen < 16 && plen != 1 && plen != 2) { 483 DH_free(dh); 484 return (DST_R_INVALIDPUBLICKEY); 485 } 486 if (r.length < plen) { 487 DH_free(dh); 488 return (DST_R_INVALIDPUBLICKEY); 489 } 490 if (plen == 1 || plen == 2) { 491 if (plen == 1) { 492 special = *r.base; 493 isc_region_consume(&r, 1); 494 } else { 495 special = uint16_fromregion(&r); 496 } 497 switch (special) { 498 case 1: 499 p = BN_dup(bn768); 500 break; 501 case 2: 502 p = BN_dup(bn1024); 503 break; 504 case 3: 505 p = BN_dup(bn1536); 506 break; 507 default: 508 DH_free(dh); 509 return (DST_R_INVALIDPUBLICKEY); 510 } 511 } else { 512 p = BN_bin2bn(r.base, plen, NULL); 513 isc_region_consume(&r, plen); 514 } 515 516 /* 517 * Read the generator length. This should be 0 if the prime was 518 * special, but it might not be. If it's 0 and the prime is not 519 * special, we have a problem. 520 */ 521 if (r.length < 2) { 522 DH_free(dh); 523 return (DST_R_INVALIDPUBLICKEY); 524 } 525 glen = uint16_fromregion(&r); 526 if (r.length < glen) { 527 DH_free(dh); 528 return (DST_R_INVALIDPUBLICKEY); 529 } 530 if (special != 0) { 531 if (glen == 0) { 532 g = BN_dup(bn2); 533 } else { 534 g = BN_bin2bn(r.base, glen, NULL); 535 if (g != NULL && BN_cmp(g, bn2) != 0) { 536 DH_free(dh); 537 BN_free(g); 538 return (DST_R_INVALIDPUBLICKEY); 539 } 540 } 541 } else { 542 if (glen == 0) { 543 DH_free(dh); 544 return (DST_R_INVALIDPUBLICKEY); 545 } 546 g = BN_bin2bn(r.base, glen, NULL); 547 } 548 isc_region_consume(&r, glen); 549 550 if (p == NULL || g == NULL) { 551 DH_free(dh); 552 if (p != NULL) { 553 BN_free(p); 554 } 555 if (g != NULL) { 556 BN_free(g); 557 } 558 return (dst__openssl_toresult(ISC_R_NOMEMORY)); 559 } 560 DH_set0_pqg(dh, p, NULL, g); 561 562 if (r.length < 2) { 563 DH_free(dh); 564 return (DST_R_INVALIDPUBLICKEY); 565 } 566 publen = uint16_fromregion(&r); 567 if (r.length < publen) { 568 DH_free(dh); 569 return (DST_R_INVALIDPUBLICKEY); 570 } 571 pub_key = BN_bin2bn(r.base, publen, NULL); 572 if (pub_key == NULL) { 573 DH_free(dh); 574 return (dst__openssl_toresult(ISC_R_NOMEMORY)); 575 } 576 #if (LIBRESSL_VERSION_NUMBER >= 0x2070000fL) && \ 577 (LIBRESSL_VERSION_NUMBER <= 0x2070200fL) 578 /* 579 * LibreSSL << 2.7.3 DH_get0_key requires priv_key to be set when 580 * DH structure is empty, hence we cannot use DH_get0_key(). 581 */ 582 dh->pub_key = pub_key; 583 #else /* LIBRESSL_VERSION_NUMBER */ 584 DH_set0_key(dh, pub_key, NULL); 585 #endif /* LIBRESSL_VERSION_NUMBER */ 586 isc_region_consume(&r, publen); 587 588 key->key_size = BN_num_bits(p); 589 590 isc_buffer_forward(data, plen + glen + publen + 6); 591 592 key->keydata.dh = dh; 593 594 return (ISC_R_SUCCESS); 595 } 596 597 static isc_result_t 598 openssldh_tofile(const dst_key_t *key, const char *directory) { 599 int i; 600 DH *dh; 601 const BIGNUM *pub_key = NULL, *priv_key = NULL, *p = NULL, *g = NULL; 602 dst_private_t priv; 603 unsigned char *bufs[4]; 604 isc_result_t result; 605 606 if (key->keydata.dh == NULL) { 607 return (DST_R_NULLKEY); 608 } 609 610 if (key->external) { 611 return (DST_R_EXTERNALKEY); 612 } 613 614 dh = key->keydata.dh; 615 DH_get0_key(dh, &pub_key, &priv_key); 616 DH_get0_pqg(dh, &p, NULL, &g); 617 618 memset(bufs, 0, sizeof(bufs)); 619 for (i = 0; i < 4; i++) { 620 bufs[i] = isc_mem_get(key->mctx, BN_num_bytes(p)); 621 } 622 623 i = 0; 624 625 priv.elements[i].tag = TAG_DH_PRIME; 626 priv.elements[i].length = BN_num_bytes(p); 627 BN_bn2bin(p, bufs[i]); 628 priv.elements[i].data = bufs[i]; 629 i++; 630 631 priv.elements[i].tag = TAG_DH_GENERATOR; 632 priv.elements[i].length = BN_num_bytes(g); 633 BN_bn2bin(g, bufs[i]); 634 priv.elements[i].data = bufs[i]; 635 i++; 636 637 priv.elements[i].tag = TAG_DH_PRIVATE; 638 priv.elements[i].length = BN_num_bytes(priv_key); 639 BN_bn2bin(priv_key, bufs[i]); 640 priv.elements[i].data = bufs[i]; 641 i++; 642 643 priv.elements[i].tag = TAG_DH_PUBLIC; 644 priv.elements[i].length = BN_num_bytes(pub_key); 645 BN_bn2bin(pub_key, bufs[i]); 646 priv.elements[i].data = bufs[i]; 647 i++; 648 649 priv.nelements = i; 650 result = dst__privstruct_writefile(key, &priv, directory); 651 652 for (i = 0; i < 4; i++) { 653 if (bufs[i] == NULL) { 654 break; 655 } 656 isc_mem_put(key->mctx, bufs[i], BN_num_bytes(p)); 657 } 658 return (result); 659 } 660 661 static isc_result_t 662 openssldh_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { 663 dst_private_t priv; 664 isc_result_t ret; 665 int i; 666 DH *dh = NULL; 667 BIGNUM *pub_key = NULL, *priv_key = NULL, *p = NULL, *g = NULL; 668 isc_mem_t *mctx; 669 #define DST_RET(a) \ 670 { \ 671 ret = a; \ 672 goto err; \ 673 } 674 675 UNUSED(pub); 676 mctx = key->mctx; 677 678 /* read private key file */ 679 ret = dst__privstruct_parse(key, DST_ALG_DH, lexer, mctx, &priv); 680 if (ret != ISC_R_SUCCESS) { 681 return (ret); 682 } 683 684 if (key->external) { 685 DST_RET(DST_R_EXTERNALKEY); 686 } 687 688 dh = DH_new(); 689 if (dh == NULL) { 690 DST_RET(ISC_R_NOMEMORY); 691 } 692 DH_clear_flags(dh, DH_FLAG_CACHE_MONT_P); 693 key->keydata.dh = dh; 694 695 for (i = 0; i < priv.nelements; i++) { 696 BIGNUM *bn; 697 bn = BN_bin2bn(priv.elements[i].data, priv.elements[i].length, 698 NULL); 699 if (bn == NULL) { 700 DST_RET(ISC_R_NOMEMORY); 701 } 702 703 switch (priv.elements[i].tag) { 704 case TAG_DH_PRIME: 705 p = bn; 706 break; 707 case TAG_DH_GENERATOR: 708 g = bn; 709 break; 710 case TAG_DH_PRIVATE: 711 priv_key = bn; 712 break; 713 case TAG_DH_PUBLIC: 714 pub_key = bn; 715 break; 716 } 717 } 718 dst__privstruct_free(&priv, mctx); 719 DH_set0_key(dh, pub_key, priv_key); 720 DH_set0_pqg(dh, p, NULL, g); 721 722 key->key_size = BN_num_bits(p); 723 return (ISC_R_SUCCESS); 724 725 err: 726 if (p != NULL) { 727 BN_free(p); 728 } 729 if (g != NULL) { 730 BN_free(g); 731 } 732 if (pub_key != NULL) { 733 BN_free(pub_key); 734 } 735 if (priv_key != NULL) { 736 BN_free(priv_key); 737 } 738 openssldh_destroy(key); 739 dst__privstruct_free(&priv, mctx); 740 isc_safe_memwipe(&priv, sizeof(priv)); 741 return (ret); 742 } 743 744 static void 745 openssldh_cleanup(void) { 746 BN_free(bn2); 747 bn2 = NULL; 748 749 BN_free(bn768); 750 bn768 = NULL; 751 752 BN_free(bn1024); 753 bn1024 = NULL; 754 755 BN_free(bn1536); 756 bn1536 = NULL; 757 } 758 759 static dst_func_t openssldh_functions = { 760 NULL, /*%< createctx */ 761 NULL, /*%< createctx2 */ 762 NULL, /*%< destroyctx */ 763 NULL, /*%< adddata */ 764 NULL, /*%< openssldh_sign */ 765 NULL, /*%< openssldh_verify */ 766 NULL, /*%< openssldh_verify2 */ 767 openssldh_computesecret, 768 openssldh_compare, 769 openssldh_paramcompare, 770 openssldh_generate, 771 openssldh_isprivate, 772 openssldh_destroy, 773 openssldh_todns, 774 openssldh_fromdns, 775 openssldh_tofile, 776 openssldh_parse, 777 openssldh_cleanup, 778 NULL, /*%< fromlabel */ 779 NULL, /*%< dump */ 780 NULL, /*%< restore */ 781 }; 782 783 isc_result_t 784 dst__openssldh_init(dst_func_t **funcp) { 785 REQUIRE(funcp != NULL); 786 if (*funcp == NULL) { 787 if (BN_hex2bn(&bn2, PRIME2) == 0 || bn2 == NULL) { 788 goto cleanup; 789 } 790 if (BN_hex2bn(&bn768, PRIME768) == 0 || bn768 == NULL) { 791 goto cleanup; 792 } 793 if (BN_hex2bn(&bn1024, PRIME1024) == 0 || bn1024 == NULL) { 794 goto cleanup; 795 } 796 if (BN_hex2bn(&bn1536, PRIME1536) == 0 || bn1536 == NULL) { 797 goto cleanup; 798 } 799 *funcp = &openssldh_functions; 800 } 801 return (ISC_R_SUCCESS); 802 803 cleanup: 804 if (bn2 != NULL) { 805 BN_free(bn2); 806 } 807 if (bn768 != NULL) { 808 BN_free(bn768); 809 } 810 if (bn1024 != NULL) { 811 BN_free(bn1024); 812 } 813 if (bn1536 != NULL) { 814 BN_free(bn1536); 815 } 816 return (ISC_R_NOMEMORY); 817 } 818