1use crate::{JSON_FILE_EXTENSION, TRUSTCHAIN_DATA};
3use serde_json::{from_str, to_string_pretty as to_json};
4use ssi::jwk::JWK;
5use ssi::one_or_many::OneOrMany;
6use std::fs::{File, OpenOptions};
7use std::io::{Read, Write};
8use std::path::{Path, PathBuf};
9use thiserror::Error;
10
11#[derive(Error, Debug)]
13pub enum KeyManagerError {
14 #[error("Key does not exist.")]
16 FailedToLoadKey,
17 #[error("Key could not be saved.")]
19 FailedToSaveKey,
20 #[error("Failed to read UTF-8 data.")]
22 FailedToReadUTF8,
23 #[error("Failed to parse JSON string to JWK.")]
25 FailedToParseJWK,
26 #[error("Failed to create path for DID keys during save.")]
28 FailedToCreateDir,
29 #[error("Failed to remove key.")]
31 FailedToRemoveKey,
32 #[error("No TRUSTCHAIN_DATA environment variable.")]
34 TrustchainDataNotPresent,
35 #[error("Expected only one key but found many.")]
37 InvalidManyKeys,
38 #[error(transparent)]
40 SSIJWKError(#[from] ssi::jwk::Error),
41}
42
43#[derive(Debug, PartialEq, Eq, Hash)]
45pub enum KeyType {
46 UpdateKey,
47 NextUpdateKey,
48 RecoveryKey,
49 SigningKey,
50}
51
52pub trait ControllerKeyManager: KeyManager {
53 fn read_recovery_key(&self, did_suffix: &str) -> Result<JWK, KeyManagerError> {
55 let key = self.read_key(did_suffix, &KeyType::RecoveryKey);
56 self.only_one_key(key)
57 }
58 fn read_update_key(&self, did_suffix: &str) -> Result<JWK, KeyManagerError> {
60 let key = self.read_key(did_suffix, &KeyType::UpdateKey);
61 self.only_one_key(key)
62 }
63
64 fn read_next_update_key(&self, did_suffix: &str) -> Result<JWK, KeyManagerError> {
66 let key = self.read_key(did_suffix, &KeyType::NextUpdateKey);
67 self.only_one_key(key)
68 }
69
70 fn apply_next_update_key(
72 &self,
73 did_suffix: &str,
74 next_update_key: &JWK,
75 ) -> Result<(), KeyManagerError> {
76 self.save_key(did_suffix, KeyType::UpdateKey, next_update_key, true)?;
78
79 self.remove_keys(did_suffix, &KeyType::NextUpdateKey)?;
81
82 Ok(())
83 }
84}
85
86pub trait AttestorKeyManager: KeyManager {
87 fn read_signing_keys(&self, did_suffix: &str) -> Result<OneOrMany<JWK>, KeyManagerError> {
89 self.read_key(did_suffix, &KeyType::SigningKey)
90 }
91}
92
93pub trait KeyManager {
94 fn read_key(
96 &self,
97 did_suffix: &str,
98 key_type: &KeyType,
99 ) -> Result<OneOrMany<JWK>, KeyManagerError> {
100 let path = &self.get_path(did_suffix, key_type, false)?;
102
103 let file = File::open(path);
105
106 if let Ok(file) = file {
108 self.read_keys_from(Box::new(file))
109 } else {
110 Err(KeyManagerError::FailedToLoadKey)
111 }
112 }
113
114 fn only_one_key(
116 &self,
117 key: Result<OneOrMany<JWK>, KeyManagerError>,
118 ) -> Result<JWK, KeyManagerError> {
119 match key {
120 Ok(OneOrMany::One(x)) => Ok(x),
121 Ok(OneOrMany::Many(_)) => Err(KeyManagerError::InvalidManyKeys),
122 Err(e) => Err(e),
123 }
124 }
125
126 fn read_keys_from(&self, mut reader: Box<dyn Read>) -> Result<OneOrMany<JWK>, KeyManagerError> {
128 let buf: &mut String = &mut String::new();
130 let read_result = reader.read_to_string(buf);
131
132 let jwk_result = match read_result {
134 Ok(_) => from_str::<OneOrMany<JWK>>(buf),
135 Err(_) => return Err(KeyManagerError::FailedToReadUTF8),
136 };
137
138 match jwk_result {
140 Ok(x) => Ok(x),
141 Err(_) => Err(KeyManagerError::FailedToParseJWK),
142 }
143 }
144
145 fn get_path(
147 &self,
148 did_suffix: &str,
149 key_type: &KeyType,
150 dir_only: bool,
151 ) -> Result<PathBuf, KeyManagerError> {
152 let file_name = match key_type {
154 KeyType::UpdateKey => format!("update_key{}", JSON_FILE_EXTENSION),
155 KeyType::NextUpdateKey => format!("next_update_key{}", JSON_FILE_EXTENSION),
156 KeyType::RecoveryKey => format!("recovery_key{}", JSON_FILE_EXTENSION),
157 KeyType::SigningKey => format!("signing_key{}", JSON_FILE_EXTENSION),
158 };
159
160 let path: String = match std::env::var(TRUSTCHAIN_DATA) {
162 Ok(val) => val,
163 Err(_) => return Err(KeyManagerError::TrustchainDataNotPresent),
164 };
165
166 let directory = Path::new(path.as_str())
168 .join("key_manager")
169 .join(did_suffix);
170
171 if dir_only {
173 Ok(directory)
174 } else {
175 Ok(directory.join(file_name))
176 }
177 }
178
179 fn keys_exist(&self, did_suffix: &str, key_type: &KeyType) -> bool {
181 self.get_path(did_suffix, key_type, false).unwrap().exists()
182 }
183
184 fn save_key(
186 &self,
187 did_suffix: &str,
188 key_type: KeyType,
189 key: &JWK,
190 overwrite: bool,
191 ) -> Result<(), KeyManagerError> {
192 self.save_keys(
193 did_suffix,
194 key_type,
195 &OneOrMany::One(key.clone()),
196 overwrite,
197 )
198 }
199
200 fn save_keys(
202 &self,
203 did_suffix: &str,
204 key_type: KeyType,
205 keys: &OneOrMany<JWK>,
206 overwrite: bool,
207 ) -> Result<(), KeyManagerError> {
208 let directory = &self.get_path(did_suffix, &key_type, true)?;
210 let path = &self.get_path(did_suffix, &key_type, false)?;
211
212 if self.keys_exist(did_suffix, &key_type) && !overwrite {
214 return Err(KeyManagerError::FailedToSaveKey);
215 }
216
217 match std::fs::create_dir_all(directory) {
219 Ok(_) => (),
220 Err(_) => return Err(KeyManagerError::FailedToCreateDir),
221 };
222
223 let file = OpenOptions::new()
225 .create(true)
226 .write(true)
227 .truncate(true)
228 .open(path);
229
230 if let Ok(mut file) = file {
232 match writeln!(file, "{}", &to_json(keys).unwrap()) {
233 Ok(_) => Ok(()),
234 Err(_) => Err(KeyManagerError::FailedToSaveKey),
235 }
236 } else {
237 Err(KeyManagerError::FailedToSaveKey)
238 }
239 }
240
241 fn remove_keys(&self, did_suffix: &str, key_type: &KeyType) -> Result<(), KeyManagerError> {
243 let path = &self.get_path(did_suffix, key_type, false)?;
245
246 if path.is_file() {
248 match std::fs::remove_file(path) {
249 Ok(_) => Ok(()),
250 Err(_) => Err(KeyManagerError::FailedToRemoveKey),
251 }
252 } else {
253 Err(KeyManagerError::FailedToRemoveKey)
254 }
255 }
256}
257
258#[cfg(test)]
259pub mod tests {
260 use super::*;
261 use crate::data::{
262 TEST_NEXT_UPDATE_KEY, TEST_RECOVERY_KEY, TEST_SIGNING_KEYS, TEST_UPDATE_KEY,
263 };
264 use crate::utils::{generate_key, init};
265 use mockall::mock;
266 use ssi::jwk::Params;
267 use std::io::Read;
268
269 pub struct TestKeyManager;
270
271 impl KeyManager for TestKeyManager {}
272 impl AttestorKeyManager for TestKeyManager {}
273 impl ControllerKeyManager for TestKeyManager {}
274
275 #[test]
276 fn test_generate_key() {
277 let result = generate_key();
278
279 match result.params {
281 ssi::jwk::Params::EC(ecparams) => {
282 assert_eq!(ecparams.curve, Some(String::from("secp256k1")))
283 }
284 _ => panic!(),
285 }
286 }
287
288 mock! {
290 Reader {} impl Read for Reader { fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize>;
293 fn read_to_string(&mut self, buf: &mut String) -> std::io::Result<usize>;
294 }
295 }
296
297 #[test]
298 fn test_read_update_key() -> Result<(), Box<dyn std::error::Error>> {
299 init();
301
302 let did_suffix = "test_read_update_key";
304
305 let expected_key: JWK = serde_json::from_str(TEST_UPDATE_KEY).unwrap();
307
308 let target = TestKeyManager;
309 target.save_key(did_suffix, KeyType::UpdateKey, &expected_key, true)?;
310
311 let res = target.read_update_key(did_suffix);
313
314 assert!(res.is_ok());
316
317 assert_eq!(expected_key, res.unwrap());
319
320 Ok(())
321 }
322
323 #[test]
324 fn test_read_recovery_key() -> Result<(), Box<dyn std::error::Error>> {
325 init();
327
328 let did_suffix = "test_read_recovery_key";
330
331 let expected_key: JWK = serde_json::from_str(TEST_RECOVERY_KEY)?;
333
334 let target = TestKeyManager;
335 target.save_key(did_suffix, KeyType::RecoveryKey, &expected_key, true)?;
336
337 let res = target.read_recovery_key(did_suffix);
339
340 assert!(res.is_ok());
342
343 assert_eq!(expected_key, res.unwrap());
345
346 Ok(())
347 }
348
349 #[test]
350 fn test_read_keys_from() {
351 let mut mock_reader = MockReader::new();
353 mock_reader.expect_read_to_string().return_once(move |buf| {
354 buf.push_str(TEST_UPDATE_KEY);
356 std::io::Result::Ok(0)
358 });
359
360 let target = TestKeyManager;
361 let result = target.read_keys_from(Box::new(mock_reader));
362 assert!(result.is_ok());
363
364 let key = result.unwrap();
365
366 if let OneOrMany::One(key) = key {
368 match &key.params {
369 Params::EC(ecparams) => assert_eq!(ecparams.curve, Some(String::from("secp256k1"))),
370 _ => panic!(),
371 }
372 } else {
373 panic!()
374 }
375 }
376
377 #[test]
378 fn test_keys_exist() -> Result<(), Box<dyn std::error::Error>> {
379 init();
381
382 let target = TestKeyManager;
383
384 let expected_key: JWK = serde_json::from_str(TEST_UPDATE_KEY)?;
386
387 let did_suffix = "test_keys_exist";
389
390 assert!(!target.keys_exist(did_suffix, &KeyType::UpdateKey));
391
392 target.save_key(did_suffix, KeyType::UpdateKey, &expected_key, true)?;
394
395 assert!(target.keys_exist(did_suffix, &KeyType::UpdateKey));
396
397 let try_overwrite = target.save_key(did_suffix, KeyType::UpdateKey, &expected_key, false);
399 assert!(try_overwrite.is_err());
400
401 let try_overwrite = target.save_key(did_suffix, KeyType::UpdateKey, &expected_key, true);
403 assert!(try_overwrite.is_ok());
404
405 Ok(())
406 }
407
408 #[test]
409 fn test_save_key() -> Result<(), Box<dyn std::error::Error>> {
410 init();
412
413 let did_suffix = "test_save_key";
415
416 let expected_key: JWK = serde_json::from_str(TEST_UPDATE_KEY)?;
418
419 let target = TestKeyManager;
421 target.save_key(did_suffix, KeyType::UpdateKey, &expected_key, true)?;
422
423 let actual_key = target.read_update_key(did_suffix)?;
425
426 assert_eq!(expected_key, actual_key);
428
429 Ok(())
430 }
431
432 #[test]
433 fn test_save_keys() -> Result<(), Box<dyn std::error::Error>> {
434 init();
436
437 let did_suffix = "test_save_keys";
439
440 let keys: OneOrMany<JWK> = serde_json::from_str(TEST_SIGNING_KEYS)?;
442
443 let target = TestKeyManager;
445 target.save_keys(did_suffix, KeyType::SigningKey, &keys, true)?;
446
447 let actual_signing = target.read_signing_keys(did_suffix)?;
449
450 assert_eq!(keys, actual_signing);
452
453 Ok(())
454 }
455
456 #[test]
457 fn test_apply_next_update_key() -> Result<(), Box<dyn std::error::Error>> {
458 init();
460
461 let did_suffix = "test_apply_next_update_key";
463
464 let target = TestKeyManager;
465
466 let update_key: JWK = serde_json::from_str(TEST_UPDATE_KEY)?;
468 let next_update_key: JWK = serde_json::from_str(TEST_NEXT_UPDATE_KEY)?;
469 target.save_key(did_suffix, KeyType::UpdateKey, &update_key, true)?;
470 target.save_key(did_suffix, KeyType::NextUpdateKey, &next_update_key, true)?;
471
472 let loaded_update_key = target.read_update_key(did_suffix)?;
474 let loaded_next_update_key = target.read_next_update_key(did_suffix)?;
475 assert_eq!(loaded_update_key, update_key);
476 assert_eq!(loaded_next_update_key, next_update_key);
477
478 target.apply_next_update_key(did_suffix, &next_update_key)?;
480
481 let path = target.get_path(did_suffix, &KeyType::NextUpdateKey, false)?;
483 if path.is_file() {
484 return Err(Box::new(KeyManagerError::FailedToRemoveKey));
485 }
486
487 let actual_update_key = target.read_update_key(did_suffix)?;
489
490 assert_eq!(next_update_key, actual_update_key);
492
493 Ok(())
494 }
495}