Skip to main content

tor_proto/channel/
handshake.rs

1//! Implementations for the channel handshake
2
3use digest::Digest;
4use futures::io::{AsyncRead, AsyncWrite};
5use futures::sink::SinkExt;
6use futures::stream::{Stream, StreamExt};
7use std::net::IpAddr;
8use std::sync::Arc;
9use tracing::{debug, instrument, trace};
10
11use safelog::{MaybeSensitive, Redacted};
12use tor_cell::chancell::msg::AnyChanMsg;
13use tor_cell::chancell::{AnyChanCell, ChanMsg, msg};
14use tor_cell::restrict::{RestrictedMsg, restricted_msg};
15use tor_cert::CertType;
16use tor_checkable::{TimeValidityError, Timebound};
17use tor_error::internal;
18use tor_linkspec::{
19    ChanTarget, ChannelMethod, OwnedChanTarget, OwnedChanTargetBuilder, RelayIds, RelayIdsBuilder,
20};
21use tor_llcrypto as ll;
22use tor_llcrypto::pk::{ValidatableSignature, ed25519::Ed25519Identity};
23use tor_rtcompat::{CoarseTimeProvider, Runtime, SleepProvider, StreamOps};
24use web_time_compat::{SystemTime, SystemTimeExt};
25
26use crate::channel::handler::SlogDigest;
27use crate::channel::{Canonicity, ChannelFrame, ChannelMode, UniqId};
28use crate::memquota::ChannelAccount;
29use crate::peer::PeerInfo;
30use crate::util::skew::ClockSkew;
31use crate::{Error, Result};
32
33/// A list of the link protocols that we support.
34pub(crate) static LINK_PROTOCOLS: &[u16] = &[4, 5];
35
36/// Base trait that all handshake type must implement.
37///
38/// It has common code that all handshake share including getters for the channel frame for cell
39/// decoding/encoding and the unique ID used for logging.
40///
41/// It has both a recv() and send() function for the VERSIONS cell since every handshake must start
42/// with this cell to negotiate the link protocol version.
43pub(crate) trait ChannelBaseHandshake<T>
44where
45    T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
46{
47    /// Return a mutable reference to the channel frame.
48    fn framed_tls(&mut self) -> &mut ChannelFrame<T>;
49    /// Return a reference to the unique ID of this handshake.
50    fn unique_id(&self) -> &UniqId;
51
52    /// Send a [msg::Versions] cell.
53    ///
54    /// A tuple is returned that is respectively the instant and wallclock of the send.
55    async fn send_versions_cell<F>(
56        &mut self,
57        now_fn: F,
58    ) -> Result<(coarsetime::Instant, SystemTime)>
59    where
60        F: FnOnce() -> SystemTime,
61    {
62        trace!(stream_id = %self.unique_id(), "sending versions");
63        // Send versions cell
64        let version_cell = AnyChanCell::new(
65            None,
66            msg::Versions::new(LINK_PROTOCOLS)
67                .map_err(|e| Error::from_cell_enc(e, "versions message"))?
68                .into(),
69        );
70        self.framed_tls().send(version_cell).await?;
71        Ok((
72            coarsetime::Instant::now(), // Flushed at instant
73            now_fn(),                   // Flushed at wallclock
74        ))
75    }
76
77    /// Receive a [msg::Versions] cell.
78    ///
79    /// The negotiated link protocol is returned, and also recorded in the underlying channel
80    /// frame. This automatically transitions the frame into the "Handshake" state of the
81    /// underlying cell handler. In other words, once the link protocol version is negotiated, the
82    /// handler can encode and decode cells for that version in order to continue the handshake.
83    async fn recv_versions_cell(&mut self) -> Result<u16> {
84        // Get versions cell.
85        // Get versions cell.
86        trace!(stream_id = %self.unique_id(), "waiting for versions");
87        // This can be None if we've reached EOF or any type of I/O error on the underlying TCP or
88        // TLS stream. Either case, it is unexpected.
89        let Some(cell) = self.framed_tls().next().await.transpose()? else {
90            return Err(Error::ChanIoErr(Arc::new(std::io::Error::from(
91                std::io::ErrorKind::UnexpectedEof,
92            ))));
93        };
94        let AnyChanMsg::Versions(their_versions) = cell.into_circid_and_msg().1 else {
95            return Err(Error::from(internal!(
96                "Unexpected cell, expecting a VERSIONS cell",
97            )));
98        };
99        trace!(stream_id = %self.unique_id(), "received their VERSIONS {:?}", their_versions);
100
101        // Determine which link protocol we negotiated.
102        let link_protocol = their_versions
103            .best_shared_link_protocol(LINK_PROTOCOLS)
104            .ok_or_else(|| Error::HandshakeProto("No shared link protocols".into()))?;
105        trace!(stream_id = %self.unique_id(), "negotiated version {}", link_protocol);
106
107        Ok(link_protocol)
108    }
109
110    /// Given a link protocol version, set it into our channel cell handler. All channel type do
111    /// this after negotiating a [`msg::Versions`] cell.
112    ///
113    /// This will effectively transition the handler's state from New to Handshake.
114    fn set_link_protocol(&mut self, link_protocol: u16) -> Result<()> {
115        self.framed_tls()
116            .codec_mut()
117            .set_link_version(link_protocol)
118    }
119}
120
121/// Helper: This enum is for adding semantic to the function receiving cells indicating it to
122/// either take the auth log out or leave it in place.
123///
124/// With this, we avoid using a flat bool which is confusing at the call site.
125pub(crate) enum AuthLogAction {
126    /// Leave it in place.
127    Leave,
128    /// Take it out.
129    Take,
130}
131
132impl AuthLogAction {
133    /// Return true iff this value is [`AuthLogAction::Take`]
134    fn is_take(&self) -> bool {
135        matches!(self, Self::Take)
136    }
137}
138
139/// Handshake initiator base trait. All initiator handshake should implement this trait in order to
140/// enjoy the helper functions.
141///
142/// It requires the base handshake trait to be implement for access to the base getters.
143pub(crate) trait ChannelInitiatorHandshake<T>: ChannelBaseHandshake<T>
144where
145    T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
146{
147    /// As an initiator, we are expecting the responder's cells which are:
148    /// - [msg::Certs]
149    /// - [msg::AuthChallenge]
150    /// - [msg::Netinfo]
151    ///
152    /// Any duplicate, missing cell or unexpected results in a protocol level error.
153    ///
154    /// This returns the:
155    /// - [msg::AuthChallenge] cell
156    /// - [msg::Certs] cell
157    /// - [msg::Netinfo] cell
158    /// - the instant when the netinfo cell was received (needed for the clock skew calculation)
159    /// - the SLOG digest if `auth_log_action` is [`AuthLogAction::Take`] (needed if we send an
160    ///   [msg::Authenticate] cell in the future)
161    async fn recv_cells_from_responder(
162        &mut self,
163        auth_log_action: AuthLogAction,
164    ) -> Result<(
165        msg::AuthChallenge,
166        msg::Certs,
167        (msg::Netinfo, coarsetime::Instant),
168        Option<SlogDigest>,
169    )> {
170        // IMPORTANT: Protocol wise, we MUST only allow one single cell of each type for a valid
171        // handshake. Any duplicates lead to a failure.
172        // They must arrive in a specific order in order for the SLOG calculation to be valid.
173
174        // Note that the `ChannelFrame` already restricts the messages due to its handshake cell
175        // handler.
176
177        let certs = loop {
178            restricted_msg! {
179                enum CertsMsg : ChanMsg {
180                    // VPADDING cells (but not PADDING) can be sent during handshaking.
181                    Vpadding,
182                    Certs,
183               }
184            }
185
186            break match read_msg(*self.unique_id(), self.framed_tls()).await? {
187                CertsMsg::Vpadding(_) => continue,
188                CertsMsg::Certs(msg) => msg,
189            };
190        };
191
192        // Clients don't care about AuthChallenge,
193        // but the responder always sends it anyways so we require it here.
194        let auth_challenge = loop {
195            restricted_msg! {
196                enum AuthChallengeMsg : ChanMsg {
197                    // VPADDING cells (but not PADDING) can be sent during handshaking.
198                    Vpadding,
199                    AuthChallenge,
200               }
201            }
202
203            break match read_msg(*self.unique_id(), self.framed_tls()).await? {
204                AuthChallengeMsg::Vpadding(_) => continue,
205                AuthChallengeMsg::AuthChallenge(msg) => msg,
206            };
207        };
208
209        let slog_digest = if auth_log_action.is_take() {
210            // We're the initiator, which means that the recv log is the SLOG.
211            Some(SlogDigest::new(
212                self.framed_tls().codec_mut().take_recv_log_digest()?,
213            ))
214        } else {
215            None
216        };
217
218        let (netinfo, netinfo_rcvd_at) = loop {
219            restricted_msg! {
220                enum NetinfoMsg : ChanMsg {
221                    // VPADDING cells (but not PADDING) can be sent during handshaking.
222                    Vpadding,
223                    Netinfo,
224               }
225            }
226
227            break match read_msg(*self.unique_id(), self.framed_tls()).await? {
228                NetinfoMsg::Vpadding(_) => continue,
229                NetinfoMsg::Netinfo(msg) => (msg, coarsetime::Instant::now()),
230            };
231        };
232
233        Ok((
234            auth_challenge,
235            certs,
236            (netinfo, netinfo_rcvd_at),
237            slog_digest,
238        ))
239    }
240}
241
242/// A base channel on which versions have been negotiated and the relay's handshake has been read,
243/// but where the certs have not been checked.
244///
245/// Both relay and client have specialized objects for an unverified channel which include this one
246/// as the base in order to share functionalities.
247pub(crate) struct UnverifiedChannel<
248    T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
249    S: CoarseTimeProvider + SleepProvider,
250> {
251    /// Runtime handle (insofar as we need it)
252    pub(crate) sleep_prov: S,
253    /// Memory quota account
254    pub(crate) memquota: ChannelAccount,
255    /// The negotiated link protocol.  Must be a member of LINK_PROTOCOLS
256    pub(crate) link_protocol: u16,
257    /// The Source+Sink on which we're reading and writing cells.
258    pub(crate) framed_tls: ChannelFrame<T>,
259    /// Declared target method for this channel, if any.
260    pub(crate) target_method: Option<ChannelMethod>,
261    /// How much clock skew did we detect in this handshake?
262    ///
263    /// This value is _unauthenticated_, since we have not yet checked whether
264    /// the keys in the handshake are the ones we expected.
265    pub(crate) clock_skew: ClockSkew,
266    /// Logging identifier for this stream.  (Used for logging only.)
267    pub(crate) unique_id: UniqId,
268}
269
270/// A base initiator channel on which versions have been negotiated and the relay's handshake has
271/// been read, but where the [`msg::Certs`] has not been checked.
272///
273/// Both relay and client have specialized objects for an unverified channel which include this one
274/// as the base in order to share functionnalities.
275///
276/// We need this intermediary object between the specialized one (client/relay) and the
277/// [`UnverifiedChannel`] because certs validation is quite different from a respodner channel.
278/// This avoid code duplication.
279pub(crate) struct UnverifiedInitiatorChannel<
280    T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
281    S: CoarseTimeProvider + SleepProvider,
282> {
283    /// Base unverified channel.
284    pub(crate) inner: UnverifiedChannel<T, S>,
285    /// The [`msg::Certs`] received during the handshake.
286    pub(crate) certs_cell: msg::Certs,
287}
288
289/// A base channel on which versions have been negotiated, relay's handshake has been read, but the
290/// client has not yet finished the handshake.
291///
292/// This type is separate from UnverifiedChannel, since finishing the handshake requires a bunch of
293/// CPU, and you might want to do it as a separate task or after a yield.
294///
295/// Both relay and client have specialized objects for an unverified channel which include this one
296/// as the base in order to share functionalities.
297pub(crate) struct VerifiedChannel<
298    T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
299    S: CoarseTimeProvider + SleepProvider,
300> {
301    /// Runtime handle (insofar as we need it)
302    pub(crate) sleep_prov: S,
303    /// Memory quota account
304    pub(crate) memquota: ChannelAccount,
305    /// The negotiated link protocol.
306    pub(crate) link_protocol: u16,
307    /// The Source+Sink on which we're reading and writing cells.
308    pub(crate) framed_tls: ChannelFrame<T>,
309    /// Declared target method for this stream, if any.
310    pub(crate) target_method: Option<ChannelMethod>,
311    /// Logging identifier for this stream.  (Used for logging only.)
312    pub(crate) unique_id: UniqId,
313    /// Authenticated clock skew for this peer.
314    pub(crate) clock_skew: ClockSkew,
315
316    /// Verified peer identities
317    pub(crate) peer_relay_ids: RelayIds,
318    /// Validated RSA identity digest of the DER format for this peer.
319    pub(crate) peer_rsa_id_digest: [u8; 32],
320}
321
322impl<
323    T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
324    S: CoarseTimeProvider + SleepProvider,
325> UnverifiedChannel<T, S>
326{
327    /// Return a newly constructed [`VerifiedChannel`].
328    pub(crate) fn into_verified(
329        self,
330        peer_relay_ids: RelayIds,
331        peer_rsa_id_digest: [u8; 32],
332    ) -> VerifiedChannel<T, S> {
333        VerifiedChannel {
334            link_protocol: self.link_protocol,
335            framed_tls: self.framed_tls,
336            unique_id: self.unique_id,
337            target_method: self.target_method,
338            peer_relay_ids,
339            peer_rsa_id_digest,
340            clock_skew: self.clock_skew,
341            sleep_prov: self.sleep_prov,
342            memquota: self.memquota,
343        }
344    }
345
346    /// This validates the relay identities (Ed25519 and RSA) and signing key cert (Ed25519) found
347    /// in the received [`msg::Certs`] cell. It also enforces that the peer claimed IDs are the one
348    /// we expected (`peer_target`).
349    ///
350    /// Successful validation returns the relay ed25519 identitiy key, the ed25519 signing key and
351    /// the RSA public key of the peer. This means that we consider the peer verified as in we've
352    /// established that we are talking to the right target.
353    ///
354    /// Reason for the RSA public key is because the caller needs the SHA256 digest for the
355    /// [`msg::Authenticate`] cell.
356    pub(crate) fn check_relay_identities<U: ChanTarget + ?Sized>(
357        &self,
358        peer_target: &U,
359        peer_certs: &msg::Certs,
360        now: SystemTime,
361    ) -> Result<(RelayIds, Ed25519Identity, [u8; 32])> {
362        use tor_checkable::*;
363
364        // Get the identity signing cert IDENTITY_V_SIGNING.
365        let cert_signing = get_cert(peer_certs, CertType::IDENTITY_V_SIGNING)?;
366
367        // Check the identity->signing cert
368        let (cert_signing, cert_signing_sig) = cert_signing
369            .should_have_signing_key()
370            .map_err(Error::HandshakeCertErr)?
371            .dangerously_split()
372            .map_err(Error::HandshakeCertErr)?;
373        let (cert_signing_timeliness, cert_signing) =
374            check_cert_timeliness(cert_signing, now, self.clock_skew);
375
376        // Make sure the ed25519 identity cert is well signed before parsing more data.
377        if !cert_signing_sig.is_valid() {
378            return Err(Error::HandshakeProto(
379                "Invalid ed25519 identity cert signature in handshake".into(),
380            ));
381        }
382
383        // Take the identity key from the identity->signing cert
384        let kp_relayid_ed = cert_signing.signing_key().ok_or_else(|| {
385            Error::HandshakeProto("Missing identity key in identity->signing cert".into())
386        })?;
387
388        // Take the signing key from the identity->signing cert
389        let kp_relaysign_ed = cert_signing.subject_key().as_ed25519().ok_or_else(|| {
390            Error::HandshakeProto("Bad key type in identity->signing cert".into())
391        })?;
392
393        // What is the RSA identity key, according to the X.509 certificate
394        // in which it is self-signed?
395        //
396        // (We don't actually check this self-signed certificate, and we use
397        // a kludge to extract the RSA key)
398        let rsa_id_cert_bytes = peer_certs
399            .cert_body(CertType::RSA_ID_X509)
400            .ok_or_else(|| Error::HandshakeProto("Couldn't find RSA identity cert".into()))?;
401        let kp_relayid_rsa = ll::util::x509_extract_rsa_subject_kludge(rsa_id_cert_bytes)
402            .ok_or_else(|| {
403                Error::HandshakeProto(
404                    "Couldn't find RSA SubjectPublicKey from RSA identity cert".into(),
405                )
406            })?;
407
408        // Now verify the RSA identity -> Ed Identity crosscert.
409        //
410        // This proves that the RSA key vouches for the Ed key.  Note that
411        // the Ed key does not vouch for the RSA key: The RSA key is too
412        // weak.
413        let rsa_cert = peer_certs
414            .cert_body(CertType::RSA_ID_V_IDENTITY)
415            .ok_or_else(|| Error::HandshakeProto("No RSA->Ed crosscert".into()))?;
416        let rsa_cert = tor_cert::rsa::RsaCrosscert::decode(rsa_cert)
417            .map_err(|e| Error::from_bytes_err(e, "RSA identity cross-certificate"))?
418            .check_signature(&kp_relayid_rsa)
419            .map_err(|_| Error::HandshakeProto("Bad RSA->Ed crosscert signature".into()))?;
420        let (rsa_cert_timeliness, rsa_cert) = check_cert_timeliness(rsa_cert, now, self.clock_skew);
421
422        if !rsa_cert.subject_key_matches(kp_relayid_ed) {
423            return Err(Error::HandshakeProto(
424                "RSA->Ed crosscert certifies incorrect key".into(),
425            ));
426        }
427
428        // The only remaining concern is certificate timeliness.  If the
429        // certificates are expired by an amount that is too large for the
430        // declared clock skew to explain, then  we'll return
431        // `Error::HandshakeProto`: in that case the clock skew is _not_
432        // authenticated.  But if the certs are only expired by a little bit,
433        // we'll reject the handshake with `Error::HandshakeCertsExpired`, and
434        // the caller can trust the clock skew.
435        //
436        // We note expired certs last, since we only want to return
437        // `HandshakeCertsExpired` when there are no other errors.
438        cert_signing_timeliness?;
439        rsa_cert_timeliness?;
440
441        // Now that we've done all the verification steps on the
442        // certificates, we know who we are talking to.  It's time to
443        // make sure that the peer we are talking to is the peer we
444        // actually wanted.
445        //
446        // We do this _last_, since "this is the wrong peer" is
447        // usually a different situation than "this peer couldn't even
448        // identify itself right."
449        let actual_identity = RelayIds::builder()
450            .ed_identity(*kp_relayid_ed)
451            .rsa_identity(kp_relayid_rsa.to_rsa_identity())
452            .build()
453            .expect("Unable to build RelayIds");
454
455        // We enforce that the relay claimed to have every ID that we wanted:
456        // it may also have additional IDs that we didn't ask for.
457        match super::check_id_match_helper(&actual_identity, peer_target) {
458            Err(Error::ChanMismatch(msg)) => Err(Error::HandshakeProto(msg)),
459            other => other,
460        }?;
461
462        let rsa_id_digest: [u8; 32] = ll::d::Sha256::digest(kp_relayid_rsa.to_der()).into();
463
464        Ok((actual_identity, *kp_relaysign_ed, rsa_id_digest))
465    }
466
467    /// Finalize this channel into an actual channel and its reactor.
468    ///
469    /// An unverified channel can be finalized as it skipped the cert verification and
470    /// authentication because simply the other side is not authenticating.
471    ///
472    /// Two cases for this:
473    ///     - Client <-> Relay channel
474    ///     - Bridge <-> Relay channel
475    ///
476    /// `peer_netinfo` is the received [`msg::Netinfo`] cell from the peer.
477    ///
478    /// `my_addrs` are our advertised addresses as a relay.
479    ///
480    /// `peer_info` is the verified peer information (identities and addresses).
481    ///
482    // NOTE: Unfortunately, this function has duplicated code with the VerifiedChannel::finish()
483    // so make sure any changes here is reflected there. A proper refactoring is welcome!
484    #[instrument(skip_all, level = "trace")]
485    pub(crate) fn finish(
486        mut self,
487        peer_netinfo: &msg::Netinfo,
488        my_addrs: &[IpAddr],
489        peer_info: MaybeSensitive<PeerInfo>,
490        channel_mode: ChannelMode,
491    ) -> Result<(Arc<super::Channel>, super::reactor::Reactor<S>)>
492    where
493        S: Runtime,
494    {
495        // We treat a completed channel as incoming traffic since all cells were exchanged.
496        //
497        // TODO: conceivably we should remember the time when we _got_ the
498        // final cell on the handshake, and update the channel completion
499        // time to be no earlier than _that_ timestamp.
500        //
501        // TODO: This shouldn't be here. This should be called in the trait functions that actually
502        // receives the data (recv_*). We'll move it at a later commit.
503        crate::note_incoming_traffic();
504
505        // We have finalized the handshake, move our codec to Open.
506        self.framed_tls.codec_mut().set_open()?;
507
508        // Grab the channel type from our underlying frame as we are about to consume the
509        // framed_tls.
510        // Do a sanity check that the provided channel mode agrees with the type.
511        let channel_type = self.framed_tls.codec().channel_type();
512        channel_mode.check_agrees_with_type(channel_type)?;
513
514        // Grab a new handle on which we can apply StreamOps (needed for KIST).
515        // On Unix platforms, this handle is a wrapper over the fd of the socket.
516        //
517        // Note: this is necessary because after `StreamExit::split()`,
518        // we no longer have access to the underlying stream
519        // or its StreamOps implementation.
520        let stream_ops = self.framed_tls.new_handle();
521        let (tls_sink, tls_stream) = self.framed_tls.split();
522
523        let canonicity =
524            Canonicity::from_netinfo(peer_netinfo, my_addrs, peer_info.addr().netinfo_addr());
525
526        // We need this because the Channel still uses a `OwnedChanTarget` in a lot of places but
527        // the real verified truth about our connected peer is in `PeerInfo`.
528        let peer_target = build_filtered_chan_target(self.target_method.take(), &peer_info);
529
530        debug!(
531            stream_id = %self.unique_id,
532            "Completed handshake without authentication to {}", Redacted::new(&peer_target)
533        );
534
535        super::Channel::new(
536            channel_mode,
537            self.link_protocol,
538            Box::new(tls_sink),
539            Box::new(tls_stream),
540            stream_ops,
541            self.unique_id,
542            peer_target,
543            peer_info,
544            self.clock_skew,
545            self.sleep_prov,
546            self.memquota,
547            canonicity,
548        )
549    }
550}
551
552impl<
553    T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
554    S: CoarseTimeProvider + SleepProvider,
555> VerifiedChannel<T, S>
556{
557    /// Mark this channel as authenticated.
558    pub(crate) fn set_authenticated(&mut self) -> Result<()> {
559        self.framed_tls.codec_mut().set_authenticated()?;
560        Ok(())
561    }
562
563    /// Return our [`RelayIds`] corresponding to this channel identities.
564    pub(crate) fn relay_ids(&self) -> &RelayIds {
565        &self.peer_relay_ids
566    }
567
568    /// Finalize this channel into an actual channel and its reactor.
569    ///
570    /// `peer_netinfo` is the received [`msg::Netinfo`] cell from the peer.
571    ///
572    /// `my_addrs` are our advertised addresses as a relay.
573    ///
574    /// `peer_info` is the verified peer information (identities and addresses).
575    ///
576    // NOTE: Unfortunately, this function has duplicated code with the VerifiedChannel::finish()
577    // so make sure any changes here is reflected there. A proper refactoring is welcome!
578    #[instrument(skip_all, level = "trace")]
579    pub(crate) async fn finish(
580        mut self,
581        peer_netinfo: &msg::Netinfo,
582        my_addrs: &[IpAddr],
583        peer_info: MaybeSensitive<PeerInfo>,
584        channel_mode: ChannelMode,
585    ) -> Result<(Arc<super::Channel>, super::reactor::Reactor<S>)>
586    where
587        S: Runtime,
588    {
589        // We treat a completed channel -- that is to say, one where the
590        // authentication is finished -- as incoming traffic.
591        //
592        // TODO: conceivably we should remember the time when we _got_ the
593        // final cell on the handshake, and update the channel completion
594        // time to be no earlier than _that_ timestamp.
595        //
596        // TODO: This shouldn't be here. This should be called in the trait functions that actually
597        // receives the data (recv_*). We'll move it at a later commit.
598        crate::note_incoming_traffic();
599
600        // We have finalized the handshake, move our codec to Open.
601        self.framed_tls.codec_mut().set_open()?;
602
603        // Grab the channel type from our underlying frame as we are about to consume the
604        // framed_tls.
605        // Do a sanity check that the provided channel mode agrees with the type.
606        let channel_type = self.framed_tls.codec().channel_type();
607        channel_mode.check_agrees_with_type(channel_type)?;
608
609        debug!(
610            stream_id = %self.unique_id,
611            "Completed handshake with peer: {}", peer_info
612        );
613
614        // Grab a new handle on which we can apply StreamOps (needed for KIST).
615        // On Unix platforms, this handle is a wrapper over the fd of the socket.
616        //
617        // Note: this is necessary because after `StreamExit::split()`,
618        // we no longer have access to the underlying stream
619        // or its StreamOps implementation.
620        let stream_ops = self.framed_tls.new_handle();
621        let (tls_sink, tls_stream) = self.framed_tls.split();
622
623        let canonicity =
624            Canonicity::from_netinfo(peer_netinfo, my_addrs, peer_info.addr().netinfo_addr());
625
626        let peer_target = build_filtered_chan_target(self.target_method.take(), &peer_info);
627
628        super::Channel::new(
629            channel_mode,
630            self.link_protocol,
631            Box::new(tls_sink),
632            Box::new(tls_stream),
633            stream_ops,
634            self.unique_id,
635            peer_target,
636            peer_info,
637            self.clock_skew,
638            self.sleep_prov,
639            self.memquota,
640            canonicity,
641        )
642    }
643}
644
645impl<
646    T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
647    S: CoarseTimeProvider + SleepProvider,
648> UnverifiedInitiatorChannel<T, S>
649{
650    /// Validate all relay identities and TLS cert SIGNING_V_TLS_CERT located in the received
651    /// `certs_cell`.
652    ///
653    /// `peer_target` is the relay we want to connect to.
654    ///
655    /// 'peer_cert_digest' is the digest of the x.509 certificate that the peer presented during
656    /// its TLS handshake (ServerHello).
657    ///
658    /// 'now' is the time at which to check that certificates are valid.  `None` means to use the
659    /// current time. It can be used for testing to override the current view of the time.
660    pub(crate) fn verify<U: ChanTarget + ?Sized>(
661        self,
662        peer_target: &U,
663        peer_cert_digest: [u8; 32],
664        now: Option<std::time::SystemTime>,
665    ) -> Result<VerifiedChannel<T, S>> {
666        use tor_cert::CertType;
667
668        // Replace 'now' with the real time to use.
669        let now = now.unwrap_or_else(SystemTime::get);
670
671        // We are a client initiating a channel to a relay or a bridge. We have received a CERTS
672        // cell and we need to verify these certs:
673        //
674        //   Relay Identities:
675        //      IDENTITY_V_SIGNING_CERT (CertType 4)
676        //      RSA_ID_X509             (CertType 2)
677        //      RSA_ID_V_IDENTITY       (CertType 7)
678        //
679        //   Connection Cert:
680        //      SIGNING_V_TLS_CERT      (CertType 5)
681        //
682        // Validating the relay identities first so we can make sure we are talking to the relay
683        // (peer) we wanted. Then, check the TLS cert validity.
684        //
685        // The end result is a verified channel (not authenticated yet) which guarantee that we are
686        // talking to the right relay that we wanted. We validate so we can prove these:
687        //
688        // - IDENTITY_V_SIGNING proves that KP_relaysign_ed speaks on behalf of KP_relayid_ed
689        // - SIGNING_V_TLS_CERT proves that the peer's TLS cert public key speaks on behalf of
690        //   KP_relaysign_ed.
691        // - The TLS handshake proved that the channel is authenticated by the peer's TLS public key.
692        // - Therefore, we have a chain from:
693        //   KS_relayid_ed → KP_relaysign_ed → subject key in TLS cert → the channel itself.
694        //
695        // As for legacy certs, they prove nothing but we can extract keys:
696        //
697        // - RSA_ID_X509 proves nothing; we just extract its subject key as KP_relayid_rsa.
698        // - RSA_ID_V_IDENTITY proves that KP_relayid_ed speaks on behalf of KP_relayid_rsa.
699        // - Therefore we have a chain from:
700        //   KP_relayid_rsa → KS_relayid_ed → KP_relaysign_ed → subject key in TLS cert → channel.
701
702        // Check the relay identities in the CERTS cell.
703        let (peer_relay_ids, peer_kp_relaysign_ed, peer_rsa_id_digest) = self
704            .inner
705            .check_relay_identities(peer_target, &self.certs_cell, now)?;
706
707        // Now look at the signing->TLS cert and check it against the
708        // peer certificate.
709        let cert_tls = get_cert(&self.certs_cell, CertType::SIGNING_V_TLS_CERT)?;
710        let (cert_tls, cert_tls_sig) = cert_tls
711            .should_be_signed_with(&peer_kp_relaysign_ed)
712            .map_err(Error::HandshakeCertErr)?
713            .dangerously_split()
714            .map_err(Error::HandshakeCertErr)?;
715        let (cert_tls_timeliness, cert_tls) =
716            check_cert_timeliness(cert_tls, now, self.inner.clock_skew);
717
718        if peer_cert_digest != cert_tls.subject_key().as_bytes() {
719            return Err(Error::HandshakeProto(
720                "Peer cert did not authenticate TLS cert".into(),
721            ));
722        }
723
724        // Make sure the TLS cert is well signed.
725        if !cert_tls_sig.is_valid() {
726            return Err(Error::HandshakeProto(
727                "Invalid ed25519 TLS cert signature in handshake".into(),
728            ));
729        }
730
731        // Check TLS cert timeliness.
732        cert_tls_timeliness?;
733
734        Ok(self.inner.into_verified(peer_relay_ids, peer_rsa_id_digest))
735    }
736}
737
738/// Validate the LINK_AUTH cert (CertType 6).
739///
740/// `certs` is the [`msg::Certs`] cell received during the handshake.
741///
742/// `kp_relaysign_ed` is the relay signing ed25519 key taken from the signing cert
743/// IDENTITY_V_SIGNING. It is used to sign the LINK_AUTH cert.
744///
745/// 'now' is the time at which to check that certificates are valid.  `None` means to use the
746/// current time. It can be used for testing to override the current view of the time.
747///
748/// The `clock_skew` is the time skew detected during the handshake.
749///
750/// If verification is successful, return the peer KP_link_ed.
751pub(crate) fn verify_link_auth_cert(
752    certs: &msg::Certs,
753    kp_relaysign_ed: &Ed25519Identity,
754    now: Option<std::time::SystemTime>,
755    clock_skew: ClockSkew,
756) -> Result<Ed25519Identity> {
757    use tor_cert::CertType;
758
759    // Replace 'now' with the real time to use.
760    let now = now.unwrap_or_else(SystemTime::get);
761
762    // Now look at the signing->TLS cert and check it against the
763    // peer certificate.
764    let cert = get_cert(certs, CertType::SIGNING_V_LINK_AUTH)?;
765    let (cert, cert_sig) = cert
766        .should_be_signed_with(kp_relaysign_ed)
767        .map_err(Error::HandshakeCertErr)?
768        .dangerously_split()
769        .map_err(Error::HandshakeCertErr)?;
770    let (cert_timeliness, cert) = check_cert_timeliness(cert, now, clock_skew);
771
772    // Make sure the cert is well signed.
773    if cert_sig.is_valid() {
774        return Err(Error::HandshakeProto(
775            "Invalid ed25519 LINK_AUTH signature in handshake".into(),
776        ));
777    }
778
779    // Check TLS cert timeliness.
780    cert_timeliness?;
781
782    // We are all verified, extract the subject key and return it.
783    let peer_kp_link_ed = *cert
784        .subject_key()
785        .as_ed25519()
786        .ok_or(Error::HandshakeProto(
787            "Missing kp_link_ed in LINK_AUTH cert subject key".into(),
788        ))?;
789
790    Ok(peer_kp_link_ed)
791}
792
793/// Helper: given a time-bound input, give a result reflecting its
794/// validity at `now`, and the inner object.
795///
796/// We use this here because we want to validate the whole handshake
797/// regardless of whether the certs are expired, so we can determine
798/// whether we got a plausible handshake with a skewed partner, or
799/// whether the handshake is definitely bad.
800pub(crate) fn check_cert_timeliness<C, CERT>(
801    checkable: C,
802    now: SystemTime,
803    clock_skew: ClockSkew,
804) -> (Result<()>, CERT)
805where
806    C: Timebound<CERT, Error = TimeValidityError>,
807{
808    let status = checkable
809        .is_valid_at(&now)
810        .map_err(|e| match (e, clock_skew) {
811            (TimeValidityError::Expired(expired_by), ClockSkew::Fast(skew))
812                if expired_by < skew =>
813            {
814                Error::HandshakeCertsExpired { expired_by }
815            }
816            // As it so happens, we don't need to check for this case, since the certs in use
817            // here only have an expiration time in them.
818            // (TimeValidityError::NotYetValid(_), ClockSkew::Slow(_)) => todo!(),
819            (_, _) => Error::HandshakeProto("Certificate expired or not yet valid".into()),
820        });
821    let cert = checkable.dangerously_assume_timely();
822    (status, cert)
823}
824
825/// Helper: get a cert from our Certs cell, and convert errors appropriately.
826pub(crate) fn get_cert(certs: &msg::Certs, tp: CertType) -> Result<tor_cert::KeyUnknownCert> {
827    match certs.parse_ed_cert(tp) {
828        Ok(c) => Ok(c),
829        Err(tor_cell::Error::ChanProto(e)) => Err(Error::HandshakeProto(e)),
830        Err(e) => Err(Error::HandshakeProto(e.to_string())),
831    }
832}
833
834/// Helper: Calculate a clock skew from the [msg::Netinfo] cell data and the time at which we sent
835/// the [msg::Versions] cell.
836///
837/// This is unauthenticated as in not validated with the certificates. Before using it, make sure
838/// that you have authenticated the other party.
839pub(crate) fn unauthenticated_clock_skew(
840    netinfo_cell: &msg::Netinfo,
841    netinfo_rcvd_at: coarsetime::Instant,
842    versions_flushed_at: coarsetime::Instant,
843    versions_flushed_wallclock: SystemTime,
844) -> ClockSkew {
845    // Try to compute our clock skew.  It won't be authenticated yet, since we haven't checked
846    // the certificates.
847    if let Some(netinfo_timestamp) = netinfo_cell.timestamp() {
848        let delay = netinfo_rcvd_at - versions_flushed_at;
849        ClockSkew::from_handshake_timestamps(
850            versions_flushed_wallclock,
851            netinfo_timestamp,
852            delay.into(),
853        )
854    } else {
855        ClockSkew::None
856    }
857}
858
859/// Helper: Build a OwnedChanTarget that retains only the address that was actually used.
860fn build_filtered_chan_target(
861    target_method: Option<ChannelMethod>,
862    peer_info: &MaybeSensitive<PeerInfo>,
863) -> OwnedChanTarget {
864    let mut peer_builder = OwnedChanTargetBuilder::default();
865    if let Some(mut method) = target_method {
866        // Retain only the address that was actually used to connect.
867        if let Some(addr) = peer_info.addr().socket_addr() {
868            let _ = method.retain_addrs(|socket_addr| socket_addr == &addr);
869            peer_builder.addrs(vec![addr]);
870        }
871        peer_builder.method(method);
872    }
873    *peer_builder.ids() = RelayIdsBuilder::from_relay_ids(peer_info.ids());
874
875    peer_builder
876        .build()
877        .expect("OwnedChanTarget builder failed")
878}
879
880/// Read a message from the stream.
881///
882/// The `expecting` parameter is used for logging purposes, not filtering.
883pub(crate) async fn read_msg<T>(
884    stream_id: UniqId,
885    mut stream: impl Stream<Item = Result<AnyChanCell>> + Unpin,
886) -> Result<T>
887where
888    T: RestrictedMsg + TryFrom<AnyChanMsg, Error = AnyChanMsg>,
889{
890    let Some(cell) = stream.next().await.transpose()? else {
891        // The entire channel has ended, so nothing else to be done.
892        return Err(Error::HandshakeProto("Stream ended unexpectedly".into()));
893    };
894
895    let (id, m) = cell.into_circid_and_msg();
896    trace!(%stream_id, "received a {} cell", m.cmd());
897
898    // TODO: Maybe also check this in the channel handshake codec?
899    if let Some(id) = id {
900        return Err(Error::HandshakeProto(format!(
901            "Expected no circ ID for {} cell, but received circ ID of {id} instead",
902            m.cmd(),
903        )));
904    }
905
906    let m = m.try_into().map_err(|m: AnyChanMsg| {
907        Error::HandshakeProto(format!(
908            "Expected [{}] cell, but received {} cell instead",
909            tor_basic_utils::iter_join(", ", T::cmds_for_logging().iter()),
910            m.cmd(),
911        ))
912    })?;
913
914    Ok(m)
915}
916
917#[cfg(test)]
918pub(crate) mod test {
919    #![allow(clippy::unwrap_used)]
920    use hex_literal::hex;
921    use regex::Regex;
922    use std::future::Future;
923    use std::net::IpAddr;
924    use std::pin::Pin;
925    use std::time::{Duration, SystemTime};
926    use tor_llcrypto::pk::rsa::RsaIdentity;
927
928    use super::*;
929    use crate::channel::ClientInitiatorHandshake;
930    use crate::channel::handler::test::MsgBuf;
931    use crate::channel::{ChannelType, new_frame};
932    use crate::util::fake_mq;
933    use crate::{Error, Result};
934    use tor_cell::chancell::msg;
935    use tor_linkspec::OwnedChanTargetBuilder;
936    use tor_rtcompat::{PreferredRuntime, Runtime};
937
938    #[cfg(feature = "relay")]
939    use {
940        crate::relay::channel::handshake::RelayInitiatorHandshake,
941        crate::relay::channel::test::{RelayMsgBuf, fake_auth_material},
942        tor_basic_utils::test_rng::{TestingRng, testing_rng},
943        tor_llcrypto::rng::FakeEntropicRng,
944    };
945
946    pub(crate) const VERSIONS: &[u8] = &hex!("0000 07 0006 0003 0004 0005");
947    // no certificates in this cell, but connect() doesn't care.
948    pub(crate) const NOCERTS: &[u8] = &hex!("00000000 81 0001 00");
949    pub(crate) const NETINFO_PREFIX: &[u8] = &hex!(
950        "00000000 08 00000000
951         04 04 7f 00 00 02
952         01
953         04 04 7f 00 00 03"
954    );
955    pub(crate) const NETINFO_PREFIX_WITH_TIME: &[u8] = &hex!(
956        "00000000 08 48949290
957         04 04 7f 00 00 02
958         01
959         04 04 7f 00 00 03"
960    );
961    pub(crate) const AUTHCHALLENGE: &[u8] = &hex!(
962        "00000000 82 0026
963         FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
964         FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
965         0002 0003 00ff"
966    );
967
968    pub(crate) const VPADDING: &[u8] = &hex!("00000000 80 0003 FF FF FF");
969
970    /// Append `cell` to `buf`, zero-padded to a full 514-byte fixed-length cell.
971    pub(crate) fn add_padded(buf: &mut Vec<u8>, cell: &[u8]) {
972        let len_prev = buf.len();
973        buf.extend_from_slice(cell);
974        buf.resize(len_prev + 514, 0);
975    }
976
977    /// Append a minimal NETINFO cell to `buf`.
978    pub(crate) fn add_netinfo(buf: &mut Vec<u8>) {
979        add_padded(buf, NETINFO_PREFIX);
980    }
981
982    /// This module has a few certificates to play with. They're taken
983    /// from a chutney network. They match those used in the CERTS
984    /// cell test vector in the tor-cell crate.
985    ///
986    /// The names are taken from the type of the certificate.
987    pub(crate) mod certs {
988        use hex_literal::hex;
989
990        pub(crate) const CERT_T2: &[u8] = &hex!(
991            "308201B930820122A0030201020208607C28BE6C390943300D06092A864886F70D01010B0500301F311D301B06035504030C147777772E74636A76356B766A646472322E636F6D301E170D3230303831303030303030305A170D3231303831303030303030305A301F311D301B06035504030C147777772E74636A76356B766A646472322E636F6D30819F300D06092A864886F70D010101050003818D0030818902818100D38B1E6CEB946E0DB0751F4CBACE3DCB9688B6C25304227B4710C35AFB73627E50500F5913E158B621802612D1C75827003703338375237552EB3CD3C12F6AB3604E60C1A2D26BB1FBAD206FF023969A90909D6A65A5458A5312C26EBD3A3DAD30302D4515CDCD264146AC18E6FC60A04BD3EC327F04294D96BA5AA25B464C3F0203010001300D06092A864886F70D01010B0500038181003BCE561EA7F95CC00B78AAB5D69573FF301C282A751D4A651921D042F1BECDBA24D918A6D8A5E138DC07BBA0B335478AE37ABD2C93A93932442AE9084329E846170FE0FC4A50AAFC804F311CC3CA4F41D845A7BA5901CBBC3E021E9794AAC70CE1F37B0A951592DB1B64F2B4AFB81AE52DBD9B6FEDE96A5FB8125EB6251EE50A"
992        );
993
994        pub(crate) const CERT_T4: &[u8] = &hex!(
995            "01040006CC2A01F82294B866A31F01FC5D0DA8572850A9B929545C3266558D7D2316E3B74172B00100200400DCB604DB2034B00FD16986D4ADB9D16B21CB4E4457A33DEC0F538903683E96E9FF1A5203FA27F86EF7528D89A0845D2520166E340754FFEA2AAE0F612B7CE5DA094A0236CDAC45034B0B6842C18E7F6B51B93A3CF7E60663B8AD061C30A62602"
996        );
997        pub(crate) const CERT_T5: &[u8] = &hex!(
998            "01050006C98A03B4FD606B64E4CBD466B8D76CB131069BAE6F3AA1878857C9F624E31D77A799B8007173E5F8068431D0D3F5EE16B4C9FFD59DF373E152A87281BAE744AA5FCF72171BF4B27C4E8FC1C6A9FC5CA11058BC49647063D7903CFD9F512F89099B27BC0C"
999        );
1000
1001        pub(crate) const CERT_T7: &[u8] = &hex!(
1002            "DCB604DB2034B00FD16986D4ADB9D16B21CB4E4457A33DEC0F538903683E96E90006DA3A805CF6006F9179066534DE6B45AD47A5C469063EE462762723396DC9F25452A0A52DA3F5087DD239F2A311F6B0D4DFEFF4ABD089DC3D0237A0ABAB19EB2045B91CDCAF04BE0A72D548A27BF2E77BD876ECFE5E1BE622350DA6BF31F6E306ED896488DD5B39409B23FC3EB7B2C9F7328EB18DA36D54D80575899EA6507CCBFCDF1F"
1003        );
1004
1005        pub(crate) const PEER_CERT_DIGEST: &[u8; 32] =
1006            &hex!("b4fd606b64e4cbd466b8d76cb131069bae6f3aa1878857c9f624e31d77a799b8");
1007
1008        pub(crate) const PEER_ED: &[u8] =
1009            &hex!("dcb604db2034b00fd16986d4adb9d16b21cb4e4457a33dec0f538903683e96e9");
1010        pub(crate) const PEER_RSA: &[u8] = &hex!("2f1fb49bb332a9eec617e41e911c33fb3890aef3");
1011    }
1012
1013    fn make_unverified<R>(runtime: R) -> UnverifiedChannel<MsgBuf, R>
1014    where
1015        R: Runtime,
1016    {
1017        let mut framed_tls = new_frame(MsgBuf::new(&b""[..]), ChannelType::ClientInitiator);
1018        let _ = framed_tls.codec_mut().set_link_version(4);
1019        let _ = framed_tls.codec_mut().set_open();
1020        let clock_skew = ClockSkew::None;
1021        UnverifiedChannel {
1022            link_protocol: 4,
1023            framed_tls,
1024            clock_skew,
1025            target_method: None,
1026            unique_id: UniqId::new(),
1027            sleep_prov: runtime,
1028            memquota: fake_mq(),
1029        }
1030    }
1031
1032    // Timestamp when the example certificates were all valid.
1033    fn cert_timestamp() -> SystemTime {
1034        use humantime::parse_rfc3339;
1035        parse_rfc3339("2020-09-26T18:01:20Z").unwrap()
1036    }
1037
1038    fn certs_test<R>(
1039        certs: msg::Certs,
1040        when: Option<SystemTime>,
1041        peer_ed: &[u8],
1042        peer_rsa: &[u8],
1043        peer_cert_sha256: [u8; 32],
1044        runtime: &R,
1045    ) -> Result<VerifiedChannel<MsgBuf, R>>
1046    where
1047        R: Runtime,
1048    {
1049        let relay_ids = RelayIdsBuilder::default()
1050            .ed_identity(Ed25519Identity::from_bytes(peer_ed).unwrap())
1051            .rsa_identity(RsaIdentity::from_bytes(peer_rsa).unwrap())
1052            .build()
1053            .unwrap();
1054        let mut peer_builder = OwnedChanTargetBuilder::default();
1055        *peer_builder.ids() = RelayIdsBuilder::from_relay_ids(&relay_ids);
1056        let peer = peer_builder.build().unwrap();
1057
1058        let unverified = UnverifiedInitiatorChannel {
1059            inner: make_unverified(runtime.clone()),
1060            certs_cell: certs,
1061        };
1062        unverified.verify(&peer, peer_cert_sha256, when)
1063    }
1064
1065    // no certs at all!
1066    #[test]
1067    fn certs_none() {
1068        let rt = PreferredRuntime::create().unwrap();
1069        let err = certs_test(
1070            msg::Certs::new_empty(),
1071            None,
1072            &[0_u8; 32],
1073            &[0_u8; 20],
1074            [0_u8; 32],
1075            &rt,
1076        )
1077        .err()
1078        .unwrap();
1079        assert_eq!(
1080            format!("{}", err),
1081            "Handshake protocol violation: Missing IDENTITY_V_SIGNING certificate"
1082        );
1083    }
1084
1085    #[test]
1086    fn certs_good() {
1087        let rt = PreferredRuntime::create().unwrap();
1088        let mut certs = msg::Certs::new_empty();
1089
1090        certs.push_cert_body(2.into(), certs::CERT_T2);
1091        certs.push_cert_body(5.into(), certs::CERT_T5);
1092        certs.push_cert_body(7.into(), certs::CERT_T7);
1093        certs.push_cert_body(4.into(), certs::CERT_T4);
1094        let res = certs_test(
1095            certs,
1096            Some(cert_timestamp()),
1097            certs::PEER_ED,
1098            certs::PEER_RSA,
1099            *certs::PEER_CERT_DIGEST,
1100            &rt,
1101        );
1102        let _ = res.unwrap();
1103    }
1104
1105    #[test]
1106    fn certs_missing() {
1107        let rt = PreferredRuntime::create().unwrap();
1108        let all_certs = [
1109            (2, certs::CERT_T2, "Couldn't find RSA identity cert"),
1110            (7, certs::CERT_T7, "No RSA->Ed crosscert"),
1111            (4, certs::CERT_T4, "Missing IDENTITY_V_SIGNING certificate"),
1112            (5, certs::CERT_T5, "Missing SIGNING_V_TLS_CERT certificate"),
1113        ];
1114
1115        for omit_idx in 0..4 {
1116            // build a certs cell with all but one certificate
1117            let mut certs = msg::Certs::new_empty();
1118            let mut expect_err = None;
1119            for (idx, (ctype, cert, err)) in all_certs.iter().enumerate() {
1120                if idx == omit_idx {
1121                    expect_err = Some(err);
1122                    continue;
1123                }
1124
1125                certs.push_cert_body((*ctype).into(), &cert[..]);
1126            }
1127            let res = certs_test(
1128                certs,
1129                Some(cert_timestamp()),
1130                certs::PEER_ED,
1131                certs::PEER_RSA,
1132                *certs::PEER_CERT_DIGEST,
1133                &rt,
1134            )
1135            .err()
1136            .unwrap();
1137
1138            assert_eq!(
1139                format!("{}", res),
1140                format!("Handshake protocol violation: {}", expect_err.unwrap())
1141            );
1142        }
1143    }
1144
1145    #[test]
1146    fn certs_wrongtarget() {
1147        let rt = PreferredRuntime::create().unwrap();
1148        let mut certs = msg::Certs::new_empty();
1149        certs.push_cert_body(2.into(), certs::CERT_T2);
1150        certs.push_cert_body(5.into(), certs::CERT_T5);
1151        certs.push_cert_body(7.into(), certs::CERT_T7);
1152        certs.push_cert_body(4.into(), certs::CERT_T4);
1153        let err = certs_test(
1154            certs.clone(),
1155            Some(cert_timestamp()),
1156            &[0x10; 32],
1157            certs::PEER_RSA,
1158            *certs::PEER_CERT_DIGEST,
1159            &rt,
1160        )
1161        .err()
1162        .unwrap();
1163
1164        let re = Regex::new(
1165            // identities might be scrubbed by safelog
1166            r"Identity .* does not match target .*",
1167        )
1168        .unwrap();
1169        assert!(re.is_match(&format!("{}", err)));
1170
1171        let err = certs_test(
1172            certs.clone(),
1173            Some(cert_timestamp()),
1174            certs::PEER_ED,
1175            &[0x99; 20],
1176            *certs::PEER_CERT_DIGEST,
1177            &rt,
1178        )
1179        .err()
1180        .unwrap();
1181
1182        let re = Regex::new(
1183            // identities might be scrubbed by safelog
1184            r"Identity .* does not match target .*",
1185        )
1186        .unwrap();
1187        assert!(re.is_match(&format!("{}", err)));
1188
1189        let err = certs_test(
1190            certs,
1191            Some(cert_timestamp()),
1192            certs::PEER_ED,
1193            certs::PEER_RSA,
1194            [0; 32],
1195            &rt,
1196        )
1197        .err()
1198        .unwrap();
1199
1200        assert_eq!(
1201            format!("{}", err),
1202            "Handshake protocol violation: Peer cert did not authenticate TLS cert"
1203        );
1204    }
1205
1206    #[test]
1207    fn certs_badsig() {
1208        let rt = PreferredRuntime::create().unwrap();
1209        fn munge(inp: &[u8]) -> Vec<u8> {
1210            let mut v: Vec<u8> = inp.into();
1211            v[inp.len() - 1] ^= 0x10;
1212            v
1213        }
1214        let mut certs = msg::Certs::new_empty();
1215        certs.push_cert_body(2.into(), certs::CERT_T2);
1216        certs.push_cert_body(5.into(), munge(certs::CERT_T5)); // munge an ed signature
1217        certs.push_cert_body(7.into(), certs::CERT_T7);
1218        certs.push_cert_body(4.into(), certs::CERT_T4);
1219        let res = certs_test(
1220            certs,
1221            Some(cert_timestamp()),
1222            certs::PEER_ED,
1223            certs::PEER_RSA,
1224            *certs::PEER_CERT_DIGEST,
1225            &rt,
1226        )
1227        .err()
1228        .unwrap();
1229
1230        assert_eq!(
1231            format!("{}", res),
1232            "Handshake protocol violation: Invalid ed25519 TLS cert signature in handshake"
1233        );
1234
1235        let mut certs = msg::Certs::new_empty();
1236        certs.push_cert_body(2.into(), certs::CERT_T2);
1237        certs.push_cert_body(5.into(), certs::CERT_T5);
1238        certs.push_cert_body(7.into(), munge(certs::CERT_T7)); // munge an RSA signature
1239        certs.push_cert_body(4.into(), certs::CERT_T4);
1240        let res = certs_test(
1241            certs,
1242            Some(cert_timestamp()),
1243            certs::PEER_ED,
1244            certs::PEER_RSA,
1245            *certs::PEER_CERT_DIGEST,
1246            &rt,
1247        )
1248        .err()
1249        .unwrap();
1250
1251        assert_eq!(
1252            format!("{}", res),
1253            "Handshake protocol violation: Bad RSA->Ed crosscert signature"
1254        );
1255    }
1256
1257    // Handshake initiator connect tests.
1258    //
1259    // Both `ClientInitiatorHandshake` and `RelayInitiatorHandshake` expect the same response from
1260    // the peer they are connected to (a relay). Each `#[test]` below runs the scenario for both
1261    // types. The following are helpers to build an handshake and call connect() on it.
1262
1263    /// The (link_protocol, clock_skew) tuple returned by a connect().
1264    type ConnectOutcome = crate::Result<(u16, ClockSkew)>;
1265    /// Boxed future returned by a handshake factory.
1266    type ConnectFut = Pin<Box<dyn Future<Output = ConnectOutcome>>>;
1267    /// Given raw bytes (cells) for the [`MsgBuf`], a timestamp for now, run `.connect()` and
1268    /// return `(link_protocol, clock_skew)`.
1269    type HandshakeConnectFn = dyn Fn(Vec<u8>, SystemTime) -> ConnectFut;
1270
1271    /// Returns a closure which runs a [`ClientInitiatorHandshake::connect()`] future using the
1272    /// given byte buffer and system time, and returns the resulting `UnverifiedClientChannel`s
1273    /// link protocol and clock skew.
1274    fn client_connect<R: Runtime>(rt: R) -> impl Fn(Vec<u8>, SystemTime) -> ConnectFut {
1275        move |input, now| {
1276            let rt = rt.clone();
1277            Box::pin(async move {
1278                let unverified =
1279                    ClientInitiatorHandshake::new(MsgBuf::new(input), None, rt, fake_mq())
1280                        .connect(move || now)
1281                        .await?;
1282                Ok((unverified.link_protocol(), unverified.clock_skew()))
1283            })
1284        }
1285    }
1286
1287    /// Return a [`RelayInitiatorHandshake`] connect() future.
1288    #[cfg(feature = "relay")]
1289    fn relay_connect<R: Runtime>(rt: R) -> impl Fn(Vec<u8>, SystemTime) -> ConnectFut {
1290        move |input, now| {
1291            let rt = rt.clone();
1292            Box::pin(async move {
1293                use crate::{
1294                    circuit::test::new_circ_net_params,
1295                    relay::{CreateRequestHandler, channel::test::DummyChanProvider},
1296                };
1297                use std::{net::SocketAddr, sync::Weak};
1298
1299                let chan_provider = Arc::new(DummyChanProvider::new_without_chan(rt.clone()));
1300                // TODO(relay): Might worth having a helper function to create the request handler
1301                // which could also generate this dummy ntor keys.
1302                let ntor_keys = {
1303                    use tor_key_forge::Keygen;
1304                    use tor_relay_crypto::pk::{RelayNtorKeypair, RelayNtorKeys};
1305                    let mut rng = FakeEntropicRng::<TestingRng>(testing_rng());
1306                    let ntor = RelayNtorKeypair::from(
1307                        tor_llcrypto::pk::curve25519::StaticKeypair::generate(&mut rng).unwrap(),
1308                    );
1309                    RelayNtorKeys::new(ntor)
1310                };
1311                let create_handler = Arc::new(CreateRequestHandler::new(
1312                    Arc::downgrade(&chan_provider) as Weak<_>,
1313                    new_circ_net_params(),
1314                    ntor_keys,
1315                ));
1316                let peer_target = OwnedChanTargetBuilder::default().build().unwrap();
1317                let unverified = RelayInitiatorHandshake::new(
1318                    RelayMsgBuf(MsgBuf::new(input)),
1319                    rt,
1320                    fake_auth_material(),
1321                    vec![SocketAddr::new(IpAddr::from([127, 0, 0, 1]), 6666)],
1322                    &peer_target,
1323                    fake_mq(),
1324                    create_handler,
1325                )
1326                .connect(move || now)
1327                .await?;
1328                Ok((unverified.link_protocol(), unverified.clock_skew()))
1329            })
1330        }
1331    }
1332
1333    /// Run the connect function and expect an error.
1334    async fn connect_err_with(input: impl Into<Vec<u8>>, make: &HandshakeConnectFn) -> Error {
1335        make(input.into(), SystemTime::get()).await.err().unwrap()
1336    }
1337
1338    #[test]
1339    fn connect_ok() -> Result<()> {
1340        tor_rtcompat::test_with_one_runtime!(|rt| async move {
1341            for make in [
1342                &client_connect(rt.clone()) as &HandshakeConnectFn,
1343                #[cfg(feature = "relay")]
1344                &relay_connect(rt.clone()),
1345            ] {
1346                let now = humantime::parse_rfc3339("2008-08-02T17:00:00Z").unwrap();
1347
1348                // Basic success: versions, certs, auth_challenge, netinfo.
1349                let mut buf = Vec::new();
1350                buf.extend_from_slice(VERSIONS);
1351                buf.extend_from_slice(NOCERTS);
1352                buf.extend_from_slice(AUTHCHALLENGE);
1353                add_padded(&mut buf, NETINFO_PREFIX);
1354                let (link_protocol, clock_skew) = make(buf, now).await?;
1355                assert_eq!(link_protocol, 5);
1356                assert_eq!(clock_skew, ClockSkew::None);
1357
1358                // With VPADDING and a timestamp in NETINFO.
1359                let mut buf = Vec::new();
1360                buf.extend_from_slice(VERSIONS);
1361                buf.extend_from_slice(NOCERTS);
1362                buf.extend_from_slice(VPADDING);
1363                buf.extend_from_slice(AUTHCHALLENGE);
1364                buf.extend_from_slice(VPADDING);
1365                add_padded(&mut buf, NETINFO_PREFIX_WITH_TIME);
1366                let (_, clock_skew) = make(buf.clone(), now).await?;
1367                assert_eq!(clock_skew, ClockSkew::None);
1368
1369                // Pretend our clock is fast.
1370                let now2 = now + Duration::from_secs(3600);
1371                let (_, clock_skew) = make(buf, now2).await?;
1372                assert_eq!(clock_skew, ClockSkew::Fast(Duration::from_secs(3600)));
1373            }
1374            Ok(())
1375        })
1376    }
1377
1378    #[test]
1379    fn connect_badver() {
1380        tor_rtcompat::test_with_one_runtime!(|rt| async move {
1381            for make in [
1382                &client_connect(rt.clone()) as &HandshakeConnectFn,
1383                #[cfg(feature = "relay")]
1384                &relay_connect(rt.clone()),
1385            ] {
1386                let err = connect_err_with(&b"HTTP://"[..], make).await;
1387                assert!(matches!(err, Error::HandshakeProto(_)));
1388                assert_eq!(
1389                    format!("{}", err),
1390                    "Handshake protocol violation: Invalid CircID in variable cell"
1391                );
1392
1393                let err = connect_err_with(&hex!("0000 07 0004 1234 ffff")[..], make).await;
1394                assert!(matches!(err, Error::HandshakeProto(_)));
1395                assert_eq!(
1396                    format!("{}", err),
1397                    "Handshake protocol violation: No shared link protocols"
1398                );
1399            }
1400        });
1401    }
1402
1403    #[test]
1404    fn connect_cellparse() {
1405        tor_rtcompat::test_with_one_runtime!(|rt| async move {
1406            for make in [
1407                &client_connect(rt.clone()) as &HandshakeConnectFn,
1408                #[cfg(feature = "relay")]
1409                &relay_connect(rt.clone()),
1410            ] {
1411                let mut buf = Vec::new();
1412                buf.extend_from_slice(VERSIONS);
1413                // A certs cell with invalid contents.
1414                buf.extend_from_slice(&hex!("00000000 81 0001 01")[..]);
1415                let err = connect_err_with(buf, make).await;
1416                assert!(matches!(err, Error::HandshakeProto { .. }));
1417            }
1418        });
1419    }
1420
1421    #[test]
1422    fn connect_duplicates() {
1423        tor_rtcompat::test_with_one_runtime!(|rt| async move {
1424            for make in [
1425                &client_connect(rt.clone()) as &HandshakeConnectFn,
1426                #[cfg(feature = "relay")]
1427                &relay_connect(rt.clone()),
1428            ] {
1429                // Duplicate CERTS cell.
1430                let mut buf = Vec::new();
1431                buf.extend_from_slice(VERSIONS);
1432                buf.extend_from_slice(NOCERTS);
1433                buf.extend_from_slice(NOCERTS);
1434                add_netinfo(&mut buf);
1435                let err = connect_err_with(buf, make).await;
1436                assert!(matches!(err, Error::HandshakeProto(_)));
1437                assert_eq!(
1438                    format!("{}", err),
1439                    "Handshake protocol violation: Expected [VPADDING, AUTH_CHALLENGE] cell, but received CERTS cell instead"
1440                );
1441
1442                // Duplicate AUTH_CHALLENGE cell.
1443                let mut buf = Vec::new();
1444                buf.extend_from_slice(VERSIONS);
1445                buf.extend_from_slice(NOCERTS);
1446                buf.extend_from_slice(AUTHCHALLENGE);
1447                buf.extend_from_slice(AUTHCHALLENGE);
1448                add_netinfo(&mut buf);
1449                let err = connect_err_with(buf, make).await;
1450                assert!(matches!(err, Error::HandshakeProto(_)));
1451                assert_eq!(
1452                    format!("{}", err),
1453                    "Handshake protocol violation: Expected [VPADDING, NETINFO] cell, but received AUTH_CHALLENGE cell instead"
1454                );
1455            }
1456        });
1457    }
1458
1459    #[test]
1460    fn connect_missing_certs() {
1461        tor_rtcompat::test_with_one_runtime!(|rt| async move {
1462            for make in [
1463                &client_connect(rt.clone()) as &HandshakeConnectFn,
1464                #[cfg(feature = "relay")]
1465                &relay_connect(rt.clone()),
1466            ] {
1467                let mut buf = Vec::new();
1468                buf.extend_from_slice(VERSIONS);
1469                add_netinfo(&mut buf);
1470                let err = connect_err_with(buf, make).await;
1471                assert!(matches!(err, Error::HandshakeProto(_)));
1472                assert_eq!(
1473                    format!("{}", err),
1474                    "Handshake protocol violation: Expected [VPADDING, CERTS] cell, but received NETINFO cell instead"
1475                );
1476            }
1477        });
1478    }
1479
1480    #[test]
1481    fn connect_missing_netinfo() {
1482        tor_rtcompat::test_with_one_runtime!(|rt| async move {
1483            for make in [
1484                &client_connect(rt.clone()) as &HandshakeConnectFn,
1485                #[cfg(feature = "relay")]
1486                &relay_connect(rt.clone()),
1487            ] {
1488                let mut buf = Vec::new();
1489                buf.extend_from_slice(VERSIONS);
1490                buf.extend_from_slice(NOCERTS);
1491                let err = connect_err_with(buf, make).await;
1492                assert!(matches!(err, Error::HandshakeProto(_)));
1493                assert_eq!(
1494                    format!("{}", err),
1495                    "Handshake protocol violation: Stream ended unexpectedly"
1496                );
1497            }
1498        });
1499    }
1500
1501    #[test]
1502    fn connect_misplaced_cell() {
1503        tor_rtcompat::test_with_one_runtime!(|rt| async move {
1504            for make in [
1505                &client_connect(rt.clone()) as &HandshakeConnectFn,
1506                #[cfg(feature = "relay")]
1507                &relay_connect(rt.clone()),
1508            ] {
1509                let mut buf = Vec::new();
1510                buf.extend_from_slice(VERSIONS);
1511                // A CREATE cell where a CERTS cell is expected.
1512                add_padded(&mut buf, &hex!("00000001 01")[..]);
1513                let err = connect_err_with(buf, make).await;
1514                assert!(matches!(err, Error::HandshakeProto(_)));
1515                assert_eq!(
1516                    format!("{}", err),
1517                    "Handshake protocol violation: Decoding cell error: Error while parsing channel cell: Bad object: Unexpected command CREATE in HandshakeRelayResponderMsg"
1518                );
1519            }
1520        });
1521    }
1522}