diff --git a/src/backup/key_derivation.rs b/src/backup/key_derivation.rs index a76d95d2..4f7036fa 100644 --- a/src/backup/key_derivation.rs +++ b/src/backup/key_derivation.rs @@ -60,6 +60,8 @@ pub struct KeyConfig { pub kdf: Option, #[serde(with = "proxmox::tools::serde::date_time_as_rfc3339")] pub created: DateTime, + #[serde(with = "proxmox::tools::serde::date_time_as_rfc3339")] + pub modified: DateTime, #[serde(with = "proxmox::tools::serde::bytes_as_base64")] pub data: Vec, } @@ -96,12 +98,10 @@ pub fn store_key_config( Ok(()) } -pub fn store_key_with_passphrase( - path: &std::path::Path, +pub fn encrypt_key_with_passphrase( raw_key: &[u8], passphrase: &[u8], - replace: bool, -) -> Result<(), Error> { +) -> Result { let salt = proxmox::sys::linux::random_data(32)?; @@ -135,14 +135,15 @@ pub fn store_key_with_passphrase( let created = Local.timestamp(Local::now().timestamp(), 0); - store_key_config(path, replace, KeyConfig { + Ok(KeyConfig { kdf: Some(kdf), created, + modified: created, data: enc_data, }) } -pub fn load_and_decrtypt_key(path: &std::path::Path, passphrase: fn() -> Result, Error>) -> Result<[u8;32], Error> { +pub fn load_and_decrtypt_key(path: &std::path::Path, passphrase: fn() -> Result, Error>) -> Result<([u8;32], DateTime), Error> { let raw = crate::tools::file_get_contents(&path)?; let data = String::from_utf8(raw)?; @@ -150,6 +151,7 @@ pub fn load_and_decrtypt_key(path: &std::path::Path, passphrase: fn() -> Result< let key_config: KeyConfig = serde_json::from_str(&data)?; let raw_data = key_config.data; + let created = key_config.created; let key = if let Some(kdf) = key_config.kdf { @@ -186,5 +188,5 @@ pub fn load_and_decrtypt_key(path: &std::path::Path, passphrase: fn() -> Result< let mut result = [0u8; 32]; result.copy_from_slice(&key); - Ok(result) + Ok((result, created)) } diff --git a/src/bin/proxmox-backup-client.rs b/src/bin/proxmox-backup-client.rs index 0ff6bb91..e4b3c2f6 100644 --- a/src/bin/proxmox-backup-client.rs +++ b/src/bin/proxmox-backup-client.rs @@ -471,7 +471,7 @@ fn create_backup( let crypt_config = match keyfile { None => None, Some(path) => { - let key = load_and_decrtypt_key(&path, get_encryption_key_password)?; + let (key, _) = load_and_decrtypt_key(&path, get_encryption_key_password)?; Some(Arc::new(CryptConfig::new(key)?)) } }; @@ -832,7 +832,9 @@ fn key_create( let password = crate::tools::tty::read_password("Encryption Key Password: ")?; - store_key_with_passphrase(&path, &key, &password, false)?; + let key_config = encrypt_key_with_passphrase(&key, &password)?; + + store_key_config(&path, false, key_config)?; Ok(Value::Null) } else if kdf == "none" { @@ -841,6 +843,7 @@ fn key_create( store_key_config(&path, false, KeyConfig { kdf: None, created, + modified: created, data: key, })?; @@ -867,7 +870,7 @@ fn key_change_passphrase( bail!("unable to change passphrase - no tty"); } - let key = load_and_decrtypt_key(&path, get_encryption_key_password)?; + let (key, created) = load_and_decrtypt_key(&path, get_encryption_key_password)?; if kdf == "scrypt" { @@ -882,16 +885,19 @@ fn key_change_passphrase( bail!("Password is too short!"); } - store_key_with_passphrase(&path, &key, new_pw.as_bytes(), true)?; + let mut new_key_config = encrypt_key_with_passphrase(&key, new_pw.as_bytes())?; + new_key_config.created = created; // keep original value + + store_key_config(&path, true, new_key_config)?; Ok(Value::Null) } else if kdf == "none" { - // fixme: keep original creation time, add modified timestamp ?? - let created = Local.timestamp(Local::now().timestamp(), 0); + let modified = Local.timestamp(Local::now().timestamp(), 0); store_key_config(&path, true, KeyConfig { kdf: None, - created, + created, // keep original value + modified, data: key.to_vec(), })?;