1
//! Implementations for the relay channel handshake
2

            
3
use futures::SinkExt;
4
use futures::io::{AsyncRead, AsyncWrite};
5
use rand::RngExt;
6
use safelog::Sensitive;
7
use std::net::{IpAddr, SocketAddr};
8
use std::{sync::Arc, time::SystemTime};
9
use tracing::trace;
10

            
11
use tor_cell::chancell::msg;
12
use tor_cell::restrict::restricted_msg;
13
use tor_error::internal;
14
use tor_linkspec::{ChannelMethod, HasChanMethod, OwnedChanTarget};
15
use tor_rtcompat::{CertifiedConn, CoarseTimeProvider, SleepProvider, StreamOps};
16

            
17
use crate::Result;
18
use crate::channel::handshake::{
19
    AuthLogAction, ChannelBaseHandshake, ChannelInitiatorHandshake, UnverifiedChannel,
20
    UnverifiedInitiatorChannel, read_msg, unauthenticated_clock_skew,
21
};
22
use crate::channel::{ChannelFrame, ChannelType, ClogDigest, SlogDigest, UniqId, new_frame};
23
use crate::memquota::ChannelAccount;
24
use crate::peer::PeerAddr;
25
use crate::relay::CreateRequestHandler;
26
use crate::relay::channel::initiator::UnverifiedInitiatorRelayChannel;
27
use crate::relay::channel::responder::{
28
    MaybeVerifiableRelayResponderChannel, NonVerifiableResponderRelayChannel,
29
    UnverifiedResponderRelayChannel,
30
};
31
use crate::relay::channel::{RelayChannelAuthMaterial, build_certs_cell, build_netinfo_cell};
32

            
33
/// The "Ed25519-SHA256-RFC5705" link authentication which is value "00 03".
34
pub(super) static AUTHTYPE_ED25519_SHA256_RFC5705: u16 = 3;
35

            
36
/// A relay channel handshake as the initiator.
37
pub struct RelayInitiatorHandshake<
38
    T: AsyncRead + AsyncWrite + CertifiedConn + StreamOps + Send + Unpin + 'static,
39
    S: CoarseTimeProvider + SleepProvider,
40
> {
41
    /// Runtime handle (insofar as we need it)
42
    sleep_prov: S,
43
    /// Memory quota account
44
    memquota: ChannelAccount,
45
    /// Underlying TLS stream in a channel frame.
46
    ///
47
    /// (We don't enforce that this is actually TLS, but if it isn't, the
48
    /// connection won't be secure.)
49
    framed_tls: ChannelFrame<T>,
50
    /// Logging identifier for this stream.  (Used for logging only.)
51
    unique_id: UniqId,
52
    /// Our identity keys needed for authentication.
53
    auth_material: Arc<RelayChannelAuthMaterial>,
54
    /// The peer we are attempting to connect to.
55
    target_method: ChannelMethod,
56
    /// Our advertised addresses. Needed for the NETINFO.
57
    my_addrs: Vec<IpAddr>,
58
    /// Provided to each new channel so that they can handle CREATE* requests.
59
    create_request_handler: Arc<CreateRequestHandler>,
60
}
61

            
62
/// Implement the base channel handshake trait.
63
impl<T, S> ChannelBaseHandshake<T> for RelayInitiatorHandshake<T, S>
64
where
65
    T: AsyncRead + AsyncWrite + CertifiedConn + StreamOps + Send + Unpin + 'static,
66
    S: CoarseTimeProvider + SleepProvider,
67
{
68
58
    fn framed_tls(&mut self) -> &mut ChannelFrame<T> {
69
58
        &mut self.framed_tls
70
58
    }
71
64
    fn unique_id(&self) -> &UniqId {
72
64
        &self.unique_id
73
64
    }
74
}
75

            
76
/// Implement the initiator channel handshake trait.
77
impl<T, S> ChannelInitiatorHandshake<T> for RelayInitiatorHandshake<T, S>
78
where
79
    T: AsyncRead + AsyncWrite + CertifiedConn + StreamOps + Send + Unpin + 'static,
80
    S: CoarseTimeProvider + SleepProvider,
81
{
82
}
83

            
84
impl<
85
    T: AsyncRead + AsyncWrite + CertifiedConn + StreamOps + Send + Unpin + 'static,
86
    S: CoarseTimeProvider + SleepProvider,
87
> RelayInitiatorHandshake<T, S>
88
{
89
    /// Constructor.
90
11
    pub(crate) fn new(
91
11
        tls: T,
92
11
        sleep_prov: S,
93
11
        auth_material: Arc<RelayChannelAuthMaterial>,
94
11
        my_addrs: Vec<SocketAddr>,
95
11
        peer_target: &OwnedChanTarget,
96
11
        memquota: ChannelAccount,
97
11
        create_request_handler: Arc<CreateRequestHandler>,
98
11
    ) -> Self {
99
        Self {
100
11
            framed_tls: new_frame(tls, ChannelType::RelayInitiator),
101
11
            unique_id: UniqId::new(),
102
11
            sleep_prov,
103
11
            auth_material,
104
11
            memquota,
105
11
            my_addrs: my_addrs.into_iter().map(|a| a.ip()).collect(),
106
11
            target_method: peer_target.chan_method(),
107
11
            create_request_handler,
108
        }
109
11
    }
110

            
111
    /// Connect to another relay as the relay Initiator.
112
    ///
113
    /// Takes a function that reports the current time.  In theory, this can just be
114
    /// `SystemTime::get()`.
115
11
    pub async fn connect<F>(mut self, now_fn: F) -> Result<UnverifiedInitiatorRelayChannel<T, S>>
116
11
    where
117
11
        F: FnOnce() -> SystemTime,
118
11
    {
119
        // Send the VERSIONS.
120
11
        let (versions_flushed_at, versions_flushed_wallclock) =
121
11
            self.send_versions_cell(now_fn).await?;
122

            
123
        // Receive the VERSIONS.
124
11
        let link_protocol = self.recv_versions_cell().await?;
125

            
126
        // VERSIONS cell have been exchanged, set the link protocol into our channel frame.
127
9
        self.set_link_protocol(link_protocol)?;
128

            
129
        // Read until we have all the remaining cells from the responder.
130
3
        let (auth_challenge_cell, certs_cell, (netinfo_cell, netinfo_rcvd_at), slog_digest) =
131
9
            self.recv_cells_from_responder(AuthLogAction::Take).await?;
132

            
133
        // TODO: It would be nice to come up with a better design for getting the SLOG.
134
3
        let slog_digest =
135
3
            slog_digest.ok_or_else(|| internal!("Asked for SLOG, but `None` returned?"))?;
136

            
137
3
        trace!(stream_id = %self.unique_id,
138
            "received handshake, ready to verify.",
139
        );
140

            
141
        // Calculate our clock skew from the timings we just got/calculated.
142
3
        let clock_skew = unauthenticated_clock_skew(
143
3
            &netinfo_cell,
144
3
            netinfo_rcvd_at,
145
3
            versions_flushed_at,
146
3
            versions_flushed_wallclock,
147
        );
148

            
149
3
        Ok(UnverifiedInitiatorRelayChannel {
150
3
            inner: UnverifiedInitiatorChannel {
151
3
                inner: UnverifiedChannel {
152
3
                    link_protocol,
153
3
                    framed_tls: self.framed_tls,
154
3
                    clock_skew,
155
3
                    memquota: self.memquota,
156
3
                    target_method: Some(self.target_method),
157
3
                    unique_id: self.unique_id,
158
3
                    sleep_prov: self.sleep_prov.clone(),
159
3
                },
160
3
                certs_cell,
161
3
            },
162
3
            auth_challenge_cell,
163
3
            slog_digest,
164
3
            netinfo_cell,
165
3
            auth_material: self.auth_material,
166
3
            my_addrs: self.my_addrs,
167
3
            create_request_handler: self.create_request_handler,
168
3
        })
169
11
    }
170
}
171

            
172
/// A relay channel handshake as the responder.
173
pub struct RelayResponderHandshake<
174
    T: AsyncRead + AsyncWrite + CertifiedConn + StreamOps + Send + Unpin + 'static,
175
    S: CoarseTimeProvider + SleepProvider,
176
> {
177
    /// Runtime handle (insofar as we need it)
178
    sleep_prov: S,
179
    /// Memory quota account
180
    memquota: ChannelAccount,
181
    /// Underlying TLS stream in a channel frame.
182
    ///
183
    /// (We don't enforce that this is actually TLS, but if it isn't, the
184
    /// connection won't be secure.)
185
    framed_tls: ChannelFrame<T>,
186
    /// The peer IP address as in the address the initiator is connecting from. This can be a
187
    /// client so keep it sensitive.
188
    peer_addr: Sensitive<PeerAddr>,
189
    /// Our advertised addresses. Needed for the NETINFO.
190
    my_addrs: Vec<IpAddr>,
191
    /// Logging identifier for this stream.  (Used for logging only.)
192
    unique_id: UniqId,
193
    /// Our identity keys needed for authentication.
194
    auth_material: Arc<RelayChannelAuthMaterial>,
195
    /// Provided to each new channel so that they can handle CREATE* requests.
196
    create_request_handler: Arc<CreateRequestHandler>,
197
}
198

            
199
/// Implement the base channel handshake trait.
200
impl<T, S> ChannelBaseHandshake<T> for RelayResponderHandshake<T, S>
201
where
202
    T: AsyncRead + AsyncWrite + CertifiedConn + StreamOps + Send + Unpin + 'static,
203
    S: CoarseTimeProvider + SleepProvider,
204
{
205
    fn framed_tls(&mut self) -> &mut ChannelFrame<T> {
206
        &mut self.framed_tls
207
    }
208
    fn unique_id(&self) -> &UniqId {
209
        &self.unique_id
210
    }
211
}
212

            
213
impl<
214
    T: AsyncRead + AsyncWrite + CertifiedConn + StreamOps + Send + Unpin + 'static,
215
    S: CoarseTimeProvider + SleepProvider,
216
> RelayResponderHandshake<T, S>
217
{
218
    /// Constructor.
219
    pub(crate) fn new(
220
        peer_addr: Sensitive<PeerAddr>,
221
        my_addrs: Vec<SocketAddr>,
222
        tls: T,
223
        sleep_prov: S,
224
        auth_material: Arc<RelayChannelAuthMaterial>,
225
        memquota: ChannelAccount,
226
        create_request_handler: Arc<CreateRequestHandler>,
227
    ) -> Self {
228
        Self {
229
            peer_addr,
230
            my_addrs: my_addrs.into_iter().map(|a| a.ip()).collect(),
231
            framed_tls: new_frame(
232
                tls,
233
                ChannelType::RelayResponder {
234
                    authenticated: false,
235
                },
236
            ),
237
            unique_id: UniqId::new(),
238
            sleep_prov,
239
            auth_material,
240
            memquota,
241
            create_request_handler,
242
        }
243
    }
244

            
245
    /// Begin the handshake process.
246
    ///
247
    /// Takes a function that reports the current time.  In theory, this can just be
248
    /// `SystemTime::get()`.
249
    pub async fn handshake<F>(
250
        mut self,
251
        now_fn: F,
252
    ) -> Result<MaybeVerifiableRelayResponderChannel<T, S>>
253
    where
254
        F: FnOnce() -> SystemTime,
255
    {
256
        // Receive initiator VERSIONS.
257
        let link_protocol = self.recv_versions_cell().await?;
258

            
259
        // Send the VERSIONS message.
260
        let (versions_flushed_at, versions_flushed_wallclock) =
261
            self.send_versions_cell(now_fn).await?;
262

            
263
        // VERSIONS cell have been exchanged, set the link protocol into our channel frame.
264
        self.set_link_protocol(link_protocol)?;
265

            
266
        // Send CERTS, AUTH_CHALLENGE and NETINFO
267
        let slog_digest = self.send_cells_to_initiator().await?;
268

            
269
        // Receive NETINFO and possibly [CERTS, AUTHENTICATE]. The connection could be from a
270
        // client/bridge and thus no authentication meaning no CERTS/AUTHENTICATE cells.
271
        let (certs_and_auth_and_clog, (netinfo_cell, netinfo_rcvd_at)) =
272
            self.recv_cells_from_initiator().await?;
273

            
274
        // Try to unpack these into something we can use later.
275
        let (certs_cell, auth_and_clog) = match certs_and_auth_and_clog {
276
            Some((certs, auth, clog)) => (Some(certs), Some((auth, clog))),
277
            None => (None, None),
278
        };
279

            
280
        // Calculate our clock skew from the timings we just got/calculated.
281
        let clock_skew = unauthenticated_clock_skew(
282
            &netinfo_cell,
283
            netinfo_rcvd_at,
284
            versions_flushed_at,
285
            versions_flushed_wallclock,
286
        );
287

            
288
        let inner = UnverifiedChannel {
289
            link_protocol,
290
            framed_tls: self.framed_tls,
291
            clock_skew,
292
            memquota: self.memquota,
293
            target_method: None,
294
            unique_id: self.unique_id,
295
            sleep_prov: self.sleep_prov,
296
        };
297

            
298
        // With an AUTHENTICATE cell, we can verify (relay). Else (client/bridge), we can't.
299
        Ok(match auth_and_clog {
300
            Some((auth_cell, clog_digest)) => {
301
                MaybeVerifiableRelayResponderChannel::Verifiable(UnverifiedResponderRelayChannel {
302
                    inner,
303
                    auth_cell,
304
                    netinfo_cell,
305
                    // TODO(relay): Should probably put that in the match {} and not assume.
306
                    certs_cell: certs_cell.expect("AUTHENTICATE cell without CERTS cell"),
307
                    auth_material: self.auth_material,
308
                    my_addrs: self.my_addrs,
309
                    peer_addr: self.peer_addr.into_inner(), // Relay address.
310
                    clog_digest,
311
                    slog_digest,
312
                    create_request_handler: self.create_request_handler,
313
                })
314
            }
315
            None => MaybeVerifiableRelayResponderChannel::NonVerifiable(
316
                NonVerifiableResponderRelayChannel {
317
                    inner,
318
                    netinfo_cell,
319
                    my_addrs: self.my_addrs,
320
                    peer_addr: self.peer_addr,
321
                    create_request_handler: self.create_request_handler,
322
                    our_ed25519_id: self.auth_material.ed_id,
323
                    our_rsa_id: self.auth_material.rsa_id,
324
                },
325
            ),
326
        })
327
    }
328

            
329
    /// Receive all the cells expected from the initiator of the connection. Keep in mind that it
330
    /// can be either a relay or client or bridge.
331
    async fn recv_cells_from_initiator(
332
        &mut self,
333
    ) -> Result<(
334
        Option<(msg::Certs, msg::Authenticate, ClogDigest)>,
335
        (msg::Netinfo, coarsetime::Instant),
336
    )> {
337
        // IMPORTANT: Protocol wise, we MUST only allow one single cell of each type for a valid
338
        // handshake. Any duplicates lead to a failure.
339
        // They must arrive in a specific order in order for the CLOG calculation to be valid.
340

            
341
        // Note that the `ChannelFrame` already restricts the messages due to its handshake cell
342
        // handler.
343

            
344
        // This is kind of ugly, but I don't see a nicer way to write the authentication branch
345
        // without a bunch of boilerplate for a state machine.
346
        let (certs_and_auth_and_clog, netinfo, netinfo_rcvd_at) = 'outer: {
347
            // CERTS or NETINFO cell.
348
            let certs = loop {
349
                restricted_msg! {
350
                    enum CertsNetinfoMsg : ChanMsg {
351
                        // VPADDING cells (but not PADDING) can be sent during handshaking.
352
                        Vpadding,
353
                        Netinfo,
354
                        Certs,
355
                   }
356
                }
357

            
358
                break match read_msg(*self.unique_id(), self.framed_tls()).await? {
359
                    CertsNetinfoMsg::Vpadding(_) => continue,
360
                    // If a NETINFO cell, the initiator did not authenticate and we can stop early.
361
                    CertsNetinfoMsg::Netinfo(msg) => {
362
                        break 'outer (None, msg, coarsetime::Instant::now());
363
                    }
364
                    // If a CERTS cell, the initiator is authenticating.
365
                    CertsNetinfoMsg::Certs(msg) => msg,
366
                };
367
            };
368

            
369
            // We're the responder, which means that the recv log is the CLOG.
370
            let clog_digest =
371
                ClogDigest::new(self.framed_tls().codec_mut().take_recv_log_digest()?);
372

            
373
            // AUTHENTICATE cell.
374
            let auth = loop {
375
                restricted_msg! {
376
                    enum AuthenticateMsg : ChanMsg {
377
                        // VPADDING cells (but not PADDING) can be sent during handshaking.
378
                        Vpadding,
379
                        Authenticate,
380
                   }
381
                }
382

            
383
                break match read_msg(*self.unique_id(), self.framed_tls()).await? {
384
                    AuthenticateMsg::Vpadding(_) => continue,
385
                    AuthenticateMsg::Authenticate(msg) => msg,
386
                };
387
            };
388

            
389
            // NETINFO cell (if we didn't receive it earlier).
390
            let (netinfo, netinfo_rcvd_at) = loop {
391
                restricted_msg! {
392
                    enum NetinfoMsg : ChanMsg {
393
                        // VPADDING cells (but not PADDING) can be sent during handshaking.
394
                        Vpadding,
395
                        Netinfo,
396
                   }
397
                }
398

            
399
                break match read_msg(*self.unique_id(), self.framed_tls()).await? {
400
                    NetinfoMsg::Vpadding(_) => continue,
401
                    NetinfoMsg::Netinfo(msg) => (msg, coarsetime::Instant::now()),
402
                };
403
            };
404

            
405
            (Some((certs, auth, clog_digest)), netinfo, netinfo_rcvd_at)
406
        };
407

            
408
        Ok((certs_and_auth_and_clog, (netinfo, netinfo_rcvd_at)))
409
    }
410

            
411
    /// Send all expected cells to the initiator of the channel as the responder.
412
    ///
413
    /// Return the SLOG (send log) digest to be later used when verifying the initiator's
414
    /// AUTHENTICATE cell.
415
    async fn send_cells_to_initiator(&mut self) -> Result<SlogDigest> {
416
        // Send the CERTS message.
417
        let certs = build_certs_cell(&self.auth_material, /* is_responder */ true);
418
        trace!(channel_id = %self.unique_id, "Sending CERTS as responder cell.");
419
        self.framed_tls.send(certs.into()).await?;
420

            
421
        // Send the AUTH_CHALLENGE.
422
        let challenge: [u8; 32] = rand::rng().random();
423
        let auth_challenge = msg::AuthChallenge::new(challenge, [AUTHTYPE_ED25519_SHA256_RFC5705]);
424
        trace!(channel_id = %self.unique_id, "Sending AUTH_CHALLENGE as responder cell.");
425
        self.framed_tls.send(auth_challenge.into()).await?;
426

            
427
        // We're the responder, which means that the send log is the SLOG.
428
        let slog_digest = SlogDigest::new(self.framed_tls.codec_mut().take_send_log_digest()?);
429

            
430
        // Send the NETINFO message.
431
        let peer_ip = self.peer_addr.netinfo_addr();
432
        let netinfo = build_netinfo_cell(peer_ip, self.my_addrs.clone(), &self.sleep_prov)?;
433
        trace!(channel_id = %self.unique_id, "Sending NETINFO as responder cell.");
434
        self.framed_tls.send(netinfo.into()).await?;
435

            
436
        Ok(slog_digest)
437
    }
438
}