1
//! Relay channel code.
2
//!
3
//! This contains relay specific channel code. In other words, everything 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::EncodedEd25519Cert;
22
use tor_cert::rsa::EncodedRsaCrosscert;
23
use tor_cert::x509::TlsKeyAndCert;
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
96
    pub fn new(
82
96
        rsa_id_pk: &rsa::PublicKey,
83
96
        ed_id: Ed25519Identity,
84
96
        link_sign_kp: RelayLinkSigningKeypair,
85
96
        cert_id_sign_ed: EncodedEd25519Cert,
86
96
        cert_sign_tls_ed: EncodedEd25519Cert,
87
96
        cert_sign_link_auth_ed: EncodedEd25519Cert,
88
96
        cert_id_x509_rsa: Vec<u8>,
89
96
        cert_id_rsa: EncodedRsaCrosscert,
90
96
        tls_key_and_cert: TlsKeyAndCert,
91
96
    ) -> Self {
92
96
        Self {
93
96
            rsa_id_der_digest: ll::d::Sha256::digest(rsa_id_pk.to_der()).into(),
94
96
            rsa_id: rsa_id_pk.to_rsa_identity(),
95
96
            ed_id,
96
96
            link_sign_kp,
97
96
            cert_id_sign_ed,
98
96
            cert_sign_tls_ed,
99
96
            cert_sign_link_auth_ed,
100
96
            cert_id_x509_rsa,
101
96
            cert_id_rsa,
102
96
            tls_key_and_cert,
103
96
        }
104
96
    }
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
    /// Return a vector of bytes of an [`msg::Authenticate`] cell but without the random bytes and
221
    /// the signature.
222
    ///
223
    /// This is needed so a responder can compare what is expected from what it got. A responder
224
    /// can only verify the signature and so we can't compare the full [`msg::Authenticate`]
225
    /// message we received with what we expect.
226
    pub(crate) fn as_body_no_rand<C: CertifiedConn>(&self, tls: &C) -> Result<Vec<u8>> {
227
        // The body is exactly 352 bytes so optimize a bit memory.
228
        let mut body = Vec::with_capacity(352);
229

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

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

            
248
        Ok(body)
249
    }
250

            
251
    /// Consume ourself and return an AUTHENTICATE cell from the data we hold.
252
    pub(crate) fn into_authenticate<C: CertifiedConn>(
253
        self,
254
        tls: &C,
255
        link_ed: &RelayLinkSigningKeypair,
256
    ) -> Result<msg::Authenticate> {
257
        // Get us everything except the random bytes and signature.
258
        let mut body = self.as_body_no_rand(tls)?;
259

            
260
        // Add the random bytes.
261
        let random: [u8; 24] = rand::rng().random();
262
        body.extend_from_slice(&random);
263

            
264
        // Create signature with our KP_link_ed and append it to body. We hard expect the
265
        // KP_link_ed because this would be a code flow error.
266
        let sig = link_ed.sign(&body);
267
        body.extend_from_slice(&sig.to_bytes());
268

            
269
        // Lets go with the AUTHENTICATE cell.
270
        Ok(msg::Authenticate::new(self.link_auth, body))
271
    }
272

            
273
    /// Build a [`ChannelAuthenticationData`] for an initiator channel handshake.
274
    ///
275
    /// `auth_challenge_cell` is the [`msg::AuthChallenge`] we recevied during the handshake.
276
    ///
277
    /// `identities` are our [`RelayIdentities`]
278
    ///
279
    /// `verified` is a [`VerifiedChannel`] which we need to consume the CLOG/SLOG
280
    ///
281
    /// `peer_cert_digest` is the TLS certificate presented by the peer.
282
    pub(crate) fn build_initiator<T, S>(
283
        auth_challenge_cell: &msg::AuthChallenge,
284
        identities: &Arc<RelayIdentities>,
285
        clog: [u8; 32],
286
        slog: [u8; 32],
287
        verified: &mut VerifiedChannel<T, S>,
288
        peer_cert_digest: [u8; 32],
289
    ) -> Result<ChannelAuthenticationData>
290
    where
291
        T: AsyncRead + AsyncWrite + CertifiedConn + StreamOps + Send + Unpin + 'static,
292
        S: CoarseTimeProvider + SleepProvider,
293
    {
294
        // Keep what we know from the AUTH_CHALLENGE and we max() on it.
295
        let link_auth = *LINK_AUTH
296
            .iter()
297
            .filter(|m| auth_challenge_cell.methods().contains(m))
298
            .max()
299
            .ok_or(Error::BadCellAuth)?;
300
        // The ordering matter as this is an initiator.
301
        let cid = identities.rsa_id_der_digest;
302
        let sid = verified.rsa_id_digest;
303
        let cid_ed = identities.ed_id_bytes();
304
        let sid_ed = (*verified
305
            .relay_ids()
306
            .ed_identity()
307
            .expect("Verified channel without Ed25519 identity"))
308
        .into();
309

            
310
        Ok(Self {
311
            link_auth,
312
            cid,
313
            sid,
314
            cid_ed,
315
            sid_ed,
316
            clog,
317
            slog,
318
            scert: peer_cert_digest,
319
        })
320
    }
321

            
322
    /// Build a [`ChannelAuthenticationData`] for an initiator channel handshake.
323
    ///
324
    /// `initiator_auth_type` is the authentication type from the [`msg::Authenticate`] received
325
    /// from the initiator.
326
    ///
327
    /// `identities` are our [`RelayIdentities`]
328
    ///
329
    /// `verified` is a [`VerifiedChannel`] which we need to consume the CLOG/SLOG
330
    ///
331
    /// `our_cert_digest` is our TLS certificate that we presented as a channel responder.
332
    ///
333
    /// IMPORTANT: The CLOG and SLOG from the framed_tls codec is consumed here so calling twice
334
    /// build_auth_data() will result in different AUTHENTICATE cells.
335
    pub(crate) fn build_responder<T, S>(
336
        initiator_auth_type: u16,
337
        identities: &Arc<RelayIdentities>,
338
        clog: [u8; 32],
339
        slog: [u8; 32],
340
        verified: &mut VerifiedChannel<T, S>,
341
        our_cert_digest: [u8; 32],
342
    ) -> Result<ChannelAuthenticationData>
343
    where
344
        T: AsyncRead + AsyncWrite + CertifiedConn + StreamOps + Send + Unpin + 'static,
345
        S: CoarseTimeProvider + SleepProvider,
346
    {
347
        // Max on what we know.
348
        let link_auth = if LINK_AUTH.contains(&initiator_auth_type) {
349
            initiator_auth_type
350
        } else {
351
            return Err(Error::UnsupportedAuth(initiator_auth_type));
352
        };
353
        // The ordering matter as this is a respodner. It is inversed from the initiator.
354
        let cid = identities.rsa_id_der_digest;
355
        let sid = verified.rsa_id_digest;
356
        let cid_ed = identities.ed_id_bytes();
357
        let sid_ed = (*verified
358
            .relay_ids()
359
            .ed_identity()
360
            .expect("Verified channel without Ed25519 identity"))
361
        .into();
362

            
363
        Ok(Self {
364
            link_auth,
365
            // Notice, everything is inversed here as the responder.
366
            cid: sid,
367
            sid: cid,
368
            cid_ed: sid_ed,
369
            sid_ed: cid_ed,
370
            clog,
371
            slog,
372
            scert: our_cert_digest,
373
        })
374
    }
375
}
376

            
377
/// Helper: Build a [`msg::Certs`] cell for the given relay identities and channel type.
378
///
379
/// Both relay initiator and responder handshake use this.
380
pub(crate) fn build_certs_cell(
381
    identities: &Arc<RelayIdentities>,
382
    is_responder: bool,
383
) -> msg::Certs {
384
    let mut certs = msg::Certs::new_empty();
385
    // Push into the cell the CertType 2 RSA (RSA_ID_X509)
386
    certs.push_cert_body(
387
        tor_cert::CertType::RSA_ID_X509,
388
        identities.cert_id_x509_rsa.clone(),
389
    );
390

            
391
    // Push into the cell the CertType 7 RSA (RSA_ID_V_IDENTITY)
392
    certs.push_cert(&identities.cert_id_rsa);
393

            
394
    // Push into the cell the CertType 4 Ed25519 (IDENTITY_V_SIGNING)
395
    certs.push_cert(&identities.cert_id_sign_ed);
396
    // Push into the cell the CertType 5/6 Ed25519
397
    if is_responder {
398
        // Responder has CertType 5 (SIGNING_V_TLS)
399
        certs.push_cert(&identities.cert_sign_tls_ed);
400
    } else {
401
        // Initiator has CertType 6 (SIGINING_V_LINK_AUTH)
402
        certs.push_cert(&identities.cert_sign_link_auth_ed);
403
    }
404
    certs
405
}
406

            
407
/// Build a [`msg::Netinfo`] cell from the given peer IPs and our advertised addresses.
408
///
409
/// Both relay initiator and responder handshake use this.
410
pub(crate) fn build_netinfo_cell<S>(
411
    peer_ip: Option<IpAddr>,
412
    my_addrs: Vec<IpAddr>,
413
    sleep_prov: &S,
414
) -> Result<msg::Netinfo>
415
where
416
    S: CoarseTimeProvider + SleepProvider,
417
{
418
    // Unix timestamp but over 32bit. This will be sad in 2038 but proposal 338 addresses this
419
    // issue with a change to 64bit.
420
    let timestamp = sleep_prov
421
        .wallclock()
422
        .duration_since(UNIX_EPOCH)
423
        .map_err(|e| internal!("Wallclock may have gone backwards: {e}"))?
424
        .as_secs()
425
        .try_into()
426
        .map_err(|e| internal!("Wallclock secs fail to convert to 32bit: {e}"))?;
427
    Ok(msg::Netinfo::from_relay(timestamp, peer_ip, my_addrs))
428
}