keyfile: use serde_with::base64

This commit is contained in:
Alexander Weiss 2023-03-23 13:11:02 +01:00
parent 9a602428ca
commit 61dbe027cc
3 changed files with 25 additions and 25 deletions

1
Cargo.lock generated
View File

@ -1829,7 +1829,6 @@ dependencies = [
"aho-corasick",
"anyhow",
"backoff",
"base64 0.21.0",
"binrw",
"bytes",
"bytesize",

View File

@ -42,10 +42,10 @@ scrypt = { version = "0.11", default-features = false }
# cdc = "0.1"
integer-sqrt = "0.1"
# serialization
base64 = "0.21"
binrw = "0.11"
hex = { version = "0.4", features = ["serde"] }
serde = { version = "1", features = ["derive"] }
serde_with = { version = "2.3", features = ["base64"] }
serde_json = "1"
serde-aux = "4"
# other dependencies
@ -76,7 +76,6 @@ directories = "5"
nom = "7"
toml = "0.7"
merge = "0.1"
serde_with = "2.3"
rpassword = "7"
bytesize = "1"
indicatif = "0.17"

View File

@ -1,14 +1,16 @@
use anyhow::{anyhow, Result};
use base64::{engine::general_purpose::STANDARD, Engine as _};
use chrono::{DateTime, Local};
use rand::{thread_rng, RngCore};
use scrypt::Params;
use serde::{Deserialize, Serialize};
use serde_with::base64::Base64;
use serde_with::serde_as;
use crate::backend::{FileType, ReadBackend};
use crate::crypto::{CryptoKey, Key};
use crate::id::Id;
#[serde_as]
#[serde_with::apply(Option => #[serde(default, skip_serializing_if = "Option::is_none")])]
#[derive(Debug, Serialize, Deserialize)]
pub struct KeyFile {
@ -20,8 +22,10 @@ pub struct KeyFile {
n: u32,
r: u32,
p: u32,
data: String,
salt: String,
#[serde_as(as = "Base64")]
data: Vec<u8>,
#[serde_as(as = "Base64")]
salt: Vec<u8>,
}
impl KeyFile {
@ -29,10 +33,10 @@ impl KeyFile {
fn kdf_key(&self, passwd: &impl AsRef<[u8]>) -> Result<Key> {
let params = Params::new(log_2(self.n), self.r, self.p, Params::RECOMMENDED_LEN)
.map_err(|_| anyhow!("invalid scrypt paramters"))?;
let salt = STANDARD.decode(&self.salt)?;
let mut key = [0; 64];
scrypt::scrypt(passwd.as_ref(), &salt, &params, &mut key).expect("output length invalid?");
scrypt::scrypt(passwd.as_ref(), &self.salt, &params, &mut key)
.expect("output length invalid?");
Ok(Key::from_slice(&key))
}
@ -41,7 +45,7 @@ impl KeyFile {
/// The key usually should be the key generated by [`kdf_key()`](Self::kdf_key)
fn key_from_data(&self, key: &Key) -> Result<Key> {
let dec_data = key
.decrypt_data(&STANDARD.decode(&self.data)?)
.decrypt_data(&self.data)
.map_err(|_| anyhow!("decryption failed"))?;
serde_json::from_slice::<MasterKey>(&dec_data)?.key()
}
@ -62,7 +66,7 @@ impl KeyFile {
) -> Result<Self> {
let masterkey = MasterKey::from_key(key);
let params = Params::recommended();
let mut salt = [0; 64];
let mut salt = vec![0; 64];
thread_rng().fill_bytes(&mut salt);
let mut key = [0; 64];
@ -79,8 +83,8 @@ impl KeyFile {
r: params.r(),
p: params.p(),
created: with_created.then(Local::now),
data: STANDARD.encode(data),
salt: STANDARD.encode(salt),
data,
salt,
})
}
}
@ -102,36 +106,34 @@ fn log_2(x: u32) -> u8 {
num_bits::<u32>() as u8 - x.leading_zeros() as u8 - 1
}
#[serde_as]
#[derive(Debug, Serialize, Deserialize)]
struct Mac {
k: String,
r: String,
#[serde_as(as = "Base64")]
k: Vec<u8>,
#[serde_as(as = "Base64")]
r: Vec<u8>,
}
#[serde_as]
#[derive(Debug, Serialize, Deserialize)]
struct MasterKey {
mac: Mac,
encrypt: String,
#[serde_as(as = "Base64")]
encrypt: Vec<u8>,
}
impl MasterKey {
fn from_key(key: Key) -> Self {
let (encrypt, k, r) = key.to_keys();
Self {
encrypt: STANDARD.encode(encrypt),
mac: Mac {
k: STANDARD.encode(k),
r: STANDARD.encode(r),
},
encrypt,
mac: Mac { k, r },
}
}
fn key(&self) -> Result<Key> {
Ok(Key::from_keys(
&STANDARD.decode(&self.encrypt)?,
&STANDARD.decode(&self.mac.k)?,
&STANDARD.decode(&self.mac.r)?,
))
Ok(Key::from_keys(&self.encrypt, &self.mac.k, &self.mac.r))
}
}