pub(crate) mod fast;
#[cfg(feature = "hs-common")]
pub mod hs_ntor;
pub(crate) mod ntor;
pub(crate) mod ntor_v3;
use std::borrow::Borrow;
use crate::Result;
use rand_core::{CryptoRng, RngCore};
use tor_bytes::SecretBuf;
pub(crate) trait ClientHandshake {
type KeyType;
type StateType;
type KeyGen;
type ClientAuxData: ?Sized;
type ServerAuxData;
fn client1<R: RngCore + CryptoRng, M: Borrow<Self::ClientAuxData>>(
rng: &mut R,
key: &Self::KeyType,
client_aux_data: &M,
) -> Result<(Self::StateType, Vec<u8>)>;
fn client2<T: AsRef<[u8]>>(
state: Self::StateType,
msg: T,
) -> Result<(Self::ServerAuxData, Self::KeyGen)>;
}
pub(crate) trait AuxDataReply<H>
where
H: ServerHandshake + ?Sized,
{
fn reply(&mut self, msg: &H::ClientAuxData) -> Option<H::ServerAuxData>;
}
impl<F, H> AuxDataReply<H> for F
where
H: ServerHandshake + ?Sized,
F: FnMut(&H::ClientAuxData) -> Option<H::ServerAuxData>,
{
fn reply(&mut self, msg: &H::ClientAuxData) -> Option<H::ServerAuxData> {
self(msg)
}
}
pub(crate) trait ServerHandshake {
type KeyType;
type KeyGen;
type ClientAuxData: ?Sized;
type ServerAuxData;
#[allow(dead_code)] fn server<R: RngCore + CryptoRng, REPLY: AuxDataReply<Self>, T: AsRef<[u8]>>(
rng: &mut R,
reply_fn: &mut REPLY,
key: &[Self::KeyType],
msg: T,
) -> RelayHandshakeResult<(Self::KeyGen, Vec<u8>)>;
}
#[allow(unreachable_pub)] pub trait KeyGenerator {
fn expand(self, keylen: usize) -> Result<SecretBuf>;
}
pub(crate) struct TapKeyGenerator {
seed: SecretBuf,
}
impl TapKeyGenerator {
pub(crate) fn new(seed: SecretBuf) -> Self {
TapKeyGenerator { seed }
}
}
impl KeyGenerator for TapKeyGenerator {
fn expand(self, keylen: usize) -> Result<SecretBuf> {
use crate::crypto::ll::kdf::{Kdf, LegacyKdf};
LegacyKdf::new(1).derive(&self.seed[..], keylen)
}
}
#[cfg_attr(feature = "bench", visibility::make(pub))]
pub(crate) struct ShakeKeyGenerator {
seed: SecretBuf,
}
impl ShakeKeyGenerator {
#[allow(dead_code)] #[cfg_attr(feature = "bench", visibility::make(pub))]
pub(crate) fn new(seed: SecretBuf) -> Self {
ShakeKeyGenerator { seed }
}
}
impl KeyGenerator for ShakeKeyGenerator {
fn expand(self, keylen: usize) -> Result<SecretBuf> {
use crate::crypto::ll::kdf::{Kdf, ShakeKdf};
ShakeKdf::new().derive(&self.seed[..], keylen)
}
}
#[derive(Clone, Debug, thiserror::Error)]
pub(crate) enum RelayHandshakeError {
#[error("Problem decoding onion handshake")]
Fmt(#[from] tor_bytes::Error),
#[error("Client asked for a key or ID that we don't have")]
MissingKey,
#[error("Bad handshake from client")]
BadClientHandshake,
#[error("Internal error")]
Internal(#[from] tor_error::Bug),
}
pub(crate) type RelayHandshakeResult<T> = std::result::Result<T, RelayHandshakeError>;