aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQuentin Dufour <quentin@deuxfleurs.fr>2023-11-21 09:56:31 +0100
committerQuentin Dufour <quentin@deuxfleurs.fr>2023-11-21 09:56:31 +0100
commit6e8b2cfc9ff1abf2b4844884d9ebd807d37bd76e (patch)
tree2eb6dc92646f97fe4452485f4dbeac588c80e5a4
parentbd6c3464e609dc76e119457ea583af0f08eeabb4 (diff)
downloadaerogramme-6e8b2cfc9ff1abf2b4844884d9ebd807d37bd76e.tar.gz
aerogramme-6e8b2cfc9ff1abf2b4844884d9ebd807d37bd76e.zip
rewrite CryptoKeys with Storage abstraction
-rw-r--r--src/login/mod.rs107
-rw-r--r--src/storage/garage.rs6
-rw-r--r--src/storage/in_memory.rs6
-rw-r--r--src/storage/mod.rs3
4 files changed, 38 insertions, 84 deletions
diff --git a/src/login/mod.rs b/src/login/mod.rs
index 52d9829..050151d 100644
--- a/src/login/mod.rs
+++ b/src/login/mod.rs
@@ -6,13 +6,7 @@ use std::sync::Arc;
use anyhow::{anyhow, bail, Context, Result};
use async_trait::async_trait;
-use k2v_client::{
- BatchInsertOp, BatchReadOp, CausalValue, CausalityToken, Filter, K2vClient, K2vValue,
-};
use rand::prelude::*;
-use rusoto_core::HttpClient;
-use rusoto_credential::{AwsCredentials, StaticProvider};
-use rusoto_s3::S3Client;
use crate::cryptoblob::*;
use crate::storage::*;
@@ -90,12 +84,12 @@ impl Credentials {
impl CryptoKeys {
pub async fn init(
- storage: &StorageCredentials,
+ storage: &Builders,
user_secrets: &UserSecrets,
password: &str,
) -> Result<Self> {
// Check that salt and public don't exist already
- let k2v = storage.k2v_client()?;
+ let k2v = storage.row_store()?;
let (salt_ct, public_ct) = Self::check_uninitialized(&k2v).await?;
// Generate salt for password identifiers
@@ -140,12 +134,12 @@ impl CryptoKeys {
}
pub async fn init_without_password(
- storage: &StorageCredentials,
+ storage: &Builders,
master: &Key,
secret: &SecretKey,
) -> Result<Self> {
// Check that salt and public don't exist already
- let k2v = storage.k2v_client()?;
+ let k2v = storage.row_store()?;
let (salt_ct, public_ct) = Self::check_uninitialized(&k2v).await?;
// Generate salt for password identifiers
@@ -172,7 +166,7 @@ impl CryptoKeys {
}
pub async fn open(
- storage: &StorageCredentials,
+ storage: &Builders,
user_secrets: &UserSecrets,
password: &str,
) -> Result<Self> {
@@ -215,11 +209,11 @@ impl CryptoKeys {
}
pub async fn open_without_password(
- storage: &StorageCredentials,
+ storage: &Builders,
master: &Key,
secret: &SecretKey,
) -> Result<Self> {
- let k2v = storage.k2v_client()?;
+ let k2v = storage.row_store()?;
let (_ident_salt, expected_public) = Self::load_salt_and_public(&k2v).await?;
// Create CryptoKeys struct from given keys
@@ -240,11 +234,11 @@ impl CryptoKeys {
pub async fn add_password(
&self,
- storage: &StorageCredentials,
+ storage: &Builders,
user_secrets: &UserSecrets,
password: &str,
) -> Result<()> {
- let k2v = storage.k2v_client()?;
+ let k2v = storage.row_store()?;
let (ident_salt, _public) = Self::load_salt_and_public(&k2v).await?;
// Generate short password digest (= password identity)
@@ -289,11 +283,11 @@ impl CryptoKeys {
}
pub async fn delete_password(
- storage: &StorageCredentials,
+ storage: &Builders,
password: &str,
allow_delete_all: bool,
) -> Result<()> {
- let k2v = storage.k2v_client()?;
+ let k2v = storage.row_client()?;
let (ident_salt, _public) = Self::load_salt_and_public(&k2v).await?;
// Generate short password digest (= password identity)
@@ -322,47 +316,32 @@ impl CryptoKeys {
// ---- STORAGE UTIL ----
async fn check_uninitialized(
- k2v: &K2vClient,
- ) -> Result<(Option<CausalityToken>, Option<CausalityToken>)> {
+ k2v: &RowStore,
+ ) -> Result<(RowRef, RowRef)> {
let params = k2v
- .read_batch(&[
- k2v_read_single_key("keys", "salt", true),
- k2v_read_single_key("keys", "public", true),
- ])
+ .select(Selector::List(vec![
+ ("keys", "salt"),
+ ("keys", "public"),
+ ]))
.await
.context("ReadBatch for salt and public in check_uninitialized")?;
+
if params.len() != 2 {
bail!(
"Invalid response from k2v storage: {:?} (expected two items)",
params
);
}
- if params[0].items.len() > 1 || params[1].items.len() > 1 {
- bail!(
- "invalid response from k2v storage: {:?} (several items in single_item read)",
- params
- );
- }
- let salt_ct = match params[0].items.iter().next() {
- None => None,
- Some((_, CausalValue { causality, value })) => {
- if value.iter().any(|x| matches!(x, K2vValue::Value(_))) {
- bail!("key storage already initialized");
- }
- Some(causality.clone())
- }
- };
+ let salt_ct = params[0].to_ref();
+ if params[0].content().iter().any(|x| matches!(x, Alternative::Value(_))) {
+ bail!("key storage already initialized");
+ }
- let public_ct = match params[1].items.iter().next() {
- None => None,
- Some((_, CausalValue { causality, value })) => {
- if value.iter().any(|x| matches!(x, K2vValue::Value(_))) {
- bail!("key storage already initialized");
- }
- Some(causality.clone())
- }
- };
+ let public_ct = params[1].to_ref();
+ if params[1].content().iter().any(|x| matches!(x, Alternative::Value(_))) {
+ bail!("key storage already initialized");
+ }
Ok((salt_ct, public_ct))
}
@@ -511,37 +490,3 @@ pub fn argon2_kdf(salt: &[u8], password: &[u8], output_len: usize) -> Result<Vec
assert!(hash.len() == output_len);
Ok(hash.as_bytes().to_vec())
}
-
-pub fn k2v_read_single_key<'a>(
- partition_key: &'a str,
- sort_key: &'a str,
- tombstones: bool,
-) -> BatchReadOp<'a> {
- BatchReadOp {
- partition_key,
- filter: Filter {
- start: Some(sort_key),
- end: None,
- prefix: None,
- limit: None,
- reverse: false,
- },
- conflicts_only: false,
- tombstones,
- single_item: true,
- }
-}
-
-pub fn k2v_insert_single_key<'a>(
- partition_key: &'a str,
- sort_key: &'a str,
- causality: Option<CausalityToken>,
- value: impl AsRef<[u8]>,
-) -> BatchInsertOp<'a> {
- BatchInsertOp {
- partition_key,
- sort_key,
- causality,
- value: K2vValue::Value(value.as_ref().to_vec()),
- }
-}
diff --git a/src/storage/garage.rs b/src/storage/garage.rs
index ad33769..0a22928 100644
--- a/src/storage/garage.rs
+++ b/src/storage/garage.rs
@@ -85,7 +85,11 @@ impl IRowValue for GrgValue {
}
}
-
+impl std::fmt::Debug for GrgValue {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ unimplemented!();
+ }
+}
/*
diff --git a/src/storage/in_memory.rs b/src/storage/in_memory.rs
index cde2335..49169d7 100644
--- a/src/storage/in_memory.rs
+++ b/src/storage/in_memory.rs
@@ -90,4 +90,8 @@ impl IRowValue for MemValue {
}
}
-
+impl std::fmt::Debug for MemValue {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ unimplemented!();
+ }
+}
diff --git a/src/storage/mod.rs b/src/storage/mod.rs
index c948a08..324e6b9 100644
--- a/src/storage/mod.rs
+++ b/src/storage/mod.rs
@@ -44,6 +44,7 @@ impl std::fmt::Display for StorageError {
match self {
Self::NotFound => f.write_str("Item not found"),
Self::Internal => f.write_str("An internal error occured"),
+ Self::IncompatibleOrphan => f.write_str("Incompatible orphan"),
}
}
}
@@ -110,7 +111,7 @@ pub type RowRef = Box<dyn IRowRef + Send + Sync>;
}*/
-pub trait IRowValue
+pub trait IRowValue: std::fmt::Debug
{
fn to_ref(&self) -> RowRef;
fn content(&self) -> ConcurrentValues;