Individiual methods for keystores
Signed-off-by: Lee Smet <lee.smet@hotmail.com>
This commit is contained in:
parent
78c0fd7871
commit
e9b867a36e
@ -3,12 +3,18 @@
|
|||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// An error during cryptographic operations
|
/// An error during cryptographic operations
|
||||||
Crypto(CryptoError),
|
Crypto(CryptoError),
|
||||||
|
/// An error while performing an I/O operation
|
||||||
|
IOError(std::io::Error),
|
||||||
|
/// A corrupt keyspace is returned if a keyspace can't be decrypted
|
||||||
|
CorruptKeyspace,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl core::fmt::Display for Error {
|
impl core::fmt::Display for Error {
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Error::Crypto(e) => f.write_fmt(format_args!("crypto: {e}")),
|
Error::Crypto(e) => f.write_fmt(format_args!("crypto: {e}")),
|
||||||
|
Error::IOError(e) => f.write_fmt(format_args!("io: {e}")),
|
||||||
|
Error::CorruptKeyspace => f.write_str("corrupt keyspace"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -56,3 +62,9 @@ impl From<CryptoError> for Error {
|
|||||||
Self::Crypto(value)
|
Self::Crypto(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<std::io::Error> for Error {
|
||||||
|
fn from(value: std::io::Error) -> Self {
|
||||||
|
Self::IOError(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -5,17 +5,17 @@ mod wasm;
|
|||||||
mod fallback;
|
mod fallback;
|
||||||
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
use wasm::KeySpace as KS;
|
use wasm::KeySpace as Ks;
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
use fallback::KeySpace as KS;
|
use fallback::KeySpace as Ks;
|
||||||
|
|
||||||
use crate::{error::Error, key::Key};
|
use crate::{error::Error, key::Key};
|
||||||
|
|
||||||
/// A keyspace represents a group of stored cryptographic keys. The storage is encrypted, a
|
/// A keyspace represents a group of stored cryptographic keys. The storage is encrypted, a
|
||||||
/// password must be provided when opening the KeySpace to decrypt the keys.
|
/// password must be provided when opening the KeySpace to decrypt the keys.
|
||||||
pub struct KeySpace {
|
pub struct KeySpace {
|
||||||
store: KS,
|
store: Ks,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wasm32 constructor
|
/// Wasm32 constructor
|
||||||
|
@ -1,2 +1,72 @@
|
|||||||
|
use std::{collections::HashMap, io::Write, path::PathBuf};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
error::Error,
|
||||||
|
key::{Key, symmetric::SymmetricKey},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Magic value used as header in decrypted keyspace files.
|
||||||
|
const KEYSPACE_MAGIC: [u8; 14] = [
|
||||||
|
118, 97, 117, 108, 116, 95, 107, 101, 121, 115, 112, 97, 99, 101,
|
||||||
|
]; //"vault_keyspace"
|
||||||
|
|
||||||
/// A KeySpace using the filesystem as storage
|
/// A KeySpace using the filesystem as storage
|
||||||
pub mod KeySpace {}
|
pub struct KeySpace {
|
||||||
|
/// Path to file on disk
|
||||||
|
path: PathBuf,
|
||||||
|
/// Decrypted keys held in the store
|
||||||
|
keystore: HashMap<String, Key>,
|
||||||
|
/// The encryption key used to encrypt/decrypt the storage.
|
||||||
|
encryption_key: SymmetricKey,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl KeySpace {
|
||||||
|
/// Opens the `KeySpace`. If it does not exist, it will be created. The provided encryption key
|
||||||
|
/// will be used for Encrypting and Decrypting the content of the KeySpace.
|
||||||
|
async fn open(path: PathBuf, encryption_key: SymmetricKey) -> Result<Self, Error> {
|
||||||
|
/// If the path does not exist, create it first and write the encrypted magic header
|
||||||
|
if !path.exists() {
|
||||||
|
// Since we checked path does not exist, the only errors here can be actual IO errors
|
||||||
|
// (unless something else creates the same file at the same time).
|
||||||
|
let mut file = std::fs::File::create_new(path)?;
|
||||||
|
let content = encryption_key.encrypt(&KEYSPACE_MAGIC)?;
|
||||||
|
file.write_all(&content)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load file, try to decrypt, verify magic header, deserialize keystore
|
||||||
|
let mut file = std::fs::File::open(path)?;
|
||||||
|
let mut buffer = Vec::new();
|
||||||
|
file.read_to_end(&mut buffer)?;
|
||||||
|
if buffer.len() < KEYSPACE_MAGIC.len() {
|
||||||
|
return Err(Error::CorruptKeyspace);
|
||||||
|
}
|
||||||
|
|
||||||
|
if buffer[..KEYSPACE_MAGIC.len()] != KEYSPACE_MAGIC {
|
||||||
|
return Err(Error::CorruptKeyspace);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Actual deserialization
|
||||||
|
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a [`Key`] previously stored under the provided name.
|
||||||
|
async fn get(&self, key: &str) -> Result<Option<Key>, Error> {
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Store a [`Key`] under the provided name.
|
||||||
|
async fn set(&self, key: &str, value: Key) -> Result<(), Error> {
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Delete the [`Key`] stored under the provided name.
|
||||||
|
async fn delete(&self, key: &str) -> Result<(), Error> {
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Iterate over all stored [`keys`](Key) in the KeySpace
|
||||||
|
async fn iter(&self) -> Result<impl Iterator<Item = (String, Key)>, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,2 +1,26 @@
|
|||||||
|
use crate::{error::Error, key::Key};
|
||||||
|
|
||||||
/// KeySpace represents an IndexDB keyspace
|
/// KeySpace represents an IndexDB keyspace
|
||||||
pub struct KeySpace {}
|
pub struct KeySpace {}
|
||||||
|
|
||||||
|
impl KeySpace {
|
||||||
|
/// Get a [`Key`] previously stored under the provided name.
|
||||||
|
async fn get(&self, key: &str) -> Result<Option<Key>, Error> {
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Store a [`Key`] under the provided name.
|
||||||
|
async fn set(&self, key: &str, value: Key) -> Result<(), Error> {
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Delete the [`Key`] stored under the provided name.
|
||||||
|
async fn delete(&self, key: &str) -> Result<(), Error> {
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Iterate over all stored [`keys`](Key) in the KeySpace
|
||||||
|
async fn iter(&self) -> Result<impl Iterator<Item = (String, Key)>, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user