]> git.proxmox.com Git - proxmox-backup.git/blobdiff - src/config/tape_encryption_keys.rs
typo fixes all over the place
[proxmox-backup.git] / src / config / tape_encryption_keys.rs
index 3e94dfa04bce857f72b9bb6456704626a15d00f5..42c3184dea0b50751c814156f38c37dfe50ffee2 100644 (file)
@@ -1,3 +1,15 @@
+//! Store Tape encryptions keys
+//!
+//! This module can store 256bit encryption keys for tape backups,
+//! indexed by key fingerprint.
+//!
+//! We store the plain key (unencrypted), as well as a encrypted
+//! version protected by password (see struct `KeyConfig`)
+//!
+//! Tape backups store the password protected version on tape, so that
+//! it is possible to restore the key from tape if you know the
+//! password.
+
 use std::collections::HashMap;
 
 use anyhow::{bail, Error};
@@ -11,11 +23,9 @@ use proxmox::tools::fs::{
 };
 
 use crate::{
-    api2::types::Kdf,
     backup::{
         Fingerprint,
         KeyConfig,
-        CryptConfig,
     },
 };
 
@@ -44,25 +54,16 @@ mod hex_key {
     }
 }
 
-/// Store Hardware Encryption keys (private part)
+/// Store Hardware Encryption keys (plain, unprotected keys)
 #[derive(Deserialize, Serialize)]
 pub struct EncryptionKeyInfo {
+    /// Key fingerprint (we verify the fingerprint on load)
     pub fingerprint: Fingerprint,
+    /// The plain encryption key
     #[serde(with = "hex_key")]
     pub key: [u8; 32],
 }
 
-pub fn compute_tape_key_fingerprint(key: &[u8; 32]) -> Result<Fingerprint, Error> {
-    let crypt_config = CryptConfig::new(key.clone())?;
-    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 {
     pub fn new(key: [u8; 32], fingerprint: Fingerprint) -> Self {
         Self { fingerprint, key }
@@ -73,7 +74,7 @@ pub const TAPE_KEYS_FILENAME: &str = "/etc/proxmox-backup/tape-encryption-keys.j
 pub const TAPE_KEY_CONFIG_FILENAME: &str = "/etc/proxmox-backup/tape-encryption-key-config.json";
 pub const TAPE_KEYS_LOCKFILE: &str = "/etc/proxmox-backup/.tape-encryption-keys.lck";
 
-/// Load tape encryption keys (private part)
+/// Load tape encryption keys (plain, unprotected keys)
 pub fn load_keys() -> Result<(HashMap<Fingerprint, EncryptionKeyInfo>,  [u8;32]), Error> {
 
     let content = file_read_optional_string(TAPE_KEYS_FILENAME)?;
@@ -86,7 +87,8 @@ pub fn load_keys() -> Result<(HashMap<Fingerprint, EncryptionKeyInfo>,  [u8;32])
     let mut map = HashMap::new();
 
     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 {
             bail!(
                 "inconsistent fingerprint ({} != {})",
@@ -103,7 +105,7 @@ pub fn load_keys() -> Result<(HashMap<Fingerprint, EncryptionKeyInfo>,  [u8;32])
     Ok((map, digest))
 }
 
-/// Load tape encryption key configurations (public part)
+/// Load tape encryption key configurations (password protected keys)
 pub fn load_key_configs() -> Result<(HashMap<Fingerprint, KeyConfig>,  [u8;32]), Error> {
 
     let content = file_read_optional_string(TAPE_KEY_CONFIG_FILENAME)?;
@@ -129,6 +131,9 @@ pub fn load_key_configs() -> Result<(HashMap<Fingerprint, KeyConfig>,  [u8;32]),
     Ok((map, digest))
 }
 
+/// Store tape encryption keys (plain, unprotected keys)
+///
+/// The file is only accessible by user root (mode 0600).
 pub fn save_keys(map: HashMap<Fingerprint, EncryptionKeyInfo>) -> Result<(), Error> {
 
     let mut list = Vec::new();
@@ -152,6 +157,7 @@ pub fn save_keys(map: HashMap<Fingerprint, EncryptionKeyInfo>) -> Result<(), Err
     Ok(())
 }
 
+/// Store tape encryption key configurations (password protected keys)
 pub fn save_key_configs(map: HashMap<Fingerprint, KeyConfig>) -> Result<(), Error> {
 
     let mut list = Vec::new();
@@ -163,7 +169,7 @@ pub fn save_key_configs(map: HashMap<Fingerprint, KeyConfig>) -> Result<(), Erro
     let raw = serde_json::to_string_pretty(&list)?;
 
     let backup_user = crate::backup::backup_user()?;
-    let mode = nix::sys::stat::Mode::from_bits_truncate(0o0600);
+    let mode = nix::sys::stat::Mode::from_bits_truncate(0o0640);
     // set the correct owner/group/permissions while saving file
     // owner(rw) = root, group(r)= backup
     let options = CreateOptions::new()
@@ -176,7 +182,10 @@ pub fn save_key_configs(map: HashMap<Fingerprint, KeyConfig>) -> Result<(), Erro
     Ok(())
 }
 
-pub fn insert_key(key: [u8;32], key_config: KeyConfig) -> Result<(), Error> {
+/// Insert a new key
+///
+/// Get the lock, load both files, insert the new key, store files.
+pub fn insert_key(key: [u8;32], key_config: KeyConfig, force: bool) -> Result<(), Error> {
 
     let _lock = open_file_locked(
         TAPE_KEYS_LOCKFILE,
@@ -192,8 +201,10 @@ pub fn insert_key(key: [u8;32], key_config: KeyConfig) -> Result<(), Error> {
         None => bail!("missing encryption key fingerprint - internal error"),
     };
 
-    if let Some(_) = config_map.get(&fingerprint) {
-        bail!("encryption key '{}' already exists.", fingerprint);
+    if !force {
+        if config_map.get(&fingerprint).is_some() {
+            bail!("encryption key '{}' already exists.", fingerprint);
+        }
     }
 
     let item = EncryptionKeyInfo::new(key, fingerprint.clone());
@@ -207,6 +218,7 @@ pub fn insert_key(key: [u8;32], key_config: KeyConfig) -> Result<(), Error> {
 }
 
 // shell completion helper
+/// Complete tape encryption key fingerprints
 pub fn complete_key_fingerprint(_arg: &str, _param: &HashMap<String, String>) -> Vec<String> {
     let data = match load_key_configs() {
         Ok((data, _digest)) => data,