1
//! The [`Keystore`] trait and its implementations.
2

            
3
pub(crate) mod arti;
4
#[cfg(feature = "ctor-keystore")]
5
pub(crate) mod ctor;
6
pub(crate) mod fs_utils;
7

            
8
#[cfg(feature = "ephemeral-keystore")]
9
pub(crate) mod ephemeral;
10

            
11
use tor_key_forge::{EncodableItem, ErasedKey, KeystoreItemType};
12

            
13
use crate::raw::RawEntryId;
14
use crate::{KeySpecifier, KeystoreEntry, KeystoreId, Result, UnrecognizedEntryError};
15

            
16
/// A type alias returned by `Keystore::list`.
17
pub 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.
23
impl<'a> From<UnrecognizedEntryError> for KeystoreEntryResult<KeystoreEntry<'a>> {
24
    fn from(val: UnrecognizedEntryError) -> Self {
25
        Err(val)
26
    }
27
}
28

            
29
/// A generic key store.
30
pub 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
    fn remove_unchecked(&self, entry_id: &RawEntryId) -> Result<()>;
94

            
95
    /// List all the entries in this keystore.
96
    ///
97
    /// Returns a list of results, where `Ok` signifies a recognized entry,
98
    /// and `Err(KeystoreListError)` an unrecognized one.
99
    /// An entry is said to be recognized if it has a valid [`KeyPath`](crate).
100
    fn list(&self) -> Result<Vec<KeystoreEntryResult<KeystoreEntry>>>;
101
}