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, 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    ///
479    /// If generating a new destroy cell,
480    /// you should always create it with [`DestroyReason::NONE`].
481    ///
482    /// `tor-spec/tearing-down-circuits.md`:
483    ///
484    /// > Implementations SHOULD always use the NONE reason to avoid side channels: [...]
485    pub fn new(reason: DestroyReason) -> Self {
486        Destroy { reason }
487    }
488    /// Return the provided reason for destroying the circuit.
489    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    /// Declared reason for ending a circuit.
508    #[derive(Deftly)]
509    #[derive_deftly(HasMemoryCost)]
510    pub struct DestroyReason(u8) {
511        /// No reason given.
512        ///
513        /// This is the only reason that clients send.
514        NONE = 0,
515        /// Protocol violation
516        PROTOCOL = 1,
517        /// Internal error.
518        INTERNAL = 2,
519        /// Client sent a TRUNCATE command.
520        REQUESTED = 3,
521        /// Relay is hibernating and not accepting requests
522        HIBERNATING = 4,
523        /// Ran out of memory, sockets, or circuit IDs
524        RESOURCELIMIT = 5,
525        /// Couldn't connect to relay.
526        CONNECTFAILED = 6,
527        /// Connected to a relay, but its OR identity wasn't as requested.
528        OR_IDENTITY = 7,
529        /// One of the OR channels carrying this circuit died.
530        CHANNEL_CLOSED = 8,
531        /// Circuit expired for being too dirty or old
532        FINISHED = 9,
533        /// Circuit construction took too long
534        TIMEOUT = 10,
535        /// Circuit was destroyed w/o client truncate (?)
536        DESTROYED = 11,
537        /// Request for unknown onion service
538        NOSUCHSERVICE = 12
539    }
540}
541
542impl DestroyReason {
543    /// Return a human-readable string for this reason.
544    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/// The netinfo message ends channel negotiation.
565///
566/// It tells the other party on the channel our view of the current time,
567/// our own list of public addresses, and our view of its address.
568///
569/// When we get a netinfo cell, we can start creating circuits on a
570/// channel and sending data.
571#[derive(Clone, Debug, Deftly)]
572#[derive_deftly(HasMemoryCost)]
573pub struct Netinfo {
574    /// Time when this cell was sent, or 0 if this cell is sent by a client.
575    ///
576    /// TODO-SPEC(nickm): Y2038 issue here.  Better add a new handshake version
577    /// to solve it.  See
578    /// [torspec#80](https://gitlab.torproject.org/tpo/core/torspec/-/issues/80).
579    timestamp: u32,
580    /// Observed address for party that did not send the netinfo cell.
581    their_addr: Option<IpAddr>,
582    /// Canonical addresses for the party that did send the netinfo cell.
583    my_addr: Vec<IpAddr>,
584}
585/// helper: encode a single address in the form that netinfo messages expect
586fn enc_one_netinfo_addr<W: Writer + ?Sized>(w: &mut W, addr: &IpAddr) {
587    match addr {
588        IpAddr::V4(ipv4) => {
589            w.write_u8(0x04); // type.
590            w.write_u8(4); // length.
591            w.write_all(&ipv4.octets()[..]);
592        }
593        IpAddr::V6(ipv6) => {
594            w.write_u8(0x06); // type.
595            w.write_u8(16); // length.
596            w.write_all(&ipv6.octets()[..]);
597        }
598    }
599}
600/// helper: take an address as encoded in a netinfo message
601fn 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            // TODO(nickm) is there a better way?
612            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    /// Construct a new Netinfo to be sent by a client.
621    pub fn from_client(their_addr: Option<IpAddr>) -> Self {
622        Netinfo {
623            timestamp: 0, // clients don't report their timestamps.
624            their_addr,
625            my_addr: Vec::new(), // clients don't report their addrs.
626        }
627    }
628    /// Construct a new Netinfo to be sent by a relay
629    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    /// Return the time reported in this NETINFO cell.
641    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    /// Return a reference to the their address field.
651    ///
652    /// None is returned if their address is 0.0.0.0/:: (unspecified).
653    pub fn their_addr(&self) -> Option<&IpAddr> {
654        self.their_addr.as_ref()
655    }
656
657    /// Return a reference to the my address field.
658    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/// A Versions message begins channel negotiation.
701///
702/// Every channel must begin by sending a Versions message.  This message
703/// lists the link protocol versions that this Tor implementation supports.
704///
705/// Note that we should never actually send Versions cells using the
706/// usual channel cell encoding: Versions cells _always_ use two-byte
707/// circuit IDs, whereas all the other cell types use four-byte
708/// circuit IDs [assuming a non-obsolete version is negotiated].
709#[derive(Clone, Debug, Deftly)]
710#[derive_deftly(HasMemoryCost)]
711pub struct Versions {
712    /// List of supported link protocol versions
713    versions: Vec<u16>,
714}
715impl Versions {
716    /// Construct a new Versions message using a provided list of link
717    /// protocols.
718    ///
719    /// Returns an error if the list of versions is too long.
720    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    /// Encode this VERSIONS cell in the manner expected for a handshake.
732    ///
733    /// (That's different from a standard cell encoding, since we
734    /// have not negotiated versions yet, and so our circuit-ID length
735    /// is an obsolete 2 bytes).
736    pub fn encode_for_handshake(self) -> EncodeResult<Vec<u8>> {
737        let mut v = Vec::new();
738        v.write_u16(0); // obsolete circuit ID length.
739        v.write_u8(ChanCmd::VERSIONS.into());
740        v.write_u16((self.versions.len() * 2) as u16); // message length.
741        self.encode_onto(&mut v)?;
742        Ok(v)
743    }
744    /// Return the best (numerically highest) link protocol that is
745    /// shared by this versions cell and my_protos.
746    pub fn best_shared_link_protocol(&self, my_protos: &[u16]) -> Option<u16> {
747        // NOTE: this implementation is quadratic, but it shouldn't matter
748        // much so long as my_protos is small.
749        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    /// A ChanCmd is the type of a channel cell.  The value of the ChanCmd
776    /// indicates the meaning of the cell, and (possibly) its length.
777    #[derive(Deftly)]
778    #[derive_deftly(HasMemoryCost)]
779    pub struct PaddingNegotiateCmd(u8) {
780        /// Start padding
781        START = 2,
782
783        /// Stop padding
784        STOP = 1,
785    }
786}
787
788/// A PaddingNegotiate message is used to negotiate channel padding.
789///
790/// Sent by a client to its guard node,
791/// to instruct the relay to enable/disable channel padding.
792/// (Not relevant for channels used only for directory lookups,
793/// nor inter-relay channels.)
794/// See `padding-spec.txt`, section 2.2.
795///
796/// This message is constructed in the channel manager and transmitted by the reactor.
797///
798/// The `Default` impl is the same as [`start_default()`](PaddingNegotiate::start_default`)
799#[derive(Clone, Debug, Eq, PartialEq, Deftly)]
800#[derive_deftly(HasMemoryCost)]
801pub struct PaddingNegotiate {
802    /// Whether to start or stop padding
803    command: PaddingNegotiateCmd,
804    /// Suggested lower-bound value for inter-packet timeout in msec.
805    // TODO(nickm) is that right?
806    ito_low_ms: u16,
807    /// Suggested upper-bound value for inter-packet timeout in msec.
808    // TODO(nickm) is that right?
809    ito_high_ms: u16,
810}
811impl PaddingNegotiate {
812    /// Create a new PADDING_NEGOTIATE START message requesting consensus timing parameters.
813    ///
814    /// This message restores the state to the one which exists at channel startup.
815    pub fn start_default() -> Self {
816        // Tor Spec section 7.3, padding-spec section 2.5.
817        Self {
818            command: PaddingNegotiateCmd::START,
819            ito_low_ms: 0,
820            ito_high_ms: 0,
821        }
822    }
823
824    /// Create a new PADDING_NEGOTIATE START message.
825    pub fn start(ito_low: IntegerMilliseconds<u16>, ito_high: IntegerMilliseconds<u16>) -> Self {
826        // Tor Spec section 7.3
827        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    /// Create a new PADDING_NEGOTIATE STOP message.
835    pub fn stop() -> Self {
836        // Tor Spec section 7.3
837        Self {
838            command: PaddingNegotiateCmd::STOP,
839            ito_low_ms: 0,
840            ito_high_ms: 0,
841        }
842    }
843
844    /// Construct from the three fields: command, low_ms, high_ms, as a tuple
845    ///
846    /// For testing only
847    #[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); // version
865        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/// A single certificate in a Certs cell.
891///
892/// The formats used here are implemented in tor-cert. Ed25519Cert is the
893/// most common.
894#[derive(Clone, Debug, Deftly)]
895#[derive_deftly(HasMemoryCost)]
896struct TorCert {
897    /// Type code for this certificate.
898    certtype: u8,
899    /// Encoded certificate
900    cert: Vec<u8>,
901}
902/// encode a single TorCert `c` onto a Writer `w`.
903fn 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}
914/// Try to extract a TorCert from the reader `r`.
915fn 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/// A Certs message is used as part of the channel handshake to send
925/// additional certificates.
926///
927/// These certificates are not presented as part of the TLS handshake.
928/// Originally this was meant to make Tor TLS handshakes look "normal", but
929/// nowadays it serves less purpose, especially now that we have TLS 1.3.
930///
931/// Every relay sends this message as part of channel negotiation;
932/// clients do not send them.
933#[derive(Clone, Debug, Deftly)]
934#[derive_deftly(HasMemoryCost)]
935pub struct Certs {
936    /// The certificates in this cell
937    certs: Vec<TorCert>,
938}
939impl Certs {
940    /// Return a new empty certs cell.
941    pub fn new_empty() -> Self {
942        Certs { certs: Vec::new() }
943    }
944    /// Add a new encoded certificate to this cell.
945    ///
946    /// Does not check anything about the well-formedness of the certificate.
947    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    /// Add a new encoded certificate to this cell,
957    /// taking taking the type from the certificate itself.
958    #[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    /// Return the body of the certificate tagged with 'tp', if any.
967    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    /// Look for a certificate of type 'tp' in this cell; return it if
976    /// there is one.
977    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
1023/// Length of the body for an authentication challenge
1024const CHALLENGE_LEN: usize = 32;
1025
1026/// An AuthChallenge message is part of negotiation, sent by
1027/// responders to initiators.
1028///
1029/// The AuthChallenge cell is used to ensure that some unpredictable material
1030/// has been sent on the channel, and to tell the initiator what
1031/// authentication methods will be accepted.
1032///
1033/// Clients can safely ignore this message: they don't need to authenticate.
1034#[derive(Clone, Debug, Deftly)]
1035#[derive_deftly(HasMemoryCost)]
1036pub struct AuthChallenge {
1037    /// Random challenge to be used in generating response
1038    challenge: [u8; CHALLENGE_LEN],
1039    /// List of permitted authentication methods
1040    methods: Vec<u16>,
1041}
1042impl AuthChallenge {
1043    /// Construct a new AuthChallenge cell with a given challenge
1044    /// value (chosen randomly) and a set of acceptable authentication methods.
1045    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    /// Return a reference to the list of methods.
1057    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.take(CHALLENGE_LEN)?.into();
1080        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/// Part of negotiation: sent by initiators to responders.
1091///
1092/// The Authenticate cell proves the initiator's identity to the
1093/// responder, even if TLS client authentication was not used.
1094///
1095/// Clients do not use this.
1096#[derive(Clone, Debug, Deftly, Eq, PartialEq)]
1097#[derive_deftly(HasMemoryCost)]
1098pub struct Authenticate {
1099    /// Authentication method in use
1100    authtype: u16,
1101    /// Encoded authentication object
1102    auth: Vec<u8>,
1103}
1104impl Authenticate {
1105    /// The signature field length.
1106    const SIG_LEN: usize = 64;
1107    /// The body length that is all fields except the rand and signature.
1108    pub const BODY_LEN: usize = 264;
1109
1110    /// Create a new Authenticate message from a given type and body.
1111    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    /// Return the authentication type value.
1122    pub fn auth_type(&self) -> u16 {
1123        self.authtype
1124    }
1125
1126    /// Return a referrence to the body of the cell that is all fields minus the random bytes
1127    /// located before the signature.
1128    pub fn body_no_rand(&self) -> Result<&[u8]> {
1129        // The RAND field length.
1130        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    /// Return a referrence to the body of the cell that is all fields except the signature.
1137    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    /// Return a reference to the authentcation object.
1147    pub fn auth(&self) -> &[u8] {
1148        &self.auth
1149    }
1150
1151    /// Return a reference to the signature bytes.
1152    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/// Holds any message whose command we don't recognize.
1186///
1187/// Well-behaved Tor implementations are required to ignore commands
1188/// like this.
1189///
1190/// TODO: I believe that this is not a risky case of Postel's law,
1191/// since it is only for channels, but we should be careful here.
1192#[derive(Clone, Debug, Deftly)]
1193#[derive_deftly(HasMemoryCost)]
1194pub struct Unrecognized {
1195    /// The channel command that we got with this cell
1196    cmd: ChanCmd,
1197    /// The contents of the cell
1198    content: Vec<u8>,
1199}
1200impl Unrecognized {
1201    /// Construct a new cell of arbitrary or unrecognized type.
1202    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    /// Return the command from this cell.
1210    pub fn cmd(&self) -> ChanCmd {
1211        self.cmd
1212    }
1213    /// Take an unrecognized cell's body from a reader `r`, and apply
1214    /// the given command to it.
1215    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
1236/// Helper: declare a From<> implementation from message types for
1237/// cells that don't take a circid.
1238macro_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
1260/// Helper: declare a ChanMsg implementation for a message type that has a
1261/// fixed command.
1262//
1263// TODO: It might be better to merge Body with ChanMsg, but that is complex,
1264// since their needs are _slightly_ different.
1265//
1266// TODO: If we *do* make the change above, then perhaps we should also implement
1267// our restricted enums in terms of this, so that there is only one instance of
1268// [<$body:snake:upper>]
1269macro_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
1289// We implement ChanMsg for every body type, so that you can write code that does
1290// e.g. ChanCell<Relay>.
1291msg_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    // @@ begin test lint list maintained by maint/add_warning @@
1314    #![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)] // See arti#2571
1326    //! <!-- @@ end test lint list maintained by maint/add_warning @@ -->
1327    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); // not a specified number.
1335        assert_eq!(r2.human_str(), "Unrecognized reason");
1336    }
1337}