#[cfg(feature = "kdf")]
pub mod derivation;
#[cfg(feature = "kdf")]
pub mod kdf_counter;
pub mod lifecycle;
pub mod manager;
pub mod openssl_rsa;
#[cfg(feature = "post_quantum")]
pub mod post_quantum;
pub mod rotation;
pub mod usage_limit;
#[cfg(test)]
mod tests;
use crate::error::Result;
use crate::memory::{ProtectedKey, SecretBytes};
use crate::types::Algorithm;
use chrono::{DateTime, Utc};
use uuid::Uuid;
pub trait KeyManagerOperations {
fn generate_key_operation(&self, algorithm: Algorithm) -> Result<String>;
fn get_key_operation(&self, key_id: &str) -> Result<Key>;
fn destroy_key_operation(&self, key_id: &str) -> Result<()>;
fn list_keys_operation(&self) -> Result<Vec<String>>;
}
#[cfg(feature = "kdf")]
#[allow(unused)]
pub use kdf_counter::{KdfUsageCounter, KdfUsagePolicy, KdfUsageType};
#[allow(unused)]
pub use lifecycle::{KeyLifecycleManager, KeyLifecyclePolicy, KeyManagerLifecycleExt};
#[allow(unused)]
pub use manager::KeyManager;
#[cfg(feature = "post_quantum")]
#[allow(unused)]
pub use post_quantum::{PqcAlgorithm, PqcKey, PqcKeyManager, PqcOperations};
#[allow(unused)]
pub use rotation::{KeyRotationManager, RotationConfig, RotationTrigger};
#[allow(unused)]
pub use usage_limit::{
KeyUsageLimit, ResetStrategy, UsageLimitManager, UsageLimitPolicy, UsageLimitType,
UsageReportEntry,
};
pub struct KeyStateManager;
impl KeyStateManager {
pub fn is_valid_transition(from: KeyState, to: KeyState) -> bool {
match (from, to) {
(KeyState::Generated, KeyState::Active) => true,
(KeyState::Active, KeyState::Suspended) => true,
(KeyState::Active, KeyState::Destroyed) => true,
(KeyState::Suspended, KeyState::Active) => true,
(KeyState::Suspended, KeyState::Destroyed) => true,
(KeyState::Destroyed, _) => false,
_ => false,
}
}
#[allow(dead_code)]
pub fn get_state_description(state: KeyState) -> &'static str {
match state {
KeyState::Generated => "密钥已生成,等待激活",
KeyState::Active => "密钥已激活,可以使用",
KeyState::Suspended => "密钥已暂停,不能使用",
KeyState::Destroyed => "密钥已销毁,不能再使用",
}
}
}
#[derive(Clone)]
pub struct Key {
id: String,
algorithm: Algorithm,
data: ProtectedKey,
state: KeyState,
created_at: DateTime<Utc>,
activated_at: Option<DateTime<Utc>>,
suspended_at: Option<DateTime<Utc>>,
destroyed_at: Option<DateTime<Utc>>,
expires_at: Option<DateTime<Utc>>,
usage_count: usize,
max_usage: Option<usize>,
metadata: std::collections::HashMap<String, String>,
}
impl Key {
pub fn new(algorithm: Algorithm, data: Vec<u8>) -> Result<Self> {
let secret = SecretBytes::new(data)?;
Ok(Self {
id: Uuid::new_v4().to_string(),
algorithm,
data: ProtectedKey::new(secret)?,
state: KeyState::Generated,
created_at: Utc::now(),
activated_at: None,
suspended_at: None,
destroyed_at: None,
expires_at: None,
usage_count: 0,
max_usage: None,
metadata: std::collections::HashMap::new(),
})
}
pub fn new_active(algorithm: Algorithm, data: Vec<u8>) -> Result<Self> {
let secret = SecretBytes::new(data)?;
let now = Utc::now();
Ok(Self {
id: Uuid::new_v4().to_string(),
algorithm,
data: ProtectedKey::new(secret)?,
state: KeyState::Active,
created_at: now,
activated_at: Some(now),
suspended_at: None,
destroyed_at: None,
expires_at: None,
usage_count: 0,
max_usage: None,
metadata: std::collections::HashMap::new(),
})
}
pub fn new_with_id(algorithm: Algorithm, data: Vec<u8>, id: &str) -> Result<Self> {
let secret = SecretBytes::new(data)?;
Ok(Self {
id: id.to_string(),
algorithm,
data: ProtectedKey::new(secret)?,
state: KeyState::Generated,
created_at: Utc::now(),
activated_at: None,
suspended_at: None,
destroyed_at: None,
expires_at: None,
usage_count: 0,
max_usage: None,
metadata: std::collections::HashMap::new(),
})
}
pub fn activate(&mut self, tenant_id: Option<&str>) -> Result<()> {
if !KeyStateManager::is_valid_transition(self.state, KeyState::Active) {
return Err(crate::error::CryptoError::KeyError(format!(
"Invalid state transition from {:?} to Active",
self.state
)));
}
self.state = KeyState::Active;
self.activated_at = Some(Utc::now());
if let Some(tenant) = tenant_id {
crate::audit::AuditLogger::log_with_tenant(
"KEY_ACTIVATED",
Some(self.algorithm),
Some(&self.id),
Some(tenant),
Ok(()),
"authorized",
);
} else {
crate::audit::AuditLogger::log(
"KEY_ACTIVATED",
Some(self.algorithm),
Some(&self.id),
Ok(()),
);
}
Ok(())
}
pub fn suspend(&mut self) -> Result<()> {
if !KeyStateManager::is_valid_transition(self.state, KeyState::Suspended) {
return Err(crate::error::CryptoError::KeyError(format!(
"Invalid state transition from {:?} to Suspended",
self.state
)));
}
self.state = KeyState::Suspended;
self.suspended_at = Some(Utc::now());
crate::audit::AuditLogger::log(
"KEY_SUSPENDED",
Some(self.algorithm),
Some(&self.id),
Ok(()),
);
Ok(())
}
pub fn resume(&mut self) -> Result<()> {
if !KeyStateManager::is_valid_transition(self.state, KeyState::Active) {
return Err(crate::error::CryptoError::KeyError(format!(
"Invalid state transition from {:?} to Active",
self.state
)));
}
self.state = KeyState::Active;
self.suspended_at = None;
crate::audit::AuditLogger::log("KEY_RESUMED", Some(self.algorithm), Some(&self.id), Ok(()));
Ok(())
}
pub fn destroy(&mut self) -> Result<()> {
if !KeyStateManager::is_valid_transition(self.state, KeyState::Destroyed) {
return Err(crate::error::CryptoError::KeyError(format!(
"Invalid state transition from {:?} to Destroyed",
self.state
)));
}
self.state = KeyState::Destroyed;
self.destroyed_at = Some(Utc::now());
let zeroized_key =
crate::memory::SecretBytes::new(vec![0u8; self.data.access()?.as_bytes().len()])?;
self.data = crate::memory::ProtectedKey::new(zeroized_key)?;
crate::audit::AuditLogger::log(
"KEY_DESTROYED",
Some(self.algorithm),
Some(&self.id),
Ok(()),
);
Ok(())
}
pub fn is_expired(&self) -> bool {
if let Some(expires_at) = self.expires_at {
Utc::now() >= expires_at
} else {
false
}
}
pub fn is_valid(&self) -> bool {
self.state == KeyState::Active && !self.is_expired() && !self.is_usage_exceeded()
}
pub fn is_usage_exceeded(&self) -> bool {
if let Some(max_usage) = self.max_usage {
self.usage_count >= max_usage
} else {
false
}
}
pub fn increment_usage(&mut self) -> Result<()> {
if !self.is_valid() {
return Err(crate::error::CryptoError::KeyError(
"Key is not valid for use".into(),
));
}
self.usage_count += 1;
Ok(())
}
pub(crate) fn set_max_usage(&mut self, max_usage: Option<usize>) {
self.max_usage = max_usage;
}
pub fn get_lifecycle_status(&self) -> String {
format!(
"Key {}: {} (created: {}, state: {:?}, usage: {}, expired: {})",
self.id,
if self.is_valid() { "VALID" } else { "INVALID" },
self.created_at.format("%Y-%m-%d %H:%M:%S"),
self.state,
self.usage_count,
self.is_expired()
)
}
pub fn id(&self) -> &str {
&self.id
}
pub fn algorithm(&self) -> Algorithm {
self.algorithm
}
pub fn state(&self) -> KeyState {
self.state
}
pub fn secret_bytes(&self) -> Result<&SecretBytes> {
if !self.is_valid() {
return Err(crate::error::CryptoError::KeyError(
"Key is not valid for use".into(),
));
}
self.data.access()
}
pub fn public_bytes(&self) -> Result<Vec<u8>> {
if !self.is_valid() {
return Err(crate::error::CryptoError::KeyError(
"Key is not valid for use".into(),
));
}
let key_bytes = self.data.access()?;
let bytes = key_bytes.as_bytes();
match self.algorithm {
Algorithm::Ed25519 => {
if bytes.len() == 32 {
Ok(bytes.to_vec())
} else if bytes.len() >= 32 {
Ok(bytes[..32].to_vec())
} else {
Err(crate::error::CryptoError::KeyError(
"Invalid Ed25519 key length for public key extraction".into(),
))
}
}
_ => Err(crate::error::CryptoError::KeyError(format!(
"Public key extraction not implemented for algorithm {:?}",
self.algorithm
))),
}
}
pub fn created_at(&self) -> DateTime<Utc> {
self.created_at
}
pub fn activated_at(&self) -> Option<DateTime<Utc>> {
self.activated_at
}
pub fn expires_at(&self) -> Option<DateTime<Utc>> {
self.expires_at
}
pub fn set_expires_at(&mut self, expires_at: DateTime<Utc>) {
self.expires_at = Some(expires_at);
}
pub fn usage_count(&self) -> usize {
self.usage_count
}
pub fn metadata(&self) -> &std::collections::HashMap<String, String> {
&self.metadata
}
pub fn metadata_mut(&mut self) -> &mut std::collections::HashMap<String, String> {
&mut self.metadata
}
}
impl Drop for Key {
fn drop(&mut self) {
if let Ok(_secret) = self.data.access() {
if let Ok(zeroized_key) =
crate::memory::SecretBytes::new(vec![0u8; _secret.as_bytes().len()])
{
let _ = crate::memory::ProtectedKey::new(zeroized_key);
}
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum KeyState {
Generated,
Active,
Suspended,
Destroyed,
}