1
//! Different kinds of messages that can be encoded in channel cells.
2

            
3
use super::{ChanCmd, RawCellBody, CELL_DATA_LEN};
4
use std::convert::TryInto;
5
use std::net::{IpAddr, Ipv4Addr};
6
use tor_basic_utils::skip_fmt;
7
use tor_bytes::{self, Error, Readable, Reader, Result, Writer};
8

            
9
use caret::caret_int;
10
use educe::Educe;
11

            
12
/// Trait for the 'bodies' of channel messages.
13
pub trait Body: Readable {
14
    /// Convert this type into a ChanMsg, wrapped as appropriate.
15
    fn into_message(self) -> ChanMsg;
16
    /// Consume this message and encode its body onto `w`.
17
    ///
18
    /// Does not encode anything _but_ the cell body, and does not pad
19
    /// to the cell length.
20
    fn write_body_onto<W: Writer + ?Sized>(self, w: &mut W);
21
}
22

            
23
/// Decoded message from a channel.
24
///
25
/// A ChanMsg is an item received on a channel -- a message from
26
/// another Tor client or relay that we are connected to directly over
27
/// a TLS connection.
28
#[non_exhaustive]
29
1476
#[derive(Clone, Debug)]
30
pub enum ChanMsg {
31
    /// A Padding message
32
    Padding(Padding),
33
    /// Variable-length padding message
34
    VPadding(VPadding),
35
    /// (Deprecated) TAP-based cell to create a new circuit.
36
    Create(Create),
37
    /// (Mostly deprecated) HMAC-based cell to create a new circuit.
38
    CreateFast(CreateFast),
39
    /// Cell to create a new circuit
40
    Create2(Create2),
41
    /// (Deprecated) Answer to a Create cell
42
    Created(Created),
43
    /// (Mostly Deprecated) Answer to a CreateFast cell
44
    CreatedFast(CreatedFast),
45
    /// Answer to a Create2 cell
46
    Created2(Created2),
47
    /// A message sent along a circuit, likely to a more-distant relay.
48
    Relay(Relay),
49
    /// A message sent along a circuit (limited supply)
50
    RelayEarly(Relay),
51
    /// Tear down a circuit
52
    Destroy(Destroy),
53
    /// Part of channel negotiation: describes our position on the network
54
    Netinfo(Netinfo),
55
    /// Part of channel negotiation: describes what link protocol versions
56
    /// we support
57
    Versions(Versions),
58
    /// Negotiates what kind of channel padding to send
59
    PaddingNegotiate(PaddingNegotiate),
60
    /// Part of channel negotiation: additional certificates not in the
61
    /// TLS handshake
62
    Certs(Certs),
63
    /// Part of channel negotiation: additional random material to be used
64
    /// as part of authentication
65
    AuthChallenge(AuthChallenge),
66
    /// Part of channel negotiation: used to authenticate relays when they
67
    /// initiate the channel.
68
    Authenticate(Authenticate),
69
    /// Not yet used
70
    Authorize(Authorize),
71
    /// Any cell whose command we don't recognize
72
    Unrecognized(Unrecognized),
73
}
74

            
75
impl ChanMsg {
76
    /// Return the ChanCmd for this message.
77
1716
    pub fn cmd(&self) -> ChanCmd {
78
1716
        use ChanMsg::*;
79
1716
        match self {
80
66
            Padding(_) => ChanCmd::PADDING,
81
44
            VPadding(_) => ChanCmd::VPADDING,
82
44
            Create(_) => ChanCmd::CREATE,
83
44
            CreateFast(_) => ChanCmd::CREATE_FAST,
84
110
            Create2(_) => ChanCmd::CREATE2,
85
110
            Created(_) => ChanCmd::CREATED,
86
44
            CreatedFast(_) => ChanCmd::CREATED_FAST,
87
132
            Created2(_) => ChanCmd::CREATED2,
88
110
            Relay(_) => ChanCmd::RELAY,
89
44
            RelayEarly(_) => ChanCmd::RELAY_EARLY,
90
220
            Destroy(_) => ChanCmd::DESTROY,
91
132
            Netinfo(_) => ChanCmd::NETINFO,
92
154
            Versions(_) => ChanCmd::VERSIONS,
93
22
            PaddingNegotiate(_) => ChanCmd::PADDING_NEGOTIATE,
94
286
            Certs(_) => ChanCmd::CERTS,
95
22
            AuthChallenge(_) => ChanCmd::AUTH_CHALLENGE,
96
22
            Authenticate(_) => ChanCmd::AUTHENTICATE,
97
22
            Authorize(_) => ChanCmd::AUTHORIZE,
98
88
            Unrecognized(c) => c.cmd(),
99
        }
100
1716
    }
101

            
102
    /// Write the body of this message (not including length or command).
103
402
    pub fn write_body_onto<W: Writer + ?Sized>(self, w: &mut W) {
104
402
        use ChanMsg::*;
105
402
        match self {
106
46
            Padding(b) => b.write_body_onto(w),
107
4
            VPadding(b) => b.write_body_onto(w),
108
2
            Create(b) => b.write_body_onto(w),
109
2
            CreateFast(b) => b.write_body_onto(w),
110
2
            Create2(b) => b.write_body_onto(w),
111
2
            Created(b) => b.write_body_onto(w),
112
2
            CreatedFast(b) => b.write_body_onto(w),
113
2
            Created2(b) => b.write_body_onto(w),
114
46
            Relay(b) => b.write_body_onto(w),
115
2
            RelayEarly(b) => b.write_body_onto(w),
116
92
            Destroy(b) => b.write_body_onto(w),
117
52
            Netinfo(b) => b.write_body_onto(w),
118
2
            Versions(b) => b.write_body_onto(w),
119
2
            PaddingNegotiate(b) => b.write_body_onto(w),
120
90
            Certs(b) => b.write_body_onto(w),
121
2
            AuthChallenge(b) => b.write_body_onto(w),
122
2
            Authenticate(b) => b.write_body_onto(w),
123
2
            Authorize(b) => b.write_body_onto(w),
124
48
            Unrecognized(b) => b.write_body_onto(w),
125
        }
126
402
    }
127

            
128
    /// Decode this message from a given reader, according to a specified
129
    /// command value. The reader must be truncated to the exact length
130
    /// of the body.
131
1342
    pub fn take(r: &mut Reader<'_>, cmd: ChanCmd) -> Result<Self> {
132
1342
        use ChanMsg::*;
133
1342
        Ok(match cmd {
134
66
            ChanCmd::PADDING => Padding(r.extract()?),
135
88
            ChanCmd::VPADDING => VPadding(r.extract()?),
136
44
            ChanCmd::CREATE => Create(r.extract()?),
137
22
            ChanCmd::CREATE_FAST => CreateFast(r.extract()?),
138
22
            ChanCmd::CREATE2 => Create2(r.extract()?),
139
22
            ChanCmd::CREATED => Created(r.extract()?),
140
22
            ChanCmd::CREATED_FAST => CreatedFast(r.extract()?),
141
22
            ChanCmd::CREATED2 => Created2(r.extract()?),
142
110
            ChanCmd::RELAY => Relay(r.extract()?),
143
22
            ChanCmd::RELAY_EARLY => RelayEarly(r.extract()?),
144
132
            ChanCmd::DESTROY => Destroy(r.extract()?),
145
220
            ChanCmd::NETINFO => Netinfo(r.extract()?),
146
22
            ChanCmd::VERSIONS => Versions(r.extract()?),
147
44
            ChanCmd::PADDING_NEGOTIATE => PaddingNegotiate(r.extract()?),
148
264
            ChanCmd::CERTS => Certs(r.extract()?),
149
88
            ChanCmd::AUTH_CHALLENGE => AuthChallenge(r.extract()?),
150
22
            ChanCmd::AUTHENTICATE => Authenticate(r.extract()?),
151
22
            ChanCmd::AUTHORIZE => Authorize(r.extract()?),
152
88
            _ => Unrecognized(unrecognized_with_cmd(cmd, r)?),
153
        })
154
1342
    }
155
}
156

            
157
/// A Padding message is a fixed-length message on a channel that is
158
/// ignored.
159
///
160
/// Padding message can be used to disguise the true amount of data on a
161
/// channel, or as a "keep-alive".
162
///
163
/// The correct response to a padding cell is to drop it and do nothing.
164
132
#[derive(Clone, Debug, Default)]
165
#[non_exhaustive]
166
pub struct Padding {}
167
impl Padding {
168
    /// Create a new fixed-length padding cell
169
22
    pub fn new() -> Self {
170
22
        Padding {}
171
22
    }
172
}
173
impl Body for Padding {
174
44
    fn into_message(self) -> ChanMsg {
175
44
        ChanMsg::Padding(self)
176
44
    }
177
46
    fn write_body_onto<W: Writer + ?Sized>(self, _w: &mut W) {}
178
}
179
impl Readable for Padding {
180
66
    fn take_from(_r: &mut Reader<'_>) -> Result<Self> {
181
66
        Ok(Padding {})
182
66
    }
183
}
184

            
185
/// A VPadding message is a variable-length padding message.
186
///
187
/// The correct response to a padding cell is to drop it and do nothing.
188
88
#[derive(Clone, Debug)]
189
pub struct VPadding {
190
    /// How much padding to send in this cell's body.
191
    len: u16,
192
}
193
impl VPadding {
194
    /// Return a new vpadding cell with given length.
195
44
    pub fn new(len: u16) -> Self {
196
44
        VPadding { len }
197
44
    }
198
}
199
impl Body for VPadding {
200
44
    fn into_message(self) -> ChanMsg {
201
44
        ChanMsg::VPadding(self)
202
44
    }
203
4
    fn write_body_onto<W: Writer + ?Sized>(self, w: &mut W) {
204
4
        w.write_zeros(self.len as usize);
205
4
    }
206
}
207
impl Readable for VPadding {
208
88
    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
209
88
        if r.remaining() > std::u16::MAX as usize {
210
            return Err(Error::BadMessage("Too many bytes in VPADDING cell"));
211
88
        }
212
88
        Ok(VPadding {
213
88
            len: r.remaining() as u16,
214
88
        })
215
88
    }
216
}
217

            
218
/// helper -- declare a fixed-width cell where a fixed number of bytes
219
/// matter and the rest are ignored
220
macro_rules! fixed_len {
221
    {
222
        $(#[$meta:meta])*
223
        $name:ident , $cmd:ident, $len:ident
224
    } => {
225
        $(#[$meta])*
226
176
        #[derive(Clone,Debug)]
227
        pub struct $name {
228
            handshake: Vec<u8>
229
        }
230
        impl $name {
231
            /// Create a new cell from a provided handshake.
232
21
            pub fn new<B>(handshake: B) -> Self
233
21
                where B: Into<Vec<u8>>
234
21
            {
235
21
                let handshake = handshake.into();
236
21
                $name { handshake }
237
21
            }
238
        }
239
        impl Body for $name {
240
330
            fn into_message(self) -> ChanMsg {
241
330
                ChanMsg::$name(self)
242
330
            }
243
8
            fn write_body_onto<W: Writer + ?Sized>(self, w: &mut W) {
244
8
                w.write_all(&self.handshake[..])
245
8
            }
246
        }
247
        impl Readable for $name {
248
110
            fn take_from(r: &mut Reader<'_>) -> Result<Self> {
249
110
                Ok($name {
250
110
                    handshake: r.take($len)?.into(),
251
                })
252
110
            }
253
        }
254
    }
255
}
256

            
257
/// Number of bytes used for a TAP handshake by the initiator.
258
pub(crate) const TAP_C_HANDSHAKE_LEN: usize = 128 + 16 + 42;
259
/// Number of bytes used for a TAP handshake response
260
pub(crate) const TAP_S_HANDSHAKE_LEN: usize = 128 + 20;
261

            
262
/// Number of bytes used for a CREATE_FAST handshake by the initiator
263
const FAST_C_HANDSHAKE_LEN: usize = 20;
264
/// Number of bytes used for a CRATE_FAST handshake response
265
const FAST_S_HANDSHAKE_LEN: usize = 20 + 20;
266

            
267
fixed_len! {
268
    /// A Create message creates a circuit, using the TAP handshake.
269
    ///
270
    /// TAP is an obsolete handshake based on RSA-1024 and DH-1024.
271
    /// Relays respond to Create message with a Created reply on
272
    /// success, or a Destroy message on failure.
273
    ///
274
    /// In Tor today, Create is only used for the deprecated v2 onion
275
    /// service protocol.
276
    Create, CREATE, TAP_C_HANDSHAKE_LEN
277
}
278
fixed_len! {
279
    /// A Created message responds to a Created message, using the TAP
280
    /// handshake.
281
    ///
282
    /// TAP is an obsolete handshake based on RSA-1024 and DH-1024.
283
    Created, CREATED, TAP_S_HANDSHAKE_LEN
284
}
285
fixed_len! {
286
    /// A CreateFast message creates a circuit using no public-key crypto.
287
    ///
288
    /// CreateFast is safe only when used on an already-secure TLS
289
    /// connection.  It can only be used for the first hop of a circuit.
290
    ///
291
    /// Relays reply to a CreateFast message with CreatedFast on
292
    /// success, or a Destroy message on failure.
293
    ///
294
    /// This handshake was originally used for the first hop of every
295
    /// circuit.  Nowadays it is used for creating one-hop circuits
296
    /// when we don't know any onion key for the first hop.
297
    CreateFast, CREATE_FAST, FAST_C_HANDSHAKE_LEN
298
}
299
impl CreateFast {
300
    /// Return the content of this handshake
301
110
    pub fn body(&self) -> &[u8] {
302
110
        &self.handshake
303
110
    }
304
}
305
fixed_len! {
306
    /// A CreatedFast message responds to a CreateFast message
307
    ///
308
    /// Relays send this message back to indicate that the CrateFast handshake
309
    /// is complete.
310
    CreatedFast, CREATED_FAST, FAST_S_HANDSHAKE_LEN
311
}
312
impl CreatedFast {
313
    /// Consume this message and return the content of this handshake
314
110
    pub fn into_body(self) -> Vec<u8> {
315
110
        self.handshake
316
110
    }
317
}
318

            
319
/// A Create2 message create a circuit on the current channel.
320
///
321
/// To create a circuit, the client sends a Create2 cell containing a
322
/// handshake of a given type; the relay responds with a Created2 cell
323
/// containing a reply.
324
///
325
/// Currently, most Create2 cells contain a client-side instance of the
326
/// "ntor" handshake.
327
44
#[derive(Clone, Debug)]
328
pub struct Create2 {
329
    /// Identifier for what kind of handshake this is.
330
    handshake_type: u16,
331
    /// Body of the handshake.
332
    handshake: Vec<u8>,
333
}
334
impl Body for Create2 {
335
286
    fn into_message(self) -> ChanMsg {
336
286
        ChanMsg::Create2(self)
337
286
    }
338
2
    fn write_body_onto<W: Writer + ?Sized>(self, w: &mut W) {
339
2
        w.write_u16(self.handshake_type);
340
2
        assert!(self.handshake.len() <= std::u16::MAX as usize);
341
2
        w.write_u16(self.handshake.len() as u16);
342
2
        w.write_all(&self.handshake[..]);
343
2
    }
344
}
345
impl Readable for Create2 {
346
22
    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
347
22
        let handshake_type = r.take_u16()?;
348
22
        let hlen = r.take_u16()?;
349
22
        let handshake = r.take(hlen as usize)?.into();
350
22
        Ok(Create2 {
351
22
            handshake_type,
352
22
            handshake,
353
22
        })
354
22
    }
355
}
356
impl Create2 {
357
    /// Wrap a typed handshake as a Create2 message
358
14
    pub fn new<B>(handshake_type: u16, handshake: B) -> Self
359
14
    where
360
14
        B: Into<Vec<u8>>,
361
14
    {
362
14
        let handshake = handshake.into();
363
14
        Create2 {
364
14
            handshake_type,
365
14
            handshake,
366
14
        }
367
14
    }
368

            
369
    /// Return the type of this handshake.
370
22
    pub fn handshake_type(&self) -> u16 {
371
22
        self.handshake_type
372
22
    }
373

            
374
    /// Return the body of this handshake.
375
110
    pub fn body(&self) -> &[u8] {
376
110
        &self.handshake[..]
377
110
    }
378
}
379

            
380
/// A Created2 message completes a circuit-creation handshake.
381
///
382
/// When a relay receives a valid Create2 message that it can handle, it
383
/// establishes the circuit and replies with a Created2.
384
44
#[derive(Clone, Debug)]
385
pub struct Created2 {
386
    /// Body of the handshake reply
387
    handshake: Vec<u8>,
388
}
389
impl Created2 {
390
    /// Create a new Created2 to hold a given handshake.
391
16
    pub fn new<B>(handshake: B) -> Self
392
16
    where
393
16
        B: Into<Vec<u8>>,
394
16
    {
395
16
        let handshake = handshake.into();
396
16
        Created2 { handshake }
397
16
    }
398
    /// Consume this created2 cell and return its body.
399
110
    pub fn into_body(self) -> Vec<u8> {
400
110
        self.handshake
401
110
    }
402
}
403
impl Body for Created2 {
404
242
    fn into_message(self) -> ChanMsg {
405
242
        ChanMsg::Created2(self)
406
242
    }
407
2
    fn write_body_onto<W: Writer + ?Sized>(self, w: &mut W) {
408
2
        assert!(self.handshake.len() <= std::u16::MAX as usize);
409
2
        w.write_u16(self.handshake.len() as u16);
410
2
        w.write_all(&self.handshake[..]);
411
2
    }
412
}
413
impl Readable for Created2 {
414
22
    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
415
22
        let hlen = r.take_u16()?;
416
22
        let handshake = r.take(hlen as usize)?.into();
417
22
        Ok(Created2 { handshake })
418
22
    }
419
}
420

            
421
/// A Relay cell - that is, one transmitted over a circuit.
422
///
423
/// Once a circuit has been established, relay cells can be sent over
424
/// it.  Clients can send relay cells to any relay on the circuit. Any
425
/// relay on the circuit can send relay cells to the client, either
426
/// directly (if it is the first hop), or indirectly through the
427
/// intermediate hops.
428
///
429
/// A different protocol is defined over the relay cells; it is implemented
430
/// in the [crate::relaycell] module.
431
452
#[derive(Clone, Educe)]
432
#[educe(Debug)]
433
pub struct Relay {
434
    /// The contents of the relay cell as encoded for transfer.
435
    ///
436
    /// TODO(nickm): It's nice that this is boxed, since we don't want to copy
437
    /// cell data all over the place. But unfortunately, a there are some other
438
    /// places where we _don't_ Box things that we should, and more copies than
439
    /// necessary happen. We should refactor our data handling until we're mostly
440
    /// moving around pointers rather than copying data;  see ticket #7.
441
    #[educe(Debug(method = "skip_fmt"))]
442
    body: Box<RawCellBody>,
443
}
444
impl Relay {
445
    /// Construct a Relay message from a slice containing its contents.
446
13
    pub fn new<P>(body: P) -> Self
447
13
    where
448
13
        P: AsRef<[u8]>,
449
13
    {
450
13
        let body = body.as_ref();
451
13
        let mut r = [0_u8; CELL_DATA_LEN];
452
13
        // TODO: This will panic if body is too long, but that would be a
453
13
        // programming error anyway.
454
13
        r[..body.len()].copy_from_slice(body);
455
13
        Relay { body: Box::new(r) }
456
13
    }
457
    /// Construct a Relay message from its body.
458
54934
    pub fn from_raw(body: RawCellBody) -> Self {
459
54934
        Relay {
460
54934
            body: Box::new(body),
461
54934
        }
462
54934
    }
463

            
464
    /// Consume this Relay message and return a RelayCellBody for
465
    /// encryption/decryption.
466
54582
    pub fn into_relay_body(self) -> RawCellBody {
467
54582
        *self.body
468
54582
    }
469
    /// Wrap this Relay message into a RelayMsg as a RELAY_EARLY cell.
470
22
    pub fn into_early(self) -> ChanMsg {
471
22
        ChanMsg::RelayEarly(self)
472
22
    }
473
}
474
impl Body for Relay {
475
242
    fn into_message(self) -> ChanMsg {
476
242
        ChanMsg::Relay(self)
477
242
    }
478
48
    fn write_body_onto<W: Writer + ?Sized>(self, w: &mut W) {
479
48
        w.write_all(&self.body[..]);
480
48
    }
481
}
482
impl Readable for Relay {
483
132
    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
484
132
        let mut body = Box::new([0_u8; CELL_DATA_LEN]);
485
132
        body.copy_from_slice(r.take(CELL_DATA_LEN)?);
486
132
        Ok(Relay { body })
487
132
    }
488
}
489

            
490
/// The Destroy message tears down a circuit.
491
///
492
/// On receiving a Destroy message, a Tor implementation should
493
/// tear down the associated circuit, and pass the destroy message
494
/// down the circuit to later/earlier hops on the circuit (if any).
495
100
#[derive(Clone, Debug)]
496
pub struct Destroy {
497
    /// Reason code given for tearing down this circuit
498
    reason: DestroyReason,
499
}
500
impl Destroy {
501
    /// Create a new destroy cell.
502
440
    pub fn new(reason: DestroyReason) -> Self {
503
440
        Destroy { reason }
504
440
    }
505
    /// Return the provided reason for destroying the circuit.
506
88
    pub fn reason(&self) -> DestroyReason {
507
88
        self.reason
508
88
    }
509
}
510
impl Body for Destroy {
511
352
    fn into_message(self) -> ChanMsg {
512
352
        ChanMsg::Destroy(self)
513
352
    }
514
92
    fn write_body_onto<W: Writer + ?Sized>(self, w: &mut W) {
515
92
        w.write_u8(self.reason.into());
516
92
    }
517
}
518
impl Readable for Destroy {
519
132
    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
520
132
        let reason = r.take_u8()?.into();
521
132
        Ok(Destroy { reason })
522
132
    }
523
}
524

            
525
caret_int! {
526
    /// Declared reason for ending a circuit.
527
    pub struct DestroyReason(u8) {
528
        /// No reason given.
529
        ///
530
        /// (This is the only reason that clients send.
531
        NONE = 0,
532
        /// Protocol violation
533
        PROTOCOL = 1,
534
        /// Internal error.
535
        INTERNAL = 2,
536
        /// Client sent a TRUNCATE command.
537
        REQUESTED = 3,
538
        /// Relay is hibernating and not accepting requests
539
        HIBERNATING = 4,
540
        /// Ran out of memory, sockets, or circuit IDs
541
        RESOURCELIMIT = 5,
542
        /// Couldn't connect to relay.
543
        CONNECTFAILED = 6,
544
        /// Connected to a relay, but its OR identity wasn't as requested.
545
        OR_IDENTITY = 7,
546
        /// One of the OR channels carrying this circuit died.
547
        CHANNEL_CLOSED = 8,
548
        /// Circuit expired for being too dirty or old
549
        FINISHED = 9,
550
        /// Circuit construction took too long
551
        TIMEOUT = 10,
552
        /// Circuit was destroyed w/o client truncate (?)
553
        DESTROYED = 11,
554
        /// Request for unknown onion service
555
        NOSUCHSERVICE = 12
556
    }
557
}
558

            
559
impl DestroyReason {
560
    /// Return a human-readable string for this reason.
561
2
    pub fn human_str(&self) -> &'static str {
562
2
        match *self {
563
            DestroyReason::NONE => "No reason",
564
            DestroyReason::PROTOCOL => "Protocol violation",
565
            DestroyReason::INTERNAL => "Internal error",
566
            DestroyReason::REQUESTED => "Client sent a TRUNCATE command",
567
            DestroyReason::HIBERNATING => "Relay is hibernating and not accepting requests",
568
            DestroyReason::RESOURCELIMIT => "Relay ran out of resources",
569
1
            DestroyReason::CONNECTFAILED => "Couldn't connect to relay",
570
            DestroyReason::OR_IDENTITY => "Connected to relay with different OR identity",
571
            DestroyReason::CHANNEL_CLOSED => "The OR channels carrying this circuit died",
572
            DestroyReason::FINISHED => "Circuit expired for being too dirty or old",
573
            DestroyReason::TIMEOUT => "Circuit construction took too long",
574
            DestroyReason::DESTROYED => "Circuit was destroyed without client truncate",
575
            DestroyReason::NOSUCHSERVICE => "No such onion service",
576
1
            _ => "Unrecognized reason",
577
        }
578
2
    }
579
}
580

            
581
/// The netinfo message ends channel negotiation.
582
///
583
/// It tells the other party on the channel our view of the current time,
584
/// our own list of public addresses, and our view of its address.
585
///
586
/// When we get a netinfo cell, we can start creating circuits on a
587
/// channel and sending data.
588
220
#[derive(Clone, Debug)]
589
pub struct Netinfo {
590
    /// Time when this cell was sent, or 0 if this cell is sent by
591
    /// a client.
592
    timestamp: u32,
593
    /// Observed address for party that did not send the netinfo cell.
594
    their_addr: Option<IpAddr>,
595
    /// Canonical addresses for the party that did send the netinfo cell.
596
    my_addr: Vec<IpAddr>,
597
}
598
/// helper: encode a single address in the form that netinfo messages expect
599
58
fn enc_one_netinfo_addr<W: Writer + ?Sized>(w: &mut W, addr: &IpAddr) {
600
58
    match addr {
601
54
        IpAddr::V4(ipv4) => {
602
54
            w.write_u8(0x04); // type.
603
54
            w.write_u8(4); // length.
604
54
            w.write_all(&ipv4.octets()[..]);
605
54
        }
606
4
        IpAddr::V6(ipv6) => {
607
4
            w.write_u8(0x06); // type.
608
4
            w.write_u8(16); // length.
609
4
            w.write_all(&ipv6.octets()[..]);
610
4
        }
611
    }
612
58
}
613
/// helper: take an address as encoded in a netinfo message
614
506
fn take_one_netinfo_addr(r: &mut Reader<'_>) -> Result<Option<IpAddr>> {
615
506
    let atype = r.take_u8()?;
616
506
    let alen = r.take_u8()?;
617
506
    let abody = r.take(alen as usize)?;
618
506
    match (atype, alen) {
619
        (0x04, 4) => {
620
154
            let bytes = [abody[0], abody[1], abody[2], abody[3]];
621
154
            Ok(Some(IpAddr::V4(bytes.into())))
622
        }
623
        (0x06, 16) => {
624
            // TODO(nickm) is there a better way?
625
66
            let mut bytes = [0_u8; 16];
626
66
            bytes.copy_from_slice(abody);
627
66
            Ok(Some(IpAddr::V6(bytes.into())))
628
        }
629
22
        (0x04, _) => Ok(None),
630
22
        (0x06, _) => Ok(None),
631
242
        (_, _) => Ok(None),
632
    }
633
506
}
634
impl Netinfo {
635
    /// Construct a new Netinfo to be sent by a client.
636
330
    pub fn for_client(their_addr: Option<IpAddr>) -> Self {
637
330
        Netinfo {
638
330
            timestamp: 0, // clients don't report their timestamps.
639
330
            their_addr,
640
330
            my_addr: Vec::new(), // clients don't report their addrs.
641
330
        }
642
330
    }
643
    /// Construct a new Netinfo to be sent by a relay
644
3
    pub fn for_relay<V>(timestamp: u32, their_addr: Option<IpAddr>, my_addrs: V) -> Self
645
3
    where
646
3
        V: Into<Vec<IpAddr>>,
647
3
    {
648
3
        let my_addr = my_addrs.into();
649
3
        Netinfo {
650
3
            timestamp,
651
3
            their_addr,
652
3
            my_addr,
653
3
        }
654
3
    }
655
}
656
impl Body for Netinfo {
657
154
    fn into_message(self) -> ChanMsg {
658
154
        ChanMsg::Netinfo(self)
659
154
    }
660
52
    fn write_body_onto<W: Writer + ?Sized>(self, w: &mut W) {
661
52
        w.write_u32(self.timestamp);
662
52
        let their_addr = self
663
52
            .their_addr
664
52
            .unwrap_or_else(|| Ipv4Addr::UNSPECIFIED.into());
665
52
        enc_one_netinfo_addr(w, &their_addr);
666
52
        let n_addrs: u8 = self
667
52
            .my_addr
668
52
            .len()
669
52
            .try_into()
670
52
            .expect("Too many addrs in netinfo cell");
671
52
        w.write_u8(n_addrs);
672
58
        for addr in &self.my_addr {
673
6
            enc_one_netinfo_addr(w, addr);
674
6
        }
675
52
    }
676
}
677
impl Readable for Netinfo {
678
220
    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
679
220
        let timestamp = r.take_u32()?;
680
220
        let their_addr = take_one_netinfo_addr(r)?.filter(|a| !a.is_unspecified());
681
220
        let mut my_addr = Vec::new();
682
220
        let my_n_addrs = r.take_u8()?;
683
220
        for _ in 0..my_n_addrs {
684
286
            if let Some(a) = take_one_netinfo_addr(r)? {
685
110
                my_addr.push(a);
686
176
            }
687
        }
688
220
        Ok(Netinfo {
689
220
            timestamp,
690
220
            their_addr,
691
220
            my_addr,
692
220
        })
693
220
    }
694
}
695

            
696
/// A Versions message begins channel negotiation.
697
///
698
/// Every channel must begin by sending a Versions message.  This message
699
/// lists the link protocol versions that this Tor implementation supports.
700
///
701
/// Note that we should never actually send Versions cells using the
702
/// usual channel cell encoding: Versions cells _always_ use two-byte
703
/// circuit IDs, whereas all the other cell types use four-byte
704
/// circuit IDs [assuming a non-obsolete version is negotiated].
705
44
#[derive(Clone, Debug)]
706
pub struct Versions {
707
    /// List of supported link protocol versions
708
    versions: Vec<u16>,
709
}
710
impl Versions {
711
    /// Construct a new Versions message using a provided list of link
712
    /// protocols.
713
    ///
714
    /// Returns an error if the list of versions is too long.
715
18
    pub fn new<B>(vs: B) -> crate::Result<Self>
716
18
    where
717
18
        B: Into<Vec<u16>>,
718
18
    {
719
18
        let versions = vs.into();
720
18
        if versions.len() < (std::u16::MAX / 2) as usize {
721
18
            Ok(Self { versions })
722
        } else {
723
            Err(crate::Error::CantEncode)
724
        }
725
18
    }
726
    /// Encode this VERSIONS cell in the manner expected for a handshake.
727
    ///
728
    /// (That's different from a standard cell encoding, since we
729
    /// have not negotiated versions yet, and so our circuit-ID length
730
    /// is an obsolete 2 bytes).
731
242
    pub fn encode_for_handshake(self) -> Vec<u8> {
732
242
        let mut v = Vec::new();
733
242
        v.write_u16(0); // obsolete circuit ID length.
734
242
        v.write_u8(ChanCmd::VERSIONS.into());
735
242
        v.write_u16((self.versions.len() * 2) as u16); // message length.
736
242
        self.write_body_onto(&mut v);
737
242
        v
738
242
    }
739
    /// Return the best (numerically highest) link protocol that is
740
    /// shared by this versions cell and my_protos.
741
286
    pub fn best_shared_link_protocol(&self, my_protos: &[u16]) -> Option<u16> {
742
286
        // NOTE: this implementation is quadratic, but it shouldn't matter
743
286
        // much so long as my_protos is small.
744
286
        let p = my_protos
745
286
            .iter()
746
484
            .filter(|p| self.versions.contains(p))
747
308
            .fold(0_u16, |a, b| u16::max(a, *b));
748
286
        if p == 0 {
749
66
            None
750
        } else {
751
220
            Some(p)
752
        }
753
286
    }
754
}
755
impl Body for Versions {
756
176
    fn into_message(self) -> ChanMsg {
757
176
        ChanMsg::Versions(self)
758
176
    }
759
286
    fn write_body_onto<W: Writer + ?Sized>(self, w: &mut W) {
760
704
        for v in &self.versions {
761
418
            w.write_u16(*v);
762
418
        }
763
286
    }
764
}
765
impl Readable for Versions {
766
220
    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
767
220
        let mut versions = Vec::new();
768
858
        while r.remaining() > 0 {
769
638
            versions.push(r.take_u16()?);
770
        }
771
220
        Ok(Versions { versions })
772
220
    }
773
}
774

            
775
/// A PaddingNegotiate message is used to negotiate channel padding.
776
///
777
/// TODO: say more once we implement channel padding.
778
44
#[derive(Clone, Debug)]
779
pub struct PaddingNegotiate {
780
    /// Whether to start or stop padding
781
    command: u8,
782
    /// Suggested lower-bound value for inter-packet timeout in msec.
783
    // TODO(nickm) is that right?
784
    ito_low_ms: u16,
785
    /// Suggested upper-bound value for inter-packet timeout in msec.
786
    // TODO(nickm) is that right?
787
    ito_high_ms: u16,
788
}
789
impl PaddingNegotiate {
790
    /// Create a new PaddingNegotiate message.
791
    ///
792
    /// If `start` is true, this is a message to enable padding. Otherwise
793
    /// this is a message to disable padding.
794
22
    pub fn new(start: bool, ito_low_ms: u16, ito_high_ms: u16) -> Self {
795
22
        let command = if start { 2 } else { 1 };
796
22
        Self {
797
22
            command,
798
22
            ito_low_ms,
799
22
            ito_high_ms,
800
22
        }
801
22
    }
802
}
803
impl Body for PaddingNegotiate {
804
22
    fn into_message(self) -> ChanMsg {
805
22
        ChanMsg::PaddingNegotiate(self)
806
22
    }
807
2
    fn write_body_onto<W: Writer + ?Sized>(self, w: &mut W) {
808
2
        w.write_u8(0); // version
809
2
        w.write_u8(self.command);
810
2
        w.write_u16(self.ito_low_ms);
811
2
        w.write_u16(self.ito_high_ms);
812
2
    }
813
}
814
impl Readable for PaddingNegotiate {
815
44
    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
816
44
        let v = r.take_u8()?;
817
44
        if v != 0 {
818
22
            return Err(Error::BadMessage(
819
22
                "Unrecognized padding negotiation version",
820
22
            ));
821
22
        }
822
22
        let command = r.take_u8()?;
823
22
        let ito_low_ms = r.take_u16()?;
824
22
        let ito_high_ms = r.take_u16()?;
825
22
        Ok(PaddingNegotiate {
826
22
            command,
827
22
            ito_low_ms,
828
22
            ito_high_ms,
829
22
        })
830
44
    }
831
}
832

            
833
/// A single certificate in a Certs cell.
834
///
835
/// The formats used here are implemented in tor-cert. Ed25519Cert is the
836
/// most common.
837
220
#[derive(Clone, Debug)]
838
struct TorCert {
839
    /// Type code for this certificate.
840
    certtype: u8,
841
    /// Encoded certificate
842
    cert: Vec<u8>,
843
}
844
/// encode a single TorCert `c` onto a Writer `w`.
845
10
fn enc_one_tor_cert<W: Writer + ?Sized>(w: &mut W, c: &TorCert) {
846
10
    w.write_u8(c.certtype);
847
10
    let cert_len: u16 = c
848
10
        .cert
849
10
        .len()
850
10
        .try_into()
851
10
        .expect("Impossibly long certificate");
852
10
    w.write_u16(cert_len);
853
10
    w.write_all(&c.cert[..]);
854
10
}
855
/// Try to extract a TorCert from the reader `r`.
856
242
fn take_one_tor_cert(r: &mut Reader<'_>) -> Result<TorCert> {
857
242
    let certtype = r.take_u8()?;
858
220
    let certlen = r.take_u16()?;
859
220
    let cert = r.take(certlen as usize)?;
860
220
    Ok(TorCert {
861
220
        certtype,
862
220
        cert: cert.into(),
863
220
    })
864
242
}
865
/// A Certs message is used as part of the channel handshake to send
866
/// additional certificates.
867
///
868
/// These certificates are not presented as part of the TLS handshake.
869
/// Originally this was meant to make Tor TLS handshakes look "normal", but
870
/// nowadays it serves less purpose, especially now that we have TLS 1.3.
871
///
872
/// Every relay sends this message as part of channel negotiation;
873
/// clients do not send them.
874
44
#[derive(Clone, Debug)]
875
pub struct Certs {
876
    /// The certificates in this cell
877
    certs: Vec<TorCert>,
878
}
879
impl Certs {
880
    /// Return a new empty certs cell.
881
418
    pub fn new_empty() -> Self {
882
418
        Certs { certs: Vec::new() }
883
418
    }
884
    /// Add a new encoded certificate to this cell.
885
    ///
886
    /// Does not check anything about the well-formedness of the certificate.
887
34
    pub fn push_cert_body<B>(&mut self, certtype: tor_cert::CertType, cert: B)
888
34
    where
889
34
        B: Into<Vec<u8>>,
890
34
    {
891
34
        let certtype = certtype.into();
892
34
        let cert = cert.into();
893
34
        self.certs.push(TorCert { certtype, cert });
894
34
    }
895

            
896
    /// Return the body of the certificate tagged with 'tp', if any.
897
836
    pub fn cert_body(&self, tp: tor_cert::CertType) -> Option<&[u8]> {
898
836
        self.certs
899
836
            .iter()
900
2266
            .find(|c| c.certtype == tp.into())
901
836
            .map(|c| &c.cert[..])
902
836
    }
903

            
904
    /// Look for a certificate of type 'tp' in this cell; return it if
905
    /// there is one.
906
506
    pub fn parse_ed_cert(&self, tp: tor_cert::CertType) -> crate::Result<tor_cert::KeyUnknownCert> {
907
506
        let body = self
908
506
            .cert_body(tp)
909
506
            .ok_or_else(|| crate::Error::ChanProto(format!("Missing {} certificate", tp)))?;
910

            
911
440
        let cert = tor_cert::Ed25519Cert::decode(body)?;
912
418
        if cert.peek_cert_type() != tp {
913
            return Err(crate::Error::ChanProto(format!(
914
                "Found a {} certificate labeled as {}",
915
                cert.peek_cert_type(),
916
                tp
917
            )));
918
418
        }
919
418

            
920
418
        Ok(cert)
921
506
    }
922
}
923

            
924
impl Body for Certs {
925
198
    fn into_message(self) -> ChanMsg {
926
198
        ChanMsg::Certs(self)
927
198
    }
928
90
    fn write_body_onto<W: Writer + ?Sized>(self, w: &mut W) {
929
90
        let n_certs: u8 = self
930
90
            .certs
931
90
            .len()
932
90
            .try_into()
933
90
            .expect("Too many certs to encode in cell.");
934
90
        w.write_u8(n_certs);
935
100
        for c in &self.certs {
936
10
            enc_one_tor_cert(w, c);
937
10
        }
938
90
    }
939
}
940
impl Readable for Certs {
941
264
    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
942
264
        let n = r.take_u8()?;
943
264
        let mut certs = Vec::new();
944
264
        for _ in 0..n {
945
242
            certs.push(take_one_tor_cert(r)?);
946
        }
947
242
        Ok(Certs { certs })
948
264
    }
949
}
950

            
951
/// Length of the body for an authentication challenge
952
const CHALLENGE_LEN: usize = 32;
953

            
954
/// An AuthChallenge message is part of negotiation, sent by
955
/// responders to initiators.
956
///
957
/// The AuthChallenge cell is used to ensure that some unpredictable material
958
/// has been sent on the channel, and to tell the initiator what
959
/// authentication methods will be accepted.
960
///
961
/// Clients can safely ignore this message: they don't need to authenticate.
962
44
#[derive(Clone, Debug)]
963
pub struct AuthChallenge {
964
    /// Random challenge to be used in generating response
965
    challenge: [u8; CHALLENGE_LEN],
966
    /// List of permitted authentication methods
967
    methods: Vec<u16>,
968
}
969
impl AuthChallenge {
970
    /// Construct a new AuthChallenge cell with a given challenge
971
    /// value (chosen randomly) and a set of acceptable authentication methods.
972
1
    pub fn new<B, M>(challenge: B, methods: M) -> Self
973
1
    where
974
1
        B: Into<[u8; CHALLENGE_LEN]>,
975
1
        M: Into<Vec<u16>>,
976
1
    {
977
1
        AuthChallenge {
978
1
            challenge: challenge.into(),
979
1
            methods: methods.into(),
980
1
        }
981
1
    }
982
}
983

            
984
impl Body for AuthChallenge {
985
22
    fn into_message(self) -> ChanMsg {
986
22
        ChanMsg::AuthChallenge(self)
987
22
    }
988
2
    fn write_body_onto<W: Writer + ?Sized>(self, w: &mut W) {
989
2
        w.write_all(&self.challenge[..]);
990
2
        assert!(self.methods.len() <= std::u16::MAX as usize);
991
2
        w.write_u16(self.methods.len() as u16);
992
6
        for m in &self.methods {
993
4
            w.write_u16(*m);
994
4
        }
995
2
    }
996
}
997
impl Readable for AuthChallenge {
998
88
    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
999
        //let challenge = r.take(CHALLENGE_LEN)?.into();
88
        let challenge = r.extract()?;
88
        let n_methods = r.take_u16()?;
88
        let mut methods = Vec::new();
88
        for _ in 0..n_methods {
176
            methods.push(r.take_u16()?);
        }
88
        Ok(AuthChallenge { challenge, methods })
88
    }
}

            
/// Part of negotiation: sent by initiators to responders.
///
/// The Authenticate cell proves the initiator's identity to the
/// responder, even if TLS client authentication was not used.
///
/// Clients do not use this.
44
#[derive(Clone, Debug)]
pub struct Authenticate {
    /// Authentication method in use
    authtype: u16,
    /// Encoded authentication object
    auth: Vec<u8>,
}
impl Authenticate {
    /// Create a new Authenticate message from a given type and body.
1
    pub fn new<B>(authtype: u16, body: B) -> Self
1
    where
1
        B: Into<Vec<u8>>,
1
    {
1
        Authenticate {
1
            authtype,
1
            auth: body.into(),
1
        }
1
    }
}
impl Body for Authenticate {
22
    fn into_message(self) -> ChanMsg {
22
        ChanMsg::Authenticate(self)
22
    }
2
    fn write_body_onto<W: Writer + ?Sized>(self, w: &mut W) {
2
        w.write_u16(self.authtype);
2
        assert!(self.auth.len() <= std::u16::MAX as usize);
2
        w.write_u16(self.auth.len() as u16);
2
        w.write_all(&self.auth[..]);
2
    }
}
impl Readable for Authenticate {
22
    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
22
        let authtype = r.take_u16()?;
22
        let authlen = r.take_u16()?;
22
        let auth = r.take(authlen as usize)?.into();
22
        Ok(Authenticate { authtype, auth })
22
    }
}

            
/// The Authorize message type is not yet used.
44
#[derive(Clone, Debug)]
pub struct Authorize {
    /// The cell's content, which isn't really specified yet.
    content: Vec<u8>,
}
impl Authorize {
    /// Construct a new Authorize cell.
1
    pub fn new<B>(content: B) -> Self
1
    where
1
        B: Into<Vec<u8>>,
1
    {
1
        let content = content.into();
1
        Authorize { content }
1
    }
}
impl Body for Authorize {
22
    fn into_message(self) -> ChanMsg {
22
        ChanMsg::Authorize(self)
22
    }
2
    fn write_body_onto<W: Writer + ?Sized>(self, w: &mut W) {
2
        w.write_all(&self.content[..]);
2
    }
}
impl Readable for Authorize {
22
    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
22
        Ok(Authorize {
22
            content: r.take(r.remaining())?.into(),
        })
22
    }
}

            
/// Holds any message whose command we don't recognize.
///
/// Well-behaved Tor implementations are required to ignore commands
/// like this.
///
/// TODO: I believe that this is not a risky case of Postel's law,
/// since it is only for channels, but we should be careful here.
176
#[derive(Clone, Debug)]
pub struct Unrecognized {
    /// The channel command that we got with this cell
    cmd: ChanCmd,
    /// The contents of the cell
    content: Vec<u8>,
}
/// Take an unrecognized cell's body from a reader `r`, and apply
/// the given command to it.
88
fn unrecognized_with_cmd(cmd: ChanCmd, r: &mut Reader<'_>) -> Result<Unrecognized> {
88
    let mut u = Unrecognized::take_from(r)?;
88
    u.cmd = cmd;
88
    Ok(u)
88
}
impl Unrecognized {
    /// Construct a new cell of arbitrary or unrecognized type.
3
    pub fn new<B>(cmd: ChanCmd, content: B) -> Self
3
    where
3
        B: Into<Vec<u8>>,
3
    {
3
        let content = content.into();
3
        Unrecognized { cmd, content }
3
    }
    /// Return the command from this cell.
88
    fn cmd(&self) -> ChanCmd {
88
        self.cmd
88
    }
}
impl Body for Unrecognized {
66
    fn into_message(self) -> ChanMsg {
66
        ChanMsg::Unrecognized(self)
66
    }
48
    fn write_body_onto<W: Writer + ?Sized>(self, w: &mut W) {
48
        w.write_all(&self.content[..]);
48
    }
}
impl Readable for Unrecognized {
88
    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
88
        Ok(Unrecognized {
88
            cmd: 0.into(),
88
            content: r.take(r.remaining())?.into(),
        })
88
    }
}

            
impl<B: Body> From<B> for ChanMsg {
98
    fn from(body: B) -> Self {
98
        body.into_message()
98
    }
}

            
/// Helper: declare a From<> implementation from message types for
/// cells that don't take a circid.
macro_rules! msg_into_cell {
    ($body:ident) => {
        impl From<$body> for super::ChanCell {
66
            fn from(body: $body) -> super::ChanCell {
66
                super::ChanCell {
66
                    circid: 0.into(),
66
                    msg: body.into_message(),
66
                }
66
            }
        }
    };
}

            
msg_into_cell!(Padding);
msg_into_cell!(VPadding);
msg_into_cell!(Netinfo);
msg_into_cell!(Versions);
msg_into_cell!(PaddingNegotiate);
msg_into_cell!(Certs);
msg_into_cell!(AuthChallenge);
msg_into_cell!(Authenticate);
msg_into_cell!(Authorize);

            
#[cfg(test)]
mod test {
    use super::*;
    #[test]
    fn destroy_reason() {
        let r1 = DestroyReason::CONNECTFAILED;

            
        assert_eq!(r1.human_str(), "Couldn't connect to relay");

            
        let r2 = DestroyReason::from(200); // not a specified number.
        assert_eq!(r2.human_str(), "Unrecognized reason");
    }
}