cleanup: always compute fingerprint in KeyConfig constructors

This commit is contained in:
Dietmar Maurer 2021-01-21 11:56:54 +01:00
parent d543587d34
commit 1c86893d95
5 changed files with 24 additions and 39 deletions

View File

@ -15,7 +15,6 @@ use crate::{
config::{ config::{
tape_encryption_keys::{ tape_encryption_keys::{
TAPE_KEYS_LOCKFILE, TAPE_KEYS_LOCKFILE,
generate_tape_encryption_key,
load_keys, load_keys,
load_key_configs, load_key_configs,
save_keys, save_keys,
@ -133,7 +132,6 @@ pub fn change_passphrase(
let (key, created, fingerprint) = key_config.decrypt(&|| Ok(password.as_bytes().to_vec()))?; let (key, created, fingerprint) = key_config.decrypt(&|| Ok(password.as_bytes().to_vec()))?;
let mut new_key_config = KeyConfig::with_key(&key, new_password.as_bytes(), kdf)?; let mut new_key_config = KeyConfig::with_key(&key, new_password.as_bytes(), kdf)?;
new_key_config.created = created; // keep original value new_key_config.created = created; // keep original value
new_key_config.fingerprint = Some(fingerprint.clone());
new_key_config.hint = Some(hint); new_key_config.hint = Some(hint);
config_map.insert(fingerprint, new_key_config); config_map.insert(fingerprint, new_key_config);
@ -178,7 +176,7 @@ pub fn create_key(
bail!("Please specify a key derivation funktion (none is not allowed here)."); bail!("Please specify a key derivation funktion (none is not allowed here).");
} }
let (key, mut key_config) = generate_tape_encryption_key(password.as_bytes(), kdf)?; let (key, mut key_config) = KeyConfig::new(password.as_bytes(), kdf)?;
key_config.hint = Some(hint); key_config.hint = Some(hint);
let fingerprint = key_config.fingerprint.clone().unwrap(); let fingerprint = key_config.fingerprint.clone().unwrap();

View File

@ -117,21 +117,25 @@ impl KeyConfig {
} }
/// Creates a new, unencrypted key. /// Creates a new, unencrypted key.
pub fn without_password(raw_key: [u8; 32]) -> Self { pub fn without_password(raw_key: [u8; 32]) -> Result<Self, Error> {
// always compute fingerprint
let crypt_config = CryptConfig::new(raw_key.clone())?;
let fingerprint = Some(crypt_config.fingerprint());
let created = proxmox::tools::time::epoch_i64(); let created = proxmox::tools::time::epoch_i64();
Self { Ok(Self {
kdf: None, kdf: None,
created, created,
modified: created, modified: created,
data: raw_key.to_vec(), data: raw_key.to_vec(),
fingerprint: None, fingerprint,
hint: None, hint: None,
} })
} }
/// Creates a new instance, protect raw_key with passphrase. /// Creates a new instance, protect raw_key with passphrase.
pub fn with_key( pub fn with_key(
raw_key: &[u8], raw_key: &[u8; 32],
passphrase: &[u8], passphrase: &[u8],
kdf: Kdf, kdf: Kdf,
) -> Result<Self, Error> { ) -> Result<Self, Error> {
@ -170,7 +174,7 @@ impl KeyConfig {
&derived_key, &derived_key,
Some(&iv), Some(&iv),
b"", b"",
&raw_key, raw_key,
&mut tag, &mut tag,
)?; )?;
@ -181,12 +185,16 @@ impl KeyConfig {
let created = proxmox::tools::time::epoch_i64(); let created = proxmox::tools::time::epoch_i64();
// always compute fingerprint
let crypt_config = CryptConfig::new(raw_key.clone())?;
let fingerprint = Some(crypt_config.fingerprint());
Ok(Self { Ok(Self {
kdf: Some(kdf), kdf: Some(kdf),
created, created,
modified: created, modified: created,
data: enc_data, data: enc_data,
fingerprint: None, fingerprint,
hint: None, hint: None,
}) })
} }

View File

@ -924,9 +924,8 @@ async fn create_backup(
let pem_data = file_get_contents(path)?; let pem_data = file_get_contents(path)?;
let rsa = openssl::rsa::Rsa::public_key_from_pem(&pem_data)?; let rsa = openssl::rsa::Rsa::public_key_from_pem(&pem_data)?;
let mut key_config = KeyConfig::without_password(key); let mut key_config = KeyConfig::without_password(key)?;
key_config.created = created; // keep original value key_config.created = created; // keep original value
key_config.fingerprint = Some(fingerprint);
let enc_key = rsa_encrypt_key_config(rsa, &key_config)?; let enc_key = rsa_encrypt_key_config(rsa, &key_config)?;
println!("Master key '{:?}'", path); println!("Master key '{:?}'", path);

View File

@ -27,7 +27,6 @@ use proxmox_backup::{
}, },
backup::{ backup::{
rsa_decrypt_key_config, rsa_decrypt_key_config,
CryptConfig,
KeyConfig, KeyConfig,
}, },
tools, tools,
@ -127,7 +126,6 @@ fn create(
let mut key = [0u8; 32]; let mut key = [0u8; 32];
proxmox::sys::linux::fill_with_random_data(&mut key)?; proxmox::sys::linux::fill_with_random_data(&mut key)?;
let crypt_config = CryptConfig::new(key.clone())?;
match kdf { match kdf {
Kdf::None => { Kdf::None => {
@ -135,8 +133,7 @@ fn create(
bail!("password hint not allowed for Kdf::None"); bail!("password hint not allowed for Kdf::None");
} }
let mut key_config = KeyConfig::without_password(key); let key_config = KeyConfig::without_password(key)?;
key_config.fingerprint = Some(crypt_config.fingerprint());
key_config.store(path, false)?; key_config.store(path, false)?;
} }
@ -149,7 +146,6 @@ fn create(
let password = tty::read_and_verify_password("Encryption Key Password: ")?; let password = tty::read_and_verify_password("Encryption Key Password: ")?;
let mut key_config = KeyConfig::with_key(&key, &password, kdf)?; let mut key_config = KeyConfig::with_key(&key, &password, kdf)?;
key_config.fingerprint = Some(crypt_config.fingerprint());
key_config.hint = hint; key_config.hint = hint;
key_config.store(&path, false)?; key_config.store(&path, false)?;
@ -214,7 +210,7 @@ async fn import_with_master_key(
.rsa() .rsa()
.map_err(|err| format_err!("not a valid private RSA key - {}", err))?; .map_err(|err| format_err!("not a valid private RSA key - {}", err))?;
let (key, created, fingerprint) = let (key, created, _fingerprint) =
rsa_decrypt_key_config(master_key, &encrypted_key, &get_encryption_key_password)?; rsa_decrypt_key_config(master_key, &encrypted_key, &get_encryption_key_password)?;
let kdf = kdf.unwrap_or_default(); let kdf = kdf.unwrap_or_default();
@ -224,9 +220,8 @@ async fn import_with_master_key(
bail!("password hint not allowed for Kdf::None"); bail!("password hint not allowed for Kdf::None");
} }
let mut key_config = KeyConfig::without_password(key); let mut key_config = KeyConfig::without_password(key)?;
key_config.created = created; // keep original value key_config.created = created; // keep original value
key_config.fingerprint = Some(fingerprint);
key_config.store(path, true)?; key_config.store(path, true)?;
@ -236,7 +231,6 @@ async fn import_with_master_key(
let mut new_key_config = KeyConfig::with_key(&key, &password, kdf)?; let mut new_key_config = KeyConfig::with_key(&key, &password, kdf)?;
new_key_config.created = created; // keep original value new_key_config.created = created; // keep original value
new_key_config.fingerprint = Some(fingerprint);
new_key_config.hint = hint; new_key_config.hint = hint;
new_key_config.store(path, true)?; new_key_config.store(path, true)?;
@ -289,7 +283,7 @@ fn change_passphrase(
} }
let key_config = KeyConfig::load(&path)?; let key_config = KeyConfig::load(&path)?;
let (key, created, fingerprint) = key_config.decrypt(&get_encryption_key_password)?; let (key, created, _fingerprint) = key_config.decrypt(&get_encryption_key_password)?;
match kdf { match kdf {
Kdf::None => { Kdf::None => {
@ -297,9 +291,8 @@ fn change_passphrase(
bail!("password hint not allowed for Kdf::None"); bail!("password hint not allowed for Kdf::None");
} }
let mut key_config = KeyConfig::without_password(key); let mut key_config = KeyConfig::without_password(key)?;
key_config.created = created; // keep original value key_config.created = created; // keep original value
key_config.fingerprint = Some(fingerprint);
key_config.store(&path, true)?; key_config.store(&path, true)?;
} }
@ -308,7 +301,6 @@ fn change_passphrase(
let mut new_key_config = KeyConfig::with_key(&key, &password, kdf)?; let mut new_key_config = KeyConfig::with_key(&key, &password, kdf)?;
new_key_config.created = created; // keep original value new_key_config.created = created; // keep original value
new_key_config.fingerprint = Some(fingerprint);
new_key_config.hint = hint; new_key_config.hint = hint;
new_key_config.store(&path, true)?; new_key_config.store(&path, true)?;

View File

@ -11,11 +11,9 @@ use proxmox::tools::fs::{
}; };
use crate::{ use crate::{
api2::types::Kdf,
backup::{ backup::{
Fingerprint, Fingerprint,
KeyConfig, KeyConfig,
CryptConfig,
}, },
}; };
@ -52,17 +50,6 @@ pub struct EncryptionKeyInfo {
pub key: [u8; 32], pub key: [u8; 32],
} }
pub fn compute_tape_key_fingerprint(key: &[u8; 32]) -> Result<Fingerprint, Error> {
let crypt_config = CryptConfig::new(*key)?;
Ok(crypt_config.fingerprint())
}
pub fn generate_tape_encryption_key(password: &[u8], kdf: Kdf) -> Result<([u8; 32], KeyConfig), Error> {
let (key, mut key_config) = KeyConfig::new(password, kdf)?;
key_config.fingerprint = Some(compute_tape_key_fingerprint(&key)?);
Ok((key, key_config))
}
impl EncryptionKeyInfo { impl EncryptionKeyInfo {
pub fn new(key: [u8; 32], fingerprint: Fingerprint) -> Self { pub fn new(key: [u8; 32], fingerprint: Fingerprint) -> Self {
Self { fingerprint, key } Self { fingerprint, key }
@ -86,7 +73,8 @@ pub fn load_keys() -> Result<(HashMap<Fingerprint, EncryptionKeyInfo>, [u8;32])
let mut map = HashMap::new(); let mut map = HashMap::new();
for item in key_list { for item in key_list {
let expected_fingerprint = compute_tape_key_fingerprint(&item.key)?; let key_config = KeyConfig::without_password(item.key)?; // to compute fingerprint
let expected_fingerprint = key_config.fingerprint.unwrap();
if item.fingerprint != expected_fingerprint { if item.fingerprint != expected_fingerprint {
bail!( bail!(
"inconsistent fingerprint ({} != {})", "inconsistent fingerprint ({} != {})",