Merge branch 'hs-cells' into 'main'

Implement ESTABLISH_INTRO relay cell

See merge request tpo/core/arti!626
This commit is contained in:
eta 2022-07-22 13:42:50 +00:00
commit 274bfb94c7
4 changed files with 89 additions and 1 deletions

View File

@ -16,6 +16,7 @@ default = []
experimental = ["experimental-udp"]
# Enable experimental UDP support.
experimental-udp = []
onion-service = []
# Enable testing only API
testing = ["experimental-udp"]

View File

@ -11,6 +11,8 @@ use rand::{CryptoRng, Rng};
pub mod extend;
pub mod msg;
#[cfg(feature = "onion-service")]
pub mod onion_service;
#[cfg(feature = "experimental-udp")]
pub mod udp;

View File

@ -17,6 +17,8 @@ use tor_llcrypto::pk::rsa::RsaIdentity;
use bitflags::bitflags;
#[cfg(feature = "onion-service")]
use super::onion_service;
#[cfg(feature = "experimental-udp")]
use super::udp;
@ -63,10 +65,13 @@ pub enum RelayMsg {
/// UDP stream data
#[cfg(feature = "experimental-udp")]
Datagram(udp::Datagram),
// No hs for now.
#[cfg(feature = "onion-service")]
/// Establish Introduction
EstablishIntro(onion_service::EstablishIntro),
/// An unrecognized command.
Unrecognized(Unrecognized),
// No hs for now.
}
/// Internal: traits in common different cell bodies.
@ -111,6 +116,8 @@ impl RelayMsg {
ConnectedUdp(_) => RelayCmd::CONNECTED_UDP,
#[cfg(feature = "experimental-udp")]
Datagram(_) => RelayCmd::DATAGRAM,
#[cfg(feature = "onion-service")]
EstablishIntro(_) => RelayCmd::ESTABLISH_INTRO,
Unrecognized(u) => u.cmd(),
}
}
@ -140,6 +147,10 @@ impl RelayMsg {
}
#[cfg(feature = "experimental-udp")]
RelayCmd::DATAGRAM => RelayMsg::Datagram(udp::Datagram::decode_from_reader(r)?),
#[cfg(feature = "onion-service")]
RelayCmd::ESTABLISH_INTRO => {
RelayMsg::EstablishIntro(onion_service::EstablishIntro::decode_from_reader(r)?)
}
_ => RelayMsg::Unrecognized(Unrecognized::decode_with_cmd(c, r)?),
})
}
@ -168,6 +179,8 @@ impl RelayMsg {
ConnectedUdp(b) => b.encode_onto(w),
#[cfg(feature = "experimental-udp")]
Datagram(b) => b.encode_onto(w),
#[cfg(feature = "onion-service")]
EstablishIntro(b) => b.encode_onto(w),
Unrecognized(b) => b.encode_onto(w),
}
}

View File

@ -0,0 +1,72 @@
//! Encoding and decoding for relay messages
//!
//! Relay messages are sent along circuits, inside RELAY or RELAY_EARLY
//! cells.
use super::msg;
use caret::caret_int;
use tor_bytes::{Error, Result};
use tor_bytes::{Reader, Writer};
caret_int! {
/// The type of the introduction point auth key
pub struct AuthKeyType(u8) {
/// Ed25519; SHA3-256
ED25519_SHA3_256 = 2,
}
}
/// A hidden services establishes a new introduction point,
/// by sending an EstablishIntro message.
#[derive(Debug, Clone)]
pub struct EstablishIntro {
/// Introduction point auth key type and the type of
/// the MAC used in `handshake_auth`.
auth_key_type: AuthKeyType,
/// The public introduction point auth key.
auth_key: Vec<u8>,
/// the MAC of all earlier fields in the cell.
handshake_auth: [u8; 32],
/// A signature using `auth_key` of all contents
/// of the cell.
sig: Vec<u8>,
}
impl msg::Body for EstablishIntro {
fn into_message(self) -> msg::RelayMsg {
msg::RelayMsg::EstablishIntro(self)
}
fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
let auth_key_type = r.take_u8()?.into();
let auth_key_len = r.take_u16()?;
let auth_key = r.take(auth_key_len as usize)?.into();
if r.take_u8()? != 0 {
// TODO: Support ESTABLISH_INTRO extensions
return Err(Error::BadMessage(
"ESTABLISH_INTRO extension not supported.",
));
}
let handshake_auth = r.extract()?;
let sig_len = r.take_u16()?;
let sig = r.take(sig_len as usize)?.into();
Ok(EstablishIntro {
auth_key_type,
auth_key,
handshake_auth,
sig,
})
}
fn encode_onto(self, w: &mut Vec<u8>) {
w.write_u8(self.auth_key_type.get());
// TODO: This should fail when auth_key is too long,
// but `as` truncates the value silently. This depends on
// `tor_bytes::Writer::write` to return a `Result`.
w.write_u16(self.auth_key.len() as u16);
w.write_all(&self.auth_key[..]);
// N_EXTENTIONS is zero for now
w.write_u8(0_u8);
w.write_all(&self.handshake_auth[..]);
w.write_u16(self.sig.len() as u16);
w.write_all(&self.sig[..]);
}
}