aboutsummaryrefslogtreecommitdiff
path: root/src/login
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 /src/login
parentbd6c3464e609dc76e119457ea583af0f08eeabb4 (diff)
downloadaerogramme-6e8b2cfc9ff1abf2b4844884d9ebd807d37bd76e.tar.gz
aerogramme-6e8b2cfc9ff1abf2b4844884d9ebd807d37bd76e.zip
rewrite CryptoKeys with Storage abstraction
Diffstat (limited to 'src/login')
-rw-r--r--src/login/mod.rs107
1 files changed, 26 insertions, 81 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()),
- }
-}