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