1use self::ext::{decl_extension_group, ExtGroup, ExtList};
4
5use super::msg::{self, Body};
6use caret::caret_int;
7use derive_deftly::Deftly;
8use tor_bytes::{EncodeError, EncodeResult, Error as BytesError, Result};
9use tor_bytes::{Readable, Reader, Writeable, Writer};
10use tor_hscrypto::RendCookie;
11use tor_llcrypto::pk::rsa::RsaIdentity;
12use tor_memquota::derive_deftly_template_HasMemoryCost;
13
14pub mod est_intro;
15mod ext;
16pub mod intro_payload;
17pub mod pow;
18
19pub use ext::UnrecognizedExt;
20
21caret_int! {
22 #[derive(Deftly)]
24 #[derive_deftly(HasMemoryCost)]
25 pub struct AuthKeyType(u8) {
26 ED25519_SHA3_256 = 2,
28 }
29}
30
31#[derive(Debug, Clone, Deftly)]
33#[derive_deftly(HasMemoryCost)]
34pub struct EstablishRendezvous {
35 cookie: RendCookie,
38}
39impl EstablishRendezvous {
40 pub fn new(cookie: RendCookie) -> Self {
42 Self { cookie }
43 }
44}
45impl msg::Body for EstablishRendezvous {
46 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
47 let cookie = r.extract()?;
48 r.take_rest();
49 Ok(Self { cookie })
50 }
51 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
52 w.write(&self.cookie)
53 }
54}
55
56#[derive(Debug, Clone, Deftly)]
57#[derive_deftly(HasMemoryCost)]
58pub struct Introduce1(Introduce);
60
61impl msg::Body for Introduce1 {
62 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
63 let (intro, _) = Introduce::decode_from_reader(r)?;
64 Ok(Self(intro))
65 }
66 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
67 self.0.encode_onto(w)
68 }
69}
70
71impl Introduce1 {
72 pub fn new(auth_key_type: AuthKeyType, auth_key: Vec<u8>, encrypted: Vec<u8>) -> Self {
74 Self(Introduce::new(auth_key_type, auth_key, encrypted))
75 }
76}
77
78#[derive(Debug, Clone, Deftly)]
79#[derive_deftly(HasMemoryCost)]
80pub struct Introduce2 {
82 encoded_header: Vec<u8>,
84 msg: Introduce,
86}
87
88impl msg::Body for Introduce2 {
89 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
90 let (msg, header) = Introduce::decode_from_reader(r)?;
91 let encoded_header = header.to_vec();
92
93 Ok(Self {
94 encoded_header,
95 msg,
96 })
97 }
98 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
99 self.msg.encode_onto(w)
100 }
101}
102
103impl Introduce2 {
104 #[cfg(test)] pub fn new(auth_key_type: AuthKeyType, auth_key: Vec<u8>, encrypted: Vec<u8>) -> Self {
111 let msg = Introduce::new(auth_key_type, auth_key, encrypted);
112 let mut encoded_header = Vec::new();
113 msg.header
114 .write_onto(&mut encoded_header)
115 .expect("Generated a header that we could not encode");
116 Self {
117 encoded_header,
118 msg,
119 }
120 }
121
122 pub fn encoded_header(&self) -> &[u8] {
126 &self.encoded_header[..]
127 }
128 pub fn header(&self) -> &IntroduceHeader {
130 &self.msg.header
131 }
132 pub fn encrypted_body(&self) -> &[u8] {
136 &self.msg.encrypted[..]
137 }
138}
139
140caret_int! {
141 #[derive(Ord,PartialOrd)]
143 pub struct IntroduceExtType(u8) {
144 }
145}
146
147decl_extension_group! {
148 #[derive(Debug,Clone,Deftly)]
152 #[derive_deftly(HasMemoryCost)]
153 enum IntroduceExt [ IntroduceExtType ] {
154 }
155}
156
157#[derive(Debug, Clone, Deftly)]
162#[derive_deftly(HasMemoryCost)]
163pub struct IntroduceHeader {
164 auth_key_type: AuthKeyType,
167 auth_key: Vec<u8>,
169 extensions: ExtList<IntroduceExt>,
171}
172
173impl tor_bytes::Readable for IntroduceHeader {
174 fn take_from(r: &mut Reader<'_>) -> Result<Self> {
175 let legacy_key_id: RsaIdentity = r.extract()?;
176 if !legacy_key_id.is_zero() {
177 return Err(BytesError::InvalidMessage(
178 "legacy key id in Introduce1.".into(),
179 ));
180 }
181 let auth_key_type = r.take_u8()?.into();
182 let auth_key_len = r.take_u16()?;
183 let auth_key = r.take(auth_key_len as usize)?.into();
184 let extensions = r.extract()?;
185 Ok(Self {
186 auth_key_type,
187 auth_key,
188 extensions,
189 })
190 }
191}
192
193impl tor_bytes::Writeable for IntroduceHeader {
194 fn write_onto<W: Writer + ?Sized>(&self, w: &mut W) -> EncodeResult<()> {
195 w.write_all(&[0_u8; 20]);
196 w.write_u8(self.auth_key_type.get());
197 w.write_u16(u16::try_from(self.auth_key.len()).map_err(|_| EncodeError::BadLengthValue)?);
198 w.write_all(&self.auth_key[..]);
199 w.write(&self.extensions)?;
200 Ok(())
201 }
202}
203
204#[derive(Debug, Clone, Deftly)]
205#[derive_deftly(HasMemoryCost)]
206struct Introduce {
208 header: IntroduceHeader,
210 encrypted: Vec<u8>,
212}
213
214impl Introduce {
215 fn new(auth_key_type: AuthKeyType, auth_key: Vec<u8>, encrypted: Vec<u8>) -> Self {
217 Self {
218 header: IntroduceHeader {
219 auth_key_type,
220 auth_key,
221 extensions: Default::default(),
222 },
223 encrypted,
224 }
225 }
226 fn decode_from_reader<'a>(r: &mut Reader<'a>) -> Result<(Self, &'a [u8])> {
230 let header_start = r.cursor();
231 let header = r.extract()?;
232 let header_end = r.cursor();
233 let encrypted = r.take_rest().into();
234 Ok((
235 Self { header, encrypted },
236 r.range(header_start, header_end),
237 ))
238 }
239 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
241 w.write(&self.header)?;
242 w.write_all(&self.encrypted[..]);
243 Ok(())
244 }
245}
246
247#[derive(Debug, Clone, Deftly)]
250#[derive_deftly(HasMemoryCost)]
251pub struct Rendezvous1 {
252 cookie: RendCookie,
254 handshake_info: Vec<u8>,
256}
257
258impl Body for Rendezvous1 {
259 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
260 let cookie = r.extract()?;
261 let handshake_info = r.take_rest().into();
262 Ok(Self {
263 cookie,
264 handshake_info,
265 })
266 }
267
268 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
269 w.write(&self.cookie)?;
270 w.write_all(&self.handshake_info[..]);
271 Ok(())
272 }
273}
274
275impl Rendezvous1 {
276 pub fn new(cookie: RendCookie, handshake_info: impl Into<Vec<u8>>) -> Self {
279 Self {
280 cookie,
281 handshake_info: handshake_info.into(),
282 }
283 }
284}
285
286#[derive(Debug, Clone, Deftly)]
289#[derive_deftly(HasMemoryCost)]
290pub struct Rendezvous2 {
291 handshake_info: Vec<u8>,
293}
294
295impl Rendezvous2 {
296 pub fn new(handshake_info: impl Into<Vec<u8>>) -> Self {
298 Self {
299 handshake_info: handshake_info.into(),
300 }
301 }
302
303 pub fn handshake_info(&self) -> &[u8] {
306 &self.handshake_info
307 }
308}
309
310impl From<Rendezvous1> for Rendezvous2 {
311 fn from(value: Rendezvous1) -> Self {
312 Self {
313 handshake_info: value.handshake_info,
314 }
315 }
316}
317
318impl Body for Rendezvous2 {
319 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
320 let handshake_info = r.take_rest().into();
321 Ok(Self { handshake_info })
322 }
323
324 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
325 w.write_all(&self.handshake_info[..]);
326 Ok(())
327 }
328}
329
330caret_int! {
331 #[derive(Ord, PartialOrd)]
333 pub struct IntroEstablishedExtType(u8) {
334 }
335}
336
337decl_extension_group! {
338 #[derive(Debug,Clone,Deftly)]
342 #[derive_deftly(HasMemoryCost)]
343 #[non_exhaustive]
344 pub enum IntroEstablishedExt [ IntroEstablishedExtType ] {
345 }
346}
347
348#[derive(Debug, Clone, Default, Deftly)]
351#[derive_deftly(HasMemoryCost)]
352pub struct IntroEstablished {
353 extensions: ExtList<IntroEstablishedExt>,
355}
356
357impl IntroEstablished {
358 pub fn new() -> Self {
360 Self::default()
361 }
362
363 pub fn iter_extensions(&self) -> impl Iterator<Item = &IntroEstablishedExt> {
365 self.extensions.iter()
366 }
367}
368
369impl Body for IntroEstablished {
370 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
371 let extensions = r.extract()?;
372 Ok(Self { extensions })
373 }
374
375 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
376 w.write(&self.extensions)?;
377 Ok(())
378 }
379}
380
381caret_int! {
382 #[derive(Deftly)]
384 #[derive_deftly(HasMemoryCost)]
385 pub struct IntroduceAckStatus(u16) {
386 SUCCESS = 0x0000,
388 NOT_RECOGNIZED = 0x0001,
391 BAD_MESSAGE_FORMAT = 0x0002,
393 CANT_RELAY = 0x0003,
395 }
396}
397caret_int! {
398 #[derive(Ord, PartialOrd, Deftly)]
400 #[derive_deftly(HasMemoryCost)]
401 pub struct IntroduceAckExtType(u8) {
402 }
403}
404decl_extension_group! {
405 #[derive(Debug,Clone,Deftly)]
409 #[derive_deftly(HasMemoryCost)]
410 enum IntroduceAckExt [ IntroduceAckExtType ] {
411 }
412}
413
414#[derive(Clone, Debug, Deftly)]
417#[derive_deftly(HasMemoryCost)]
418pub struct IntroduceAck {
419 status_code: IntroduceAckStatus,
421 extensions: ExtList<IntroduceAckExt>,
423}
424impl IntroduceAck {
425 pub fn new(status_code: IntroduceAckStatus) -> Self {
427 Self {
428 status_code,
429 extensions: Default::default(),
430 }
431 }
432
433 pub fn status(&self) -> IntroduceAckStatus {
435 self.status_code
436 }
437
438 pub fn success(self) -> std::result::Result<IntroduceAck, IntroduceAckStatus> {
447 if self.status() == IntroduceAckStatus::SUCCESS {
448 Ok(self)
449 } else {
450 Err(self.status())
451 }
452 }
453}
454
455impl Body for IntroduceAck {
456 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
457 let status_code = r.take_u16()?.into();
458 let extensions = r.extract()?;
459 Ok(IntroduceAck {
460 status_code,
461 extensions,
462 })
463 }
464
465 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
466 w.write_u16(self.status_code.into());
467 w.write(&self.extensions)?;
468 Ok(())
469 }
470}
471
472impl tor_error::HasRetryTime for IntroduceAckStatus {
477 fn retry_time(&self) -> tor_error::RetryTime {
478 use tor_error::RetryTime as RT;
479 use IntroduceAckStatus as S;
480 match *self {
481 S::SUCCESS => RT::Never, S::NOT_RECOGNIZED => RT::AfterWaiting,
483 S::BAD_MESSAGE_FORMAT => RT::Never,
484 S::CANT_RELAY => RT::AfterWaiting,
485 _ => RT::AfterWaiting, }
487 }
488}
489
490super::msg::empty_body! {
491 pub struct RendezvousEstablished {}
493}