1
//! Entry point of a Tor relay that is the [`TorRelay`] objects
2

            
3
use std::sync::Arc;
4

            
5
use tor_chanmgr::Dormancy;
6
use tor_config_path::CfgPathResolver;
7
use tor_error::internal;
8
use tor_keymgr::{
9
    ArtiEphemeralKeystore, ArtiNativeKeystore, KeyMgr, KeyMgrBuilder, KeystoreSelector,
10
};
11
use tor_memquota::ArcMemoryQuotaTrackerExt as _;
12
use tor_netdir::params::NetParameters;
13
use tor_proto::memquota::ToplevelAccount;
14
use tor_relay_crypto::pk::{RelayIdentityKeypair, RelayIdentityKeypairSpecifier};
15
use tor_rtcompat::Runtime;
16
use tracing::info;
17

            
18
use crate::config::TorRelayConfig;
19
use crate::err::ErrorDetail;
20

            
21
/// Represent an active Relay on the Tor network.
22
#[derive(Clone)]
23
pub(crate) struct TorRelay<R: Runtime> {
24
    /// Asynchronous runtime object.
25
    #[allow(unused)] // TODO RELAY remove
26
    runtime: R,
27
    /// Path resolver for expanding variables in [`CfgPath`](tor_config_path::CfgPath)s.
28
    #[allow(unused)] // TODO RELAY remove
29
    path_resolver: CfgPathResolver,
30
    /// Channel manager, used by circuits etc.,
31
    #[allow(unused)] // TODO RELAY remove
32
    chanmgr: Arc<tor_chanmgr::ChanMgr<R>>,
33
    /// Key manager holding all relay keys and certificates.
34
    #[allow(unused)] // TODO RELAY remove
35
    keymgr: Arc<KeyMgr>,
36
}
37

            
38
impl<R: Runtime> TorRelay<R> {
39
    /// Create a new Tor relay with the given [runtime][tor_rtcompat] and configuration.
40
    pub(crate) fn new(
41
        runtime: R,
42
        config: &TorRelayConfig,
43
        path_resolver: CfgPathResolver,
44
    ) -> Result<Self, ErrorDetail> {
45
        let keymgr = Self::create_keymgr(config, &path_resolver)?;
46
        let 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
            Some(keymgr.clone()),
53
        ));
54

            
55
        Ok(Self {
56
            runtime,
57
            path_resolver,
58
            chanmgr,
59
            keymgr,
60
        })
61
    }
62

            
63
    /// Create the [key manager](KeyMgr).
64
    fn create_keymgr(
65
        config: &TorRelayConfig,
66
        path_resolver: &CfgPathResolver,
67
    ) -> Result<Arc<KeyMgr>, ErrorDetail> {
68
        let key_store_dir = config.storage.keystore_dir(path_resolver)?;
69
        let permissions = config.storage.permissions();
70

            
71
        // Store for the short-term keys that we don't need to keep on disk. The store identifier
72
        // is relay explicit because it can be used in other crates for channel and circuit.
73
        let ephemeral_store = ArtiEphemeralKeystore::new("relay-ephemeral".into());
74
        let persistent_store =
75
            ArtiNativeKeystore::from_path_and_mistrust(&key_store_dir, permissions)?;
76
        info!("Using relay keystore from {key_store_dir:?}");
77

            
78
        let keymgr = Arc::new(
79
            KeyMgrBuilder::default()
80
                .primary_store(Box::new(persistent_store))
81
                .set_secondary_stores(vec![Box::new(ephemeral_store)])
82
                .build()
83
                .map_err(|e| internal!("Failed to build KeyMgr: {e}"))?,
84
        );
85

            
86
        // Attempt to generate any missing keys/cert from the KeyMgr.
87
        Self::try_generate_keys(&keymgr)?;
88

            
89
        Ok(keymgr)
90
    }
91

            
92
    /// Generate the relay keys.
93
    fn try_generate_keys(keymgr: &KeyMgr) -> Result<(), ErrorDetail> {
94
        let mut rng = tor_llcrypto::rng::CautiousRng;
95

            
96
        // Attempt to get the relay long-term identity key from the key manager. If not present,
97
        // generate it. We need this key to sign the signing certificates.
98
        let _kp_relay_id = keymgr.get_or_generate::<RelayIdentityKeypair>(
99
            &RelayIdentityKeypairSpecifier::new(),
100
            KeystoreSelector::default(),
101
            &mut rng,
102
        )?;
103

            
104
        // TODO: Once certificate supports is added to the KeyMgr, we need to get/gen the
105
        // RelaySigning (KP_relaysign_ed) certs from the native persistent store.
106
        //
107
        // If present, rotate it if expired. Else, generate it. Rotation or creation require the
108
        // relay identity keypair (above) in order to sign the RelaySigning.
109
        //
110
        // We then need to generate the RelayLink (KP_link_ed) certificate which is in turn signed
111
        // by the RelaySigning cert.
112

            
113
        Ok(())
114
    }
115
}