1//! Entry point of a Tor relay that is the [`TorRelay`] objects
23use std::sync::Arc;
45use tor_chanmgr::Dormancy;
6use tor_config_path::CfgPathResolver;
7use tor_error::internal;
8use tor_keymgr::{
9 ArtiEphemeralKeystore, ArtiNativeKeystore, KeyMgr, KeyMgrBuilder, KeystoreSelector,
10};
11use tor_memquota::ArcMemoryQuotaTrackerExt as _;
12use tor_netdir::params::NetParameters;
13use tor_proto::memquota::ToplevelAccount;
14use tor_relay_crypto::pk::{RelayIdentityKeypair, RelayIdentityKeypairSpecifier};
15use tor_rtcompat::Runtime;
16use tracing::info;
1718use crate::config::TorRelayConfig;
19use crate::err::ErrorDetail;
2021/// Represent an active Relay on the Tor network.
22#[derive(Clone)]
23pub(crate) struct TorRelay<R: Runtime> {
24/// Asynchronous runtime object.
25#[allow(unused)] // TODO RELAY remove
26runtime: R,
27/// Path resolver for expanding variables in [`CfgPath`](tor_config_path::CfgPath)s.
28#[allow(unused)] // TODO RELAY remove
29path_resolver: CfgPathResolver,
30/// Channel manager, used by circuits etc.,
31#[allow(unused)] // TODO RELAY remove
32chanmgr: Arc<tor_chanmgr::ChanMgr<R>>,
33/// Key manager holding all relay keys and certificates.
34#[allow(unused)] // TODO RELAY remove
35keymgr: Arc<KeyMgr>,
36}
3738impl<R: Runtime> TorRelay<R> {
39/// Create a new Tor relay with the given [runtime][tor_rtcompat] and configuration.
40pub(crate) fn new(
41 runtime: R,
42 config: &TorRelayConfig,
43 path_resolver: CfgPathResolver,
44 ) -> Result<Self, ErrorDetail> {
45let keymgr = Self::create_keymgr(config, &path_resolver)?;
46let chanmgr = Arc::new(tor_chanmgr::ChanMgr::new(
47 runtime.clone(),
48&config.channel,
49 Dormancy::Active,
50&NetParameters::default(),
51 ToplevelAccount::new_noop(), // TODO RELAY get mq from TorRelay
52));
5354Ok(Self {
55 runtime,
56 path_resolver,
57 chanmgr,
58 keymgr,
59 })
60 }
6162/// Create the [key manager](KeyMgr).
63fn create_keymgr(
64 config: &TorRelayConfig,
65 path_resolver: &CfgPathResolver,
66 ) -> Result<Arc<KeyMgr>, ErrorDetail> {
67let key_store_dir = config.storage.keystore_dir(path_resolver)?;
68let permissions = config.storage.permissions();
6970// Store for the short-term keys that we don't need to keep on disk. The store identifier
71 // is relay explicit because it can be used in other crates for channel and circuit.
72let ephemeral_store = ArtiEphemeralKeystore::new("relay-ephemeral".into());
73let persistent_store =
74 ArtiNativeKeystore::from_path_and_mistrust(&key_store_dir, permissions)?;
75info!("Using relay keystore from {key_store_dir:?}");
7677let keymgr = Arc::new(
78 KeyMgrBuilder::default()
79 .primary_store(Box::new(persistent_store))
80 .set_secondary_stores(vec![Box::new(ephemeral_store)])
81 .build()
82 .map_err(|e| internal!("Failed to build KeyMgr: {e}"))?,
83 );
8485// Attempt to generate any missing keys/cert from the KeyMgr.
86Self::try_generate_keys(&keymgr)?;
8788Ok(keymgr)
89 }
9091/// Generate the relay keys.
92fn try_generate_keys(keymgr: &KeyMgr) -> Result<(), ErrorDetail> {
93let mut rng = tor_llcrypto::rng::CautiousRng;
9495// Attempt to get the relay long-term identity key from the key manager. If not present,
96 // generate it. We need this key to sign the signing certificates.
97let _kp_relay_id = keymgr.get_or_generate::<RelayIdentityKeypair>(
98&RelayIdentityKeypairSpecifier::new(),
99 KeystoreSelector::default(),
100&mut rng,
101 )?;
102103// TODO: Once certificate supports is added to the KeyMgr, we need to get/gen the
104 // RelaySigning (KP_relaysign_ed) certs from the native persistent store.
105 //
106 // If present, rotate it if expired. Else, generate it. Rotation or creation require the
107 // relay identity keypair (above) in order to sign the RelaySigning.
108 //
109 // We then need to generate the RelayLink (KP_link_ed) certificate which is in turn signed
110 // by the RelaySigning cert.
111112Ok(())
113 }
114}