1use super::{BoxedCellBody, CELL_DATA_LEN, ChanCmd, RawCellBody};
4use std::net::{IpAddr, Ipv4Addr};
5
6use tor_basic_utils::skip_fmt;
7use tor_bytes::{self, EncodeError, EncodeResult, Error, Readable, Reader, Result, Writer};
8use tor_memquota::derive_deftly_template_HasMemoryCost;
9use tor_units::IntegerMilliseconds;
10
11use caret::caret_int;
12use derive_deftly::Deftly;
13use educe::Educe;
14
15pub trait Body: Readable {
17 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
19 r.extract()
20 }
21 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()>;
26}
27
28crate::restrict::restricted_msg! {
29#[derive(Clone, Debug, Deftly)]
35#[derive_deftly(HasMemoryCost)]
36#[non_exhaustive]
37@omit_from "avoid_conflict_with_a_blanket_implementation"
38pub enum AnyChanMsg : ChanMsg {
39 Padding,
41 Vpadding,
43 Create,
45 CreateFast,
47 Create2,
49 Created,
51 CreatedFast,
53 Created2,
55 Relay,
57 RelayEarly,
59 Destroy,
61 Netinfo,
63 Versions,
66 PaddingNegotiate,
68 Certs,
71 AuthChallenge,
74 Authenticate,
77 _ =>
78 Unrecognized,
80}
81}
82
83#[derive(Clone, Debug, Default, Deftly)]
91#[derive_deftly(HasMemoryCost)]
92#[non_exhaustive]
93pub struct Padding {}
94impl Padding {
95 pub fn new() -> Self {
97 Padding {}
98 }
99}
100impl Body for Padding {
101 fn encode_onto<W: Writer + ?Sized>(self, _w: &mut W) -> EncodeResult<()> {
102 Ok(())
103 }
104}
105impl Readable for Padding {
106 fn take_from(_b: &mut Reader<'_>) -> Result<Self> {
107 Ok(Padding {})
108 }
109}
110
111#[derive(Clone, Debug, Deftly)]
115#[derive_deftly(HasMemoryCost)]
116pub struct Vpadding {
117 len: u16,
119}
120impl Vpadding {
121 pub fn new(len: u16) -> Self {
123 Vpadding { len }
124 }
125}
126impl Body for Vpadding {
127 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
128 w.write_zeros(self.len as usize);
129 Ok(())
130 }
131}
132impl Readable for Vpadding {
133 fn take_from(b: &mut Reader<'_>) -> Result<Self> {
134 if b.remaining() > u16::MAX as usize {
135 return Err(Error::InvalidMessage(
136 "Too many bytes in VPADDING cell".into(),
137 ));
138 }
139 Ok(Vpadding {
140 len: b.remaining() as u16,
141 })
142 }
143}
144
145macro_rules! fixed_len_handshake {
148 {
149 $(#[$meta:meta])*
150 $name:ident , $cmd:ident, $len:ident
151 } => {
152 $(#[$meta])*
153 #[derive(Clone,Debug,Deftly)]
154 #[derive_deftly(HasMemoryCost)]
155 pub struct $name {
156 handshake: Vec<u8>
157 }
158 impl $name {
159 pub fn new<B>(handshake: B) -> Self
161 where B: Into<Vec<u8>>
162 {
163 let handshake = handshake.into();
164 $name { handshake }
165 }
166 }
167 impl Body for $name {
168 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
169 w.write_all(&self.handshake[..]);
170 Ok(())
171 }
172 }
173 impl Readable for $name {
174 fn take_from(b: &mut Reader<'_>) -> Result<Self> {
175 Ok($name {
176 handshake: b.take($len)?.into(),
177 })
178 }
179 }
180 }
181}
182
183pub(crate) const TAP_C_HANDSHAKE_LEN: usize = 128 + 16 + 42;
185pub(crate) const TAP_S_HANDSHAKE_LEN: usize = 128 + 20;
187
188const FAST_C_HANDSHAKE_LEN: usize = 20;
190const FAST_S_HANDSHAKE_LEN: usize = 20 + 20;
192
193fixed_len_handshake! {
194 Create, CREATE, TAP_C_HANDSHAKE_LEN
203}
204fixed_len_handshake! {
205 Created, CREATED, TAP_S_HANDSHAKE_LEN
210}
211fixed_len_handshake! {
212 CreateFast, CREATE_FAST, FAST_C_HANDSHAKE_LEN
224}
225impl CreateFast {
226 pub fn handshake(&self) -> &[u8] {
228 &self.handshake
229 }
230}
231fixed_len_handshake! {
232 CreatedFast, CREATED_FAST, FAST_S_HANDSHAKE_LEN
237}
238impl CreatedFast {
239 pub fn into_handshake(self) -> Vec<u8> {
241 self.handshake
242 }
243}
244
245caret_int! {
246 #[derive(Deftly)]
249 #[derive_deftly(HasMemoryCost)]
250 pub struct HandshakeType(u16) {
251 TAP = 0,
253
254 NTOR = 2,
258 NTOR_V3 = 3,
260 }
261}
262
263#[derive(Clone, Debug, Deftly)]
272#[derive_deftly(HasMemoryCost)]
273pub struct Create2 {
274 handshake_type: HandshakeType,
276 handshake: Vec<u8>,
278}
279impl Body for Create2 {
280 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
281 w.write_u16(self.handshake_type.into());
282 let handshake_len = self
283 .handshake
284 .len()
285 .try_into()
286 .map_err(|_| EncodeError::BadLengthValue)?;
287 w.write_u16(handshake_len);
288 w.write_all(&self.handshake[..]);
289 Ok(())
290 }
291}
292impl Readable for Create2 {
293 fn take_from(b: &mut Reader<'_>) -> Result<Self> {
294 let handshake_type = HandshakeType::from(b.take_u16()?);
295 let hlen = b.take_u16()?;
296 let handshake = b.take(hlen as usize)?.into();
297 Ok(Create2 {
298 handshake_type,
299 handshake,
300 })
301 }
302}
303impl Create2 {
304 pub fn new<B>(handshake_type: HandshakeType, handshake: B) -> Self
306 where
307 B: Into<Vec<u8>>,
308 {
309 let handshake = handshake.into();
310 Create2 {
311 handshake_type,
312 handshake,
313 }
314 }
315
316 pub fn handshake_type(&self) -> HandshakeType {
318 self.handshake_type
319 }
320
321 pub fn body(&self) -> &[u8] {
323 &self.handshake[..]
324 }
325}
326
327#[derive(Clone, Debug, Deftly)]
332#[derive_deftly(HasMemoryCost)]
333pub struct Created2 {
334 handshake: Vec<u8>,
336}
337impl Created2 {
338 pub fn new<B>(handshake: B) -> Self
340 where
341 B: Into<Vec<u8>>,
342 {
343 let handshake = handshake.into();
344 Created2 { handshake }
345 }
346 pub fn into_body(self) -> Vec<u8> {
348 self.handshake
349 }
350}
351impl Body for Created2 {
352 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
353 let handshake_len = self
354 .handshake
355 .len()
356 .try_into()
357 .map_err(|_| EncodeError::BadLengthValue)?;
358 w.write_u16(handshake_len);
359 w.write_all(&self.handshake[..]);
360 Ok(())
361 }
362}
363impl Readable for Created2 {
364 fn take_from(b: &mut Reader<'_>) -> Result<Self> {
365 let hlen = b.take_u16()?;
366 let handshake = b.take(hlen as usize)?.into();
367 Ok(Created2 { handshake })
368 }
369}
370
371#[derive(Clone, Educe, derive_more::From, Deftly)]
382#[derive_deftly(HasMemoryCost)]
383#[educe(Debug)]
384pub struct Relay {
385 #[educe(Debug(method = "skip_fmt"))]
393 body: BoxedCellBody,
394}
395impl Relay {
396 pub fn new<P>(body: P) -> Self
398 where
399 P: AsRef<[u8]>,
400 {
401 let body = body.as_ref();
402 let mut r = [0_u8; CELL_DATA_LEN];
403 r[..body.len()].copy_from_slice(body);
406 Relay { body: Box::new(r) }
407 }
408 pub fn from_raw(body: RawCellBody) -> Self {
410 Relay {
411 body: Box::new(body),
412 }
413 }
414 pub fn into_relay_body(self) -> BoxedCellBody {
417 self.body
418 }
419 pub fn into_early(self) -> AnyChanMsg {
421 AnyChanMsg::RelayEarly(RelayEarly(self))
422 }
423}
424impl Body for Relay {
425 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
426 w.write_all(&self.body[..]);
427 Ok(())
428 }
429}
430impl Readable for Relay {
431 fn take_from(b: &mut Reader<'_>) -> Result<Self> {
432 let mut body = Box::new([0_u8; CELL_DATA_LEN]);
433 body.copy_from_slice(b.take(CELL_DATA_LEN)?);
434 Ok(Relay { body })
435 }
436}
437
438#[derive(Clone, Debug, derive_more::Deref, derive_more::From, Deftly)]
442#[derive_deftly(HasMemoryCost)]
443pub struct RelayEarly(Relay);
444impl Readable for RelayEarly {
445 fn take_from(r: &mut Reader<'_>) -> Result<Self> {
446 Ok(RelayEarly(Relay::take_from(r)?))
447 }
448}
449impl Body for RelayEarly {
450 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
451 self.0.encode_onto(w)
452 }
453}
454impl RelayEarly {
455 pub fn into_relay_body(self) -> BoxedCellBody {
461 self.0.body
462 }
463}
464
465#[derive(Clone, Debug, Deftly)]
471#[derive_deftly(HasMemoryCost)]
472pub struct Destroy {
473 reason: DestroyReason,
475}
476impl Destroy {
477 pub fn new(reason: DestroyReason) -> Self {
486 Destroy { reason }
487 }
488 pub fn reason(&self) -> DestroyReason {
490 self.reason
491 }
492}
493impl Body for Destroy {
494 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
495 w.write_u8(self.reason.into());
496 Ok(())
497 }
498}
499impl Readable for Destroy {
500 fn take_from(r: &mut Reader<'_>) -> Result<Self> {
501 let reason = r.take_u8()?.into();
502 Ok(Destroy { reason })
503 }
504}
505
506caret_int! {
507 #[derive(Deftly)]
509 #[derive_deftly(HasMemoryCost)]
510 pub struct DestroyReason(u8) {
511 NONE = 0,
515 PROTOCOL = 1,
517 INTERNAL = 2,
519 REQUESTED = 3,
521 HIBERNATING = 4,
523 RESOURCELIMIT = 5,
525 CONNECTFAILED = 6,
527 OR_IDENTITY = 7,
529 CHANNEL_CLOSED = 8,
531 FINISHED = 9,
533 TIMEOUT = 10,
535 DESTROYED = 11,
537 NOSUCHSERVICE = 12
539 }
540}
541
542impl DestroyReason {
543 pub fn human_str(&self) -> &'static str {
545 match *self {
546 DestroyReason::NONE => "No reason",
547 DestroyReason::PROTOCOL => "Protocol violation",
548 DestroyReason::INTERNAL => "Internal error",
549 DestroyReason::REQUESTED => "Client sent a TRUNCATE command",
550 DestroyReason::HIBERNATING => "Relay is hibernating and not accepting requests",
551 DestroyReason::RESOURCELIMIT => "Relay ran out of resources",
552 DestroyReason::CONNECTFAILED => "Couldn't connect to relay",
553 DestroyReason::OR_IDENTITY => "Connected to relay with different OR identity",
554 DestroyReason::CHANNEL_CLOSED => "The OR channels carrying this circuit died",
555 DestroyReason::FINISHED => "Circuit expired for being too dirty or old",
556 DestroyReason::TIMEOUT => "Circuit construction took too long",
557 DestroyReason::DESTROYED => "Circuit was destroyed without client truncate",
558 DestroyReason::NOSUCHSERVICE => "No such onion service",
559 _ => "Unrecognized reason",
560 }
561 }
562}
563
564#[derive(Clone, Debug, Deftly)]
572#[derive_deftly(HasMemoryCost)]
573pub struct Netinfo {
574 timestamp: u32,
580 their_addr: Option<IpAddr>,
582 my_addr: Vec<IpAddr>,
584}
585fn enc_one_netinfo_addr<W: Writer + ?Sized>(w: &mut W, addr: &IpAddr) {
587 match addr {
588 IpAddr::V4(ipv4) => {
589 w.write_u8(0x04); w.write_u8(4); w.write_all(&ipv4.octets()[..]);
592 }
593 IpAddr::V6(ipv6) => {
594 w.write_u8(0x06); w.write_u8(16); w.write_all(&ipv6.octets()[..]);
597 }
598 }
599}
600fn take_one_netinfo_addr(r: &mut Reader<'_>) -> Result<Option<IpAddr>> {
602 let atype = r.take_u8()?;
603 let alen = r.take_u8()?;
604 let abody = r.take(alen as usize)?;
605 match (atype, alen) {
606 (0x04, 4) => {
607 let bytes = [abody[0], abody[1], abody[2], abody[3]];
608 Ok(Some(IpAddr::V4(bytes.into())))
609 }
610 (0x06, 16) => {
611 let mut bytes = [0_u8; 16];
613 bytes.copy_from_slice(abody);
614 Ok(Some(IpAddr::V6(bytes.into())))
615 }
616 (_, _) => Ok(None),
617 }
618}
619impl Netinfo {
620 pub fn from_client(their_addr: Option<IpAddr>) -> Self {
622 Netinfo {
623 timestamp: 0, their_addr,
625 my_addr: Vec::new(), }
627 }
628 pub fn from_relay<V>(timestamp: u32, their_addr: Option<IpAddr>, my_addrs: V) -> Self
630 where
631 V: Into<Vec<IpAddr>>,
632 {
633 let my_addr = my_addrs.into();
634 Netinfo {
635 timestamp,
636 their_addr,
637 my_addr,
638 }
639 }
640 pub fn timestamp(&self) -> Option<std::time::SystemTime> {
642 use std::time::{Duration, SystemTime};
643 if self.timestamp == 0 {
644 None
645 } else {
646 Some(SystemTime::UNIX_EPOCH + Duration::from_secs(self.timestamp.into()))
647 }
648 }
649
650 pub fn their_addr(&self) -> Option<&IpAddr> {
654 self.their_addr.as_ref()
655 }
656
657 pub fn my_addrs(&self) -> &[IpAddr] {
659 &self.my_addr
660 }
661}
662impl Body for Netinfo {
663 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
664 w.write_u32(self.timestamp);
665 let their_addr = self
666 .their_addr
667 .unwrap_or_else(|| Ipv4Addr::UNSPECIFIED.into());
668 enc_one_netinfo_addr(w, &their_addr);
669 let n_addrs: u8 = self
670 .my_addr
671 .len()
672 .try_into()
673 .map_err(|_| EncodeError::BadLengthValue)?;
674 w.write_u8(n_addrs);
675 for addr in &self.my_addr {
676 enc_one_netinfo_addr(w, addr);
677 }
678 Ok(())
679 }
680}
681impl Readable for Netinfo {
682 fn take_from(r: &mut Reader<'_>) -> Result<Self> {
683 let timestamp = r.take_u32()?;
684 let their_addr = take_one_netinfo_addr(r)?.filter(|a| !a.is_unspecified());
685 let my_n_addrs = r.take_u8()?;
686 let mut my_addr = Vec::with_capacity(my_n_addrs as usize);
687 for _ in 0..my_n_addrs {
688 if let Some(a) = take_one_netinfo_addr(r)? {
689 my_addr.push(a);
690 }
691 }
692 Ok(Netinfo {
693 timestamp,
694 their_addr,
695 my_addr,
696 })
697 }
698}
699
700#[derive(Clone, Debug, Deftly)]
710#[derive_deftly(HasMemoryCost)]
711pub struct Versions {
712 versions: Vec<u16>,
714}
715impl Versions {
716 pub fn new<B>(vs: B) -> crate::Result<Self>
721 where
722 B: Into<Vec<u16>>,
723 {
724 let versions = vs.into();
725 if versions.len() < (u16::MAX / 2) as usize {
726 Ok(Self { versions })
727 } else {
728 Err(crate::Error::CantEncode("Too many versions"))
729 }
730 }
731 pub fn encode_for_handshake(self) -> EncodeResult<Vec<u8>> {
737 let mut v = Vec::new();
738 v.write_u16(0); v.write_u8(ChanCmd::VERSIONS.into());
740 v.write_u16((self.versions.len() * 2) as u16); self.encode_onto(&mut v)?;
742 Ok(v)
743 }
744 pub fn best_shared_link_protocol(&self, my_protos: &[u16]) -> Option<u16> {
747 let p = my_protos
750 .iter()
751 .filter(|p| self.versions.contains(p))
752 .fold(0_u16, |a, b| u16::max(a, *b));
753 if p == 0 { None } else { Some(p) }
754 }
755}
756impl Body for Versions {
757 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
758 for v in &self.versions {
759 w.write_u16(*v);
760 }
761 Ok(())
762 }
763}
764impl Readable for Versions {
765 fn take_from(r: &mut Reader<'_>) -> Result<Self> {
766 let mut versions = Vec::new();
767 while r.remaining() > 0 {
768 versions.push(r.take_u16()?);
769 }
770 Ok(Versions { versions })
771 }
772}
773
774caret_int! {
775 #[derive(Deftly)]
778 #[derive_deftly(HasMemoryCost)]
779 pub struct PaddingNegotiateCmd(u8) {
780 START = 2,
782
783 STOP = 1,
785 }
786}
787
788#[derive(Clone, Debug, Eq, PartialEq, Deftly)]
800#[derive_deftly(HasMemoryCost)]
801pub struct PaddingNegotiate {
802 command: PaddingNegotiateCmd,
804 ito_low_ms: u16,
807 ito_high_ms: u16,
810}
811impl PaddingNegotiate {
812 pub fn start_default() -> Self {
816 Self {
818 command: PaddingNegotiateCmd::START,
819 ito_low_ms: 0,
820 ito_high_ms: 0,
821 }
822 }
823
824 pub fn start(ito_low: IntegerMilliseconds<u16>, ito_high: IntegerMilliseconds<u16>) -> Self {
826 Self {
828 command: PaddingNegotiateCmd::START,
829 ito_low_ms: ito_low.as_millis(),
830 ito_high_ms: ito_high.as_millis(),
831 }
832 }
833
834 pub fn stop() -> Self {
836 Self {
838 command: PaddingNegotiateCmd::STOP,
839 ito_low_ms: 0,
840 ito_high_ms: 0,
841 }
842 }
843
844 #[cfg(feature = "testing")]
848 pub fn from_raw(command: PaddingNegotiateCmd, ito_low_ms: u16, ito_high_ms: u16) -> Self {
849 PaddingNegotiate {
850 command,
851 ito_low_ms,
852 ito_high_ms,
853 }
854 }
855}
856impl Default for PaddingNegotiate {
857 fn default() -> Self {
858 Self::start_default()
859 }
860}
861
862impl Body for PaddingNegotiate {
863 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
864 w.write_u8(0); w.write_u8(self.command.get());
866 w.write_u16(self.ito_low_ms);
867 w.write_u16(self.ito_high_ms);
868 Ok(())
869 }
870}
871impl Readable for PaddingNegotiate {
872 fn take_from(r: &mut Reader<'_>) -> Result<Self> {
873 let v = r.take_u8()?;
874 if v != 0 {
875 return Err(Error::InvalidMessage(
876 "Unrecognized padding negotiation version".into(),
877 ));
878 }
879 let command = r.take_u8()?.into();
880 let ito_low_ms = r.take_u16()?;
881 let ito_high_ms = r.take_u16()?;
882 Ok(PaddingNegotiate {
883 command,
884 ito_low_ms,
885 ito_high_ms,
886 })
887 }
888}
889
890#[derive(Clone, Debug, Deftly)]
895#[derive_deftly(HasMemoryCost)]
896struct TorCert {
897 certtype: u8,
899 cert: Vec<u8>,
901}
902fn enc_one_tor_cert<W: Writer + ?Sized>(w: &mut W, c: &TorCert) -> EncodeResult<()> {
904 w.write_u8(c.certtype);
905 let cert_len: u16 = c
906 .cert
907 .len()
908 .try_into()
909 .map_err(|_| EncodeError::BadLengthValue)?;
910 w.write_u16(cert_len);
911 w.write_all(&c.cert[..]);
912 Ok(())
913}
914fn take_one_tor_cert(r: &mut Reader<'_>) -> Result<TorCert> {
916 let certtype = r.take_u8()?;
917 let certlen = r.take_u16()?;
918 let cert = r.take(certlen as usize)?;
919 Ok(TorCert {
920 certtype,
921 cert: cert.into(),
922 })
923}
924#[derive(Clone, Debug, Deftly)]
934#[derive_deftly(HasMemoryCost)]
935pub struct Certs {
936 certs: Vec<TorCert>,
938}
939impl Certs {
940 pub fn new_empty() -> Self {
942 Certs { certs: Vec::new() }
943 }
944 pub fn push_cert_body<B>(&mut self, certtype: tor_cert::CertType, cert: B)
948 where
949 B: Into<Vec<u8>>,
950 {
951 let certtype = certtype.into();
952 let cert = cert.into();
953 self.certs.push(TorCert { certtype, cert });
954 }
955
956 #[cfg(feature = "relay")]
959 pub fn push_cert<C>(&mut self, cert: &C)
960 where
961 C: tor_cert::EncodedCert,
962 {
963 self.push_cert_body(cert.cert_type(), cert.encoded());
964 }
965
966 pub fn cert_body(&self, tp: tor_cert::CertType) -> Option<&[u8]> {
968 let tp: u8 = tp.into();
969 self.certs
970 .iter()
971 .find(|c| c.certtype == tp)
972 .map(|c| &c.cert[..])
973 }
974
975 pub fn parse_ed_cert(&self, tp: tor_cert::CertType) -> crate::Result<tor_cert::KeyUnknownCert> {
978 let body = self
979 .cert_body(tp)
980 .ok_or_else(|| crate::Error::ChanProto(format!("Missing {} certificate", tp)))?;
981
982 let cert = tor_cert::Ed25519Cert::decode(body).map_err(|be| crate::Error::BytesErr {
983 err: be,
984 parsed: "ed25519 certificate",
985 })?;
986 if cert.peek_cert_type() != tp {
987 return Err(crate::Error::ChanProto(format!(
988 "Found a {} certificate labeled as {}",
989 cert.peek_cert_type(),
990 tp
991 )));
992 }
993
994 Ok(cert)
995 }
996}
997
998impl Body for Certs {
999 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
1000 let n_certs: u8 = self
1001 .certs
1002 .len()
1003 .try_into()
1004 .map_err(|_| EncodeError::BadLengthValue)?;
1005 w.write_u8(n_certs);
1006 for c in &self.certs {
1007 enc_one_tor_cert(w, c)?;
1008 }
1009 Ok(())
1010 }
1011}
1012impl Readable for Certs {
1013 fn take_from(r: &mut Reader<'_>) -> Result<Self> {
1014 let n = r.take_u8()?;
1015 let mut certs = Vec::new();
1016 for _ in 0..n {
1017 certs.push(take_one_tor_cert(r)?);
1018 }
1019 Ok(Certs { certs })
1020 }
1021}
1022
1023const CHALLENGE_LEN: usize = 32;
1025
1026#[derive(Clone, Debug, Deftly)]
1035#[derive_deftly(HasMemoryCost)]
1036pub struct AuthChallenge {
1037 challenge: [u8; CHALLENGE_LEN],
1039 methods: Vec<u16>,
1041}
1042impl AuthChallenge {
1043 pub fn new<B, M>(challenge: B, methods: M) -> Self
1046 where
1047 B: Into<[u8; CHALLENGE_LEN]>,
1048 M: Into<Vec<u16>>,
1049 {
1050 AuthChallenge {
1051 challenge: challenge.into(),
1052 methods: methods.into(),
1053 }
1054 }
1055
1056 pub fn methods(&self) -> &[u16] {
1058 &self.methods
1059 }
1060}
1061
1062impl Body for AuthChallenge {
1063 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
1064 w.write_all(&self.challenge[..]);
1065 let n_methods = self
1066 .methods
1067 .len()
1068 .try_into()
1069 .map_err(|_| EncodeError::BadLengthValue)?;
1070 w.write_u16(n_methods);
1071 for m in self.methods {
1072 w.write_u16(m);
1073 }
1074 Ok(())
1075 }
1076}
1077impl Readable for AuthChallenge {
1078 fn take_from(r: &mut Reader<'_>) -> Result<Self> {
1079 let challenge = r.extract()?;
1081 let n_methods = r.take_u16()?;
1082 let mut methods = Vec::new();
1083 for _ in 0..n_methods {
1084 methods.push(r.take_u16()?);
1085 }
1086 Ok(AuthChallenge { challenge, methods })
1087 }
1088}
1089
1090#[derive(Clone, Debug, Deftly, Eq, PartialEq)]
1097#[derive_deftly(HasMemoryCost)]
1098pub struct Authenticate {
1099 authtype: u16,
1101 auth: Vec<u8>,
1103}
1104impl Authenticate {
1105 const SIG_LEN: usize = 64;
1107 pub const BODY_LEN: usize = 264;
1109
1110 pub fn new<B>(authtype: u16, body: B) -> Self
1112 where
1113 B: Into<Vec<u8>>,
1114 {
1115 Authenticate {
1116 authtype,
1117 auth: body.into(),
1118 }
1119 }
1120
1121 pub fn auth_type(&self) -> u16 {
1123 self.authtype
1124 }
1125
1126 pub fn body_no_rand(&self) -> Result<&[u8]> {
1129 const RAND_LEN: usize = 24;
1131 let body = self.body()?;
1132 let body_end_offset = body.len().checked_sub(RAND_LEN).ok_or(Error::MissingData)?;
1133 Ok(&body[..body_end_offset])
1134 }
1135
1136 pub fn body(&self) -> Result<&[u8]> {
1138 let auth = self.auth();
1139 let sig_end_offset = auth
1140 .len()
1141 .checked_sub(Self::SIG_LEN)
1142 .ok_or(Error::MissingData)?;
1143 Ok(&auth[..sig_end_offset])
1144 }
1145
1146 pub fn auth(&self) -> &[u8] {
1148 &self.auth
1149 }
1150
1151 pub fn sig(&self) -> Result<&[u8; Self::SIG_LEN]> {
1153 let auth = self.auth();
1154 let sig_start_offset = auth
1155 .len()
1156 .checked_sub(Self::SIG_LEN)
1157 .ok_or(Error::MissingData)?;
1158 (&self.auth[sig_start_offset..])
1159 .try_into()
1160 .map_err(|_| Error::Bug(tor_error::internal!("Failed to get signature bytes")))
1161 }
1162}
1163impl Body for Authenticate {
1164 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
1165 w.write_u16(self.authtype);
1166 let authlen = self
1167 .auth
1168 .len()
1169 .try_into()
1170 .map_err(|_| EncodeError::BadLengthValue)?;
1171 w.write_u16(authlen);
1172 w.write_all(&self.auth[..]);
1173 Ok(())
1174 }
1175}
1176impl Readable for Authenticate {
1177 fn take_from(r: &mut Reader<'_>) -> Result<Self> {
1178 let authtype = r.take_u16()?;
1179 let authlen = r.take_u16()?;
1180 let auth = r.take(authlen as usize)?.into();
1181 Ok(Authenticate { authtype, auth })
1182 }
1183}
1184
1185#[derive(Clone, Debug, Deftly)]
1193#[derive_deftly(HasMemoryCost)]
1194pub struct Unrecognized {
1195 cmd: ChanCmd,
1197 content: Vec<u8>,
1199}
1200impl Unrecognized {
1201 pub fn new<B>(cmd: ChanCmd, content: B) -> Self
1203 where
1204 B: Into<Vec<u8>>,
1205 {
1206 let content = content.into();
1207 Unrecognized { cmd, content }
1208 }
1209 pub fn cmd(&self) -> ChanCmd {
1211 self.cmd
1212 }
1213 pub fn decode_with_cmd(cmd: ChanCmd, r: &mut Reader<'_>) -> Result<Unrecognized> {
1216 let mut u = Unrecognized::take_from(r)?;
1217 u.cmd = cmd;
1218 Ok(u)
1219 }
1220}
1221impl Body for Unrecognized {
1222 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
1223 w.write_all(&self.content[..]);
1224 Ok(())
1225 }
1226}
1227impl Readable for Unrecognized {
1228 fn take_from(r: &mut Reader<'_>) -> Result<Self> {
1229 Ok(Unrecognized {
1230 cmd: 0.into(),
1231 content: r.take(r.remaining())?.into(),
1232 })
1233 }
1234}
1235
1236macro_rules! msg_into_cell {
1239 ($body:ident) => {
1240 impl From<$body> for super::AnyChanCell {
1241 fn from(body: $body) -> super::AnyChanCell {
1242 super::AnyChanCell {
1243 circid: None,
1244 msg: body.into(),
1245 }
1246 }
1247 }
1248 };
1249}
1250
1251msg_into_cell!(Padding);
1252msg_into_cell!(Vpadding);
1253msg_into_cell!(Netinfo);
1254msg_into_cell!(Versions);
1255msg_into_cell!(PaddingNegotiate);
1256msg_into_cell!(Certs);
1257msg_into_cell!(AuthChallenge);
1258msg_into_cell!(Authenticate);
1259
1260macro_rules! msg_impl_chanmsg {
1270 ($($body:ident,)*) =>
1271 {paste::paste!{
1272 $(impl crate::chancell::ChanMsg for $body {
1273 fn cmd(&self) -> crate::chancell::ChanCmd { crate::chancell::ChanCmd::[< $body:snake:upper >] }
1274 fn encode_onto<W: tor_bytes::Writer + ?Sized>(self, w: &mut W) -> tor_bytes::EncodeResult<()> {
1275 crate::chancell::msg::Body::encode_onto(self, w)
1276 }
1277 fn decode_from_reader(cmd: ChanCmd, r: &mut tor_bytes::Reader<'_>) -> tor_bytes::Result<Self> {
1278 if cmd != crate::chancell::ChanCmd::[< $body:snake:upper >] {
1279 return Err(tor_bytes::Error::InvalidMessage(
1280 format!("Expected {} command; got {cmd}", stringify!([< $body:snake:upper >])).into()
1281 ));
1282 }
1283 crate::chancell::msg::Body::decode_from_reader(r)
1284 }
1285 })*
1286 }}
1287}
1288
1289msg_impl_chanmsg!(
1292 Padding,
1293 Vpadding,
1294 Create,
1295 CreateFast,
1296 Create2,
1297 Created,
1298 CreatedFast,
1299 Created2,
1300 Relay,
1301 RelayEarly,
1302 Destroy,
1303 Netinfo,
1304 Versions,
1305 PaddingNegotiate,
1306 Certs,
1307 AuthChallenge,
1308 Authenticate,
1309);
1310
1311#[cfg(test)]
1312mod test {
1313 #![allow(clippy::bool_assert_comparison)]
1315 #![allow(clippy::clone_on_copy)]
1316 #![allow(clippy::dbg_macro)]
1317 #![allow(clippy::mixed_attributes_style)]
1318 #![allow(clippy::print_stderr)]
1319 #![allow(clippy::print_stdout)]
1320 #![allow(clippy::single_char_pattern)]
1321 #![allow(clippy::unwrap_used)]
1322 #![allow(clippy::unchecked_time_subtraction)]
1323 #![allow(clippy::useless_vec)]
1324 #![allow(clippy::needless_pass_by_value)]
1325 #![allow(clippy::string_slice)] use super::*;
1328 #[test]
1329 fn destroy_reason() {
1330 let r1 = DestroyReason::CONNECTFAILED;
1331
1332 assert_eq!(r1.human_str(), "Couldn't connect to relay");
1333
1334 let r2 = DestroyReason::from(200); assert_eq!(r2.human_str(), "Unrecognized reason");
1336 }
1337}