Skip to content

Commit 2949c6e

Browse files
committed
Refine KeyStore logic
1 parent 5e48d93 commit 2949c6e

3 files changed

Lines changed: 37 additions & 16 deletions

File tree

src/lib.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,7 @@ use std::path::PathBuf;
55

66
use serde::{Deserialize, Serialize};
77

8-
use crate::{
9-
error::Error,
10-
secure::{KeyStore, PlatformKeyStore},
11-
};
8+
use crate::{error::Error, secure::get_key_store};
129

1310
/// Contains the [error::Error] type.
1411
pub mod error;
@@ -91,7 +88,7 @@ pub trait GlobalByteBox<const SECURE: bool>: Serialize + for<'de> Deserialize<'d
9188
let name = format!("{}", Self::path().display());
9289

9390
let bytes = bitcode::serialize(self)?;
94-
let key = PlatformKeyStore::get_key_or_generate(&name)?;
91+
let key = get_key_store().get_key_or_generate(&name)?;
9592

9693
secure::encrypt(&bytes, key)
9794
} else {
@@ -105,7 +102,7 @@ pub trait GlobalByteBox<const SECURE: bool>: Serialize + for<'de> Deserialize<'d
105102
fn decode(bytes: &[u8]) -> Result<Self, Error> {
106103
if SECURE {
107104
let name = Self::path().to_string_lossy().to_string();
108-
let key = PlatformKeyStore::get_key_or_generate(&name)?;
105+
let key = get_key_store().get_key_or_generate(&name)?;
109106
let decrypted = secure::decrypt(bytes.to_vec(), key)?;
110107

111108
Ok(bitcode::deserialize(&decrypted)?)
@@ -189,7 +186,7 @@ pub trait ByteBox<const SECURE: bool>: Serialize + for<'de> Deserialize<'de> {
189186
if SECURE {
190187
let name = format!("{}", self.path().display());
191188
let bytes = bitcode::serialize(self)?;
192-
let key = PlatformKeyStore::get_key_or_generate(&name)?;
189+
let key = get_key_store().get_key_or_generate(&name)?;
193190

194191
secure::encrypt(&bytes, key)
195192
} else {
@@ -204,7 +201,7 @@ pub trait ByteBox<const SECURE: bool>: Serialize + for<'de> Deserialize<'de> {
204201
if SECURE {
205202
let name = format!("{}", self.path().display());
206203

207-
let key = PlatformKeyStore::get_key_or_generate(&name)?;
204+
let key = get_key_store().get_key_or_generate(&name)?;
208205
let decrypted = secure::decrypt(bytes.to_vec(), key)?;
209206

210207
Ok(bitcode::deserialize(&decrypted)?)

src/secure/keyring.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::secure::namespace;
66
pub struct KeyStore;
77

88
impl super::KeyStore for KeyStore {
9-
fn get_key(name: &str) -> Result<Option<Vec<u8>>, crate::error::Error> {
9+
fn get_key(&self, name: &str) -> Result<Option<Vec<u8>>, crate::error::Error> {
1010
let entry = Entry::new(namespace()?.as_str(), name)?;
1111

1212
match entry.get_secret() {
@@ -16,7 +16,7 @@ impl super::KeyStore for KeyStore {
1616
}
1717
}
1818

19-
fn set_key(name: &str, key: Vec<u8>) -> Result<(), crate::error::Error> {
19+
fn set_key(&self, name: &str, key: Vec<u8>) -> Result<(), crate::error::Error> {
2020
let entry = Entry::new(namespace()?.as_str(), name)?;
2121

2222
entry.set_secret(&key)?;

src/secure/mod.rs

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::sync::OnceLock;
2+
13
use chacha20poly1305::{
24
aead::{AeadMut, Key, Nonce, OsRng},
35
AeadCore, KeyInit, XChaCha20Poly1305,
@@ -15,6 +17,28 @@ pub type PlatformKeyStore = keyring::KeyStore;
1517

1618
const NONCE_SIZE: usize = 24;
1719

20+
/// The global [KeyStore] instance.
21+
///
22+
/// Normally initialized with the default implementation on first access.
23+
pub static KEY_STORE: OnceLock<Box<dyn KeyStore>> = OnceLock::new();
24+
25+
/// Returns the set [KeyStore] implementation, initializing it with the default if necessary.
26+
pub fn get_key_store<'a>() -> &'a Box<dyn KeyStore> {
27+
KEY_STORE.get_or_init(default_key_store)
28+
}
29+
30+
/// Returns the default [KeyStore] implementation for this platform.
31+
pub fn default_key_store() -> Box<dyn KeyStore> {
32+
#[cfg(use_keyring)]
33+
{
34+
return Box::new(keyring::KeyStore);
35+
}
36+
#[cfg(not(use_keyring))]
37+
{
38+
panic!("Platform not supported!");
39+
}
40+
}
41+
1842
/// Encrypts the given data using the provided key.
1943
pub fn encrypt(data: &[u8], key: Vec<u8>) -> Result<Vec<u8>, Error> {
2044
let key = Key::<XChaCha20Poly1305>::from_iter(key);
@@ -64,23 +88,23 @@ pub fn namespace() -> Result<String, Error> {
6488
}
6589

6690
/// A trait for storing and retrieving keys.
67-
pub trait KeyStore {
91+
pub trait KeyStore: Send + Sync + 'static {
6892
/// Returns the key with the given name, generating a new one if none exists.
69-
fn get_key_or_generate(name: &str) -> Result<Vec<u8>, Error> {
70-
let key = Self::get_key(name)?;
93+
fn get_key_or_generate(&self, name: &str) -> Result<Vec<u8>, Error> {
94+
let key = self.get_key(name)?;
7195

7296
if let Some(key) = key {
7397
Ok(key)
7498
} else {
7599
let key = generate_key();
76-
Self::set_key(name, key.to_vec())?;
100+
self.set_key(name, key.to_vec())?;
77101
Ok(key.to_vec())
78102
}
79103
}
80104

81105
/// Returns the key with the given name, if one exists.
82-
fn get_key(name: &str) -> Result<Option<Vec<u8>>, Error>;
106+
fn get_key(&self, name: &str) -> Result<Option<Vec<u8>>, Error>;
83107

84108
/// Sets the key with the given name.
85-
fn set_key(name: &str, key: Vec<u8>) -> Result<(), Error>;
109+
fn set_key(&self, name: &str, key: Vec<u8>) -> Result<(), Error>;
86110
}

0 commit comments

Comments
 (0)