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