mirror of
https://github.com/rustic-rs/rustic.git
synced 2025-10-26 11:18:51 +00:00
keyfile: use serde_with::base64
This commit is contained in:
parent
9a602428ca
commit
61dbe027cc
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1829,7 +1829,6 @@ dependencies = [
|
||||
"aho-corasick",
|
||||
"anyhow",
|
||||
"backoff",
|
||||
"base64 0.21.0",
|
||||
"binrw",
|
||||
"bytes",
|
||||
"bytesize",
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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, ¶ms, &mut key).expect("output length invalid?");
|
||||
scrypt::scrypt(passwd.as_ref(), &self.salt, ¶ms, &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))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user