tor_proto/client/channel/
handshake.rs1use digest::Digest;
4use futures::SinkExt;
5use futures::io::{AsyncRead, AsyncWrite};
6use std::sync::Arc;
7use std::time::SystemTime;
8use tracing::{debug, instrument, trace};
9
10use safelog::MaybeSensitive;
11use tor_cell::chancell::msg;
12use tor_linkspec::{ChannelMethod, OwnedChanTarget};
13use tor_rtcompat::{CoarseTimeProvider, Runtime, SleepProvider, StreamOps};
14
15use crate::ClockSkew;
16use crate::Result;
17use crate::channel::handshake::{
18 AuthLogAction, ChannelBaseHandshake, ChannelInitiatorHandshake, UnverifiedChannel,
19 UnverifiedInitiatorChannel, VerifiedChannel, unauthenticated_clock_skew,
20};
21use crate::channel::{Channel, ChannelFrame, ChannelMode, ChannelType, Reactor, UniqId, new_frame};
22use crate::memquota::ChannelAccount;
23use crate::peer::{PeerAddr, PeerInfo};
24
25pub struct ClientInitiatorHandshake<
27 T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
28 S: CoarseTimeProvider + SleepProvider,
29> {
30 sleep_prov: S,
32
33 memquota: ChannelAccount,
35
36 framed_tls: ChannelFrame<T>,
41
42 target_method: Option<ChannelMethod>,
44
45 unique_id: UniqId,
47}
48
49impl<T, S> ChannelBaseHandshake<T> for ClientInitiatorHandshake<T, S>
51where
52 T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
53 S: CoarseTimeProvider + SleepProvider,
54{
55 fn framed_tls(&mut self) -> &mut ChannelFrame<T> {
56 &mut self.framed_tls
57 }
58 fn unique_id(&self) -> &UniqId {
59 &self.unique_id
60 }
61}
62
63impl<T, S> ChannelInitiatorHandshake<T> for ClientInitiatorHandshake<T, S>
65where
66 T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
67 S: CoarseTimeProvider + SleepProvider,
68{
69}
70
71impl<
72 T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
73 S: CoarseTimeProvider + SleepProvider,
74> ClientInitiatorHandshake<T, S>
75{
76 pub(crate) fn new(
78 tls: T,
79 target_method: Option<ChannelMethod>,
80 sleep_prov: S,
81 memquota: ChannelAccount,
82 ) -> Self {
83 Self {
84 framed_tls: new_frame(tls, ChannelType::ClientInitiator),
85 target_method,
86 unique_id: UniqId::new(),
87 sleep_prov,
88 memquota,
89 }
90 }
91
92 #[instrument(skip_all, level = "trace")]
98 pub async fn connect<F>(mut self, now_fn: F) -> Result<UnverifiedClientChannel<T, S>>
99 where
100 F: FnOnce() -> SystemTime,
101 {
102 match &self.target_method {
103 Some(method) => debug!(
104 stream_id = %self.unique_id,
105 "starting Tor handshake with {:?}",
106 method
107 ),
108 None => debug!(stream_id = %self.unique_id, "starting Tor handshake"),
109 }
110 let (versions_flushed_at, versions_flushed_wallclock) =
112 self.send_versions_cell(now_fn).await?;
113
114 let link_protocol = self.recv_versions_cell().await?;
116
117 self.set_link_protocol(link_protocol)?;
119
120 let (_auth_chal_cell, certs_cell, (netinfo_cell, netinfo_rcvd_at), _slog) =
123 self.recv_cells_from_responder(AuthLogAction::Leave).await?;
124
125 let clock_skew = unauthenticated_clock_skew(
127 &netinfo_cell,
128 netinfo_rcvd_at,
129 versions_flushed_at,
130 versions_flushed_wallclock,
131 );
132
133 trace!(stream_id = %self.unique_id, "received handshake, ready to verify.");
134
135 Ok(UnverifiedClientChannel {
136 inner: UnverifiedInitiatorChannel {
137 inner: UnverifiedChannel {
138 link_protocol,
139 framed_tls: self.framed_tls,
140 clock_skew,
141 target_method: self.target_method.take(),
142 unique_id: self.unique_id,
143 sleep_prov: self.sleep_prov.clone(),
144 memquota: self.memquota.clone(),
145 },
146 certs_cell,
147 },
148 netinfo_cell,
149 })
150 }
151}
152
153pub struct UnverifiedClientChannel<
156 T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
157 S: CoarseTimeProvider + SleepProvider,
158> {
159 inner: UnverifiedInitiatorChannel<T, S>,
161 netinfo_cell: msg::Netinfo,
163}
164
165impl<
166 T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
167 S: CoarseTimeProvider + SleepProvider,
168> UnverifiedClientChannel<T, S>
169{
170 #[instrument(skip_all, level = "trace")]
185 pub fn verify(
186 self,
187 peer_target: &OwnedChanTarget,
188 peer_tls_cert: &[u8],
189 now: Option<std::time::SystemTime>,
190 ) -> Result<VerifiedClientChannel<T, S>> {
191 let peer_cert_digest = tor_llcrypto::d::Sha256::digest(peer_tls_cert).into();
192 let inner = self.inner.verify(peer_target, peer_cert_digest, now)?;
193
194 Ok(VerifiedClientChannel {
195 inner,
196 netinfo_cell: self.netinfo_cell,
197 })
198 }
199
200 pub fn clock_skew(&self) -> ClockSkew {
202 self.inner.inner.clock_skew
203 }
204
205 #[cfg(test)]
207 pub(crate) fn link_protocol(&self) -> u16 {
208 self.inner.inner.link_protocol
209 }
210}
211
212pub struct VerifiedClientChannel<
218 T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
219 S: CoarseTimeProvider + SleepProvider,
220> {
221 inner: VerifiedChannel<T, S>,
223 netinfo_cell: msg::Netinfo,
225}
226
227impl<
228 T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
229 S: CoarseTimeProvider + SleepProvider,
230> VerifiedClientChannel<T, S>
231{
232 #[instrument(skip_all, level = "trace")]
240 pub async fn finish(
241 mut self,
242 peer_addr: MaybeSensitive<PeerAddr>,
243 ) -> Result<(Arc<Channel>, Reactor<S>)>
244 where
245 S: Runtime,
246 {
247 let netinfo = msg::Netinfo::from_client(peer_addr.netinfo_addr());
249 trace!(stream_id = %self.inner.unique_id, "Sending netinfo cell.");
250 self.inner.framed_tls.send(netinfo.into()).await?;
251
252 let peer_info = MaybeSensitive::sensitive(PeerInfo::new(
254 peer_addr.inner(),
255 self.inner.relay_ids().clone(),
256 ));
257
258 self.inner
260 .finish(&self.netinfo_cell, &[], peer_info, ChannelMode::Client)
261 .await
262 }
263}
264
265#[cfg(test)]
266pub(crate) mod test {
267 #![allow(clippy::unwrap_used)]
268 use tor_linkspec::RelayIds;
269
270 use super::*;
271 use crate::channel::handler::test::MsgBuf;
272 use crate::channel::{ChannelType, new_frame};
273 use crate::util::fake_mq;
274 use tor_cell::chancell::msg::Netinfo;
275
276 #[test]
277 fn test_finish() {
278 tor_rtcompat::test_with_one_runtime!(|rt| async move {
279 let peer_addr = "127.1.1.2:443".parse().unwrap();
280 let mut framed_tls = new_frame(MsgBuf::new(&b""[..]), ChannelType::ClientInitiator);
281 let _ = framed_tls.codec_mut().set_link_version(4);
282 let ver = VerifiedChannel {
283 link_protocol: 4,
284 framed_tls,
285 unique_id: UniqId::new(),
286 target_method: Some(ChannelMethod::Direct(vec![peer_addr])),
287 peer_relay_ids: RelayIds::empty(),
288 peer_rsa_id_digest: [0; 32],
289 clock_skew: ClockSkew::None,
290 sleep_prov: rt,
291 memquota: fake_mq(),
292 };
293
294 let peer_ip = peer_addr.ip();
295 let netinfo = Netinfo::from_client(Some(peer_ip));
296
297 let (_chan, _reactor) = ver
298 .finish(
299 &netinfo,
300 &[],
301 MaybeSensitive::not_sensitive(PeerInfo::EMPTY),
302 ChannelMode::Client,
303 )
304 .await
305 .unwrap();
306
307 });
309 }
310}