From 40551a5c26f7731c3095655c0da222b2641eef37 Mon Sep 17 00:00:00 2001 From: ryan Date: Tue, 9 Apr 2024 20:14:59 -0400 Subject: [PATCH] keyforkd: require hardened derivation on two highest indexes --- Cargo.lock | 2 +- crates/daemon/keyforkd-client/src/tests.rs | 3 +++ crates/daemon/keyforkd-models/src/lib.rs | 4 ++++ crates/daemon/keyforkd/Cargo.toml | 2 +- crates/daemon/keyforkd/src/service.rs | 15 +++++++++++++++ crates/daemon/keyforkd/src/test_util.rs | 11 ++++++++--- 6 files changed, 32 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 64df936..99b4c64 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1879,7 +1879,7 @@ dependencies = [ [[package]] name = "keyforkd" -version = "0.1.0" +version = "0.1.1" dependencies = [ "bincode", "hex-literal", diff --git a/crates/daemon/keyforkd-client/src/tests.rs b/crates/daemon/keyforkd-client/src/tests.rs index f6a32b8..ab396da 100644 --- a/crates/daemon/keyforkd-client/src/tests.rs +++ b/crates/daemon/keyforkd-client/src/tests.rs @@ -25,6 +25,9 @@ fn secp256k1_test_suite() { if chain_len < 2 { continue; } + if chain.iter().take(2).any(|index| !index.is_hardened()) { + continue; + } // Consistency check: ensure the server and the client can each derive the same // key using an XPrv, for all but the last XPrv, which is verified after this for i in 2..chain_len { diff --git a/crates/daemon/keyforkd-models/src/lib.rs b/crates/daemon/keyforkd-models/src/lib.rs index 4414415..b719023 100644 --- a/crates/daemon/keyforkd-models/src/lib.rs +++ b/crates/daemon/keyforkd-models/src/lib.rs @@ -43,6 +43,10 @@ pub enum DerivationError { #[error("Invalid derivation length: Expected at least 2, actual: {0}")] InvalidDerivationLength(usize), + /// The derivation request did not use hardened derivation on the 2 highest indexes. + #[error("Invalid derivation paths: expected index #{0} (1) to be hardened")] + InvalidDerivationPath(usize, u32), + /// An error occurred while deriving data. #[error("Derivation error: {0}")] Derivation(String), diff --git a/crates/daemon/keyforkd/Cargo.toml b/crates/daemon/keyforkd/Cargo.toml index c1ed74b..b354175 100644 --- a/crates/daemon/keyforkd/Cargo.toml +++ b/crates/daemon/keyforkd/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "keyforkd" -version = "0.1.0" +version = "0.1.1" edition = "2021" license = "AGPL-3.0-only" diff --git a/crates/daemon/keyforkd/src/service.rs b/crates/daemon/keyforkd/src/service.rs index fee1cad..af8b373 100644 --- a/crates/daemon/keyforkd/src/service.rs +++ b/crates/daemon/keyforkd/src/service.rs @@ -69,6 +69,18 @@ impl Service for Keyforkd { return Err(DerivationError::InvalidDerivationLength(len).into()); } + if let Some((i, unhardened_index)) = req + .path() + .iter() + .take(2) + .enumerate() + .find(|(_, index)| { + !index.is_hardened() + }) + { + return Err(DerivationError::InvalidDerivationPath(i, unhardened_index.inner()).into()) + } + #[cfg(feature = "tracing")] if let Some(target) = guess_target(req.path()) { info!("Deriving path: {target}"); @@ -110,6 +122,9 @@ mod tests { if chain.len() < 2 { continue; } + if chain.iter().take(2).any(|index| !index.is_hardened()) { + continue; + } let req = DerivationRequest::new(DerivationAlgorithm::Secp256k1, &chain); let response: DerivationResponse = keyforkd .ready() diff --git a/crates/daemon/keyforkd/src/test_util.rs b/crates/daemon/keyforkd/src/test_util.rs index 67ad0c8..ba72cf6 100644 --- a/crates/daemon/keyforkd/src/test_util.rs +++ b/crates/daemon/keyforkd/src/test_util.rs @@ -61,7 +61,7 @@ where )); let socket_dir = tempfile::tempdir().expect(bug!("can't create tempdir")); let socket_path = socket_dir.path().join("keyforkd.sock"); - rt.block_on(async move { + let result = rt.block_on(async move { let (tx, mut rx) = tokio::sync::mpsc::channel(1); let server_handle = tokio::spawn({ let socket_path = socket_path.clone(); @@ -87,8 +87,13 @@ where let result = test_handle.await; server_handle.abort(); result - }) - .expect(bug!("runtime could not join all threads")) + }); + if let Err(e) = result { + if e.is_panic() { + std::panic::resume_unwind(e.into_panic()); + } + } + Ok(()) } #[cfg(test)]