1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
//! The [`Keystore`] trait and its implementations.
pub(crate) mod arti;
#[cfg(feature = "ctor-keystore")]
pub(crate) mod ctor;
pub(crate) mod fs_utils;
#[cfg(feature = "ephemeral-keystore")]
pub(crate) mod ephemeral;
use tor_key_forge::{EncodableItem, ErasedKey, KeystoreItemType};
use crate::{KeyPath, KeySpecifier, KeystoreId, Result};
/// A generic key store.
pub trait Keystore: Send + Sync + 'static {
/// An identifier for this key store instance.
///
/// This identifier is used by some [`KeyMgr`](crate::KeyMgr) APIs to identify a specific key
/// store.
fn id(&self) -> &KeystoreId;
/// Check if the key identified by `key_spec` exists in this key store.
fn contains(&self, key_spec: &dyn KeySpecifier, item_type: &KeystoreItemType) -> Result<bool>;
/// Retrieve the key identified by `key_spec`.
///
/// Returns `Ok(Some(key))` if the key was successfully retrieved. Returns `Ok(None)` if the
/// key does not exist in this key store.
fn get(
&self,
key_spec: &dyn KeySpecifier,
item_type: &KeystoreItemType,
) -> Result<Option<ErasedKey>>;
/// Write `key` to the key store.
//
// Note: the item_type argument here might seem redundant: `key` implements `EncodableItem`,
// which has a `item_type` function. However:
// * `item_type` is an associated function on `EncodableItem`, not a method, which means we
// can't call it on `key: &dyn EncodableItem` (you can't call an associated function of trait
// object). The caller of `Keystore::insert` (i.e. `KeyMgr`) OTOH _can_ call `K::item_type()`
// on the `EncodableItem` because the concrete type `K` that implements `EncodableItem` is
// known.
// * one could argue I should make `item_type` a `&self` method rather than an associated function,
// which would fix this problem (and enable us to remove the additional `item_type` param).
// However, that would break `KeyMgr::remove`, which calls
// `store.remove(key_spec, K::Key::item_type())`, where `K` is a type parameter specified by
// the caller (in `KeyMgr::remove` we don't have a `value: K`, so we can't call `item_type` if
// `item_type` is a `&self` method)...
//
// TODO: Maybe we can refactor this API and remove the "redundant" param somehow.
fn insert(
&self,
key: &dyn EncodableItem,
key_spec: &dyn KeySpecifier,
item_type: &KeystoreItemType,
) -> Result<()>;
/// Remove the specified key.
///
/// A return value of `Ok(None)` indicates the key doesn't exist in this key store, whereas
/// `Ok(Some(())` means the key was successfully removed.
///
/// Returns `Err` if an error occurred while trying to remove the key.
fn remove(
&self,
key_spec: &dyn KeySpecifier,
item_type: &KeystoreItemType,
) -> Result<Option<()>>;
/// List all the keys in this keystore.
fn list(&self) -> Result<Vec<(KeyPath, KeystoreItemType)>>;
}
|