1use futures::io::{AsyncRead, AsyncWrite};
4use futures::sink::SinkExt;
5use futures::stream::StreamExt;
6use tor_cell::chancell::msg::AnyChanMsg;
7use tor_error::internal;
8
9use crate::channel::{ChannelType, UniqId, new_frame};
10use crate::memquota::ChannelAccount;
11use crate::util::skew::ClockSkew;
12use crate::{Error, Result};
13use tor_cell::chancell::{AnyChanCell, ChanMsg, msg};
14use tor_rtcompat::{CoarseTimeProvider, SleepProvider, StreamOps};
15
16use std::net::SocketAddr;
17use std::sync::Arc;
18use std::time::SystemTime;
19
20use tor_linkspec::{ChanTarget, ChannelMethod, OwnedChanTargetBuilder, RelayIds};
21use tor_llcrypto as ll;
22use tor_llcrypto::pk::ed25519::Ed25519Identity;
23use tor_llcrypto::pk::rsa::RsaIdentity;
24
25use digest::Digest;
26
27use super::ChannelFrame;
28
29use tracing::{debug, instrument, trace};
30
31static LINK_PROTOCOLS: &[u16] = &[4, 5];
33
34trait ChannelBaseHandshake<T>
42where
43 T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
44{
45 fn framed_tls(&mut self) -> &mut ChannelFrame<T>;
47 fn unique_id(&self) -> &UniqId;
49
50 async fn send_versions_cell<F>(
54 &mut self,
55 now_fn: F,
56 ) -> Result<(coarsetime::Instant, SystemTime)>
57 where
58 F: FnOnce() -> SystemTime,
59 {
60 trace!(stream_id = %self.unique_id(), "sending versions");
61 let version_cell = AnyChanCell::new(
63 None,
64 msg::Versions::new(LINK_PROTOCOLS)
65 .map_err(|e| Error::from_cell_enc(e, "versions message"))?
66 .into(),
67 );
68 self.framed_tls().send(version_cell).await?;
69 Ok((
70 coarsetime::Instant::now(), now_fn(), ))
73 }
74
75 async fn recv_versions_cell(&mut self) -> Result<u16> {
82 trace!(stream_id = %self.unique_id(), "waiting for versions");
85 let Some(cell) = self.framed_tls().next().await.transpose()? else {
88 return Err(Error::ChanIoErr(Arc::new(std::io::Error::from(
89 std::io::ErrorKind::UnexpectedEof,
90 ))));
91 };
92 let AnyChanMsg::Versions(their_versions) = cell.into_circid_and_msg().1 else {
93 return Err(Error::from(internal!(
94 "Unexpected cell, expecting a VERSIONS cell",
95 )));
96 };
97 trace!(stream_id = %self.unique_id(), "received their VERSIONS {:?}", their_versions);
98
99 let link_protocol = their_versions
101 .best_shared_link_protocol(LINK_PROTOCOLS)
102 .ok_or_else(|| Error::HandshakeProto("No shared link protocols".into()))?;
103 trace!(stream_id = %self.unique_id(), "negotiated version {}", link_protocol);
104
105 self.framed_tls()
107 .codec_mut()
108 .set_link_version(link_protocol)?;
109 Ok(link_protocol)
110 }
111}
112
113trait ChannelInitiatorHandshake<T>: ChannelBaseHandshake<T>
118where
119 T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
120{
121 fn is_expecting_auth_challenge(&self) -> bool;
125
126 async fn recv_cells_from_responder(
134 &mut self,
135 ) -> Result<(
136 Option<msg::AuthChallenge>,
137 msg::Certs,
138 (msg::Netinfo, coarsetime::Instant),
139 )> {
140 let mut auth_challenge_cell: Option<msg::AuthChallenge> = None;
141 let mut certs_cell: Option<msg::Certs> = None;
142 let mut netinfo_cell: Option<(msg::Netinfo, coarsetime::Instant)> = None;
143
144 while let Some(cell) = self.framed_tls().next().await.transpose()? {
149 use super::AnyChanMsg::*;
150 let (_, m) = cell.into_circid_and_msg();
151 trace!(stream_id = %self.unique_id(), "received a {} cell.", m.cmd());
152 match m {
153 Vpadding(_) => (),
155 AuthChallenge(ac) => {
157 if auth_challenge_cell.replace(ac).is_some() {
158 return Err(Error::HandshakeProto(
159 "Duplicate AUTH_CHALLENGE cell".into(),
160 ));
161 }
162 }
163 Certs(c) => {
164 if certs_cell.replace(c).is_some() {
165 return Err(Error::HandshakeProto("Duplicate CERTS cell".into()));
166 }
167 }
168 Netinfo(n) => {
169 if netinfo_cell.is_some() {
170 return Err(Error::from(internal!(
173 "Somehow tried to record a duplicate NETINFO cell"
174 )));
175 }
176 netinfo_cell = Some((n, coarsetime::Instant::now()));
177 break;
178 }
179 _ => {
182 return Err(Error::from(internal!(
183 "Unexpected cell during initiator handshake: {m:?}"
184 )));
185 }
186 }
187 }
188
189 let Some((netinfo, netinfo_rcvd_at)) = netinfo_cell else {
192 return Err(Error::HandshakeProto("Missing NETINFO cell".into()));
193 };
194 let Some(certs) = certs_cell else {
195 return Err(Error::HandshakeProto("Missing CERTS cell".into()));
196 };
197 if self.is_expecting_auth_challenge() && auth_challenge_cell.is_none() {
199 return Err(Error::HandshakeProto("Missing AUTH_CHALLENGE cell".into()));
200 };
201
202 Ok((auth_challenge_cell, certs, (netinfo, netinfo_rcvd_at)))
203 }
204}
205
206pub struct ClientInitiatorHandshake<
208 T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
209 S: CoarseTimeProvider + SleepProvider,
210> {
211 sleep_prov: S,
213
214 memquota: ChannelAccount,
216
217 framed_tls: ChannelFrame<T>,
222
223 target_method: Option<ChannelMethod>,
225
226 unique_id: UniqId,
228}
229
230impl<T, S> ChannelBaseHandshake<T> for ClientInitiatorHandshake<T, S>
232where
233 T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
234 S: CoarseTimeProvider + SleepProvider,
235{
236 fn framed_tls(&mut self) -> &mut ChannelFrame<T> {
237 &mut self.framed_tls
238 }
239 fn unique_id(&self) -> &UniqId {
240 &self.unique_id
241 }
242}
243
244impl<T, S> ChannelInitiatorHandshake<T> for ClientInitiatorHandshake<T, S>
246where
247 T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
248 S: CoarseTimeProvider + SleepProvider,
249{
250 fn is_expecting_auth_challenge(&self) -> bool {
251 false
253 }
254}
255
256pub struct UnverifiedChannel<
260 T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
261 S: CoarseTimeProvider + SleepProvider,
262> {
263 channel_type: ChannelType,
265 sleep_prov: S,
267 memquota: ChannelAccount,
269 link_protocol: u16,
271 framed_tls: ChannelFrame<T>,
273 certs_cell: msg::Certs,
275 target_method: Option<ChannelMethod>,
277 #[allow(dead_code)] netinfo_cell: msg::Netinfo,
280 clock_skew: ClockSkew,
285 unique_id: UniqId,
287}
288
289pub struct VerifiedChannel<
297 T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
298 S: CoarseTimeProvider + SleepProvider,
299> {
300 channel_type: ChannelType,
302 sleep_prov: S,
304 memquota: ChannelAccount,
306 link_protocol: u16,
308 framed_tls: ChannelFrame<T>,
310 target_method: Option<ChannelMethod>,
312 unique_id: UniqId,
314 ed25519_id: Ed25519Identity,
316 rsa_id: RsaIdentity,
318 clock_skew: ClockSkew,
320}
321
322impl<
323 T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
324 S: CoarseTimeProvider + SleepProvider,
325> ClientInitiatorHandshake<T, S>
326{
327 pub(crate) fn new(
329 tls: T,
330 target_method: Option<ChannelMethod>,
331 sleep_prov: S,
332 memquota: ChannelAccount,
333 ) -> Self {
334 Self {
335 framed_tls: new_frame(tls, ChannelType::ClientInitiator),
336 target_method,
337 unique_id: UniqId::new(),
338 sleep_prov,
339 memquota,
340 }
341 }
342
343 #[instrument(skip_all, level = "trace")]
349 pub async fn connect<F>(mut self, now_fn: F) -> Result<UnverifiedChannel<T, S>>
350 where
351 F: FnOnce() -> SystemTime,
352 {
353 match &self.target_method {
354 Some(method) => debug!(
355 stream_id = %self.unique_id,
356 "starting Tor handshake with {:?}",
357 method
358 ),
359 None => debug!(stream_id = %self.unique_id, "starting Tor handshake"),
360 }
361 let (versions_flushed_at, versions_flushed_wallclock) =
363 self.send_versions_cell(now_fn).await?;
364
365 let link_protocol = self.recv_versions_cell().await?;
367
368 let (_, certs_cell, (netinfo_cell, netinfo_rcvd_at)) =
371 self.recv_cells_from_responder().await?;
372
373 let clock_skew = unauthenticated_clock_skew(
375 &netinfo_cell,
376 netinfo_rcvd_at,
377 versions_flushed_at,
378 versions_flushed_wallclock,
379 );
380
381 trace!(stream_id = %self.unique_id, "received handshake, ready to verify.");
382
383 Ok(UnverifiedChannel {
384 channel_type: ChannelType::ClientInitiator,
385 link_protocol,
386 framed_tls: self.framed_tls,
387 certs_cell,
388 netinfo_cell,
389 clock_skew,
390 target_method: self.target_method.take(),
391 unique_id: self.unique_id,
392 sleep_prov: self.sleep_prov.clone(),
393 memquota: self.memquota.clone(),
394 })
395 }
396}
397
398impl<
399 T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
400 S: CoarseTimeProvider + SleepProvider,
401> UnverifiedChannel<T, S>
402{
403 pub fn clock_skew(&self) -> ClockSkew {
412 self.clock_skew
413 }
414
415 #[instrument(skip_all, level = "trace")]
429 pub fn check<U: ChanTarget + ?Sized>(
430 self,
431 peer: &U,
432 peer_cert: &[u8],
433 now: Option<std::time::SystemTime>,
434 ) -> Result<VerifiedChannel<T, S>> {
435 let peer_cert_sha256 = ll::d::Sha256::digest(peer_cert);
436 self.check_internal(peer, &peer_cert_sha256[..], now)
437 }
438
439 fn check_internal<U: ChanTarget + ?Sized>(
442 self,
443 peer: &U,
444 peer_cert_sha256: &[u8],
445 now: Option<SystemTime>,
446 ) -> Result<VerifiedChannel<T, S>> {
447 use tor_cert::CertType;
448 use tor_checkable::*;
449
450 fn check_timeliness<C, T>(checkable: C, now: SystemTime, skew: ClockSkew) -> (Result<()>, T)
458 where
459 C: Timebound<T, Error = TimeValidityError>,
460 {
461 let status = checkable.is_valid_at(&now).map_err(|e| match (e, skew) {
462 (TimeValidityError::Expired(expired_by), ClockSkew::Fast(skew))
463 if expired_by < skew =>
464 {
465 Error::HandshakeCertsExpired { expired_by }
466 }
467 (_, _) => Error::HandshakeProto("Certificate expired or not yet valid".into()),
471 });
472 let cert = checkable.dangerously_assume_timely();
473 (status, cert)
474 }
475 let now = now.unwrap_or_else(SystemTime::now);
477
478 let c = &self.certs_cell;
492 fn get_cert(
494 certs: &tor_cell::chancell::msg::Certs,
495 tp: CertType,
496 ) -> Result<tor_cert::KeyUnknownCert> {
497 match certs.parse_ed_cert(tp) {
498 Ok(c) => Ok(c),
499 Err(tor_cell::Error::ChanProto(e)) => Err(Error::HandshakeProto(e)),
500 Err(e) => Err(Error::HandshakeProto(e.to_string())),
501 }
502 }
503
504 let id_sk = get_cert(c, CertType::IDENTITY_V_SIGNING)?;
505 let sk_tls = get_cert(c, CertType::SIGNING_V_TLS_CERT)?;
506
507 let mut sigs = Vec::new();
508
509 let (id_sk, id_sk_sig) = id_sk
518 .should_have_signing_key()
519 .map_err(Error::HandshakeCertErr)?
520 .dangerously_split()
521 .map_err(Error::HandshakeCertErr)?;
522 sigs.push(&id_sk_sig);
523 let (id_sk_timeliness, id_sk) = check_timeliness(id_sk, now, self.clock_skew);
524
525 let identity_key = id_sk.signing_key().ok_or_else(|| {
527 Error::HandshakeProto("Missing identity key in identity->signing cert".into())
528 })?;
529
530 let signing_key = id_sk.subject_key().as_ed25519().ok_or_else(|| {
532 Error::HandshakeProto("Bad key type in identity->signing cert".into())
533 })?;
534
535 let (sk_tls, sk_tls_sig) = sk_tls
538 .should_be_signed_with(signing_key)
539 .map_err(Error::HandshakeCertErr)?
540 .dangerously_split()
541 .map_err(Error::HandshakeCertErr)?;
542 sigs.push(&sk_tls_sig);
543 let (sk_tls_timeliness, sk_tls) = check_timeliness(sk_tls, now, self.clock_skew);
544
545 if peer_cert_sha256 != sk_tls.subject_key().as_bytes() {
546 return Err(Error::HandshakeProto(
547 "Peer cert did not authenticate TLS cert".into(),
548 ));
549 }
550
551 if !ll::pk::ed25519::validate_batch(&sigs[..]) {
557 return Err(Error::HandshakeProto(
558 "Invalid ed25519 signature in handshake".into(),
559 ));
560 }
561
562 let pkrsa = c
570 .cert_body(CertType::RSA_ID_X509)
571 .and_then(ll::util::x509_extract_rsa_subject_kludge)
572 .ok_or_else(|| Error::HandshakeProto("Couldn't find RSA identity key".into()))?;
573
574 let rsa_cert = c
580 .cert_body(CertType::RSA_ID_V_IDENTITY)
581 .ok_or_else(|| Error::HandshakeProto("No RSA->Ed crosscert".into()))?;
582 let rsa_cert = tor_cert::rsa::RsaCrosscert::decode(rsa_cert)
583 .map_err(|e| Error::from_bytes_err(e, "RSA identity cross-certificate"))?
584 .check_signature(&pkrsa)
585 .map_err(|_| Error::HandshakeProto("Bad RSA->Ed crosscert signature".into()))?;
586 let (rsa_cert_timeliness, rsa_cert) = check_timeliness(rsa_cert, now, self.clock_skew);
587
588 if !rsa_cert.subject_key_matches(identity_key) {
589 return Err(Error::HandshakeProto(
590 "RSA->Ed crosscert certifies incorrect key".into(),
591 ));
592 }
593
594 let rsa_id = pkrsa.to_rsa_identity();
595
596 trace!(
597 stream_id = %self.unique_id,
598 "Validated identity as {} [{}]",
599 identity_key,
600 rsa_id
601 );
602
603 let actual_identity = RelayIds::builder()
613 .ed_identity(*identity_key)
614 .rsa_identity(rsa_id)
615 .build()
616 .expect("Unable to build RelayIds");
617
618 match super::check_id_match_helper(&actual_identity, peer) {
621 Err(Error::ChanMismatch(msg)) => Err(Error::HandshakeProto(msg)),
622 other => other,
623 }?;
624
625 id_sk_timeliness?;
640 sk_tls_timeliness?;
641 rsa_cert_timeliness?;
642
643 Ok(VerifiedChannel {
644 channel_type: self.channel_type,
645 link_protocol: self.link_protocol,
646 framed_tls: self.framed_tls,
647 unique_id: self.unique_id,
648 target_method: self.target_method,
649 ed25519_id: *identity_key,
650 rsa_id,
651 clock_skew: self.clock_skew,
652 sleep_prov: self.sleep_prov,
653 memquota: self.memquota,
654 })
655 }
656}
657
658impl<
659 T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
660 S: CoarseTimeProvider + SleepProvider,
661> VerifiedChannel<T, S>
662{
663 #[instrument(skip_all, level = "trace")]
670 pub async fn finish(mut self) -> Result<(Arc<super::Channel>, super::reactor::Reactor<S>)> {
671 crate::note_incoming_traffic();
678 trace!(stream_id = %self.unique_id, "Sending netinfo cell.");
679
680 let peer_ip = self
685 .target_method
686 .as_ref()
687 .and_then(ChannelMethod::socket_addrs)
688 .and_then(|addrs| addrs.first())
689 .map(SocketAddr::ip);
690 let netinfo = msg::Netinfo::from_client(peer_ip);
691 self.framed_tls.send(netinfo.into()).await?;
692
693 self.framed_tls.codec_mut().set_open()?;
695
696 debug!(
697 stream_id = %self.unique_id,
698 "Completed handshake with {} [{}]",
699 self.ed25519_id, self.rsa_id
700 );
701
702 let stream_ops = self.framed_tls.new_handle();
709 let (tls_sink, tls_stream) = self.framed_tls.split();
710
711 let mut peer_builder = OwnedChanTargetBuilder::default();
712 if let Some(target_method) = self.target_method {
713 if let Some(addrs) = target_method.socket_addrs() {
714 peer_builder.addrs(addrs.to_owned());
715 }
716 peer_builder.method(target_method);
717 }
718 let peer_id = peer_builder
719 .ed_identity(self.ed25519_id)
720 .rsa_identity(self.rsa_id)
721 .build()
722 .expect("OwnedChanTarget builder failed");
723
724 super::Channel::new(
725 self.channel_type,
726 self.link_protocol,
727 Box::new(tls_sink),
728 Box::new(tls_stream),
729 stream_ops,
730 self.unique_id,
731 peer_id,
732 self.clock_skew,
733 self.sleep_prov,
734 self.memquota,
735 )
736 }
737}
738
739fn unauthenticated_clock_skew(
745 netinfo_cell: &msg::Netinfo,
746 netinfo_rcvd_at: coarsetime::Instant,
747 versions_flushed_at: coarsetime::Instant,
748 versions_flushed_wallclock: SystemTime,
749) -> ClockSkew {
750 if let Some(netinfo_timestamp) = netinfo_cell.timestamp() {
753 let delay = netinfo_rcvd_at - versions_flushed_at;
754 ClockSkew::from_handshake_timestamps(
755 versions_flushed_wallclock,
756 netinfo_timestamp,
757 delay.into(),
758 )
759 } else {
760 ClockSkew::None
761 }
762}
763
764#[cfg(test)]
765pub(super) mod test {
766 #![allow(clippy::unwrap_used)]
767 use hex_literal::hex;
768 use regex::Regex;
769 use std::time::{Duration, SystemTime};
770
771 use super::*;
772 use crate::Result;
773 use crate::channel::handler::test::MsgBuf;
774 use crate::util::fake_mq;
775 use tor_cell::chancell::msg;
776 use tor_linkspec::OwnedChanTarget;
777 use tor_rtcompat::{PreferredRuntime, Runtime};
778
779 const VERSIONS: &[u8] = &hex!("0000 07 0006 0003 0004 0005");
780 const NOCERTS: &[u8] = &hex!("00000000 81 0001 00");
782 const NETINFO_PREFIX: &[u8] = &hex!(
783 "00000000 08 00000000
784 04 04 7f 00 00 02
785 01
786 04 04 7f 00 00 03"
787 );
788 const NETINFO_PREFIX_WITH_TIME: &[u8] = &hex!(
789 "00000000 08 48949290
790 04 04 7f 00 00 02
791 01
792 04 04 7f 00 00 03"
793 );
794 const AUTHCHALLENGE: &[u8] = &hex!(
795 "00000000 82 0026
796 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
797 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
798 0002 0003 00ff"
799 );
800
801 const VPADDING: &[u8] = &hex!("00000000 80 0003 FF FF FF");
802
803 fn add_padded(buf: &mut Vec<u8>, cell: &[u8]) {
804 let len_prev = buf.len();
805 buf.extend_from_slice(cell);
806 buf.resize(len_prev + 514, 0);
807 }
808 fn add_netinfo(buf: &mut Vec<u8>) {
809 add_padded(buf, NETINFO_PREFIX);
810 }
811
812 #[test]
813 fn connect_ok() -> Result<()> {
814 tor_rtcompat::test_with_one_runtime!(|rt| async move {
815 let now = humantime::parse_rfc3339("2008-08-02T17:00:00Z").unwrap();
816 let mut buf = Vec::new();
817 buf.extend_from_slice(VERSIONS);
819 buf.extend_from_slice(NOCERTS);
821 add_padded(&mut buf, NETINFO_PREFIX);
823 let mb = MsgBuf::new(&buf[..]);
824 let handshake = ClientInitiatorHandshake::new(mb, None, rt.clone(), fake_mq());
825 let unverified = handshake.connect(|| now).await?;
826
827 assert_eq!(unverified.link_protocol, 5);
828 assert_eq!(unverified.clock_skew(), ClockSkew::None);
830
831 let mut buf = Vec::new();
833 buf.extend_from_slice(VERSIONS);
834 buf.extend_from_slice(NOCERTS);
835 buf.extend_from_slice(VPADDING);
836 buf.extend_from_slice(AUTHCHALLENGE);
837 buf.extend_from_slice(VPADDING);
838 add_padded(&mut buf, NETINFO_PREFIX_WITH_TIME);
839 let mb = MsgBuf::new(&buf[..]);
840 let handshake = ClientInitiatorHandshake::new(mb, None, rt.clone(), fake_mq());
841 let unverified = handshake.connect(|| now).await?;
842 assert_eq!(unverified.clock_skew(), ClockSkew::None);
844
845 let now2 = now + Duration::from_secs(3600);
847 let mb = MsgBuf::new(&buf[..]);
848 let handshake = ClientInitiatorHandshake::new(mb, None, rt.clone(), fake_mq());
849 let unverified = handshake.connect(|| now2).await?;
850 assert_eq!(
851 unverified.clock_skew(),
852 ClockSkew::Fast(Duration::from_secs(3600))
853 );
854
855 Ok(())
856 })
857 }
858
859 async fn connect_err<T: Into<Vec<u8>>, S>(input: T, sleep_prov: S) -> Error
860 where
861 S: CoarseTimeProvider + SleepProvider,
862 {
863 let mb = MsgBuf::new(input);
864 let handshake = ClientInitiatorHandshake::new(mb, None, sleep_prov, fake_mq());
865 handshake.connect(SystemTime::now).await.err().unwrap()
866 }
867
868 #[test]
869 fn connect_badver() {
870 tor_rtcompat::test_with_one_runtime!(|rt| async move {
871 let err = connect_err(&b"HTTP://"[..], rt.clone()).await;
872 assert!(matches!(err, Error::HandshakeProto(_)));
873 assert_eq!(
874 format!("{}", err),
875 "Handshake protocol violation: Invalid CircID in variable cell"
876 );
877
878 let err = connect_err(&hex!("0000 07 0004 1234 ffff")[..], rt.clone()).await;
879 assert!(matches!(err, Error::HandshakeProto(_)));
880 assert_eq!(
881 format!("{}", err),
882 "Handshake protocol violation: No shared link protocols"
883 );
884 });
885 }
886
887 #[test]
888 fn connect_cellparse() {
889 tor_rtcompat::test_with_one_runtime!(|rt| async move {
890 let mut buf = Vec::new();
891 buf.extend_from_slice(VERSIONS);
892 buf.extend_from_slice(&hex!("00000000 81 0001 01")[..]);
894 let err = connect_err(buf, rt.clone()).await;
895 assert!(matches!(err, Error::HandshakeProto { .. }));
896 });
897 }
898
899 #[test]
900 fn connect_duplicates() {
901 tor_rtcompat::test_with_one_runtime!(|rt| async move {
902 let mut buf = Vec::new();
903 buf.extend_from_slice(VERSIONS);
904 buf.extend_from_slice(NOCERTS);
905 buf.extend_from_slice(NOCERTS);
906 add_netinfo(&mut buf);
907 let err = connect_err(buf, rt.clone()).await;
908 assert!(matches!(err, Error::HandshakeProto(_)));
909 assert_eq!(
910 format!("{}", err),
911 "Handshake protocol violation: Duplicate CERTS cell"
912 );
913
914 let mut buf = Vec::new();
915 buf.extend_from_slice(VERSIONS);
916 buf.extend_from_slice(NOCERTS);
917 buf.extend_from_slice(AUTHCHALLENGE);
918 buf.extend_from_slice(AUTHCHALLENGE);
919 add_netinfo(&mut buf);
920 let err = connect_err(buf, rt.clone()).await;
921 assert!(matches!(err, Error::HandshakeProto(_)));
922 assert_eq!(
923 format!("{}", err),
924 "Handshake protocol violation: Duplicate AUTH_CHALLENGE cell"
925 );
926 });
927 }
928
929 #[test]
930 fn connect_missing_certs() {
931 tor_rtcompat::test_with_one_runtime!(|rt| async move {
932 let mut buf = Vec::new();
933 buf.extend_from_slice(VERSIONS);
934 add_netinfo(&mut buf);
935 let err = connect_err(buf, rt.clone()).await;
936 assert!(matches!(err, Error::HandshakeProto(_)));
937 assert_eq!(
938 format!("{}", err),
939 "Handshake protocol violation: Missing CERTS cell"
940 );
941 });
942 }
943
944 #[test]
945 fn connect_missing_netinfo() {
946 tor_rtcompat::test_with_one_runtime!(|rt| async move {
947 let mut buf = Vec::new();
948 buf.extend_from_slice(VERSIONS);
949 buf.extend_from_slice(NOCERTS);
950 let err = connect_err(buf, rt.clone()).await;
951 assert!(matches!(err, Error::HandshakeProto(_)));
952 assert_eq!(
953 format!("{}", err),
954 "Handshake protocol violation: Missing NETINFO cell"
955 );
956 });
957 }
958
959 #[test]
960 fn connect_misplaced_cell() {
961 tor_rtcompat::test_with_one_runtime!(|rt| async move {
962 let mut buf = Vec::new();
963 buf.extend_from_slice(VERSIONS);
964 add_padded(&mut buf, &hex!("00000001 01")[..]);
966 let err = connect_err(buf, rt.clone()).await;
967 assert!(matches!(err, Error::HandshakeProto(_)));
968 assert_eq!(
969 format!("{}", err),
970 "Handshake protocol violation: Decoding cell error: Error while parsing channel cell: Bad object: Unexpected command CREATE in HandshakeRelayResponderMsg"
971 );
972 });
973 }
974
975 fn make_unverified<R>(certs: msg::Certs, runtime: R) -> UnverifiedChannel<MsgBuf, R>
976 where
977 R: Runtime,
978 {
979 let localhost = std::net::IpAddr::V4(std::net::Ipv4Addr::LOCALHOST);
980 let netinfo_cell = msg::Netinfo::from_client(Some(localhost));
981 let mut framed_tls = new_frame(MsgBuf::new(&b""[..]), ChannelType::ClientInitiator);
982 let _ = framed_tls.codec_mut().set_link_version(4);
983 let _ = framed_tls.codec_mut().set_open();
984 let clock_skew = ClockSkew::None;
985 UnverifiedChannel {
986 channel_type: ChannelType::ClientInitiator,
987 link_protocol: 4,
988 framed_tls,
989 certs_cell: certs,
990 netinfo_cell,
991 clock_skew,
992 target_method: None,
993 unique_id: UniqId::new(),
994 sleep_prov: runtime,
995 memquota: fake_mq(),
996 }
997 }
998
999 fn cert_timestamp() -> SystemTime {
1001 use humantime::parse_rfc3339;
1002 parse_rfc3339("2020-09-26T18:01:20Z").unwrap()
1003 }
1004
1005 fn certs_test<R>(
1006 certs: msg::Certs,
1007 when: Option<SystemTime>,
1008 peer_ed: &[u8],
1009 peer_rsa: &[u8],
1010 peer_cert_sha256: &[u8],
1011 runtime: &R,
1012 ) -> Result<VerifiedChannel<MsgBuf, R>>
1013 where
1014 R: Runtime,
1015 {
1016 let unver = make_unverified(certs, runtime.clone());
1017 let ed = Ed25519Identity::from_bytes(peer_ed).unwrap();
1018 let rsa = RsaIdentity::from_bytes(peer_rsa).unwrap();
1019 let chan = OwnedChanTarget::builder()
1020 .ed_identity(ed)
1021 .rsa_identity(rsa)
1022 .build()
1023 .unwrap();
1024 unver.check_internal(&chan, peer_cert_sha256, when)
1025 }
1026
1027 #[test]
1029 fn certs_none() {
1030 let rt = PreferredRuntime::create().unwrap();
1031 let err = certs_test(
1032 msg::Certs::new_empty(),
1033 None,
1034 &[0_u8; 32],
1035 &[0_u8; 20],
1036 &[0_u8; 128],
1037 &rt,
1038 )
1039 .err()
1040 .unwrap();
1041 assert_eq!(
1042 format!("{}", err),
1043 "Handshake protocol violation: Missing IDENTITY_V_SIGNING certificate"
1044 );
1045 }
1046
1047 #[test]
1048 fn certs_good() {
1049 let rt = PreferredRuntime::create().unwrap();
1050 let mut certs = msg::Certs::new_empty();
1051
1052 certs.push_cert_body(2.into(), certs::CERT_T2);
1053 certs.push_cert_body(5.into(), certs::CERT_T5);
1054 certs.push_cert_body(7.into(), certs::CERT_T7);
1055 certs.push_cert_body(4.into(), certs::CERT_T4);
1056 let res = certs_test(
1057 certs,
1058 Some(cert_timestamp()),
1059 certs::PEER_ED,
1060 certs::PEER_RSA,
1061 certs::PEER_CERT_DIGEST,
1062 &rt,
1063 );
1064 let _ = res.unwrap();
1065 }
1066
1067 #[test]
1068 fn certs_missing() {
1069 let rt = PreferredRuntime::create().unwrap();
1070 let all_certs = [
1071 (2, certs::CERT_T2, "Couldn't find RSA identity key"),
1072 (7, certs::CERT_T7, "No RSA->Ed crosscert"),
1073 (4, certs::CERT_T4, "Missing IDENTITY_V_SIGNING certificate"),
1074 (5, certs::CERT_T5, "Missing SIGNING_V_TLS_CERT certificate"),
1075 ];
1076
1077 for omit_idx in 0..4 {
1078 let mut certs = msg::Certs::new_empty();
1080 let mut expect_err = None;
1081 for (idx, (ctype, cert, err)) in all_certs.iter().enumerate() {
1082 if idx == omit_idx {
1083 expect_err = Some(err);
1084 continue;
1085 }
1086
1087 certs.push_cert_body((*ctype).into(), &cert[..]);
1088 }
1089 let res = certs_test(
1090 certs,
1091 Some(cert_timestamp()),
1092 certs::PEER_ED,
1093 certs::PEER_RSA,
1094 certs::PEER_CERT_DIGEST,
1095 &rt,
1096 )
1097 .err()
1098 .unwrap();
1099
1100 assert_eq!(
1101 format!("{}", res),
1102 format!("Handshake protocol violation: {}", expect_err.unwrap())
1103 );
1104 }
1105 }
1106
1107 #[test]
1108 fn certs_wrongtarget() {
1109 let rt = PreferredRuntime::create().unwrap();
1110 let mut certs = msg::Certs::new_empty();
1111 certs.push_cert_body(2.into(), certs::CERT_T2);
1112 certs.push_cert_body(5.into(), certs::CERT_T5);
1113 certs.push_cert_body(7.into(), certs::CERT_T7);
1114 certs.push_cert_body(4.into(), certs::CERT_T4);
1115 let err = certs_test(
1116 certs.clone(),
1117 Some(cert_timestamp()),
1118 &[0x10; 32],
1119 certs::PEER_RSA,
1120 certs::PEER_CERT_DIGEST,
1121 &rt,
1122 )
1123 .err()
1124 .unwrap();
1125
1126 let re = Regex::new(
1127 r"Identity .* does not match target .*",
1129 )
1130 .unwrap();
1131 assert!(re.is_match(&format!("{}", err)));
1132
1133 let err = certs_test(
1134 certs.clone(),
1135 Some(cert_timestamp()),
1136 certs::PEER_ED,
1137 &[0x99; 20],
1138 certs::PEER_CERT_DIGEST,
1139 &rt,
1140 )
1141 .err()
1142 .unwrap();
1143
1144 let re = Regex::new(
1145 r"Identity .* does not match target .*",
1147 )
1148 .unwrap();
1149 assert!(re.is_match(&format!("{}", err)));
1150
1151 let err = certs_test(
1152 certs,
1153 Some(cert_timestamp()),
1154 certs::PEER_ED,
1155 certs::PEER_RSA,
1156 &[0; 32],
1157 &rt,
1158 )
1159 .err()
1160 .unwrap();
1161
1162 assert_eq!(
1163 format!("{}", err),
1164 "Handshake protocol violation: Peer cert did not authenticate TLS cert"
1165 );
1166 }
1167
1168 #[test]
1169 fn certs_badsig() {
1170 let rt = PreferredRuntime::create().unwrap();
1171 fn munge(inp: &[u8]) -> Vec<u8> {
1172 let mut v: Vec<u8> = inp.into();
1173 v[inp.len() - 1] ^= 0x10;
1174 v
1175 }
1176 let mut certs = msg::Certs::new_empty();
1177 certs.push_cert_body(2.into(), certs::CERT_T2);
1178 certs.push_cert_body(5.into(), munge(certs::CERT_T5)); certs.push_cert_body(7.into(), certs::CERT_T7);
1180 certs.push_cert_body(4.into(), certs::CERT_T4);
1181 let res = certs_test(
1182 certs,
1183 Some(cert_timestamp()),
1184 certs::PEER_ED,
1185 certs::PEER_RSA,
1186 certs::PEER_CERT_DIGEST,
1187 &rt,
1188 )
1189 .err()
1190 .unwrap();
1191
1192 assert_eq!(
1193 format!("{}", res),
1194 "Handshake protocol violation: Invalid ed25519 signature in handshake"
1195 );
1196
1197 let mut certs = msg::Certs::new_empty();
1198 certs.push_cert_body(2.into(), certs::CERT_T2);
1199 certs.push_cert_body(5.into(), certs::CERT_T5);
1200 certs.push_cert_body(7.into(), munge(certs::CERT_T7)); certs.push_cert_body(4.into(), certs::CERT_T4);
1202 let res = certs_test(
1203 certs,
1204 Some(cert_timestamp()),
1205 certs::PEER_ED,
1206 certs::PEER_RSA,
1207 certs::PEER_CERT_DIGEST,
1208 &rt,
1209 )
1210 .err()
1211 .unwrap();
1212
1213 assert_eq!(
1214 format!("{}", res),
1215 "Handshake protocol violation: Bad RSA->Ed crosscert signature"
1216 );
1217 }
1218
1219 mod certs {
1225 use hex_literal::hex;
1226
1227 pub(crate) const CERT_T2: &[u8] = &hex!(
1228 "308201B930820122A0030201020208607C28BE6C390943300D06092A864886F70D01010B0500301F311D301B06035504030C147777772E74636A76356B766A646472322E636F6D301E170D3230303831303030303030305A170D3231303831303030303030305A301F311D301B06035504030C147777772E74636A76356B766A646472322E636F6D30819F300D06092A864886F70D010101050003818D0030818902818100D38B1E6CEB946E0DB0751F4CBACE3DCB9688B6C25304227B4710C35AFB73627E50500F5913E158B621802612D1C75827003703338375237552EB3CD3C12F6AB3604E60C1A2D26BB1FBAD206FF023969A90909D6A65A5458A5312C26EBD3A3DAD30302D4515CDCD264146AC18E6FC60A04BD3EC327F04294D96BA5AA25B464C3F0203010001300D06092A864886F70D01010B0500038181003BCE561EA7F95CC00B78AAB5D69573FF301C282A751D4A651921D042F1BECDBA24D918A6D8A5E138DC07BBA0B335478AE37ABD2C93A93932442AE9084329E846170FE0FC4A50AAFC804F311CC3CA4F41D845A7BA5901CBBC3E021E9794AAC70CE1F37B0A951592DB1B64F2B4AFB81AE52DBD9B6FEDE96A5FB8125EB6251EE50A"
1229 );
1230
1231 pub(crate) const CERT_T4: &[u8] = &hex!(
1232 "01040006CC2A01F82294B866A31F01FC5D0DA8572850A9B929545C3266558D7D2316E3B74172B00100200400DCB604DB2034B00FD16986D4ADB9D16B21CB4E4457A33DEC0F538903683E96E9FF1A5203FA27F86EF7528D89A0845D2520166E340754FFEA2AAE0F612B7CE5DA094A0236CDAC45034B0B6842C18E7F6B51B93A3CF7E60663B8AD061C30A62602"
1233 );
1234 pub(crate) const CERT_T5: &[u8] = &hex!(
1235 "01050006C98A03B4FD606B64E4CBD466B8D76CB131069BAE6F3AA1878857C9F624E31D77A799B8007173E5F8068431D0D3F5EE16B4C9FFD59DF373E152A87281BAE744AA5FCF72171BF4B27C4E8FC1C6A9FC5CA11058BC49647063D7903CFD9F512F89099B27BC0C"
1236 );
1237
1238 pub(crate) const CERT_T7: &[u8] = &hex!(
1239 "DCB604DB2034B00FD16986D4ADB9D16B21CB4E4457A33DEC0F538903683E96E90006DA3A805CF6006F9179066534DE6B45AD47A5C469063EE462762723396DC9F25452A0A52DA3F5087DD239F2A311F6B0D4DFEFF4ABD089DC3D0237A0ABAB19EB2045B91CDCAF04BE0A72D548A27BF2E77BD876ECFE5E1BE622350DA6BF31F6E306ED896488DD5B39409B23FC3EB7B2C9F7328EB18DA36D54D80575899EA6507CCBFCDF1F"
1240 );
1241
1242 pub(crate) const PEER_CERT_DIGEST: &[u8] =
1243 &hex!("b4fd606b64e4cbd466b8d76cb131069bae6f3aa1878857c9f624e31d77a799b8");
1244
1245 pub(crate) const PEER_ED: &[u8] =
1246 &hex!("dcb604db2034b00fd16986d4adb9d16b21cb4e4457a33dec0f538903683e96e9");
1247 pub(crate) const PEER_RSA: &[u8] = &hex!("2f1fb49bb332a9eec617e41e911c33fb3890aef3");
1248 }
1249
1250 #[test]
1251 fn test_finish() {
1252 tor_rtcompat::test_with_one_runtime!(|rt| async move {
1253 let ed25519_id = [3_u8; 32].into();
1254 let rsa_id = [4_u8; 20].into();
1255 let peer_addr = "127.1.1.2:443".parse().unwrap();
1256 let mut framed_tls = new_frame(MsgBuf::new(&b""[..]), ChannelType::ClientInitiator);
1257 let _ = framed_tls.codec_mut().set_link_version(4);
1258 let ver = VerifiedChannel {
1259 channel_type: ChannelType::ClientInitiator,
1260 link_protocol: 4,
1261 framed_tls,
1262 unique_id: UniqId::new(),
1263 target_method: Some(ChannelMethod::Direct(vec![peer_addr])),
1264 ed25519_id,
1265 rsa_id,
1266 clock_skew: ClockSkew::None,
1267 sleep_prov: rt,
1268 memquota: fake_mq(),
1269 };
1270
1271 let (_chan, _reactor) = ver.finish().await.unwrap();
1272
1273 });
1275 }
1276}