serdevault 0.1.2

Encrypted serialization/deserialization using Serde
Documentation
use crate::consts::{NONCE_SIZE, SALT_SIZE};
use crate::encrypter::encrypted_content::EncryptedContent;
use crate::SerdeVaultError;
use aes_gcm::aead::{Aead, KeyInit};
use aes_gcm::{Aes256Gcm, Key, Nonce};
use rand::rngs::OsRng;
use rand::TryRngCore;
use sha2::{Digest, Sha256};

#[derive(Clone, Eq, PartialEq, Debug)]
pub struct Content(Vec<u8>);

impl Content {
    pub fn new(msg: Vec<u8>) -> Self
    where
        Self: Sized,
    {
        Self(msg)
    }

    pub fn into_vec(self) -> Vec<u8> {
        self.0
    }

    pub fn as_slice(&self) -> &[u8] {
        &self.0
    }

    pub fn from_encrypted(data: EncryptedContent, pwd: &str) -> Result<Self, SerdeVaultError> {
        let key = derive_key(pwd, &data.salt[..])?;

        let nonce = Nonce::from_slice(&data.nonce[..]);
        let cipher = Aes256Gcm::new(&key);

        let decrypted = cipher.decrypt(nonce, &data.encrypted[..]).map_err(|_| {
            SerdeVaultError::DecryptionError("Decryption failed - incorrect password?".to_string())
        })?;
        Ok(Content::new(decrypted))
    }

    pub fn encrypt(&self, password: &str) -> Result<EncryptedContent, SerdeVaultError> {
        let mut salt = [0u8; SALT_SIZE];
        OsRng
            .try_fill_bytes(&mut salt)
            .map_err(|e| SerdeVaultError::EncryptionError(e.to_string()))?;
        let key = derive_key(&password, &salt)?;

        let mut nonce_bytes = [0u8; NONCE_SIZE];
        OsRng
            .try_fill_bytes(&mut nonce_bytes)
            .map_err(|e| SerdeVaultError::EncryptionError(e.to_string()))?;
        let nonce = Nonce::from_slice(&nonce_bytes);

        let cipher = Aes256Gcm::new(&key);
        let encrypted_data = cipher
            .encrypt(nonce, self.0.as_ref())
            .map_err(|e| SerdeVaultError::EncryptionError(e.to_string()))?;
        Ok(EncryptedContent::new(encrypted_data, salt, nonce_bytes))
    }
}

fn derive_key(password: &str, salt: &[u8]) -> Result<Key<Aes256Gcm>, SerdeVaultError> {
    let mut hasher = Sha256::new();
    hasher.update(password.as_bytes());
    hasher.update(salt);

    let result = hasher.finalize();
    let key = Key::<Aes256Gcm>::from_slice(result.as_slice());

    Ok(*key)
}