1use 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
33pub(crate) static LINK_PROTOCOLS: &[u16] = &[4, 5];
35
36pub(crate) trait ChannelBaseHandshake<T>
44where
45 T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
46{
47 fn framed_tls(&mut self) -> &mut ChannelFrame<T>;
49 fn unique_id(&self) -> &UniqId;
51
52 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 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(), now_fn(), ))
75 }
76
77 async fn recv_versions_cell(&mut self) -> Result<u16> {
84 trace!(stream_id = %self.unique_id(), "waiting for versions");
87 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 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 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
121pub(crate) enum AuthLogAction {
126 Leave,
128 Take,
130}
131
132impl AuthLogAction {
133 fn is_take(&self) -> bool {
135 matches!(self, Self::Take)
136 }
137}
138
139pub(crate) trait ChannelInitiatorHandshake<T>: ChannelBaseHandshake<T>
144where
145 T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
146{
147 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 let certs = loop {
178 restricted_msg! {
179 enum CertsMsg : ChanMsg {
180 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 let auth_challenge = loop {
195 restricted_msg! {
196 enum AuthChallengeMsg : ChanMsg {
197 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 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,
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
242pub(crate) struct UnverifiedChannel<
248 T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
249 S: CoarseTimeProvider + SleepProvider,
250> {
251 pub(crate) sleep_prov: S,
253 pub(crate) memquota: ChannelAccount,
255 pub(crate) link_protocol: u16,
257 pub(crate) framed_tls: ChannelFrame<T>,
259 pub(crate) target_method: Option<ChannelMethod>,
261 pub(crate) clock_skew: ClockSkew,
266 pub(crate) unique_id: UniqId,
268}
269
270pub(crate) struct UnverifiedInitiatorChannel<
280 T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
281 S: CoarseTimeProvider + SleepProvider,
282> {
283 pub(crate) inner: UnverifiedChannel<T, S>,
285 pub(crate) certs_cell: msg::Certs,
287}
288
289pub(crate) struct VerifiedChannel<
298 T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
299 S: CoarseTimeProvider + SleepProvider,
300> {
301 pub(crate) sleep_prov: S,
303 pub(crate) memquota: ChannelAccount,
305 pub(crate) link_protocol: u16,
307 pub(crate) framed_tls: ChannelFrame<T>,
309 pub(crate) target_method: Option<ChannelMethod>,
311 pub(crate) unique_id: UniqId,
313 pub(crate) clock_skew: ClockSkew,
315
316 pub(crate) peer_relay_ids: RelayIds,
318 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 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 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 let cert_signing = get_cert(peer_certs, CertType::IDENTITY_V_SIGNING)?;
366
367 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 if !cert_signing_sig.is_valid() {
378 return Err(Error::HandshakeProto(
379 "Invalid ed25519 identity cert signature in handshake".into(),
380 ));
381 }
382
383 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 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 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 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 cert_signing_timeliness?;
439 rsa_cert_timeliness?;
440
441 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 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 #[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 crate::note_incoming_traffic();
504
505 self.framed_tls.codec_mut().set_open()?;
507
508 let channel_type = self.framed_tls.codec().channel_type();
512 channel_mode.check_agrees_with_type(channel_type)?;
513
514 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 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 pub(crate) fn set_authenticated(&mut self) -> Result<()> {
559 self.framed_tls.codec_mut().set_authenticated()?;
560 Ok(())
561 }
562
563 pub(crate) fn relay_ids(&self) -> &RelayIds {
565 &self.peer_relay_ids
566 }
567
568 #[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 crate::note_incoming_traffic();
599
600 self.framed_tls.codec_mut().set_open()?;
602
603 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 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 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 let now = now.unwrap_or_else(SystemTime::get);
670
671 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 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 if !cert_tls_sig.is_valid() {
726 return Err(Error::HandshakeProto(
727 "Invalid ed25519 TLS cert signature in handshake".into(),
728 ));
729 }
730
731 cert_tls_timeliness?;
733
734 Ok(self.inner.into_verified(peer_relay_ids, peer_rsa_id_digest))
735 }
736}
737
738pub(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 let now = now.unwrap_or_else(SystemTime::get);
761
762 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 if cert_sig.is_valid() {
774 return Err(Error::HandshakeProto(
775 "Invalid ed25519 LINK_AUTH signature in handshake".into(),
776 ));
777 }
778
779 cert_timeliness?;
781
782 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
793pub(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 (_, _) => Error::HandshakeProto("Certificate expired or not yet valid".into()),
820 });
821 let cert = checkable.dangerously_assume_timely();
822 (status, cert)
823}
824
825pub(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
834pub(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 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
859fn 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 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
880pub(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 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 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 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 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 pub(crate) fn add_netinfo(buf: &mut Vec<u8>) {
979 add_padded(buf, NETINFO_PREFIX);
980 }
981
982 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 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 #[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 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 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 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)); 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)); 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 type ConnectOutcome = crate::Result<(u16, ClockSkew)>;
1265 type ConnectFut = Pin<Box<dyn Future<Output = ConnectOutcome>>>;
1267 type HandshakeConnectFn = dyn Fn(Vec<u8>, SystemTime) -> ConnectFut;
1270
1271 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 #[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 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 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 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 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 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 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 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 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 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}