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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
//! The [`Keystore`] trait and its implementations.
pub(crate) mod arti;
use tor_hscrypto::pk::{HsClientDescEncSecretKey, HsClientIntroAuthKeypair};
use tor_llcrypto::pk::{curve25519, ed25519};
use crate::key_type::KeyType;
use crate::{KeySpecifier, Result};
use std::any::Any;
/// A type-erased key returned by a [`Keystore`].
pub type ErasedKey = Box<dyn Any>;
/// A generic key store.
//
// TODO HSS: eventually this will be able to store items that aren't keys (such as certificates and
// perhaps other types of sensitive data). We should consider renaming this (and other Key* types)
// to something more generic (such as `SecretStore` or `Vault`).
pub trait Keystore: Send + Sync + 'static {
/// 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, key_type: KeyType) -> Result<Option<ErasedKey>>;
/// Write `key` to the key store.
//
// TODO HSS: the key_type argument here might seem redundant: `key` implements `EncodableKey`,
// which has a `key_type` function. However:
// * `key_type` is an associated function on `EncodableKey`, not a method, which means we
// can't call it on `key: &dyn EncodableKey` (you can't call an associated function of trait
// object). The caller of `Keystore::insert` (i.e. `KeyMgr`) OTOH _can_ call `K::key_type()`
// on the `EncodableKey` because the concrete type `K` that implements `EncodableKey` is
// known.
// * one argue I should make `key_type` a `&self` method rather than an associated function,
// which would fix this problem (and enable us to remove the additional `key_type` param).
// However, that would break `KeyMgr::remove`, which calls
// `store.remove(key_spec, K::Key::key_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 `key_type` if
// `key_type` is a `&self` method)...
//
// Maybe we can refactor this API and remove the "redundant" param somehow.
fn insert(
&self,
key: &dyn EncodableKey,
key_spec: &dyn KeySpecifier,
key_type: KeyType,
) -> Result<()>;
/// Remove the specified key.
///
/// A return vaue 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, key_type: KeyType) -> Result<Option<()>>;
/// Check whether the key bundle associated with the specified identity is in the store.
fn has_key_bundle(&self, key_spec: &dyn KeySpecifier) -> Result<bool>;
}
/// A key that can be serialized to, and deserialized from, a format used by a
/// [`Keystore`](crate::Keystore).
pub trait EncodableKey {
/// The type of the key.
fn key_type() -> KeyType
where
Self: Sized;
}
impl EncodableKey for curve25519::StaticSecret {
fn key_type() -> KeyType
where
Self: Sized,
{
KeyType::X25519StaticSecret
}
}
impl EncodableKey for ed25519::Keypair {
fn key_type() -> KeyType
where
Self: Sized,
{
KeyType::Ed25519Keypair
}
}
/// A key that can be converted to an [`EncodableKey`].
//
// TODO HSS: try to fold this trait into `EncodableKey`.
pub trait ToEncodableKey {
/// The key type this can be converted to/from.
type Key: EncodableKey + 'static;
/// Convert this key to a type that implements [`EncodableKey`].
fn to_encodable_key(self) -> Self::Key;
/// Convert an [`EncodableKey`] to another key type.
fn from_encodable_key(key: Self::Key) -> Self;
}
impl ToEncodableKey for HsClientDescEncSecretKey {
type Key = curve25519::StaticSecret;
fn to_encodable_key(self) -> Self::Key {
self.into()
}
fn from_encodable_key(key: Self::Key) -> Self {
HsClientDescEncSecretKey::from(key)
}
}
impl ToEncodableKey for HsClientIntroAuthKeypair {
type Key = ed25519::Keypair;
fn to_encodable_key(self) -> Self::Key {
self.into()
}
fn from_encodable_key(key: Self::Key) -> Self {
HsClientIntroAuthKeypair::from(key)
}
}
|