1use futures::SinkExt;
4use futures::io::{AsyncRead, AsyncWrite};
5use rand::Rng;
6use safelog::Sensitive;
7use std::net::{IpAddr, SocketAddr};
8use std::{sync::Arc, time::SystemTime};
9use tracing::trace;
10
11use tor_cell::chancell::msg;
12use tor_cell::restrict::restricted_msg;
13use tor_error::internal;
14use tor_linkspec::{ChannelMethod, HasChanMethod, OwnedChanTarget};
15use tor_rtcompat::{CertifiedConn, CoarseTimeProvider, SleepProvider, StreamOps};
16
17use crate::Result;
18use crate::channel::handshake::{
19 AuthLogAction, ChannelBaseHandshake, ChannelInitiatorHandshake, UnverifiedChannel,
20 UnverifiedInitiatorChannel, read_msg, unauthenticated_clock_skew,
21};
22use crate::channel::{ChannelFrame, ChannelType, ClogDigest, SlogDigest, UniqId, new_frame};
23use crate::memquota::ChannelAccount;
24use crate::peer::PeerAddr;
25use crate::relay::CreateRequestHandler;
26use crate::relay::channel::initiator::UnverifiedInitiatorRelayChannel;
27use crate::relay::channel::responder::{
28 MaybeVerifiableRelayResponderChannel, NonVerifiableResponderRelayChannel,
29 UnverifiedResponderRelayChannel,
30};
31use crate::relay::channel::{RelayChannelAuthMaterial, build_certs_cell, build_netinfo_cell};
32
33pub(super) static AUTHTYPE_ED25519_SHA256_RFC5705: u16 = 3;
35
36pub struct RelayInitiatorHandshake<
38 T: AsyncRead + AsyncWrite + CertifiedConn + StreamOps + Send + Unpin + 'static,
39 S: CoarseTimeProvider + SleepProvider,
40> {
41 sleep_prov: S,
43 memquota: ChannelAccount,
45 framed_tls: ChannelFrame<T>,
50 unique_id: UniqId,
52 auth_material: Arc<RelayChannelAuthMaterial>,
54 target_method: ChannelMethod,
56 my_addrs: Vec<IpAddr>,
58 create_request_handler: Arc<CreateRequestHandler>,
60}
61
62impl<T, S> ChannelBaseHandshake<T> for RelayInitiatorHandshake<T, S>
64where
65 T: AsyncRead + AsyncWrite + CertifiedConn + StreamOps + Send + Unpin + 'static,
66 S: CoarseTimeProvider + SleepProvider,
67{
68 fn framed_tls(&mut self) -> &mut ChannelFrame<T> {
69 &mut self.framed_tls
70 }
71 fn unique_id(&self) -> &UniqId {
72 &self.unique_id
73 }
74}
75
76impl<T, S> ChannelInitiatorHandshake<T> for RelayInitiatorHandshake<T, S>
78where
79 T: AsyncRead + AsyncWrite + CertifiedConn + StreamOps + Send + Unpin + 'static,
80 S: CoarseTimeProvider + SleepProvider,
81{
82}
83
84impl<
85 T: AsyncRead + AsyncWrite + CertifiedConn + StreamOps + Send + Unpin + 'static,
86 S: CoarseTimeProvider + SleepProvider,
87> RelayInitiatorHandshake<T, S>
88{
89 pub(crate) fn new(
91 tls: T,
92 sleep_prov: S,
93 auth_material: Arc<RelayChannelAuthMaterial>,
94 my_addrs: Vec<SocketAddr>,
95 peer_target: &OwnedChanTarget,
96 memquota: ChannelAccount,
97 create_request_handler: Arc<CreateRequestHandler>,
98 ) -> Self {
99 Self {
100 framed_tls: new_frame(tls, ChannelType::RelayInitiator),
101 unique_id: UniqId::new(),
102 sleep_prov,
103 auth_material,
104 memquota,
105 my_addrs: my_addrs.into_iter().map(|a| a.ip()).collect(),
106 target_method: peer_target.chan_method(),
107 create_request_handler,
108 }
109 }
110
111 pub async fn connect<F>(mut self, now_fn: F) -> Result<UnverifiedInitiatorRelayChannel<T, S>>
116 where
117 F: FnOnce() -> SystemTime,
118 {
119 let (versions_flushed_at, versions_flushed_wallclock) =
121 self.send_versions_cell(now_fn).await?;
122
123 let link_protocol = self.recv_versions_cell().await?;
125
126 self.set_link_protocol(link_protocol)?;
128
129 let (auth_challenge_cell, certs_cell, (netinfo_cell, netinfo_rcvd_at), slog_digest) =
131 self.recv_cells_from_responder(AuthLogAction::Take).await?;
132
133 let slog_digest = slog_digest.ok_or(internal!("Asked for SLOG, but `None` returned?"))?;
135
136 trace!(stream_id = %self.unique_id,
137 "received handshake, ready to verify.",
138 );
139
140 let clock_skew = unauthenticated_clock_skew(
142 &netinfo_cell,
143 netinfo_rcvd_at,
144 versions_flushed_at,
145 versions_flushed_wallclock,
146 );
147
148 Ok(UnverifiedInitiatorRelayChannel {
149 inner: UnverifiedInitiatorChannel {
150 inner: UnverifiedChannel {
151 link_protocol,
152 framed_tls: self.framed_tls,
153 clock_skew,
154 memquota: self.memquota,
155 target_method: Some(self.target_method),
156 unique_id: self.unique_id,
157 sleep_prov: self.sleep_prov.clone(),
158 },
159 certs_cell,
160 },
161 auth_challenge_cell,
162 slog_digest,
163 netinfo_cell,
164 auth_material: self.auth_material,
165 my_addrs: self.my_addrs,
166 create_request_handler: self.create_request_handler,
167 })
168 }
169}
170
171pub struct RelayResponderHandshake<
173 T: AsyncRead + AsyncWrite + CertifiedConn + StreamOps + Send + Unpin + 'static,
174 S: CoarseTimeProvider + SleepProvider,
175> {
176 sleep_prov: S,
178 memquota: ChannelAccount,
180 framed_tls: ChannelFrame<T>,
185 peer_addr: Sensitive<PeerAddr>,
188 my_addrs: Vec<IpAddr>,
190 unique_id: UniqId,
192 auth_material: Arc<RelayChannelAuthMaterial>,
194 create_request_handler: Arc<CreateRequestHandler>,
196}
197
198impl<T, S> ChannelBaseHandshake<T> for RelayResponderHandshake<T, S>
200where
201 T: AsyncRead + AsyncWrite + CertifiedConn + StreamOps + Send + Unpin + 'static,
202 S: CoarseTimeProvider + SleepProvider,
203{
204 fn framed_tls(&mut self) -> &mut ChannelFrame<T> {
205 &mut self.framed_tls
206 }
207 fn unique_id(&self) -> &UniqId {
208 &self.unique_id
209 }
210}
211
212impl<
213 T: AsyncRead + AsyncWrite + CertifiedConn + StreamOps + Send + Unpin + 'static,
214 S: CoarseTimeProvider + SleepProvider,
215> RelayResponderHandshake<T, S>
216{
217 pub(crate) fn new(
219 peer_addr: Sensitive<PeerAddr>,
220 my_addrs: Vec<SocketAddr>,
221 tls: T,
222 sleep_prov: S,
223 auth_material: Arc<RelayChannelAuthMaterial>,
224 memquota: ChannelAccount,
225 create_request_handler: Arc<CreateRequestHandler>,
226 ) -> Self {
227 Self {
228 peer_addr,
229 my_addrs: my_addrs.into_iter().map(|a| a.ip()).collect(),
230 framed_tls: new_frame(
231 tls,
232 ChannelType::RelayResponder {
233 authenticated: false,
234 },
235 ),
236 unique_id: UniqId::new(),
237 sleep_prov,
238 auth_material,
239 memquota,
240 create_request_handler,
241 }
242 }
243
244 pub async fn handshake<F>(
249 mut self,
250 now_fn: F,
251 ) -> Result<MaybeVerifiableRelayResponderChannel<T, S>>
252 where
253 F: FnOnce() -> SystemTime,
254 {
255 let link_protocol = self.recv_versions_cell().await?;
257
258 let (versions_flushed_at, versions_flushed_wallclock) =
260 self.send_versions_cell(now_fn).await?;
261
262 self.set_link_protocol(link_protocol)?;
264
265 let slog_digest = self.send_cells_to_initiator().await?;
267
268 let (certs_and_auth_and_clog, (netinfo_cell, netinfo_rcvd_at)) =
271 self.recv_cells_from_initiator().await?;
272
273 let (certs_cell, auth_and_clog) = match certs_and_auth_and_clog {
275 Some((certs, auth, clog)) => (Some(certs), Some((auth, clog))),
276 None => (None, None),
277 };
278
279 let clock_skew = unauthenticated_clock_skew(
281 &netinfo_cell,
282 netinfo_rcvd_at,
283 versions_flushed_at,
284 versions_flushed_wallclock,
285 );
286
287 let inner = UnverifiedChannel {
288 link_protocol,
289 framed_tls: self.framed_tls,
290 clock_skew,
291 memquota: self.memquota,
292 target_method: None,
293 unique_id: self.unique_id,
294 sleep_prov: self.sleep_prov,
295 };
296
297 Ok(match auth_and_clog {
299 Some((auth_cell, clog_digest)) => {
300 MaybeVerifiableRelayResponderChannel::Verifiable(UnverifiedResponderRelayChannel {
301 inner,
302 auth_cell,
303 netinfo_cell,
304 certs_cell: certs_cell.expect("AUTHENTICATE cell without CERTS cell"),
306 auth_material: self.auth_material,
307 my_addrs: self.my_addrs,
308 peer_addr: self.peer_addr.into_inner(), clog_digest,
310 slog_digest,
311 create_request_handler: self.create_request_handler,
312 })
313 }
314 None => MaybeVerifiableRelayResponderChannel::NonVerifiable(
315 NonVerifiableResponderRelayChannel {
316 inner,
317 netinfo_cell,
318 my_addrs: self.my_addrs,
319 peer_addr: self.peer_addr,
320 create_request_handler: self.create_request_handler,
321 our_ed25519_id: self.auth_material.ed_id,
322 our_rsa_id: self.auth_material.rsa_id,
323 },
324 ),
325 })
326 }
327
328 async fn recv_cells_from_initiator(
331 &mut self,
332 ) -> Result<(
333 Option<(msg::Certs, msg::Authenticate, ClogDigest)>,
334 (msg::Netinfo, coarsetime::Instant),
335 )> {
336 let (certs_and_auth_and_clog, netinfo, netinfo_rcvd_at) = 'outer: {
346 let certs = loop {
348 restricted_msg! {
349 enum CertsNetinfoMsg : ChanMsg {
350 Vpadding,
352 Netinfo,
353 Certs,
354 }
355 }
356
357 break match read_msg(*self.unique_id(), self.framed_tls()).await? {
358 CertsNetinfoMsg::Vpadding(_) => continue,
359 CertsNetinfoMsg::Netinfo(msg) => {
361 break 'outer (None, msg, coarsetime::Instant::now());
362 }
363 CertsNetinfoMsg::Certs(msg) => msg,
365 };
366 };
367
368 let clog_digest =
370 ClogDigest::new(self.framed_tls().codec_mut().take_recv_log_digest()?);
371
372 let auth = loop {
374 restricted_msg! {
375 enum AuthenticateMsg : ChanMsg {
376 Vpadding,
378 Authenticate,
379 }
380 }
381
382 break match read_msg(*self.unique_id(), self.framed_tls()).await? {
383 AuthenticateMsg::Vpadding(_) => continue,
384 AuthenticateMsg::Authenticate(msg) => msg,
385 };
386 };
387
388 let (netinfo, netinfo_rcvd_at) = loop {
390 restricted_msg! {
391 enum NetinfoMsg : ChanMsg {
392 Vpadding,
394 Netinfo,
395 }
396 }
397
398 break match read_msg(*self.unique_id(), self.framed_tls()).await? {
399 NetinfoMsg::Vpadding(_) => continue,
400 NetinfoMsg::Netinfo(msg) => (msg, coarsetime::Instant::now()),
401 };
402 };
403
404 (Some((certs, auth, clog_digest)), netinfo, netinfo_rcvd_at)
405 };
406
407 Ok((certs_and_auth_and_clog, (netinfo, netinfo_rcvd_at)))
408 }
409
410 async fn send_cells_to_initiator(&mut self) -> Result<SlogDigest> {
415 let certs = build_certs_cell(&self.auth_material, true);
417 trace!(channel_id = %self.unique_id, "Sending CERTS as responder cell.");
418 self.framed_tls.send(certs.into()).await?;
419
420 let challenge: [u8; 32] = rand::rng().random();
422 let auth_challenge = msg::AuthChallenge::new(challenge, [AUTHTYPE_ED25519_SHA256_RFC5705]);
423 trace!(channel_id = %self.unique_id, "Sending AUTH_CHALLENGE as responder cell.");
424 self.framed_tls.send(auth_challenge.into()).await?;
425
426 let slog_digest = SlogDigest::new(self.framed_tls.codec_mut().take_send_log_digest()?);
428
429 let peer_ip = self.peer_addr.netinfo_addr();
431 let netinfo = build_netinfo_cell(peer_ip, self.my_addrs.clone(), &self.sleep_prov)?;
432 trace!(channel_id = %self.unique_id, "Sending NETINFO as responder cell.");
433 self.framed_tls.send(netinfo.into()).await?;
434
435 Ok(slog_digest)
436 }
437}