chie_crypto/
hsm.rs

1//! Hardware Security Module (HSM) and TPM integration for enterprise deployments.
2//!
3//! This module provides an abstraction layer for cryptographic operations that can be
4//! backed by either software keys or hardware security modules (HSM/TPM).
5//!
6//! Supported backends:
7//! - Software: Uses in-memory Ed25519 keys (default)
8//! - PKCS#11: For HSM devices supporting PKCS#11 interface
9//! - TPM 2.0: For Trusted Platform Module integration
10//!
11//! # Phase 17A Enhancements
12//!
13//! - Audit logging for all HSM operations
14//! - Key versioning and rotation tracking
15//! - Health monitoring for HSM availability
16//! - Batch operations for improved performance
17//! - Session management for connection pooling
18//! - Key lifecycle states (active, archived, compromised, revoked)
19
20#![allow(dead_code)]
21
22use crate::{KeyPair, PublicKey, SecretKey, SignatureBytes, SigningError, verify};
23use serde::{Deserialize, Serialize};
24use std::collections::HashMap;
25use std::sync::{Arc, RwLock};
26use std::time::SystemTime;
27use thiserror::Error;
28
29/// Errors specific to HSM operations.
30#[derive(Debug, Error)]
31pub enum HsmError {
32    #[error("HSM not initialized")]
33    NotInitialized,
34
35    #[error("HSM connection failed: {0}")]
36    ConnectionFailed(String),
37
38    #[error("HSM authentication failed")]
39    AuthenticationFailed,
40
41    #[error("Key not found: {0}")]
42    KeyNotFound(String),
43
44    #[error("Key generation failed: {0}")]
45    KeyGenerationFailed(String),
46
47    #[error("Signing operation failed: {0}")]
48    SigningFailed(String),
49
50    #[error("Unsupported operation: {0}")]
51    UnsupportedOperation(String),
52
53    #[error("PKCS#11 error: {0}")]
54    Pkcs11Error(String),
55
56    #[error("TPM error: {0}")]
57    TpmError(String),
58
59    #[error("Signing error: {0}")]
60    Signing(#[from] SigningError),
61
62    #[error("Configuration error: {0}")]
63    ConfigError(String),
64}
65
66/// Result type for HSM operations.
67pub type HsmResult<T> = Result<T, HsmError>;
68
69/// Key lifecycle state for tracking key status.
70#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
71pub enum KeyLifecycleState {
72    /// Key is active and can be used for operations
73    #[default]
74    Active,
75    /// Key is archived (read-only, not for new operations)
76    Archived,
77    /// Key is suspected to be compromised
78    Compromised,
79    /// Key is revoked and must not be used
80    Revoked,
81    /// Key is pending activation
82    Pending,
83}
84
85impl std::fmt::Display for KeyLifecycleState {
86    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
87        match self {
88            Self::Active => write!(f, "active"),
89            Self::Archived => write!(f, "archived"),
90            Self::Compromised => write!(f, "compromised"),
91            Self::Revoked => write!(f, "revoked"),
92            Self::Pending => write!(f, "pending"),
93        }
94    }
95}
96
97/// Audit event type for HSM operations.
98#[derive(Debug, Clone, Serialize, Deserialize)]
99pub enum AuditEventType {
100    /// Key generation event
101    KeyGenerated,
102    /// Key import event
103    KeyImported,
104    /// Key export event
105    KeyExported,
106    /// Signing operation
107    SignOperation,
108    /// Key deletion event
109    KeyDeleted,
110    /// Key state change
111    KeyStateChanged,
112    /// Authentication event
113    Authentication,
114    /// Configuration change
115    ConfigChange,
116    /// Health check
117    HealthCheck,
118}
119
120impl std::fmt::Display for AuditEventType {
121    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
122        match self {
123            Self::KeyGenerated => write!(f, "key_generated"),
124            Self::KeyImported => write!(f, "key_imported"),
125            Self::KeyExported => write!(f, "key_exported"),
126            Self::SignOperation => write!(f, "sign_operation"),
127            Self::KeyDeleted => write!(f, "key_deleted"),
128            Self::KeyStateChanged => write!(f, "key_state_changed"),
129            Self::Authentication => write!(f, "authentication"),
130            Self::ConfigChange => write!(f, "config_change"),
131            Self::HealthCheck => write!(f, "health_check"),
132        }
133    }
134}
135
136/// Audit log entry for HSM operations.
137#[derive(Debug, Clone, Serialize, Deserialize)]
138pub struct AuditEntry {
139    /// Timestamp of the event (Unix seconds)
140    pub timestamp: u64,
141    /// Type of event
142    pub event_type: AuditEventType,
143    /// Provider name
144    pub provider: String,
145    /// Key ID involved (if applicable)
146    pub key_id: Option<String>,
147    /// Success flag
148    pub success: bool,
149    /// Error message (if failed)
150    pub error: Option<String>,
151    /// Additional metadata
152    pub metadata: HashMap<String, String>,
153}
154
155impl AuditEntry {
156    /// Create a new audit entry
157    pub fn new(event_type: AuditEventType, provider: impl Into<String>) -> Self {
158        Self {
159            timestamp: SystemTime::now()
160                .duration_since(SystemTime::UNIX_EPOCH)
161                .unwrap_or_default()
162                .as_secs(),
163            event_type,
164            provider: provider.into(),
165            key_id: None,
166            success: true,
167            error: None,
168            metadata: HashMap::new(),
169        }
170    }
171
172    /// Set key ID
173    pub fn with_key_id(mut self, key_id: impl Into<String>) -> Self {
174        self.key_id = Some(key_id.into());
175        self
176    }
177
178    /// Mark as failed with error message
179    pub fn with_error(mut self, error: impl Into<String>) -> Self {
180        self.success = false;
181        self.error = Some(error.into());
182        self
183    }
184
185    /// Add metadata
186    pub fn with_metadata(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
187        self.metadata.insert(key.into(), value.into());
188        self
189    }
190}
191
192/// Health status for HSM provider.
193#[derive(Debug, Clone, Serialize, Deserialize)]
194pub struct HealthStatus {
195    /// Provider name
196    pub provider: String,
197    /// Is provider healthy
198    pub healthy: bool,
199    /// Last health check timestamp
200    pub last_check: u64,
201    /// Response time in milliseconds
202    pub response_time_ms: u64,
203    /// Error message (if unhealthy)
204    pub error: Option<String>,
205    /// Additional metrics
206    pub metrics: HashMap<String, String>,
207}
208
209impl HealthStatus {
210    /// Create a new health status
211    pub fn new(provider: impl Into<String>, healthy: bool) -> Self {
212        Self {
213            provider: provider.into(),
214            healthy,
215            last_check: SystemTime::now()
216                .duration_since(SystemTime::UNIX_EPOCH)
217                .unwrap_or_default()
218                .as_secs(),
219            response_time_ms: 0,
220            error: None,
221            metrics: HashMap::new(),
222        }
223    }
224
225    /// Set response time
226    pub fn with_response_time(mut self, ms: u64) -> Self {
227        self.response_time_ms = ms;
228        self
229    }
230
231    /// Set error
232    pub fn with_error(mut self, error: impl Into<String>) -> Self {
233        self.error = Some(error.into());
234        self.healthy = false;
235        self
236    }
237
238    /// Add metric
239    pub fn with_metric(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
240        self.metrics.insert(key.into(), value.into());
241        self
242    }
243}
244
245/// Key identifier for HSM-stored keys.
246#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
247pub struct KeyId(pub String);
248
249impl KeyId {
250    /// Create a new key identifier.
251    pub fn new(id: impl Into<String>) -> Self {
252        Self(id.into())
253    }
254}
255
256impl std::fmt::Display for KeyId {
257    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
258        write!(f, "{}", self.0)
259    }
260}
261
262/// Key metadata stored alongside the key.
263#[derive(Debug, Clone, Serialize, Deserialize)]
264pub struct KeyMetadata {
265    /// Key identifier.
266    pub id: KeyId,
267    /// Human-readable label.
268    pub label: String,
269    /// Key algorithm (e.g., "Ed25519").
270    pub algorithm: String,
271    /// Creation timestamp (Unix seconds).
272    pub created_at: u64,
273    /// Whether the key can be exported.
274    pub exportable: bool,
275    /// Key lifecycle state.
276    pub state: KeyLifecycleState,
277    /// Key version (increments with rotation).
278    pub version: u32,
279    /// Last used timestamp (Unix seconds).
280    pub last_used: Option<u64>,
281    /// Last rotated timestamp (Unix seconds).
282    pub last_rotated: Option<u64>,
283    /// Operation count (how many times key was used).
284    pub operation_count: u64,
285    /// Custom attributes.
286    pub attributes: HashMap<String, String>,
287}
288
289impl KeyMetadata {
290    /// Create new key metadata.
291    pub fn new(id: KeyId, label: impl Into<String>) -> Self {
292        Self {
293            id,
294            label: label.into(),
295            algorithm: "Ed25519".to_string(),
296            created_at: std::time::SystemTime::now()
297                .duration_since(std::time::UNIX_EPOCH)
298                .unwrap_or_default()
299                .as_secs(),
300            exportable: false,
301            state: KeyLifecycleState::Active,
302            version: 1,
303            last_used: None,
304            last_rotated: None,
305            operation_count: 0,
306            attributes: HashMap::new(),
307        }
308    }
309
310    /// Set exportable flag.
311    pub fn with_exportable(mut self, exportable: bool) -> Self {
312        self.exportable = exportable;
313        self
314    }
315
316    /// Set lifecycle state.
317    pub fn with_state(mut self, state: KeyLifecycleState) -> Self {
318        self.state = state;
319        self
320    }
321
322    /// Add a custom attribute.
323    pub fn with_attribute(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
324        self.attributes.insert(key.into(), value.into());
325        self
326    }
327
328    /// Record key usage.
329    pub fn record_usage(&mut self) {
330        self.operation_count += 1;
331        self.last_used = Some(
332            SystemTime::now()
333                .duration_since(SystemTime::UNIX_EPOCH)
334                .unwrap_or_default()
335                .as_secs(),
336        );
337    }
338
339    /// Mark key as rotated.
340    pub fn mark_rotated(&mut self) {
341        self.version += 1;
342        self.last_rotated = Some(
343            SystemTime::now()
344                .duration_since(SystemTime::UNIX_EPOCH)
345                .unwrap_or_default()
346                .as_secs(),
347        );
348    }
349
350    /// Check if key is usable for operations.
351    pub fn is_usable(&self) -> bool {
352        matches!(self.state, KeyLifecycleState::Active)
353    }
354}
355
356/// Trait for cryptographic signing providers.
357///
358/// This trait abstracts over different key storage backends, allowing
359/// the same code to work with software keys, HSMs, or TPMs.
360pub trait SigningProvider: Send + Sync {
361    /// Get the provider name.
362    fn name(&self) -> &str;
363
364    /// Check if the provider is available and initialized.
365    fn is_available(&self) -> bool;
366
367    /// Generate a new key pair and return its identifier.
368    fn generate_key(&self, label: &str) -> HsmResult<KeyId>;
369
370    /// Import an existing secret key.
371    fn import_key(&self, label: &str, secret_key: &SecretKey) -> HsmResult<KeyId>;
372
373    /// Get the public key for a key identifier.
374    fn get_public_key(&self, key_id: &KeyId) -> HsmResult<PublicKey>;
375
376    /// Sign a message using the specified key.
377    fn sign(&self, key_id: &KeyId, message: &[u8]) -> HsmResult<SignatureBytes>;
378
379    /// Verify a signature (can use public key directly).
380    fn verify(
381        &self,
382        public_key: &PublicKey,
383        message: &[u8],
384        signature: &SignatureBytes,
385    ) -> HsmResult<()> {
386        verify(public_key, message, signature).map_err(HsmError::from)
387    }
388
389    /// List all key identifiers.
390    fn list_keys(&self) -> HsmResult<Vec<KeyMetadata>>;
391
392    /// Delete a key.
393    fn delete_key(&self, key_id: &KeyId) -> HsmResult<()>;
394
395    /// Check if a key exists.
396    fn key_exists(&self, key_id: &KeyId) -> bool;
397
398    /// Export secret key (if allowed by key policy).
399    fn export_key(&self, key_id: &KeyId) -> HsmResult<SecretKey> {
400        let _ = key_id;
401        Err(HsmError::UnsupportedOperation(
402            "Key export not supported by this provider".to_string(),
403        ))
404    }
405
406    // Phase 17A enhancements:
407
408    /// Get key metadata including lifecycle state and usage stats.
409    fn get_key_metadata(&self, key_id: &KeyId) -> HsmResult<KeyMetadata> {
410        // Default implementation returns basic metadata from list_keys
411        let keys = self.list_keys()?;
412        keys.into_iter()
413            .find(|k| k.id == *key_id)
414            .ok_or_else(|| HsmError::KeyNotFound(key_id.to_string()))
415    }
416
417    /// Update key lifecycle state.
418    fn update_key_state(&self, key_id: &KeyId, state: KeyLifecycleState) -> HsmResult<()> {
419        let _ = (key_id, state);
420        Err(HsmError::UnsupportedOperation(
421            "Key state updates not supported by this provider".to_string(),
422        ))
423    }
424
425    /// Perform health check and return status.
426    fn health_check(&self) -> HsmResult<HealthStatus> {
427        let start = SystemTime::now();
428        let healthy = self.is_available();
429        let elapsed = start.elapsed().unwrap_or_default().as_millis() as u64;
430
431        Ok(HealthStatus::new(self.name(), healthy).with_response_time(elapsed))
432    }
433
434    /// Batch sign multiple messages.
435    fn batch_sign(&self, key_id: &KeyId, messages: &[&[u8]]) -> HsmResult<Vec<SignatureBytes>> {
436        // Default implementation: sign each message individually
437        messages.iter().map(|msg| self.sign(key_id, msg)).collect()
438    }
439
440    /// Get audit log entries (if supported).
441    fn get_audit_log(&self, limit: usize) -> HsmResult<Vec<AuditEntry>> {
442        let _ = limit;
443        Err(HsmError::UnsupportedOperation(
444            "Audit log not supported by this provider".to_string(),
445        ))
446    }
447
448    /// Rotate a key (generate new version while archiving old one).
449    fn rotate_key(&self, key_id: &KeyId, new_label: &str) -> HsmResult<KeyId> {
450        // Default implementation: archive old key, generate new one
451        self.update_key_state(key_id, KeyLifecycleState::Archived)?;
452        self.generate_key(new_label)
453    }
454}
455
456/// Software-based signing provider using in-memory keys.
457///
458/// This is the default provider and is suitable for development
459/// and non-enterprise deployments.
460pub struct SoftwareProvider {
461    keys: RwLock<HashMap<KeyId, (KeyPair, KeyMetadata)>>,
462    allow_export: bool,
463    audit_log: RwLock<Vec<AuditEntry>>,
464}
465
466impl Default for SoftwareProvider {
467    fn default() -> Self {
468        Self::new()
469    }
470}
471
472impl SoftwareProvider {
473    /// Create a new software provider.
474    pub fn new() -> Self {
475        Self {
476            keys: RwLock::new(HashMap::new()),
477            allow_export: true,
478            audit_log: RwLock::new(Vec::new()),
479        }
480    }
481
482    /// Create a provider that doesn't allow key export.
483    pub fn new_non_exportable() -> Self {
484        Self {
485            keys: RwLock::new(HashMap::new()),
486            allow_export: false,
487            audit_log: RwLock::new(Vec::new()),
488        }
489    }
490
491    /// Log an audit event.
492    fn log_audit(&self, entry: AuditEntry) {
493        let mut log = self.audit_log.write().unwrap();
494        log.push(entry);
495        // Keep only last 10,000 entries to prevent unbounded growth
496        if log.len() > 10_000 {
497            log.drain(0..1000);
498        }
499    }
500
501    fn next_key_id(&self) -> KeyId {
502        let keys = self.keys.read().unwrap();
503        let mut id = keys.len();
504        loop {
505            let key_id = KeyId::new(format!("sw-key-{}", id));
506            if !keys.contains_key(&key_id) {
507                return key_id;
508            }
509            id += 1;
510        }
511    }
512}
513
514impl SigningProvider for SoftwareProvider {
515    fn name(&self) -> &str {
516        "Software"
517    }
518
519    fn is_available(&self) -> bool {
520        true
521    }
522
523    #[allow(clippy::redundant_closure_call)]
524    fn generate_key(&self, label: &str) -> HsmResult<KeyId> {
525        let result: HsmResult<KeyId> = (|| {
526            let key_pair = KeyPair::generate();
527            let key_id = self.next_key_id();
528            let metadata =
529                KeyMetadata::new(key_id.clone(), label).with_exportable(self.allow_export);
530
531            let mut keys = self.keys.write().unwrap();
532            keys.insert(key_id.clone(), (key_pair, metadata));
533            Ok(key_id.clone())
534        })();
535
536        // Log audit event
537        let entry = match &result {
538            Ok(key_id) => AuditEntry::new(AuditEventType::KeyGenerated, self.name())
539                .with_key_id(key_id.to_string())
540                .with_metadata("label", label),
541            Err(e) => {
542                AuditEntry::new(AuditEventType::KeyGenerated, self.name()).with_error(e.to_string())
543            }
544        };
545        self.log_audit(entry);
546
547        result
548    }
549
550    fn import_key(&self, label: &str, secret_key: &SecretKey) -> HsmResult<KeyId> {
551        let result: HsmResult<KeyId> = (|| {
552            let key_pair = KeyPair::from_secret_key(secret_key)?;
553            let key_id = self.next_key_id();
554            let metadata =
555                KeyMetadata::new(key_id.clone(), label).with_exportable(self.allow_export);
556
557            let mut keys = self.keys.write().unwrap();
558            keys.insert(key_id.clone(), (key_pair, metadata));
559            Ok(key_id.clone())
560        })();
561
562        // Log audit event
563        let entry = match &result {
564            Ok(key_id) => AuditEntry::new(AuditEventType::KeyImported, self.name())
565                .with_key_id(key_id.to_string())
566                .with_metadata("label", label),
567            Err(e) => {
568                AuditEntry::new(AuditEventType::KeyImported, self.name()).with_error(e.to_string())
569            }
570        };
571        self.log_audit(entry);
572
573        result
574    }
575
576    fn get_public_key(&self, key_id: &KeyId) -> HsmResult<PublicKey> {
577        let keys = self.keys.read().unwrap();
578        let (key_pair, _) = keys
579            .get(key_id)
580            .ok_or_else(|| HsmError::KeyNotFound(key_id.to_string()))?;
581        Ok(key_pair.public_key())
582    }
583
584    fn sign(&self, key_id: &KeyId, message: &[u8]) -> HsmResult<SignatureBytes> {
585        let result = (|| {
586            let mut keys = self.keys.write().unwrap();
587            let (key_pair, metadata) = keys
588                .get_mut(key_id)
589                .ok_or_else(|| HsmError::KeyNotFound(key_id.to_string()))?;
590
591            // Check if key is usable
592            if !metadata.is_usable() {
593                return Err(HsmError::UnsupportedOperation(format!(
594                    "Key {} is in state '{}' and cannot be used for signing",
595                    key_id, metadata.state
596                )));
597            }
598
599            // Record usage
600            metadata.record_usage();
601
602            Ok(key_pair.sign(message))
603        })();
604
605        // Log audit event
606        let entry = match &result {
607            Ok(_) => AuditEntry::new(AuditEventType::SignOperation, self.name())
608                .with_key_id(key_id.to_string())
609                .with_metadata("message_len", message.len().to_string()),
610            Err(e) => AuditEntry::new(AuditEventType::SignOperation, self.name())
611                .with_key_id(key_id.to_string())
612                .with_error(e.to_string()),
613        };
614        self.log_audit(entry);
615
616        result
617    }
618
619    fn list_keys(&self) -> HsmResult<Vec<KeyMetadata>> {
620        let keys = self.keys.read().unwrap();
621        Ok(keys.values().map(|(_, meta)| meta.clone()).collect())
622    }
623
624    fn delete_key(&self, key_id: &KeyId) -> HsmResult<()> {
625        let result: HsmResult<()> = (|| {
626            let mut keys = self.keys.write().unwrap();
627            keys.remove(key_id)
628                .ok_or_else(|| HsmError::KeyNotFound(key_id.to_string()))?;
629            Ok(())
630        })();
631
632        // Log audit event
633        let entry = match &result {
634            Ok(_) => AuditEntry::new(AuditEventType::KeyDeleted, self.name())
635                .with_key_id(key_id.to_string()),
636            Err(e) => AuditEntry::new(AuditEventType::KeyDeleted, self.name())
637                .with_key_id(key_id.to_string())
638                .with_error(e.to_string()),
639        };
640        self.log_audit(entry);
641
642        result
643    }
644
645    fn key_exists(&self, key_id: &KeyId) -> bool {
646        let keys = self.keys.read().unwrap();
647        keys.contains_key(key_id)
648    }
649
650    fn export_key(&self, key_id: &KeyId) -> HsmResult<SecretKey> {
651        let result = (|| {
652            let keys = self.keys.read().unwrap();
653            let (key_pair, metadata) = keys
654                .get(key_id)
655                .ok_or_else(|| HsmError::KeyNotFound(key_id.to_string()))?;
656
657            if !metadata.exportable {
658                return Err(HsmError::UnsupportedOperation(
659                    "Key is not exportable".to_string(),
660                ));
661            }
662
663            Ok(key_pair.secret_key())
664        })();
665
666        // Log audit event
667        let entry = match &result {
668            Ok(_) => AuditEntry::new(AuditEventType::KeyExported, self.name())
669                .with_key_id(key_id.to_string()),
670            Err(e) => AuditEntry::new(AuditEventType::KeyExported, self.name())
671                .with_key_id(key_id.to_string())
672                .with_error(e.to_string()),
673        };
674        self.log_audit(entry);
675
676        result
677    }
678
679    // Phase 17A enhanced methods:
680
681    fn update_key_state(&self, key_id: &KeyId, state: KeyLifecycleState) -> HsmResult<()> {
682        let result: HsmResult<KeyLifecycleState> = (|| {
683            let mut keys = self.keys.write().unwrap();
684            let (_, metadata) = keys
685                .get_mut(key_id)
686                .ok_or_else(|| HsmError::KeyNotFound(key_id.to_string()))?;
687
688            let old_state = metadata.state;
689            metadata.state = state;
690            Ok(old_state)
691        })();
692
693        // Log audit event
694        let entry = match &result {
695            Ok(old_state) => AuditEntry::new(AuditEventType::KeyStateChanged, self.name())
696                .with_key_id(key_id.to_string())
697                .with_metadata("old_state", old_state.to_string())
698                .with_metadata("new_state", state.to_string()),
699            Err(e) => AuditEntry::new(AuditEventType::KeyStateChanged, self.name())
700                .with_key_id(key_id.to_string())
701                .with_error(e.to_string()),
702        };
703        self.log_audit(entry);
704
705        result.map(|_| ())
706    }
707
708    fn get_audit_log(&self, limit: usize) -> HsmResult<Vec<AuditEntry>> {
709        let log = self.audit_log.read().unwrap();
710        let len = log.len();
711        let start = len.saturating_sub(limit);
712        Ok(log[start..].to_vec())
713    }
714}
715
716/// Configuration for PKCS#11 HSM provider.
717#[derive(Debug, Clone)]
718pub struct Pkcs11Config {
719    /// Path to the PKCS#11 library (.so/.dll).
720    pub library_path: String,
721    /// Slot ID to use.
722    pub slot_id: u64,
723    /// PIN for authentication.
724    pub pin: String,
725    /// Token label filter (optional).
726    pub token_label: Option<String>,
727}
728
729impl Pkcs11Config {
730    /// Create new PKCS#11 configuration.
731    pub fn new(library_path: impl Into<String>, slot_id: u64, pin: impl Into<String>) -> Self {
732        Self {
733            library_path: library_path.into(),
734            slot_id,
735            pin: pin.into(),
736            token_label: None,
737        }
738    }
739
740    /// Set token label filter.
741    pub fn with_token_label(mut self, label: impl Into<String>) -> Self {
742        self.token_label = Some(label.into());
743        self
744    }
745}
746
747/// PKCS#11 HSM provider (stub implementation).
748///
749/// This provides the interface for PKCS#11 HSM integration.
750/// A full implementation would use the `pkcs11` or `cryptoki` crate.
751///
752/// Enterprise users would implement this against their specific HSM:
753/// - SafeNet Luna
754/// - Thales nShield
755/// - AWS CloudHSM
756/// - YubiHSM
757pub struct Pkcs11Provider {
758    config: Pkcs11Config,
759    initialized: bool,
760}
761
762impl Pkcs11Provider {
763    /// Create a new PKCS#11 provider.
764    pub fn new(config: Pkcs11Config) -> Self {
765        Self {
766            config,
767            initialized: false,
768        }
769    }
770
771    /// Initialize the PKCS#11 session.
772    ///
773    /// In a real implementation, this would:
774    /// 1. Load the PKCS#11 library
775    /// 2. Initialize the library
776    /// 3. Open a session on the specified slot
777    /// 4. Login with the provided PIN
778    pub fn initialize(&mut self) -> HsmResult<()> {
779        // Stub: Verify library path exists
780        if self.config.library_path.is_empty() {
781            return Err(HsmError::ConfigError(
782                "PKCS#11 library path is empty".to_string(),
783            ));
784        }
785
786        // In real implementation:
787        // let ctx = Pkcs11::new(&self.config.library_path)?;
788        // ctx.initialize(CInitializeArgs::OsThreads)?;
789        // let session = ctx.open_rw_session(self.config.slot_id)?;
790        // session.login(UserType::User, Some(&self.config.pin))?;
791
792        self.initialized = true;
793        Ok(())
794    }
795
796    /// Close the PKCS#11 session.
797    pub fn finalize(&mut self) -> HsmResult<()> {
798        self.initialized = false;
799        Ok(())
800    }
801}
802
803impl SigningProvider for Pkcs11Provider {
804    fn name(&self) -> &str {
805        "PKCS#11 HSM"
806    }
807
808    fn is_available(&self) -> bool {
809        self.initialized
810    }
811
812    fn generate_key(&self, label: &str) -> HsmResult<KeyId> {
813        if !self.initialized {
814            return Err(HsmError::NotInitialized);
815        }
816
817        // In real implementation:
818        // let mechanism = Mechanism::EccKeyPairGen;
819        // let pub_template = vec![
820        //     Attribute::Token(true),
821        //     Attribute::Label(label.to_vec()),
822        //     Attribute::EcParams(ED25519_OID),
823        // ];
824        // let priv_template = vec![
825        //     Attribute::Token(true),
826        //     Attribute::Private(true),
827        //     Attribute::Sensitive(true),
828        //     Attribute::Sign(true),
829        // ];
830        // let (pub_handle, priv_handle) = session.generate_key_pair(&mechanism, &pub_template, &priv_template)?;
831
832        Err(HsmError::Pkcs11Error(format!(
833            "PKCS#11 key generation not implemented for label: {}",
834            label
835        )))
836    }
837
838    fn import_key(&self, label: &str, _secret_key: &SecretKey) -> HsmResult<KeyId> {
839        if !self.initialized {
840            return Err(HsmError::NotInitialized);
841        }
842
843        Err(HsmError::Pkcs11Error(format!(
844            "PKCS#11 key import not implemented for label: {}",
845            label
846        )))
847    }
848
849    fn get_public_key(&self, key_id: &KeyId) -> HsmResult<PublicKey> {
850        if !self.initialized {
851            return Err(HsmError::NotInitialized);
852        }
853
854        Err(HsmError::Pkcs11Error(format!(
855            "PKCS#11 get_public_key not implemented for key: {}",
856            key_id
857        )))
858    }
859
860    fn sign(&self, key_id: &KeyId, _message: &[u8]) -> HsmResult<SignatureBytes> {
861        if !self.initialized {
862            return Err(HsmError::NotInitialized);
863        }
864
865        // In real implementation:
866        // let mechanism = Mechanism::Eddsa;
867        // let signature = session.sign(&mechanism, priv_handle, message)?;
868
869        Err(HsmError::Pkcs11Error(format!(
870            "PKCS#11 signing not implemented for key: {}",
871            key_id
872        )))
873    }
874
875    fn list_keys(&self) -> HsmResult<Vec<KeyMetadata>> {
876        if !self.initialized {
877            return Err(HsmError::NotInitialized);
878        }
879
880        Ok(Vec::new())
881    }
882
883    fn delete_key(&self, key_id: &KeyId) -> HsmResult<()> {
884        if !self.initialized {
885            return Err(HsmError::NotInitialized);
886        }
887
888        Err(HsmError::Pkcs11Error(format!(
889            "PKCS#11 key deletion not implemented for key: {}",
890            key_id
891        )))
892    }
893
894    fn key_exists(&self, _key_id: &KeyId) -> bool {
895        false
896    }
897}
898
899/// Configuration for TPM 2.0 provider.
900#[derive(Debug, Clone)]
901pub struct TpmConfig {
902    /// TCTI (TPM Command Transmission Interface) connection string.
903    /// Examples: "device:/dev/tpm0", "mssim:host=localhost,port=2321"
904    pub tcti: String,
905    /// Owner authorization value.
906    pub owner_auth: Option<String>,
907    /// Hierarchy to use (owner, endorsement, platform).
908    pub hierarchy: TpmHierarchy,
909}
910
911/// TPM hierarchy for key storage.
912#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
913pub enum TpmHierarchy {
914    /// Owner hierarchy (default for user keys).
915    #[default]
916    Owner,
917    /// Endorsement hierarchy (for attestation).
918    Endorsement,
919    /// Platform hierarchy (for platform keys).
920    Platform,
921}
922
923impl TpmConfig {
924    /// Create new TPM configuration for a device.
925    pub fn device(path: impl Into<String>) -> Self {
926        Self {
927            tcti: format!("device:{}", path.into()),
928            owner_auth: None,
929            hierarchy: TpmHierarchy::Owner,
930        }
931    }
932
933    /// Create new TPM configuration for TPM simulator.
934    pub fn simulator(host: &str, port: u16) -> Self {
935        Self {
936            tcti: format!("mssim:host={},port={}", host, port),
937            owner_auth: None,
938            hierarchy: TpmHierarchy::Owner,
939        }
940    }
941
942    /// Set owner authorization.
943    pub fn with_owner_auth(mut self, auth: impl Into<String>) -> Self {
944        self.owner_auth = Some(auth.into());
945        self
946    }
947
948    /// Set hierarchy.
949    pub fn with_hierarchy(mut self, hierarchy: TpmHierarchy) -> Self {
950        self.hierarchy = hierarchy;
951        self
952    }
953}
954
955/// TPM 2.0 provider (stub implementation).
956///
957/// This provides the interface for TPM 2.0 integration.
958/// A full implementation would use the `tss-esapi` crate.
959///
960/// TPM benefits:
961/// - Hardware-bound keys (non-extractable)
962/// - Platform attestation
963/// - Secure boot integration
964/// - Available on most modern systems
965pub struct TpmProvider {
966    config: TpmConfig,
967    initialized: bool,
968}
969
970impl TpmProvider {
971    /// Create a new TPM provider.
972    pub fn new(config: TpmConfig) -> Self {
973        Self {
974            config,
975            initialized: false,
976        }
977    }
978
979    /// Initialize the TPM session.
980    ///
981    /// In a real implementation, this would:
982    /// 1. Connect to the TPM via TCTI
983    /// 2. Create an ESYS context
984    /// 3. Start an authorization session
985    pub fn initialize(&mut self) -> HsmResult<()> {
986        // Stub: Verify TCTI string
987        if self.config.tcti.is_empty() {
988            return Err(HsmError::ConfigError("TPM TCTI is empty".to_string()));
989        }
990
991        // In real implementation:
992        // let tcti = TctiNameConf::from_str(&self.config.tcti)?;
993        // let context = Context::new(tcti)?;
994
995        self.initialized = true;
996        Ok(())
997    }
998
999    /// Close the TPM session.
1000    pub fn finalize(&mut self) -> HsmResult<()> {
1001        self.initialized = false;
1002        Ok(())
1003    }
1004}
1005
1006impl SigningProvider for TpmProvider {
1007    fn name(&self) -> &str {
1008        "TPM 2.0"
1009    }
1010
1011    fn is_available(&self) -> bool {
1012        self.initialized
1013    }
1014
1015    fn generate_key(&self, label: &str) -> HsmResult<KeyId> {
1016        if !self.initialized {
1017            return Err(HsmError::NotInitialized);
1018        }
1019
1020        // TPM doesn't natively support Ed25519, would need to use ECDSA
1021        // or implement Ed25519 in software with TPM-protected seed
1022
1023        // In real implementation with ECDSA:
1024        // let primary = context.create_primary(
1025        //     Hierarchy::Owner,
1026        //     PublicBuilder::new()
1027        //         .with_ecc_parameters(EccParameters::new(...))
1028        //         .build()?,
1029        // )?;
1030
1031        Err(HsmError::TpmError(format!(
1032            "TPM key generation not implemented for label: {}",
1033            label
1034        )))
1035    }
1036
1037    fn import_key(&self, label: &str, _secret_key: &SecretKey) -> HsmResult<KeyId> {
1038        if !self.initialized {
1039            return Err(HsmError::NotInitialized);
1040        }
1041
1042        Err(HsmError::TpmError(format!(
1043            "TPM key import not implemented for label: {}",
1044            label
1045        )))
1046    }
1047
1048    fn get_public_key(&self, key_id: &KeyId) -> HsmResult<PublicKey> {
1049        if !self.initialized {
1050            return Err(HsmError::NotInitialized);
1051        }
1052
1053        Err(HsmError::TpmError(format!(
1054            "TPM get_public_key not implemented for key: {}",
1055            key_id
1056        )))
1057    }
1058
1059    fn sign(&self, key_id: &KeyId, _message: &[u8]) -> HsmResult<SignatureBytes> {
1060        if !self.initialized {
1061            return Err(HsmError::NotInitialized);
1062        }
1063
1064        // In real implementation:
1065        // let signature = context.sign(
1066        //     key_handle,
1067        //     Digest::try_from(message)?,
1068        //     SignatureScheme::EcDsa,
1069        // )?;
1070
1071        Err(HsmError::TpmError(format!(
1072            "TPM signing not implemented for key: {}",
1073            key_id
1074        )))
1075    }
1076
1077    fn list_keys(&self) -> HsmResult<Vec<KeyMetadata>> {
1078        if !self.initialized {
1079            return Err(HsmError::NotInitialized);
1080        }
1081
1082        Ok(Vec::new())
1083    }
1084
1085    fn delete_key(&self, key_id: &KeyId) -> HsmResult<()> {
1086        if !self.initialized {
1087            return Err(HsmError::NotInitialized);
1088        }
1089
1090        Err(HsmError::TpmError(format!(
1091            "TPM key deletion not implemented for key: {}",
1092            key_id
1093        )))
1094    }
1095
1096    fn key_exists(&self, _key_id: &KeyId) -> bool {
1097        false
1098    }
1099}
1100
1101/// HSM manager that provides a unified interface to multiple backends.
1102///
1103/// This allows applications to:
1104/// - Configure multiple HSM backends
1105/// - Fall back from HSM to software keys
1106/// - Abstract over the specific HSM implementation
1107pub struct HsmManager {
1108    providers: RwLock<Vec<Arc<dyn SigningProvider>>>,
1109    default_provider: usize,
1110}
1111
1112impl Default for HsmManager {
1113    fn default() -> Self {
1114        Self::new()
1115    }
1116}
1117
1118impl HsmManager {
1119    /// Create a new HSM manager with software provider as default.
1120    pub fn new() -> Self {
1121        let software = Arc::new(SoftwareProvider::new()) as Arc<dyn SigningProvider>;
1122        Self {
1123            providers: RwLock::new(vec![software]),
1124            default_provider: 0,
1125        }
1126    }
1127
1128    /// Add a signing provider.
1129    pub fn add_provider(&self, provider: Arc<dyn SigningProvider>) -> usize {
1130        let mut providers = self.providers.write().unwrap();
1131        let index = providers.len();
1132        providers.push(provider);
1133        index
1134    }
1135
1136    /// Set the default provider by index.
1137    pub fn set_default_provider(&mut self, index: usize) -> HsmResult<()> {
1138        let providers = self.providers.read().unwrap();
1139        if index >= providers.len() {
1140            return Err(HsmError::ConfigError(format!(
1141                "Invalid provider index: {}",
1142                index
1143            )));
1144        }
1145        drop(providers);
1146        self.default_provider = index;
1147        Ok(())
1148    }
1149
1150    /// Get the default provider.
1151    pub fn default_provider(&self) -> Arc<dyn SigningProvider> {
1152        let providers = self.providers.read().unwrap();
1153        providers[self.default_provider].clone()
1154    }
1155
1156    /// Get a provider by index.
1157    pub fn provider(&self, index: usize) -> Option<Arc<dyn SigningProvider>> {
1158        let providers = self.providers.read().unwrap();
1159        providers.get(index).cloned()
1160    }
1161
1162    /// List all providers.
1163    pub fn list_providers(&self) -> Vec<String> {
1164        let providers = self.providers.read().unwrap();
1165        providers.iter().map(|p| p.name().to_string()).collect()
1166    }
1167
1168    /// Generate a key using the default provider.
1169    pub fn generate_key(&self, label: &str) -> HsmResult<KeyId> {
1170        self.default_provider().generate_key(label)
1171    }
1172
1173    /// Import a key using the default provider.
1174    pub fn import_key(&self, label: &str, secret_key: &SecretKey) -> HsmResult<KeyId> {
1175        self.default_provider().import_key(label, secret_key)
1176    }
1177
1178    /// Sign using the default provider.
1179    pub fn sign(&self, key_id: &KeyId, message: &[u8]) -> HsmResult<SignatureBytes> {
1180        self.default_provider().sign(key_id, message)
1181    }
1182
1183    /// Get public key using the default provider.
1184    pub fn get_public_key(&self, key_id: &KeyId) -> HsmResult<PublicKey> {
1185        self.default_provider().get_public_key(key_id)
1186    }
1187
1188    /// Verify a signature (delegates to software verification).
1189    pub fn verify(
1190        &self,
1191        public_key: &PublicKey,
1192        message: &[u8],
1193        signature: &SignatureBytes,
1194    ) -> HsmResult<()> {
1195        self.default_provider()
1196            .verify(public_key, message, signature)
1197    }
1198}
1199
1200/// Builder for configuring HSM providers.
1201pub struct HsmManagerBuilder {
1202    providers: Vec<Arc<dyn SigningProvider>>,
1203    default_index: usize,
1204}
1205
1206impl Default for HsmManagerBuilder {
1207    fn default() -> Self {
1208        Self::new()
1209    }
1210}
1211
1212impl HsmManagerBuilder {
1213    /// Create a new builder.
1214    pub fn new() -> Self {
1215        Self {
1216            providers: Vec::new(),
1217            default_index: 0,
1218        }
1219    }
1220
1221    /// Add the software provider.
1222    pub fn with_software(mut self) -> Self {
1223        let provider = Arc::new(SoftwareProvider::new()) as Arc<dyn SigningProvider>;
1224        self.providers.push(provider);
1225        self
1226    }
1227
1228    /// Add a PKCS#11 provider.
1229    pub fn with_pkcs11(mut self, config: Pkcs11Config) -> Self {
1230        let provider = Arc::new(Pkcs11Provider::new(config)) as Arc<dyn SigningProvider>;
1231        self.providers.push(provider);
1232        self
1233    }
1234
1235    /// Add a TPM provider.
1236    pub fn with_tpm(mut self, config: TpmConfig) -> Self {
1237        let provider = Arc::new(TpmProvider::new(config)) as Arc<dyn SigningProvider>;
1238        self.providers.push(provider);
1239        self
1240    }
1241
1242    /// Set the default provider index.
1243    pub fn with_default(mut self, index: usize) -> Self {
1244        self.default_index = index;
1245        self
1246    }
1247
1248    /// Build the HSM manager.
1249    pub fn build(self) -> HsmResult<HsmManager> {
1250        if self.providers.is_empty() {
1251            return Err(HsmError::ConfigError("No providers configured".to_string()));
1252        }
1253
1254        if self.default_index >= self.providers.len() {
1255            return Err(HsmError::ConfigError(format!(
1256                "Invalid default index: {}",
1257                self.default_index
1258            )));
1259        }
1260
1261        Ok(HsmManager {
1262            providers: RwLock::new(self.providers),
1263            default_provider: self.default_index,
1264        })
1265    }
1266}
1267
1268#[cfg(test)]
1269mod tests {
1270    use super::*;
1271
1272    #[test]
1273    fn test_software_provider_lifecycle() {
1274        let provider = SoftwareProvider::new();
1275
1276        // Generate key
1277        let key_id = provider.generate_key("test-key").unwrap();
1278        assert!(provider.key_exists(&key_id));
1279
1280        // Get public key
1281        let public_key = provider.get_public_key(&key_id).unwrap();
1282        assert_eq!(public_key.len(), 32);
1283
1284        // Sign and verify
1285        let message = b"Hello, HSM!";
1286        let signature = provider.sign(&key_id, message).unwrap();
1287        provider.verify(&public_key, message, &signature).unwrap();
1288
1289        // List keys
1290        let keys = provider.list_keys().unwrap();
1291        assert_eq!(keys.len(), 1);
1292        assert_eq!(keys[0].label, "test-key");
1293
1294        // Export key
1295        let secret = provider.export_key(&key_id).unwrap();
1296        assert_eq!(secret.len(), 32);
1297
1298        // Delete key
1299        provider.delete_key(&key_id).unwrap();
1300        assert!(!provider.key_exists(&key_id));
1301    }
1302
1303    #[test]
1304    fn test_software_provider_import() {
1305        let provider = SoftwareProvider::new();
1306
1307        // Generate a key pair
1308        let original = KeyPair::generate();
1309        let secret = original.secret_key();
1310        let public = original.public_key();
1311
1312        // Import into provider
1313        let key_id = provider.import_key("imported", &secret).unwrap();
1314
1315        // Verify public key matches
1316        let imported_public = provider.get_public_key(&key_id).unwrap();
1317        assert_eq!(public, imported_public);
1318
1319        // Sign with imported key
1320        let message = b"Test message";
1321        let signature = provider.sign(&key_id, message).unwrap();
1322
1323        // Verify signature
1324        provider.verify(&public, message, &signature).unwrap();
1325    }
1326
1327    #[test]
1328    fn test_non_exportable_keys() {
1329        let provider = SoftwareProvider::new_non_exportable();
1330
1331        let key_id = provider.generate_key("secure-key").unwrap();
1332
1333        // Export should fail
1334        let result = provider.export_key(&key_id);
1335        assert!(result.is_err());
1336        assert!(matches!(
1337            result.unwrap_err(),
1338            HsmError::UnsupportedOperation(_)
1339        ));
1340    }
1341
1342    #[test]
1343    fn test_hsm_manager() {
1344        let manager = HsmManager::new();
1345
1346        // Generate and use key
1347        let key_id = manager.generate_key("manager-key").unwrap();
1348        let public_key = manager.get_public_key(&key_id).unwrap();
1349
1350        let message = b"Manager test";
1351        let signature = manager.sign(&key_id, message).unwrap();
1352
1353        manager.verify(&public_key, message, &signature).unwrap();
1354    }
1355
1356    #[test]
1357    fn test_hsm_manager_builder() {
1358        let manager = HsmManagerBuilder::new()
1359            .with_software()
1360            .with_default(0)
1361            .build()
1362            .unwrap();
1363
1364        let providers = manager.list_providers();
1365        assert_eq!(providers.len(), 1);
1366        assert_eq!(providers[0], "Software");
1367    }
1368
1369    #[test]
1370    fn test_pkcs11_provider_not_initialized() {
1371        let config = Pkcs11Config::new("/path/to/pkcs11.so", 0, "1234");
1372        let provider = Pkcs11Provider::new(config);
1373
1374        // Operations should fail when not initialized
1375        let result = provider.generate_key("test");
1376        assert!(matches!(result.unwrap_err(), HsmError::NotInitialized));
1377    }
1378
1379    #[test]
1380    fn test_tpm_provider_not_initialized() {
1381        let config = TpmConfig::device("/dev/tpm0");
1382        let provider = TpmProvider::new(config);
1383
1384        // Operations should fail when not initialized
1385        let result = provider.generate_key("test");
1386        assert!(matches!(result.unwrap_err(), HsmError::NotInitialized));
1387    }
1388
1389    #[test]
1390    fn test_key_metadata() {
1391        let key_id = KeyId::new("test-123");
1392        let metadata = KeyMetadata::new(key_id.clone(), "My Key")
1393            .with_exportable(true)
1394            .with_attribute("purpose", "signing");
1395
1396        assert_eq!(metadata.id, key_id);
1397        assert_eq!(metadata.label, "My Key");
1398        assert!(metadata.exportable);
1399        assert_eq!(
1400            metadata.attributes.get("purpose"),
1401            Some(&"signing".to_string())
1402        );
1403    }
1404
1405    // Phase 17A enhancement tests:
1406
1407    #[test]
1408    fn test_key_lifecycle_states() {
1409        let provider = SoftwareProvider::new();
1410        let key_id = provider.generate_key("test-key").unwrap();
1411
1412        // Initially active
1413        let metadata = provider.get_key_metadata(&key_id).unwrap();
1414        assert_eq!(metadata.state, KeyLifecycleState::Active);
1415        assert!(metadata.is_usable());
1416
1417        // Archive the key
1418        provider
1419            .update_key_state(&key_id, KeyLifecycleState::Archived)
1420            .unwrap();
1421        let metadata = provider.get_key_metadata(&key_id).unwrap();
1422        assert_eq!(metadata.state, KeyLifecycleState::Archived);
1423        assert!(!metadata.is_usable());
1424
1425        // Revoke the key
1426        provider
1427            .update_key_state(&key_id, KeyLifecycleState::Revoked)
1428            .unwrap();
1429        let metadata = provider.get_key_metadata(&key_id).unwrap();
1430        assert_eq!(metadata.state, KeyLifecycleState::Revoked);
1431        assert!(!metadata.is_usable());
1432    }
1433
1434    #[test]
1435    fn test_revoked_key_cannot_sign() {
1436        let provider = SoftwareProvider::new();
1437        let key_id = provider.generate_key("test-key").unwrap();
1438
1439        // Can sign when active
1440        let message = b"test message";
1441        provider.sign(&key_id, message).unwrap();
1442
1443        // Revoke the key
1444        provider
1445            .update_key_state(&key_id, KeyLifecycleState::Revoked)
1446            .unwrap();
1447
1448        // Cannot sign when revoked
1449        let result = provider.sign(&key_id, message);
1450        assert!(result.is_err());
1451    }
1452
1453    #[test]
1454    fn test_key_usage_tracking() {
1455        let provider = SoftwareProvider::new();
1456        let key_id = provider.generate_key("test-key").unwrap();
1457
1458        let metadata = provider.get_key_metadata(&key_id).unwrap();
1459        assert_eq!(metadata.operation_count, 0);
1460        assert!(metadata.last_used.is_none());
1461
1462        // Sign some messages
1463        for i in 0..5 {
1464            provider.sign(&key_id, &[i]).unwrap();
1465        }
1466
1467        let metadata = provider.get_key_metadata(&key_id).unwrap();
1468        assert_eq!(metadata.operation_count, 5);
1469        assert!(metadata.last_used.is_some());
1470    }
1471
1472    #[test]
1473    fn test_audit_logging() {
1474        let provider = SoftwareProvider::new();
1475
1476        // Generate key
1477        let key_id = provider.generate_key("test-key").unwrap();
1478
1479        // Sign message
1480        provider.sign(&key_id, b"test").unwrap();
1481
1482        // Delete key
1483        provider.delete_key(&key_id).unwrap();
1484
1485        // Check audit log
1486        let log = provider.get_audit_log(10).unwrap();
1487        assert_eq!(log.len(), 3);
1488
1489        assert!(matches!(log[0].event_type, AuditEventType::KeyGenerated));
1490        assert!(log[0].success);
1491
1492        assert!(matches!(log[1].event_type, AuditEventType::SignOperation));
1493        assert!(log[1].success);
1494
1495        assert!(matches!(log[2].event_type, AuditEventType::KeyDeleted));
1496        assert!(log[2].success);
1497    }
1498
1499    #[test]
1500    fn test_audit_log_limit() {
1501        let provider = SoftwareProvider::new();
1502
1503        // Generate 20 keys
1504        for i in 0..20 {
1505            provider.generate_key(&format!("key-{}", i)).unwrap();
1506        }
1507
1508        // Request last 5 entries
1509        let log = provider.get_audit_log(5).unwrap();
1510        assert_eq!(log.len(), 5);
1511
1512        // All should be key generation events
1513        for entry in &log {
1514            assert!(matches!(entry.event_type, AuditEventType::KeyGenerated));
1515        }
1516    }
1517
1518    #[test]
1519    fn test_health_check() {
1520        let provider = SoftwareProvider::new();
1521        let health = provider.health_check().unwrap();
1522
1523        assert!(health.healthy);
1524        assert_eq!(health.provider, "Software");
1525        assert!(health.response_time_ms < 1000); // Should be very fast
1526    }
1527
1528    #[test]
1529    fn test_batch_signing() {
1530        let provider = SoftwareProvider::new();
1531        let key_id = provider.generate_key("batch-key").unwrap();
1532
1533        let messages: Vec<&[u8]> = vec![b"msg1", b"msg2", b"msg3", b"msg4", b"msg5"];
1534
1535        let signatures = provider.batch_sign(&key_id, &messages).unwrap();
1536        assert_eq!(signatures.len(), messages.len());
1537
1538        // Verify each signature
1539        let public_key = provider.get_public_key(&key_id).unwrap();
1540        for (i, sig) in signatures.iter().enumerate() {
1541            provider.verify(&public_key, messages[i], sig).unwrap();
1542        }
1543    }
1544
1545    #[test]
1546    fn test_key_rotation() {
1547        let provider = SoftwareProvider::new();
1548        let old_key_id = provider.generate_key("old-key").unwrap();
1549
1550        // Rotate the key
1551        let new_key_id = provider.rotate_key(&old_key_id, "new-key").unwrap();
1552
1553        // Old key should be archived
1554        let old_metadata = provider.get_key_metadata(&old_key_id).unwrap();
1555        assert_eq!(old_metadata.state, KeyLifecycleState::Archived);
1556
1557        // New key should be active
1558        let new_metadata = provider.get_key_metadata(&new_key_id).unwrap();
1559        assert_eq!(new_metadata.state, KeyLifecycleState::Active);
1560        assert!(new_metadata.is_usable());
1561
1562        // Should be able to sign with new key
1563        provider.sign(&new_key_id, b"test").unwrap();
1564
1565        // Should not be able to sign with old key
1566        let result = provider.sign(&old_key_id, b"test");
1567        assert!(result.is_err());
1568    }
1569
1570    #[test]
1571    fn test_key_versioning() {
1572        let provider = SoftwareProvider::new();
1573        let key_id = provider.generate_key("versioned-key").unwrap();
1574
1575        let metadata = provider.get_key_metadata(&key_id).unwrap();
1576        assert_eq!(metadata.version, 1);
1577        assert!(metadata.last_rotated.is_none());
1578
1579        // Manually mark as rotated (simulate rotation)
1580        let mut keys = provider.keys.write().unwrap();
1581        let (_, meta) = keys.get_mut(&key_id).unwrap();
1582        meta.mark_rotated();
1583        drop(keys);
1584
1585        let metadata = provider.get_key_metadata(&key_id).unwrap();
1586        assert_eq!(metadata.version, 2);
1587        assert!(metadata.last_rotated.is_some());
1588    }
1589
1590    #[test]
1591    fn test_lifecycle_state_display() {
1592        assert_eq!(KeyLifecycleState::Active.to_string(), "active");
1593        assert_eq!(KeyLifecycleState::Archived.to_string(), "archived");
1594        assert_eq!(KeyLifecycleState::Compromised.to_string(), "compromised");
1595        assert_eq!(KeyLifecycleState::Revoked.to_string(), "revoked");
1596        assert_eq!(KeyLifecycleState::Pending.to_string(), "pending");
1597    }
1598
1599    #[test]
1600    fn test_audit_entry_builder() {
1601        let entry = AuditEntry::new(AuditEventType::KeyGenerated, "TestProvider")
1602            .with_key_id("test-key-123")
1603            .with_metadata("label", "test-label")
1604            .with_metadata("algorithm", "Ed25519");
1605
1606        assert!(matches!(entry.event_type, AuditEventType::KeyGenerated));
1607        assert_eq!(entry.provider, "TestProvider");
1608        assert_eq!(entry.key_id, Some("test-key-123".to_string()));
1609        assert!(entry.success);
1610        assert_eq!(entry.metadata.get("label"), Some(&"test-label".to_string()));
1611    }
1612
1613    #[test]
1614    fn test_health_status_builder() {
1615        let status = HealthStatus::new("TestProvider", true)
1616            .with_response_time(42)
1617            .with_metric("connections", "5")
1618            .with_metric("keys", "10");
1619
1620        assert_eq!(status.provider, "TestProvider");
1621        assert!(status.healthy);
1622        assert_eq!(status.response_time_ms, 42);
1623        assert_eq!(status.metrics.get("connections"), Some(&"5".to_string()));
1624        assert_eq!(status.metrics.get("keys"), Some(&"10".to_string()));
1625    }
1626
1627    #[test]
1628    fn test_failed_operations_audit() {
1629        let provider = SoftwareProvider::new();
1630        let key_id = KeyId::new("nonexistent");
1631
1632        // Try to sign with nonexistent key
1633        let _ = provider.sign(&key_id, b"test");
1634
1635        // Check audit log for failure
1636        let log = provider.get_audit_log(10).unwrap();
1637        assert!(!log.is_empty());
1638
1639        let last_entry = &log[log.len() - 1];
1640        assert!(!last_entry.success);
1641        assert!(last_entry.error.is_some());
1642    }
1643}