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
128
129
130
131
132
133
134
135
use crate::TinkError;
use lazy_static::lazy_static;
use std::{
collections::HashMap,
sync::{Arc, RwLock},
};
mod kms_client;
pub use kms_client::*;
mod key_manager;
pub use key_manager::*;
mod key_templates;
pub use key_templates::*;
lazy_static! {
static ref KEY_MANAGERS: RwLock<HashMap<&'static str, Arc<dyn KeyManager>>> =
RwLock::new(HashMap::new());
static ref KMS_CLIENTS: RwLock<Vec<Arc<dyn KmsClient>>> = RwLock::new(Vec::new());
}
const MERR: &str = "global KEY_MANAGERS lock poisoned";
const CERR: &str = "global KMS_CLIENTS lock poisoned";
pub fn register_key_manager<T>(km: Arc<T>) -> Result<(), TinkError>
where
T: 'static + KeyManager,
{
let mut key_mgrs = KEY_MANAGERS.write().expect(MERR);
let type_url = km.type_url();
if key_mgrs.contains_key(type_url) {
return Err(format!(
"registry::register_key_manager: type {} already registered",
type_url
)
.into());
}
key_mgrs.insert(type_url, km);
Ok(())
}
pub fn get_key_manager(type_url: &str) -> Result<Arc<dyn KeyManager>, TinkError> {
let key_mgrs = KEY_MANAGERS.read().expect(MERR);
let km = key_mgrs.get(type_url).ok_or_else(|| {
TinkError::new(&format!(
"registry::get_key_manager: unsupported key type: {}",
type_url
))
})?;
Ok(km.clone())
}
pub fn new_key_data(kt: &tink_proto::KeyTemplate) -> Result<tink_proto::KeyData, TinkError> {
get_key_manager(&kt.type_url)?.new_key_data(&kt.value)
}
pub fn new_key(kt: &tink_proto::KeyTemplate) -> Result<Vec<u8>, TinkError> {
get_key_manager(&kt.type_url)?.new_key(&kt.value)
}
pub fn primitive_from_key_data(kd: &tink_proto::KeyData) -> Result<crate::Primitive, TinkError> {
primitive(&kd.type_url, &kd.value)
}
pub fn primitive(type_url: &str, sk: &[u8]) -> Result<crate::Primitive, TinkError> {
if sk.is_empty() {
return Err("registry::primitive: invalid serialized key".into());
}
get_key_manager(type_url)?.primitive(sk)
}
pub fn register_kms_client<T>(k: T)
where
T: 'static + KmsClient,
{
let mut kms_clients = KMS_CLIENTS.write().expect(CERR);
kms_clients.push(Arc::new(k));
}
pub fn clear_kms_clients() {
let mut kms_clients = KMS_CLIENTS.write().expect(CERR);
kms_clients.clear();
}
pub fn get_kms_client(key_uri: &str) -> Result<Arc<dyn KmsClient>, TinkError> {
let kms_clients = KMS_CLIENTS.read().expect(CERR);
for k in kms_clients.iter() {
if k.supported(key_uri) {
return Ok(k.clone());
}
}
Err(format!("KMS client supporting {} not found", key_uri).into())
}