Skip to main content

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