oxismet 0.1.0

A mass encryption tool for servers
Documentation
use std::{fs::File, io::Write, process::ExitCode};

use smet::{GcmNonce, Salt};

use crate::VERSION;

pub fn encrypt_with_password(
    password: &str,
    bytes: &[u8],
    buffer: &mut File,
) -> Result<(), ExitCode> {
    let (encrypted_data, salt) =
        smet::encrypt_with_password(bytes, password).map_err(|_| ExitCode::FAILURE)?;
    buffer
        .write_all(&VERSION.to_be_bytes())
        .map_err(|_| ExitCode::FAILURE)?;
    buffer
        .write_all(encrypted_data.nonce.as_slice())
        .map_err(|_| ExitCode::FAILURE)?;
    buffer
        .write_all(salt.as_slice())
        .map_err(|_| ExitCode::FAILURE)?;
    buffer
        .write_all(&encrypted_data.bytes)
        .map_err(|_| ExitCode::FAILURE)?;
    Ok(())
}
pub fn decrypt_with_password(
    password: &str,
    bytes: &[u8],
    buffer: &mut File,
) -> Result<(), ExitCode> {
    let Some((version_bytes, rest)) = bytes.split_first_chunk::<8>() else {
        eprintln!("Error: Input file too short to contain a version header.");
        return Err(ExitCode::FAILURE);
    };
    let version = u64::from_be_bytes(*version_bytes);
    if version != VERSION {
        eprintln!("Error: Unsupported File Version: {version}.");
        return Err(ExitCode::FAILURE);
    }
    let Some((nonce_bytes, rest)) = rest.split_first_chunk::<12>() else {
        eprintln!("Error: Input file too short to contain a nonce.");
        return Err(ExitCode::FAILURE);
    };
    let Some((salt_bytes, ciphertext)) = rest.split_first_chunk::<16>() else {
        eprintln!("Error: Input file too short to contain a salt.");
        return Err(ExitCode::FAILURE);
    };
    let plaintext = smet::decrypt_with_password(
        ciphertext,
        password,
        &Salt::from_slice(salt_bytes),
        &GcmNonce::from_slice(nonce_bytes),
    )
    .map_err(|_| ExitCode::FAILURE)?;
    buffer
        .write_all(plaintext.as_slice())
        .map_err(|_| ExitCode::FAILURE)?;
    Ok(())
}