From b9a848a7acb1761a19764f4058f3924f55d04a90 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 17 May 2023 17:04:46 -0400 Subject: [PATCH] tor-proto: Code to construct crypto layers for virtual hops. This is fairly straightforward, thanks to our existing design work on this code. --- crates/tor-proto/src/circuit.rs | 2 ++ crates/tor-proto/src/circuit/handshake.rs | 34 ++++++++++++++++++++++- crates/tor-proto/src/crypto/cell.rs | 7 +++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/crates/tor-proto/src/circuit.rs b/crates/tor-proto/src/circuit.rs index f54e36c65..29779f834 100644 --- a/crates/tor-proto/src/circuit.rs +++ b/crates/tor-proto/src/circuit.rs @@ -410,6 +410,8 @@ impl ClientCirc { role: handshake::HandshakeRole, seed: impl handshake::KeyGenerator, ) -> Result<()> { + let (outbound, inbound) = protocol.construct_layers(role, seed)?; + todo!() // TODO hs implement } diff --git a/crates/tor-proto/src/circuit/handshake.rs b/crates/tor-proto/src/circuit/handshake.rs index 2a261ef3d..1c5c9491a 100644 --- a/crates/tor-proto/src/circuit/handshake.rs +++ b/crates/tor-proto/src/circuit/handshake.rs @@ -11,6 +11,11 @@ // that can wait IMO until we have a second circuit creation mechanism for use // with ntor. +use crate::crypto::cell::{ + ClientLayer, CryptInit, InboundClientLayer, OutboundClientLayer, Tor1Hsv3RelayCrypto, +}; +use crate::Result; + pub use crate::crypto::handshake::hs_ntor; pub use crate::crypto::handshake::KeyGenerator; @@ -27,7 +32,7 @@ pub enum RelayProtocol { } /// What role we are playing in a handshake. -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] #[non_exhaustive] pub enum HandshakeRole { /// We are the party initiating the handshake. @@ -35,3 +40,30 @@ pub enum HandshakeRole { /// We are the party responding to the handshake. Responder, } + +impl RelayProtocol { + /// Construct the cell-crypto layers that are needed for a given set of + /// circuit hop parameters. + pub(crate) fn construct_layers( + self, + role: HandshakeRole, + keygen: impl KeyGenerator, + ) -> Result<( + Box, + Box, + )> { + match self { + RelayProtocol::HsV3 => { + let seed_needed = Tor1Hsv3RelayCrypto::seed_len(); + let seed = keygen.expand(seed_needed)?; + let layer = Tor1Hsv3RelayCrypto::initialize(&seed)?; + let (fwd, back) = layer.split(); + let (fwd, back) = match role { + HandshakeRole::Initiator => (fwd, back), + HandshakeRole::Responder => (back, fwd), + }; + Ok((Box::new(fwd), Box::new(back))) + } + } + } +} diff --git a/crates/tor-proto/src/crypto/cell.rs b/crates/tor-proto/src/crypto/cell.rs index 82764685c..e77340f7e 100644 --- a/crates/tor-proto/src/crypto/cell.rs +++ b/crates/tor-proto/src/crypto/cell.rs @@ -211,6 +211,13 @@ impl InboundClientCrypt { pub(crate) type Tor1RelayCrypto = tor1::CryptStatePair; +/// Standard Tor relay crypto, as instantiated for the HSv3 protocol. +/// +/// (The use of SHA3 is ridiculously overkill.) +#[cfg(feature = "hs-common")] +pub(crate) type Tor1Hsv3RelayCrypto = + tor1::CryptStatePair; + /// Incomplete untested implementation of Tor's current cell crypto. pub(crate) mod tor1 { use super::*;