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// NOTE: Some methods require a `KeystoreEntryResult<KeystoreEntry>` as an
20// argument (e.g.: `KeyMgr::raw_keystore_entry`). For this reason implementing
21// `From<UnrecognizedEntryError> for <KeystoreEntryResult<KeystoreEntry>>` makes
22// `UnrecognizedEntryError` more ergonomic.
23impl<'a> From<UnrecognizedEntryError> for KeystoreEntryResult<KeystoreEntry<'a>> {
24 fn from(val: UnrecognizedEntryError) -> Self {
25 Err(val)
26 }
27}
28
29/// A generic key store.
30pub trait Keystore: Send + Sync + 'static {
31 /// An identifier for this key store instance.
32 ///
33 /// This identifier is used by some [`KeyMgr`](crate::KeyMgr) APIs to identify a specific key
34 /// store.
35 fn id(&self) -> &KeystoreId;
36
37 /// Check if the key identified by `key_spec` exists in this key store.
38 fn contains(&self, key_spec: &dyn KeySpecifier, item_type: &KeystoreItemType) -> Result<bool>;
39
40 /// Retrieve the key identified by `key_spec`.
41 ///
42 /// Returns `Ok(Some(key))` if the key was successfully retrieved. Returns `Ok(None)` if the
43 /// key does not exist in this key store.
44 fn get(
45 &self,
46 key_spec: &dyn KeySpecifier,
47 item_type: &KeystoreItemType,
48 ) -> Result<Option<ErasedKey>>;
49
50 /// Convert the specified string to a [`RawEntryId`] that
51 /// represents the raw unique identifier of an entry in this keystore.
52 ///
53 /// The specified `raw_id` is allowed to represent an unrecognized
54 /// or nonexistent entry.
55 ///
56 /// Returns a `RawEntryId` that is specific to this [`Keystore`] implementation.
57 ///
58 /// Returns an error if `raw_id` cannot be converted to
59 /// the correct variant for this keystore implementation
60 /// (e.g.: `RawEntryId::Path(PathBuf) for [`ArtiNativeKeystore`](crate::ArtiNativeKeystore)).
61 ///
62 /// Important: a `RawEntryId` should only be used to access
63 /// the entries of the keystore it originates from
64 /// (if used with a *different* keystore, the behavior is unspecified:
65 /// the operation may fail, it may succeed, or it may lead to the
66 /// wrong entry being accessed).
67 #[cfg(feature = "onion-service-cli-extra")]
68 fn raw_entry_id(&self, raw_id: &str) -> Result<RawEntryId>;
69
70 /// Write `key` to the key store.
71 fn insert(&self, key: &dyn EncodableItem, key_spec: &dyn KeySpecifier) -> Result<()>;
72
73 /// Remove the specified key.
74 ///
75 /// A return value of `Ok(None)` indicates the key doesn't exist in this key store, whereas
76 /// `Ok(Some(())` means the key was successfully removed.
77 ///
78 /// Returns `Err` if an error occurred while trying to remove the key.
79 fn remove(
80 &self,
81 key_spec: &dyn KeySpecifier,
82 item_type: &KeystoreItemType,
83 ) -> Result<Option<()>>;
84
85 /// Remove the specified keystore entry.
86 ///
87 /// This method accepts both recognized and unrecognized entries, identified
88 /// by a [`RawEntryId`] instance.
89 ///
90 /// If the entry wasn't successfully removed, or if the entry doesn't
91 /// exists, `Err` is returned.
92 #[cfg(feature = "onion-service-cli-extra")]
93 #[cfg_attr(docsrs, doc(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}