1
//! Implementations for the channel handshake
2

            
3
use futures::io::{AsyncRead, AsyncWrite};
4
use futures::sink::SinkExt;
5
use futures::stream::StreamExt;
6
use tor_cell::chancell::msg::AnyChanMsg;
7
use tor_error::internal;
8

            
9
use crate::channel::{ChannelType, UniqId, new_frame};
10
use crate::memquota::ChannelAccount;
11
use crate::util::skew::ClockSkew;
12
use crate::{Error, Result};
13
use tor_cell::chancell::{AnyChanCell, ChanMsg, msg};
14
use tor_rtcompat::{CoarseTimeProvider, SleepProvider, StreamOps};
15

            
16
use std::net::SocketAddr;
17
use std::sync::Arc;
18
use std::time::SystemTime;
19

            
20
use tor_linkspec::{ChanTarget, ChannelMethod, OwnedChanTargetBuilder, RelayIds};
21
use tor_llcrypto as ll;
22
use tor_llcrypto::pk::ed25519::Ed25519Identity;
23
use tor_llcrypto::pk::rsa::RsaIdentity;
24

            
25
use digest::Digest;
26

            
27
use super::ChannelFrame;
28

            
29
use tracing::{debug, instrument, trace};
30

            
31
/// A list of the link protocols that we support.
32
static LINK_PROTOCOLS: &[u16] = &[4, 5];
33

            
34
/// Base trait that all handshake type must implement.
35
///
36
/// It has common code that all handshake share including getters for the channel frame for cell
37
/// decoding/encoding and the unique ID used for logging.
38
///
39
/// It has both a recv() and send() function for the VERSIONS cell since every handshake must start
40
/// with this cell to negotiate the link protocol version.
41
trait ChannelBaseHandshake<T>
42
where
43
    T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
44
{
45
    /// Return a mutable reference to the channel frame.
46
    fn framed_tls(&mut self) -> &mut ChannelFrame<T>;
47
    /// Return a reference to the unique ID of this handshake.
48
    fn unique_id(&self) -> &UniqId;
49

            
50
    /// Send a [msg::Versions] cell.
51
    ///
52
    /// A tuple is returned that is respectively the instant and wallclock of the send.
53
24
    async fn send_versions_cell<F>(
54
24
        &mut self,
55
24
        now_fn: F,
56
24
    ) -> Result<(coarsetime::Instant, SystemTime)>
57
24
    where
58
24
        F: FnOnce() -> SystemTime,
59
24
    {
60
24
        trace!(stream_id = %self.unique_id(), "sending versions");
61
        // Send versions cell
62
24
        let version_cell = AnyChanCell::new(
63
24
            None,
64
24
            msg::Versions::new(LINK_PROTOCOLS)
65
24
                .map_err(|e| Error::from_cell_enc(e, "versions message"))?
66
24
                .into(),
67
        );
68
24
        self.framed_tls().send(version_cell).await?;
69
24
        Ok((
70
24
            coarsetime::Instant::now(), // Flushed at instant
71
24
            now_fn(),                   // Flushed at wallclock
72
24
        ))
73
24
    }
74

            
75
    /// Receive a [msg::Versions] cell.
76
    ///
77
    /// The negotiated link protocol is returned, and also recorded in the underlying channel
78
    /// frame. This automatically transitions the frame into the "Handshake" state of the
79
    /// underlying cell handler. In other words, once the link protocol version is negotiated, the
80
    /// handler can encode and decode cells for that version in order to continue the handshake.
81
24
    async fn recv_versions_cell(&mut self) -> Result<u16> {
82
        // Get versions cell.
83
        // Get versions cell.
84
24
        trace!(stream_id = %self.unique_id(), "waiting for versions");
85
        // This can be None if we've reached EOF or any type of I/O error on the underlying TCP or
86
        // TLS stream. Either case, it is unexpected.
87
24
        let Some(cell) = self.framed_tls().next().await.transpose()? else {
88
            return Err(Error::ChanIoErr(Arc::new(std::io::Error::from(
89
                std::io::ErrorKind::UnexpectedEof,
90
            ))));
91
        };
92
22
        let AnyChanMsg::Versions(their_versions) = cell.into_circid_and_msg().1 else {
93
            return Err(Error::from(internal!(
94
                "Unexpected cell, expecting a VERSIONS cell",
95
            )));
96
        };
97
22
        trace!(stream_id = %self.unique_id(), "received their VERSIONS {:?}", their_versions);
98

            
99
        // Determine which link protocol we negotiated.
100
22
        let link_protocol = their_versions
101
22
            .best_shared_link_protocol(LINK_PROTOCOLS)
102
22
            .ok_or_else(|| Error::HandshakeProto("No shared link protocols".into()))?;
103
20
        trace!(stream_id = %self.unique_id(), "negotiated version {}", link_protocol);
104

            
105
        // Set the link protocol into our channel frame.
106
20
        self.framed_tls()
107
20
            .codec_mut()
108
20
            .set_link_version(link_protocol)?;
109
20
        Ok(link_protocol)
110
24
    }
111
}
112

            
113
/// Handshake initiator base trait. All initiator handshake should implement this trait in order to
114
/// enjoy the helper functions.
115
///
116
/// It requires the base handshake trait to be implement for access to the base getters.
117
trait ChannelInitiatorHandshake<T>: ChannelBaseHandshake<T>
118
where
119
    T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
120
{
121
    /// Return true iff this handshake is expecting to receive an AUTH_CHALLENGE from the
122
    /// responder. As a handshake initiator, we always know if we expect one or not. A client or
123
    /// bridge do not authenticate with the responder while relays will always do.
124
    fn is_expecting_auth_challenge(&self) -> bool;
125

            
126
    /// As an initiator, we are expecting the responder's cells which are (not in that order):
127
    ///     - [msg::AuthChallenge], [msg::Certs], [msg::Netinfo]
128
    ///
129
    /// Any duplicate, missing cell or unexpected results in a protocol level error.
130
    ///
131
    /// This returns the [msg::AuthChallenge], [msg::Certs] and [msg::Netinfo] cells along the
132
    /// instant when the netinfo cell was received. This is needed for the clock skew calculation.
133
20
    async fn recv_cells_from_responder(
134
20
        &mut self,
135
20
    ) -> Result<(
136
20
        Option<msg::AuthChallenge>,
137
20
        msg::Certs,
138
20
        (msg::Netinfo, coarsetime::Instant),
139
20
    )> {
140
20
        let mut auth_challenge_cell: Option<msg::AuthChallenge> = None;
141
20
        let mut certs_cell: Option<msg::Certs> = None;
142
20
        let mut netinfo_cell: Option<(msg::Netinfo, coarsetime::Instant)> = None;
143

            
144
        // IMPORTANT: Protocol wise, we MUST only allow one single cell of each type for a valid
145
        // handshake. Any duplicates lead to a failure. They can arrive in any order unfortunately.
146

            
147
        // Read until we have the netinfo cell.
148
48
        while let Some(cell) = self.framed_tls().next().await.transpose()? {
149
            use super::AnyChanMsg::*;
150
42
            let (_, m) = cell.into_circid_and_msg();
151
42
            trace!(stream_id = %self.unique_id(), "received a {} cell.", m.cmd());
152
42
            match m {
153
                // Ignore the padding. Only VPADDING cell can be sent during handshaking.
154
8
                Vpadding(_) => (),
155
                // Clients don't care about AuthChallenge
156
8
                AuthChallenge(ac) => {
157
8
                    if auth_challenge_cell.replace(ac).is_some() {
158
2
                        return Err(Error::HandshakeProto(
159
2
                            "Duplicate AUTH_CHALLENGE cell".into(),
160
2
                        ));
161
6
                    }
162
                }
163
16
                Certs(c) => {
164
16
                    if certs_cell.replace(c).is_some() {
165
2
                        return Err(Error::HandshakeProto("Duplicate CERTS cell".into()));
166
14
                    }
167
                }
168
10
                Netinfo(n) => {
169
10
                    if netinfo_cell.is_some() {
170
                        // This should be impossible, since we would
171
                        // exit this loop on the first netinfo cell.
172
                        return Err(Error::from(internal!(
173
                            "Somehow tried to record a duplicate NETINFO cell"
174
                        )));
175
10
                    }
176
10
                    netinfo_cell = Some((n, coarsetime::Instant::now()));
177
10
                    break;
178
                }
179
                // This should not happen because the ChannelFrame makes sure that only allowed cell on
180
                // the channel are decoded. However, Rust wants us to consider all AnyChanMsg.
181
                _ => {
182
                    return Err(Error::from(internal!(
183
                        "Unexpected cell during initiator handshake: {m:?}"
184
                    )));
185
                }
186
            }
187
        }
188

            
189
        // Missing any of the above means we are not connected to a Relay and so we abort the
190
        // handshake protocol.
191
12
        let Some((netinfo, netinfo_rcvd_at)) = netinfo_cell else {
192
2
            return Err(Error::HandshakeProto("Missing NETINFO cell".into()));
193
        };
194
10
        let Some(certs) = certs_cell else {
195
2
            return Err(Error::HandshakeProto("Missing CERTS cell".into()));
196
        };
197
        // If we plan to authenticate, we require an AUTH_CHALLENGE cell from the responder.
198
8
        if self.is_expecting_auth_challenge() && auth_challenge_cell.is_none() {
199
            return Err(Error::HandshakeProto("Missing AUTH_CHALLENGE cell".into()));
200
8
        };
201

            
202
8
        Ok((auth_challenge_cell, certs, (netinfo, netinfo_rcvd_at)))
203
20
    }
204
}
205

            
206
/// A raw client channel on which nothing has been done.
207
pub struct ClientInitiatorHandshake<
208
    T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
209
    S: CoarseTimeProvider + SleepProvider,
210
> {
211
    /// Runtime handle (insofar as we need it)
212
    sleep_prov: S,
213

            
214
    /// Memory quota account
215
    memquota: ChannelAccount,
216

            
217
    /// Cell encoder/decoder wrapping the underlying TLS stream
218
    ///
219
    /// (We don't enforce that this is actually TLS, but if it isn't, the
220
    /// connection won't be secure.)
221
    framed_tls: ChannelFrame<T>,
222

            
223
    /// Declared target method for this channel, if any.
224
    target_method: Option<ChannelMethod>,
225

            
226
    /// Logging identifier for this stream.  (Used for logging only.)
227
    unique_id: UniqId,
228
}
229

            
230
/// Implement the base channel handshake trait.
231
impl<T, S> ChannelBaseHandshake<T> for ClientInitiatorHandshake<T, S>
232
where
233
    T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
234
    S: CoarseTimeProvider + SleepProvider,
235
{
236
116
    fn framed_tls(&mut self) -> &mut ChannelFrame<T> {
237
116
        &mut self.framed_tls
238
116
    }
239
120
    fn unique_id(&self) -> &UniqId {
240
120
        &self.unique_id
241
120
    }
242
}
243

            
244
/// Implement the initiator channel handshake trait.
245
impl<T, S> ChannelInitiatorHandshake<T> for ClientInitiatorHandshake<T, S>
246
where
247
    T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
248
    S: CoarseTimeProvider + SleepProvider,
249
{
250
8
    fn is_expecting_auth_challenge(&self) -> bool {
251
        // Client never authenticate with a responder, only relay do.
252
8
        false
253
8
    }
254
}
255

            
256
/// A client channel on which versions have been negotiated and the
257
/// relay's handshake has been read, but where the certs have not
258
/// been checked.
259
pub struct UnverifiedChannel<
260
    T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
261
    S: CoarseTimeProvider + SleepProvider,
262
> {
263
    /// Indicate what type of channel this is.
264
    channel_type: ChannelType,
265
    /// Runtime handle (insofar as we need it)
266
    sleep_prov: S,
267
    /// Memory quota account
268
    memquota: ChannelAccount,
269
    /// The negotiated link protocol.  Must be a member of LINK_PROTOCOLS
270
    link_protocol: u16,
271
    /// The Source+Sink on which we're reading and writing cells.
272
    framed_tls: ChannelFrame<T>,
273
    /// The certs cell that we got from the relay.
274
    certs_cell: msg::Certs,
275
    /// Declared target method for this channel, if any.
276
    target_method: Option<ChannelMethod>,
277
    /// The netinfo cell that we got from the relay.
278
    #[allow(dead_code)] // Relays will need this.
279
    netinfo_cell: msg::Netinfo,
280
    /// How much clock skew did we detect in this handshake?
281
    ///
282
    /// This value is _unauthenticated_, since we have not yet checked whether
283
    /// the keys in the handshake are the ones we expected.
284
    clock_skew: ClockSkew,
285
    /// Logging identifier for this stream.  (Used for logging only.)
286
    unique_id: UniqId,
287
}
288

            
289
/// A client channel on which versions have been negotiated,
290
/// relay's handshake has been read, but the client has not yet
291
/// finished the handshake.
292
///
293
/// This type is separate from UnverifiedChannel, since finishing the
294
/// handshake requires a bunch of CPU, and you might want to do it as
295
/// a separate task or after a yield.
296
pub struct VerifiedChannel<
297
    T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
298
    S: CoarseTimeProvider + SleepProvider,
299
> {
300
    /// Indicate what type of channel this is.
301
    channel_type: ChannelType,
302
    /// Runtime handle (insofar as we need it)
303
    sleep_prov: S,
304
    /// Memory quota account
305
    memquota: ChannelAccount,
306
    /// The negotiated link protocol.
307
    link_protocol: u16,
308
    /// The Source+Sink on which we're reading and writing cells.
309
    framed_tls: ChannelFrame<T>,
310
    /// Declared target method for this stream, if any.
311
    target_method: Option<ChannelMethod>,
312
    /// Logging identifier for this stream.  (Used for logging only.)
313
    unique_id: UniqId,
314
    /// Validated Ed25519 identity for this peer.
315
    ed25519_id: Ed25519Identity,
316
    /// Validated RSA identity for this peer.
317
    rsa_id: RsaIdentity,
318
    /// Authenticated clock skew for this peer.
319
    clock_skew: ClockSkew,
320
}
321

            
322
impl<
323
    T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
324
    S: CoarseTimeProvider + SleepProvider,
325
> ClientInitiatorHandshake<T, S>
326
{
327
    /// Construct a new OutboundClientHandshake.
328
26
    pub(crate) fn new(
329
26
        tls: T,
330
26
        target_method: Option<ChannelMethod>,
331
26
        sleep_prov: S,
332
26
        memquota: ChannelAccount,
333
26
    ) -> Self {
334
26
        Self {
335
26
            framed_tls: new_frame(tls, ChannelType::ClientInitiator),
336
26
            target_method,
337
26
            unique_id: UniqId::new(),
338
26
            sleep_prov,
339
26
            memquota,
340
26
        }
341
26
    }
342

            
343
    /// Negotiate a link protocol version with the relay, and read
344
    /// the relay's handshake information.
345
    ///
346
    /// Takes a function that reports the current time.  In theory, this can just be
347
    /// `SystemTime::now()`.
348
    #[instrument(skip_all, level = "trace")]
349
24
    pub async fn connect<F>(mut self, now_fn: F) -> Result<UnverifiedChannel<T, S>>
350
24
    where
351
24
        F: FnOnce() -> SystemTime,
352
24
    {
353
        match &self.target_method {
354
            Some(method) => debug!(
355
                stream_id = %self.unique_id,
356
                "starting Tor handshake with {:?}",
357
                method
358
            ),
359
            None => debug!(stream_id = %self.unique_id, "starting Tor handshake"),
360
        }
361
        // Send versions cell.
362
        let (versions_flushed_at, versions_flushed_wallclock) =
363
            self.send_versions_cell(now_fn).await?;
364

            
365
        // Receive versions cell.
366
        let link_protocol = self.recv_versions_cell().await?;
367

            
368
        // Receive the relay responder cells. Ignore the AUTH_CHALLENGE cell, we don't need it as
369
        // we are not authenticating with our responder because we are a client.
370
        let (_, certs_cell, (netinfo_cell, netinfo_rcvd_at)) =
371
            self.recv_cells_from_responder().await?;
372

            
373
        // Get the clock skew.
374
        let clock_skew = unauthenticated_clock_skew(
375
            &netinfo_cell,
376
            netinfo_rcvd_at,
377
            versions_flushed_at,
378
            versions_flushed_wallclock,
379
        );
380

            
381
        trace!(stream_id = %self.unique_id, "received handshake, ready to verify.");
382

            
383
        Ok(UnverifiedChannel {
384
            channel_type: ChannelType::ClientInitiator,
385
            link_protocol,
386
            framed_tls: self.framed_tls,
387
            certs_cell,
388
            netinfo_cell,
389
            clock_skew,
390
            target_method: self.target_method.take(),
391
            unique_id: self.unique_id,
392
            sleep_prov: self.sleep_prov.clone(),
393
            memquota: self.memquota.clone(),
394
        })
395
24
    }
396
}
397

            
398
impl<
399
    T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
400
    S: CoarseTimeProvider + SleepProvider,
401
> UnverifiedChannel<T, S>
402
{
403
    /// Return the reported clock skew from this handshake.
404
    ///
405
    /// Note that the skew reported by this function might not be "true": the
406
    /// relay might have its clock set wrong, or it might be lying to us.
407
    ///
408
    /// The clock skew reported here is not yet authenticated; if you need to
409
    /// make sure that the skew is authenticated, use
410
    /// [`Channel::clock_skew`](super::Channel::clock_skew) instead.
411
8
    pub fn clock_skew(&self) -> ClockSkew {
412
8
        self.clock_skew
413
8
    }
414

            
415
    /// Validate the certificates and keys in the relay's handshake.
416
    ///
417
    /// 'peer' is the peer that we want to make sure we're connecting to.
418
    ///
419
    /// 'peer_cert' is the x.509 certificate that the peer presented during
420
    /// its TLS handshake (ServerHello).
421
    ///
422
    /// 'now' is the time at which to check that certificates are
423
    /// valid.  `None` means to use the current time. It can be used
424
    /// for testing to override the current view of the time.
425
    ///
426
    /// This is a separate function because it's likely to be somewhat
427
    /// CPU-intensive.
428
    #[instrument(skip_all, level = "trace")]
429
2
    pub fn check<U: ChanTarget + ?Sized>(
430
2
        self,
431
2
        peer: &U,
432
2
        peer_cert: &[u8],
433
2
        now: Option<std::time::SystemTime>,
434
2
    ) -> Result<VerifiedChannel<T, S>> {
435
2
        let peer_cert_sha256 = ll::d::Sha256::digest(peer_cert);
436
2
        self.check_internal(peer, &peer_cert_sha256[..], now)
437
2
    }
438

            
439
    /// Same as `check`, but takes the SHA256 hash of the peer certificate,
440
    /// since that is all we use.
441
24
    fn check_internal<U: ChanTarget + ?Sized>(
442
24
        self,
443
24
        peer: &U,
444
24
        peer_cert_sha256: &[u8],
445
24
        now: Option<SystemTime>,
446
24
    ) -> Result<VerifiedChannel<T, S>> {
447
        use tor_cert::CertType;
448
        use tor_checkable::*;
449

            
450
        /// Helper: given a time-bound input, give a result reflecting its
451
        /// validity at `now`, and the inner object.
452
        ///
453
        /// We use this here because we want to validate the whole handshake
454
        /// regardless of whether the certs are expired, so we can determine
455
        /// whether we got a plausible handshake with a skewed partner, or
456
        /// whether the handshake is definitely bad.
457
44
        fn check_timeliness<C, T>(checkable: C, now: SystemTime, skew: ClockSkew) -> (Result<()>, T)
458
44
        where
459
44
            C: Timebound<T, Error = TimeValidityError>,
460
        {
461
44
            let status = checkable.is_valid_at(&now).map_err(|e| match (e, skew) {
462
                (TimeValidityError::Expired(expired_by), ClockSkew::Fast(skew))
463
                    if expired_by < skew =>
464
                {
465
                    Error::HandshakeCertsExpired { expired_by }
466
                }
467
                // As it so happens, we don't need to check for this case, since the certs in use
468
                // here only have an expiration time in them.
469
                // (TimeValidityError::NotYetValid(_), ClockSkew::Slow(_)) => todo!(),
470
                (_, _) => Error::HandshakeProto("Certificate expired or not yet valid".into()),
471
            });
472
44
            let cert = checkable.dangerously_assume_timely();
473
44
            (status, cert)
474
44
        }
475
        // Replace 'now' with the real time to use.
476
24
        let now = now.unwrap_or_else(SystemTime::now);
477

            
478
        // We need to check the following lines of authentication:
479
        //
480
        // First, to bind the ed identity to the channel.
481
        //    peer.ed_identity() matches the key in...
482
        //    IDENTITY_V_SIGNING cert, which signs...
483
        //    SIGNING_V_TLS_CERT cert, which signs peer_cert.
484
        //
485
        // Second, to bind the rsa identity to the ed identity:
486
        //    peer.rsa_identity() matches the key in...
487
        //    the x.509 RSA identity certificate (type 2), which signs...
488
        //    the RSA->Ed25519 crosscert (type 7), which signs...
489
        //    peer.ed_identity().
490

            
491
24
        let c = &self.certs_cell;
492
        /// Helper: get a cert from a Certs cell, and convert errors appropriately.
493
134
        fn get_cert(
494
134
            certs: &tor_cell::chancell::msg::Certs,
495
134
            tp: CertType,
496
134
        ) -> Result<tor_cert::KeyUnknownCert> {
497
134
            match certs.parse_ed_cert(tp) {
498
128
                Ok(c) => Ok(c),
499
6
                Err(tor_cell::Error::ChanProto(e)) => Err(Error::HandshakeProto(e)),
500
                Err(e) => Err(Error::HandshakeProto(e.to_string())),
501
            }
502
134
        }
503

            
504
24
        let id_sk = get_cert(c, CertType::IDENTITY_V_SIGNING)?;
505
20
        let sk_tls = get_cert(c, CertType::SIGNING_V_TLS_CERT)?;
506

            
507
18
        let mut sigs = Vec::new();
508

            
509
        // Part 1: validate ed25519 stuff.
510
        //
511
        // (We are performing our timeliness checks now, but not inspecting them
512
        // until later in the function, so that we can distinguish failures that
513
        // might be caused by clock skew from failures that are definitely not
514
        // clock skew.)
515

            
516
        // Check the identity->signing cert
517
18
        let (id_sk, id_sk_sig) = id_sk
518
18
            .should_have_signing_key()
519
18
            .map_err(Error::HandshakeCertErr)?
520
18
            .dangerously_split()
521
18
            .map_err(Error::HandshakeCertErr)?;
522
18
        sigs.push(&id_sk_sig);
523
18
        let (id_sk_timeliness, id_sk) = check_timeliness(id_sk, now, self.clock_skew);
524

            
525
        // Take the identity key from the identity->signing cert
526
18
        let identity_key = id_sk.signing_key().ok_or_else(|| {
527
            Error::HandshakeProto("Missing identity key in identity->signing cert".into())
528
        })?;
529

            
530
        // Take the signing key from the identity->signing cert
531
18
        let signing_key = id_sk.subject_key().as_ed25519().ok_or_else(|| {
532
            Error::HandshakeProto("Bad key type in identity->signing cert".into())
533
        })?;
534

            
535
        // Now look at the signing->TLS cert and check it against the
536
        // peer certificate.
537
18
        let (sk_tls, sk_tls_sig) = sk_tls
538
18
            .should_be_signed_with(signing_key)
539
18
            .map_err(Error::HandshakeCertErr)?
540
18
            .dangerously_split()
541
18
            .map_err(Error::HandshakeCertErr)?;
542
18
        sigs.push(&sk_tls_sig);
543
18
        let (sk_tls_timeliness, sk_tls) = check_timeliness(sk_tls, now, self.clock_skew);
544

            
545
18
        if peer_cert_sha256 != sk_tls.subject_key().as_bytes() {
546
2
            return Err(Error::HandshakeProto(
547
2
                "Peer cert did not authenticate TLS cert".into(),
548
2
            ));
549
16
        }
550

            
551
        // Batch-verify the ed25519 certificates in this handshake.
552
        //
553
        // In theory we could build a list of _all_ the certificates here
554
        // and call pk::validate_all_sigs() instead, but that doesn't gain
555
        // any performance.
556
16
        if !ll::pk::ed25519::validate_batch(&sigs[..]) {
557
2
            return Err(Error::HandshakeProto(
558
2
                "Invalid ed25519 signature in handshake".into(),
559
2
            ));
560
14
        }
561

            
562
        // Part 2: validate rsa stuff.
563

            
564
        // What is the RSA identity key, according to the X.509 certificate
565
        // in which it is self-signed?
566
        //
567
        // (We don't actually check this self-signed certificate, and we use
568
        // a kludge to extract the RSA key)
569
14
        let pkrsa = c
570
14
            .cert_body(CertType::RSA_ID_X509)
571
14
            .and_then(ll::util::x509_extract_rsa_subject_kludge)
572
14
            .ok_or_else(|| Error::HandshakeProto("Couldn't find RSA identity key".into()))?;
573

            
574
        // Now verify the RSA identity -> Ed Identity crosscert.
575
        //
576
        // This proves that the RSA key vouches for the Ed key.  Note that
577
        // the Ed key does not vouch for the RSA key: The RSA key is too
578
        // weak.
579
12
        let rsa_cert = c
580
12
            .cert_body(CertType::RSA_ID_V_IDENTITY)
581
12
            .ok_or_else(|| Error::HandshakeProto("No RSA->Ed crosscert".into()))?;
582
10
        let rsa_cert = tor_cert::rsa::RsaCrosscert::decode(rsa_cert)
583
10
            .map_err(|e| Error::from_bytes_err(e, "RSA identity cross-certificate"))?
584
10
            .check_signature(&pkrsa)
585
10
            .map_err(|_| Error::HandshakeProto("Bad RSA->Ed crosscert signature".into()))?;
586
8
        let (rsa_cert_timeliness, rsa_cert) = check_timeliness(rsa_cert, now, self.clock_skew);
587

            
588
8
        if !rsa_cert.subject_key_matches(identity_key) {
589
            return Err(Error::HandshakeProto(
590
                "RSA->Ed crosscert certifies incorrect key".into(),
591
            ));
592
8
        }
593

            
594
8
        let rsa_id = pkrsa.to_rsa_identity();
595

            
596
8
        trace!(
597
            stream_id = %self.unique_id,
598
            "Validated identity as {} [{}]",
599
            identity_key,
600
            rsa_id
601
        );
602

            
603
        // Now that we've done all the verification steps on the
604
        // certificates, we know who we are talking to.  It's time to
605
        // make sure that the peer we are talking to is the peer we
606
        // actually wanted.
607
        //
608
        // We do this _last_, since "this is the wrong peer" is
609
        // usually a different situation than "this peer couldn't even
610
        // identify itself right."
611

            
612
8
        let actual_identity = RelayIds::builder()
613
8
            .ed_identity(*identity_key)
614
8
            .rsa_identity(rsa_id)
615
8
            .build()
616
8
            .expect("Unable to build RelayIds");
617

            
618
        // We enforce that the relay proved that it has every ID that we wanted:
619
        // it may also have additional IDs that we didn't ask for.
620
8
        match super::check_id_match_helper(&actual_identity, peer) {
621
4
            Err(Error::ChanMismatch(msg)) => Err(Error::HandshakeProto(msg)),
622
4
            other => other,
623
4
        }?;
624

            
625
        // If we reach this point, the clock skew might be may now be considered
626
        // authenticated: The certificates are what we wanted, and everything
627
        // was well signed.
628
        //
629
        // The only remaining concern is certificate timeliness.  If the
630
        // certificates are expired by an amount that is too large for the
631
        // declared clock skew to explain, then  we'll return
632
        // `Error::HandshakeProto`: in that case the clock skew is _not_
633
        // authenticated.  But if the certs are only expired by a little bit,
634
        // we'll reject the handshake with `Error::HandshakeCertsExpired`, and
635
        // the caller can trust the clock skew.
636
        //
637
        // We note expired certs last, since we only want to return
638
        // `HandshakeCertsExpired` when there are no other errors.
639
4
        id_sk_timeliness?;
640
4
        sk_tls_timeliness?;
641
4
        rsa_cert_timeliness?;
642

            
643
4
        Ok(VerifiedChannel {
644
4
            channel_type: self.channel_type,
645
4
            link_protocol: self.link_protocol,
646
4
            framed_tls: self.framed_tls,
647
4
            unique_id: self.unique_id,
648
4
            target_method: self.target_method,
649
4
            ed25519_id: *identity_key,
650
4
            rsa_id,
651
4
            clock_skew: self.clock_skew,
652
4
            sleep_prov: self.sleep_prov,
653
4
            memquota: self.memquota,
654
4
        })
655
24
    }
656
}
657

            
658
impl<
659
    T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
660
    S: CoarseTimeProvider + SleepProvider,
661
> VerifiedChannel<T, S>
662
{
663
    /// Send a 'Netinfo' message to the relay to finish the handshake,
664
    /// and create an open channel and reactor.
665
    ///
666
    /// The channel is used to send cells, and to create outgoing circuits.
667
    /// The reactor is used to route incoming messages to their appropriate
668
    /// circuit.
669
    #[instrument(skip_all, level = "trace")]
670
4
    pub async fn finish(mut self) -> Result<(Arc<super::Channel>, super::reactor::Reactor<S>)> {
671
        // We treat a completed channel -- that is to say, one where the
672
        // authentication is finished -- as incoming traffic.
673
        //
674
        // TODO: conceivably we should remember the time when we _got_ the
675
        // final cell on the handshake, and update the channel completion
676
        // time to be no earlier than _that_ timestamp.
677
        crate::note_incoming_traffic();
678
        trace!(stream_id = %self.unique_id, "Sending netinfo cell.");
679

            
680
        // We do indeed want the real IP here, regardless of whether the
681
        // ChannelMethod is Direct connection or not.  The role of the IP in a
682
        // NETINFO cell is to tell our peer what address we believe they had, so
683
        // that they can better notice MITM attacks and such.
684
        let peer_ip = self
685
            .target_method
686
            .as_ref()
687
            .and_then(ChannelMethod::socket_addrs)
688
4
            .and_then(|addrs| addrs.first())
689
            .map(SocketAddr::ip);
690
        let netinfo = msg::Netinfo::from_client(peer_ip);
691
        self.framed_tls.send(netinfo.into()).await?;
692

            
693
        // We have finalized the handshake, move our codec to Open.
694
        self.framed_tls.codec_mut().set_open()?;
695

            
696
        debug!(
697
            stream_id = %self.unique_id,
698
            "Completed handshake with {} [{}]",
699
            self.ed25519_id, self.rsa_id
700
        );
701

            
702
        // Grab a new handle on which we can apply StreamOps (needed for KIST).
703
        // On Unix platforms, this handle is a wrapper over the fd of the socket.
704
        //
705
        // Note: this is necessary because after `StreamExit::split()`,
706
        // we no longer have access to the underlying stream
707
        // or its StreamOps implementation.
708
        let stream_ops = self.framed_tls.new_handle();
709
        let (tls_sink, tls_stream) = self.framed_tls.split();
710

            
711
        let mut peer_builder = OwnedChanTargetBuilder::default();
712
4
        if let Some(target_method) = self.target_method {
713
            if let Some(addrs) = target_method.socket_addrs() {
714
                peer_builder.addrs(addrs.to_owned());
715
            }
716
            peer_builder.method(target_method);
717
        }
718
        let peer_id = peer_builder
719
            .ed_identity(self.ed25519_id)
720
            .rsa_identity(self.rsa_id)
721
            .build()
722
            .expect("OwnedChanTarget builder failed");
723

            
724
        super::Channel::new(
725
            self.channel_type,
726
            self.link_protocol,
727
            Box::new(tls_sink),
728
            Box::new(tls_stream),
729
            stream_ops,
730
            self.unique_id,
731
            peer_id,
732
            self.clock_skew,
733
            self.sleep_prov,
734
            self.memquota,
735
        )
736
4
    }
737
}
738

            
739
/// Helper: Calculate a clock skew from the [msg::Netinfo] cell data and the time at which we sent
740
/// the [msg::Versions] cell.
741
///
742
/// This is unauthenticated as in not validated with the certificates. Before using it, make sure
743
/// that you have authenticated the other party.
744
53
fn unauthenticated_clock_skew(
745
53
    netinfo_cell: &msg::Netinfo,
746
53
    netinfo_rcvd_at: coarsetime::Instant,
747
53
    versions_flushed_at: coarsetime::Instant,
748
53
    versions_flushed_wallclock: SystemTime,
749
53
) -> ClockSkew {
750
    // Try to compute our clock skew.  It won't be authenticated yet, since we haven't checked
751
    // the certificates.
752
53
    if let Some(netinfo_timestamp) = netinfo_cell.timestamp() {
753
51
        let delay = netinfo_rcvd_at - versions_flushed_at;
754
51
        ClockSkew::from_handshake_timestamps(
755
51
            versions_flushed_wallclock,
756
51
            netinfo_timestamp,
757
51
            delay.into(),
758
        )
759
    } else {
760
2
        ClockSkew::None
761
    }
762
53
}
763

            
764
#[cfg(test)]
765
pub(super) mod test {
766
    #![allow(clippy::unwrap_used)]
767
    use hex_literal::hex;
768
    use regex::Regex;
769
    use std::time::{Duration, SystemTime};
770

            
771
    use super::*;
772
    use crate::Result;
773
    use crate::channel::handler::test::MsgBuf;
774
    use crate::util::fake_mq;
775
    use tor_cell::chancell::msg;
776
    use tor_linkspec::OwnedChanTarget;
777
    use tor_rtcompat::{PreferredRuntime, Runtime};
778

            
779
    const VERSIONS: &[u8] = &hex!("0000 07 0006 0003 0004 0005");
780
    // no certificates in this cell, but connect() doesn't care.
781
    const NOCERTS: &[u8] = &hex!("00000000 81 0001 00");
782
    const NETINFO_PREFIX: &[u8] = &hex!(
783
        "00000000 08 00000000
784
         04 04 7f 00 00 02
785
         01
786
         04 04 7f 00 00 03"
787
    );
788
    const NETINFO_PREFIX_WITH_TIME: &[u8] = &hex!(
789
        "00000000 08 48949290
790
         04 04 7f 00 00 02
791
         01
792
         04 04 7f 00 00 03"
793
    );
794
    const AUTHCHALLENGE: &[u8] = &hex!(
795
        "00000000 82 0026
796
         FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
797
         FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
798
         0002 0003 00ff"
799
    );
800

            
801
    const VPADDING: &[u8] = &hex!("00000000 80 0003 FF FF FF");
802

            
803
    fn add_padded(buf: &mut Vec<u8>, cell: &[u8]) {
804
        let len_prev = buf.len();
805
        buf.extend_from_slice(cell);
806
        buf.resize(len_prev + 514, 0);
807
    }
808
    fn add_netinfo(buf: &mut Vec<u8>) {
809
        add_padded(buf, NETINFO_PREFIX);
810
    }
811

            
812
    #[test]
813
    fn connect_ok() -> Result<()> {
814
        tor_rtcompat::test_with_one_runtime!(|rt| async move {
815
            let now = humantime::parse_rfc3339("2008-08-02T17:00:00Z").unwrap();
816
            let mut buf = Vec::new();
817
            // versions cell
818
            buf.extend_from_slice(VERSIONS);
819
            // certs cell -- no certs in it, but this function doesn't care.
820
            buf.extend_from_slice(NOCERTS);
821
            // netinfo cell -- quite minimal.
822
            add_padded(&mut buf, NETINFO_PREFIX);
823
            let mb = MsgBuf::new(&buf[..]);
824
            let handshake = ClientInitiatorHandshake::new(mb, None, rt.clone(), fake_mq());
825
            let unverified = handshake.connect(|| now).await?;
826

            
827
            assert_eq!(unverified.link_protocol, 5);
828
            // No timestamp in the NETINFO, so no skew.
829
            assert_eq!(unverified.clock_skew(), ClockSkew::None);
830

            
831
            // Try again with some padding.
832
            let mut buf = Vec::new();
833
            buf.extend_from_slice(VERSIONS);
834
            buf.extend_from_slice(NOCERTS);
835
            buf.extend_from_slice(VPADDING);
836
            buf.extend_from_slice(AUTHCHALLENGE);
837
            buf.extend_from_slice(VPADDING);
838
            add_padded(&mut buf, NETINFO_PREFIX_WITH_TIME);
839
            let mb = MsgBuf::new(&buf[..]);
840
            let handshake = ClientInitiatorHandshake::new(mb, None, rt.clone(), fake_mq());
841
            let unverified = handshake.connect(|| now).await?;
842
            // Correct timestamp in the NETINFO, so no skew.
843
            assert_eq!(unverified.clock_skew(), ClockSkew::None);
844

            
845
            // Now pretend our clock is fast.
846
            let now2 = now + Duration::from_secs(3600);
847
            let mb = MsgBuf::new(&buf[..]);
848
            let handshake = ClientInitiatorHandshake::new(mb, None, rt.clone(), fake_mq());
849
            let unverified = handshake.connect(|| now2).await?;
850
            assert_eq!(
851
                unverified.clock_skew(),
852
                ClockSkew::Fast(Duration::from_secs(3600))
853
            );
854

            
855
            Ok(())
856
        })
857
    }
858

            
859
    async fn connect_err<T: Into<Vec<u8>>, S>(input: T, sleep_prov: S) -> Error
860
    where
861
        S: CoarseTimeProvider + SleepProvider,
862
    {
863
        let mb = MsgBuf::new(input);
864
        let handshake = ClientInitiatorHandshake::new(mb, None, sleep_prov, fake_mq());
865
        handshake.connect(SystemTime::now).await.err().unwrap()
866
    }
867

            
868
    #[test]
869
    fn connect_badver() {
870
        tor_rtcompat::test_with_one_runtime!(|rt| async move {
871
            let err = connect_err(&b"HTTP://"[..], rt.clone()).await;
872
            assert!(matches!(err, Error::HandshakeProto(_)));
873
            assert_eq!(
874
                format!("{}", err),
875
                "Handshake protocol violation: Invalid CircID in variable cell"
876
            );
877

            
878
            let err = connect_err(&hex!("0000 07 0004 1234 ffff")[..], rt.clone()).await;
879
            assert!(matches!(err, Error::HandshakeProto(_)));
880
            assert_eq!(
881
                format!("{}", err),
882
                "Handshake protocol violation: No shared link protocols"
883
            );
884
        });
885
    }
886

            
887
    #[test]
888
    fn connect_cellparse() {
889
        tor_rtcompat::test_with_one_runtime!(|rt| async move {
890
            let mut buf = Vec::new();
891
            buf.extend_from_slice(VERSIONS);
892
            // Here's a certs cell that will fail.
893
            buf.extend_from_slice(&hex!("00000000 81 0001 01")[..]);
894
            let err = connect_err(buf, rt.clone()).await;
895
            assert!(matches!(err, Error::HandshakeProto { .. }));
896
        });
897
    }
898

            
899
    #[test]
900
    fn connect_duplicates() {
901
        tor_rtcompat::test_with_one_runtime!(|rt| async move {
902
            let mut buf = Vec::new();
903
            buf.extend_from_slice(VERSIONS);
904
            buf.extend_from_slice(NOCERTS);
905
            buf.extend_from_slice(NOCERTS);
906
            add_netinfo(&mut buf);
907
            let err = connect_err(buf, rt.clone()).await;
908
            assert!(matches!(err, Error::HandshakeProto(_)));
909
            assert_eq!(
910
                format!("{}", err),
911
                "Handshake protocol violation: Duplicate CERTS cell"
912
            );
913

            
914
            let mut buf = Vec::new();
915
            buf.extend_from_slice(VERSIONS);
916
            buf.extend_from_slice(NOCERTS);
917
            buf.extend_from_slice(AUTHCHALLENGE);
918
            buf.extend_from_slice(AUTHCHALLENGE);
919
            add_netinfo(&mut buf);
920
            let err = connect_err(buf, rt.clone()).await;
921
            assert!(matches!(err, Error::HandshakeProto(_)));
922
            assert_eq!(
923
                format!("{}", err),
924
                "Handshake protocol violation: Duplicate AUTH_CHALLENGE cell"
925
            );
926
        });
927
    }
928

            
929
    #[test]
930
    fn connect_missing_certs() {
931
        tor_rtcompat::test_with_one_runtime!(|rt| async move {
932
            let mut buf = Vec::new();
933
            buf.extend_from_slice(VERSIONS);
934
            add_netinfo(&mut buf);
935
            let err = connect_err(buf, rt.clone()).await;
936
            assert!(matches!(err, Error::HandshakeProto(_)));
937
            assert_eq!(
938
                format!("{}", err),
939
                "Handshake protocol violation: Missing CERTS cell"
940
            );
941
        });
942
    }
943

            
944
    #[test]
945
    fn connect_missing_netinfo() {
946
        tor_rtcompat::test_with_one_runtime!(|rt| async move {
947
            let mut buf = Vec::new();
948
            buf.extend_from_slice(VERSIONS);
949
            buf.extend_from_slice(NOCERTS);
950
            let err = connect_err(buf, rt.clone()).await;
951
            assert!(matches!(err, Error::HandshakeProto(_)));
952
            assert_eq!(
953
                format!("{}", err),
954
                "Handshake protocol violation: Missing NETINFO cell"
955
            );
956
        });
957
    }
958

            
959
    #[test]
960
    fn connect_misplaced_cell() {
961
        tor_rtcompat::test_with_one_runtime!(|rt| async move {
962
            let mut buf = Vec::new();
963
            buf.extend_from_slice(VERSIONS);
964
            // here's a create cell.
965
            add_padded(&mut buf, &hex!("00000001 01")[..]);
966
            let err = connect_err(buf, rt.clone()).await;
967
            assert!(matches!(err, Error::HandshakeProto(_)));
968
            assert_eq!(
969
                format!("{}", err),
970
                "Handshake protocol violation: Decoding cell error: Error while parsing channel cell: Bad object: Unexpected command CREATE in HandshakeRelayResponderMsg"
971
            );
972
        });
973
    }
974

            
975
    fn make_unverified<R>(certs: msg::Certs, runtime: R) -> UnverifiedChannel<MsgBuf, R>
976
    where
977
        R: Runtime,
978
    {
979
        let localhost = std::net::IpAddr::V4(std::net::Ipv4Addr::LOCALHOST);
980
        let netinfo_cell = msg::Netinfo::from_client(Some(localhost));
981
        let mut framed_tls = new_frame(MsgBuf::new(&b""[..]), ChannelType::ClientInitiator);
982
        let _ = framed_tls.codec_mut().set_link_version(4);
983
        let _ = framed_tls.codec_mut().set_open();
984
        let clock_skew = ClockSkew::None;
985
        UnverifiedChannel {
986
            channel_type: ChannelType::ClientInitiator,
987
            link_protocol: 4,
988
            framed_tls,
989
            certs_cell: certs,
990
            netinfo_cell,
991
            clock_skew,
992
            target_method: None,
993
            unique_id: UniqId::new(),
994
            sleep_prov: runtime,
995
            memquota: fake_mq(),
996
        }
997
    }
998

            
999
    // Timestamp when the example certificates were all valid.
    fn cert_timestamp() -> SystemTime {
        use humantime::parse_rfc3339;
        parse_rfc3339("2020-09-26T18:01:20Z").unwrap()
    }
    fn certs_test<R>(
        certs: msg::Certs,
        when: Option<SystemTime>,
        peer_ed: &[u8],
        peer_rsa: &[u8],
        peer_cert_sha256: &[u8],
        runtime: &R,
    ) -> Result<VerifiedChannel<MsgBuf, R>>
    where
        R: Runtime,
    {
        let unver = make_unverified(certs, runtime.clone());
        let ed = Ed25519Identity::from_bytes(peer_ed).unwrap();
        let rsa = RsaIdentity::from_bytes(peer_rsa).unwrap();
        let chan = OwnedChanTarget::builder()
            .ed_identity(ed)
            .rsa_identity(rsa)
            .build()
            .unwrap();
        unver.check_internal(&chan, peer_cert_sha256, when)
    }
    // no certs at all!
    #[test]
    fn certs_none() {
        let rt = PreferredRuntime::create().unwrap();
        let err = certs_test(
            msg::Certs::new_empty(),
            None,
            &[0_u8; 32],
            &[0_u8; 20],
            &[0_u8; 128],
            &rt,
        )
        .err()
        .unwrap();
        assert_eq!(
            format!("{}", err),
            "Handshake protocol violation: Missing IDENTITY_V_SIGNING certificate"
        );
    }
    #[test]
    fn certs_good() {
        let rt = PreferredRuntime::create().unwrap();
        let mut certs = msg::Certs::new_empty();
        certs.push_cert_body(2.into(), certs::CERT_T2);
        certs.push_cert_body(5.into(), certs::CERT_T5);
        certs.push_cert_body(7.into(), certs::CERT_T7);
        certs.push_cert_body(4.into(), certs::CERT_T4);
        let res = certs_test(
            certs,
            Some(cert_timestamp()),
            certs::PEER_ED,
            certs::PEER_RSA,
            certs::PEER_CERT_DIGEST,
            &rt,
        );
        let _ = res.unwrap();
    }
    #[test]
    fn certs_missing() {
        let rt = PreferredRuntime::create().unwrap();
        let all_certs = [
            (2, certs::CERT_T2, "Couldn't find RSA identity key"),
            (7, certs::CERT_T7, "No RSA->Ed crosscert"),
            (4, certs::CERT_T4, "Missing IDENTITY_V_SIGNING certificate"),
            (5, certs::CERT_T5, "Missing SIGNING_V_TLS_CERT certificate"),
        ];
        for omit_idx in 0..4 {
            // build a certs cell with all but one certificate
            let mut certs = msg::Certs::new_empty();
            let mut expect_err = None;
            for (idx, (ctype, cert, err)) in all_certs.iter().enumerate() {
                if idx == omit_idx {
                    expect_err = Some(err);
                    continue;
                }
                certs.push_cert_body((*ctype).into(), &cert[..]);
            }
            let res = certs_test(
                certs,
                Some(cert_timestamp()),
                certs::PEER_ED,
                certs::PEER_RSA,
                certs::PEER_CERT_DIGEST,
                &rt,
            )
            .err()
            .unwrap();
            assert_eq!(
                format!("{}", res),
                format!("Handshake protocol violation: {}", expect_err.unwrap())
            );
        }
    }
    #[test]
    fn certs_wrongtarget() {
        let rt = PreferredRuntime::create().unwrap();
        let mut certs = msg::Certs::new_empty();
        certs.push_cert_body(2.into(), certs::CERT_T2);
        certs.push_cert_body(5.into(), certs::CERT_T5);
        certs.push_cert_body(7.into(), certs::CERT_T7);
        certs.push_cert_body(4.into(), certs::CERT_T4);
        let err = certs_test(
            certs.clone(),
            Some(cert_timestamp()),
            &[0x10; 32],
            certs::PEER_RSA,
            certs::PEER_CERT_DIGEST,
            &rt,
        )
        .err()
        .unwrap();
        let re = Regex::new(
            // identities might be scrubbed by safelog
            r"Identity .* does not match target .*",
        )
        .unwrap();
        assert!(re.is_match(&format!("{}", err)));
        let err = certs_test(
            certs.clone(),
            Some(cert_timestamp()),
            certs::PEER_ED,
            &[0x99; 20],
            certs::PEER_CERT_DIGEST,
            &rt,
        )
        .err()
        .unwrap();
        let re = Regex::new(
            // identities might be scrubbed by safelog
            r"Identity .* does not match target .*",
        )
        .unwrap();
        assert!(re.is_match(&format!("{}", err)));
        let err = certs_test(
            certs,
            Some(cert_timestamp()),
            certs::PEER_ED,
            certs::PEER_RSA,
            &[0; 32],
            &rt,
        )
        .err()
        .unwrap();
        assert_eq!(
            format!("{}", err),
            "Handshake protocol violation: Peer cert did not authenticate TLS cert"
        );
    }
    #[test]
    fn certs_badsig() {
        let rt = PreferredRuntime::create().unwrap();
        fn munge(inp: &[u8]) -> Vec<u8> {
            let mut v: Vec<u8> = inp.into();
            v[inp.len() - 1] ^= 0x10;
            v
        }
        let mut certs = msg::Certs::new_empty();
        certs.push_cert_body(2.into(), certs::CERT_T2);
        certs.push_cert_body(5.into(), munge(certs::CERT_T5)); // munge an ed signature
        certs.push_cert_body(7.into(), certs::CERT_T7);
        certs.push_cert_body(4.into(), certs::CERT_T4);
        let res = certs_test(
            certs,
            Some(cert_timestamp()),
            certs::PEER_ED,
            certs::PEER_RSA,
            certs::PEER_CERT_DIGEST,
            &rt,
        )
        .err()
        .unwrap();
        assert_eq!(
            format!("{}", res),
            "Handshake protocol violation: Invalid ed25519 signature in handshake"
        );
        let mut certs = msg::Certs::new_empty();
        certs.push_cert_body(2.into(), certs::CERT_T2);
        certs.push_cert_body(5.into(), certs::CERT_T5);
        certs.push_cert_body(7.into(), munge(certs::CERT_T7)); // munge an RSA signature
        certs.push_cert_body(4.into(), certs::CERT_T4);
        let res = certs_test(
            certs,
            Some(cert_timestamp()),
            certs::PEER_ED,
            certs::PEER_RSA,
            certs::PEER_CERT_DIGEST,
            &rt,
        )
        .err()
        .unwrap();
        assert_eq!(
            format!("{}", res),
            "Handshake protocol violation: Bad RSA->Ed crosscert signature"
        );
    }
    /// This module has a few certificates to play with. They're taken
    /// from a chutney network. They match those used in the CERTS
    /// cell test vector in the tor-cell crate.
    ///
    /// The names are taken from the type of the certificate.
    mod certs {
        use hex_literal::hex;
        pub(crate) const CERT_T2: &[u8] = &hex!(
            "308201B930820122A0030201020208607C28BE6C390943300D06092A864886F70D01010B0500301F311D301B06035504030C147777772E74636A76356B766A646472322E636F6D301E170D3230303831303030303030305A170D3231303831303030303030305A301F311D301B06035504030C147777772E74636A76356B766A646472322E636F6D30819F300D06092A864886F70D010101050003818D0030818902818100D38B1E6CEB946E0DB0751F4CBACE3DCB9688B6C25304227B4710C35AFB73627E50500F5913E158B621802612D1C75827003703338375237552EB3CD3C12F6AB3604E60C1A2D26BB1FBAD206FF023969A90909D6A65A5458A5312C26EBD3A3DAD30302D4515CDCD264146AC18E6FC60A04BD3EC327F04294D96BA5AA25B464C3F0203010001300D06092A864886F70D01010B0500038181003BCE561EA7F95CC00B78AAB5D69573FF301C282A751D4A651921D042F1BECDBA24D918A6D8A5E138DC07BBA0B335478AE37ABD2C93A93932442AE9084329E846170FE0FC4A50AAFC804F311CC3CA4F41D845A7BA5901CBBC3E021E9794AAC70CE1F37B0A951592DB1B64F2B4AFB81AE52DBD9B6FEDE96A5FB8125EB6251EE50A"
        );
        pub(crate) const CERT_T4: &[u8] = &hex!(
            "01040006CC2A01F82294B866A31F01FC5D0DA8572850A9B929545C3266558D7D2316E3B74172B00100200400DCB604DB2034B00FD16986D4ADB9D16B21CB4E4457A33DEC0F538903683E96E9FF1A5203FA27F86EF7528D89A0845D2520166E340754FFEA2AAE0F612B7CE5DA094A0236CDAC45034B0B6842C18E7F6B51B93A3CF7E60663B8AD061C30A62602"
        );
        pub(crate) const CERT_T5: &[u8] = &hex!(
            "01050006C98A03B4FD606B64E4CBD466B8D76CB131069BAE6F3AA1878857C9F624E31D77A799B8007173E5F8068431D0D3F5EE16B4C9FFD59DF373E152A87281BAE744AA5FCF72171BF4B27C4E8FC1C6A9FC5CA11058BC49647063D7903CFD9F512F89099B27BC0C"
        );
        pub(crate) const CERT_T7: &[u8] = &hex!(
            "DCB604DB2034B00FD16986D4ADB9D16B21CB4E4457A33DEC0F538903683E96E90006DA3A805CF6006F9179066534DE6B45AD47A5C469063EE462762723396DC9F25452A0A52DA3F5087DD239F2A311F6B0D4DFEFF4ABD089DC3D0237A0ABAB19EB2045B91CDCAF04BE0A72D548A27BF2E77BD876ECFE5E1BE622350DA6BF31F6E306ED896488DD5B39409B23FC3EB7B2C9F7328EB18DA36D54D80575899EA6507CCBFCDF1F"
        );
        pub(crate) const PEER_CERT_DIGEST: &[u8] =
            &hex!("b4fd606b64e4cbd466b8d76cb131069bae6f3aa1878857c9f624e31d77a799b8");
        pub(crate) const PEER_ED: &[u8] =
            &hex!("dcb604db2034b00fd16986d4adb9d16b21cb4e4457a33dec0f538903683e96e9");
        pub(crate) const PEER_RSA: &[u8] = &hex!("2f1fb49bb332a9eec617e41e911c33fb3890aef3");
    }
    #[test]
    fn test_finish() {
        tor_rtcompat::test_with_one_runtime!(|rt| async move {
            let ed25519_id = [3_u8; 32].into();
            let rsa_id = [4_u8; 20].into();
            let peer_addr = "127.1.1.2:443".parse().unwrap();
            let mut framed_tls = new_frame(MsgBuf::new(&b""[..]), ChannelType::ClientInitiator);
            let _ = framed_tls.codec_mut().set_link_version(4);
            let ver = VerifiedChannel {
                channel_type: ChannelType::ClientInitiator,
                link_protocol: 4,
                framed_tls,
                unique_id: UniqId::new(),
                target_method: Some(ChannelMethod::Direct(vec![peer_addr])),
                ed25519_id,
                rsa_id,
                clock_skew: ClockSkew::None,
                sleep_prov: rt,
                memquota: fake_mq(),
            };
            let (_chan, _reactor) = ver.finish().await.unwrap();
            // TODO: check contents of netinfo cell
        });
    }
}