Skip to main content

tor_keymgr/
keystore.rs

1//! The [`Keystore`] trait and its implementations.
2
3pub(crate) mod arti;
4#[cfg(feature = "ctor-keystore")]
5pub(crate) mod ctor;
6pub(crate) mod fs_utils;
7
8#[cfg(feature = "ephemeral-keystore")]
9pub(crate) mod ephemeral;
10
11use tor_key_forge::{EncodableItem, ErasedKey, KeystoreItemType};
12
13use crate::raw::RawEntryId;
14use crate::{KeySpecifier, KeystoreEntry, KeystoreId, Result, UnrecognizedEntryError};
15
16/// A type alias returned by `Keystore::list`.
17pub type KeystoreEntryResult<T> = std::result::Result<T, UnrecognizedEntryError>;
18
19/// A generic key store.
20pub trait Keystore: Send + Sync + 'static {
21    /// An identifier for this key store instance.
22    ///
23    /// This identifier is used by some [`KeyMgr`](crate::KeyMgr) APIs to identify a specific key
24    /// store.
25    fn id(&self) -> &KeystoreId;
26
27    /// Check if the key identified by `key_spec` exists in this key store.
28    fn contains(&self, key_spec: &dyn KeySpecifier, item_type: &KeystoreItemType) -> Result<bool>;
29
30    /// Retrieve the key identified by `key_spec`.
31    ///
32    /// Returns `Ok(Some(key))` if the key was successfully retrieved. Returns `Ok(None)` if the
33    /// key does not exist in this key store.
34    fn get(
35        &self,
36        key_spec: &dyn KeySpecifier,
37        item_type: &KeystoreItemType,
38    ) -> Result<Option<ErasedKey>>;
39
40    /// Convert the specified string to a [`RawEntryId`] that
41    /// represents the raw unique identifier of an entry in this keystore.
42    ///
43    /// The specified `raw_id` is allowed to represent an unrecognized
44    /// or nonexistent entry.
45    ///
46    /// Implementations that do not have `RawEntryId`s
47    /// that are deserializable from string will return an error.
48    //
49    // TODO: currently, the only such implementation is the EphemeralKeystore.
50    // If we ever decide to remove EphemeralKeystore
51    // (see https://gitlab.torproject.org/tpo/core/arti/-/merge_requests/2580),
52    // we should consider rethinking this API too.
53    //
54    // For example, we might want to remove this function altogether,
55    // and let the user create the RawEntryId instead.
56    //
57    ///
58    /// Returns a `RawEntryId` that is specific to this [`Keystore`] implementation.
59    ///
60    /// Returns an error if `raw_id` cannot be converted to
61    /// the correct variant for this keystore implementation
62    /// (e.g.: `RawEntryId::Path(PathBuf) for [`ArtiNativeKeystore`](crate::ArtiNativeKeystore)).
63    ///
64    /// Important: a `RawEntryId` should only be used to access
65    /// the entries of the keystore it originates from
66    /// (if used with a *different* keystore, the behavior is unspecified:
67    /// the operation may fail, it may succeed, or it may lead to the
68    /// wrong entry being accessed).
69    #[cfg(feature = "onion-service-cli-extra")]
70    fn raw_entry_id(&self, raw_id: &str) -> Result<RawEntryId>;
71
72    /// Write `key` to the key store.
73    fn insert(&self, key: &dyn EncodableItem, key_spec: &dyn KeySpecifier) -> Result<()>;
74
75    /// Remove the specified key.
76    ///
77    /// A return value of `Ok(None)` indicates the key doesn't exist in this key store, whereas
78    /// `Ok(Some(())` means the key was successfully removed.
79    ///
80    /// Returns `Err` if an error occurred while trying to remove the key.
81    fn remove(
82        &self,
83        key_spec: &dyn KeySpecifier,
84        item_type: &KeystoreItemType,
85    ) -> Result<Option<()>>;
86
87    /// Remove a keystore entry given its [`RawEntryId`].
88    ///
89    /// Unlike [`remove`](Keystore::remove), this method can also remove
90    /// entries that are unrecognized
91    /// (i.e. those that do not have a corresponding [`KeySpecifier`] and [`KeystoreItemType`]).
92    ///
93    /// Returns an error if the entry couldn't be removed, or if the entry doesn't exist.
94    #[cfg(feature = "onion-service-cli-extra")]
95    fn remove_unchecked(&self, entry_id: &RawEntryId) -> Result<()>;
96
97    /// List all the entries in this keystore.
98    ///
99    /// Returns a list of results, where `Ok` signifies a recognized entry,
100    /// and `Err(KeystoreListError)` an unrecognized one.
101    /// An entry is said to be recognized if it has a valid [`KeyPath`](crate).
102    fn list(&self) -> Result<Vec<KeystoreEntryResult<KeystoreEntry>>>;
103}