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}