keymgr: Add KeyMgr::generate() for generating new keys.
This commit is contained in:
parent
9c326ced81
commit
f96298a791
|
@ -4567,6 +4567,7 @@ dependencies = [
|
||||||
"ssh-key",
|
"ssh-key",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"tor-basic-utils",
|
||||||
"tor-config",
|
"tor-config",
|
||||||
"tor-error",
|
"tor-error",
|
||||||
"tor-hscrypto",
|
"tor-hscrypto",
|
||||||
|
|
|
@ -42,6 +42,7 @@ zeroize = "1"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tempfile = "3"
|
tempfile = "3"
|
||||||
|
tor-basic-utils = { path = "../tor-basic-utils", version = "0.7.1" }
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
all-features = true
|
all-features = true
|
||||||
|
|
|
@ -15,3 +15,4 @@ ADDED: a `to_bytes` function to `EncodableKey` trait
|
||||||
ADDED: `Keystore::contains()`
|
ADDED: `Keystore::contains()`
|
||||||
ADDED: `KeygenRng` trait
|
ADDED: `KeygenRng` trait
|
||||||
ADDED: `EncodableKey::generate()`
|
ADDED: `EncodableKey::generate()`
|
||||||
|
ADDED: `KeyMgr::generate()`
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
//! [`Keystore`].
|
//! [`Keystore`].
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
EncodableKey, KeySpecifier, Keystore, KeystoreId, KeystoreSelector, Result, ToEncodableKey,
|
EncodableKey, KeySpecifier, KeygenRng, Keystore, KeystoreId, KeystoreSelector, Result,
|
||||||
|
ToEncodableKey,
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
@ -45,6 +46,32 @@ impl KeyMgr {
|
||||||
self.get_from_store(key_spec, self.all_stores())
|
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`.
|
/// Insert `key` into the [`Keystore`] specified by `selector`.
|
||||||
///
|
///
|
||||||
/// If the key already exists, it is overwritten.
|
/// If the key already exists, it is overwritten.
|
||||||
|
@ -156,6 +183,7 @@ mod tests {
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::RwLock;
|
use std::sync::RwLock;
|
||||||
|
use tor_basic_utils::test_rng::testing_rng;
|
||||||
|
|
||||||
/// The type of "key" stored in the test key stores.
|
/// The type of "key" stored in the test key stores.
|
||||||
type TestKey = String;
|
type TestKey = String;
|
||||||
|
@ -433,4 +461,44 @@ mod tests {
|
||||||
.contains(&TestKeySpecifier1, TestKey::key_type())
|
.contains(&TestKeySpecifier1, TestKey::key_type())
|
||||||
.unwrap());
|
.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())
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue