1
//! Relay channel code.
2
//!
3
//! This contains relay specific channel code. In other words, everyting that a relay needs to
4
//! establish a channel according to the Tor protocol.
5

            
6
pub(crate) mod handshake;
7
pub(crate) mod initiator;
8
pub(crate) mod responder;
9

            
10
pub use responder::MaybeVerifiableRelayResponderChannel;
11

            
12
use digest::Digest;
13
use futures::{AsyncRead, AsyncWrite};
14
use rand::Rng;
15
use safelog::Sensitive;
16
use std::net::IpAddr;
17
use std::sync::Arc;
18
use std::time::UNIX_EPOCH;
19

            
20
use tor_cell::chancell::msg;
21
use tor_cert::rsa::EncodedRsaCrosscert;
22
use tor_cert::x509::TlsKeyAndCert;
23
use tor_cert::{CertType, EncodedEd25519Cert};
24
use tor_error::internal;
25
use tor_linkspec::{HasRelayIds, OwnedChanTarget, RelayIdRef, RelayIdType};
26
use tor_llcrypto as ll;
27
use tor_llcrypto::pk::{
28
    ed25519::{Ed25519Identity, Ed25519SigningKey},
29
    rsa,
30
    rsa::RsaIdentity,
31
};
32
use tor_relay_crypto::pk::RelayLinkSigningKeypair;
33
use tor_rtcompat::{CertifiedConn, CoarseTimeProvider, SleepProvider, StreamOps};
34

            
35
use crate::channel::handshake::VerifiedChannel;
36
use crate::peer::PeerAddr;
37
use crate::relay::channel::handshake::{AUTHTYPE_ED25519_SHA256_RFC5705, RelayResponderHandshake};
38
use crate::{Error, Result, channel::RelayInitiatorHandshake, memquota::ChannelAccount};
39

            
40
// TODO(relay): We should probably get those values from protover crate or some other
41
// crate that have all "network parameters" we support?
42
/// A list of link authentication that we support (LinkAuth).
43
pub(crate) static LINK_AUTH: &[u16] = &[AUTHTYPE_ED25519_SHA256_RFC5705];
44

            
45
/// Object containing the key and certificate that basically identifies us as a relay. They are
46
/// used for channel authentication.
47
///
48
/// We use this intermediary object in order to not have tor-proto crate have access to the KeyMgr
49
/// meaning access to all keys. This restricts the view to what is needed.
50
pub struct RelayIdentities {
51
    /// The SHA256(DER(KP_relayid_rsa)) digest for the AUTHENTICATE cell CID.
52
    pub(crate) rsa_id_der_digest: [u8; 32],
53
    /// Our RSA identity `KP_relayid_rsa` (SHA1). Needed for HasRelayIds which is required to
54
    /// compare this with a [`tor_linkspec::ChanTarget`].
55
    pub(crate) rsa_id: RsaIdentity,
56
    /// Our Ed identity key (KP_relayid_ed). For the [`msg::Authenticate`] cell CID_ED field.
57
    pub(crate) ed_id: Ed25519Identity,
58
    /// Our link signing keypair. Used to sign the [`msg::Authenticate`] cell.
59
    pub(crate) link_sign_kp: RelayLinkSigningKeypair,
60
    /// The Ed25519 identity signing cert (CertType 4) for the [`msg::Certs`] cell.
61
    pub(crate) cert_id_sign_ed: EncodedEd25519Cert,
62
    /// The Ed25519 signing TLS cert (CertType 5) for the [`msg::Certs`] cell.
63
    pub(crate) cert_sign_tls_ed: EncodedEd25519Cert,
64
    /// The Ed25519 signing link auth cert (CertType 6) for the [`msg::Certs`] cell.
65
    pub(crate) cert_sign_link_auth_ed: EncodedEd25519Cert,
66
    /// Legacy: the RSA identity X509 cert (CertType 2) for the [`msg::Certs`] cell.
67
    ///
68
    /// We only have the bytes here as create_legacy_rsa_id_cert() takes a key and gives us back
69
    /// the encoded cert.
70
    pub(crate) cert_id_x509_rsa: Vec<u8>,
71
    /// Legacy: the RSA identity cert (CertType 7) for the [`msg::Certs`] cell.
72
    pub(crate) cert_id_rsa: EncodedRsaCrosscert,
73
    /// Tls key and cert. This is for the TLS acceptor object needed to be a responder (TLS server
74
    /// side).
75
    pub(crate) tls_key_and_cert: TlsKeyAndCert,
76
}
77

            
78
impl RelayIdentities {
79
    /// Constructor.
80
    #[allow(clippy::too_many_arguments)] // Yes, plethora of keys...
81
    pub fn new(
82
        rsa_id_pk: &rsa::PublicKey,
83
        ed_id: Ed25519Identity,
84
        link_sign_kp: RelayLinkSigningKeypair,
85
        cert_id_sign_ed: EncodedEd25519Cert,
86
        cert_sign_tls_ed: EncodedEd25519Cert,
87
        cert_sign_link_auth_ed: EncodedEd25519Cert,
88
        cert_id_x509_rsa: Vec<u8>,
89
        cert_id_rsa: EncodedRsaCrosscert,
90
        tls_key_and_cert: TlsKeyAndCert,
91
    ) -> Self {
92
        Self {
93
            rsa_id_der_digest: ll::d::Sha256::digest(rsa_id_pk.to_der()).into(),
94
            rsa_id: rsa_id_pk.to_rsa_identity(),
95
            ed_id,
96
            link_sign_kp,
97
            cert_id_sign_ed,
98
            cert_sign_tls_ed,
99
            cert_sign_link_auth_ed,
100
            cert_id_x509_rsa,
101
            cert_id_rsa,
102
            tls_key_and_cert,
103
        }
104
    }
105

            
106
    /// Return the TLS key and certificate to use for the underlying TLS provider.
107
    ///
108
    /// This is used by the TLS acceptor that acts as the TLS server provider.
109
    pub fn tls_key_and_cert(&self) -> &TlsKeyAndCert {
110
        &self.tls_key_and_cert
111
    }
112

            
113
    /// Return our Ed identity key (KP_relayid_ed) as bytes.
114
    pub(crate) fn ed_id_bytes(&self) -> [u8; 32] {
115
        self.ed_id.into()
116
    }
117
}
118

            
119
impl HasRelayIds for RelayIdentities {
120
    fn identity(&self, key_type: RelayIdType) -> Option<RelayIdRef<'_>> {
121
        match key_type {
122
            RelayIdType::Ed25519 => Some(RelayIdRef::from(&self.ed_id)),
123
            RelayIdType::Rsa => Some(RelayIdRef::from(&self.rsa_id)),
124
            _ => None, // Non-exhaustive...
125
        }
126
    }
127
}
128

            
129
/// Structure for building and launching a relay Tor channel.
130
#[derive(Default)]
131
#[non_exhaustive]
132
pub struct RelayChannelBuilder;
133

            
134
impl RelayChannelBuilder {
135
    /// Constructor.
136
    pub fn new() -> Self {
137
        Self::default()
138
    }
139

            
140
    /// Launch a new handshake over a TLS stream.
141
    ///
142
    /// After calling this function, you'll need to call `connect()` on the result to start the
143
    /// handshake.  If that succeeds, you'll have authentication info from the relay: call
144
    /// `check()` on the result to check that.  Finally, to finish the handshake, call `finish()`
145
    /// on the result of _that_.
146
    #[allow(clippy::too_many_arguments)] // TODO consider if we want a builder
147
    pub fn launch<T, S>(
148
        self,
149
        tls: T,
150
        sleep_prov: S,
151
        identities: Arc<RelayIdentities>,
152
        my_addrs: Vec<IpAddr>,
153
        peer: &OwnedChanTarget,
154
        memquota: ChannelAccount,
155
    ) -> RelayInitiatorHandshake<T, S>
156
    where
157
        T: AsyncRead + AsyncWrite + CertifiedConn + StreamOps + Send + Unpin + 'static,
158
        S: CoarseTimeProvider + SleepProvider,
159
    {
160
        RelayInitiatorHandshake::new(tls, sleep_prov, identities, my_addrs, peer, memquota)
161
    }
162

            
163
    /// Accept a new handshake over a TLS stream.
164
    pub fn accept<T, S>(
165
        self,
166
        peer_addr: Sensitive<PeerAddr>,
167
        my_addrs: Vec<IpAddr>,
168
        tls: T,
169
        sleep_prov: S,
170
        identities: Arc<RelayIdentities>,
171
        memquota: ChannelAccount,
172
    ) -> RelayResponderHandshake<T, S>
173
    where
174
        T: AsyncRead + AsyncWrite + CertifiedConn + StreamOps + Send + Unpin + 'static,
175
        S: CoarseTimeProvider + SleepProvider,
176
    {
177
        RelayResponderHandshake::new(peer_addr, my_addrs, tls, sleep_prov, identities, memquota)
178
    }
179
}
180

            
181
/// Channel authentication data. This is only relevant for a Relay to Relay channel which are
182
/// authenticated using this buffet of bytes.
183
#[derive(Debug)]
184
pub(crate) struct ChannelAuthenticationData {
185
    /// Authentication method to use.
186
    pub(crate) link_auth: u16,
187
    /// SHA256 digest of the initiator KP_relayid_rsa.
188
    pub(crate) cid: [u8; 32],
189
    /// SHA256 digest of the responder KP_relayid_rsa.
190
    pub(crate) sid: [u8; 32],
191
    /// The initiator KP_relayid_ed.
192
    pub(crate) cid_ed: [u8; 32],
193
    /// The responder KP_relayid_ed.
194
    pub(crate) sid_ed: [u8; 32],
195
    /// Initiator log SHA256 digest.
196
    pub(crate) clog: [u8; 32],
197
    /// Responder log SHA256 digest.
198
    pub(crate) slog: [u8; 32],
199
    /// SHA256 of responder's TLS certificate.
200
    pub(crate) scert: [u8; 32],
201
}
202

            
203
impl ChannelAuthenticationData {
204
    /// Helper: return the authentication type string from the given link auth version.
205
    const fn auth_type_bytes(link_auth: u16) -> Result<&'static [u8]> {
206
        match link_auth {
207
            3 => Ok(b"AUTH0003"),
208
            _ => Err(Error::BadCellAuth),
209
        }
210
    }
211

            
212
    /// Helper: return the keying material label from the given link auth version.
213
    const fn keying_material_label_bytes(link_auth: u16) -> Result<&'static [u8]> {
214
        match link_auth {
215
            3 => Ok(b"EXPORTER FOR TOR TLS CLIENT BINDING AUTH0003"),
216
            _ => Err(Error::BadCellAuth),
217
        }
218
    }
219

            
220
    /// Consume ourself and return an AUTHENTICATE cell from the data we hold.
221
    pub(crate) fn into_authenticate<C: CertifiedConn>(
222
        self,
223
        tls: &C,
224
        link_ed: &RelayLinkSigningKeypair,
225
    ) -> Result<msg::Authenticate> {
226
        // The body is exactly 352 bytes so optimize a bit memory.
227
        let mut body = Vec::with_capacity(352);
228

            
229
        // Obviously, ordering matteres. See tor-spec section Ed25519-SHA256-RFC5705
230
        body.extend_from_slice(Self::auth_type_bytes(self.link_auth)?);
231
        body.extend_from_slice(&self.cid);
232
        body.extend_from_slice(&self.sid);
233
        body.extend_from_slice(&self.cid_ed);
234
        body.extend_from_slice(&self.sid_ed);
235
        body.extend_from_slice(&self.slog);
236
        body.extend_from_slice(&self.clog);
237
        body.extend_from_slice(&self.scert);
238

            
239
        // TLSSECRETS is built from the CID.
240
        let tls_secrets = tls.export_keying_material(
241
            32,
242
            Self::keying_material_label_bytes(self.link_auth)?,
243
            Some(&self.cid[..]),
244
        )?;
245
        body.extend_from_slice(tls_secrets.as_slice());
246

            
247
        // Add the random bytes.
248
        let random: [u8; 24] = rand::rng().random();
249
        body.extend_from_slice(&random);
250

            
251
        // Create signature with our KP_link_ed and append it to body. We hard expect the
252
        // KP_link_ed because this would be a code flow error.
253
        let sig = link_ed.sign(&body);
254
        body.extend_from_slice(&sig.to_bytes());
255

            
256
        // Lets go with the AUTHENTICATE cell.
257
        Ok(msg::Authenticate::new(self.link_auth, body))
258
    }
259

            
260
    /// Build the [`ChannelAuthenticationData`] given a [`VerifiedChannel`].
261
    ///
262
    /// We should never check or build authentication data if the channel is not verified thus the
263
    /// requirement to pass the verified channel to this function.
264
    ///
265
    /// The `our_cert` parameter is for the responder case only that is it contains our certificate
266
    /// that we presented as the TLS server side. This MUST be Some() if auth_challenge_cell is
267
    /// None.
268
    ///
269
    /// Both initiator and responder handshake build this data in order to authenticate.
270
    ///
271
    /// IMPORTANT: The CLOG and SLOG from the framed_tls codec is consumed here so calling twice
272
    /// build_auth_data() will result in different AUTHENTICATE cells.
273
    pub(crate) fn build<T, S>(
274
        auth_challenge_cell: Option<&msg::AuthChallenge>,
275
        identities: &Arc<RelayIdentities>,
276
        verified: &mut VerifiedChannel<T, S>,
277
        our_cert: Option<[u8; 32]>,
278
    ) -> Result<ChannelAuthenticationData>
279
    where
280
        T: AsyncRead + AsyncWrite + CertifiedConn + StreamOps + Send + Unpin + 'static,
281
        S: CoarseTimeProvider + SleepProvider,
282
    {
283
        // With an AUTH_CHALLENGE, we are the Initiator. With an AUTHENTICATE, we are the
284
        // Responder. See tor-spec for a diagram of messages.
285
        let is_responder = auth_challenge_cell.is_none();
286

            
287
        // Without an AUTH_CHALLENGE, we use our known link protocol value. Else, we only keep what
288
        // we know from the AUTH_CHALLENGE and we max() on it.
289
        let link_auth = *LINK_AUTH
290
            .iter()
291
            .filter(|m| auth_challenge_cell.is_none_or(|cell| cell.methods().contains(m)))
292
            .max()
293
            .ok_or(Error::BadCellAuth)?;
294
        // The ordering matter based on if initiator or responder.
295
        let cid = identities.rsa_id_der_digest;
296
        let sid = verified.rsa_id_digest;
297
        let cid_ed = identities.ed_id_bytes();
298
        let sid_ed = verified.ed25519_id.into();
299
        // Both values are consumed from the underlying codec.
300
        let send_log = verified.framed_tls.codec_mut().take_send_log_digest()?;
301
        let recv_log = verified.framed_tls.codec_mut().take_recv_log_digest()?;
302

            
303
        let (cid, sid, cid_ed, sid_ed) = if is_responder {
304
            // Reverse when responder as in CID becomes SID, and so on.
305
            (sid, cid, sid_ed, cid_ed)
306
        } else {
307
            // Keep it that way if we are initiator.
308
            (cid, sid, cid_ed, sid_ed)
309
        };
310

            
311
        let (clog, slog) = if is_responder {
312
            // We're the responder (acting like a server),
313
            // so the SLOG is the digest of the bytes we sent.
314
            (recv_log, send_log)
315
        } else {
316
            // We're the initiator (acting like a client),
317
            // so the CLOG is the digest of the bytes we sent.
318
            (send_log, recv_log)
319
        };
320

            
321
        let scert = if is_responder {
322
            our_cert.ok_or(internal!("Responder channel without own certificate"))?
323
        } else {
324
            verified.peer_cert_digest
325
        };
326

            
327
        Ok(Self {
328
            link_auth,
329
            cid,
330
            sid,
331
            cid_ed,
332
            sid_ed,
333
            clog,
334
            slog,
335
            scert,
336
        })
337
    }
338
}
339

            
340
/// Helper: Build a [`msg::Certs`] cell for the given relay identities and channel type.
341
///
342
/// Both relay initiator and responder handshake use this.
343
pub(crate) fn build_certs_cell(
344
    identities: &Arc<RelayIdentities>,
345
    is_responder: bool,
346
) -> msg::Certs {
347
    let mut certs = msg::Certs::new_empty();
348
    // Push into the cell the CertType 2 RSA
349
    certs.push_cert_body(
350
        tor_cert::CertType::RSA_ID_X509,
351
        identities.cert_id_x509_rsa.clone(),
352
    );
353

            
354
    // Push into the cell the CertType 7 RSA
355
    certs.push_cert_body(CertType::RSA_ID_V_IDENTITY, identities.cert_id_rsa.clone());
356

            
357
    // Push into the cell the CertType 4 Ed25519
358
    certs.push_cert_body(
359
        CertType::IDENTITY_V_SIGNING,
360
        identities.cert_id_sign_ed.clone(),
361
    );
362
    // Push into the cell the CertType 5/6 Ed25519
363
    if is_responder {
364
        // Responder has CertType 5
365
        certs.push_cert_body(
366
            CertType::SIGNING_V_TLS_CERT,
367
            identities.cert_sign_tls_ed.clone(),
368
        );
369
    } else {
370
        // Initiator has CertType 6
371
        certs.push_cert_body(
372
            CertType::SIGNING_V_LINK_AUTH,
373
            identities.cert_sign_link_auth_ed.clone(),
374
        );
375
    }
376
    certs
377
}
378

            
379
/// Build a [`msg::Netinfo`] cell from the given peer IPs and our advertised addresses.
380
///
381
/// Both relay initiator and responder handshake use this.
382
pub(crate) fn build_netinfo_cell<S>(
383
    peer_ip: Option<IpAddr>,
384
    my_addrs: Vec<IpAddr>,
385
    sleep_prov: &S,
386
) -> Result<msg::Netinfo>
387
where
388
    S: CoarseTimeProvider + SleepProvider,
389
{
390
    // Unix timestamp but over 32bit. This will be sad in 2038 but proposal 338 addresses this
391
    // issue with a change to 64bit.
392
    let timestamp = sleep_prov
393
        .wallclock()
394
        .duration_since(UNIX_EPOCH)
395
        .map_err(|e| internal!("Wallclock may have gone backwards: {e}"))?
396
        .as_secs()
397
        .try_into()
398
        .map_err(|e| internal!("Wallclock secs fail to convert to 32bit: {e}"))?;
399
    Ok(msg::Netinfo::from_relay(timestamp, peer_ip, my_addrs))
400
}