tor_proto/relay/
channel.rs

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
6pub(crate) mod handshake;
7
8use digest::Digest;
9use futures::{AsyncRead, AsyncWrite};
10use std::sync::Arc;
11
12use tor_cert::{Ed25519Cert, rsa::RsaCrosscert};
13use tor_llcrypto as ll;
14use tor_llcrypto::pk::{ed25519::Ed25519Identity, rsa::RsaIdentity};
15use tor_rtcompat::{CoarseTimeProvider, SleepProvider, StreamOps};
16
17use crate::{channel::RelayInitiatorHandshake, memquota::ChannelAccount};
18
19/// Object containing the key and certificate that basically identifies us as a relay. They are
20/// used for channel authentication.
21///
22/// We use this intermediary object in order to not have tor-proto crate have access to the KeyMgr
23/// meaning access to all keys. This restricts the view to what is needed.
24#[expect(unused)] // TODO(relay). remove
25pub struct RelayIdentities {
26    /// As a relay, our RSA identity key: KP_relayid_rsa
27    pub(crate) rsa_id: RsaIdentity,
28    /// As a relay, our Ed identity key: KP_relayid_ed
29    pub(crate) ed_id: Ed25519Identity,
30    /// The Ed25519 identity signing cert (CertType 4)
31    pub(crate) cert_id_sign_ed: Ed25519Cert,
32    /// The Ed25519 signing TLS cert (CertType 5)
33    pub(crate) cert_sign_tls_ed: Ed25519Cert,
34    /// The Ed25519 signing link auth cert (CertType 6)
35    pub(crate) cert_sign_link_auth_ed: Ed25519Cert,
36    /// Legacy: the RSA identity X509 cert (CertType 2). We only have the bytes here as
37    /// create_legacy_rsa_id_cert() takes a key and gives us back the encoded cert.
38    pub(crate) cert_id_x509_rsa: Vec<u8>,
39    /// Legacy: the RSA identity cert (CertType 7)
40    pub(crate) cert_id_rsa: RsaCrosscert,
41}
42
43impl RelayIdentities {
44    /// Constructor.
45    pub fn new(
46        rsa_id: RsaIdentity,
47        ed_id: Ed25519Identity,
48        cert_id_sign_ed: Ed25519Cert,
49        cert_sign_tls_ed: Ed25519Cert,
50        cert_sign_link_auth_ed: Ed25519Cert,
51        cert_id_x509_rsa: Vec<u8>,
52        cert_id_rsa: RsaCrosscert,
53    ) -> Self {
54        Self {
55            rsa_id,
56            ed_id,
57            cert_id_sign_ed,
58            cert_sign_tls_ed,
59            cert_sign_link_auth_ed,
60            cert_id_x509_rsa,
61            cert_id_rsa,
62        }
63    }
64}
65
66impl RelayIdentities {
67    /// Return our Ed identity key (KP_relayid_ed) as bytes.
68    pub(crate) fn ed_id_bytes(&self) -> [u8; 32] {
69        self.ed_id.into()
70    }
71
72    /// Return the digest of the RSA x509 certificate (CertType 2) as bytes.
73    pub(crate) fn rsa_x509_digest(&self) -> [u8; 32] {
74        ll::d::Sha256::digest(&self.cert_id_x509_rsa).into()
75    }
76}
77
78/// Structure for building and launching a relay Tor channel.
79#[derive(Default)]
80#[non_exhaustive]
81pub struct RelayChannelBuilder;
82
83impl RelayChannelBuilder {
84    /// Constructor.
85    pub fn new() -> Self {
86        Self::default()
87    }
88
89    /// Launch a new handshake over a TLS stream.
90    ///
91    /// After calling this function, you'll need to call `connect()` on the result to start the
92    /// handshake.  If that succeeds, you'll have authentication info from the relay: call
93    /// `check()` on the result to check that.  Finally, to finish the handshake, call `finish()`
94    /// on the result of _that_.
95    pub fn launch<T, S>(
96        self,
97        tls: T,
98        sleep_prov: S,
99        identities: Arc<RelayIdentities>,
100        memquota: ChannelAccount,
101    ) -> RelayInitiatorHandshake<T, S>
102    where
103        T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
104        S: CoarseTimeProvider + SleepProvider,
105    {
106        RelayInitiatorHandshake::new(tls, sleep_prov, identities, memquota)
107    }
108}