From 4ec9ec92bc7b3d6131051f0c32a10b2a2b385fb0 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Fri, 24 Feb 2023 12:19:45 +0000 Subject: [PATCH] HS secret keys: Move aggregate/config to tor-hsclient Provide a more cookied "secret keys for use to connecting to a particular HS" type, with a builder. This wants to use config stuff, so oughtn't to be in tor-*crypto. The individual types remain there. --- Cargo.lock | 1 + crates/tor-hsclient/Cargo.toml | 1 + crates/tor-hsclient/src/keys.rs | 79 +++++++++++++++++++++++++++++++++ crates/tor-hscrypto/src/pk.rs | 11 ----- 4 files changed, 81 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 01e4ce2f3..cb3c51b69 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3961,6 +3961,7 @@ dependencies = [ "rand_core 0.6.4", "thiserror", "tor-circmgr", + "tor-config", "tor-hscrypto", "tor-llcrypto", "tor-netdir", diff --git a/crates/tor-hsclient/Cargo.toml b/crates/tor-hsclient/Cargo.toml index ddeb4efc6..2c303d4cf 100644 --- a/crates/tor-hsclient/Cargo.toml +++ b/crates/tor-hsclient/Cargo.toml @@ -21,6 +21,7 @@ async-trait = "0.1.2" rand_core = "0.6.2" thiserror = "1" tor-circmgr = { version = "0.7.2", path = "../tor-circmgr", features = ["hs-client"] } +tor-config = { path = "../tor-config", version = "0.7.1" } tor-hscrypto = { version = "0.1.1", path = "../tor-hscrypto" } tor-llcrypto = { version = "0.4.2", path = "../tor-llcrypto" } tor-netdir = { version = "0.8.0", path = "../tor-netdir" } diff --git a/crates/tor-hsclient/src/keys.rs b/crates/tor-hsclient/src/keys.rs index 8d91d833e..c712b7e22 100644 --- a/crates/tor-hsclient/src/keys.rs +++ b/crates/tor-hsclient/src/keys.rs @@ -5,3 +5,82 @@ // the hs connector for each connection. Otherwise there would have to be an // HsKeyProvider trait here, and error handling gets complicated. +use std::hash::{Hash, Hasher}; +use std::sync::Arc; + +use tor_hscrypto::pk::{HsClientDescEncSecretKey, HsClientIntroAuthSecretKey}; + +/// Keys to use when connecting to a specific onion service. +/// +/// This is constructed with a `Builder`: +/// use `ClientSecretKeysBuilder::default()`, +/// optionally call setters, and then call `build()`. +/// +/// For client connections to share circuits and streams, +/// call `build` only once. +/// Different calls to `build` yield `ClientSecretKeys` values +/// which won't share circuits, streams, or authentication +/// +/// Conversely, `Clone`s of a `ClientSecretKeys` *can* share circuits. +// +// TODO HS some way to read these from files or something! +#[derive(Clone)] +pub struct HsClientSecretKeys { + /// The actual keys + /// + /// This is compared and hashed by the Arc pointer value. + /// We don't want to implement key comparison by comparing secret key values. + keys: Arc, +} + +impl PartialEq for HsClientSecretKeys { + fn eq(&self, other: &Self) -> bool { + Arc::ptr_eq(&self.keys, &other.keys) + } +} +impl Eq for HsClientSecretKeys {} +impl Hash for HsClientSecretKeys { + fn hash(&self, state: &mut H) { + Arc::as_ptr(&self.keys).hash(state); + } +} + +/// Client secret key values +/// +/// Skip the whole builder pattern derivation, etc. - the types are just the same +type ClientSecretKeyValues = HsClientSecretKeysBuilder; + +/// Builder for `HsClientSecretKeys` +#[derive(Default, Debug)] +pub struct HsClientSecretKeysBuilder { + /// Possibly, a key that is used to decrypt a descriptor. + ks_hsc_desc_enc: Option, + + /// Possibly, a key that is used to authenticate while introducing. + ks_hsc_intro_auth: Option, +} + +// TODO derive these setters +// +// TODO HS is this what we want for an API? We need *some* API. +// This is a bit like config but we probably don't want to +// feed secret key material through config-rs, etc. +impl HsClientSecretKeysBuilder { + /// Provide a descriptor decryption key + pub fn ks_hsc_desc_enc(&mut self, ks: HsClientDescEncSecretKey) -> &mut Self { + self.ks_hsc_desc_enc = Some(ks); + self + } + /// Provide an introduction authentication key + pub fn ks_hsc_intro_auth(&mut self, ks: HsClientIntroAuthSecretKey) -> &mut Self { + self.ks_hsc_intro_auth = Some(ks); + self + } + + /// Convert these + pub fn build(self) -> Result { + Ok(HsClientSecretKeys { + keys: Arc::new(self), + }) + } +} diff --git a/crates/tor-hscrypto/src/pk.rs b/crates/tor-hscrypto/src/pk.rs index 5cd66ece8..c5a171a47 100644 --- a/crates/tor-hscrypto/src/pk.rs +++ b/crates/tor-hscrypto/src/pk.rs @@ -293,17 +293,6 @@ define_pk_keypair! { pub struct HsSvcDescEncKey(curve25519::PublicKey) / HsSvcDescEncSecretKey(curve25519::StaticSecret); } -/// A set of keys to tell the client to use when connecting to an onion service. -// -// TODO hs -pub struct ClientSecretKeys { - /// Possibly, a key that is used to decrypt a descriptor. - desc_auth: Option, - /// Possibly, a key that is used to authenticate while - /// introducing. - intro_auth: Option, -} - #[cfg(test)] mod test { // @@ begin test lint list maintained by maint/add_warning @@