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