mirror of
https://github.com/NLnetLabs/dnst.git
synced 2026-09-29 05:05:00 +02:00
Store key references are file URLs.
This commit is contained in:
Generated
+277
@@ -312,6 +312,17 @@ version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
|
||||
|
||||
[[package]]
|
||||
name = "displaydoc"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dnst"
|
||||
version = "0.1.1-dev"
|
||||
@@ -336,6 +347,7 @@ dependencies = [
|
||||
"tokio",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -438,6 +450,15 @@ version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
|
||||
dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.31"
|
||||
@@ -557,6 +578,113 @@ dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_collections"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"potential_utf",
|
||||
"yoke",
|
||||
"zerofrom",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_locale_core"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"litemap",
|
||||
"tinystr",
|
||||
"writeable",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_normalizer"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"icu_collections",
|
||||
"icu_normalizer_data",
|
||||
"icu_properties",
|
||||
"icu_provider",
|
||||
"smallvec",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_normalizer_data"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3"
|
||||
|
||||
[[package]]
|
||||
name = "icu_properties"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"icu_collections",
|
||||
"icu_locale_core",
|
||||
"icu_properties_data",
|
||||
"icu_provider",
|
||||
"potential_utf",
|
||||
"zerotrie",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_properties_data"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632"
|
||||
|
||||
[[package]]
|
||||
name = "icu_provider"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"icu_locale_core",
|
||||
"stable_deref_trait",
|
||||
"tinystr",
|
||||
"writeable",
|
||||
"yoke",
|
||||
"zerofrom",
|
||||
"zerotrie",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e"
|
||||
dependencies = [
|
||||
"idna_adapter",
|
||||
"smallvec",
|
||||
"utf8_iter",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna_adapter"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344"
|
||||
dependencies = [
|
||||
"icu_normalizer",
|
||||
"icu_properties",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is_terminal_polyfill"
|
||||
version = "1.70.1"
|
||||
@@ -627,6 +755,12 @@ version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12"
|
||||
|
||||
[[package]]
|
||||
name = "litemap"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.13"
|
||||
@@ -843,6 +977,12 @@ dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.16"
|
||||
@@ -876,6 +1016,15 @@ dependencies = [
|
||||
"portable-atomic",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "potential_utf"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585"
|
||||
dependencies = [
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "powerfmt"
|
||||
version = "0.2.0"
|
||||
@@ -1187,6 +1336,12 @@ dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stable_deref_trait"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.11.1"
|
||||
@@ -1204,6 +1359,17 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "synstructure"
|
||||
version = "0.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tagptr"
|
||||
version = "0.2.0"
|
||||
@@ -1290,6 +1456,16 @@ dependencies = [
|
||||
"time-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinystr"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.45.1"
|
||||
@@ -1408,6 +1584,23 @@ version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "utf8_iter"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.2"
|
||||
@@ -1734,12 +1927,42 @@ dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "writeable"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb"
|
||||
|
||||
[[package]]
|
||||
name = "yansi"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
|
||||
|
||||
[[package]]
|
||||
name = "yoke"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"stable_deref_trait",
|
||||
"yoke-derive",
|
||||
"zerofrom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yoke-derive"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.8.25"
|
||||
@@ -1760,8 +1983,62 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerofrom"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5"
|
||||
dependencies = [
|
||||
"zerofrom-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerofrom-derive"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zeroize"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
|
||||
|
||||
[[package]]
|
||||
name = "zerotrie"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"yoke",
|
||||
"zerofrom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerovec"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428"
|
||||
dependencies = [
|
||||
"yoke",
|
||||
"zerofrom",
|
||||
"zerovec-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerovec-derive"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
@@ -56,6 +56,7 @@ serde_json = "1.0.137"
|
||||
serde = "1.0.217"
|
||||
tracing = "0.1.41"
|
||||
tracing-subscriber = "0.3.19"
|
||||
url = "2.5.4"
|
||||
|
||||
[dev-dependencies]
|
||||
const_format = " 0.2.33"
|
||||
|
||||
+186
-99
@@ -24,8 +24,9 @@ use std::collections::HashMap;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::fs::{remove_file, File};
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
use std::path::{absolute, Path, PathBuf};
|
||||
use std::time::Duration;
|
||||
use url::Url;
|
||||
|
||||
const MAX_KEY_TAG_TRIES: u8 = 10;
|
||||
|
||||
@@ -68,9 +69,15 @@ impl Keyset {
|
||||
let domainname = self
|
||||
.domain_name
|
||||
.ok_or::<Error>("domain name option expected\n".into())?;
|
||||
|
||||
let state_file = self
|
||||
.keyset_state
|
||||
.ok_or::<Error>("state file option expected\n".into())?;
|
||||
let state_file = absolute(&state_file).map_err::<Error, _>(|e| {
|
||||
format!("unable to make {} absolute: {}", state_file.display(), e).into()
|
||||
})?;
|
||||
let keys_dir = make_parent_dir(state_file.clone());
|
||||
|
||||
let ks = KeySet::new(domainname);
|
||||
let kss = KeySetState {
|
||||
keyset: ks,
|
||||
@@ -83,6 +90,7 @@ impl Keyset {
|
||||
const FOUR_WEEKS: u64 = 2419200;
|
||||
let ksc = KeySetConfig {
|
||||
state_file: state_file.clone(),
|
||||
keys_dir,
|
||||
use_csk: false,
|
||||
ksk_generate_params: KeyParameters::RsaSha256(2048),
|
||||
zsk_generate_params: KeyParameters::RsaSha256(2048),
|
||||
@@ -135,12 +143,13 @@ impl Keyset {
|
||||
ksc.csk_generate_params.to_generate_params(),
|
||||
true,
|
||||
kss.keyset.keys(),
|
||||
&ksc.keys_dir,
|
||||
env,
|
||||
)?;
|
||||
kss.keyset
|
||||
.add_key_csk(
|
||||
csk_pub_name.clone(),
|
||||
Some(csk_priv_name),
|
||||
csk_pub_name.to_string(),
|
||||
Some(csk_priv_name.to_string()),
|
||||
algorithm,
|
||||
key_tag,
|
||||
UnixTime::now(),
|
||||
@@ -148,43 +157,45 @@ impl Keyset {
|
||||
.expect("should not happen");
|
||||
|
||||
kss.keyset
|
||||
.start_roll(RollType::AlgorithmRoll, &[], &[&csk_pub_name])
|
||||
.start_roll(RollType::AlgorithmRoll, &[], &[&csk_pub_name.as_str()])
|
||||
.expect("should not happen")
|
||||
} else {
|
||||
let (ksk_pub_name, ksk_priv_name, algorithm, key_tag) = new_keys(
|
||||
let (ksk_pub_url, ksk_priv_url, algorithm, key_tag) = new_keys(
|
||||
kss.keyset.name(),
|
||||
ksc.ksk_generate_params.to_generate_params(),
|
||||
true,
|
||||
kss.keyset.keys(),
|
||||
&ksc.keys_dir,
|
||||
env,
|
||||
)?;
|
||||
kss.keyset
|
||||
.add_key_ksk(
|
||||
ksk_pub_name.clone(),
|
||||
Some(ksk_priv_name),
|
||||
ksk_pub_url.to_string(),
|
||||
Some(ksk_priv_url.to_string()),
|
||||
algorithm,
|
||||
key_tag,
|
||||
UnixTime::now(),
|
||||
)
|
||||
.expect("should not happen");
|
||||
let (zsk_pub_name, zsk_priv_name, algorithm, key_tag) = new_keys(
|
||||
let (zsk_pub_url, zsk_priv_url, algorithm, key_tag) = new_keys(
|
||||
kss.keyset.name(),
|
||||
ksc.zsk_generate_params.to_generate_params(),
|
||||
false,
|
||||
kss.keyset.keys(),
|
||||
&ksc.keys_dir,
|
||||
env,
|
||||
)?;
|
||||
kss.keyset
|
||||
.add_key_zsk(
|
||||
zsk_pub_name.clone(),
|
||||
Some(zsk_priv_name),
|
||||
zsk_pub_url.to_string(),
|
||||
Some(zsk_priv_url.to_string()),
|
||||
algorithm,
|
||||
key_tag,
|
||||
UnixTime::now(),
|
||||
)
|
||||
.expect("should not happen");
|
||||
|
||||
let new = [ksk_pub_name.as_ref(), zsk_pub_name.as_ref()];
|
||||
let new = [ksk_pub_url.as_ref(), zsk_pub_url.as_ref()];
|
||||
kss.keyset
|
||||
.start_roll(RollType::AlgorithmRoll, &[], &new)
|
||||
.expect("should not happen")
|
||||
@@ -237,26 +248,27 @@ impl Keyset {
|
||||
// Collect algorithms. Maybe this needs to be in the library.
|
||||
|
||||
// Create a new KSK
|
||||
let (ksk_pub_name, ksk_priv_name, algorithm, key_tag) = new_keys(
|
||||
let (ksk_pub_url, ksk_priv_url, algorithm, key_tag) = new_keys(
|
||||
kss.keyset.name(),
|
||||
ksc.ksk_generate_params.to_generate_params(),
|
||||
true,
|
||||
kss.keyset.keys(),
|
||||
&ksc.keys_dir,
|
||||
env,
|
||||
)?;
|
||||
kss.keyset
|
||||
.add_key_ksk(
|
||||
ksk_pub_name.clone(),
|
||||
Some(ksk_priv_name.clone()),
|
||||
ksk_pub_url.to_string(),
|
||||
Some(ksk_priv_url.to_string()),
|
||||
algorithm,
|
||||
key_tag,
|
||||
UnixTime::now(),
|
||||
)
|
||||
.map_err::<Error, _>(|e| {
|
||||
format!("unable to add KSK {ksk_pub_name}: {e}\n").into()
|
||||
format!("unable to add KSK {ksk_pub_url}: {e}\n").into()
|
||||
})?;
|
||||
|
||||
let new = [ksk_pub_name.as_ref()];
|
||||
let new = [ksk_pub_url.as_ref()];
|
||||
|
||||
// Start the key roll
|
||||
let actions = match kss
|
||||
@@ -267,12 +279,23 @@ impl Keyset {
|
||||
Ok(actions) => actions,
|
||||
Err(e) => {
|
||||
// Remove the key files we just created.
|
||||
remove_file(ksk_priv_name.clone()).map_err::<Error, _>(|e| {
|
||||
format!("unable to remove private key file {ksk_priv_name}: {e}\n").into()
|
||||
})?;
|
||||
remove_file(ksk_pub_name.clone()).map_err::<Error, _>(|e| {
|
||||
format!("unable to remove public key file {ksk_pub_name}: {e}\n").into()
|
||||
})?;
|
||||
if ksk_priv_url.scheme() == "file" {
|
||||
remove_file(ksk_priv_url.path()).map_err::<Error, _>(|e| {
|
||||
format!("unable to remove private key file {ksk_priv_url}: {e}\n")
|
||||
.into()
|
||||
})?;
|
||||
} else {
|
||||
panic!("unsupported URL scheme in {ksk_priv_url}");
|
||||
}
|
||||
|
||||
if ksk_pub_url.scheme() == "file" {
|
||||
remove_file(ksk_pub_url.path()).map_err::<Error, _>(|e| {
|
||||
format!("unable to remove public key file {ksk_pub_url}: {e}\n").into()
|
||||
})?;
|
||||
} else {
|
||||
panic!("unsupported URL scheme in {ksk_pub_url}");
|
||||
}
|
||||
|
||||
return Err(e);
|
||||
}
|
||||
};
|
||||
@@ -320,26 +343,27 @@ impl Keyset {
|
||||
// Collect algorithms. Maybe this needs to be in the library.
|
||||
|
||||
// Create a new ZSK
|
||||
let (zsk_pub_name, zsk_priv_name, algorithm, key_tag) = new_keys(
|
||||
let (zsk_pub_url, zsk_priv_url, algorithm, key_tag) = new_keys(
|
||||
kss.keyset.name(),
|
||||
ksc.zsk_generate_params.to_generate_params(),
|
||||
false,
|
||||
kss.keyset.keys(),
|
||||
&ksc.keys_dir,
|
||||
env,
|
||||
)?;
|
||||
kss.keyset
|
||||
.add_key_zsk(
|
||||
zsk_pub_name.clone(),
|
||||
Some(zsk_priv_name.clone()),
|
||||
zsk_pub_url.to_string(),
|
||||
Some(zsk_priv_url.to_string()),
|
||||
algorithm,
|
||||
key_tag,
|
||||
UnixTime::now(),
|
||||
)
|
||||
.map_err::<Error, _>(|e| {
|
||||
format!("unable to add ZSK {zsk_pub_name}: {e}\n").into()
|
||||
format!("unable to add ZSK {zsk_pub_url}: {e}\n").into()
|
||||
})?;
|
||||
|
||||
let new = [zsk_pub_name.as_ref()];
|
||||
let new = [zsk_pub_url.as_ref()];
|
||||
|
||||
// Start the key roll
|
||||
let actions = match kss
|
||||
@@ -350,12 +374,21 @@ impl Keyset {
|
||||
Ok(actions) => actions,
|
||||
Err(e) => {
|
||||
// Remove the key files we just created.
|
||||
remove_file(zsk_priv_name.clone()).map_err::<Error, _>(|e| {
|
||||
format!("unable to remove private key file {zsk_priv_name}: {e}\n").into()
|
||||
})?;
|
||||
remove_file(zsk_pub_name.clone()).map_err::<Error, _>(|e| {
|
||||
format!("unable to remove public key file {zsk_pub_name}: {e}\n").into()
|
||||
})?;
|
||||
if zsk_priv_url.scheme() == "file" {
|
||||
remove_file(zsk_priv_url.path()).map_err::<Error, _>(|e| {
|
||||
format!("unable to remove private key file {zsk_priv_url}: {e}\n")
|
||||
.into()
|
||||
})?;
|
||||
} else {
|
||||
panic!("unsupported URL scheme in {zsk_priv_url}");
|
||||
}
|
||||
if zsk_pub_url.scheme() == "file" {
|
||||
remove_file(zsk_pub_url.path()).map_err::<Error, _>(|e| {
|
||||
format!("unable to remove public key file {zsk_pub_url}: {e}\n").into()
|
||||
})?;
|
||||
} else {
|
||||
panic!("unsupported URL scheme in {zsk_pub_url}");
|
||||
}
|
||||
return Err(e);
|
||||
}
|
||||
};
|
||||
@@ -388,82 +421,85 @@ impl Keyset {
|
||||
|
||||
// Collect algorithms. Maybe this needs to be in the library.
|
||||
|
||||
let (new_stored, new_files) = if ksc.use_csk {
|
||||
let mut new_files = Vec::new();
|
||||
let (new_stored, new_urls) = if ksc.use_csk {
|
||||
let mut new_urls = Vec::new();
|
||||
|
||||
// Create a new CSK
|
||||
let (csk_pub_name, csk_priv_name, algorithm, key_tag) = new_keys(
|
||||
let (csk_pub_url, csk_priv_url, algorithm, key_tag) = new_keys(
|
||||
kss.keyset.name(),
|
||||
ksc.csk_generate_params.to_generate_params(),
|
||||
true,
|
||||
kss.keyset.keys(),
|
||||
&ksc.keys_dir,
|
||||
env,
|
||||
)?;
|
||||
new_files.push(csk_priv_name.clone());
|
||||
new_files.push(csk_pub_name.clone());
|
||||
new_urls.push(csk_priv_url.clone());
|
||||
new_urls.push(csk_pub_url.clone());
|
||||
kss.keyset
|
||||
.add_key_csk(
|
||||
csk_pub_name.clone(),
|
||||
Some(csk_priv_name.clone()),
|
||||
csk_pub_url.to_string(),
|
||||
Some(csk_priv_url.to_string()),
|
||||
algorithm,
|
||||
key_tag,
|
||||
UnixTime::now(),
|
||||
)
|
||||
.map_err::<Error, _>(|e| {
|
||||
format!("unable to add CSK {csk_pub_name}: {e}\n").into()
|
||||
format!("unable to add CSK {csk_pub_url}: {e}\n").into()
|
||||
})?;
|
||||
|
||||
let new = vec![csk_pub_name];
|
||||
(new, new_files)
|
||||
let new = vec![csk_pub_url];
|
||||
(new, new_urls)
|
||||
} else {
|
||||
let mut new_files = Vec::new();
|
||||
let mut new_urls = Vec::new();
|
||||
|
||||
// Create a new KSK
|
||||
let (ksk_pub_name, ksk_priv_name, algorithm, key_tag) = new_keys(
|
||||
let (ksk_pub_url, ksk_priv_url, algorithm, key_tag) = new_keys(
|
||||
kss.keyset.name(),
|
||||
ksc.ksk_generate_params.to_generate_params(),
|
||||
true,
|
||||
kss.keyset.keys(),
|
||||
&ksc.keys_dir,
|
||||
env,
|
||||
)?;
|
||||
new_files.push(ksk_priv_name.clone());
|
||||
new_files.push(ksk_pub_name.clone());
|
||||
new_urls.push(ksk_priv_url.clone());
|
||||
new_urls.push(ksk_pub_url.clone());
|
||||
kss.keyset
|
||||
.add_key_ksk(
|
||||
ksk_pub_name.clone(),
|
||||
Some(ksk_priv_name.clone()),
|
||||
ksk_pub_url.to_string(),
|
||||
Some(ksk_priv_url.to_string()),
|
||||
algorithm,
|
||||
key_tag,
|
||||
UnixTime::now(),
|
||||
)
|
||||
.map_err::<Error, _>(|e| {
|
||||
format!("unable to add KSK {ksk_pub_name}: {e}\n").into()
|
||||
format!("unable to add KSK {ksk_pub_url}: {e}\n").into()
|
||||
})?;
|
||||
|
||||
// Create a new ZSK
|
||||
let (zsk_pub_name, zsk_priv_name, algorithm, key_tag) = new_keys(
|
||||
let (zsk_pub_url, zsk_priv_url, algorithm, key_tag) = new_keys(
|
||||
kss.keyset.name(),
|
||||
ksc.zsk_generate_params.to_generate_params(),
|
||||
false,
|
||||
kss.keyset.keys(),
|
||||
&ksc.keys_dir,
|
||||
env,
|
||||
)?;
|
||||
new_files.push(zsk_priv_name.clone());
|
||||
new_files.push(zsk_pub_name.clone());
|
||||
new_urls.push(zsk_priv_url.clone());
|
||||
new_urls.push(zsk_pub_url.clone());
|
||||
kss.keyset
|
||||
.add_key_zsk(
|
||||
zsk_pub_name.clone(),
|
||||
Some(zsk_priv_name.clone()),
|
||||
zsk_pub_url.to_string(),
|
||||
Some(zsk_priv_url.to_string()),
|
||||
algorithm,
|
||||
key_tag,
|
||||
UnixTime::now(),
|
||||
)
|
||||
.map_err::<Error, _>(|e| {
|
||||
format!("unable to add ZSK {zsk_pub_name}: {e}\n").into()
|
||||
format!("unable to add ZSK {zsk_pub_url}: {e}\n").into()
|
||||
})?;
|
||||
|
||||
let new = vec![ksk_pub_name, zsk_pub_name];
|
||||
(new, new_files)
|
||||
let new = vec![ksk_pub_url, zsk_pub_url];
|
||||
(new, new_urls)
|
||||
};
|
||||
|
||||
let new: Vec<_> = new_stored.iter().map(|v| v.as_ref()).collect();
|
||||
@@ -477,10 +513,14 @@ impl Keyset {
|
||||
Ok(actions) => actions,
|
||||
Err(e) => {
|
||||
// Remove the key files we just created.
|
||||
for f in new_files {
|
||||
remove_file(&f).map_err::<Error, _>(|e| {
|
||||
format!("unable to private key file {f}: {e}\n").into()
|
||||
})?;
|
||||
for u in new_urls {
|
||||
if u.scheme() == "file" {
|
||||
remove_file(u.path()).map_err::<Error, _>(|e| {
|
||||
format!("unable to remove private key file {u}: {e}\n").into()
|
||||
})?;
|
||||
} else {
|
||||
panic!("unsupported URL scheme in {u}");
|
||||
}
|
||||
}
|
||||
return Err(e);
|
||||
}
|
||||
@@ -513,82 +553,85 @@ impl Keyset {
|
||||
.collect();
|
||||
let old: Vec<_> = old_stored.iter().map(|name| name.as_ref()).collect();
|
||||
|
||||
let (new_stored, new_files) = if ksc.use_csk {
|
||||
let mut new_files = Vec::new();
|
||||
let (new_stored, new_urls) = if ksc.use_csk {
|
||||
let mut new_urls = Vec::new();
|
||||
|
||||
// Create a new CSK
|
||||
let (csk_pub_name, csk_priv_name, algorithm, key_tag) = new_keys(
|
||||
let (csk_pub_url, csk_priv_url, algorithm, key_tag) = new_keys(
|
||||
kss.keyset.name(),
|
||||
ksc.csk_generate_params.to_generate_params(),
|
||||
true,
|
||||
kss.keyset.keys(),
|
||||
&ksc.keys_dir,
|
||||
env,
|
||||
)?;
|
||||
new_files.push(csk_priv_name.clone());
|
||||
new_files.push(csk_pub_name.clone());
|
||||
new_urls.push(csk_priv_url.clone());
|
||||
new_urls.push(csk_pub_url.clone());
|
||||
kss.keyset
|
||||
.add_key_csk(
|
||||
csk_pub_name.clone(),
|
||||
Some(csk_priv_name.clone()),
|
||||
csk_pub_url.to_string(),
|
||||
Some(csk_priv_url.to_string()),
|
||||
algorithm,
|
||||
key_tag,
|
||||
UnixTime::now(),
|
||||
)
|
||||
.map_err::<Error, _>(|e| {
|
||||
format!("unable to add CSK {csk_pub_name}: {e}\n").into()
|
||||
format!("unable to add CSK {csk_pub_url}: {e}\n").into()
|
||||
})?;
|
||||
|
||||
let new = vec![csk_pub_name];
|
||||
(new, new_files)
|
||||
let new = vec![csk_pub_url];
|
||||
(new, new_urls)
|
||||
} else {
|
||||
let mut new_files = Vec::new();
|
||||
let mut new_urls = Vec::new();
|
||||
|
||||
// Create a new KSK
|
||||
let (ksk_pub_name, ksk_priv_name, algorithm, key_tag) = new_keys(
|
||||
let (ksk_pub_url, ksk_priv_url, algorithm, key_tag) = new_keys(
|
||||
kss.keyset.name(),
|
||||
ksc.ksk_generate_params.to_generate_params(),
|
||||
true,
|
||||
kss.keyset.keys(),
|
||||
&ksc.keys_dir,
|
||||
env,
|
||||
)?;
|
||||
new_files.push(ksk_priv_name.clone());
|
||||
new_files.push(ksk_pub_name.clone());
|
||||
new_urls.push(ksk_priv_url.clone());
|
||||
new_urls.push(ksk_pub_url.clone());
|
||||
kss.keyset
|
||||
.add_key_ksk(
|
||||
ksk_pub_name.clone(),
|
||||
Some(ksk_priv_name.clone()),
|
||||
ksk_pub_url.to_string(),
|
||||
Some(ksk_priv_url.to_string()),
|
||||
algorithm,
|
||||
key_tag,
|
||||
UnixTime::now(),
|
||||
)
|
||||
.map_err::<Error, _>(|e| {
|
||||
format!("unable to add KSK {ksk_pub_name}: {e}\n").into()
|
||||
format!("unable to add KSK {ksk_pub_url}: {e}\n").into()
|
||||
})?;
|
||||
|
||||
// Create a new ZSK
|
||||
let (zsk_pub_name, zsk_priv_name, algorithm, key_tag) = new_keys(
|
||||
let (zsk_pub_url, zsk_priv_url, algorithm, key_tag) = new_keys(
|
||||
kss.keyset.name(),
|
||||
ksc.zsk_generate_params.to_generate_params(),
|
||||
false,
|
||||
kss.keyset.keys(),
|
||||
&ksc.keys_dir,
|
||||
env,
|
||||
)?;
|
||||
new_files.push(zsk_priv_name.clone());
|
||||
new_files.push(zsk_pub_name.clone());
|
||||
new_urls.push(zsk_priv_url.clone());
|
||||
new_urls.push(zsk_pub_url.clone());
|
||||
kss.keyset
|
||||
.add_key_zsk(
|
||||
zsk_pub_name.clone(),
|
||||
Some(zsk_priv_name.clone()),
|
||||
zsk_pub_url.to_string(),
|
||||
Some(zsk_priv_url.to_string()),
|
||||
algorithm,
|
||||
key_tag,
|
||||
UnixTime::now(),
|
||||
)
|
||||
.map_err::<Error, _>(|e| {
|
||||
format!("unable to add ZSK {zsk_pub_name}: {e}\n").into()
|
||||
format!("unable to add ZSK {zsk_pub_url}: {e}\n").into()
|
||||
})?;
|
||||
|
||||
let new = vec![ksk_pub_name, zsk_pub_name];
|
||||
(new, new_files)
|
||||
let new = vec![ksk_pub_url, zsk_pub_url];
|
||||
(new, new_urls)
|
||||
};
|
||||
|
||||
let new: Vec<_> = new_stored.iter().map(|v| v.as_ref()).collect();
|
||||
@@ -602,10 +645,14 @@ impl Keyset {
|
||||
Ok(actions) => actions,
|
||||
Err(e) => {
|
||||
// Remove the key files we just created.
|
||||
for f in new_files {
|
||||
remove_file(&f).map_err::<Error, _>(|e| {
|
||||
format!("unable to private key file {f}: {e}\n").into()
|
||||
})?;
|
||||
for u in new_urls {
|
||||
if u.scheme() == "file" {
|
||||
remove_file(u.path()).map_err::<Error, _>(|e| {
|
||||
format!("unable to private key file {u}: {e}\n").into()
|
||||
})?;
|
||||
} else {
|
||||
panic!("unsupported scheme in {u}");
|
||||
}
|
||||
}
|
||||
return Err(e);
|
||||
}
|
||||
@@ -1002,6 +1049,7 @@ impl Keyset {
|
||||
#[derive(Deserialize, Serialize)]
|
||||
struct KeySetConfig {
|
||||
state_file: PathBuf,
|
||||
keys_dir: PathBuf,
|
||||
|
||||
use_csk: bool,
|
||||
|
||||
@@ -1153,8 +1201,9 @@ fn new_keys(
|
||||
algorithm: GenerateParams,
|
||||
make_ksk: bool,
|
||||
keys: &HashMap<String, Key>,
|
||||
keys_dir: &Path,
|
||||
env: &impl Env,
|
||||
) -> Result<(String, String, SecurityAlgorithm, u16), Error> {
|
||||
) -> Result<(Url, Url, SecurityAlgorithm, u16), Error> {
|
||||
// Generate the key.
|
||||
// TODO: Attempt repeated generation to avoid key tag collisions.
|
||||
// TODO: Add a high-level operation in 'domain' to select flags?
|
||||
@@ -1186,8 +1235,10 @@ fn new_keys(
|
||||
key_tag
|
||||
);
|
||||
|
||||
let secret_key_path = format!("{base}.private");
|
||||
let public_key_path = format!("{base}.key");
|
||||
let mut secret_key_path = keys_dir.to_path_buf();
|
||||
secret_key_path.push(Path::new(&format!("{base}.private")));
|
||||
let mut public_key_path = keys_dir.to_path_buf();
|
||||
public_key_path.push(Path::new(&format!("{base}.key")));
|
||||
|
||||
let mut secret_key_file = util::create_new_file(&env, &secret_key_path)?;
|
||||
let mut public_key_file = util::create_new_file(&env, &public_key_path)?;
|
||||
@@ -1203,7 +1254,21 @@ fn new_keys(
|
||||
.write_all(public_key.as_bytes())
|
||||
.map_err(|err| format!("error while writing public key file '{base}.key': {err}"))?;
|
||||
|
||||
Ok((public_key_path, secret_key_path, algorithm, key_tag))
|
||||
let secret_key_path = secret_key_path.to_str().ok_or::<Error>(
|
||||
format!("path {} needs to be valid UTF-8", secret_key_path.display()).into(),
|
||||
)?;
|
||||
let secret_key_url = "file://".to_owned() + secret_key_path;
|
||||
let public_key_path = public_key_path.to_str().ok_or::<Error>(
|
||||
format!("path {} needs to be valid UTF-8", public_key_path.display()).into(),
|
||||
)?;
|
||||
let public_key_url = "file://".to_owned() + public_key_path;
|
||||
|
||||
let secret_key_url = Url::parse(&secret_key_url)
|
||||
.map_err::<Error, _>(|e| format!("unable to parse {secret_key_url} as URL: {e}").into())?;
|
||||
let public_key_url = Url::parse(&public_key_url)
|
||||
.map_err::<Error, _>(|e| format!("unable to parse {public_key_url} as URL: {e}").into())?;
|
||||
|
||||
Ok((public_key_url, secret_key_url, algorithm, key_tag))
|
||||
}
|
||||
|
||||
fn update_dnskey_rrset(
|
||||
@@ -1220,9 +1285,17 @@ fn update_dnskey_rrset(
|
||||
KeyType::Include(key_state) => key_state.present(),
|
||||
};
|
||||
|
||||
let pub_url = Url::parse(k).expect("valid URL expected");
|
||||
|
||||
if present {
|
||||
let mut file = File::open(env.in_cwd(&k))?;
|
||||
let zonefile = domain::zonefile::inplace::Zonefile::load(&mut file)?;
|
||||
dbg!("before open");
|
||||
let zonefile = if pub_url.scheme() == "file" {
|
||||
let mut file = File::open(env.in_cwd(&pub_url.path().to_string()))?;
|
||||
domain::zonefile::inplace::Zonefile::load(&mut file)?
|
||||
} else {
|
||||
panic!("unsupported scheme in {pub_url}");
|
||||
};
|
||||
dbg!("after open");
|
||||
for entry in zonefile {
|
||||
let entry = entry
|
||||
.map_err::<Error, _>(|e| format!("bad entry in key file {k}: {e}\n").into())?;
|
||||
@@ -1269,12 +1342,22 @@ fn update_dnskey_rrset(
|
||||
|
||||
if dnskey_signer {
|
||||
let privref = v.privref().ok_or("missing private key")?;
|
||||
let private_data = std::fs::read_to_string(privref)?;
|
||||
let priv_url = Url::parse(privref).expect("valid URL expected");
|
||||
let private_data = if priv_url.scheme() == "file" {
|
||||
std::fs::read_to_string(priv_url.path())?
|
||||
} else {
|
||||
panic!("unsupported URL scheme in {priv_url}");
|
||||
};
|
||||
let secret_key =
|
||||
SecretKeyBytes::parse_from_bind(&private_data).map_err::<Error, _>(|e| {
|
||||
format!("unable to parse private key file {privref}: {e}").into()
|
||||
})?;
|
||||
let public_data = std::fs::read_to_string(k)?;
|
||||
let pub_url = Url::parse(k).expect("valid URL expected");
|
||||
let public_data = if pub_url.scheme() == "file" {
|
||||
std::fs::read_to_string(pub_url.path())?
|
||||
} else {
|
||||
panic!("unsupported URL scheme in {pub_url}");
|
||||
};
|
||||
let public_key = parse_from_bind(&public_data).map_err::<Error, _>(|e| {
|
||||
format!("unable to parse public key file {k}: {e}").into()
|
||||
})?;
|
||||
@@ -1641,3 +1724,7 @@ fn key_expired(key: &Key, ksc: &KeySetConfig) -> (bool, &'static str) {
|
||||
};
|
||||
(timestamp.elapsed() > validity, label)
|
||||
}
|
||||
|
||||
fn make_parent_dir(filename: PathBuf) -> PathBuf {
|
||||
filename.parent().unwrap_or(Path::new("/")).to_path_buf()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user