mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
Tolerate non-extractable Ed25519/Ed448 private keys in tofile
openssleddsa_tofile() called EVP_PKEY_get_raw_private_key() unconditionally whenever the dst_key_t had a private EVP_PKEY attached and aborted with ISC_R_FAILURE on any error. That is wrong for keys whose private material lives in a hardware token (PKCS#11): the provider deliberately refuses to export the raw bytes, but the keypair is still valid and the .private file should be written containing only the PKCS#11 label, with no raw key material. Without this, "dnssec-keyfromlabel -a ed25519 -l pkcs11:..." fails with "failed to write key ...: failure" even though pkcs11-tool has generated a valid Ed25519 key in SoftHSM. Mirror the behaviour already implemented in opensslecdsa_tofile(): if the raw private key cannot be retrieved AND the key has a PKCS#11 label to fall back on, clear the OpenSSL error queue and fall through to writing just the Label element. If extraction fails and there is no label to fall back on, return the OpenSSL failure rather than silently producing a .private file with neither raw key material nor a label, which would be unusable on the next load. Consolidate buffer cleanup into a single cleanup: path, freeing with the original allocation size (alginfo->key_size) rather than the potentially-modified len output parameter. Assisted-by: Claude:claude-opus-4-7
This commit is contained in:
parent
6811a8490a
commit
945838e621
1 changed files with 15 additions and 7 deletions
|
|
@ -371,14 +371,22 @@ openssleddsa_tofile(const dst_key_t *key, const char *directory) {
|
|||
len = alginfo->key_size;
|
||||
buf = isc_mem_get(key->mctx, len);
|
||||
if (EVP_PKEY_get_raw_private_key(key->keydata.pkeypair.priv,
|
||||
buf, &len) != 1)
|
||||
buf, &len) == 1)
|
||||
{
|
||||
CLEANUP(dst__openssl_toresult(ISC_R_FAILURE));
|
||||
priv.elements[i].tag = TAG_EDDSA_PRIVATEKEY;
|
||||
priv.elements[i].length = len;
|
||||
priv.elements[i].data = buf;
|
||||
i++;
|
||||
} else if (key->label != NULL) {
|
||||
/*
|
||||
* The raw private key is not extractable
|
||||
* (e.g. HSM-backed via PKCS#11); fall through to
|
||||
* writing only the label.
|
||||
*/
|
||||
ERR_clear_error();
|
||||
} else {
|
||||
CLEANUP(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
|
||||
}
|
||||
priv.elements[i].tag = TAG_EDDSA_PRIVATEKEY;
|
||||
priv.elements[i].length = len;
|
||||
priv.elements[i].data = buf;
|
||||
i++;
|
||||
}
|
||||
if (key->label != NULL) {
|
||||
priv.elements[i].tag = TAG_EDDSA_LABEL;
|
||||
|
|
@ -393,7 +401,7 @@ openssleddsa_tofile(const dst_key_t *key, const char *directory) {
|
|||
|
||||
cleanup:
|
||||
if (buf != NULL) {
|
||||
isc_mem_put(key->mctx, buf, len);
|
||||
isc_mem_put(key->mctx, buf, alginfo->key_size);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue