tor_cell/chancell/
msg.rs

1//! Different kinds of messages that can be encoded in channel cells.
2
3use super::{BoxedCellBody, CELL_DATA_LEN, ChanCmd, RawCellBody};
4use std::net::{IpAddr, Ipv4Addr};
5use tor_basic_utils::skip_fmt;
6use tor_bytes::{self, EncodeError, EncodeResult, Error, Readable, Reader, Result, Writer};
7use tor_memquota::derive_deftly_template_HasMemoryCost;
8use tor_units::IntegerMilliseconds;
9
10use caret::caret_int;
11use derive_deftly::Deftly;
12use educe::Educe;
13
14/// Trait for the 'bodies' of channel messages.
15pub trait Body: Readable {
16    /// Decode a channel cell body from a provided reader.
17    fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
18        r.extract()
19    }
20    /// Consume this message and encode its body onto `w`.
21    ///
22    /// Does not encode anything _but_ the cell body, and does not pad
23    /// to the cell length.
24    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()>;
25}
26
27crate::restrict::restricted_msg! {
28/// Decoded message from a channel.
29///
30/// A ChanMsg is an item received on a channel -- a message from
31/// another Tor client or relay that we are connected to directly over
32/// a TLS connection.
33#[derive(Clone, Debug, Deftly)]
34#[derive_deftly(HasMemoryCost)]
35#[non_exhaustive]
36@omit_from "avoid_conflict_with_a_blanket_implementation"
37pub enum AnyChanMsg : ChanMsg {
38    /// A Padding message
39    Padding,
40    /// Variable-length padding message
41    Vpadding,
42    /// (Deprecated) TAP-based cell to create a new circuit.
43    Create,
44    /// (Mostly deprecated) HMAC-based cell to create a new circuit.
45    CreateFast,
46    /// Cell to create a new circuit
47    Create2,
48    /// (Deprecated) Answer to a Create cell
49    Created,
50    /// (Mostly Deprecated) Answer to a CreateFast cell
51    CreatedFast,
52    /// Answer to a Create2 cell
53    Created2,
54    /// A message sent along a circuit, likely to a more-distant relay.
55    Relay,
56    /// A message sent along a circuit (limited supply)
57    RelayEarly,
58    /// Tear down a circuit
59    Destroy,
60    /// Part of channel negotiation: describes our position on the network
61    Netinfo,
62    /// Part of channel negotiation: describes what link protocol versions
63    /// we support
64    Versions,
65    /// Negotiates what kind of channel padding to send
66    PaddingNegotiate,
67    /// Part of channel negotiation: additional certificates not in the
68    /// TLS handshake
69    Certs,
70    /// Part of channel negotiation: additional random material to be used
71    /// as part of authentication
72    AuthChallenge,
73    /// Part of channel negotiation: used to authenticate relays when they
74    /// initiate the channel.
75    Authenticate,
76    _ =>
77    /// Any cell whose command we don't recognize
78    Unrecognized,
79}
80}
81
82/// A Padding message is a fixed-length message on a channel that is
83/// ignored.
84///
85/// Padding message can be used to disguise the true amount of data on a
86/// channel, or as a "keep-alive".
87///
88/// The correct response to a padding cell is to drop it and do nothing.
89#[derive(Clone, Debug, Default, Deftly)]
90#[derive_deftly(HasMemoryCost)]
91#[non_exhaustive]
92pub struct Padding {}
93impl Padding {
94    /// Create a new fixed-length padding cell
95    pub fn new() -> Self {
96        Padding {}
97    }
98}
99impl Body for Padding {
100    fn encode_onto<W: Writer + ?Sized>(self, _w: &mut W) -> EncodeResult<()> {
101        Ok(())
102    }
103}
104impl Readable for Padding {
105    fn take_from(_b: &mut Reader<'_>) -> Result<Self> {
106        Ok(Padding {})
107    }
108}
109
110/// A VPadding message is a variable-length padding message.
111///
112/// The correct response to a padding cell is to drop it and do nothing.
113#[derive(Clone, Debug, Deftly)]
114#[derive_deftly(HasMemoryCost)]
115pub struct Vpadding {
116    /// How much padding to send in this cell's body.
117    len: u16,
118}
119impl Vpadding {
120    /// Return a new vpadding cell with given length.
121    pub fn new(len: u16) -> Self {
122        Vpadding { len }
123    }
124}
125impl Body for Vpadding {
126    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
127        w.write_zeros(self.len as usize);
128        Ok(())
129    }
130}
131impl Readable for Vpadding {
132    fn take_from(b: &mut Reader<'_>) -> Result<Self> {
133        if b.remaining() > u16::MAX as usize {
134            return Err(Error::InvalidMessage(
135                "Too many bytes in VPADDING cell".into(),
136            ));
137        }
138        Ok(Vpadding {
139            len: b.remaining() as u16,
140        })
141    }
142}
143
144/// helper -- declare a fixed-width cell for handshake commands, in which
145/// a fixed number of bytes matter and the rest are ignored
146macro_rules! fixed_len_handshake {
147    {
148        $(#[$meta:meta])*
149        $name:ident , $cmd:ident, $len:ident
150    } => {
151        $(#[$meta])*
152        #[derive(Clone,Debug,Deftly)]
153        #[derive_deftly(HasMemoryCost)]
154        pub struct $name {
155            handshake: Vec<u8>
156        }
157        impl $name {
158            /// Create a new cell from a provided handshake.
159            pub fn new<B>(handshake: B) -> Self
160                where B: Into<Vec<u8>>
161            {
162                let handshake = handshake.into();
163                $name { handshake }
164            }
165        }
166        impl Body for $name {
167            fn encode_onto<W: Writer + ?Sized>(self, w: &mut W)  -> EncodeResult<()> {
168                w.write_all(&self.handshake[..]);
169                Ok(())
170            }
171        }
172        impl Readable for $name {
173            fn take_from(b: &mut Reader<'_>) -> Result<Self> {
174                Ok($name {
175                    handshake: b.take($len)?.into(),
176                })
177            }
178        }
179    }
180}
181
182/// Number of bytes used for a TAP handshake by the initiator.
183pub(crate) const TAP_C_HANDSHAKE_LEN: usize = 128 + 16 + 42;
184/// Number of bytes used for a TAP handshake response
185pub(crate) const TAP_S_HANDSHAKE_LEN: usize = 128 + 20;
186
187/// Number of bytes used for a CREATE_FAST handshake by the initiator
188const FAST_C_HANDSHAKE_LEN: usize = 20;
189/// Number of bytes used for a CREATE_FAST handshake response
190const FAST_S_HANDSHAKE_LEN: usize = 20 + 20;
191
192fixed_len_handshake! {
193    /// A Create message creates a circuit, using the TAP handshake.
194    ///
195    /// TAP is an obsolete handshake based on RSA-1024 and DH-1024.
196    /// Relays respond to Create message with a Created reply on
197    /// success, or a Destroy message on failure.
198    ///
199    /// In Tor today, Create is only used for the deprecated v2 onion
200    /// service protocol.
201    Create, CREATE, TAP_C_HANDSHAKE_LEN
202}
203fixed_len_handshake! {
204    /// A Created message responds to a Created message, using the TAP
205    /// handshake.
206    ///
207    /// TAP is an obsolete handshake based on RSA-1024 and DH-1024.
208    Created, CREATED, TAP_S_HANDSHAKE_LEN
209}
210fixed_len_handshake! {
211    /// A CreateFast message creates a circuit using no public-key crypto.
212    ///
213    /// CreateFast is safe only when used on an already-secure TLS
214    /// connection.  It can only be used for the first hop of a circuit.
215    ///
216    /// Relays reply to a CreateFast message with CreatedFast on
217    /// success, or a Destroy message on failure.
218    ///
219    /// This handshake was originally used for the first hop of every
220    /// circuit.  Nowadays it is used for creating one-hop circuits
221    /// when we don't know any onion key for the first hop.
222    CreateFast, CREATE_FAST, FAST_C_HANDSHAKE_LEN
223}
224impl CreateFast {
225    /// Return the content of this handshake
226    pub fn handshake(&self) -> &[u8] {
227        &self.handshake
228    }
229}
230fixed_len_handshake! {
231    /// A CreatedFast message responds to a CreateFast message
232    ///
233    /// Relays send this message back to indicate that the CrateFast handshake
234    /// is complete.
235    CreatedFast, CREATED_FAST, FAST_S_HANDSHAKE_LEN
236}
237impl CreatedFast {
238    /// Consume this message and return the content of this handshake
239    pub fn into_handshake(self) -> Vec<u8> {
240        self.handshake
241    }
242}
243
244caret_int! {
245    /// Handshake type, corresponding to [`HTYPE` in
246    /// tor-spec](https://spec.torproject.org/tor-spec/create-created-cells.html).
247    #[derive(Deftly)]
248    #[derive_deftly(HasMemoryCost)]
249    pub struct HandshakeType(u16) {
250        /// [TAP](https://spec.torproject.org/tor-spec/create-created-cells.html#TAP) -- the original Tor handshake.
251        TAP = 0,
252
253        // 1 is reserved
254
255        /// [ntor](https://spec.torproject.org/tor-spec/create-created-cells.html#ntor) -- the ntor+curve25519+sha256 handshake.
256        NTOR = 2,
257        /// [ntor-v3](https://spec.torproject.org/tor-spec/create-created-cells.html#ntor-v3) -- ntor extended with extra data.
258        NTOR_V3 = 3,
259    }
260}
261
262/// A Create2 message create a circuit on the current channel.
263///
264/// To create a circuit, the client sends a Create2 cell containing a
265/// handshake of a given type; the relay responds with a Created2 cell
266/// containing a reply.
267///
268/// Currently, most Create2 cells contain a client-side instance of the
269/// "ntor" handshake.
270#[derive(Clone, Debug, Deftly)]
271#[derive_deftly(HasMemoryCost)]
272pub struct Create2 {
273    /// Identifier for what kind of handshake this is.
274    handshake_type: HandshakeType,
275    /// Body of the handshake.
276    handshake: Vec<u8>,
277}
278impl Body for Create2 {
279    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
280        w.write_u16(self.handshake_type.into());
281        let handshake_len = self
282            .handshake
283            .len()
284            .try_into()
285            .map_err(|_| EncodeError::BadLengthValue)?;
286        w.write_u16(handshake_len);
287        w.write_all(&self.handshake[..]);
288        Ok(())
289    }
290}
291impl Readable for Create2 {
292    fn take_from(b: &mut Reader<'_>) -> Result<Self> {
293        let handshake_type = HandshakeType::from(b.take_u16()?);
294        let hlen = b.take_u16()?;
295        let handshake = b.take(hlen as usize)?.into();
296        Ok(Create2 {
297            handshake_type,
298            handshake,
299        })
300    }
301}
302impl Create2 {
303    /// Wrap a typed handshake as a Create2 message
304    pub fn new<B>(handshake_type: HandshakeType, handshake: B) -> Self
305    where
306        B: Into<Vec<u8>>,
307    {
308        let handshake = handshake.into();
309        Create2 {
310            handshake_type,
311            handshake,
312        }
313    }
314
315    /// Return the type of this handshake.
316    pub fn handshake_type(&self) -> HandshakeType {
317        self.handshake_type
318    }
319
320    /// Return the body of this handshake.
321    pub fn body(&self) -> &[u8] {
322        &self.handshake[..]
323    }
324}
325
326/// A Created2 message completes a circuit-creation handshake.
327///
328/// When a relay receives a valid Create2 message that it can handle, it
329/// establishes the circuit and replies with a Created2.
330#[derive(Clone, Debug, Deftly)]
331#[derive_deftly(HasMemoryCost)]
332pub struct Created2 {
333    /// Body of the handshake reply
334    handshake: Vec<u8>,
335}
336impl Created2 {
337    /// Create a new Created2 to hold a given handshake.
338    pub fn new<B>(handshake: B) -> Self
339    where
340        B: Into<Vec<u8>>,
341    {
342        let handshake = handshake.into();
343        Created2 { handshake }
344    }
345    /// Consume this created2 cell and return its body.
346    pub fn into_body(self) -> Vec<u8> {
347        self.handshake
348    }
349}
350impl Body for Created2 {
351    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
352        let handshake_len = self
353            .handshake
354            .len()
355            .try_into()
356            .map_err(|_| EncodeError::BadLengthValue)?;
357        w.write_u16(handshake_len);
358        w.write_all(&self.handshake[..]);
359        Ok(())
360    }
361}
362impl Readable for Created2 {
363    fn take_from(b: &mut Reader<'_>) -> Result<Self> {
364        let hlen = b.take_u16()?;
365        let handshake = b.take(hlen as usize)?.into();
366        Ok(Created2 { handshake })
367    }
368}
369
370/// A Relay cell - that is, one transmitted over a circuit.
371///
372/// Once a circuit has been established, relay cells can be sent over
373/// it.  Clients can send relay cells to any relay on the circuit. Any
374/// relay on the circuit can send relay cells to the client, either
375/// directly (if it is the first hop), or indirectly through the
376/// intermediate hops.
377///
378/// A different protocol is defined over the relay cells; it is implemented
379/// in the [crate::relaycell] module.
380#[derive(Clone, Educe, derive_more::From, Deftly)]
381#[derive_deftly(HasMemoryCost)]
382#[educe(Debug)]
383pub struct Relay {
384    /// The contents of the relay cell as encoded for transfer.
385    ///
386    /// TODO(nickm): It's nice that this is boxed, since we don't want to copy
387    /// cell data all over the place. But unfortunately, there are some other
388    /// places where we _don't_ Box things that we should, and more copies than
389    /// necessary happen. We should refactor our data handling until we're mostly
390    /// moving around pointers rather than copying data;  see ticket #7.
391    #[educe(Debug(method = "skip_fmt"))]
392    body: BoxedCellBody,
393}
394impl Relay {
395    /// Construct a Relay message from a slice containing its contents.
396    pub fn new<P>(body: P) -> Self
397    where
398        P: AsRef<[u8]>,
399    {
400        let body = body.as_ref();
401        let mut r = [0_u8; CELL_DATA_LEN];
402        // TODO: This will panic if body is too long, but that would be a
403        // programming error anyway.
404        r[..body.len()].copy_from_slice(body);
405        Relay { body: Box::new(r) }
406    }
407    /// Construct a Relay message from its body.
408    pub fn from_raw(body: RawCellBody) -> Self {
409        Relay {
410            body: Box::new(body),
411        }
412    }
413    /// Consume this Relay message and return a BoxedCellBody for
414    /// encryption/decryption.
415    pub fn into_relay_body(self) -> BoxedCellBody {
416        self.body
417    }
418    /// Wrap this Relay message into a RelayMsg as a RELAY_EARLY cell.
419    pub fn into_early(self) -> AnyChanMsg {
420        AnyChanMsg::RelayEarly(RelayEarly(self))
421    }
422}
423impl Body for Relay {
424    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
425        w.write_all(&self.body[..]);
426        Ok(())
427    }
428}
429impl Readable for Relay {
430    fn take_from(b: &mut Reader<'_>) -> Result<Self> {
431        let mut body = Box::new([0_u8; CELL_DATA_LEN]);
432        body.copy_from_slice(b.take(CELL_DATA_LEN)?);
433        Ok(Relay { body })
434    }
435}
436
437/// A Relay cell that is allowed to contain a CREATE message.
438///
439/// Only a limited number of these may be sent on each circuit.
440#[derive(Clone, Debug, derive_more::Deref, derive_more::From, derive_more::Into, Deftly)]
441#[derive_deftly(HasMemoryCost)]
442pub struct RelayEarly(Relay);
443impl Readable for RelayEarly {
444    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
445        Ok(RelayEarly(Relay::take_from(r)?))
446    }
447}
448impl Body for RelayEarly {
449    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
450        self.0.encode_onto(w)
451    }
452}
453impl RelayEarly {
454    /// Consume this RelayEarly message and return a BoxedCellBody for
455    /// encryption/decryption.
456    //
457    // (Since this method takes `self` by value, we can't take advantage of
458    // Deref.)
459    pub fn into_relay_body(self) -> BoxedCellBody {
460        self.0.body
461    }
462}
463
464/// The Destroy message tears down a circuit.
465///
466/// On receiving a Destroy message, a Tor implementation should
467/// tear down the associated circuit, and pass the destroy message
468/// down the circuit to later/earlier hops on the circuit (if any).
469#[derive(Clone, Debug, Deftly)]
470#[derive_deftly(HasMemoryCost)]
471pub struct Destroy {
472    /// Reason code given for tearing down this circuit
473    reason: DestroyReason,
474}
475impl Destroy {
476    /// Create a new destroy cell.
477    pub fn new(reason: DestroyReason) -> Self {
478        Destroy { reason }
479    }
480    /// Return the provided reason for destroying the circuit.
481    pub fn reason(&self) -> DestroyReason {
482        self.reason
483    }
484}
485impl Body for Destroy {
486    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
487        w.write_u8(self.reason.into());
488        Ok(())
489    }
490}
491impl Readable for Destroy {
492    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
493        let reason = r.take_u8()?.into();
494        Ok(Destroy { reason })
495    }
496}
497
498caret_int! {
499    /// Declared reason for ending a circuit.
500    #[derive(Deftly)]
501    #[derive_deftly(HasMemoryCost)]
502    pub struct DestroyReason(u8) {
503        /// No reason given.
504        ///
505        /// This is the only reason that clients send.
506        NONE = 0,
507        /// Protocol violation
508        PROTOCOL = 1,
509        /// Internal error.
510        INTERNAL = 2,
511        /// Client sent a TRUNCATE command.
512        REQUESTED = 3,
513        /// Relay is hibernating and not accepting requests
514        HIBERNATING = 4,
515        /// Ran out of memory, sockets, or circuit IDs
516        RESOURCELIMIT = 5,
517        /// Couldn't connect to relay.
518        CONNECTFAILED = 6,
519        /// Connected to a relay, but its OR identity wasn't as requested.
520        OR_IDENTITY = 7,
521        /// One of the OR channels carrying this circuit died.
522        CHANNEL_CLOSED = 8,
523        /// Circuit expired for being too dirty or old
524        FINISHED = 9,
525        /// Circuit construction took too long
526        TIMEOUT = 10,
527        /// Circuit was destroyed w/o client truncate (?)
528        DESTROYED = 11,
529        /// Request for unknown onion service
530        NOSUCHSERVICE = 12
531    }
532}
533
534impl DestroyReason {
535    /// Return a human-readable string for this reason.
536    pub fn human_str(&self) -> &'static str {
537        match *self {
538            DestroyReason::NONE => "No reason",
539            DestroyReason::PROTOCOL => "Protocol violation",
540            DestroyReason::INTERNAL => "Internal error",
541            DestroyReason::REQUESTED => "Client sent a TRUNCATE command",
542            DestroyReason::HIBERNATING => "Relay is hibernating and not accepting requests",
543            DestroyReason::RESOURCELIMIT => "Relay ran out of resources",
544            DestroyReason::CONNECTFAILED => "Couldn't connect to relay",
545            DestroyReason::OR_IDENTITY => "Connected to relay with different OR identity",
546            DestroyReason::CHANNEL_CLOSED => "The OR channels carrying this circuit died",
547            DestroyReason::FINISHED => "Circuit expired for being too dirty or old",
548            DestroyReason::TIMEOUT => "Circuit construction took too long",
549            DestroyReason::DESTROYED => "Circuit was destroyed without client truncate",
550            DestroyReason::NOSUCHSERVICE => "No such onion service",
551            _ => "Unrecognized reason",
552        }
553    }
554}
555
556/// The netinfo message ends channel negotiation.
557///
558/// It tells the other party on the channel our view of the current time,
559/// our own list of public addresses, and our view of its address.
560///
561/// When we get a netinfo cell, we can start creating circuits on a
562/// channel and sending data.
563#[derive(Clone, Debug, Deftly)]
564#[derive_deftly(HasMemoryCost)]
565pub struct Netinfo {
566    /// Time when this cell was sent, or 0 if this cell is sent by a client.
567    ///
568    /// TODO-SPEC(nickm): Y2038 issue here.  Better add a new handshake version
569    /// to solve it.  See
570    /// [torspec#80](https://gitlab.torproject.org/tpo/core/torspec/-/issues/80).
571    timestamp: u32,
572    /// Observed address for party that did not send the netinfo cell.
573    their_addr: Option<IpAddr>,
574    /// Canonical addresses for the party that did send the netinfo cell.
575    my_addr: Vec<IpAddr>,
576}
577/// helper: encode a single address in the form that netinfo messages expect
578fn enc_one_netinfo_addr<W: Writer + ?Sized>(w: &mut W, addr: &IpAddr) {
579    match addr {
580        IpAddr::V4(ipv4) => {
581            w.write_u8(0x04); // type.
582            w.write_u8(4); // length.
583            w.write_all(&ipv4.octets()[..]);
584        }
585        IpAddr::V6(ipv6) => {
586            w.write_u8(0x06); // type.
587            w.write_u8(16); // length.
588            w.write_all(&ipv6.octets()[..]);
589        }
590    }
591}
592/// helper: take an address as encoded in a netinfo message
593fn take_one_netinfo_addr(r: &mut Reader<'_>) -> Result<Option<IpAddr>> {
594    let atype = r.take_u8()?;
595    let alen = r.take_u8()?;
596    let abody = r.take(alen as usize)?;
597    match (atype, alen) {
598        (0x04, 4) => {
599            let bytes = [abody[0], abody[1], abody[2], abody[3]];
600            Ok(Some(IpAddr::V4(bytes.into())))
601        }
602        (0x06, 16) => {
603            // TODO(nickm) is there a better way?
604            let mut bytes = [0_u8; 16];
605            bytes.copy_from_slice(abody);
606            Ok(Some(IpAddr::V6(bytes.into())))
607        }
608        (_, _) => Ok(None),
609    }
610}
611impl Netinfo {
612    /// Construct a new Netinfo to be sent by a client.
613    pub fn from_client(their_addr: Option<IpAddr>) -> Self {
614        Netinfo {
615            timestamp: 0, // clients don't report their timestamps.
616            their_addr,
617            my_addr: Vec::new(), // clients don't report their addrs.
618        }
619    }
620    /// Construct a new Netinfo to be sent by a relay
621    pub fn from_relay<V>(timestamp: u32, their_addr: Option<IpAddr>, my_addrs: V) -> Self
622    where
623        V: Into<Vec<IpAddr>>,
624    {
625        let my_addr = my_addrs.into();
626        Netinfo {
627            timestamp,
628            their_addr,
629            my_addr,
630        }
631    }
632    /// Return the time reported in this NETINFO cell.
633    pub fn timestamp(&self) -> Option<std::time::SystemTime> {
634        use std::time::{Duration, SystemTime};
635        if self.timestamp == 0 {
636            None
637        } else {
638            Some(SystemTime::UNIX_EPOCH + Duration::from_secs(self.timestamp.into()))
639        }
640    }
641}
642impl Body for Netinfo {
643    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
644        w.write_u32(self.timestamp);
645        let their_addr = self
646            .their_addr
647            .unwrap_or_else(|| Ipv4Addr::UNSPECIFIED.into());
648        enc_one_netinfo_addr(w, &their_addr);
649        let n_addrs: u8 = self
650            .my_addr
651            .len()
652            .try_into()
653            .map_err(|_| EncodeError::BadLengthValue)?;
654        w.write_u8(n_addrs);
655        for addr in &self.my_addr {
656            enc_one_netinfo_addr(w, addr);
657        }
658        Ok(())
659    }
660}
661impl Readable for Netinfo {
662    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
663        let timestamp = r.take_u32()?;
664        let their_addr = take_one_netinfo_addr(r)?.filter(|a| !a.is_unspecified());
665        let my_n_addrs = r.take_u8()?;
666        let mut my_addr = Vec::with_capacity(my_n_addrs as usize);
667        for _ in 0..my_n_addrs {
668            if let Some(a) = take_one_netinfo_addr(r)? {
669                my_addr.push(a);
670            }
671        }
672        Ok(Netinfo {
673            timestamp,
674            their_addr,
675            my_addr,
676        })
677    }
678}
679
680/// A Versions message begins channel negotiation.
681///
682/// Every channel must begin by sending a Versions message.  This message
683/// lists the link protocol versions that this Tor implementation supports.
684///
685/// Note that we should never actually send Versions cells using the
686/// usual channel cell encoding: Versions cells _always_ use two-byte
687/// circuit IDs, whereas all the other cell types use four-byte
688/// circuit IDs [assuming a non-obsolete version is negotiated].
689#[derive(Clone, Debug, Deftly)]
690#[derive_deftly(HasMemoryCost)]
691pub struct Versions {
692    /// List of supported link protocol versions
693    versions: Vec<u16>,
694}
695impl Versions {
696    /// Construct a new Versions message using a provided list of link
697    /// protocols.
698    ///
699    /// Returns an error if the list of versions is too long.
700    pub fn new<B>(vs: B) -> crate::Result<Self>
701    where
702        B: Into<Vec<u16>>,
703    {
704        let versions = vs.into();
705        if versions.len() < (u16::MAX / 2) as usize {
706            Ok(Self { versions })
707        } else {
708            Err(crate::Error::CantEncode("Too many versions"))
709        }
710    }
711    /// Encode this VERSIONS cell in the manner expected for a handshake.
712    ///
713    /// (That's different from a standard cell encoding, since we
714    /// have not negotiated versions yet, and so our circuit-ID length
715    /// is an obsolete 2 bytes).
716    pub fn encode_for_handshake(self) -> EncodeResult<Vec<u8>> {
717        let mut v = Vec::new();
718        v.write_u16(0); // obsolete circuit ID length.
719        v.write_u8(ChanCmd::VERSIONS.into());
720        v.write_u16((self.versions.len() * 2) as u16); // message length.
721        self.encode_onto(&mut v)?;
722        Ok(v)
723    }
724    /// Return the best (numerically highest) link protocol that is
725    /// shared by this versions cell and my_protos.
726    pub fn best_shared_link_protocol(&self, my_protos: &[u16]) -> Option<u16> {
727        // NOTE: this implementation is quadratic, but it shouldn't matter
728        // much so long as my_protos is small.
729        let p = my_protos
730            .iter()
731            .filter(|p| self.versions.contains(p))
732            .fold(0_u16, |a, b| u16::max(a, *b));
733        if p == 0 { None } else { Some(p) }
734    }
735}
736impl Body for Versions {
737    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
738        for v in &self.versions {
739            w.write_u16(*v);
740        }
741        Ok(())
742    }
743}
744impl Readable for Versions {
745    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
746        let mut versions = Vec::new();
747        while r.remaining() > 0 {
748            versions.push(r.take_u16()?);
749        }
750        Ok(Versions { versions })
751    }
752}
753
754caret_int! {
755    /// A ChanCmd is the type of a channel cell.  The value of the ChanCmd
756    /// indicates the meaning of the cell, and (possibly) its length.
757    #[derive(Deftly)]
758    #[derive_deftly(HasMemoryCost)]
759    pub struct PaddingNegotiateCmd(u8) {
760        /// Start padding
761        START = 2,
762
763        /// Stop padding
764        STOP = 1,
765    }
766}
767
768/// A PaddingNegotiate message is used to negotiate channel padding.
769///
770/// Sent by a client to its guard node,
771/// to instruct the relay to enable/disable channel padding.
772/// (Not relevant for channels used only for directory lookups,
773/// nor inter-relay channels.)
774/// See `padding-spec.txt`, section 2.2.
775///
776/// This message is constructed in the channel manager and transmitted by the reactor.
777///
778/// The `Default` impl is the same as [`start_default()`](PaddingNegotiate::start_default`)
779#[derive(Clone, Debug, Eq, PartialEq, Deftly)]
780#[derive_deftly(HasMemoryCost)]
781pub struct PaddingNegotiate {
782    /// Whether to start or stop padding
783    command: PaddingNegotiateCmd,
784    /// Suggested lower-bound value for inter-packet timeout in msec.
785    // TODO(nickm) is that right?
786    ito_low_ms: u16,
787    /// Suggested upper-bound value for inter-packet timeout in msec.
788    // TODO(nickm) is that right?
789    ito_high_ms: u16,
790}
791impl PaddingNegotiate {
792    /// Create a new PADDING_NEGOTIATE START message requesting consensus timing parameters.
793    ///
794    /// This message restores the state to the one which exists at channel startup.
795    pub fn start_default() -> Self {
796        // Tor Spec section 7.3, padding-spec section 2.5.
797        Self {
798            command: PaddingNegotiateCmd::START,
799            ito_low_ms: 0,
800            ito_high_ms: 0,
801        }
802    }
803
804    /// Create a new PADDING_NEGOTIATE START message.
805    pub fn start(ito_low: IntegerMilliseconds<u16>, ito_high: IntegerMilliseconds<u16>) -> Self {
806        // Tor Spec section 7.3
807        Self {
808            command: PaddingNegotiateCmd::START,
809            ito_low_ms: ito_low.as_millis(),
810            ito_high_ms: ito_high.as_millis(),
811        }
812    }
813
814    /// Create a new PADDING_NEGOTIATE STOP message.
815    pub fn stop() -> Self {
816        // Tor Spec section 7.3
817        Self {
818            command: PaddingNegotiateCmd::STOP,
819            ito_low_ms: 0,
820            ito_high_ms: 0,
821        }
822    }
823
824    /// Construct from the three fields: command, low_ms, high_ms, as a tuple
825    ///
826    /// For testing only
827    #[cfg(feature = "testing")]
828    pub fn from_raw(command: PaddingNegotiateCmd, ito_low_ms: u16, ito_high_ms: u16) -> Self {
829        PaddingNegotiate {
830            command,
831            ito_low_ms,
832            ito_high_ms,
833        }
834    }
835}
836impl Default for PaddingNegotiate {
837    fn default() -> Self {
838        Self::start_default()
839    }
840}
841
842impl Body for PaddingNegotiate {
843    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
844        w.write_u8(0); // version
845        w.write_u8(self.command.get());
846        w.write_u16(self.ito_low_ms);
847        w.write_u16(self.ito_high_ms);
848        Ok(())
849    }
850}
851impl Readable for PaddingNegotiate {
852    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
853        let v = r.take_u8()?;
854        if v != 0 {
855            return Err(Error::InvalidMessage(
856                "Unrecognized padding negotiation version".into(),
857            ));
858        }
859        let command = r.take_u8()?.into();
860        let ito_low_ms = r.take_u16()?;
861        let ito_high_ms = r.take_u16()?;
862        Ok(PaddingNegotiate {
863            command,
864            ito_low_ms,
865            ito_high_ms,
866        })
867    }
868}
869
870/// A single certificate in a Certs cell.
871///
872/// The formats used here are implemented in tor-cert. Ed25519Cert is the
873/// most common.
874#[derive(Clone, Debug, Deftly)]
875#[derive_deftly(HasMemoryCost)]
876struct TorCert {
877    /// Type code for this certificate.
878    certtype: u8,
879    /// Encoded certificate
880    cert: Vec<u8>,
881}
882/// encode a single TorCert `c` onto a Writer `w`.
883fn enc_one_tor_cert<W: Writer + ?Sized>(w: &mut W, c: &TorCert) -> EncodeResult<()> {
884    w.write_u8(c.certtype);
885    let cert_len: u16 = c
886        .cert
887        .len()
888        .try_into()
889        .map_err(|_| EncodeError::BadLengthValue)?;
890    w.write_u16(cert_len);
891    w.write_all(&c.cert[..]);
892    Ok(())
893}
894/// Try to extract a TorCert from the reader `r`.
895fn take_one_tor_cert(r: &mut Reader<'_>) -> Result<TorCert> {
896    let certtype = r.take_u8()?;
897    let certlen = r.take_u16()?;
898    let cert = r.take(certlen as usize)?;
899    Ok(TorCert {
900        certtype,
901        cert: cert.into(),
902    })
903}
904/// A Certs message is used as part of the channel handshake to send
905/// additional certificates.
906///
907/// These certificates are not presented as part of the TLS handshake.
908/// Originally this was meant to make Tor TLS handshakes look "normal", but
909/// nowadays it serves less purpose, especially now that we have TLS 1.3.
910///
911/// Every relay sends this message as part of channel negotiation;
912/// clients do not send them.
913#[derive(Clone, Debug, Deftly)]
914#[derive_deftly(HasMemoryCost)]
915pub struct Certs {
916    /// The certificates in this cell
917    certs: Vec<TorCert>,
918}
919impl Certs {
920    /// Return a new empty certs cell.
921    pub fn new_empty() -> Self {
922        Certs { certs: Vec::new() }
923    }
924    /// Add a new encoded certificate to this cell.
925    ///
926    /// Does not check anything about the well-formedness of the certificate.
927    pub fn push_cert_body<B>(&mut self, certtype: tor_cert::CertType, cert: B)
928    where
929        B: Into<Vec<u8>>,
930    {
931        let certtype = certtype.into();
932        let cert = cert.into();
933        self.certs.push(TorCert { certtype, cert });
934    }
935
936    /// Return the body of the certificate tagged with 'tp', if any.
937    pub fn cert_body(&self, tp: tor_cert::CertType) -> Option<&[u8]> {
938        let tp: u8 = tp.into();
939        self.certs
940            .iter()
941            .find(|c| c.certtype == tp)
942            .map(|c| &c.cert[..])
943    }
944
945    /// Look for a certificate of type 'tp' in this cell; return it if
946    /// there is one.
947    pub fn parse_ed_cert(&self, tp: tor_cert::CertType) -> crate::Result<tor_cert::KeyUnknownCert> {
948        let body = self
949            .cert_body(tp)
950            .ok_or_else(|| crate::Error::ChanProto(format!("Missing {} certificate", tp)))?;
951
952        let cert = tor_cert::Ed25519Cert::decode(body).map_err(|be| crate::Error::BytesErr {
953            err: be,
954            parsed: "ed25519 certificate",
955        })?;
956        if cert.peek_cert_type() != tp {
957            return Err(crate::Error::ChanProto(format!(
958                "Found a {} certificate labeled as {}",
959                cert.peek_cert_type(),
960                tp
961            )));
962        }
963
964        Ok(cert)
965    }
966}
967
968impl Body for Certs {
969    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
970        let n_certs: u8 = self
971            .certs
972            .len()
973            .try_into()
974            .map_err(|_| EncodeError::BadLengthValue)?;
975        w.write_u8(n_certs);
976        for c in &self.certs {
977            enc_one_tor_cert(w, c)?;
978        }
979        Ok(())
980    }
981}
982impl Readable for Certs {
983    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
984        let n = r.take_u8()?;
985        let mut certs = Vec::new();
986        for _ in 0..n {
987            certs.push(take_one_tor_cert(r)?);
988        }
989        Ok(Certs { certs })
990    }
991}
992
993/// Length of the body for an authentication challenge
994const CHALLENGE_LEN: usize = 32;
995
996/// An AuthChallenge message is part of negotiation, sent by
997/// responders to initiators.
998///
999/// The AuthChallenge cell is used to ensure that some unpredictable material
1000/// has been sent on the channel, and to tell the initiator what
1001/// authentication methods will be accepted.
1002///
1003/// Clients can safely ignore this message: they don't need to authenticate.
1004#[derive(Clone, Debug, Deftly)]
1005#[derive_deftly(HasMemoryCost)]
1006pub struct AuthChallenge {
1007    /// Random challenge to be used in generating response
1008    challenge: [u8; CHALLENGE_LEN],
1009    /// List of permitted authentication methods
1010    methods: Vec<u16>,
1011}
1012impl AuthChallenge {
1013    /// Construct a new AuthChallenge cell with a given challenge
1014    /// value (chosen randomly) and a set of acceptable authentication methods.
1015    pub fn new<B, M>(challenge: B, methods: M) -> Self
1016    where
1017        B: Into<[u8; CHALLENGE_LEN]>,
1018        M: Into<Vec<u16>>,
1019    {
1020        AuthChallenge {
1021            challenge: challenge.into(),
1022            methods: methods.into(),
1023        }
1024    }
1025
1026    /// Return a reference to the list of methods.
1027    pub fn methods(&self) -> &[u16] {
1028        &self.methods
1029    }
1030}
1031
1032impl Body for AuthChallenge {
1033    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
1034        w.write_all(&self.challenge[..]);
1035        let n_methods = self
1036            .methods
1037            .len()
1038            .try_into()
1039            .map_err(|_| EncodeError::BadLengthValue)?;
1040        w.write_u16(n_methods);
1041        for m in self.methods {
1042            w.write_u16(m);
1043        }
1044        Ok(())
1045    }
1046}
1047impl Readable for AuthChallenge {
1048    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
1049        //let challenge = r.take(CHALLENGE_LEN)?.into();
1050        let challenge = r.extract()?;
1051        let n_methods = r.take_u16()?;
1052        let mut methods = Vec::new();
1053        for _ in 0..n_methods {
1054            methods.push(r.take_u16()?);
1055        }
1056        Ok(AuthChallenge { challenge, methods })
1057    }
1058}
1059
1060/// Part of negotiation: sent by initiators to responders.
1061///
1062/// The Authenticate cell proves the initiator's identity to the
1063/// responder, even if TLS client authentication was not used.
1064///
1065/// Clients do not use this.
1066#[derive(Clone, Debug, Deftly)]
1067#[derive_deftly(HasMemoryCost)]
1068pub struct Authenticate {
1069    /// Authentication method in use
1070    authtype: u16,
1071    /// Encoded authentication object
1072    auth: Vec<u8>,
1073}
1074impl Authenticate {
1075    /// Create a new Authenticate message from a given type and body.
1076    pub fn new<B>(authtype: u16, body: B) -> Self
1077    where
1078        B: Into<Vec<u8>>,
1079    {
1080        Authenticate {
1081            authtype,
1082            auth: body.into(),
1083        }
1084    }
1085}
1086impl Body for Authenticate {
1087    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
1088        w.write_u16(self.authtype);
1089        let authlen = self
1090            .auth
1091            .len()
1092            .try_into()
1093            .map_err(|_| EncodeError::BadLengthValue)?;
1094        w.write_u16(authlen);
1095        w.write_all(&self.auth[..]);
1096        Ok(())
1097    }
1098}
1099impl Readable for Authenticate {
1100    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
1101        let authtype = r.take_u16()?;
1102        let authlen = r.take_u16()?;
1103        let auth = r.take(authlen as usize)?.into();
1104        Ok(Authenticate { authtype, auth })
1105    }
1106}
1107
1108/// Holds any message whose command we don't recognize.
1109///
1110/// Well-behaved Tor implementations are required to ignore commands
1111/// like this.
1112///
1113/// TODO: I believe that this is not a risky case of Postel's law,
1114/// since it is only for channels, but we should be careful here.
1115#[derive(Clone, Debug, Deftly)]
1116#[derive_deftly(HasMemoryCost)]
1117pub struct Unrecognized {
1118    /// The channel command that we got with this cell
1119    cmd: ChanCmd,
1120    /// The contents of the cell
1121    content: Vec<u8>,
1122}
1123impl Unrecognized {
1124    /// Construct a new cell of arbitrary or unrecognized type.
1125    pub fn new<B>(cmd: ChanCmd, content: B) -> Self
1126    where
1127        B: Into<Vec<u8>>,
1128    {
1129        let content = content.into();
1130        Unrecognized { cmd, content }
1131    }
1132    /// Return the command from this cell.
1133    pub fn cmd(&self) -> ChanCmd {
1134        self.cmd
1135    }
1136    /// Take an unrecognized cell's body from a reader `r`, and apply
1137    /// the given command to it.
1138    pub fn decode_with_cmd(cmd: ChanCmd, r: &mut Reader<'_>) -> Result<Unrecognized> {
1139        let mut u = Unrecognized::take_from(r)?;
1140        u.cmd = cmd;
1141        Ok(u)
1142    }
1143}
1144impl Body for Unrecognized {
1145    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
1146        w.write_all(&self.content[..]);
1147        Ok(())
1148    }
1149}
1150impl Readable for Unrecognized {
1151    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
1152        Ok(Unrecognized {
1153            cmd: 0.into(),
1154            content: r.take(r.remaining())?.into(),
1155        })
1156    }
1157}
1158
1159/// Helper: declare a From<> implementation from message types for
1160/// cells that don't take a circid.
1161macro_rules! msg_into_cell {
1162    ($body:ident) => {
1163        impl From<$body> for super::AnyChanCell {
1164            fn from(body: $body) -> super::AnyChanCell {
1165                super::AnyChanCell {
1166                    circid: None,
1167                    msg: body.into(),
1168                }
1169            }
1170        }
1171    };
1172}
1173
1174msg_into_cell!(Padding);
1175msg_into_cell!(Vpadding);
1176msg_into_cell!(Netinfo);
1177msg_into_cell!(Versions);
1178msg_into_cell!(PaddingNegotiate);
1179msg_into_cell!(Certs);
1180msg_into_cell!(AuthChallenge);
1181msg_into_cell!(Authenticate);
1182
1183/// Helper: declare a ChanMsg implementation for a message type that has a
1184/// fixed command.
1185//
1186// TODO: It might be better to merge Body with ChanMsg, but that is complex,
1187// since their needs are _slightly_ different.
1188//
1189// TODO: If we *do* make the change above, then perhaps we should also implement
1190// our restricted enums in terms of this, so that there is only one instance of
1191// [<$body:snake:upper>]
1192macro_rules! msg_impl_chanmsg {
1193    ($($body:ident,)*) =>
1194    {paste::paste!{
1195       $(impl crate::chancell::ChanMsg for $body {
1196            fn cmd(&self) -> crate::chancell::ChanCmd { crate::chancell::ChanCmd::[< $body:snake:upper >] }
1197            fn encode_onto<W: tor_bytes::Writer + ?Sized>(self, w: &mut W) -> tor_bytes::EncodeResult<()> {
1198                crate::chancell::msg::Body::encode_onto(self, w)
1199            }
1200            fn decode_from_reader(cmd: ChanCmd, r: &mut tor_bytes::Reader<'_>) -> tor_bytes::Result<Self> {
1201                if cmd != crate::chancell::ChanCmd::[< $body:snake:upper >] {
1202                    return Err(tor_bytes::Error::InvalidMessage(
1203                        format!("Expected {} command; got {cmd}", stringify!([< $body:snake:upper >])).into()
1204                    ));
1205                }
1206                crate::chancell::msg::Body::decode_from_reader(r)
1207            }
1208        })*
1209    }}
1210}
1211
1212// We implement ChanMsg for every body type, so that you can write code that does
1213// e.g. ChanCell<Relay>.
1214msg_impl_chanmsg!(
1215    Padding,
1216    Vpadding,
1217    Create,
1218    CreateFast,
1219    Create2,
1220    Created,
1221    CreatedFast,
1222    Created2,
1223    Relay,
1224    RelayEarly,
1225    Destroy,
1226    Netinfo,
1227    Versions,
1228    PaddingNegotiate,
1229    Certs,
1230    AuthChallenge,
1231    Authenticate,
1232);
1233
1234#[cfg(test)]
1235mod test {
1236    // @@ begin test lint list maintained by maint/add_warning @@
1237    #![allow(clippy::bool_assert_comparison)]
1238    #![allow(clippy::clone_on_copy)]
1239    #![allow(clippy::dbg_macro)]
1240    #![allow(clippy::mixed_attributes_style)]
1241    #![allow(clippy::print_stderr)]
1242    #![allow(clippy::print_stdout)]
1243    #![allow(clippy::single_char_pattern)]
1244    #![allow(clippy::unwrap_used)]
1245    #![allow(clippy::unchecked_duration_subtraction)]
1246    #![allow(clippy::useless_vec)]
1247    #![allow(clippy::needless_pass_by_value)]
1248    //! <!-- @@ end test lint list maintained by maint/add_warning @@ -->
1249    use super::*;
1250    #[test]
1251    fn destroy_reason() {
1252        let r1 = DestroyReason::CONNECTFAILED;
1253
1254        assert_eq!(r1.human_str(), "Couldn't connect to relay");
1255
1256        let r2 = DestroyReason::from(200); // not a specified number.
1257        assert_eq!(r2.human_str(), "Unrecognized reason");
1258    }
1259}