ndn_security/
key_store.rs

1use crate::{Signer, TrustError};
2use dashmap::DashMap;
3use ndn_packet::Name;
4use std::sync::Arc;
5
6/// Supported key algorithms.
7#[derive(Clone, Copy, Debug, PartialEq, Eq)]
8pub enum KeyAlgorithm {
9    Ed25519,
10    EcdsaP256,
11    Rsa2048,
12}
13
14/// Persistent key storage.
15pub trait KeyStore: Send + Sync + 'static {
16    fn get_signer(
17        &self,
18        key_name: &Name,
19    ) -> impl std::future::Future<Output = Result<Arc<dyn Signer>, TrustError>> + Send;
20
21    fn generate_key(
22        &self,
23        name: Name,
24        algo: KeyAlgorithm,
25    ) -> impl std::future::Future<Output = Result<Name, TrustError>> + Send;
26
27    fn delete_key(
28        &self,
29        key_name: &Name,
30    ) -> impl std::future::Future<Output = Result<(), TrustError>> + Send;
31}
32
33/// In-memory key store for testing.
34pub struct MemKeyStore {
35    keys: DashMap<Arc<Name>, Arc<dyn Signer>>,
36}
37
38impl MemKeyStore {
39    pub fn new() -> Self {
40        Self {
41            keys: DashMap::new(),
42        }
43    }
44
45    /// Look up a signer synchronously.
46    pub fn get_signer_sync(&self, key_name: &Name) -> Result<Arc<dyn Signer>, TrustError> {
47        self.keys
48            .iter()
49            .find(|r| r.key().as_ref() == key_name)
50            .map(|r| Arc::clone(r.value()))
51            .ok_or_else(|| TrustError::CertNotFound {
52                name: key_name.to_string(),
53            })
54    }
55
56    pub fn add<S: Signer>(&self, key_name: Arc<Name>, signer: S) {
57        self.keys.insert(key_name, Arc::new(signer));
58    }
59}
60
61impl Default for MemKeyStore {
62    fn default() -> Self {
63        Self::new()
64    }
65}
66
67impl KeyStore for MemKeyStore {
68    async fn get_signer(&self, key_name: &Name) -> Result<Arc<dyn Signer>, TrustError> {
69        self.keys
70            .iter()
71            .find(|r| r.key().as_ref() == key_name)
72            .map(|r| Arc::clone(r.value()))
73            .ok_or_else(|| TrustError::CertNotFound {
74                name: key_name.to_string(),
75            })
76    }
77
78    async fn generate_key(&self, _name: Name, _algo: KeyAlgorithm) -> Result<Name, TrustError> {
79        Err(TrustError::KeyStore(
80            "MemKeyStore does not support key generation".into(),
81        ))
82    }
83
84    async fn delete_key(&self, key_name: &Name) -> Result<(), TrustError> {
85        let key = self
86            .keys
87            .iter()
88            .find(|r| r.key().as_ref() == key_name)
89            .map(|r| Arc::clone(r.key()));
90        if let Some(k) = key {
91            self.keys.remove(&k);
92        }
93        Ok(())
94    }
95}
96
97#[cfg(test)]
98mod tests {
99    use super::*;
100    use crate::signer::Ed25519Signer;
101    use bytes::Bytes;
102    use ndn_packet::NameComponent;
103
104    fn key_name(s: &'static str) -> Arc<Name> {
105        Arc::new(Name::from_components([NameComponent::generic(
106            Bytes::from_static(s.as_bytes()),
107        )]))
108    }
109
110    #[tokio::test]
111    async fn add_and_get_signer() {
112        let store = MemKeyStore::new();
113        let kn = key_name("mykey");
114        let signer = Ed25519Signer::from_seed(&[1u8; 32], (*kn).clone());
115        store.add(Arc::clone(&kn), signer);
116        let retrieved = store.get_signer(&kn).await.unwrap();
117        assert_eq!(retrieved.key_name(), &*kn);
118    }
119
120    #[tokio::test]
121    async fn get_missing_key_returns_err() {
122        let store = MemKeyStore::new();
123        let kn = key_name("missing");
124        assert!(matches!(
125            store.get_signer(&kn).await,
126            Err(TrustError::CertNotFound { .. })
127        ));
128    }
129
130    #[tokio::test]
131    async fn delete_key_removes_it() {
132        let store = MemKeyStore::new();
133        let kn = key_name("delkey");
134        let signer = Ed25519Signer::from_seed(&[2u8; 32], (*kn).clone());
135        store.add(Arc::clone(&kn), signer);
136        store.delete_key(&kn).await.unwrap();
137        assert!(matches!(
138            store.get_signer(&kn).await,
139            Err(TrustError::CertNotFound { .. })
140        ));
141    }
142
143    #[tokio::test]
144    async fn generate_key_returns_err() {
145        let store = MemKeyStore::new();
146        let result = store
147            .generate_key((*key_name("k")).clone(), KeyAlgorithm::Ed25519)
148            .await;
149        assert!(result.is_err());
150    }
151}