1
//! Implementations for the relay channel handshake
2

            
3
use futures::SinkExt;
4
use futures::io::{AsyncRead, AsyncWrite};
5
use rand::Rng;
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
116
    fn framed_tls(&mut self) -> &mut ChannelFrame<T> {
69
116
        &mut self.framed_tls
70
116
    }
71
128
    fn unique_id(&self) -> &UniqId {
72
128
        &self.unique_id
73
128
    }
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
22
    pub(crate) fn new(
91
22
        tls: T,
92
22
        sleep_prov: S,
93
22
        auth_material: Arc<RelayChannelAuthMaterial>,
94
22
        my_addrs: Vec<SocketAddr>,
95
22
        peer_target: &OwnedChanTarget,
96
22
        memquota: ChannelAccount,
97
22
        create_request_handler: Arc<CreateRequestHandler>,
98
22
    ) -> Self {
99
        Self {
100
22
            framed_tls: new_frame(tls, ChannelType::RelayInitiator),
101
22
            unique_id: UniqId::new(),
102
22
            sleep_prov,
103
22
            auth_material,
104
22
            memquota,
105
22
            my_addrs: my_addrs.into_iter().map(|a| a.ip()).collect(),
106
22
            target_method: peer_target.chan_method(),
107
22
            create_request_handler,
108
        }
109
22
    }
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
22
    pub async fn connect<F>(mut self, now_fn: F) -> Result<UnverifiedInitiatorRelayChannel<T, S>>
116
22
    where
117
22
        F: FnOnce() -> SystemTime,
118
22
    {
119
        // Send the VERSIONS.
120
22
        let (versions_flushed_at, versions_flushed_wallclock) =
121
22
            self.send_versions_cell(now_fn).await?;
122

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

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

            
129
        // Read until we have all the remaining cells from the responder.
130
6
        let (auth_challenge_cell, certs_cell, (netinfo_cell, netinfo_rcvd_at), slog_digest) =
131
18
            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
6
        let slog_digest = slog_digest.ok_or(internal!("Asked for SLOG, but `None` returned?"))?;
135

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

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

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

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

            
198
/// Implement the base channel handshake trait.
199
impl<T, S> ChannelBaseHandshake<T> for RelayResponderHandshake<T, S>
200
where
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

            
212
impl<
213
    T: AsyncRead + AsyncWrite + CertifiedConn + StreamOps + Send + Unpin + 'static,
214
    S: CoarseTimeProvider + SleepProvider,
215
> RelayResponderHandshake<T, S>
216
{
217
    /// Constructor.
218
    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
    /// Begin the handshake process.
245
    ///
246
    /// Takes a function that reports the current time.  In theory, this can just be
247
    /// `SystemTime::get()`.
248
    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
        // Receive initiator VERSIONS.
256
        let link_protocol = self.recv_versions_cell().await?;
257

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

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

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

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

            
273
        // Try to unpack these into something we can use later.
274
        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
        // Calculate our clock skew from the timings we just got/calculated.
280
        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
        // With an AUTHENTICATE cell, we can verify (relay). Else (client/bridge), we can't.
298
        Ok(match auth_and_clog {
299
            Some((auth_cell, clog_digest)) => {
300
                MaybeVerifiableRelayResponderChannel::Verifiable(UnverifiedResponderRelayChannel {
301
                    inner,
302
                    auth_cell,
303
                    netinfo_cell,
304
                    // TODO(relay): Should probably put that in the match {} and not assume.
305
                    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(), // Relay address.
309
                    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
                },
323
            ),
324
        })
325
    }
326

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

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

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

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

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

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

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

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

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

            
403
            (Some((certs, auth, clog_digest)), netinfo, netinfo_rcvd_at)
404
        };
405

            
406
        Ok((certs_and_auth_and_clog, (netinfo, netinfo_rcvd_at)))
407
    }
408

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

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

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

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

            
434
        Ok(slog_digest)
435
    }
436
}