openssldsa_link.c revision 287410
1/* 2 * Portions Copyright (C) 2004-2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC") 3 * Portions Copyright (C) 1999-2002 Internet Software Consortium. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS 10 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE 12 * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR 15 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 * 17 * Portions Copyright (C) 1995-2000 by 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#ifdef OPENSSL 33#ifndef USE_EVP 34#define USE_EVP 1 35#endif 36 37#include <config.h> 38 39#include <string.h> 40 41#include <isc/entropy.h> 42#include <isc/mem.h> 43#include <isc/sha1.h> 44#include <isc/util.h> 45 46#include <dst/result.h> 47 48#include "dst_internal.h" 49#include "dst_openssl.h" 50#include "dst_parse.h" 51 52#include <openssl/dsa.h> 53 54static isc_result_t openssldsa_todns(const dst_key_t *key, isc_buffer_t *data); 55 56static isc_result_t 57openssldsa_createctx(dst_key_t *key, dst_context_t *dctx) { 58#if USE_EVP 59 EVP_MD_CTX *evp_md_ctx; 60 61 UNUSED(key); 62 63 evp_md_ctx = EVP_MD_CTX_create(); 64 if (evp_md_ctx == NULL) 65 return (ISC_R_NOMEMORY); 66 67 if (!EVP_DigestInit_ex(evp_md_ctx, EVP_dss1(), NULL)) { 68 EVP_MD_CTX_destroy(evp_md_ctx); 69 return (ISC_R_FAILURE); 70 } 71 72 dctx->ctxdata.evp_md_ctx = evp_md_ctx; 73 74 return (ISC_R_SUCCESS); 75#else 76 isc_sha1_t *sha1ctx; 77 78 UNUSED(key); 79 80 sha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_sha1_t)); 81 isc_sha1_init(sha1ctx); 82 dctx->ctxdata.sha1ctx = sha1ctx; 83 return (ISC_R_SUCCESS); 84#endif 85} 86 87static void 88openssldsa_destroyctx(dst_context_t *dctx) { 89#if USE_EVP 90 EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; 91 92 if (evp_md_ctx != NULL) { 93 EVP_MD_CTX_destroy(evp_md_ctx); 94 dctx->ctxdata.evp_md_ctx = NULL; 95 } 96#else 97 isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; 98 99 if (sha1ctx != NULL) { 100 isc_sha1_invalidate(sha1ctx); 101 isc_mem_put(dctx->mctx, sha1ctx, sizeof(isc_sha1_t)); 102 dctx->ctxdata.sha1ctx = NULL; 103 } 104#endif 105} 106 107static isc_result_t 108openssldsa_adddata(dst_context_t *dctx, const isc_region_t *data) { 109#if USE_EVP 110 EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; 111 112 if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length)) { 113 return (ISC_R_FAILURE); 114 } 115#else 116 isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; 117 118 isc_sha1_update(sha1ctx, data->base, data->length); 119#endif 120 return (ISC_R_SUCCESS); 121} 122 123static int 124BN_bn2bin_fixed(BIGNUM *bn, unsigned char *buf, int size) { 125 int bytes = size - BN_num_bytes(bn); 126 while (bytes-- > 0) 127 *buf++ = 0; 128 BN_bn2bin(bn, buf); 129 return (size); 130} 131 132static isc_result_t 133openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { 134 dst_key_t *key = dctx->key; 135 DSA *dsa = key->keydata.dsa; 136 isc_region_t r; 137 DSA_SIG *dsasig; 138 unsigned int klen; 139#if USE_EVP 140 EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; 141 EVP_PKEY *pkey; 142 unsigned char *sigbuf; 143 const unsigned char *sb; 144 unsigned int siglen; 145#else 146 isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; 147 unsigned char digest[ISC_SHA1_DIGESTLENGTH]; 148#endif 149 150 isc_buffer_availableregion(sig, &r); 151 if (r.length < ISC_SHA1_DIGESTLENGTH * 2 + 1) 152 return (ISC_R_NOSPACE); 153 154#if USE_EVP 155 pkey = EVP_PKEY_new(); 156 if (pkey == NULL) 157 return (ISC_R_NOMEMORY); 158 if (!EVP_PKEY_set1_DSA(pkey, dsa)) { 159 EVP_PKEY_free(pkey); 160 return (ISC_R_FAILURE); 161 } 162 sigbuf = malloc(EVP_PKEY_size(pkey)); 163 if (sigbuf == NULL) { 164 EVP_PKEY_free(pkey); 165 return (ISC_R_NOMEMORY); 166 } 167 if (!EVP_SignFinal(evp_md_ctx, sigbuf, &siglen, pkey)) { 168 EVP_PKEY_free(pkey); 169 free(sigbuf); 170 return (dst__openssl_toresult3(dctx->category, 171 "EVP_SignFinal", 172 ISC_R_FAILURE)); 173 } 174 INSIST(EVP_PKEY_size(pkey) >= (int) siglen); 175 EVP_PKEY_free(pkey); 176 /* Convert from Dss-Sig-Value (RFC2459). */ 177 dsasig = DSA_SIG_new(); 178 if (dsasig == NULL) { 179 free(sigbuf); 180 return (ISC_R_NOMEMORY); 181 } 182 sb = sigbuf; 183 if (d2i_DSA_SIG(&dsasig, &sb, (long) siglen) == NULL) { 184 free(sigbuf); 185 return (dst__openssl_toresult3(dctx->category, 186 "d2i_DSA_SIG", 187 ISC_R_FAILURE)); 188 } 189 free(sigbuf); 190 191#elif 0 192 /* Only use EVP for the Digest */ 193 if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &siglen)) { 194 return (dst__openssl_toresult3(dctx->category, 195 "EVP_DigestFinal_ex", 196 ISC_R_FAILURE)); 197 } 198 dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa); 199 if (dsasig == NULL) 200 return (dst__openssl_toresult3(dctx->category, 201 "DSA_do_sign", 202 DST_R_SIGNFAILURE)); 203#else 204 isc_sha1_final(sha1ctx, digest); 205 206 dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa); 207 if (dsasig == NULL) 208 return (dst__openssl_toresult3(dctx->category, 209 "DSA_do_sign", 210 DST_R_SIGNFAILURE)); 211#endif 212 213 klen = (key->key_size - 512)/64; 214 if (klen > 255) 215 return (ISC_R_FAILURE); 216 *r.base = klen; 217 isc_region_consume(&r, 1); 218 219 BN_bn2bin_fixed(dsasig->r, r.base, ISC_SHA1_DIGESTLENGTH); 220 isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH); 221 BN_bn2bin_fixed(dsasig->s, r.base, ISC_SHA1_DIGESTLENGTH); 222 isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH); 223 DSA_SIG_free(dsasig); 224 isc_buffer_add(sig, ISC_SHA1_DIGESTLENGTH * 2 + 1); 225 226 return (ISC_R_SUCCESS); 227} 228 229static isc_result_t 230openssldsa_verify(dst_context_t *dctx, const isc_region_t *sig) { 231 dst_key_t *key = dctx->key; 232 DSA *dsa = key->keydata.dsa; 233 int status = 0; 234 unsigned char *cp = sig->base; 235 DSA_SIG *dsasig; 236#if USE_EVP 237 EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; 238#if 0 239 EVP_PKEY *pkey; 240 unsigned char *sigbuf; 241#endif 242 unsigned int siglen; 243#else 244 isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; 245#endif 246 unsigned char digest[ISC_SHA1_DIGESTLENGTH]; 247 248 249#if USE_EVP 250#if 1 251 /* Only use EVP for the digest */ 252 if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &siglen)) { 253 return (ISC_R_FAILURE); 254 } 255#endif 256#else 257 isc_sha1_final(sha1ctx, digest); 258#endif 259 260 if (sig->length != 2 * ISC_SHA1_DIGESTLENGTH + 1) { 261 return (DST_R_VERIFYFAILURE); 262 } 263 264 cp++; /*%< Skip T */ 265 dsasig = DSA_SIG_new(); 266 if (dsasig == NULL) 267 return (ISC_R_NOMEMORY); 268 dsasig->r = BN_bin2bn(cp, ISC_SHA1_DIGESTLENGTH, NULL); 269 cp += ISC_SHA1_DIGESTLENGTH; 270 dsasig->s = BN_bin2bn(cp, ISC_SHA1_DIGESTLENGTH, NULL); 271 272#if 0 273 pkey = EVP_PKEY_new(); 274 if (pkey == NULL) 275 return (ISC_R_NOMEMORY); 276 if (!EVP_PKEY_set1_DSA(pkey, dsa)) { 277 EVP_PKEY_free(pkey); 278 return (ISC_R_FAILURE); 279 } 280 /* Convert to Dss-Sig-Value (RFC2459). */ 281 sigbuf = malloc(EVP_PKEY_size(pkey) + 50); 282 if (sigbuf == NULL) { 283 EVP_PKEY_free(pkey); 284 return (ISC_R_NOMEMORY); 285 } 286 siglen = (unsigned) i2d_DSA_SIG(dsasig, &sigbuf); 287 INSIST(EVP_PKEY_size(pkey) >= (int) siglen); 288 status = EVP_VerifyFinal(evp_md_ctx, sigbuf, siglen, pkey); 289 EVP_PKEY_free(pkey); 290 free(sigbuf); 291#else 292 status = DSA_do_verify(digest, ISC_SHA1_DIGESTLENGTH, dsasig, dsa); 293#endif 294 DSA_SIG_free(dsasig); 295 switch (status) { 296 case 1: 297 return (ISC_R_SUCCESS); 298 case 0: 299 return (dst__openssl_toresult(DST_R_VERIFYFAILURE)); 300 default: 301 return (dst__openssl_toresult3(dctx->category, 302 "DSA_do_verify", 303 DST_R_VERIFYFAILURE)); 304 } 305} 306 307static isc_boolean_t 308openssldsa_compare(const dst_key_t *key1, const dst_key_t *key2) { 309 int status; 310 DSA *dsa1, *dsa2; 311 312 dsa1 = key1->keydata.dsa; 313 dsa2 = key2->keydata.dsa; 314 315 if (dsa1 == NULL && dsa2 == NULL) 316 return (ISC_TRUE); 317 else if (dsa1 == NULL || dsa2 == NULL) 318 return (ISC_FALSE); 319 320 status = BN_cmp(dsa1->p, dsa2->p) || 321 BN_cmp(dsa1->q, dsa2->q) || 322 BN_cmp(dsa1->g, dsa2->g) || 323 BN_cmp(dsa1->pub_key, dsa2->pub_key); 324 325 if (status != 0) 326 return (ISC_FALSE); 327 328 if (dsa1->priv_key != NULL || dsa2->priv_key != NULL) { 329 if (dsa1->priv_key == NULL || dsa2->priv_key == NULL) 330 return (ISC_FALSE); 331 if (BN_cmp(dsa1->priv_key, dsa2->priv_key)) 332 return (ISC_FALSE); 333 } 334 return (ISC_TRUE); 335} 336 337#if OPENSSL_VERSION_NUMBER > 0x00908000L 338static int 339progress_cb(int p, int n, BN_GENCB *cb) 340{ 341 union { 342 void *dptr; 343 void (*fptr)(int); 344 } u; 345 346 UNUSED(n); 347 348 u.dptr = cb->arg; 349 if (u.fptr != NULL) 350 u.fptr(p); 351 return (1); 352} 353#endif 354 355static isc_result_t 356openssldsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { 357 DSA *dsa; 358 unsigned char rand_array[ISC_SHA1_DIGESTLENGTH]; 359 isc_result_t result; 360#if OPENSSL_VERSION_NUMBER > 0x00908000L 361 BN_GENCB cb; 362 union { 363 void *dptr; 364 void (*fptr)(int); 365 } u; 366 367#else 368 369 UNUSED(callback); 370#endif 371 UNUSED(unused); 372 373 result = dst__entropy_getdata(rand_array, sizeof(rand_array), 374 ISC_FALSE); 375 if (result != ISC_R_SUCCESS) 376 return (result); 377 378#if OPENSSL_VERSION_NUMBER > 0x00908000L 379 dsa = DSA_new(); 380 if (dsa == NULL) 381 return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); 382 383 if (callback == NULL) { 384 BN_GENCB_set_old(&cb, NULL, NULL); 385 } else { 386 u.fptr = callback; 387 BN_GENCB_set(&cb, &progress_cb, u.dptr); 388 } 389 390 if (!DSA_generate_parameters_ex(dsa, key->key_size, rand_array, 391 ISC_SHA1_DIGESTLENGTH, NULL, NULL, 392 &cb)) 393 { 394 DSA_free(dsa); 395 return (dst__openssl_toresult2("DSA_generate_parameters_ex", 396 DST_R_OPENSSLFAILURE)); 397 } 398#else 399 dsa = DSA_generate_parameters(key->key_size, rand_array, 400 ISC_SHA1_DIGESTLENGTH, NULL, NULL, 401 NULL, NULL); 402 if (dsa == NULL) 403 return (dst__openssl_toresult2("DSA_generate_parameters", 404 DST_R_OPENSSLFAILURE)); 405#endif 406 407 if (DSA_generate_key(dsa) == 0) { 408 DSA_free(dsa); 409 return (dst__openssl_toresult2("DSA_generate_key", 410 DST_R_OPENSSLFAILURE)); 411 } 412 dsa->flags &= ~DSA_FLAG_CACHE_MONT_P; 413 414 key->keydata.dsa = dsa; 415 416 return (ISC_R_SUCCESS); 417} 418 419static isc_boolean_t 420openssldsa_isprivate(const dst_key_t *key) { 421 DSA *dsa = key->keydata.dsa; 422 return (ISC_TF(dsa != NULL && dsa->priv_key != NULL)); 423} 424 425static void 426openssldsa_destroy(dst_key_t *key) { 427 DSA *dsa = key->keydata.dsa; 428 DSA_free(dsa); 429 key->keydata.dsa = NULL; 430} 431 432 433static isc_result_t 434openssldsa_todns(const dst_key_t *key, isc_buffer_t *data) { 435 DSA *dsa; 436 isc_region_t r; 437 int dnslen; 438 unsigned int t, p_bytes; 439 440 REQUIRE(key->keydata.dsa != NULL); 441 442 dsa = key->keydata.dsa; 443 444 isc_buffer_availableregion(data, &r); 445 446 t = (BN_num_bytes(dsa->p) - 64) / 8; 447 if (t > 8) 448 return (DST_R_INVALIDPUBLICKEY); 449 p_bytes = 64 + 8 * t; 450 451 dnslen = 1 + (key->key_size * 3)/8 + ISC_SHA1_DIGESTLENGTH; 452 if (r.length < (unsigned int) dnslen) 453 return (ISC_R_NOSPACE); 454 455 *r.base = t; 456 isc_region_consume(&r, 1); 457 BN_bn2bin_fixed(dsa->q, r.base, ISC_SHA1_DIGESTLENGTH); 458 isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH); 459 BN_bn2bin_fixed(dsa->p, r.base, key->key_size/8); 460 isc_region_consume(&r, p_bytes); 461 BN_bn2bin_fixed(dsa->g, r.base, key->key_size/8); 462 isc_region_consume(&r, p_bytes); 463 BN_bn2bin_fixed(dsa->pub_key, r.base, key->key_size/8); 464 isc_region_consume(&r, p_bytes); 465 466 isc_buffer_add(data, dnslen); 467 468 return (ISC_R_SUCCESS); 469} 470 471static isc_result_t 472openssldsa_fromdns(dst_key_t *key, isc_buffer_t *data) { 473 DSA *dsa; 474 isc_region_t r; 475 unsigned int t, p_bytes; 476 isc_mem_t *mctx = key->mctx; 477 478 UNUSED(mctx); 479 480 isc_buffer_remainingregion(data, &r); 481 if (r.length == 0) 482 return (ISC_R_SUCCESS); 483 484 dsa = DSA_new(); 485 if (dsa == NULL) 486 return (ISC_R_NOMEMORY); 487 dsa->flags &= ~DSA_FLAG_CACHE_MONT_P; 488 489 t = (unsigned int) *r.base; 490 isc_region_consume(&r, 1); 491 if (t > 8) { 492 DSA_free(dsa); 493 return (DST_R_INVALIDPUBLICKEY); 494 } 495 p_bytes = 64 + 8 * t; 496 497 if (r.length < ISC_SHA1_DIGESTLENGTH + 3 * p_bytes) { 498 DSA_free(dsa); 499 return (DST_R_INVALIDPUBLICKEY); 500 } 501 502 dsa->q = BN_bin2bn(r.base, ISC_SHA1_DIGESTLENGTH, NULL); 503 isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH); 504 505 dsa->p = BN_bin2bn(r.base, p_bytes, NULL); 506 isc_region_consume(&r, p_bytes); 507 508 dsa->g = BN_bin2bn(r.base, p_bytes, NULL); 509 isc_region_consume(&r, p_bytes); 510 511 dsa->pub_key = BN_bin2bn(r.base, p_bytes, NULL); 512 isc_region_consume(&r, p_bytes); 513 514 key->key_size = p_bytes * 8; 515 516 isc_buffer_forward(data, 1 + ISC_SHA1_DIGESTLENGTH + 3 * p_bytes); 517 518 key->keydata.dsa = dsa; 519 520 return (ISC_R_SUCCESS); 521} 522 523 524static isc_result_t 525openssldsa_tofile(const dst_key_t *key, const char *directory) { 526 int cnt = 0; 527 DSA *dsa; 528 dst_private_t priv; 529 unsigned char bufs[5][128]; 530 531 if (key->keydata.dsa == NULL) 532 return (DST_R_NULLKEY); 533 534 if (key->external) { 535 priv.nelements = 0; 536 return (dst__privstruct_writefile(key, &priv, directory)); 537 } 538 539 dsa = key->keydata.dsa; 540 541 priv.elements[cnt].tag = TAG_DSA_PRIME; 542 priv.elements[cnt].length = BN_num_bytes(dsa->p); 543 BN_bn2bin(dsa->p, bufs[cnt]); 544 priv.elements[cnt].data = bufs[cnt]; 545 cnt++; 546 547 priv.elements[cnt].tag = TAG_DSA_SUBPRIME; 548 priv.elements[cnt].length = BN_num_bytes(dsa->q); 549 BN_bn2bin(dsa->q, bufs[cnt]); 550 priv.elements[cnt].data = bufs[cnt]; 551 cnt++; 552 553 priv.elements[cnt].tag = TAG_DSA_BASE; 554 priv.elements[cnt].length = BN_num_bytes(dsa->g); 555 BN_bn2bin(dsa->g, bufs[cnt]); 556 priv.elements[cnt].data = bufs[cnt]; 557 cnt++; 558 559 priv.elements[cnt].tag = TAG_DSA_PRIVATE; 560 priv.elements[cnt].length = BN_num_bytes(dsa->priv_key); 561 BN_bn2bin(dsa->priv_key, bufs[cnt]); 562 priv.elements[cnt].data = bufs[cnt]; 563 cnt++; 564 565 priv.elements[cnt].tag = TAG_DSA_PUBLIC; 566 priv.elements[cnt].length = BN_num_bytes(dsa->pub_key); 567 BN_bn2bin(dsa->pub_key, bufs[cnt]); 568 priv.elements[cnt].data = bufs[cnt]; 569 cnt++; 570 571 priv.nelements = cnt; 572 return (dst__privstruct_writefile(key, &priv, directory)); 573} 574 575static isc_result_t 576openssldsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { 577 dst_private_t priv; 578 isc_result_t ret; 579 int i; 580 DSA *dsa = NULL; 581 isc_mem_t *mctx = key->mctx; 582#define DST_RET(a) {ret = a; goto err;} 583 584 UNUSED(pub); 585 586 /* read private key file */ 587 ret = dst__privstruct_parse(key, DST_ALG_DSA, lexer, mctx, &priv); 588 if (ret != ISC_R_SUCCESS) 589 return (ret); 590 591 dsa = DSA_new(); 592 if (dsa == NULL) 593 DST_RET(ISC_R_NOMEMORY); 594 dsa->flags &= ~DSA_FLAG_CACHE_MONT_P; 595 key->keydata.dsa = dsa; 596 597 for (i=0; i < priv.nelements; i++) { 598 BIGNUM *bn; 599 bn = BN_bin2bn(priv.elements[i].data, 600 priv.elements[i].length, NULL); 601 if (bn == NULL) 602 DST_RET(ISC_R_NOMEMORY); 603 604 switch (priv.elements[i].tag) { 605 case TAG_DSA_PRIME: 606 dsa->p = bn; 607 break; 608 case TAG_DSA_SUBPRIME: 609 dsa->q = bn; 610 break; 611 case TAG_DSA_BASE: 612 dsa->g = bn; 613 break; 614 case TAG_DSA_PRIVATE: 615 dsa->priv_key = bn; 616 break; 617 case TAG_DSA_PUBLIC: 618 dsa->pub_key = bn; 619 break; 620 } 621 } 622 dst__privstruct_free(&priv, mctx); 623 624 if (key->external) { 625 if (pub == NULL) 626 DST_RET(DST_R_INVALIDPRIVATEKEY); 627 dsa->q = pub->keydata.dsa->q; 628 pub->keydata.dsa->q = NULL; 629 dsa->p = pub->keydata.dsa->p; 630 pub->keydata.dsa->p = NULL; 631 dsa->g = pub->keydata.dsa->g; 632 pub->keydata.dsa->g = NULL; 633 dsa->pub_key = pub->keydata.dsa->pub_key; 634 pub->keydata.dsa->pub_key = NULL; 635 } 636 637 key->key_size = BN_num_bits(dsa->p); 638 639 return (ISC_R_SUCCESS); 640 641 err: 642 openssldsa_destroy(key); 643 dst__privstruct_free(&priv, mctx); 644 memset(&priv, 0, sizeof(priv)); 645 return (ret); 646} 647 648static dst_func_t openssldsa_functions = { 649 openssldsa_createctx, 650 openssldsa_destroyctx, 651 openssldsa_adddata, 652 openssldsa_sign, 653 openssldsa_verify, 654 NULL, /*%< verify2 */ 655 NULL, /*%< computesecret */ 656 openssldsa_compare, 657 NULL, /*%< paramcompare */ 658 openssldsa_generate, 659 openssldsa_isprivate, 660 openssldsa_destroy, 661 openssldsa_todns, 662 openssldsa_fromdns, 663 openssldsa_tofile, 664 openssldsa_parse, 665 NULL, /*%< cleanup */ 666 NULL, /*%< fromlabel */ 667 NULL, /*%< dump */ 668 NULL, /*%< restore */ 669}; 670 671isc_result_t 672dst__openssldsa_init(dst_func_t **funcp) { 673 REQUIRE(funcp != NULL); 674 if (*funcp == NULL) 675 *funcp = &openssldsa_functions; 676 return (ISC_R_SUCCESS); 677} 678 679#else /* OPENSSL */ 680 681#include <isc/util.h> 682 683EMPTY_TRANSLATION_UNIT 684 685#endif /* OPENSSL */ 686/*! \file */ 687