From fa8343e9c9b699681ac31997b02a90412bceb86b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Thu, 26 Jan 2023 16:11:07 +0200 Subject: [PATCH 1/4] Introduce dst__openssl_keypair_{compare,isprivate,destroy} Rename and simplify dst__openssl_compare_keypair() to dst__openssl_keypair_compare(), and introduce two additional functions dst__openssl_keypair_isprivate and dst__openssl_keypair_destroy. Use those to de-duplicated openssl{rsa,ecdsa}_isprivate, and openssl{rsa,ecdsa}_destroy. --- lib/dns/dst_openssl.h | 8 +++++++- lib/dns/openssl_link.c | 19 +++++++++++++++++-- lib/dns/opensslecdsa_link.c | 23 +++-------------------- lib/dns/opensslrsa_link.c | 23 +++-------------------- 4 files changed, 30 insertions(+), 43 deletions(-) diff --git a/lib/dns/dst_openssl.h b/lib/dns/dst_openssl.h index 4380d36364..ad13770632 100644 --- a/lib/dns/dst_openssl.h +++ b/lib/dns/dst_openssl.h @@ -46,6 +46,12 @@ dst__openssl_fromlabel(int key_base_id, const char *engine, const char *label, const char *pin, EVP_PKEY **ppub, EVP_PKEY **ppriv); bool -dst__openssl_compare_keypair(const dst_key_t *key1, const dst_key_t *key2); +dst__openssl_keypair_compare(const dst_key_t *key1, const dst_key_t *key2); + +bool +dst__openssl_keypair_isprivate(const dst_key_t *key); + +void +dst__openssl_keypair_destroy(dst_key_t *key); ISC_LANG_ENDDECLS diff --git a/lib/dns/openssl_link.c b/lib/dns/openssl_link.c index 017e5d6977..cafc747825 100644 --- a/lib/dns/openssl_link.c +++ b/lib/dns/openssl_link.c @@ -357,11 +357,11 @@ dst__openssl_fromlabel(int key_base_id, const char *engine, const char *label, } bool -dst__openssl_compare_keypair(const dst_key_t *key1, const dst_key_t *key2) { +dst__openssl_keypair_compare(const dst_key_t *key1, const dst_key_t *key2) { EVP_PKEY *pkey1 = key1->keydata.pkeypair.pub; EVP_PKEY *pkey2 = key2->keydata.pkeypair.pub; - if (pkey1 == NULL && pkey2 == NULL) { + if (pkey1 == pkey2) { return (true); } else if (pkey1 == NULL || pkey2 == NULL) { return (false); @@ -380,4 +380,19 @@ dst__openssl_compare_keypair(const dst_key_t *key1, const dst_key_t *key2) { return (true); } +bool +dst__openssl_keypair_isprivate(const dst_key_t *key) { + return (key->keydata.pkeypair.priv != NULL); +} + +void +dst__openssl_keypair_destroy(dst_key_t *key) { + if (key->keydata.pkeypair.priv != key->keydata.pkeypair.pub) { + EVP_PKEY_free(key->keydata.pkeypair.priv); + } + EVP_PKEY_free(key->keydata.pkeypair.pub); + key->keydata.pkeypair.pub = NULL; + key->keydata.pkeypair.priv = NULL; +} + /*! \file */ diff --git a/lib/dns/opensslecdsa_link.c b/lib/dns/opensslecdsa_link.c index 0482e72d11..04bd67deac 100644 --- a/lib/dns/opensslecdsa_link.c +++ b/lib/dns/opensslecdsa_link.c @@ -766,23 +766,6 @@ opensslecdsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { return (ret); } -static bool -opensslecdsa_isprivate(const dst_key_t *key) { - REQUIRE(opensslecdsa_valid_key_alg(key->key_alg)); - - return (key->keydata.pkeypair.priv != NULL); -} - -static void -opensslecdsa_destroy(dst_key_t *key) { - if (key->keydata.pkeypair.priv != key->keydata.pkeypair.pub) { - EVP_PKEY_free(key->keydata.pkeypair.priv); - } - EVP_PKEY_free(key->keydata.pkeypair.pub); - key->keydata.pkeypair.pub = NULL; - key->keydata.pkeypair.priv = NULL; -} - static isc_result_t opensslecdsa_todns(const dst_key_t *key, isc_buffer_t *data) { isc_result_t ret; @@ -1039,11 +1022,11 @@ static dst_func_t opensslecdsa_functions = { opensslecdsa_verify, NULL, /*%< verify2 */ NULL, /*%< computesecret */ - dst__openssl_compare_keypair, + dst__openssl_keypair_compare, NULL, /*%< paramcompare */ opensslecdsa_generate, - opensslecdsa_isprivate, - opensslecdsa_destroy, + dst__openssl_keypair_isprivate, + dst__openssl_keypair_destroy, opensslecdsa_todns, opensslecdsa_fromdns, opensslecdsa_tofile, diff --git a/lib/dns/opensslrsa_link.c b/lib/dns/opensslrsa_link.c index 0a254cb738..f5017b65f7 100644 --- a/lib/dns/opensslrsa_link.c +++ b/lib/dns/opensslrsa_link.c @@ -677,23 +677,6 @@ err: return (ret); } -static bool -opensslrsa_isprivate(const dst_key_t *key) { - REQUIRE(opensslrsa_valid_key_alg(key->key_alg)); - - return (key->keydata.pkeypair.priv != NULL); -} - -static void -opensslrsa_destroy(dst_key_t *key) { - if (key->keydata.pkeypair.pub != key->keydata.pkeypair.priv) { - EVP_PKEY_free(key->keydata.pkeypair.priv); - } - EVP_PKEY_free(key->keydata.pkeypair.pub); - key->keydata.pkeypair.pub = NULL; - key->keydata.pkeypair.priv = NULL; -} - static isc_result_t opensslrsa_todns(const dst_key_t *key, isc_buffer_t *data) { isc_region_t r; @@ -1103,11 +1086,11 @@ static dst_func_t opensslrsa_functions = { opensslrsa_verify, opensslrsa_verify2, NULL, /*%< computesecret */ - dst__openssl_compare_keypair, + dst__openssl_keypair_compare, NULL, /*%< paramcompare */ opensslrsa_generate, - opensslrsa_isprivate, - opensslrsa_destroy, + dst__openssl_keypair_isprivate, + dst__openssl_keypair_destroy, opensslrsa_todns, opensslrsa_fromdns, opensslrsa_tofile, From c0b1ac97bfeff955263551e48d2798d1623905da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Thu, 26 Jan 2023 16:21:00 +0200 Subject: [PATCH 2/4] Remove redundant NULL checks in OpenSSL RSA glue The OpenSSL free functions are no-op when called with NULL argument, thus remove the extra checks around *_free() calls in the OpenSSL RSA glue. --- lib/dns/opensslrsa_link.c | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/lib/dns/opensslrsa_link.c b/lib/dns/opensslrsa_link.c index f5017b65f7..cb815b73cc 100644 --- a/lib/dns/opensslrsa_link.c +++ b/lib/dns/opensslrsa_link.c @@ -378,15 +378,9 @@ opensslrsa_generate_pkey(unsigned int key_size, BIGNUM *e, ret = ISC_R_SUCCESS; err: - if (pkey != NULL) { - EVP_PKEY_free(pkey); - } - if (rsa != NULL) { - RSA_free(rsa); - } - if (cb != NULL) { - BN_GENCB_free(cb); - } + EVP_PKEY_free(pkey); + RSA_free(rsa); + BN_GENCB_free(cb); return (ret); } @@ -511,9 +505,7 @@ opensslrsa_generate_pkey(unsigned int key_size, BIGNUM *e, } ret = ISC_R_SUCCESS; err: - if (ctx != NULL) { - EVP_PKEY_CTX_free(ctx); - } + EVP_PKEY_CTX_free(ctx); return (ret); } @@ -668,12 +660,8 @@ opensslrsa_generate(dst_key_t *key, int exp, void (*callback)(int)) { ret = ISC_R_SUCCESS; err: - if (pkey != NULL) { - EVP_PKEY_free(pkey); - } - if (e != NULL) { - BN_free(e); - } + EVP_PKEY_free(pkey); + BN_free(e); return (ret); } From 28da7670b63bb4117c722e4a8a9973522e583f42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Sat, 28 Jan 2023 12:53:14 +0200 Subject: [PATCH 3/4] OpenSSL EDDSA introduce and use openssleddsa_alg_info() Move the common code into a helper function that returns the EDDSA parameters (pkey type, nid, keysize, sigsize). --- lib/dns/openssleddsa_link.c | 173 ++++++++++++++---------------------- 1 file changed, 66 insertions(+), 107 deletions(-) diff --git a/lib/dns/openssleddsa_link.c b/lib/dns/openssleddsa_link.c index f89672b26e..331292f015 100644 --- a/lib/dns/openssleddsa_link.c +++ b/lib/dns/openssleddsa_link.c @@ -56,28 +56,44 @@ #endif /* ifndef NID_ED448 */ #endif /* HAVE_OPENSSL_ED448 */ -static isc_result_t -raw_key_to_ossl(unsigned int key_alg, int private, const unsigned char *key, - size_t *key_len, EVP_PKEY **pkey) { - isc_result_t ret; - int pkey_type = EVP_PKEY_NONE; - size_t len = 0; +typedef struct eddsa_alginfo { + int pkey_type, nid; + unsigned int key_size, sig_size; +} eddsa_alginfo_t; +static const eddsa_alginfo_t * +openssleddsa_alg_info(unsigned int key_alg) { #if HAVE_OPENSSL_ED25519 if (key_alg == DST_ALG_ED25519) { - pkey_type = EVP_PKEY_ED25519; - len = DNS_KEY_ED25519SIZE; + static const eddsa_alginfo_t ed25519_alginfo = { + .pkey_type = EVP_PKEY_ED25519, + .nid = NID_ED25519, + .key_size = DNS_KEY_ED25519SIZE, + .sig_size = DNS_SIG_ED25519SIZE, + }; + return &ed25519_alginfo; } #endif /* HAVE_OPENSSL_ED25519 */ #if HAVE_OPENSSL_ED448 if (key_alg == DST_ALG_ED448) { - pkey_type = EVP_PKEY_ED448; - len = DNS_KEY_ED448SIZE; + static const eddsa_alginfo_t ed448_alginfo = { + .pkey_type = EVP_PKEY_ED448, + .nid = NID_ED448, + .key_size = DNS_KEY_ED448SIZE, + .sig_size = DNS_SIG_ED448SIZE, + }; + return &ed448_alginfo; } #endif /* HAVE_OPENSSL_ED448 */ - if (pkey_type == EVP_PKEY_NONE) { - return (ISC_R_NOTIMPLEMENTED); - } + return NULL; +} + +static isc_result_t +raw_key_to_ossl(const eddsa_alginfo_t *alginfo, int private, + const unsigned char *key, size_t *key_len, EVP_PKEY **pkey) { + isc_result_t ret; + int pkey_type = alginfo->pkey_type; + size_t len = alginfo->key_size; ret = (private ? DST_R_INVALIDPRIVATEKEY : DST_R_INVALIDPUBLICKEY); if (*key_len < len) { @@ -104,10 +120,11 @@ openssleddsa_fromlabel(dst_key_t *key, const char *engine, const char *label, static isc_result_t openssleddsa_createctx(dst_key_t *key, dst_context_t *dctx) { isc_buffer_t *buf = NULL; + const eddsa_alginfo_t *alginfo = + openssleddsa_alg_info(dctx->key->key_alg); UNUSED(key); - REQUIRE(dctx->key->key_alg == DST_ALG_ED25519 || - dctx->key->key_alg == DST_ALG_ED448); + REQUIRE(alginfo != NULL); isc_buffer_allocate(dctx->mctx, &buf, 64); dctx->ctxdata.generic = buf; @@ -118,9 +135,10 @@ openssleddsa_createctx(dst_key_t *key, dst_context_t *dctx) { static void openssleddsa_destroyctx(dst_context_t *dctx) { isc_buffer_t *buf = (isc_buffer_t *)dctx->ctxdata.generic; + const eddsa_alginfo_t *alginfo = + openssleddsa_alg_info(dctx->key->key_alg); - REQUIRE(dctx->key->key_alg == DST_ALG_ED25519 || - dctx->key->key_alg == DST_ALG_ED448); + REQUIRE(alginfo != NULL); if (buf != NULL) { isc_buffer_free(&buf); } @@ -134,9 +152,10 @@ openssleddsa_adddata(dst_context_t *dctx, const isc_region_t *data) { isc_region_t r; unsigned int length; isc_result_t result; + const eddsa_alginfo_t *alginfo = + openssleddsa_alg_info(dctx->key->key_alg); - REQUIRE(dctx->key->key_alg == DST_ALG_ED25519 || - dctx->key->key_alg == DST_ALG_ED448); + REQUIRE(alginfo != NULL); result = isc_buffer_copyregion(buf, data); if (result == ISC_R_SUCCESS) { @@ -163,21 +182,16 @@ openssleddsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { EVP_PKEY *pkey = key->keydata.pkey; EVP_MD_CTX *ctx = EVP_MD_CTX_new(); isc_buffer_t *buf = (isc_buffer_t *)dctx->ctxdata.generic; + const eddsa_alginfo_t *alginfo = openssleddsa_alg_info(key->key_alg); size_t siglen; - REQUIRE(key->key_alg == DST_ALG_ED25519 || - key->key_alg == DST_ALG_ED448); + REQUIRE(alginfo != NULL); if (ctx == NULL) { return (ISC_R_NOMEMORY); } - if (key->key_alg == DST_ALG_ED25519) { - siglen = DNS_SIG_ED25519SIZE; - } else { - siglen = DNS_SIG_ED448SIZE; - } - + siglen = alginfo->sig_size; isc_buffer_availableregion(sig, &sigreg); if (sigreg.length < (unsigned int)siglen) { DST_RET(ISC_R_NOSPACE); @@ -215,30 +229,15 @@ openssleddsa_verify(dst_context_t *dctx, const isc_region_t *sig) { EVP_PKEY *pkey = key->keydata.pkey; EVP_MD_CTX *ctx = EVP_MD_CTX_new(); isc_buffer_t *buf = (isc_buffer_t *)dctx->ctxdata.generic; - unsigned int siglen = 0; + const eddsa_alginfo_t *alginfo = openssleddsa_alg_info(key->key_alg); - REQUIRE(key->key_alg == DST_ALG_ED25519 || - key->key_alg == DST_ALG_ED448); + REQUIRE(alginfo != NULL); if (ctx == NULL) { return (ISC_R_NOMEMORY); } -#if HAVE_OPENSSL_ED25519 - if (key->key_alg == DST_ALG_ED25519) { - siglen = DNS_SIG_ED25519SIZE; - } -#endif /* if HAVE_OPENSSL_ED25519 */ -#if HAVE_OPENSSL_ED448 - if (key->key_alg == DST_ALG_ED448) { - siglen = DNS_SIG_ED448SIZE; - } -#endif /* if HAVE_OPENSSL_ED448 */ - if (siglen == 0) { - DST_RET(ISC_R_NOTIMPLEMENTED); - } - - if (sig->length != siglen) { + if (sig->length != alginfo->sig_size) { DST_RET(DST_R_VERIFYFAILURE); } @@ -249,7 +248,7 @@ openssleddsa_verify(dst_context_t *dctx, const isc_region_t *sig) { dctx->category, "EVP_DigestVerifyInit", ISC_R_FAILURE)); } - status = EVP_DigestVerify(ctx, sig->base, siglen, tbsreg.base, + status = EVP_DigestVerify(ctx, sig->base, sig->length, tbsreg.base, tbsreg.length); switch (status) { @@ -297,30 +296,14 @@ openssleddsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { isc_result_t ret; EVP_PKEY *pkey = NULL; EVP_PKEY_CTX *ctx = NULL; - int nid = 0, status; + const eddsa_alginfo_t *alginfo = openssleddsa_alg_info(key->key_alg); + int status; - REQUIRE(key->key_alg == DST_ALG_ED25519 || - key->key_alg == DST_ALG_ED448); + REQUIRE(alginfo != NULL); UNUSED(unused); UNUSED(callback); -#if HAVE_OPENSSL_ED25519 - if (key->key_alg == DST_ALG_ED25519) { - nid = NID_ED25519; - key->key_size = DNS_KEY_ED25519SIZE * 8; - } -#endif /* if HAVE_OPENSSL_ED25519 */ -#if HAVE_OPENSSL_ED448 - if (key->key_alg == DST_ALG_ED448) { - nid = NID_ED448; - key->key_size = DNS_KEY_ED448SIZE * 8; - } -#endif /* if HAVE_OPENSSL_ED448 */ - if (nid == 0) { - return (ISC_R_NOTIMPLEMENTED); - } - - ctx = EVP_PKEY_CTX_new_id(nid, NULL); + ctx = EVP_PKEY_CTX_new_id(alginfo->nid, NULL); if (ctx == NULL) { return (dst__openssl_toresult2("EVP_PKEY_CTX_new_id", DST_R_OPENSSLFAILURE)); @@ -338,6 +321,7 @@ openssleddsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { DST_R_OPENSSLFAILURE)); } + key->key_size = alginfo->key_size * 8; key->keydata.pkey = pkey; ret = ISC_R_SUCCESS; @@ -376,20 +360,15 @@ openssleddsa_destroy(dst_key_t *key) { static isc_result_t openssleddsa_todns(const dst_key_t *key, isc_buffer_t *data) { + const eddsa_alginfo_t *alginfo = openssleddsa_alg_info(key->key_alg); EVP_PKEY *pkey = key->keydata.pkey; isc_region_t r; size_t len; REQUIRE(pkey != NULL); - REQUIRE(key->key_alg == DST_ALG_ED25519 || - key->key_alg == DST_ALG_ED448); - - if (key->key_alg == DST_ALG_ED25519) { - len = DNS_KEY_ED25519SIZE; - } else { - len = DNS_KEY_ED448SIZE; - } + REQUIRE(alginfo != NULL); + len = alginfo->key_size; isc_buffer_availableregion(data, &r); if (r.length < len) { return (ISC_R_NOSPACE); @@ -405,13 +384,13 @@ openssleddsa_todns(const dst_key_t *key, isc_buffer_t *data) { static isc_result_t openssleddsa_fromdns(dst_key_t *key, isc_buffer_t *data) { + const eddsa_alginfo_t *alginfo = openssleddsa_alg_info(key->key_alg); isc_result_t ret; isc_region_t r; size_t len; EVP_PKEY *pkey; - REQUIRE(key->key_alg == DST_ALG_ED25519 || - key->key_alg == DST_ALG_ED448); + REQUIRE(alginfo != NULL); isc_buffer_remainingregion(data, &r); if (r.length == 0) { @@ -419,7 +398,7 @@ openssleddsa_fromdns(dst_key_t *key, isc_buffer_t *data) { } len = r.length; - ret = raw_key_to_ossl(key->key_alg, 0, r.base, &len, &pkey); + ret = raw_key_to_ossl(alginfo, 0, r.base, &len, &pkey); if (ret != ISC_R_SUCCESS) { return ret; } @@ -432,14 +411,14 @@ openssleddsa_fromdns(dst_key_t *key, isc_buffer_t *data) { static isc_result_t openssleddsa_tofile(const dst_key_t *key, const char *directory) { + const eddsa_alginfo_t *alginfo = openssleddsa_alg_info(key->key_alg); isc_result_t ret; dst_private_t priv; unsigned char *buf = NULL; size_t len; int i; - REQUIRE(key->key_alg == DST_ALG_ED25519 || - key->key_alg == DST_ALG_ED448); + REQUIRE(alginfo != NULL); if (key->keydata.pkey == NULL) { return (DST_R_NULLKEY); @@ -453,11 +432,7 @@ openssleddsa_tofile(const dst_key_t *key, const char *directory) { i = 0; if (openssleddsa_isprivate(key)) { - if (key->key_alg == DST_ALG_ED25519) { - len = DNS_KEY_ED25519SIZE; - } else { - len = DNS_KEY_ED448SIZE; - } + len = alginfo->key_size; buf = isc_mem_get(key->mctx, len); if (EVP_PKEY_get_raw_private_key(key->keydata.pkey, buf, &len) != 1) @@ -507,6 +482,7 @@ eddsa_check(EVP_PKEY *pkey, EVP_PKEY *pubpkey) { static isc_result_t openssleddsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { + const eddsa_alginfo_t *alginfo = openssleddsa_alg_info(key->key_alg); dst_private_t priv; isc_result_t ret; int i, privkey_index = -1; @@ -515,8 +491,7 @@ openssleddsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { size_t len; isc_mem_t *mctx = key->mctx; - REQUIRE(key->key_alg == DST_ALG_ED25519 || - key->key_alg == DST_ALG_ED448); + REQUIRE(alginfo != NULL); /* read private key file */ ret = dst__privstruct_parse(key, DST_ALG_ED25519, lexer, mctx, &priv); @@ -574,8 +549,8 @@ openssleddsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { } len = priv.elements[privkey_index].length; - ret = raw_key_to_ossl(key->key_alg, 1, - priv.elements[privkey_index].data, &len, &pkey); + ret = raw_key_to_ossl(alginfo, 1, priv.elements[privkey_index].data, + &len, &pkey); if (ret != ISC_R_SUCCESS) { goto err; } @@ -597,29 +572,13 @@ static isc_result_t openssleddsa_fromlabel(dst_key_t *key, const char *engine, const char *label, const char *pin) { #if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000 + const eddsa_alginfo_t *alginfo = openssleddsa_alg_info(key->key_alg); isc_result_t ret; ENGINE *e; EVP_PKEY *pkey = NULL, *pubpkey = NULL; - int baseid = EVP_PKEY_NONE; UNUSED(pin); - - REQUIRE(key->key_alg == DST_ALG_ED25519 || - key->key_alg == DST_ALG_ED448); - -#if HAVE_OPENSSL_ED25519 - if (key->key_alg == DST_ALG_ED25519) { - baseid = EVP_PKEY_ED25519; - } -#endif /* if HAVE_OPENSSL_ED25519 */ -#if HAVE_OPENSSL_ED448 - if (key->key_alg == DST_ALG_ED448) { - baseid = EVP_PKEY_ED448; - } -#endif /* if HAVE_OPENSSL_ED448 */ - if (baseid == EVP_PKEY_NONE) { - return (ISC_R_NOTIMPLEMENTED); - } + REQUIRE(alginfo != NULL); if (engine == NULL) { return (DST_R_NOENGINE); @@ -633,7 +592,7 @@ openssleddsa_fromlabel(dst_key_t *key, const char *engine, const char *label, return (dst__openssl_toresult2("ENGINE_load_private_key", ISC_R_NOTFOUND)); } - if (EVP_PKEY_base_id(pkey) != baseid) { + if (EVP_PKEY_base_id(pkey) != alginfo->pkey_type) { DST_RET(DST_R_INVALIDPRIVATEKEY); } From 20b4d7146b2af8303189782cb6d1b3905cc619e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Sat, 28 Jan 2023 21:14:39 +0200 Subject: [PATCH 4/4] Convert OpenSSL EDDSA glue to pkeypair Finish the OpenSSL EDSSA glue refactoring to use pkeypair - this is the same change that has been already applied to RSA and ECDSA glues. --- lib/dns/dst_internal.h | 1 - lib/dns/openssleddsa_link.c | 170 +++++++++--------------------------- 2 files changed, 43 insertions(+), 128 deletions(-) diff --git a/lib/dns/dst_internal.h b/lib/dns/dst_internal.h index ca2b6376c9..aa8fda3d7e 100644 --- a/lib/dns/dst_internal.h +++ b/lib/dns/dst_internal.h @@ -97,7 +97,6 @@ struct dst_key { void *generic; dns_gss_ctx_id_t gssctx; dst_hmac_key_t *hmac_key; - EVP_PKEY *pkey; struct { EVP_PKEY *pub; EVP_PKEY *priv; diff --git a/lib/dns/openssleddsa_link.c b/lib/dns/openssleddsa_link.c index 331292f015..a2c6f6f4a6 100644 --- a/lib/dns/openssleddsa_link.c +++ b/lib/dns/openssleddsa_link.c @@ -21,9 +21,6 @@ #include #include #include -#if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000 -#include -#endif /* if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000 */ #include #include @@ -179,7 +176,7 @@ openssleddsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { dst_key_t *key = dctx->key; isc_region_t tbsreg; isc_region_t sigreg; - EVP_PKEY *pkey = key->keydata.pkey; + EVP_PKEY *pkey = key->keydata.pkeypair.priv; EVP_MD_CTX *ctx = EVP_MD_CTX_new(); isc_buffer_t *buf = (isc_buffer_t *)dctx->ctxdata.generic; const eddsa_alginfo_t *alginfo = openssleddsa_alg_info(key->key_alg); @@ -226,7 +223,7 @@ openssleddsa_verify(dst_context_t *dctx, const isc_region_t *sig) { dst_key_t *key = dctx->key; int status; isc_region_t tbsreg; - EVP_PKEY *pkey = key->keydata.pkey; + EVP_PKEY *pkey = key->keydata.pkeypair.pub; EVP_MD_CTX *ctx = EVP_MD_CTX_new(); isc_buffer_t *buf = (isc_buffer_t *)dctx->ctxdata.generic; const eddsa_alginfo_t *alginfo = openssleddsa_alg_info(key->key_alg); @@ -272,25 +269,6 @@ err: return (ret); } -static bool -openssleddsa_compare(const dst_key_t *key1, const dst_key_t *key2) { - int status; - EVP_PKEY *pkey1 = key1->keydata.pkey; - EVP_PKEY *pkey2 = key2->keydata.pkey; - - if (pkey1 == NULL && pkey2 == NULL) { - return (true); - } else if (pkey1 == NULL || pkey2 == NULL) { - return (false); - } - - status = EVP_PKEY_eq(pkey1, pkey2); - if (status == 1) { - return (true); - } - return (false); -} - static isc_result_t openssleddsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { isc_result_t ret; @@ -322,7 +300,8 @@ openssleddsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { } key->key_size = alginfo->key_size * 8; - key->keydata.pkey = pkey; + key->keydata.pkeypair.priv = pkey; + key->keydata.pkeypair.pub = pkey; ret = ISC_R_SUCCESS; err: @@ -330,38 +309,10 @@ err: return (ret); } -static bool -openssleddsa_isprivate(const dst_key_t *key) { - EVP_PKEY *pkey = key->keydata.pkey; - size_t len; - - if (pkey == NULL) { - return (false); - } - - if (EVP_PKEY_get_raw_private_key(pkey, NULL, &len) == 1 && len > 0) { - return (true); - } - /* can check if first error is EC_R_INVALID_PRIVATE_KEY */ - while (ERR_get_error() != 0) { - /**/ - } - - return (false); -} - -static void -openssleddsa_destroy(dst_key_t *key) { - EVP_PKEY *pkey = key->keydata.pkey; - - EVP_PKEY_free(pkey); - key->keydata.pkey = NULL; -} - static isc_result_t openssleddsa_todns(const dst_key_t *key, isc_buffer_t *data) { const eddsa_alginfo_t *alginfo = openssleddsa_alg_info(key->key_alg); - EVP_PKEY *pkey = key->keydata.pkey; + EVP_PKEY *pkey = key->keydata.pkeypair.pub; isc_region_t r; size_t len; @@ -404,7 +355,7 @@ openssleddsa_fromdns(dst_key_t *key, isc_buffer_t *data) { } isc_buffer_forward(data, len); - key->keydata.pkey = pkey; + key->keydata.pkeypair.pub = pkey; key->key_size = len * 8; return (ISC_R_SUCCESS); } @@ -420,7 +371,7 @@ openssleddsa_tofile(const dst_key_t *key, const char *directory) { REQUIRE(alginfo != NULL); - if (key->keydata.pkey == NULL) { + if (key->keydata.pkeypair.pub == NULL) { return (DST_R_NULLKEY); } @@ -431,11 +382,11 @@ openssleddsa_tofile(const dst_key_t *key, const char *directory) { i = 0; - if (openssleddsa_isprivate(key)) { + if (dst__openssl_keypair_isprivate(key)) { len = alginfo->key_size; buf = isc_mem_get(key->mctx, len); - if (EVP_PKEY_get_raw_private_key(key->keydata.pkey, buf, - &len) != 1) + if (EVP_PKEY_get_raw_private_key(key->keydata.pkeypair.priv, + buf, &len) != 1) { DST_RET(dst__openssl_toresult(ISC_R_FAILURE)); } @@ -469,17 +420,6 @@ err: return (ret); } -static isc_result_t -eddsa_check(EVP_PKEY *pkey, EVP_PKEY *pubpkey) { - if (pubpkey == NULL) { - return (ISC_R_SUCCESS); - } - if (EVP_PKEY_eq(pkey, pubpkey) == 1) { - return (ISC_R_SUCCESS); - } - return (ISC_R_FAILURE); -} - static isc_result_t openssleddsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { const eddsa_alginfo_t *alginfo = openssleddsa_alg_info(key->key_alg); @@ -487,7 +427,7 @@ openssleddsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { isc_result_t ret; int i, privkey_index = -1; const char *engine = NULL, *label = NULL; - EVP_PKEY *pkey = NULL, *pubpkey = NULL; + EVP_PKEY *pkey = NULL; size_t len; isc_mem_t *mctx = key->mctx; @@ -506,15 +446,11 @@ openssleddsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { if (pub == NULL) { DST_RET(DST_R_INVALIDPRIVATEKEY); } - key->keydata.pkey = pub->keydata.pkey; - pub->keydata.pkey = NULL; - dst__privstruct_free(&priv, mctx); - isc_safe_memwipe(&priv, sizeof(priv)); - return (ISC_R_SUCCESS); - } - - if (pub != NULL) { - pubpkey = pub->keydata.pkey; + key->keydata.pkeypair.priv = pub->keydata.pkeypair.priv; + key->keydata.pkeypair.pub = pub->keydata.pkeypair.pub; + pub->keydata.pkeypair.priv = NULL; + pub->keydata.pkeypair.pub = NULL; + DST_RET(ISC_R_SUCCESS); } for (i = 0; i < priv.nelements; i++) { @@ -538,7 +474,10 @@ openssleddsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { if (ret != ISC_R_SUCCESS) { goto err; } - if (eddsa_check(key->keydata.pkey, pubpkey) != ISC_R_SUCCESS) { + /* Check that the public component matches if given */ + if (pub != NULL && EVP_PKEY_eq(key->keydata.pkeypair.pub, + pub->keydata.pkeypair.pub) != 1) + { DST_RET(DST_R_INVALIDPRIVATEKEY); } DST_RET(ISC_R_SUCCESS); @@ -554,15 +493,19 @@ openssleddsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { if (ret != ISC_R_SUCCESS) { goto err; } - if (eddsa_check(pkey, pubpkey) != ISC_R_SUCCESS) { - EVP_PKEY_free(pkey); + /* Check that the public component matches if given */ + if (pub != NULL && EVP_PKEY_eq(pkey, pub->keydata.pkeypair.pub) != 1) { DST_RET(DST_R_INVALIDPRIVATEKEY); } - key->keydata.pkey = pkey; + + key->keydata.pkeypair.priv = pkey; + key->keydata.pkeypair.pub = pkey; key->key_size = len * 8; + pkey = NULL; ret = ISC_R_SUCCESS; err: + EVP_PKEY_free(pkey); dst__privstruct_free(&priv, mctx); isc_safe_memwipe(&priv, sizeof(priv)); return (ret); @@ -571,58 +514,31 @@ err: static isc_result_t openssleddsa_fromlabel(dst_key_t *key, const char *engine, const char *label, const char *pin) { -#if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000 const eddsa_alginfo_t *alginfo = openssleddsa_alg_info(key->key_alg); + EVP_PKEY *privpkey = NULL, *pubpkey = NULL; isc_result_t ret; - ENGINE *e; - EVP_PKEY *pkey = NULL, *pubpkey = NULL; - UNUSED(pin); REQUIRE(alginfo != NULL); + UNUSED(pin); - if (engine == NULL) { - return (DST_R_NOENGINE); - } - e = dst__openssl_getengine(engine); - if (e == NULL) { - return (DST_R_NOENGINE); - } - pkey = ENGINE_load_private_key(e, label, NULL, NULL); - if (pkey == NULL) { - return (dst__openssl_toresult2("ENGINE_load_private_key", - ISC_R_NOTFOUND)); - } - if (EVP_PKEY_base_id(pkey) != alginfo->pkey_type) { - DST_RET(DST_R_INVALIDPRIVATEKEY); - } - - pubpkey = ENGINE_load_public_key(e, label, NULL, NULL); - if (eddsa_check(pkey, pubpkey) != ISC_R_SUCCESS) { - DST_RET(DST_R_INVALIDPRIVATEKEY); + ret = dst__openssl_fromlabel(alginfo->pkey_type, engine, label, pin, + &pubpkey, &privpkey); + if (ret != ISC_R_SUCCESS) { + goto err; } key->engine = isc_mem_strdup(key->mctx, engine); key->label = isc_mem_strdup(key->mctx, label); - key->key_size = EVP_PKEY_bits(pkey); - key->keydata.pkey = pkey; - pkey = NULL; - ret = ISC_R_SUCCESS; + key->key_size = EVP_PKEY_bits(privpkey); + key->keydata.pkeypair.priv = privpkey; + key->keydata.pkeypair.pub = pubpkey; + privpkey = NULL; + pubpkey = NULL; err: - if (pubpkey != NULL) { - EVP_PKEY_free(pubpkey); - } - if (pkey != NULL) { - EVP_PKEY_free(pkey); - } + EVP_PKEY_free(privpkey); + EVP_PKEY_free(pubpkey); return (ret); -#else /* if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000 */ - UNUSED(key); - UNUSED(engine); - UNUSED(label); - UNUSED(pin); - return (DST_R_NOENGINE); -#endif /* if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000 */ } static dst_func_t openssleddsa_functions = { @@ -634,11 +550,11 @@ static dst_func_t openssleddsa_functions = { openssleddsa_verify, NULL, /*%< verify2 */ NULL, /*%< computesecret */ - openssleddsa_compare, + dst__openssl_keypair_compare, NULL, /*%< paramcompare */ openssleddsa_generate, - openssleddsa_isprivate, - openssleddsa_destroy, + dst__openssl_keypair_isprivate, + dst__openssl_keypair_destroy, openssleddsa_todns, openssleddsa_fromdns, openssleddsa_tofile,