keymgr: Add KeyMgr::generate() for generating new keys.

This commit is contained in:
Gabriela Moldovan 2023-07-24 11:56:18 +01:00
parent 9c326ced81
commit f96298a791
No known key found for this signature in database
GPG Key ID: 3946E0ADE72BAC99
4 changed files with 72 additions and 1 deletions

1
Cargo.lock generated
View File

@ -4567,6 +4567,7 @@ dependencies = [
"ssh-key",
"tempfile",
"thiserror",
"tor-basic-utils",
"tor-config",
"tor-error",
"tor-hscrypto",

View File

@ -42,6 +42,7 @@ zeroize = "1"
[dev-dependencies]
tempfile = "3"
tor-basic-utils = { path = "../tor-basic-utils", version = "0.7.1" }
[package.metadata.docs.rs]
all-features = true

View File

@ -15,3 +15,4 @@ ADDED: a `to_bytes` function to `EncodableKey` trait
ADDED: `Keystore::contains()`
ADDED: `KeygenRng` trait
ADDED: `EncodableKey::generate()`
ADDED: `KeyMgr::generate()`

View File

@ -4,7 +4,8 @@
//! [`Keystore`].
use crate::{
EncodableKey, KeySpecifier, Keystore, KeystoreId, KeystoreSelector, Result, ToEncodableKey,
EncodableKey, KeySpecifier, KeygenRng, Keystore, KeystoreId, KeystoreSelector, Result,
ToEncodableKey,
};
use std::iter;
@ -45,6 +46,32 @@ impl KeyMgr {
self.get_from_store(key_spec, self.all_stores())
}
/// Generate a new key of type `K`, and insert it into the key store specified by `selector`.
///
/// If the key already exists in the specified key store, the `overwrite` flag is used to
/// decide whether to overwrite it with a newly generated key.
pub fn generate<K: ToEncodableKey>(
&self,
key_spec: &dyn KeySpecifier,
selector: KeystoreSelector,
rng: &mut dyn KeygenRng,
overwrite: bool,
) -> Result<()> {
let store = match selector {
KeystoreSelector::Id(keystore_id) => self.find_keystore(keystore_id)?,
KeystoreSelector::Default => &self.default_store,
};
let key_type = K::Key::key_type();
if overwrite || !store.contains(key_spec, key_type)? {
let key = K::Key::generate(rng);
store.insert(&key, key_spec, key_type)
} else {
Ok(())
}
}
/// Insert `key` into the [`Keystore`] specified by `selector`.
///
/// If the key already exists, it is overwritten.
@ -156,6 +183,7 @@ mod tests {
use std::collections::HashMap;
use std::str::FromStr;
use std::sync::RwLock;
use tor_basic_utils::test_rng::testing_rng;
/// The type of "key" stored in the test key stores.
type TestKey = String;
@ -433,4 +461,44 @@ mod tests {
.contains(&TestKeySpecifier1, TestKey::key_type())
.unwrap());
}
#[test]
fn keygen() {
let mgr = KeyMgr::new(Keystore1::default(), vec![]);
mgr.insert(
"coot".to_string(),
&TestKeySpecifier1,
KeystoreSelector::Default,
)
.unwrap();
// Try to generate a new key (overwrite = false)
mgr.generate::<TestKey>(
&TestKeySpecifier1,
KeystoreSelector::Default,
&mut testing_rng(),
false,
)
.unwrap();
assert_eq!(
mgr.get::<TestKey>(&TestKeySpecifier1).unwrap(),
Some("keystore1_coot".to_string())
);
// Try to generate a new key (overwrite = true)
mgr.generate::<TestKey>(
&TestKeySpecifier1,
KeystoreSelector::Default,
&mut testing_rng(),
true,
)
.unwrap();
assert_eq!(
mgr.get::<TestKey>(&TestKeySpecifier1).unwrap(),
Some("keystore1_generated_test_key".to_string())
);
}
}