1
//! Wrap [tor_cell::chancell::codec::ChannelCodec] for use with the futures_codec
2
//! crate.
3

            
4
use digest::Digest;
5
use tor_bytes::Reader;
6
use tor_cell::chancell::{
7
    AnyChanCell, ChanCell, ChanCmd, ChanMsg, codec,
8
    msg::{self, AnyChanMsg},
9
};
10
use tor_error::internal;
11
use tor_llcrypto as ll;
12

            
13
use asynchronous_codec as futures_codec;
14
use bytes::BytesMut;
15

            
16
use crate::{channel::msg::LinkVersion, util::err::Error as ChanError};
17

            
18
use super::{ChannelType, msg::MessageFilter};
19

            
20
/// Channel cell handler which is always in three state.
21
///
22
/// This ALWAYS starts the handler at New. This can only be constructed from a [ChannelType] which
23
/// forces it to start at New.
24
///
25
/// From the New state, it will automatically transition to the right state as information is
26
/// attached to it (ex: link protocol version).
27
pub(crate) enum ChannelCellHandler {
28
    /// When a network connection opens to another endpoint, the channel is considered "New" and
29
    /// so we use this handler to start the handshake.
30
    New(NewChannelHandler),
31
    /// We opened and negotiated a VERSIONS cell. If successful, we transition to this cell handler
32
    /// with sole purpose to handle the handshake phase.
33
    Handshake(HandshakeChannelHandler),
34
    /// Once the handshake is successful, the channel is Open and we use this handler.
35
    Open(OpenChannelHandler),
36
}
37

            
38
/// This is the only way to construct a ChannelCellHandler, from the channel type which will always
39
/// start the handler at the New state.
40
impl From<super::ChannelType> for ChannelCellHandler {
41
120
    fn from(ty: ChannelType) -> Self {
42
120
        Self::New(ty.into())
43
120
    }
44
}
45

            
46
impl ChannelCellHandler {
47
    /// Return the [`ChannelType`] of the inner handler.
48
50
    pub(crate) fn channel_type(&self) -> ChannelType {
49
50
        match self {
50
            Self::New(h) => h.channel_type,
51
            Self::Handshake(h) => h.channel_type(),
52
50
            Self::Open(h) => h.channel_type(),
53
        }
54
50
    }
55

            
56
    /// Set link protocol for this channel cell handler. This transition the handler into the
57
    /// handshake handler state.
58
    ///
59
    /// An error is returned if the current handler is NOT the New one or if the link version is
60
    /// unknown.
61
116
    pub(crate) fn set_link_version(&mut self, link_version: u16) -> Result<(), ChanError> {
62
116
        let Self::New(new_handler) = self else {
63
            return Err(ChanError::Bug(internal!(
64
                "Setting link protocol without a new handler",
65
            )));
66
        };
67
116
        *self = Self::Handshake(new_handler.next_handler(link_version.try_into()?));
68
116
        Ok(())
69
116
    }
70

            
71
    /// This transition into the open handler state.
72
    ///
73
    /// An error is returned if the current handler is NOT the Handshake one.
74
74
    pub(crate) fn set_open(&mut self) -> Result<(), ChanError> {
75
74
        let Self::Handshake(handler) = self else {
76
            return Err(ChanError::Bug(internal!(
77
                "Setting open without a handshake handler"
78
            )));
79
        };
80
74
        *self = Self::Open(handler.next_handler());
81
74
        Ok(())
82
74
    }
83

            
84
    /// Mark this handler as authenticated.
85
    ///
86
    /// This can only happen during the Handshake process as a New handler can't be authenticated
87
    /// from the start and an Open handler can only be opened after authentication.
88
    pub(crate) fn set_authenticated(&mut self) -> Result<(), ChanError> {
89
        let Self::Handshake(handler) = self else {
90
            return Err(ChanError::Bug(internal!(
91
                "Setting authenticated without a handshake handler"
92
            )));
93
        };
94
        handler.set_authenticated();
95
        Ok(())
96
    }
97

            
98
    /// The digest of bytes sent on this channel.
99
    ///
100
    /// This should only ever be called once as it consumes the send log.
101
    ///
102
    /// This will return an error if one of:
103
    /// - The channel is not recording the send log.
104
    /// - The send log digest has already been taken.
105
    /// - This cell handler is not using a handshake handler.
106
12
    pub(crate) fn take_send_log_digest(&mut self) -> Result<[u8; 32], ChanError> {
107
12
        if let Self::Handshake(handler) = self {
108
12
            handler
109
12
                .take_send_log_digest()
110
12
                .ok_or(ChanError::Bug(internal!(
111
12
                    "No send log digest on channel, or already taken"
112
12
                )))
113
        } else {
114
            Err(ChanError::Bug(internal!(
115
                "Getting send log digest without a handshake handler"
116
            )))
117
        }
118
12
    }
119

            
120
    /// The digest of bytes received on this channel.
121
    ///
122
    /// This should only ever be called once as it consumes the receive log.
123
    ///
124
    /// This will return `None` if one of:
125
    /// - The channel is not recording the receive log.
126
    /// - The receive log digest has already been taken.
127
    /// - This cell handler is not using a handshake handler.
128
12
    pub(crate) fn take_recv_log_digest(&mut self) -> Result<[u8; 32], ChanError> {
129
12
        if let Self::Handshake(handler) = self {
130
12
            handler
131
12
                .take_recv_log_digest()
132
12
                .ok_or(ChanError::Bug(internal!(
133
12
                    "No recv log digest on channel, or already taken"
134
12
                )))
135
        } else {
136
            Err(ChanError::Bug(internal!(
137
                "Getting recv log digest without a handshake handler"
138
            )))
139
        }
140
12
    }
141
}
142

            
143
// Security Consideration.
144
//
145
// Here is an explanation on why AnyChanCell is used as Item in the Handshake and Open handler and
146
// thus the higher level ChannelCellHandler.
147
//
148
// Technically, we could use a restricted message set and so the decoding and encoding wouldn't do
149
// anything if the cell/data was not part of that set.
150
//
151
// However, with relay and client, we have multiple channel types which means we have now a lot
152
// more sets of restricted message (see msg.rs) and each of them are per link protocol version, per
153
// stage of the channel opening process and per direction (inbound or outbound).
154
//
155
// To go around this, we use [MessageFilter] in order to decode on the specific restricted message
156
// set but still return a [AnyChanCell].
157
//
158
// If someone wants to contribute a more elegant solution that wouldn't require us to duplicate
159
// code for each restricted message set, by all means, go for it :).
160

            
161
impl futures_codec::Decoder for ChannelCellHandler {
162
    type Item = AnyChanCell;
163
    type Error = ChanError;
164

            
165
1076
    fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
166
1076
        match self {
167
212
            Self::New(c) => c
168
212
                .decode(src)
169
248
                .map(|opt| opt.map(|msg| ChanCell::new(None, msg.into()))),
170
840
            Self::Handshake(c) => c.decode(src),
171
24
            Self::Open(c) => c.decode(src),
172
        }
173
1076
    }
174
}
175

            
176
impl futures_codec::Encoder for ChannelCellHandler {
177
    type Item<'a> = AnyChanCell;
178
    type Error = ChanError;
179

            
180
154
    fn encode(&mut self, item: Self::Item<'_>, dst: &mut BytesMut) -> Result<(), Self::Error> {
181
154
        match self {
182
82
            Self::New(c) => {
183
                // The new handler pins the only possible message to be a Versions. That is why we
184
                // extract it here and validate before else we can't pass Item to encode().
185
82
                let AnyChanMsg::Versions(versions) = item.into_circid_and_msg().1 else {
186
                    return Err(Self::Error::HandshakeProto(
187
                        "Non VERSIONS cell for new handler".into(),
188
                    ));
189
                };
190
82
                c.encode(versions, dst)
191
            }
192
60
            Self::Handshake(c) => c.encode(item, dst),
193
12
            Self::Open(c) => c.encode(item, dst),
194
        }
195
154
    }
196
}
197

            
198
/// A new channel handler used when a channel is created but before the handshake meaning there is no
199
/// link protocol version yet associated with it.
200
///
201
/// This handler only handles the VERSIONS cell.
202
pub(crate) struct NewChannelHandler {
203
    /// The channel type for this handler.
204
    channel_type: ChannelType,
205
    /// The digest of bytes sent on this channel.
206
    ///
207
    /// Will be used for the SLOG or CLOG of the AUTHENTICATE cell.
208
    send_log: Option<ll::d::Sha256>,
209
    /// The digest of bytes received on this channel.
210
    ///
211
    /// Will be used for the SLOG or CLOG of the AUTHENTICATE cell.
212
    recv_log: Option<ll::d::Sha256>,
213
}
214

            
215
impl NewChannelHandler {
216
    /// Return a handshake handler ready for the given link protocol.
217
116
    fn next_handler(&mut self, link_version: LinkVersion) -> HandshakeChannelHandler {
218
116
        HandshakeChannelHandler::new(self, link_version)
219
116
    }
220
}
221

            
222
impl From<ChannelType> for NewChannelHandler {
223
120
    fn from(channel_type: ChannelType) -> Self {
224
120
        match channel_type {
225
96
            ChannelType::ClientInitiator => Self {
226
96
                channel_type,
227
96
                send_log: None,
228
96
                recv_log: None,
229
96
            },
230
            // Relay responder might not need clog/slog but that is fine. We don't know until the
231
            // end of the handshake.
232
24
            ChannelType::RelayInitiator | ChannelType::RelayResponder { .. } => Self {
233
24
                channel_type,
234
24
                send_log: Some(ll::d::Sha256::new()),
235
24
                recv_log: Some(ll::d::Sha256::new()),
236
24
            },
237
        }
238
120
    }
239
}
240

            
241
impl futures_codec::Decoder for NewChannelHandler {
242
    type Item = msg::Versions;
243
    type Error = ChanError;
244

            
245
212
    fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
246
        // NOTE: Until the body can be extracted from src buffer, it MUST NOT be modified as in
247
        // advanced with the Buf trait or modified in any ways. Reason is that we can realize we
248
        // don't have enough bytes in the src buffer for the expected body length from the header
249
        // so we have to leave the src buffer untouched and wait for more bytes.
250

            
251
        // See tor-spec, starting a handshake, all cells are variable length so the first 5 bytes
252
        // are: CircId as u16, Command as u8, Length as u16 totalling 5 bytes.
253
        const HEADER_SIZE: usize = 5;
254

            
255
        // Below this amount, this is not a valid cell we can decode. This is important because we
256
        // can get an empty buffer in normal circumstances (see how Framed work) and so we have to
257
        // return that we weren't able to decode and thus no Item.
258
212
        if src.len() < HEADER_SIZE {
259
130
            return Ok(None);
260
82
        }
261

            
262
        // Get the CircID and Command from the header. This is safe due to the header size check
263
        // above.
264
82
        let circ_id = u16::from_be_bytes([src[0], src[1]]);
265
82
        if circ_id != 0 {
266
2
            return Err(Self::Error::HandshakeProto(
267
2
                "Invalid CircID in variable cell".into(),
268
2
            ));
269
80
        }
270

            
271
        // We are only expecting these specific commands. We have to do this by hand here as after
272
        // that we can use a proper codec.
273
80
        let cmd = ChanCmd::from(src[2]);
274
80
        if cmd != ChanCmd::VERSIONS {
275
            return Err(Self::Error::HandshakeProto(format!(
276
                "Invalid command {cmd} variable cell, expected a VERSIONS."
277
            )));
278
80
        }
279

            
280
        // Get the body length now from the next two bytes. This is still safe due to the first
281
        // header size check at the start.
282
80
        let body_len = u16::from_be_bytes([src[3], src[4]]) as usize;
283

            
284
        // See https://gitlab.torproject.org/tpo/core/tor/-/issues/10365. The gist is that because
285
        // version numbers are u16, an odd payload would mean we have a trailing byte that is
286
        // unused which shouldn't be and because we don't expect not controlled that byte, as maxi
287
        // precaution, we don't allow.
288
80
        if body_len % 2 == 1 {
289
            return Err(Self::Error::HandshakeProto(
290
                "VERSIONS cell body length is odd. Rejecting.".into(),
291
            ));
292
80
        }
293

            
294
        // Make sure we have enough bytes in our payload.
295
80
        let wanted_bytes = HEADER_SIZE + body_len;
296
80
        if src.len() < wanted_bytes {
297
            // We don't haven't received enough data to decode the expected length from the header
298
            // so return no Item.
299
            //
300
            // IMPORTANT: The src buffer here can't be advance before reaching this check.
301
            return Ok(None);
302
80
        }
303
        // Extract the exact data we will be looking at.
304
80
        let mut data = src.split_to(wanted_bytes);
305

            
306
        // Update the receive log digest with the entire cell up to the end of the payload hence the
307
        // data we are looking at (and not the whole source). Even on error, this doesn't matter
308
        // because if decoding fails, the channel is closed.
309
80
        if let Some(recv_log) = self.recv_log.as_mut() {
310
12
            recv_log.update(&data);
311
68
        }
312

            
313
        // Get the actual body from the data.
314
80
        let body = data.split_off(HEADER_SIZE).freeze();
315
80
        let mut reader = Reader::from_bytes(&body);
316

            
317
        // Decode the VERSIONS.
318
80
        let cell = msg::Versions::decode_from_reader(cmd, &mut reader)
319
80
            .map_err(|e| Self::Error::from_bytes_err(e, "new cell handler"))?;
320
80
        Ok(Some(cell))
321
212
    }
322
}
323

            
324
impl futures_codec::Encoder for NewChannelHandler {
325
    type Item<'a> = msg::Versions;
326
    type Error = ChanError;
327

            
328
82
    fn encode(&mut self, item: Self::Item<'_>, dst: &mut BytesMut) -> Result<(), Self::Error> {
329
82
        let encoded_bytes = item
330
82
            .encode_for_handshake()
331
82
            .map_err(|e| Self::Error::from_bytes_enc(e, "new cell handler"))?;
332
        // Update the send log digest.
333
82
        if let Some(send_log) = self.send_log.as_mut() {
334
12
            send_log.update(&encoded_bytes);
335
70
        }
336
        // Special encoding for the VERSIONS cell.
337
82
        dst.extend_from_slice(&encoded_bytes);
338
82
        Ok(())
339
82
    }
340
}
341

            
342
/// The handshake channel handler which is used to decode and encode cells onto a channel that is
343
/// handshaking with an endpoint.
344
pub(crate) struct HandshakeChannelHandler {
345
    /// Message filter used to allow or not a certain message.
346
    filter: MessageFilter,
347
    /// The cell codec that we'll use to encode and decode our cells.
348
    inner: codec::ChannelCodec,
349
    /// The digest of bytes sent on this channel.
350
    ///
351
    /// Will be used for the SLOG or CLOG of the AUTHENTICATE cell.
352
    send_log: Option<ll::d::Sha256>,
353
    /// The digest of bytes received on this channel.
354
    ///
355
    /// Will be used for the SLOG or CLOG of the AUTHENTICATE cell.
356
    recv_log: Option<ll::d::Sha256>,
357
}
358

            
359
impl HandshakeChannelHandler {
360
    /// Constructor
361
116
    fn new(new_handler: &mut NewChannelHandler, link_version: LinkVersion) -> Self {
362
116
        Self {
363
116
            filter: MessageFilter::new(
364
116
                link_version,
365
116
                new_handler.channel_type,
366
116
                super::msg::MessageStage::Handshake,
367
116
            ),
368
116
            send_log: new_handler.send_log.take(),
369
116
            recv_log: new_handler.recv_log.take(),
370
116
            inner: codec::ChannelCodec::new(link_version.value()),
371
116
        }
372
116
    }
373

            
374
    /// Internal helper: Take a SHA256 digest and finalize it if any. None is returned if no log
375
    /// digest is given.
376
24
    fn finalize_log(log: Option<ll::d::Sha256>) -> Option<[u8; 32]> {
377
36
        log.map(|sha256| sha256.finalize().into())
378
24
    }
379

            
380
    /// Return an open handshake handler.
381
74
    fn next_handler(&mut self) -> OpenChannelHandler {
382
74
        OpenChannelHandler::new(
383
74
            self.inner
384
74
                .link_version()
385
74
                .try_into()
386
74
                .expect("Channel Codec with unknown link version"),
387
74
            self.channel_type(),
388
        )
389
74
    }
390

            
391
    /// The digest of bytes sent on this channel.
392
    ///
393
    /// This should only ever be called once as it consumes the send log.
394
    ///
395
    /// This will return `None` if one of:
396
    /// - The channel is not recording the send log.
397
    /// - The send log digest has already been taken.
398
12
    pub(crate) fn take_send_log_digest(&mut self) -> Option<[u8; 32]> {
399
12
        Self::finalize_log(self.send_log.take())
400
12
    }
401

            
402
    /// The digest of bytes received on this channel.
403
    ///
404
    /// This should only ever be called once as it consumes the receive log.
405
    ///
406
    /// This will return `None` if one of:
407
    /// - The channel is not recording the receive log.
408
    /// - The receive log digest has already been taken.
409
12
    pub(crate) fn take_recv_log_digest(&mut self) -> Option<[u8; 32]> {
410
12
        Self::finalize_log(self.recv_log.take())
411
12
    }
412

            
413
    /// Return the [`ChannelType`] of this handler.
414
74
    pub(crate) fn channel_type(&self) -> ChannelType {
415
74
        self.filter.channel_type()
416
74
    }
417

            
418
    /// Mark this handler as authenticated.
419
    pub(crate) fn set_authenticated(&mut self) {
420
        self.filter.channel_type_mut().set_authenticated();
421
    }
422
}
423

            
424
impl futures_codec::Encoder for HandshakeChannelHandler {
425
    type Item<'a> = AnyChanCell;
426
    type Error = ChanError;
427

            
428
60
    fn encode(
429
60
        &mut self,
430
60
        item: Self::Item<'_>,
431
60
        dst: &mut BytesMut,
432
60
    ) -> std::result::Result<(), Self::Error> {
433
60
        let before_dst_len = dst.len();
434
60
        self.filter.encode_cell(item, &mut self.inner, dst)?;
435
60
        let after_dst_len = dst.len();
436
60
        if let Some(send_log) = self.send_log.as_mut() {
437
12
            // Only use what we actually wrote. Variable length cell are not padded and thus this
438
12
            // won't catch a bunch of padding.
439
12
            send_log.update(&dst[before_dst_len..after_dst_len]);
440
60
        }
441
60
        Ok(())
442
60
    }
443
}
444

            
445
impl futures_codec::Decoder for HandshakeChannelHandler {
446
    type Item = AnyChanCell;
447
    type Error = ChanError;
448

            
449
840
    fn decode(
450
840
        &mut self,
451
840
        src: &mut BytesMut,
452
840
    ) -> std::result::Result<Option<Self::Item>, Self::Error> {
453
840
        let orig = src.clone(); // NOTE: Not fun. But This is only done during handshake.
454
840
        let cell = self.filter.decode_cell(&mut self.inner, src)?;
455
836
        if let Some(recv_log) = self.recv_log.as_mut() {
456
24
            let n_used = orig.len() - src.len();
457
24
            recv_log.update(&orig[..n_used]);
458
812
        }
459
836
        Ok(cell)
460
840
    }
461
}
462

            
463
/// The open channel handler which is used to decode and encode cells onto an open Channel.
464
pub(crate) struct OpenChannelHandler {
465
    /// Message filter used to allow or not a certain message.
466
    filter: MessageFilter,
467
    /// The cell codec that we'll use to encode and decode our cells.
468
    inner: codec::ChannelCodec,
469
}
470

            
471
impl OpenChannelHandler {
472
    /// Constructor
473
98
    fn new(link_version: LinkVersion, channel_type: ChannelType) -> Self {
474
98
        Self {
475
98
            inner: codec::ChannelCodec::new(link_version.value()),
476
98
            filter: MessageFilter::new(link_version, channel_type, super::msg::MessageStage::Open),
477
98
        }
478
98
    }
479

            
480
    /// Return the [`ChannelType`] of this handler.
481
50
    fn channel_type(&self) -> ChannelType {
482
50
        self.filter.channel_type()
483
50
    }
484
}
485

            
486
impl futures_codec::Encoder for OpenChannelHandler {
487
    type Item<'a> = AnyChanCell;
488
    type Error = ChanError;
489

            
490
12
    fn encode(&mut self, item: Self::Item<'_>, dst: &mut BytesMut) -> Result<(), Self::Error> {
491
12
        self.filter.encode_cell(item, &mut self.inner, dst)
492
12
    }
493
}
494

            
495
impl futures_codec::Decoder for OpenChannelHandler {
496
    type Item = AnyChanCell;
497
    type Error = ChanError;
498

            
499
24
    fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
500
24
        self.filter.decode_cell(&mut self.inner, src)
501
24
    }
502
}
503

            
504
#[cfg(test)]
505
pub(crate) mod test {
506
    #![allow(clippy::unwrap_used)]
507
    use bytes::BytesMut;
508
    use digest::Digest;
509
    use futures::io::{AsyncRead, AsyncWrite, Cursor, Result};
510
    use futures::sink::SinkExt;
511
    use futures::stream::StreamExt;
512
    use futures::task::{Context, Poll};
513
    use hex_literal::hex;
514
    use std::pin::Pin;
515

            
516
    use tor_bytes::Writer;
517
    use tor_llcrypto as ll;
518
    use tor_rtcompat::StreamOps;
519

            
520
    use crate::channel::msg::LinkVersion;
521
    use crate::channel::{ChannelType, new_frame};
522

            
523
    use super::{ChannelCellHandler, OpenChannelHandler, futures_codec};
524
    use tor_cell::chancell::{AnyChanCell, ChanCmd, ChanMsg, CircId, msg};
525

            
526
    /// Helper type for reading and writing bytes to/from buffers.
527
    pub(crate) struct MsgBuf {
528
        /// Data we have received as a reader.
529
        inbuf: futures::io::Cursor<Vec<u8>>,
530
        /// Data we write as a writer.
531
        outbuf: futures::io::Cursor<Vec<u8>>,
532
    }
533

            
534
    impl AsyncRead for MsgBuf {
535
        fn poll_read(
536
            mut self: Pin<&mut Self>,
537
            cx: &mut Context<'_>,
538
            buf: &mut [u8],
539
        ) -> Poll<Result<usize>> {
540
            Pin::new(&mut self.inbuf).poll_read(cx, buf)
541
        }
542
    }
543
    impl AsyncWrite for MsgBuf {
544
        fn poll_write(
545
            mut self: Pin<&mut Self>,
546
            cx: &mut Context<'_>,
547
            buf: &[u8],
548
        ) -> Poll<Result<usize>> {
549
            Pin::new(&mut self.outbuf).poll_write(cx, buf)
550
        }
551
        fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
552
            Pin::new(&mut self.outbuf).poll_flush(cx)
553
        }
554
        fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
555
            Pin::new(&mut self.outbuf).poll_close(cx)
556
        }
557
    }
558

            
559
    impl StreamOps for MsgBuf {}
560

            
561
    impl MsgBuf {
562
        pub(crate) fn new<T: Into<Vec<u8>>>(output: T) -> Self {
563
            let inbuf = Cursor::new(output.into());
564
            let outbuf = Cursor::new(Vec::new());
565
            MsgBuf { inbuf, outbuf }
566
        }
567

            
568
        pub(crate) fn consumed(&self) -> usize {
569
            self.inbuf.position() as usize
570
        }
571

            
572
        pub(crate) fn all_consumed(&self) -> bool {
573
            self.inbuf.get_ref().len() == self.consumed()
574
        }
575

            
576
        pub(crate) fn into_response(self) -> Vec<u8> {
577
            self.outbuf.into_inner()
578
        }
579
    }
580

            
581
    fn new_client_open_frame(mbuf: MsgBuf) -> futures_codec::Framed<MsgBuf, ChannelCellHandler> {
582
        let open_handler = ChannelCellHandler::Open(OpenChannelHandler::new(
583
            LinkVersion::V5,
584
            ChannelType::ClientInitiator,
585
        ));
586
        futures_codec::Framed::new(mbuf, open_handler)
587
    }
588

            
589
    #[test]
590
    fn check_client_encoding() {
591
        tor_rtcompat::test_with_all_runtimes!(|_rt| async move {
592
            let mb = MsgBuf::new(&b""[..]);
593
            let mut framed = new_client_open_frame(mb);
594

            
595
            let destroycell = msg::Destroy::new(2.into());
596
            framed
597
                .send(AnyChanCell::new(CircId::new(7), destroycell.into()))
598
                .await
599
                .unwrap();
600

            
601
            framed.flush().await.unwrap();
602

            
603
            let data = framed.into_inner().into_response();
604

            
605
            assert_eq!(&data[0..10], &hex!("00000007 04 0200000000")[..]);
606
        });
607
    }
608

            
609
    #[test]
610
    fn check_client_decoding() {
611
        tor_rtcompat::test_with_all_runtimes!(|_rt| async move {
612
            let mut dat = Vec::new();
613
            // DESTROY cell.
614
            dat.extend_from_slice(&hex!("00000007 04 0200000000")[..]);
615
            dat.resize(514, 0);
616
            let mb = MsgBuf::new(&dat[..]);
617
            let mut framed = new_client_open_frame(mb);
618

            
619
            let destroy = framed.next().await.unwrap().unwrap();
620

            
621
            let circ_id = CircId::new(7);
622
            assert_eq!(destroy.circid(), circ_id);
623
            assert_eq!(destroy.msg().cmd(), ChanCmd::DESTROY);
624

            
625
            assert!(framed.into_inner().all_consumed());
626
        });
627
    }
628

            
629
    #[test]
630
    fn handler_transition() {
631
        // Start as a client initiating a channel to a relay.
632
        let mut handler: ChannelCellHandler = ChannelType::ClientInitiator.into();
633
        assert!(matches!(handler, ChannelCellHandler::New(_)));
634

            
635
        // Set the link version protocol. Should transition to Handshake.
636
        let r = handler.set_link_version(5);
637
        assert!(r.is_ok());
638
        assert!(matches!(handler, ChannelCellHandler::Handshake(_)));
639

            
640
        // Set the link version protocol.
641
        let r = handler.set_open();
642
        assert!(r.is_ok());
643
        assert!(matches!(handler, ChannelCellHandler::Open(_)));
644
    }
645

            
646
    #[test]
647
    fn clog_digest() {
648
        tor_rtcompat::test_with_all_runtimes!(|_rt| async move {
649
            let mut our_clog = ll::d::Sha256::new();
650
            let mbuf = MsgBuf::new(*b"");
651
            let mut frame = new_frame(mbuf, ChannelType::RelayInitiator);
652

            
653
            // This is a VERSIONS cell with value 5 in it.
654
            our_clog.update(hex!("0000 07 0002 0005"));
655
            let version_cell = AnyChanCell::new(
656
                None,
657
                msg::Versions::new(vec![5]).expect("Fail VERSIONS").into(),
658
            );
659
            let _ = frame.send(version_cell).await.unwrap();
660

            
661
            frame
662
                .codec_mut()
663
                .set_link_version(5)
664
                .expect("Fail link version set");
665

            
666
            // This is what an empty CERTS cell looks like.
667
            our_clog.update(hex!("0000 0000 81 0001 00"));
668
            let certs_cell = msg::Certs::new_empty();
669
            frame
670
                .send(AnyChanCell::new(None, certs_cell.into()))
671
                .await
672
                .unwrap();
673

            
674
            // Final CLOG should match.
675
            let clog_hash: [u8; 32] = our_clog.finalize().into();
676
            assert_eq!(frame.codec_mut().take_send_log_digest().unwrap(), clog_hash);
677
        });
678
    }
679

            
680
    #[test]
681
    fn slog_digest() {
682
        tor_rtcompat::test_with_all_runtimes!(|_rt| async move {
683
            let mut our_slog = ll::d::Sha256::new();
684

            
685
            // Build a VERSIONS cell to start with.
686
            let mut data = BytesMut::new();
687
            data.extend_from_slice(
688
                msg::Versions::new(vec![5])
689
                    .unwrap()
690
                    .encode_for_handshake()
691
                    .expect("Fail VERSIONS encoding")
692
                    .as_slice(),
693
            );
694
            our_slog.update(&data);
695

            
696
            let mbuf = MsgBuf::new(data);
697
            let mut frame = new_frame(mbuf, ChannelType::RelayInitiator);
698

            
699
            // Receive the VERSIONS
700
            let _ = frame.next().await.transpose().expect("Fail to get cell");
701
            // Set the link version which will move the handler to Handshake state and then we'll be
702
            // able to decode the AUTH_CHALLENGE.
703
            frame
704
                .codec_mut()
705
                .set_link_version(5)
706
                .expect("Fail link version set");
707

            
708
            // Setup a new buffer for the next cell.
709
            let mut data = BytesMut::new();
710
            // This is a variable length cell with a wide circ ID of 0.
711
            data.write_u32(0);
712
            data.write_u8(ChanCmd::AUTH_CHALLENGE.into());
713
            data.write_u16(36); // This is the length of the payload.
714
            msg::AuthChallenge::new([42_u8; 32], vec![3])
715
                .encode_onto(&mut data)
716
                .expect("Fail AUTH_CHALLENGE encoding");
717
            our_slog.update(&data);
718

            
719
            // Change the I/O part of the Framed with this new buffer containing our new cell.
720
            *frame = MsgBuf::new(data);
721
            // Receive the AUTH_CHALLENGE
722
            let _ = frame.next().await.transpose().expect("Fail to get cell");
723

            
724
            // Final SLOG should match.
725
            let slog_hash: [u8; 32] = our_slog.finalize().into();
726
            assert_eq!(frame.codec_mut().take_recv_log_digest().unwrap(), slog_hash);
727
        });
728
    }
729
}