enc_file 0.6.3

Password-based file encryption tool with a versioned header, AEAD, Argon2id KDF, and streaming mode. Library + CLI + GUI.
Documentation
//! Named symmetric key map management.

use crate::file::write_all_atomic;
use crate::types::{EncFileError, EncryptOptions, KeyMap};
use secrecy::SecretString;
use std::fs::File;
use std::io::Read;
use std::path::Path;
use zeroize::Zeroize;

/// Load an encrypted key map from disk using a password.
///
/// The key map is expected to be an encrypted CBOR-encoded HashMap
/// created by `save_keymap`.
///
/// # Arguments
///
/// * `path` - Path to the encrypted key map file
/// * `password` - Password used to encrypt the key map
///
/// # Returns
///
/// The decrypted key map containing string names mapped to key data.
pub fn load_keymap(path: &Path, password: SecretString) -> Result<KeyMap, EncFileError> {
    let mut data = Vec::new();
    File::open(path)?.read_to_end(&mut data)?;
    let mut pt = crate::decrypt_bytes(&data, password)?;
    let map: KeyMap = ciborium::de::from_reader(pt.as_slice())?;

    // Zeroize the plaintext keymap data after deserialization
    pt.zeroize();

    Ok(map)
}

/// Save a key map to disk encrypted with a password.
///
/// The key map is CBOR-encoded and then encrypted using the provided options.
/// On Unix systems, the output file permissions are set to 0600 for security.
///
/// # Arguments
///
/// * `path` - Output path for the encrypted key map
/// * `password` - Password to encrypt the key map with
/// * `map` - The key map to save
/// * `opts` - Encryption options (streaming is not supported for key maps)
///
/// # Errors
///
/// Returns `EncFileError::Invalid` if streaming mode is requested, as key maps
/// don't support streaming encryption.
pub fn save_keymap(
    path: &Path,
    password: SecretString,
    map: &KeyMap,
    opts: &EncryptOptions,
) -> Result<(), EncFileError> {
    let mut pt = Vec::new();
    ciborium::ser::into_writer(map, &mut pt)?;
    let bytes = if opts.stream {
        return Err(EncFileError::Invalid("keymap: streaming not supported"));
    } else {
        crate::encrypt_bytes(&pt, password, opts)?
    };

    // Zeroize the plaintext serialized keymap data after encryption
    pt.zeroize();

    write_all_atomic(path, &bytes, true)?;
    Ok(())
}