keymgr: Use Box<dyn EncodableKey> instead of Box<dyn Any>.

Prompted by https://gitlab.torproject.org/tpo/core/arti/-/merge_requests/1337#note_2917701

This will make it harder to accidentally return the wrong value from
`Keystore::get` (the returned value is now at least guaranteed to
implement `EncodableKey`).

Closes #937
This commit is contained in:
Gabriela Moldovan 2023-07-10 14:20:17 +01:00
parent 9f3619d5c9
commit 9cde64c2c8
5 changed files with 21 additions and 10 deletions

1
Cargo.lock generated
View File

@ -4550,6 +4550,7 @@ name = "tor-keymgr"
version = "0.1.0"
dependencies = [
"derive_more",
"downcast-rs",
"dyn-clone",
"fs-mistrust",
"itertools 0.10.5",

View File

@ -25,6 +25,7 @@ experimental = ["keymgr"]
[dependencies]
derive_more = "0.99.3"
downcast-rs = "1.2.0"
dyn-clone = "1.0.11"
fs-mistrust = { path = "../fs-mistrust", version = "0.7.1", features = ["serde", "walkdir"] }
itertools = "0.10.1"

View File

@ -216,7 +216,10 @@ mod tests {
fn wrong_key_type() {
let key_type = KeyType::Ed25519Keypair;
let key = UnparsedOpenSshKey::new(OPENSSH_DSA.into(), PathBuf::from("/test/path"));
let err = key_type.parse_ssh_format_erased(key).unwrap_err();
let err = key_type
.parse_ssh_format_erased(key)
.map(|_| "<type erased key>")
.unwrap_err();
assert_eq!(
err.to_string(),
@ -232,7 +235,10 @@ mod tests {
fn invalid_ed25519_key() {
let key_type = KeyType::Ed25519Keypair;
let key = UnparsedOpenSshKey::new(OPENSSH_ED25519_BAD.into(), PathBuf::from("/test/path"));
let err = key_type.parse_ssh_format_erased(key).unwrap_err();
let err = key_type
.parse_ssh_format_erased(key)
.map(|_| "<type erased key>")
.unwrap_err();
assert_eq!(
err.to_string(),

View File

@ -8,10 +8,10 @@ use tor_llcrypto::pk::{curve25519, ed25519};
use crate::key_type::KeyType;
use crate::{KeySpecifier, Result};
use std::any::Any;
use downcast_rs::{impl_downcast, Downcast};
/// A type-erased key returned by a [`Keystore`].
pub type ErasedKey = Box<dyn Any>;
pub type ErasedKey = Box<dyn EncodableKey>;
/// A generic key store.
//
@ -63,13 +63,15 @@ pub trait Keystore: Send + Sync + 'static {
/// A key that can be serialized to, and deserialized from, a format used by a
/// [`Keystore`](crate::Keystore).
pub trait EncodableKey {
pub trait EncodableKey: Downcast {
/// The type of the key.
fn key_type() -> KeyType
where
Self: Sized;
}
impl_downcast!(EncodableKey);
impl EncodableKey for curve25519::StaticSecret {
fn key_type() -> KeyType
where

View File

@ -299,12 +299,13 @@ mod tests {
let erased_kp = KeyType::Ed25519Keypair
.parse_ssh_format_erased(key)
.unwrap();
let Ok(key) = erased_kp.downcast::<ed25519::Keypair>() else {
panic!("failed to downcast key to ed25519::Keypair")
};
key_store
.insert(
&*erased_kp.downcast::<ed25519::Keypair>().unwrap(),
&TestSpecifier,
KeyType::Ed25519Keypair,
)
.insert(&*key, &TestSpecifier, KeyType::Ed25519Keypair)
.unwrap();
// Found!