diff --git a/CHANGES b/CHANGES index 369b314ca3..6e33aa5a86 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +3723. [cleanup] Imported keys are now handled the same way + regardless of DNSSEC algorithm. [RT #35215] + 3722. [bug] Using geoip ACLs in a blackhole statement could cause a segfault. [RT #35272] diff --git a/lib/dns/dst_result.c b/lib/dns/dst_result.c index e9f7b06ab2..078ea38391 100644 --- a/lib/dns/dst_result.c +++ b/lib/dns/dst_result.c @@ -50,7 +50,8 @@ static const char *text[DST_R_NRESULTS] = { "failure computing a shared secret", /*%< 18 */ "no randomness available", /*%< 19 */ "bad key type", /*%< 20 */ - "no engine" /*%< 21 */ + "no engine", /*%< 21 */ + "illegal operation for an external key" /*%< 22 */ }; #define DST_RESULT_RESULTSET 2 diff --git a/lib/dns/hmac_link.c b/lib/dns/hmac_link.c index d1eb742611..01876d336a 100644 --- a/lib/dns/hmac_link.c +++ b/lib/dns/hmac_link.c @@ -250,6 +250,9 @@ hmacmd5_tofile(const dst_key_t *key, const char *directory) { if (key->keydata.hmacmd5 == NULL) return (DST_R_NULLKEY); + if (key->external) + return (DST_R_EXTERNALKEY); + hkey = key->keydata.hmacmd5; priv.elements[cnt].tag = TAG_HMACMD5_KEY; @@ -281,6 +284,9 @@ hmacmd5_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { if (result != ISC_R_SUCCESS) return (result); + if (key->external) + result = DST_R_EXTERNALKEY; + key->key_bits = 0; for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) { switch (priv.elements[i].tag) { @@ -527,6 +533,9 @@ hmacsha1_tofile(const dst_key_t *key, const char *directory) { if (key->keydata.hmacsha1 == NULL) return (DST_R_NULLKEY); + if (key->external) + return (DST_R_EXTERNALKEY); + hkey = key->keydata.hmacsha1; priv.elements[cnt].tag = TAG_HMACSHA1_KEY; @@ -558,8 +567,11 @@ hmacsha1_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { if (result != ISC_R_SUCCESS) return (result); + if (key->external) + result = DST_R_EXTERNALKEY; + key->key_bits = 0; - for (i = 0; i < priv.nelements; i++) { + for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) { switch (priv.elements[i].tag) { case TAG_HMACSHA1_KEY: isc_buffer_init(&b, priv.elements[i].data, @@ -806,6 +818,9 @@ hmacsha224_tofile(const dst_key_t *key, const char *directory) { if (key->keydata.hmacsha224 == NULL) return (DST_R_NULLKEY); + if (key->external) + return (DST_R_EXTERNALKEY); + hkey = key->keydata.hmacsha224; priv.elements[cnt].tag = TAG_HMACSHA224_KEY; @@ -837,8 +852,11 @@ hmacsha224_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { if (result != ISC_R_SUCCESS) return (result); + if (key->external) + result = DST_R_EXTERNALKEY; + key->key_bits = 0; - for (i = 0; i < priv.nelements; i++) { + for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) { switch (priv.elements[i].tag) { case TAG_HMACSHA224_KEY: isc_buffer_init(&b, priv.elements[i].data, @@ -1085,6 +1103,9 @@ hmacsha256_tofile(const dst_key_t *key, const char *directory) { if (key->keydata.hmacsha256 == NULL) return (DST_R_NULLKEY); + if (key->external) + return (DST_R_EXTERNALKEY); + hkey = key->keydata.hmacsha256; priv.elements[cnt].tag = TAG_HMACSHA256_KEY; @@ -1116,8 +1137,11 @@ hmacsha256_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { if (result != ISC_R_SUCCESS) return (result); + if (key->external) + result = DST_R_EXTERNALKEY; + key->key_bits = 0; - for (i = 0; i < priv.nelements; i++) { + for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) { switch (priv.elements[i].tag) { case TAG_HMACSHA256_KEY: isc_buffer_init(&b, priv.elements[i].data, @@ -1364,6 +1388,9 @@ hmacsha384_tofile(const dst_key_t *key, const char *directory) { if (key->keydata.hmacsha384 == NULL) return (DST_R_NULLKEY); + if (key->external) + return (DST_R_EXTERNALKEY); + hkey = key->keydata.hmacsha384; priv.elements[cnt].tag = TAG_HMACSHA384_KEY; @@ -1395,8 +1422,11 @@ hmacsha384_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { if (result != ISC_R_SUCCESS) return (result); + if (key->external) + result = DST_R_EXTERNALKEY; + key->key_bits = 0; - for (i = 0; i < priv.nelements; i++) { + for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) { switch (priv.elements[i].tag) { case TAG_HMACSHA384_KEY: isc_buffer_init(&b, priv.elements[i].data, @@ -1643,6 +1673,9 @@ hmacsha512_tofile(const dst_key_t *key, const char *directory) { if (key->keydata.hmacsha512 == NULL) return (DST_R_NULLKEY); + if (key->external) + return (DST_R_EXTERNALKEY); + hkey = key->keydata.hmacsha512; priv.elements[cnt].tag = TAG_HMACSHA512_KEY; @@ -1674,8 +1707,11 @@ hmacsha512_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { if (result != ISC_R_SUCCESS) return (result); + if (key->external) + result = DST_R_EXTERNALKEY; + key->key_bits = 0; - for (i = 0; i < priv.nelements; i++) { + for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) { switch (priv.elements[i].tag) { case TAG_HMACSHA512_KEY: isc_buffer_init(&b, priv.elements[i].data, diff --git a/lib/dns/include/dst/result.h b/lib/dns/include/dst/result.h index 00640a1b1c..cf9428f6bd 100644 --- a/lib/dns/include/dst/result.h +++ b/lib/dns/include/dst/result.h @@ -57,8 +57,9 @@ #define DST_R_NORANDOMNESS (ISC_RESULTCLASS_DST + 19) #define DST_R_BADKEYTYPE (ISC_RESULTCLASS_DST + 20) #define DST_R_NOENGINE (ISC_RESULTCLASS_DST + 21) +#define DST_R_EXTERNALKEY (ISC_RESULTCLASS_DST + 22) -#define DST_R_NRESULTS 22 /* Number of results */ +#define DST_R_NRESULTS 23 /* Number of results */ ISC_LANG_BEGINDECLS diff --git a/lib/dns/openssldh_link.c b/lib/dns/openssldh_link.c index cf49143358..6c3f555f8d 100644 --- a/lib/dns/openssldh_link.c +++ b/lib/dns/openssldh_link.c @@ -463,6 +463,9 @@ openssldh_tofile(const dst_key_t *key, const char *directory) { if (key->keydata.dh == NULL) return (DST_R_NULLKEY); + if (key->external) + return (DST_R_EXTERNALKEY); + dh = key->keydata.dh; memset(bufs, 0, sizeof(bufs)); @@ -528,6 +531,9 @@ openssldh_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { if (ret != ISC_R_SUCCESS) return (ret); + if (key->external) + DST_RET(DST_R_EXTERNALKEY); + dh = DH_new(); if (dh == NULL) DST_RET(ISC_R_NOMEMORY); diff --git a/lib/dns/openssldsa_link.c b/lib/dns/openssldsa_link.c index 449c8ac1a7..67b6bbdae3 100644 --- a/lib/dns/openssldsa_link.c +++ b/lib/dns/openssldsa_link.c @@ -578,6 +578,19 @@ openssldsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { if (ret != ISC_R_SUCCESS) return (ret); + if (key->external) { + if (priv.nelements != 0) + DST_RET(DST_R_INVALIDPRIVATEKEY); + if (pub == NULL) + DST_RET(DST_R_INVALIDPRIVATEKEY); + key->keydata.pkey = pub->keydata.pkey; + pub->keydata.pkey = NULL; + key->key_size = pub->key_size; + dst__privstruct_free(&priv, mctx); + memset(&priv, 0, sizeof(priv)); + return (ISC_R_SUCCESS); + } + dsa = DSA_new(); if (dsa == NULL) DST_RET(ISC_R_NOMEMORY); @@ -610,22 +623,8 @@ openssldsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { } } dst__privstruct_free(&priv, mctx); - - if (key->external) { - if (pub == NULL) - DST_RET(DST_R_INVALIDPRIVATEKEY); - dsa->q = pub->keydata.dsa->q; - pub->keydata.dsa->q = NULL; - dsa->p = pub->keydata.dsa->p; - pub->keydata.dsa->p = NULL; - dsa->g = pub->keydata.dsa->g; - pub->keydata.dsa->g = NULL; - dsa->pub_key = pub->keydata.dsa->pub_key; - pub->keydata.dsa->pub_key = NULL; - } - + memset(&priv, 0, sizeof(priv)); key->key_size = BN_num_bits(dsa->p); - return (ISC_R_SUCCESS); err: diff --git a/lib/dns/opensslecdsa_link.c b/lib/dns/opensslecdsa_link.c index c35eb67f29..da2b68b6e8 100644 --- a/lib/dns/opensslecdsa_link.c +++ b/lib/dns/opensslecdsa_link.c @@ -519,9 +519,8 @@ static isc_result_t opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { dst_private_t priv; isc_result_t ret; - EVP_PKEY *pkey, *pubpkey; - EC_KEY *eckey = NULL, *pubeckey = NULL; - const EC_POINT *pubkey; + EVP_PKEY *pkey; + EC_KEY *eckey = NULL; BIGNUM *privkey = NULL; int group_nid; isc_mem_t *mctx = key->mctx; @@ -529,6 +528,23 @@ opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { REQUIRE(key->key_alg == DST_ALG_ECDSA256 || key->key_alg == DST_ALG_ECDSA384); + /* read private key file */ + ret = dst__privstruct_parse(key, DST_ALG_ECDSA256, lexer, mctx, &priv); + if (ret != ISC_R_SUCCESS) + goto err; + + if (key->external) { + if (priv.nelements != 0) + DST_RET(DST_R_INVALIDPRIVATEKEY); + if (pub == NULL) + DST_RET(DST_R_INVALIDPRIVATEKEY); + key->keydata.pkey = pub->keydata.pkey; + pub->keydata.pkey = NULL; + dst__privstruct_free(&priv, mctx); + memset(&priv, 0, sizeof(priv)); + return (ISC_R_SUCCESS); + } + if (key->key_alg == DST_ALG_ECDSA256) group_nid = NID_X9_62_prime256v1; else @@ -538,40 +554,14 @@ opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { if (eckey == NULL) return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); - /* read private key file */ - ret = dst__privstruct_parse(key, DST_ALG_ECDSA256, lexer, mctx, &priv); - if (ret != ISC_R_SUCCESS) - goto err; - - if (key->external) { - /* - * Copy the public key to this new key. - */ - if (pub == NULL) - DST_RET(DST_R_INVALIDPRIVATEKEY); - pubpkey = pub->keydata.pkey; - pubeckey = EVP_PKEY_get1_EC_KEY(pubpkey); - if (pubeckey == NULL) - DST_RET(DST_R_INVALIDPRIVATEKEY); - pubkey = EC_KEY_get0_public_key(pubeckey); - if (pubkey == NULL) - DST_RET(DST_R_INVALIDPRIVATEKEY); - if (EC_KEY_set_public_key(eckey, pubkey) != 1) - DST_RET(DST_R_INVALIDPRIVATEKEY); - if (EC_KEY_check_key(eckey) != 1) - DST_RET(DST_R_INVALIDPRIVATEKEY); - } else { - privkey = BN_bin2bn(priv.elements[0].data, - priv.elements[0].length, NULL); - if (privkey == NULL) - DST_RET(ISC_R_NOMEMORY); - if (!EC_KEY_set_private_key(eckey, privkey)) - DST_RET(ISC_R_NOMEMORY); - if (ecdsa_check(eckey, pub) != ISC_R_SUCCESS) - DST_RET(DST_R_INVALIDPRIVATEKEY); - dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); - } + privkey = BN_bin2bn(priv.elements[0].data, + priv.elements[0].length, NULL); + if (privkey == NULL) + DST_RET(ISC_R_NOMEMORY); + if (!EC_KEY_set_private_key(eckey, privkey)) + DST_RET(ISC_R_NOMEMORY); + if (ecdsa_check(eckey, pub) != ISC_R_SUCCESS) + DST_RET(DST_R_INVALIDPRIVATEKEY); pkey = EVP_PKEY_new(); if (pkey == NULL) @@ -588,8 +578,6 @@ opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { BN_clear_free(privkey); if (eckey != NULL) EC_KEY_free(eckey); - if (pubeckey != NULL) - EC_KEY_free(pubeckey); dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ret); diff --git a/lib/dns/opensslgost_link.c b/lib/dns/opensslgost_link.c index e896b0abff..b7c35dca4e 100644 --- a/lib/dns/opensslgost_link.c +++ b/lib/dns/opensslgost_link.c @@ -452,69 +452,70 @@ opensslgost_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { BIGNUM *privkey = NULL; const unsigned char *p; - UNUSED(pub); - /* read private key file */ ret = dst__privstruct_parse(key, DST_ALG_ECCGOST, lexer, mctx, &priv); if (ret != ISC_R_SUCCESS) return (ret); if (key->external) { - INSIST(priv.nelements == 0); + if (priv.nelements != 0) + DST_RET(DST_R_INVALIDPRIVATEKEY); if (pub == NULL) DST_RET(DST_R_INVALIDPRIVATEKEY); key->keydata.pkey = pub->keydata.pkey; pub->keydata.pkey = NULL; - } else { - INSIST((priv.elements[0].tag == TAG_GOST_PRIVASN1) || - (priv.elements[0].tag == TAG_GOST_PRIVRAW)); - - if (priv.elements[0].tag == TAG_GOST_PRIVASN1) { - p = priv.elements[0].data; - if (d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p, - (long) priv.elements[0].length) == NULL) - DST_RET(dst__openssl_toresult2( - "d2i_PrivateKey", - DST_R_INVALIDPRIVATEKEY)); - } else { - if ((pub != NULL) && (pub->keydata.pkey != NULL)) { - eckey = EVP_PKEY_get0(pub->keydata.pkey); - pubkey = EC_KEY_get0_public_key(eckey); - } - - privkey = BN_bin2bn(priv.elements[0].data, - priv.elements[0].length, NULL); - if (privkey == NULL) - DST_RET(ISC_R_NOMEMORY); - - /* can't create directly the whole key */ - p = gost_dummy_key; - if (d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p, - (long) sizeof(gost_dummy_key)) == NULL) - DST_RET(dst__openssl_toresult2( - "d2i_PrivateKey", - DST_R_INVALIDPRIVATEKEY)); - - eckey = EVP_PKEY_get0(pkey); - if (eckey == NULL) - return (dst__openssl_toresult( - DST_R_OPENSSLFAILURE)); - if (!EC_KEY_set_private_key(eckey, privkey)) - DST_RET(ISC_R_NOMEMORY); - - /* have to (re)set the public key */ -#ifdef notyet - (void) gost2001_compute_public(eckey); -#else - if ((pubkey != NULL) && - !EC_KEY_set_public_key(eckey, pubkey)) - DST_RET(ISC_R_NOMEMORY); -#endif - BN_clear_free(privkey); - privkey = NULL; - } - key->keydata.pkey = pkey; + key->key_size = pub->key_size; + dst__privstruct_free(&priv, mctx); + memset(&priv, 0, sizeof(priv)); + return (ISC_R_SUCCESS); } + + INSIST((priv.elements[0].tag == TAG_GOST_PRIVASN1) || + (priv.elements[0].tag == TAG_GOST_PRIVRAW)); + + if (priv.elements[0].tag == TAG_GOST_PRIVASN1) { + p = priv.elements[0].data; + if (d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p, + (long) priv.elements[0].length) == NULL) + DST_RET(dst__openssl_toresult2( + "d2i_PrivateKey", + DST_R_INVALIDPRIVATEKEY)); + } else { + if ((pub != NULL) && (pub->keydata.pkey != NULL)) { + eckey = EVP_PKEY_get0(pub->keydata.pkey); + pubkey = EC_KEY_get0_public_key(eckey); + } + + privkey = BN_bin2bn(priv.elements[0].data, + priv.elements[0].length, NULL); + if (privkey == NULL) + DST_RET(ISC_R_NOMEMORY); + + /* can't create directly the whole key */ + p = gost_dummy_key; + if (d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p, + (long) sizeof(gost_dummy_key)) == NULL) + DST_RET(dst__openssl_toresult2( + "d2i_PrivateKey", + DST_R_INVALIDPRIVATEKEY)); + + eckey = EVP_PKEY_get0(pkey); + if (eckey == NULL) + return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + if (!EC_KEY_set_private_key(eckey, privkey)) + DST_RET(ISC_R_NOMEMORY); + + /* have to (re)set the public key */ +#ifdef notyet + (void) gost2001_compute_public(eckey); +#else + if ((pubkey != NULL) && !EC_KEY_set_public_key(eckey, pubkey)) + DST_RET(ISC_R_NOMEMORY); +#endif + BN_clear_free(privkey); + privkey = NULL; + } + key->keydata.pkey = pkey; key->key_size = EVP_PKEY_bits(pkey); dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); diff --git a/lib/dns/opensslrsa_link.c b/lib/dns/opensslrsa_link.c index e3d9be00e0..667907a955 100644 --- a/lib/dns/opensslrsa_link.c +++ b/lib/dns/opensslrsa_link.c @@ -1195,6 +1195,24 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { EVP_PKEY *pkey = NULL; #endif + /* read private key file */ + ret = dst__privstruct_parse(key, DST_ALG_RSA, lexer, mctx, &priv); + if (ret != ISC_R_SUCCESS) + goto err; + + if (key->external) { + if (priv.nelements != 0) + DST_RET(DST_R_INVALIDPRIVATEKEY); + if (pub == NULL) + DST_RET(DST_R_INVALIDPRIVATEKEY); + key->keydata.pkey = pub->keydata.pkey; + pub->keydata.pkey = NULL; + key->key_size = pub->key_size; + dst__privstruct_free(&priv, mctx); + memset(&priv, 0, sizeof(priv)); + return (ISC_R_SUCCESS); + } + #if USE_EVP if (pub != NULL && pub->keydata.pkey != NULL) pubrsa = EVP_PKEY_get1_RSA(pub->keydata.pkey); @@ -1205,14 +1223,6 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { } #endif - /* read private key file */ - ret = dst__privstruct_parse(key, DST_ALG_RSA, lexer, mctx, &priv); - if (ret != ISC_R_SUCCESS) - goto err; - - if (key->external && priv.nelements != 0) - DST_RET(DST_R_INVALIDPRIVATEKEY); - for (i = 0; i < priv.nelements; i++) { switch (priv.elements[i].tag) { case TAG_RSA_ENGINE: @@ -1335,10 +1345,8 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS) DST_RET(DST_R_INVALIDPRIVATEKEY); - if (!key->external) { - if (BN_num_bits(rsa->e) > RSA_MAX_PUBEXP_BITS) - DST_RET(ISC_R_RANGE); - } + if (BN_num_bits(rsa->e) > RSA_MAX_PUBEXP_BITS) + DST_RET(ISC_R_RANGE); key->key_size = BN_num_bits(rsa->n); if (pubrsa != NULL) RSA_free(pubrsa); diff --git a/lib/dns/pkcs11dh_link.c b/lib/dns/pkcs11dh_link.c index 570ba9efae..b8daba393b 100644 --- a/lib/dns/pkcs11dh_link.c +++ b/lib/dns/pkcs11dh_link.c @@ -925,6 +925,9 @@ pkcs11dh_tofile(const dst_key_t *key, const char *directory) { if (key->keydata.pkey == NULL) return (DST_R_NULLKEY); + if (key->external) + return (DST_R_EXTERNALKEY); + dh = key->keydata.pkey; for (attr = pk11_attribute_first(dh); @@ -1013,6 +1016,9 @@ pkcs11dh_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { if (ret != ISC_R_SUCCESS) return (ret); + if (key->external) + DST_RET(DST_R_EXTERNALKEY); + dh = (iscpk11_object_t *) isc_mem_get(key->mctx, sizeof(*dh)); if (dh == NULL) DST_RET(ISC_R_NOMEMORY); diff --git a/lib/dns/pkcs11dsa_link.c b/lib/dns/pkcs11dsa_link.c index 84d3e3cec8..e0ef40b8cd 100644 --- a/lib/dns/pkcs11dsa_link.c +++ b/lib/dns/pkcs11dsa_link.c @@ -968,14 +968,26 @@ pkcs11dsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { CK_ATTRIBUTE *attr; isc_mem_t *mctx = key->mctx; - UNUSED(pub); /* read private key file */ ret = dst__privstruct_parse(key, DST_ALG_DSA, lexer, mctx, &priv); if (ret != ISC_R_SUCCESS) return (ret); - if (key->external && priv.nelements != 0) - DST_RET(DST_R_INVALIDPRIVATEKEY); + if (key->external) { + if (priv.nelements != 0) + DST_RET(DST_R_INVALIDPRIVATEKEY); + if (pub == NULL) + DST_RET(DST_R_INVALIDPRIVATEKEY); + + key->keydata.pkey = pub->keydata.pkey; + pub->keydata.pkey = NULL; + key->key_size = pub->key_size; + + dst__privstruct_free(&priv, mctx); + memset(&priv, 0, sizeof(priv)); + + return (ISC_R_SUCCESS); + } dsa = (iscpk11_object_t *) isc_mem_get(key->mctx, sizeof(*dsa)); if (dsa == NULL) diff --git a/lib/dns/pkcs11ecdsa_link.c b/lib/dns/pkcs11ecdsa_link.c index a5e111032c..3fe0f2f271 100644 --- a/lib/dns/pkcs11ecdsa_link.c +++ b/lib/dns/pkcs11ecdsa_link.c @@ -918,15 +918,28 @@ pkcs11ecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { REQUIRE(key->key_alg == DST_ALG_ECDSA256 || key->key_alg == DST_ALG_ECDSA384); - REQUIRE((pub != NULL) && (pub->keydata.pkey != NULL)); + + if ((pub == NULL) || (pub->keydata.pkey == NULL)) + DST_RET(DST_R_INVALIDPRIVATEKEY); /* read private key file */ ret = dst__privstruct_parse(key, DST_ALG_ECDSA256, lexer, mctx, &priv); if (ret != ISC_R_SUCCESS) return (ret); - if (key->external && priv.nelements != 0) - DST_RET(DST_R_INVALIDPRIVATEKEY); + if (key->external) { + if (priv.nelements != 0) + DST_RET(DST_R_INVALIDPRIVATEKEY); + + key->keydata.pkey = pub->keydata.pkey; + pub->keydata.pkey = NULL; + key->key_size = pub->key_size; + + dst__privstruct_free(&priv, mctx); + memset(&priv, 0, sizeof(priv)); + + return (ISC_R_SUCCESS); + } for (i = 0; i < priv.nelements; i++) { switch (priv.elements[i].tag) { diff --git a/lib/dns/pkcs11gost_link.c b/lib/dns/pkcs11gost_link.c index ab261816b3..8e8d501209 100644 --- a/lib/dns/pkcs11gost_link.c +++ b/lib/dns/pkcs11gost_link.c @@ -744,7 +744,7 @@ pkcs11gost_tofile(const dst_key_t *key, const char *directory) { priv.elements[i].length = (unsigned short) attr->ulValueLen + 39; memmove(buf, gost_private_der, 39); - memmove(buf +39, attr->pValue, attr->ulValueLen); + memmove(buf + 39, attr->pValue, attr->ulValueLen); adj = (int) attr->ulValueLen - 32; if (adj != 0) { buf[1] += adj; @@ -818,15 +818,27 @@ pkcs11gost_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { CK_ATTRIBUTE *attr, *pattr; isc_mem_t *mctx = key->mctx; - REQUIRE((pub != NULL) && (pub->keydata.pkey != NULL)); + if ((pub == NULL) || (pub->keydata.pkey == NULL)) + DST_RET(DST_R_INVALIDPRIVATEKEY); /* read private key file */ ret = dst__privstruct_parse(key, DST_ALG_ECDSA256, lexer, mctx, &priv); if (ret != ISC_R_SUCCESS) return (ret); - if (key->external && priv.nelements != 0) - DST_RET(DST_R_INVALIDPRIVATEKEY); + if (key->external) { + if (priv.nelements != 0) + DST_RET(DST_R_INVALIDPRIVATEKEY); + + key->keydata.pkey = pub->keydata.pkey; + pub->keydata.pkey = NULL; + key->key_size = pub->key_size; + + dst__privstruct_free(&priv, mctx); + memset(&priv, 0, sizeof(priv)); + + return (ISC_R_SUCCESS); + } if (priv.elements[0].tag == TAG_GOST_PRIVASN1) { int adj = (int) priv.elements[0].length - (39 + 32); diff --git a/lib/dns/pkcs11rsa_link.c b/lib/dns/pkcs11rsa_link.c index 77ba303d51..cfa3da2946 100644 --- a/lib/dns/pkcs11rsa_link.c +++ b/lib/dns/pkcs11rsa_link.c @@ -1234,8 +1234,21 @@ pkcs11rsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { if (ret != ISC_R_SUCCESS) return (ret); - if (key->external && priv.nelements != 0) - DST_RET(DST_R_INVALIDPRIVATEKEY); + if (key->external) { + if (priv.nelements != 0) + DST_RET(DST_R_INVALIDPRIVATEKEY); + if (pub == NULL) + DST_RET(DST_R_INVALIDPRIVATEKEY); + + key->keydata.pkey = pub->keydata.pkey; + pub->keydata.pkey = NULL; + key->key_size = pub->key_size; + + dst__privstruct_free(&priv, mctx); + memset(&priv, 0, sizeof(priv)); + + return (ISC_R_SUCCESS); + } for (i = 0; i < priv.nelements; i++) { switch (priv.elements[i].tag) { @@ -1362,8 +1375,7 @@ pkcs11rsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { attr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT); INSIST(attr != NULL); - if (!key->external && - pk11_numbits(attr->pValue, attr->ulValueLen) > RSA_MAX_PUBEXP_BITS) + if (pk11_numbits(attr->pValue, attr->ulValueLen) > RSA_MAX_PUBEXP_BITS) DST_RET(ISC_R_RANGE); dst__privstruct_free(&priv, mctx);