trelent-hyok 0.1.12

A Rust library implementing Hold Your Own Key (HYOK) encryption patterns with support for multiple cloud providers
Documentation
//! Customer Managed Key (CMK) management and operations.
//!
//! This module provides a flexible system for managing Customer Managed Keys,
//! which are used to encrypt and decrypt Data Encryption Keys (DEKs). It supports:
//!
//! - AWS Key Management Service (KMS)
//! - Azure Key Vault
//! - Custom implementations
//!
//! The module ensures consistent encryption operations while allowing integration
//! with different key management services.

use async_trait::async_trait;

use crate::error::cmk::CMKError;

mod aws_cmk;
mod azure_cmk;
mod custom_cmk;

#[cfg(feature = "aws")]
pub use aws_cmk::*;
#[cfg(feature = "azure")]
pub use azure_cmk::*;
pub use custom_cmk::*;

/// A trait that represents a Customer Managed Key (CMK) capable of encrypting
/// and decrypting data.
///
/// This trait provides a consistent interface for key operations across different
/// key management services. Implementations should ensure:
///
/// - Secure key storage
/// - Proper encryption/decryption
/// - Error handling
/// - Access control
///
/// # Security
///
/// Implementations should:
/// - Use strong encryption algorithms
/// - Protect key material
/// - Implement proper access controls
/// - Follow cryptographic best practices
///
/// # Example
/// ```no_run
/// use async_trait::async_trait;
/// use hyokashi::{CMKTrait, CMKError};
///
/// struct MyCMK;
///
/// #[async_trait]
/// impl CMKTrait for MyCMK {
///     async fn encrypt(&self, plaintext: Vec<u8>) -> Result<Vec<u8>, CMKError> {
///         // Implement secure encryption...
///         # Ok(vec![])
///     }
///
///     async fn decrypt(&self, ciphertext: Vec<u8>) -> Result<Vec<u8>, CMKError> {
///         // Implement secure decryption...
///         # Ok(vec![])
///     }
/// }
/// ```
#[async_trait]
pub trait CMKTrait {
    /// Encrypts the given plaintext bytes using the CMK.
    ///
    /// # Arguments
    ///
    /// * `plaintext` - The data to encrypt
    ///
    /// # Errors
    ///
    /// Returns a `CMKError` if encryption fails due to:
    /// - Key access issues
    /// - Service unavailability
    /// - Invalid input data
    /// - Algorithm failures
    async fn encrypt(&self, plaintext: Vec<u8>) -> Result<Vec<u8>, CMKError>;

    /// Decrypts the given ciphertext bytes using the CMK.
    ///
    /// # Arguments
    ///
    /// * `ciphertext` - The data to decrypt
    ///
    /// # Errors
    ///
    /// Returns a `CMKError` if decryption fails due to:
    /// - Key access issues
    /// - Service unavailability
    /// - Invalid ciphertext
    /// - Algorithm failures
    async fn decrypt(&self, ciphertext: Vec<u8>) -> Result<Vec<u8>, CMKError>;
}

/// Available Customer Managed Key implementations.
///
/// This enum provides a unified interface to different key management services:
///
/// - `AWS`: AWS KMS integration (requires "aws" feature)
/// - `Azure`: Azure Key Vault integration (requires "azure" feature)
/// - `Custom`: User-defined CMK implementation
///
/// # Feature Flags
///
/// Different backends can be enabled via feature flags:
/// - `aws`: Enables AWS KMS support
/// - `azure`: Enables Azure Key Vault support
///
/// # Security
///
/// For production use:
/// - Use cloud provider solutions when possible
/// - Ensure proper key rotation
/// - Implement access controls
/// - Monitor key usage
///
/// # Example
/// ```no_run
/// use hyokashi::CMK;
///
/// // Create an AWS KMS-based CMK
/// #[cfg(feature = "aws")]
/// let cmk = CMK::AWS(AwsCMK::new(
///     client,
///     "alias/my-key".to_string(),
///     encryption_algorithm
/// ));
///
/// // Use the CMK
///     let encrypted = cmk.encrypt(vec![1, 2, 3]).await?;
///     let decrypted = cmk.decrypt(encrypted).await?;
/// ```
pub enum CMK {
    #[cfg(feature = "aws")]
    /// AWS Key Management Service implementation
    AWS(AwsCMK),
    #[cfg(feature = "azure")]
    /// Azure Key Vault implementation
    Azure(AzureCMK),
    /// Custom key management implementation
    Custom(CustomCMK),
}

impl CMK {
    /// Encrypts the provided data with the underlying CMK variant.
    ///
    /// # Errors
    ///
    /// Returns a `CMKError` if encryption fails through the underlying CMK.
    pub async fn encrypt(&self, key: Vec<u8>) -> Result<Vec<u8>, CMKError> {
        (match self {
            #[cfg(feature = "aws")]
            CMK::AWS(cmk) => cmk.encrypt(key),
            #[cfg(feature = "azure")]
            CMK::Azure(cmk) => cmk.encrypt(key),
            CMK::Custom(cmk) => cmk.encrypt(key),
        }).await
    }

    /// Decrypts the provided data with the underlying CMK variant.
    ///
    /// # Errors
    ///
    /// Returns a `CMKError` if decryption fails through the underlying CMK.
    pub async fn decrypt(&self, key: Vec<u8>) -> Result<Vec<u8>, CMKError> {
        (match self {
            #[cfg(feature = "aws")]
            CMK::AWS(cmk) => cmk.decrypt(key),
            #[cfg(feature = "azure")]
            CMK::Azure(cmk) => cmk.decrypt(key),
            CMK::Custom(cmk) => cmk.decrypt(key),
        }).await
    }
}