Skip to main content

confium_store/
keystore.rs

1//! Public-facing [`Keystore`] wrapper.
2//!
3//! A `Keystore` owns a [`crate::backend::StoreInstance`] produced by a
4//! registered backend. It is the Rust-side handle the FFI layer boxes
5//! into the opaque `FFIKeystore` pointer.
6//!
7//! The wrapper exists to keep backend dispatch centralised: the FFI
8//! functions delegate here, and this module is the one place that knows
9//! how to translate `(module_id, app_id)` strings into backend calls.
10
11use std::ffi::c_void;
12
13use crate::backend::{Compartment, Options, StoreInstance, find};
14use crate::error::Result;
15
16/// An open keystore connection.
17///
18/// Construct one with [`Keystore::new`] by naming a registered backend.
19/// The backend's instance is held behind a `Box<dyn StoreInstance>` so
20/// the public API is backend-agnostic.
21pub struct Keystore {
22    instance: Box<dyn StoreInstance>,
23}
24
25impl Keystore {
26    /// Open a keystore backed by `backend_name`. The caller may supply
27    /// backend-specific options (path, slot, pin, …).
28    pub fn new(backend_name: &str, opts: &Options) -> Result<Self> {
29        let backend = find(backend_name)?;
30        let instance = backend.open(opts)?;
31        Ok(Keystore { instance })
32    }
33
34    /// Wrap an already-constructed instance. Used by tests and by FFI
35    /// paths that have already resolved the backend.
36    pub fn from_instance(instance: Box<dyn StoreInstance>) -> Self {
37        Keystore { instance }
38    }
39
40    /// Borrow the underlying instance mutably. The FFI layer uses this
41    /// to dispatch `put_*` calls.
42    pub fn instance_mut(&mut self) -> &mut dyn StoreInstance {
43        self.instance.as_mut()
44    }
45
46    /// Borrow the underlying instance. The FFI layer uses this to
47    /// dispatch `get_*` / `enumerate` calls.
48    pub fn instance(&self) -> &dyn StoreInstance {
49        self.instance.as_ref()
50    }
51
52    pub fn put_secret(
53        &mut self,
54        module: &str,
55        app: &str,
56        key_id: &str,
57        key: *mut c_void,
58    ) -> Result<()> {
59        self.instance.put_secret(module, app, key_id, key)
60    }
61
62    pub fn get_secret(&self, module: &str, app: &str, key_id: &str) -> Result<*mut c_void> {
63        self.instance.get_secret(module, app, key_id)
64    }
65
66    pub fn put_public(
67        &mut self,
68        module: &str,
69        app: &str,
70        identity: &str,
71        key: *mut c_void,
72        sig: &[u8],
73    ) -> Result<()> {
74        self.instance.put_public(module, app, identity, key, sig)
75    }
76
77    pub fn get_public(
78        &self,
79        module: &str,
80        app: &str,
81        identity: &str,
82    ) -> Result<(*mut c_void, Vec<u8>)> {
83        self.instance.get_public(module, app, identity)
84    }
85
86    /// Sign a message with a remotely-held key (see
87    /// [`StoreInstance::sign`](crate::backend::StoreInstance::sign)).
88    pub fn sign(
89        &self,
90        module: &str,
91        app: &str,
92        key_id: &str,
93        algorithm: &str,
94        message: &[u8],
95    ) -> Result<Vec<u8>> {
96        self.instance.sign(module, app, key_id, algorithm, message)
97    }
98
99    pub fn enumerate(
100        &self,
101        module: &str,
102        app: &str,
103        compartment: Compartment,
104    ) -> Result<Vec<(*mut c_void, String)>> {
105        self.instance.enumerate(module, app, compartment)
106    }
107}