trelent-hyok 0.1.12

A Rust library implementing Hold Your Own Key (HYOK) encryption patterns with support for multiple cloud providers
Documentation
//! Custom key management implementation.
//!
//! This module enables integration with any key management system by allowing
//! users to provide their own encryption and decryption functions. It supports:
//!
//! - Custom key management systems
//! - Flexible encryption algorithms
//! - Error handling
//! - Thread-safe operations

use crate::cmk::CMKTrait;
use crate::error::cmk::CMKError;
use async_trait::async_trait;
use std::sync::Arc;

/// A customizable Customer Managed Key implementation.
///
/// This CMK implementation allows integration with any key management system
/// by accepting closures for encryption and decryption. Features include:
///
/// - Flexible key management
/// - Custom algorithms
/// - Error handling
/// - Thread-safe operations
///
/// # Security
///
/// When implementing custom operations, ensure:
/// - Strong encryption algorithms
/// - Proper key management
/// - Secure key storage
/// - Access control
/// - Audit logging
///
/// # Example
/// ```no_run
/// use hyokashi::{CustomCMK, CMKError};
///
/// // Define custom encryption/decryption functions
/// let encrypt = |data: Vec<u8>| Box::pin(async move {
///     // Implement secure encryption...
///     Ok(data)
/// });
///
/// let decrypt = |data: Vec<u8>| Box::pin(async move {
///     // Implement secure decryption...
///     Ok(data)
/// });
///
/// // Create the custom CMK
/// let cmk = CustomCMK::new(encrypt, decrypt);
///
/// // Use the CMK
/// async {
///     let data = vec![1, 2, 3];
///     let encrypted = cmk.encrypt(data).await?;
///     let decrypted = cmk.decrypt(encrypted).await?;
///     # Ok::<(), Box<dyn std::error::Error>>(())
/// };
/// ```
pub struct CustomCMK {
    encrypt_fn: Arc<
        dyn (Fn(Vec<u8>) -> futures::future::BoxFuture<'static, Result<Vec<u8>, CMKError>>) +
            Send +
            Sync
    >,
    decrypt_fn: Arc<
        dyn (Fn(Vec<u8>) -> futures::future::BoxFuture<'static, Result<Vec<u8>, CMKError>>) +
            Send +
            Sync
    >,
}

impl CustomCMK {
    /// Creates a new `CustomCMK` from the provided encryption and decryption closures.
    ///
    /// # Arguments
    ///
    /// * `encrypt_fn` - A closure or function pointer returning a future that encrypts data.
    /// * `decrypt_fn` - A closure or function pointer returning a future that decrypts data.
    ///
    /// # Returns
    ///
    /// A new `CustomCMK` that delegates encryption and decryption to the provided closures.
    pub fn new<E, D>(encrypt_fn: E, decrypt_fn: D) -> Self
        where
            E: Fn(Vec<u8>) -> futures::future::BoxFuture<'static, Result<Vec<u8>, CMKError>> +
                Send +
                Sync +
                'static,
            D: Fn(Vec<u8>) -> futures::future::BoxFuture<'static, Result<Vec<u8>, CMKError>> +
                Send +
                Sync +
                'static
    {
        CustomCMK {
            encrypt_fn: Arc::new(encrypt_fn),
            decrypt_fn: Arc::new(decrypt_fn),
        }
    }
}

#[async_trait]
impl CMKTrait for CustomCMK {
    /// Encrypts the specified plaintext data by calling the user-provided `encrypt_fn`.
    ///
    /// # Arguments
    ///
    /// * `plaintext` - The plaintext bytes to be encrypted.
    ///
    /// # Errors
    ///
    /// Returns a `CMKError` if `encrypt_fn` returns an error.
    ///
    /// # Example
    /// ```no_run
    /// let custom_cmk = CustomCMK::new(/* ... */);
    /// let encrypted = custom_cmk.encrypt(vec![0x01, 0x02]).await?;
    /// ```
    async fn encrypt(&self, plaintext: Vec<u8>) -> Result<Vec<u8>, CMKError> {
        (self.encrypt_fn)(plaintext).await
    }

    /// Decrypts the specified ciphertext data by calling the user-provided `decrypt_fn`.
    ///
    /// # Arguments
    ///
    /// * `ciphertext` - The ciphertext bytes to be decrypted.
    ///
    /// # Errors
    ///
    /// Returns a `CMKError` if `decrypt_fn` returns an error.
    ///
    /// # Example
    /// ```no_run
    /// let custom_cmk = CustomCMK::new(/* ... */);
    /// let decrypted = custom_cmk.decrypt(encrypted_data).await?;
    /// ```
    async fn decrypt(&self, ciphertext: Vec<u8>) -> Result<Vec<u8>, CMKError> {
        (self.decrypt_fn)(ciphertext).await
    }
}