Skip to main content

cratestack_cose/keys/
static_resolver.rs

1//! An in-memory [`CoseVerifierResolver`].
2
3use cratestack_core::CratestackError;
4
5use super::traits::CoseVerifierResolver;
6use super::verify_key::CoseVerifyKey;
7use crate::alg::CoseAlg;
8
9/// A fixed set of verification keys, indexed by their `kid`. For tests and
10/// for in-process use (a service that knows its peers' keys at start-up).
11/// A device-key database or a published COSE_KeySet implements
12/// [`CoseVerifierResolver`] itself.
13///
14/// The `kid` is computed from each key, so a key can never be filed under a
15/// `kid` it does not have.
16#[derive(Debug, Clone, Default)]
17pub struct StaticVerifierResolver {
18    keys: Vec<CoseVerifyKey>,
19}
20
21impl StaticVerifierResolver {
22    /// An empty resolver: every `kid` is unknown until keys are added.
23    pub fn new() -> Self {
24        Self::default()
25    }
26
27    /// Add `key`. Keys that share a `kid` (an 8-byte prefix collision, or
28    /// one HMAC secret listed for both HMAC algorithms) are all returned
29    /// for it, in the order they were added.
30    pub fn with_key(mut self, key: CoseVerifyKey) -> Self {
31        self.keys.push(key);
32        self
33    }
34}
35
36#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
37#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))]
38impl CoseVerifierResolver for StaticVerifierResolver {
39    async fn resolve(
40        &self,
41        kid: &[u8],
42        alg: CoseAlg,
43    ) -> Result<Vec<CoseVerifyKey>, CratestackError> {
44        Ok(self
45            .keys
46            .iter()
47            .filter(|key| key.kid().as_slice() == kid && key.supports(alg))
48            .cloned()
49            .collect())
50    }
51}