1 /* $NetBSD: opensslecdsa_link.c,v 1.8 2024/02/21 22:52:07 christos Exp $ */ 2 3 /* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * SPDX-License-Identifier: MPL-2.0 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 /*! \file */ 17 18 #include <stdbool.h> 19 20 #include <openssl/bn.h> 21 #include <openssl/opensslv.h> 22 #if OPENSSL_VERSION_NUMBER >= 0x30000000L && OPENSSL_API_LEVEL >= 30000 23 #include <openssl/core_names.h> 24 #endif 25 #include <openssl/ecdsa.h> 26 #include <openssl/err.h> 27 #include <openssl/evp.h> 28 #include <openssl/objects.h> 29 #if OPENSSL_VERSION_NUMBER >= 0x30000000L && OPENSSL_API_LEVEL >= 30000 30 #include <openssl/param_build.h> 31 #endif 32 #if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000 33 #include <openssl/engine.h> 34 #endif 35 36 #include <isc/mem.h> 37 #include <isc/result.h> 38 #include <isc/safe.h> 39 #include <isc/string.h> 40 #include <isc/util.h> 41 42 #include <dns/keyvalues.h> 43 44 #include "dst_internal.h" 45 #include "dst_openssl.h" 46 #include "dst_parse.h" 47 #include "openssl_shim.h" 48 49 #ifndef NID_X9_62_prime256v1 50 #error "P-256 group is not known (NID_X9_62_prime256v1)" 51 #endif /* ifndef NID_X9_62_prime256v1 */ 52 #ifndef NID_secp384r1 53 #error "P-384 group is not known (NID_secp384r1)" 54 #endif /* ifndef NID_secp384r1 */ 55 56 #define DST_RET(a) \ 57 { \ 58 ret = a; \ 59 goto err; \ 60 } 61 62 #if OPENSSL_VERSION_NUMBER >= 0x30000000L && OPENSSL_API_LEVEL >= 30000 63 static isc_result_t 64 raw_key_to_ossl(unsigned int key_alg, int private, const unsigned char *key, 65 size_t key_len, EVP_PKEY **pkey) { 66 isc_result_t ret; 67 int status; 68 const char *groupname; 69 OSSL_PARAM_BLD *bld = NULL; 70 OSSL_PARAM *params = NULL; 71 EVP_PKEY_CTX *ctx = NULL; 72 BIGNUM *priv = NULL; 73 unsigned char buf[DNS_KEY_ECDSA384SIZE + 1]; 74 75 if (key_alg == DST_ALG_ECDSA256) { 76 groupname = "P-256"; 77 } else if (key_alg == DST_ALG_ECDSA384) { 78 groupname = "P-384"; 79 } else { 80 DST_RET(ISC_R_NOTIMPLEMENTED); 81 } 82 83 bld = OSSL_PARAM_BLD_new(); 84 if (bld == NULL) { 85 DST_RET(dst__openssl_toresult2("OSSL_PARAM_BLD_new", 86 DST_R_OPENSSLFAILURE)); 87 } 88 status = OSSL_PARAM_BLD_push_utf8_string( 89 bld, OSSL_PKEY_PARAM_GROUP_NAME, groupname, 0); 90 if (status != 1) { 91 DST_RET(dst__openssl_toresult2("OSSL_PARAM_BLD_push_" 92 "utf8_string", 93 DST_R_OPENSSLFAILURE)); 94 } 95 96 if (private) { 97 priv = BN_bin2bn(key, key_len, NULL); 98 if (priv == NULL) { 99 DST_RET(dst__openssl_toresult2("BN_bin2bn", 100 DST_R_OPENSSLFAILURE)); 101 } 102 103 status = OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PRIV_KEY, 104 priv); 105 if (status != 1) { 106 DST_RET(dst__openssl_toresult2("OSSL_PARAM_BLD_push_BN", 107 DST_R_OPENSSLFAILURE)); 108 } 109 } else { 110 INSIST(key_len < sizeof(buf)); 111 buf[0] = POINT_CONVERSION_UNCOMPRESSED; 112 memmove(buf + 1, key, key_len); 113 114 status = OSSL_PARAM_BLD_push_octet_string( 115 bld, OSSL_PKEY_PARAM_PUB_KEY, buf, 1 + key_len); 116 if (status != 1) { 117 DST_RET(dst__openssl_toresult2("OSSL_PARAM_BLD_push_" 118 "octet_string", 119 DST_R_OPENSSLFAILURE)); 120 } 121 } 122 123 params = OSSL_PARAM_BLD_to_param(bld); 124 if (params == NULL) { 125 DST_RET(dst__openssl_toresult2("OSSL_PARAM_BLD_to_param", 126 DST_R_OPENSSLFAILURE)); 127 } 128 ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL); 129 if (ctx == NULL) { 130 DST_RET(dst__openssl_toresult2("EVP_PKEY_CTX_new_from_name", 131 DST_R_OPENSSLFAILURE)); 132 } 133 status = EVP_PKEY_fromdata_init(ctx); 134 if (status != 1) { 135 DST_RET(dst__openssl_toresult2("EVP_PKEY_fromdata_init", 136 DST_R_OPENSSLFAILURE)); 137 } 138 status = EVP_PKEY_fromdata( 139 ctx, pkey, private ? EVP_PKEY_KEYPAIR : EVP_PKEY_PUBLIC_KEY, 140 params); 141 if (status != 1 || *pkey == NULL) { 142 DST_RET(dst__openssl_toresult2("EVP_PKEY_fromdata", 143 DST_R_OPENSSLFAILURE)); 144 } 145 146 ret = ISC_R_SUCCESS; 147 148 err: 149 if (params != NULL) { 150 OSSL_PARAM_free(params); 151 } 152 if (bld != NULL) { 153 OSSL_PARAM_BLD_free(bld); 154 } 155 if (ctx != NULL) { 156 EVP_PKEY_CTX_free(ctx); 157 } 158 if (priv != NULL) { 159 BN_clear_free(priv); 160 } 161 162 return (ret); 163 } 164 #endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L && OPENSSL_API_LEVEL >= 30000 \ 165 */ 166 167 static isc_result_t 168 opensslecdsa_createctx(dst_key_t *key, dst_context_t *dctx) { 169 isc_result_t ret = ISC_R_SUCCESS; 170 EVP_MD_CTX *evp_md_ctx; 171 const EVP_MD *type = NULL; 172 173 UNUSED(key); 174 REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 || 175 dctx->key->key_alg == DST_ALG_ECDSA384); 176 REQUIRE(dctx->use == DO_SIGN || dctx->use == DO_VERIFY); 177 178 evp_md_ctx = EVP_MD_CTX_create(); 179 if (evp_md_ctx == NULL) { 180 DST_RET(dst__openssl_toresult(ISC_R_NOMEMORY)); 181 } 182 if (dctx->key->key_alg == DST_ALG_ECDSA256) { 183 type = EVP_sha256(); 184 } else { 185 type = EVP_sha384(); 186 } 187 188 if (dctx->use == DO_SIGN) { 189 if (EVP_DigestSignInit(evp_md_ctx, NULL, type, NULL, 190 dctx->key->keydata.pkey) != 1) 191 { 192 EVP_MD_CTX_destroy(evp_md_ctx); 193 DST_RET(dst__openssl_toresult3(dctx->category, 194 "EVP_DigestSignInit", 195 ISC_R_FAILURE)); 196 } 197 } else { 198 if (EVP_DigestVerifyInit(evp_md_ctx, NULL, type, NULL, 199 dctx->key->keydata.pkey) != 1) 200 { 201 EVP_MD_CTX_destroy(evp_md_ctx); 202 DST_RET(dst__openssl_toresult3(dctx->category, 203 "EVP_DigestVerifyInit", 204 ISC_R_FAILURE)); 205 } 206 } 207 208 dctx->ctxdata.evp_md_ctx = evp_md_ctx; 209 210 err: 211 return (ret); 212 } 213 214 static void 215 opensslecdsa_destroyctx(dst_context_t *dctx) { 216 EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; 217 218 REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 || 219 dctx->key->key_alg == DST_ALG_ECDSA384); 220 REQUIRE(dctx->use == DO_SIGN || dctx->use == DO_VERIFY); 221 222 if (evp_md_ctx != NULL) { 223 EVP_MD_CTX_destroy(evp_md_ctx); 224 dctx->ctxdata.evp_md_ctx = NULL; 225 } 226 } 227 228 static isc_result_t 229 opensslecdsa_adddata(dst_context_t *dctx, const isc_region_t *data) { 230 isc_result_t ret = ISC_R_SUCCESS; 231 EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; 232 233 REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 || 234 dctx->key->key_alg == DST_ALG_ECDSA384); 235 REQUIRE(dctx->use == DO_SIGN || dctx->use == DO_VERIFY); 236 237 if (dctx->use == DO_SIGN) { 238 if (EVP_DigestSignUpdate(evp_md_ctx, data->base, 239 data->length) != 1) 240 { 241 DST_RET(dst__openssl_toresult3(dctx->category, 242 "EVP_DigestSignUpdate", 243 ISC_R_FAILURE)); 244 } 245 } else { 246 if (EVP_DigestVerifyUpdate(evp_md_ctx, data->base, 247 data->length) != 1) 248 { 249 DST_RET(dst__openssl_toresult3(dctx->category, 250 "EVP_DigestVerifyUpdate", 251 ISC_R_FAILURE)); 252 } 253 } 254 255 err: 256 return (ret); 257 } 258 259 static int 260 BN_bn2bin_fixed(const BIGNUM *bn, unsigned char *buf, int size) { 261 int bytes = size - BN_num_bytes(bn); 262 263 INSIST(bytes >= 0); 264 265 while (bytes-- > 0) { 266 *buf++ = 0; 267 } 268 BN_bn2bin(bn, buf); 269 return (size); 270 } 271 272 static isc_result_t 273 opensslecdsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { 274 isc_result_t ret; 275 dst_key_t *key = dctx->key; 276 isc_region_t region; 277 EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; 278 ECDSA_SIG *ecdsasig = NULL; 279 size_t siglen, sigder_len = 0, sigder_alloced = 0; 280 unsigned char *sigder = NULL; 281 const unsigned char *sigder_copy; 282 const BIGNUM *r, *s; 283 284 REQUIRE(key->key_alg == DST_ALG_ECDSA256 || 285 key->key_alg == DST_ALG_ECDSA384); 286 REQUIRE(dctx->use == DO_SIGN); 287 288 if (key->key_alg == DST_ALG_ECDSA256) { 289 siglen = DNS_SIG_ECDSA256SIZE; 290 } else { 291 siglen = DNS_SIG_ECDSA384SIZE; 292 } 293 294 isc_buffer_availableregion(sig, ®ion); 295 if (region.length < siglen) { 296 DST_RET(ISC_R_NOSPACE); 297 } 298 299 if (EVP_DigestSignFinal(evp_md_ctx, NULL, &sigder_len) != 1) { 300 DST_RET(dst__openssl_toresult3( 301 dctx->category, "EVP_DigestSignFinal", ISC_R_FAILURE)); 302 } 303 if (sigder_len == 0) { 304 DST_RET(ISC_R_FAILURE); 305 } 306 sigder = isc_mem_get(dctx->mctx, sigder_len); 307 sigder_alloced = sigder_len; 308 if (EVP_DigestSignFinal(evp_md_ctx, sigder, &sigder_len) != 1) { 309 DST_RET(dst__openssl_toresult3( 310 dctx->category, "EVP_DigestSignFinal", ISC_R_FAILURE)); 311 } 312 sigder_copy = sigder; 313 if (d2i_ECDSA_SIG(&ecdsasig, &sigder_copy, sigder_len) == NULL) { 314 DST_RET(dst__openssl_toresult3(dctx->category, "d2i_ECDSA_SIG", 315 ISC_R_FAILURE)); 316 } 317 318 ECDSA_SIG_get0(ecdsasig, &r, &s); 319 BN_bn2bin_fixed(r, region.base, siglen / 2); 320 isc_region_consume(®ion, siglen / 2); 321 BN_bn2bin_fixed(s, region.base, siglen / 2); 322 isc_region_consume(®ion, siglen / 2); 323 ECDSA_SIG_free(ecdsasig); 324 isc_buffer_add(sig, siglen); 325 ret = ISC_R_SUCCESS; 326 327 err: 328 if (sigder != NULL && sigder_alloced != 0) { 329 isc_mem_put(dctx->mctx, sigder, sigder_alloced); 330 } 331 332 return (ret); 333 } 334 335 static isc_result_t 336 opensslecdsa_verify(dst_context_t *dctx, const isc_region_t *sig) { 337 isc_result_t ret; 338 dst_key_t *key = dctx->key; 339 int status; 340 unsigned char *cp = sig->base; 341 ECDSA_SIG *ecdsasig = NULL; 342 EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; 343 size_t siglen, sigder_len = 0, sigder_alloced = 0; 344 unsigned char *sigder = NULL; 345 unsigned char *sigder_copy; 346 BIGNUM *r = NULL, *s = NULL; 347 348 REQUIRE(key->key_alg == DST_ALG_ECDSA256 || 349 key->key_alg == DST_ALG_ECDSA384); 350 REQUIRE(dctx->use == DO_VERIFY); 351 352 if (key->key_alg == DST_ALG_ECDSA256) { 353 siglen = DNS_SIG_ECDSA256SIZE; 354 } else { 355 siglen = DNS_SIG_ECDSA384SIZE; 356 } 357 358 if (sig->length != siglen) { 359 DST_RET(DST_R_VERIFYFAILURE); 360 } 361 362 ecdsasig = ECDSA_SIG_new(); 363 if (ecdsasig == NULL) { 364 DST_RET(dst__openssl_toresult(ISC_R_NOMEMORY)); 365 } 366 r = BN_bin2bn(cp, siglen / 2, NULL); 367 cp += siglen / 2; 368 s = BN_bin2bn(cp, siglen / 2, NULL); 369 /* cp += siglen / 2; */ 370 ECDSA_SIG_set0(ecdsasig, r, s); 371 372 status = i2d_ECDSA_SIG(ecdsasig, NULL); 373 if (status < 0) { 374 DST_RET(dst__openssl_toresult3(dctx->category, "i2d_ECDSA_SIG", 375 DST_R_VERIFYFAILURE)); 376 } 377 378 sigder_len = (size_t)status; 379 sigder = isc_mem_get(dctx->mctx, sigder_len); 380 sigder_alloced = sigder_len; 381 382 sigder_copy = sigder; 383 status = i2d_ECDSA_SIG(ecdsasig, &sigder_copy); 384 if (status < 0) { 385 DST_RET(dst__openssl_toresult3(dctx->category, "i2d_ECDSA_SIG", 386 DST_R_VERIFYFAILURE)); 387 } 388 389 status = EVP_DigestVerifyFinal(evp_md_ctx, sigder, sigder_len); 390 391 switch (status) { 392 case 1: 393 ret = ISC_R_SUCCESS; 394 break; 395 case 0: 396 ret = dst__openssl_toresult(DST_R_VERIFYFAILURE); 397 break; 398 default: 399 ret = dst__openssl_toresult3(dctx->category, 400 "EVP_DigestVerifyFinal", 401 DST_R_VERIFYFAILURE); 402 break; 403 } 404 405 err: 406 if (ecdsasig != NULL) { 407 ECDSA_SIG_free(ecdsasig); 408 } 409 if (sigder != NULL && sigder_alloced != 0) { 410 isc_mem_put(dctx->mctx, sigder, sigder_alloced); 411 } 412 413 return (ret); 414 } 415 416 static bool 417 opensslecdsa_compare(const dst_key_t *key1, const dst_key_t *key2) { 418 bool ret; 419 EVP_PKEY *pkey1 = key1->keydata.pkey; 420 EVP_PKEY *pkey2 = key2->keydata.pkey; 421 #if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 422 EC_KEY *eckey1 = NULL; 423 EC_KEY *eckey2 = NULL; 424 const BIGNUM *priv1; 425 const BIGNUM *priv2; 426 #else 427 BIGNUM *priv1 = NULL; 428 BIGNUM *priv2 = NULL; 429 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 430 431 if (pkey1 == NULL && pkey2 == NULL) { 432 return (true); 433 } else if (pkey1 == NULL || pkey2 == NULL) { 434 return (false); 435 } 436 437 /* `EVP_PKEY_eq` checks only the public key components and paramters. */ 438 if (EVP_PKEY_eq(pkey1, pkey2) != 1) { 439 DST_RET(false); 440 } 441 442 #if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 443 eckey1 = EVP_PKEY_get1_EC_KEY(pkey1); 444 eckey2 = EVP_PKEY_get1_EC_KEY(pkey2); 445 if (eckey1 == NULL && eckey2 == NULL) { 446 ERR_clear_error(); 447 DST_RET(true); 448 } else if (eckey1 == NULL || eckey2 == NULL) { 449 ERR_clear_error(); 450 DST_RET(false); 451 } 452 priv1 = EC_KEY_get0_private_key(eckey1); 453 priv2 = EC_KEY_get0_private_key(eckey2); 454 #else 455 EVP_PKEY_get_bn_param(pkey1, OSSL_PKEY_PARAM_PRIV_KEY, &priv1); 456 EVP_PKEY_get_bn_param(pkey2, OSSL_PKEY_PARAM_PRIV_KEY, &priv2); 457 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 458 459 if (priv1 != NULL || priv2 != NULL) { 460 if (priv1 == NULL || priv2 == NULL || BN_cmp(priv1, priv2) != 0) 461 { 462 ERR_clear_error(); 463 DST_RET(false); 464 } 465 } else { 466 ERR_clear_error(); 467 } 468 469 ret = true; 470 471 err: 472 #if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 473 if (eckey1 != NULL) { 474 EC_KEY_free(eckey1); 475 } 476 if (eckey2 != NULL) { 477 EC_KEY_free(eckey2); 478 } 479 #else 480 if (priv1 != NULL) { 481 BN_clear_free(priv1); 482 } 483 if (priv2 != NULL) { 484 BN_clear_free(priv2); 485 } 486 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 487 488 return (ret); 489 } 490 491 static isc_result_t 492 opensslecdsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { 493 isc_result_t ret; 494 int status; 495 EVP_PKEY *pkey = NULL; 496 #if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 497 EC_KEY *eckey = NULL; 498 #else 499 EVP_PKEY_CTX *ctx = NULL; 500 EVP_PKEY *params_pkey = NULL; 501 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 502 int group_nid; 503 504 REQUIRE(key->key_alg == DST_ALG_ECDSA256 || 505 key->key_alg == DST_ALG_ECDSA384); 506 UNUSED(unused); 507 UNUSED(callback); 508 509 if (key->key_alg == DST_ALG_ECDSA256) { 510 group_nid = NID_X9_62_prime256v1; 511 key->key_size = DNS_KEY_ECDSA256SIZE * 4; 512 } else { 513 group_nid = NID_secp384r1; 514 key->key_size = DNS_KEY_ECDSA384SIZE * 4; 515 } 516 517 #if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 518 eckey = EC_KEY_new_by_curve_name(group_nid); 519 if (eckey == NULL) { 520 DST_RET(dst__openssl_toresult2("EC_KEY_new_by_curve_name", 521 DST_R_OPENSSLFAILURE)); 522 } 523 524 status = EC_KEY_generate_key(eckey); 525 if (status != 1) { 526 DST_RET(dst__openssl_toresult2("EC_KEY_generate_key", 527 DST_R_OPENSSLFAILURE)); 528 } 529 530 pkey = EVP_PKEY_new(); 531 if (pkey == NULL) { 532 DST_RET(dst__openssl_toresult(ISC_R_NOMEMORY)); 533 } 534 if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) { 535 DST_RET(ISC_R_FAILURE); 536 } 537 #else 538 /* Generate the key's parameters. */ 539 ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL); 540 if (ctx == NULL) { 541 DST_RET(dst__openssl_toresult2("EVP_PKEY_CTX_new_from_name", 542 DST_R_OPENSSLFAILURE)); 543 } 544 status = EVP_PKEY_paramgen_init(ctx); 545 if (status != 1) { 546 DST_RET(dst__openssl_toresult2("EVP_PKEY_paramgen_init", 547 DST_R_OPENSSLFAILURE)); 548 } 549 status = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, group_nid); 550 if (status != 1) { 551 DST_RET(dst__openssl_toresult2("EVP_PKEY_CTX_set_ec_paramgen_" 552 "curve_nid", 553 DST_R_OPENSSLFAILURE)); 554 } 555 status = EVP_PKEY_paramgen(ctx, ¶ms_pkey); 556 if (status != 1 || params_pkey == NULL) { 557 DST_RET(dst__openssl_toresult2("EVP_PKEY_paramgen", 558 DST_R_OPENSSLFAILURE)); 559 } 560 EVP_PKEY_CTX_free(ctx); 561 562 /* Generate the key. */ 563 ctx = EVP_PKEY_CTX_new(params_pkey, NULL); 564 if (ctx == NULL) { 565 DST_RET(dst__openssl_toresult2("EVP_PKEY_CTX_new", 566 DST_R_OPENSSLFAILURE)); 567 } 568 status = EVP_PKEY_keygen_init(ctx); 569 if (status != 1) { 570 DST_RET(dst__openssl_toresult2("EVP_PKEY_keygen_init", 571 DST_R_OPENSSLFAILURE)); 572 } 573 status = EVP_PKEY_keygen(ctx, &pkey); 574 if (status != 1 || pkey == NULL) { 575 DST_RET(dst__openssl_toresult2("EVP_PKEY_keygen", 576 DST_R_OPENSSLFAILURE)); 577 } 578 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 579 580 key->keydata.pkey = pkey; 581 pkey = NULL; 582 ret = ISC_R_SUCCESS; 583 584 err: 585 if (pkey != NULL) { 586 EVP_PKEY_free(pkey); 587 } 588 #if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 589 if (eckey != NULL) { 590 EC_KEY_free(eckey); 591 } 592 #else 593 if (params_pkey != NULL) { 594 EVP_PKEY_free(params_pkey); 595 } 596 if (ctx != NULL) { 597 EVP_PKEY_CTX_free(ctx); 598 } 599 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 600 601 return (ret); 602 } 603 604 static bool 605 opensslecdsa_isprivate(const dst_key_t *key) { 606 bool ret; 607 EVP_PKEY *pkey; 608 #if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 609 EC_KEY *eckey; 610 #else 611 BIGNUM *priv = NULL; 612 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 613 614 REQUIRE(key->key_alg == DST_ALG_ECDSA256 || 615 key->key_alg == DST_ALG_ECDSA384); 616 617 pkey = key->keydata.pkey; 618 if (pkey == NULL) { 619 return (false); 620 } 621 622 #if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 623 eckey = EVP_PKEY_get1_EC_KEY(pkey); 624 625 ret = (eckey != NULL && EC_KEY_get0_private_key(eckey) != NULL); 626 if (eckey != NULL) { 627 EC_KEY_free(eckey); 628 } else { 629 ERR_clear_error(); 630 } 631 #else 632 ret = (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, &priv) == 633 1 && 634 priv != NULL); 635 if (priv != NULL) { 636 BN_clear_free(priv); 637 } 638 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 639 640 return (ret); 641 } 642 643 static void 644 opensslecdsa_destroy(dst_key_t *key) { 645 EVP_PKEY *pkey = key->keydata.pkey; 646 647 if (pkey != NULL) { 648 EVP_PKEY_free(pkey); 649 key->keydata.pkey = NULL; 650 } 651 } 652 653 static isc_result_t 654 opensslecdsa_todns(const dst_key_t *key, isc_buffer_t *data) { 655 isc_result_t ret; 656 EVP_PKEY *pkey; 657 #if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 658 EC_KEY *eckey = NULL; 659 int len; 660 unsigned char *cp; 661 #else 662 int status; 663 BIGNUM *x = NULL; 664 BIGNUM *y = NULL; 665 size_t keysize = 0; 666 size_t len = 0; 667 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 668 isc_region_t r; 669 unsigned char buf[DNS_KEY_ECDSA384SIZE + 1]; 670 671 REQUIRE(key->keydata.pkey != NULL); 672 673 pkey = key->keydata.pkey; 674 675 #if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 676 eckey = EVP_PKEY_get1_EC_KEY(pkey); 677 if (eckey == NULL) { 678 DST_RET(dst__openssl_toresult(ISC_R_FAILURE)); 679 } 680 len = i2o_ECPublicKey(eckey, NULL); 681 682 /* skip form */ 683 len--; 684 #else 685 if (key->key_alg == DST_ALG_ECDSA256) { 686 keysize = DNS_KEY_ECDSA256SIZE; 687 } else if (key->key_alg == DST_ALG_ECDSA384) { 688 keysize = DNS_KEY_ECDSA384SIZE; 689 } else { 690 DST_RET(ISC_R_NOTIMPLEMENTED); 691 } 692 693 len = keysize; 694 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 695 696 isc_buffer_availableregion(data, &r); 697 if (r.length < (unsigned int)len) { 698 DST_RET(ISC_R_NOSPACE); 699 } 700 701 #if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 702 cp = buf; 703 if (!i2o_ECPublicKey(eckey, &cp)) { 704 DST_RET(dst__openssl_toresult(ISC_R_FAILURE)); 705 } 706 memmove(r.base, buf + 1, len); 707 #else 708 status = EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_EC_PUB_X, &x); 709 if (status != 1 || x == NULL) { 710 DST_RET(dst__openssl_toresult2("EVP_PKEY_get_bn_param", 711 DST_R_OPENSSLFAILURE)); 712 } 713 status = EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_EC_PUB_Y, &y); 714 if (status != 1 || y == NULL) { 715 DST_RET(dst__openssl_toresult2("EVP_PKEY_get_bn_param", 716 DST_R_OPENSSLFAILURE)); 717 } 718 BN_bn2bin_fixed(x, &buf[0], keysize / 2); 719 BN_bn2bin_fixed(y, &buf[keysize / 2], keysize / 2); 720 memmove(r.base, buf, len); 721 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 722 723 isc_buffer_add(data, len); 724 ret = ISC_R_SUCCESS; 725 726 err: 727 #if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 728 if (eckey != NULL) { 729 EC_KEY_free(eckey); 730 } 731 #else 732 if (x != NULL) { 733 BN_clear_free(x); 734 } 735 if (y != NULL) { 736 BN_clear_free(y); 737 } 738 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 739 740 return (ret); 741 } 742 743 static isc_result_t 744 opensslecdsa_fromdns(dst_key_t *key, isc_buffer_t *data) { 745 isc_result_t ret; 746 EVP_PKEY *pkey = NULL; 747 isc_region_t r; 748 #if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 749 EC_KEY *eckey = NULL; 750 const unsigned char *cp; 751 unsigned int len; 752 unsigned char buf[DNS_KEY_ECDSA384SIZE + 1]; 753 int group_nid; 754 #else 755 size_t len; 756 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 757 758 REQUIRE(key->key_alg == DST_ALG_ECDSA256 || 759 key->key_alg == DST_ALG_ECDSA384); 760 761 if (key->key_alg == DST_ALG_ECDSA256) { 762 len = DNS_KEY_ECDSA256SIZE; 763 } else { 764 len = DNS_KEY_ECDSA384SIZE; 765 } 766 767 isc_buffer_remainingregion(data, &r); 768 if (r.length == 0) { 769 DST_RET(ISC_R_SUCCESS); 770 } 771 if (r.length != len) { 772 DST_RET(DST_R_INVALIDPUBLICKEY); 773 } 774 775 #if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 776 if (key->key_alg == DST_ALG_ECDSA256) { 777 group_nid = NID_X9_62_prime256v1; 778 } else { 779 group_nid = NID_secp384r1; 780 } 781 782 eckey = EC_KEY_new_by_curve_name(group_nid); 783 if (eckey == NULL) { 784 DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE)); 785 } 786 787 buf[0] = POINT_CONVERSION_UNCOMPRESSED; 788 memmove(buf + 1, r.base, len); 789 cp = buf; 790 if (o2i_ECPublicKey(&eckey, (const unsigned char **)&cp, 791 (long)len + 1) == NULL) 792 { 793 DST_RET(dst__openssl_toresult(DST_R_INVALIDPUBLICKEY)); 794 } 795 if (EC_KEY_check_key(eckey) != 1) { 796 DST_RET(dst__openssl_toresult(DST_R_INVALIDPUBLICKEY)); 797 } 798 799 pkey = EVP_PKEY_new(); 800 if (pkey == NULL) { 801 DST_RET(dst__openssl_toresult(ISC_R_NOMEMORY)); 802 } 803 if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) { 804 EVP_PKEY_free(pkey); 805 DST_RET(dst__openssl_toresult(ISC_R_FAILURE)); 806 } 807 #else 808 ret = raw_key_to_ossl(key->key_alg, 0, r.base, len, &pkey); 809 if (ret != ISC_R_SUCCESS) { 810 DST_RET(ret); 811 } 812 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 813 814 isc_buffer_forward(data, len); 815 key->keydata.pkey = pkey; 816 key->key_size = len * 4; 817 ret = ISC_R_SUCCESS; 818 819 err: 820 #if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 821 if (eckey != NULL) { 822 EC_KEY_free(eckey); 823 } 824 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 825 return (ret); 826 } 827 828 static isc_result_t 829 opensslecdsa_tofile(const dst_key_t *key, const char *directory) { 830 isc_result_t ret; 831 EVP_PKEY *pkey; 832 #if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 833 EC_KEY *eckey = NULL; 834 const BIGNUM *privkey = NULL; 835 #else 836 int status; 837 BIGNUM *privkey = NULL; 838 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 839 dst_private_t priv; 840 unsigned char *buf = NULL; 841 unsigned short i; 842 843 if (key->keydata.pkey == NULL) { 844 DST_RET(DST_R_NULLKEY); 845 } 846 847 if (key->external) { 848 priv.nelements = 0; 849 DST_RET(dst__privstruct_writefile(key, &priv, directory)); 850 } 851 852 pkey = key->keydata.pkey; 853 #if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 854 eckey = EVP_PKEY_get1_EC_KEY(pkey); 855 if (eckey == NULL) { 856 DST_RET(dst__openssl_toresult2("EVP_PKEY_get1_EC_KEY", 857 DST_R_OPENSSLFAILURE)); 858 } 859 privkey = EC_KEY_get0_private_key(eckey); 860 if (privkey == NULL) { 861 DST_RET(dst__openssl_toresult2("EC_KEY_get0_private_key", 862 DST_R_OPENSSLFAILURE)); 863 } 864 #else 865 status = EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, 866 &privkey); 867 if (status != 1 || privkey == NULL) { 868 DST_RET(dst__openssl_toresult2("EVP_PKEY_get_bn_param", 869 DST_R_OPENSSLFAILURE)); 870 } 871 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 872 873 buf = isc_mem_get(key->mctx, BN_num_bytes(privkey)); 874 875 i = 0; 876 877 priv.elements[i].tag = TAG_ECDSA_PRIVATEKEY; 878 priv.elements[i].length = BN_num_bytes(privkey); 879 BN_bn2bin(privkey, buf); 880 priv.elements[i].data = buf; 881 i++; 882 883 if (key->engine != NULL) { 884 priv.elements[i].tag = TAG_ECDSA_ENGINE; 885 priv.elements[i].length = (unsigned short)strlen(key->engine) + 886 1; 887 priv.elements[i].data = (unsigned char *)key->engine; 888 i++; 889 } 890 891 if (key->label != NULL) { 892 priv.elements[i].tag = TAG_ECDSA_LABEL; 893 priv.elements[i].length = (unsigned short)strlen(key->label) + 894 1; 895 priv.elements[i].data = (unsigned char *)key->label; 896 i++; 897 } 898 899 priv.nelements = i; 900 ret = dst__privstruct_writefile(key, &priv, directory); 901 902 err: 903 if (buf != NULL && privkey != NULL) { 904 isc_mem_put(key->mctx, buf, BN_num_bytes(privkey)); 905 } 906 #if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 907 if (eckey != NULL) { 908 EC_KEY_free(eckey); 909 } 910 #else 911 if (privkey != NULL) { 912 BN_clear_free(privkey); 913 } 914 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 915 916 return (ret); 917 } 918 919 #if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 920 static isc_result_t 921 ecdsa_check(EC_KEY *eckey, EC_KEY *pubeckey) { 922 const EC_POINT *pubkey; 923 924 pubkey = EC_KEY_get0_public_key(eckey); 925 if (pubkey != NULL) { 926 return (ISC_R_SUCCESS); 927 } else if (pubeckey != NULL) { 928 pubkey = EC_KEY_get0_public_key(pubeckey); 929 if (pubkey == NULL) { 930 return (ISC_R_SUCCESS); 931 } 932 if (EC_KEY_set_public_key(eckey, pubkey) != 1) { 933 return (ISC_R_SUCCESS); 934 } 935 } 936 if (EC_KEY_check_key(eckey) == 1) { 937 return (ISC_R_SUCCESS); 938 } 939 940 return (ISC_R_FAILURE); 941 } 942 #else 943 static isc_result_t 944 ecdsa_check(EVP_PKEY **pkey, EVP_PKEY *pubpkey) { 945 isc_result_t ret = ISC_R_FAILURE; 946 int status; 947 size_t pkey_len = 0; 948 BIGNUM *x = NULL; 949 BIGNUM *y = NULL; 950 BIGNUM *priv = NULL; 951 char groupname[80]; 952 unsigned char buf[DNS_KEY_ECDSA384SIZE + 1]; 953 size_t keysize; 954 OSSL_PARAM_BLD *bld = NULL; 955 OSSL_PARAM *params = NULL; 956 EVP_PKEY_CTX *ctx = NULL; 957 EVP_PKEY *pkey_new = NULL; 958 959 /* Check if `pkey` has a public key. */ 960 status = EVP_PKEY_get_octet_string_param(*pkey, OSSL_PKEY_PARAM_PUB_KEY, 961 NULL, 0, &pkey_len); 962 963 /* Check if `pubpkey` exists and that we can extract its public key. */ 964 if (pubpkey == NULL || 965 EVP_PKEY_get_bn_param(pubpkey, OSSL_PKEY_PARAM_EC_PUB_X, &x) != 1 || 966 x == NULL || 967 EVP_PKEY_get_bn_param(pubpkey, OSSL_PKEY_PARAM_EC_PUB_Y, &y) != 1 || 968 y == NULL) 969 { 970 if (status != 1 || pkey_len == 0) { 971 /* No public key both in `pkey` and in `pubpkey` */ 972 DST_RET(DST_R_INVALIDPRIVATEKEY); 973 } else { 974 /* 975 * `pkey` has a public key, but there is no public key 976 * in `pubpkey` to check against. 977 */ 978 DST_RET(ISC_R_SUCCESS); 979 } 980 } 981 982 /* 983 * If `pkey` doesn't have a public key then we will copy it from 984 * `pubpkey`. 985 */ 986 if (status != 1 || pkey_len == 0) { 987 /* 988 * We can't (?) add a public key to an existing PKEY, so we 989 * have to create a new PKEY. 990 */ 991 992 keysize = (EVP_PKEY_bits(*pkey) + 7) / 8; 993 /* 994 * The "raw" public key is created by combining the "x" and "y" 995 * parts. 996 */ 997 keysize *= 2; 998 buf[0] = POINT_CONVERSION_UNCOMPRESSED; 999 BN_bn2bin_fixed(x, &buf[1], keysize / 2); 1000 BN_bn2bin_fixed(y, &buf[1 + keysize / 2], keysize / 2); 1001 1002 groupname[0] = '\0'; 1003 status = EVP_PKEY_get_utf8_string_param( 1004 *pkey, OSSL_PKEY_PARAM_GROUP_NAME, groupname, 1005 sizeof groupname, NULL); 1006 if (status != 1 || strlen(groupname) == 0) { 1007 DST_RET(ISC_R_FAILURE); 1008 } 1009 status = EVP_PKEY_get_bn_param(*pkey, OSSL_PKEY_PARAM_PRIV_KEY, 1010 &priv); 1011 if (status != 1) { 1012 DST_RET(ISC_R_FAILURE); 1013 } 1014 1015 bld = OSSL_PARAM_BLD_new(); 1016 if (bld == NULL) { 1017 DST_RET(ISC_R_FAILURE); 1018 } 1019 if (OSSL_PARAM_BLD_push_utf8_string( 1020 bld, OSSL_PKEY_PARAM_GROUP_NAME, groupname, 0) != 1) 1021 { 1022 DST_RET(ISC_R_FAILURE); 1023 } 1024 if (OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PRIV_KEY, 1025 priv) != 1) 1026 { 1027 DST_RET(ISC_R_FAILURE); 1028 } 1029 if (OSSL_PARAM_BLD_push_octet_string(bld, 1030 OSSL_PKEY_PARAM_PUB_KEY, 1031 buf, 1 + keysize) != 1) 1032 { 1033 DST_RET(ISC_R_FAILURE); 1034 } 1035 params = OSSL_PARAM_BLD_to_param(bld); 1036 if (params == NULL) { 1037 DST_RET(ISC_R_FAILURE); 1038 } 1039 1040 ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL); 1041 if (ctx == NULL) { 1042 DST_RET(ISC_R_FAILURE); 1043 } 1044 if (EVP_PKEY_fromdata_init(ctx) != 1) { 1045 DST_RET(ISC_R_FAILURE); 1046 } 1047 status = EVP_PKEY_fromdata(ctx, &pkey_new, EVP_PKEY_KEYPAIR, 1048 params); 1049 if (status != 1 || pkey_new == NULL) { 1050 DST_RET(ISC_R_FAILURE); 1051 } 1052 1053 /* Replace the old key with the new one. */ 1054 EVP_PKEY_free(*pkey); 1055 *pkey = pkey_new; 1056 } 1057 1058 if (EVP_PKEY_eq(*pkey, pubpkey) == 1) { 1059 DST_RET(ISC_R_SUCCESS); 1060 } 1061 1062 err: 1063 if (ctx != NULL) { 1064 EVP_PKEY_CTX_free(ctx); 1065 } 1066 if (params != NULL) { 1067 OSSL_PARAM_free(params); 1068 } 1069 if (bld != NULL) { 1070 OSSL_PARAM_BLD_free(bld); 1071 } 1072 if (priv != NULL) { 1073 BN_clear_free(priv); 1074 } 1075 if (x != NULL) { 1076 BN_clear_free(x); 1077 } 1078 if (y != NULL) { 1079 BN_clear_free(y); 1080 } 1081 1082 return (ret); 1083 } 1084 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 1085 1086 #if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 1087 static isc_result_t 1088 load_privkey_from_privstruct(EC_KEY *eckey, dst_private_t *priv, 1089 int privkey_index) { 1090 BIGNUM *privkey = BN_bin2bn(priv->elements[privkey_index].data, 1091 priv->elements[privkey_index].length, NULL); 1092 isc_result_t result = ISC_R_SUCCESS; 1093 1094 if (privkey == NULL) { 1095 return (ISC_R_NOMEMORY); 1096 } 1097 1098 if (!EC_KEY_set_private_key(eckey, privkey)) { 1099 result = ISC_R_NOMEMORY; 1100 } 1101 1102 BN_clear_free(privkey); 1103 return (result); 1104 } 1105 1106 static isc_result_t 1107 eckey_to_pkey(EC_KEY *eckey, EVP_PKEY **pkey) { 1108 REQUIRE(pkey != NULL && *pkey == NULL); 1109 1110 *pkey = EVP_PKEY_new(); 1111 if (*pkey == NULL) { 1112 return (dst__openssl_toresult(ISC_R_NOMEMORY)); 1113 } 1114 if (!EVP_PKEY_set1_EC_KEY(*pkey, eckey)) { 1115 EVP_PKEY_free(*pkey); 1116 *pkey = NULL; 1117 return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); 1118 } 1119 return (ISC_R_SUCCESS); 1120 } 1121 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 1122 1123 static isc_result_t 1124 finalize_eckey(dst_key_t *key, 1125 #if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 1126 EC_KEY *eckey, 1127 #endif 1128 const char *engine, const char *label) { 1129 isc_result_t result = ISC_R_SUCCESS; 1130 #if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 1131 EVP_PKEY *pkey = NULL; 1132 1133 REQUIRE(eckey != NULL); 1134 1135 result = eckey_to_pkey(eckey, &pkey); 1136 if (result != ISC_R_SUCCESS) { 1137 return (result); 1138 } 1139 1140 key->keydata.pkey = pkey; 1141 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 1142 1143 if (label != NULL) { 1144 key->label = isc_mem_strdup(key->mctx, label); 1145 key->engine = isc_mem_strdup(key->mctx, engine); 1146 } 1147 1148 if (key->key_alg == DST_ALG_ECDSA256) { 1149 key->key_size = DNS_KEY_ECDSA256SIZE * 4; 1150 } else { 1151 key->key_size = DNS_KEY_ECDSA384SIZE * 4; 1152 } 1153 1154 return (result); 1155 } 1156 1157 #if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 1158 static isc_result_t 1159 dst__key_to_eckey(dst_key_t *key, EC_KEY **eckey) { 1160 int group_nid; 1161 1162 REQUIRE(eckey != NULL && *eckey == NULL); 1163 1164 switch (key->key_alg) { 1165 case DST_ALG_ECDSA256: 1166 group_nid = NID_X9_62_prime256v1; 1167 break; 1168 case DST_ALG_ECDSA384: 1169 group_nid = NID_secp384r1; 1170 break; 1171 default: 1172 UNREACHABLE(); 1173 } 1174 1175 *eckey = EC_KEY_new_by_curve_name(group_nid); 1176 if (*eckey == NULL) { 1177 return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); 1178 } 1179 1180 return (ISC_R_SUCCESS); 1181 } 1182 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 1183 1184 static isc_result_t 1185 opensslecdsa_fromlabel(dst_key_t *key, const char *engine, const char *label, 1186 const char *pin); 1187 1188 static isc_result_t 1189 opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { 1190 dst_private_t priv; 1191 isc_result_t ret; 1192 #if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 1193 EC_KEY *eckey = NULL; 1194 EC_KEY *pubeckey = NULL; 1195 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 1196 const char *engine = NULL; 1197 const char *label = NULL; 1198 int i, privkey_index = -1; 1199 bool finalize_key = false; 1200 1201 REQUIRE(key->key_alg == DST_ALG_ECDSA256 || 1202 key->key_alg == DST_ALG_ECDSA384); 1203 1204 /* read private key file */ 1205 ret = dst__privstruct_parse(key, DST_ALG_ECDSA256, lexer, key->mctx, 1206 &priv); 1207 if (ret != ISC_R_SUCCESS) { 1208 goto err; 1209 } 1210 1211 if (key->external) { 1212 if (priv.nelements != 0 || pub == NULL) { 1213 DST_RET(dst__openssl_toresult(DST_R_INVALIDPRIVATEKEY)); 1214 } 1215 key->keydata.pkey = pub->keydata.pkey; 1216 pub->keydata.pkey = NULL; 1217 DST_RET(ISC_R_SUCCESS); 1218 } 1219 1220 for (i = 0; i < priv.nelements; i++) { 1221 switch (priv.elements[i].tag) { 1222 case TAG_ECDSA_ENGINE: 1223 engine = (char *)priv.elements[i].data; 1224 break; 1225 case TAG_ECDSA_LABEL: 1226 label = (char *)priv.elements[i].data; 1227 break; 1228 case TAG_ECDSA_PRIVATEKEY: 1229 privkey_index = i; 1230 break; 1231 default: 1232 break; 1233 } 1234 } 1235 1236 if (privkey_index < 0) { 1237 DST_RET(dst__openssl_toresult(DST_R_INVALIDPRIVATEKEY)); 1238 } 1239 1240 if (label != NULL) { 1241 ret = opensslecdsa_fromlabel(key, engine, label, NULL); 1242 if (ret != ISC_R_SUCCESS) { 1243 goto err; 1244 } 1245 1246 #if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 1247 eckey = EVP_PKEY_get1_EC_KEY(key->keydata.pkey); 1248 if (eckey == NULL) { 1249 DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE)); 1250 } 1251 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 1252 } else { 1253 #if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 1254 ret = dst__key_to_eckey(key, &eckey); 1255 if (ret != ISC_R_SUCCESS) { 1256 goto err; 1257 } 1258 1259 ret = load_privkey_from_privstruct(eckey, &priv, privkey_index); 1260 #else 1261 if (key->keydata.pkey != NULL) { 1262 EVP_PKEY_free(key->keydata.pkey); 1263 key->keydata.pkey = NULL; 1264 } 1265 1266 ret = raw_key_to_ossl(key->key_alg, 1, 1267 priv.elements[privkey_index].data, 1268 priv.elements[privkey_index].length, 1269 &key->keydata.pkey); 1270 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 1271 1272 if (ret != ISC_R_SUCCESS) { 1273 goto err; 1274 } 1275 1276 finalize_key = true; 1277 } 1278 1279 #if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 1280 if (pub != NULL && pub->keydata.pkey != NULL) { 1281 pubeckey = EVP_PKEY_get1_EC_KEY(pub->keydata.pkey); 1282 } 1283 1284 if (ecdsa_check(eckey, pubeckey) != ISC_R_SUCCESS) { 1285 DST_RET(dst__openssl_toresult(DST_R_INVALIDPRIVATEKEY)); 1286 } 1287 1288 if (finalize_key) { 1289 ret = finalize_eckey(key, eckey, engine, label); 1290 } 1291 #else 1292 if (ecdsa_check(&key->keydata.pkey, 1293 pub == NULL ? NULL : pub->keydata.pkey) != 1294 ISC_R_SUCCESS) 1295 { 1296 DST_RET(dst__openssl_toresult(DST_R_INVALIDPRIVATEKEY)); 1297 } 1298 1299 if (finalize_key) { 1300 ret = finalize_eckey(key, engine, label); 1301 } 1302 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 1303 1304 err: 1305 #if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 1306 if (pubeckey != NULL) { 1307 EC_KEY_free(pubeckey); 1308 } 1309 if (eckey != NULL) { 1310 EC_KEY_free(eckey); 1311 } 1312 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 1313 if (ret != ISC_R_SUCCESS) { 1314 key->keydata.generic = NULL; 1315 } 1316 1317 dst__privstruct_free(&priv, key->mctx); 1318 isc_safe_memwipe(&priv, sizeof(priv)); 1319 1320 return (ret); 1321 } 1322 1323 static isc_result_t 1324 opensslecdsa_fromlabel(dst_key_t *key, const char *engine, const char *label, 1325 const char *pin) { 1326 #if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000 1327 isc_result_t ret = ISC_R_SUCCESS; 1328 ENGINE *e; 1329 EC_KEY *eckey = NULL; 1330 EC_KEY *pubeckey = NULL; 1331 int group_nid; 1332 EVP_PKEY *pkey = NULL; 1333 EVP_PKEY *pubpkey = NULL; 1334 1335 REQUIRE(key->key_alg == DST_ALG_ECDSA256 || 1336 key->key_alg == DST_ALG_ECDSA384); 1337 1338 UNUSED(pin); 1339 1340 if (engine == NULL || label == NULL) { 1341 return (DST_R_NOENGINE); 1342 } 1343 e = dst__openssl_getengine(engine); 1344 if (e == NULL) { 1345 DST_RET(DST_R_NOENGINE); 1346 } 1347 1348 if (key->key_alg == DST_ALG_ECDSA256) { 1349 group_nid = NID_X9_62_prime256v1; 1350 } else { 1351 group_nid = NID_secp384r1; 1352 } 1353 1354 /* Load private key. */ 1355 pkey = ENGINE_load_private_key(e, label, NULL, NULL); 1356 if (pkey == NULL) { 1357 DST_RET(dst__openssl_toresult2("ENGINE_load_private_key", 1358 DST_R_OPENSSLFAILURE)); 1359 } 1360 /* Check base id, group nid */ 1361 if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC) { 1362 DST_RET(DST_R_INVALIDPRIVATEKEY); 1363 } 1364 eckey = EVP_PKEY_get1_EC_KEY(pkey); 1365 if (eckey == NULL) { 1366 DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE)); 1367 } 1368 if (EC_GROUP_get_curve_name(EC_KEY_get0_group(eckey)) != group_nid) { 1369 DST_RET(DST_R_INVALIDPRIVATEKEY); 1370 } 1371 1372 /* Load public key. */ 1373 pubpkey = ENGINE_load_public_key(e, label, NULL, NULL); 1374 if (pubpkey == NULL) { 1375 DST_RET(dst__openssl_toresult2("ENGINE_load_public_key", 1376 DST_R_OPENSSLFAILURE)); 1377 } 1378 /* Check base id, group nid */ 1379 if (EVP_PKEY_base_id(pubpkey) != EVP_PKEY_EC) { 1380 DST_RET(DST_R_INVALIDPUBLICKEY); 1381 } 1382 pubeckey = EVP_PKEY_get1_EC_KEY(pubpkey); 1383 if (pubeckey == NULL) { 1384 DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE)); 1385 } 1386 if (EC_GROUP_get_curve_name(EC_KEY_get0_group(pubeckey)) != group_nid) { 1387 DST_RET(DST_R_INVALIDPUBLICKEY); 1388 } 1389 1390 if (ecdsa_check(eckey, pubeckey) != ISC_R_SUCCESS) { 1391 DST_RET(dst__openssl_toresult(DST_R_INVALIDPRIVATEKEY)); 1392 } 1393 1394 key->label = isc_mem_strdup(key->mctx, label); 1395 key->engine = isc_mem_strdup(key->mctx, engine); 1396 key->key_size = EVP_PKEY_bits(pkey); 1397 key->keydata.pkey = pkey; 1398 pkey = NULL; 1399 1400 err: 1401 if (pubpkey != NULL) { 1402 EVP_PKEY_free(pubpkey); 1403 } 1404 if (pkey != NULL) { 1405 EVP_PKEY_free(pkey); 1406 } 1407 if (pubeckey != NULL) { 1408 EC_KEY_free(pubeckey); 1409 } 1410 if (eckey != NULL) { 1411 EC_KEY_free(eckey); 1412 } 1413 1414 return (ret); 1415 #else 1416 UNUSED(key); 1417 UNUSED(engine); 1418 UNUSED(label); 1419 UNUSED(pin); 1420 return (DST_R_NOENGINE); 1421 #endif /* !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000 */ 1422 } 1423 1424 static dst_func_t opensslecdsa_functions = { 1425 opensslecdsa_createctx, 1426 NULL, /*%< createctx2 */ 1427 opensslecdsa_destroyctx, 1428 opensslecdsa_adddata, 1429 opensslecdsa_sign, 1430 opensslecdsa_verify, 1431 NULL, /*%< verify2 */ 1432 NULL, /*%< computesecret */ 1433 opensslecdsa_compare, 1434 NULL, /*%< paramcompare */ 1435 opensslecdsa_generate, 1436 opensslecdsa_isprivate, 1437 opensslecdsa_destroy, 1438 opensslecdsa_todns, 1439 opensslecdsa_fromdns, 1440 opensslecdsa_tofile, 1441 opensslecdsa_parse, 1442 NULL, /*%< cleanup */ 1443 opensslecdsa_fromlabel, /*%< fromlabel */ 1444 NULL, /*%< dump */ 1445 NULL, /*%< restore */ 1446 }; 1447 1448 isc_result_t 1449 dst__opensslecdsa_init(dst_func_t **funcp) { 1450 REQUIRE(funcp != NULL); 1451 if (*funcp == NULL) { 1452 *funcp = &opensslecdsa_functions; 1453 } 1454 return (ISC_R_SUCCESS); 1455 } 1456