|
| 1 | +// Licensed under the Apache-2.0 license |
| 2 | + |
| 3 | +/// Error kind for key management operations. |
| 4 | +/// |
| 5 | +/// This represents a common set of key management operation errors that can occur across |
| 6 | +/// different implementations. The enum is `#[non_exhaustive]` to allow for future |
| 7 | +/// additions without breaking API compatibility. |
| 8 | +/// |
| 9 | +/// Implementations are free to define more specific or additional error types. |
| 10 | +/// However, by providing a mapping to these common errors through the [`Error::kind`] |
| 11 | +/// method, generic code can still react to them appropriately. |
| 12 | +#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] |
| 13 | +#[non_exhaustive] |
| 14 | +pub enum ErrorKind { |
| 15 | + /// The operation is busy and cannot be completed |
| 16 | + /// |
| 17 | + /// This indicates that the hardware or implementation is currently |
| 18 | + /// busy with another operation. The caller should retry later. |
| 19 | + Busy, |
| 20 | + |
| 21 | + /// The specified key was not found |
| 22 | + /// |
| 23 | + /// Returned when attempting to access a key that does not exist |
| 24 | + /// in the storage backend. |
| 25 | + KeyNotFound, |
| 26 | + |
| 27 | + /// Access to the key was denied |
| 28 | + /// |
| 29 | + /// This could indicate insufficient permissions, key usage policy |
| 30 | + /// violations, or other access control restrictions. |
| 31 | + AccessDenied, |
| 32 | + |
| 33 | + /// Invalid key usage specification |
| 34 | + /// |
| 35 | + /// Returned when the specified key usage constraints are invalid |
| 36 | + /// or incompatible with the key or storage backend. |
| 37 | + InvalidUsage, |
| 38 | + |
| 39 | + /// Hardware fault or failure |
| 40 | + /// |
| 41 | + /// Indicates a hardware-level error in secure storage elements, |
| 42 | + /// HSMs, or other hardware-backed key storage. |
| 43 | + HardwareFault, |
| 44 | + |
| 45 | + /// Other implementation-specific error |
| 46 | + /// |
| 47 | + /// Catch-all for errors that don't fit other categories. |
| 48 | + Other, |
| 49 | +} |
| 50 | + |
| 51 | +impl core::fmt::Display for ErrorKind { |
| 52 | + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { |
| 53 | + match self { |
| 54 | + Self::Busy => write!(f, "key storage hardware is busy"), |
| 55 | + Self::KeyNotFound => write!(f, "specified key was not found"), |
| 56 | + Self::AccessDenied => write!(f, "access to key was denied"), |
| 57 | + Self::InvalidUsage => write!(f, "invalid key usage specification"), |
| 58 | + Self::HardwareFault => write!(f, "hardware fault during key operation"), |
| 59 | + Self::Other => write!(f, "key management operation failed"), |
| 60 | + } |
| 61 | + } |
| 62 | +} |
| 63 | +/// Common interface for key management errors. |
| 64 | +/// |
| 65 | +/// This trait provides a standardized way to categorize and handle errors |
| 66 | +/// from different key management implementations. |
| 67 | +pub trait Error: core::fmt::Debug { |
| 68 | + /// Convert error to a generic error kind |
| 69 | + /// |
| 70 | + /// By using this method, errors freely defined by HAL implementations |
| 71 | + /// can be converted to a set of generic errors upon which generic |
| 72 | + /// code can act. |
| 73 | + fn kind(&self) -> ErrorKind; |
| 74 | +} |
| 75 | + |
| 76 | +/// Trait for associating a type with a key management error type. |
| 77 | +/// |
| 78 | +/// This trait is used throughout the key management module to associate operations |
| 79 | +/// with their specific error types while maintaining type safety. |
| 80 | +pub trait ErrorType { |
| 81 | + /// Error type. |
| 82 | + type Error: Error; |
| 83 | +} |
| 84 | + |
| 85 | +/// Configuration and setup operations for key vaults |
| 86 | +/// |
| 87 | +/// This trait provides methods for configuring key vault implementations |
| 88 | +/// with runtime parameters and checking their configuration state. |
| 89 | +pub trait KeyVaultSetup: ErrorType { |
| 90 | + /// Configuration type for the key vault |
| 91 | + /// |
| 92 | + /// This type contains all the runtime parameters needed to configure |
| 93 | + /// the key vault implementation. |
| 94 | + type KeyVaultConfig; |
| 95 | + |
| 96 | + /// Configure the key vault with runtime parameters |
| 97 | + /// |
| 98 | + /// This method applies the provided configuration to the key vault, |
| 99 | + /// setting up any necessary resources, security policies, or hardware |
| 100 | + /// initialization required for operation. |
| 101 | + /// |
| 102 | + /// # Parameters |
| 103 | + /// |
| 104 | + /// - `config`: Configuration parameters specific to this key vault implementation |
| 105 | + /// |
| 106 | + /// # Errors |
| 107 | + /// |
| 108 | + /// - `ErrorKind::InvalidUsage`: Invalid configuration parameters |
| 109 | + /// - `ErrorKind::HardwareFault`: Hardware initialization failed |
| 110 | + /// - `ErrorKind::AccessDenied`: Insufficient permissions for configuration |
| 111 | + /// - `ErrorKind::Busy`: Key vault is currently busy and cannot be reconfigured |
| 112 | + fn configure(&mut self, config: Self::KeyVaultConfig) -> Result<(), Self::Error>; |
| 113 | + |
| 114 | + /// Check if the key vault is properly configured |
| 115 | + /// |
| 116 | + /// Returns `true` if the key vault has been successfully configured |
| 117 | + /// and is ready for key operations, `false` otherwise. |
| 118 | + /// |
| 119 | + /// # Note |
| 120 | + /// |
| 121 | + /// This method is infallible as it only checks internal state. |
| 122 | + /// It does not perform any hardware operations that could fail. |
| 123 | + fn is_configured(&self) -> bool; |
| 124 | +} |
| 125 | + |
| 126 | +/// Core key vault operations |
| 127 | +pub trait KeyStore: ErrorType { |
| 128 | + /// Type representing a key identifier |
| 129 | + type KeyId: Copy + Clone + PartialEq + Eq; |
| 130 | + /// Type representing key usage permissions |
| 131 | + type KeyUsage: Copy + Clone + PartialEq + Eq; |
| 132 | + |
| 133 | + /// Erase a specific key |
| 134 | + fn erase_key(&mut self, id: Self::KeyId) -> Result<(), Self::Error>; |
| 135 | + |
| 136 | + /// Erase all keys that are not locked |
| 137 | + fn erase_all_keys(&mut self) -> Result<(), Self::Error>; |
| 138 | + |
| 139 | + /// Check if a key exists and is valid |
| 140 | + fn key_exists(&self, id: Self::KeyId) -> Result<bool, Self::Error>; |
| 141 | + |
| 142 | + /// Get the usage permissions for a key |
| 143 | + fn get_key_usage(&self, id: Self::KeyId) -> Result<Self::KeyUsage, Self::Error>; |
| 144 | + |
| 145 | + /// Set the usage permissions for a key |
| 146 | + fn set_key_usage(&mut self, id: Self::KeyId, usage: Self::KeyUsage) -> Result<(), Self::Error>; |
| 147 | +} |
| 148 | + |
| 149 | +/// Key locking mechanisms for security |
| 150 | +pub trait KeyLocking: ErrorType { |
| 151 | + /// Type representing a key identifier |
| 152 | + type KeyId: Copy + Clone + PartialEq + Eq; |
| 153 | + |
| 154 | + /// Check if key has write lock |
| 155 | + fn is_write_locked(&self, id: Self::KeyId) -> Result<bool, Self::Error>; |
| 156 | + |
| 157 | + /// Set write lock on key |
| 158 | + fn set_write_lock(&mut self, id: Self::KeyId) -> Result<(), Self::Error>; |
| 159 | + |
| 160 | + /// Clear write lock on key |
| 161 | + fn clear_write_lock(&mut self, id: Self::KeyId) -> Result<(), Self::Error>; |
| 162 | + |
| 163 | + /// Check if key has use lock |
| 164 | + fn is_use_locked(&self, id: Self::KeyId) -> Result<bool, Self::Error>; |
| 165 | + |
| 166 | + /// Set use lock on key |
| 167 | + fn set_use_lock(&mut self, id: Self::KeyId) -> Result<(), Self::Error>; |
| 168 | + |
| 169 | + /// Clear use lock on key |
| 170 | + fn clear_use_lock(&mut self, id: Self::KeyId) -> Result<(), Self::Error>; |
| 171 | +} |
| 172 | + |
| 173 | +/// Key lifecycle management |
| 174 | +/// Complete key lifecycle from creation to retrieval |
| 175 | +pub trait KeyLifecycle: ErrorType { |
| 176 | + /// Type representing a key identifier |
| 177 | + type KeyId: Copy + Clone + PartialEq + Eq; |
| 178 | + |
| 179 | + /// Type representing key data |
| 180 | + type KeyData; |
| 181 | + |
| 182 | + /// Type representing key metadata |
| 183 | + type KeyMetadata; |
| 184 | + |
| 185 | + /// Store a key with metadata |
| 186 | + fn store_key( |
| 187 | + &mut self, |
| 188 | + id: Self::KeyId, |
| 189 | + data: Self::KeyData, |
| 190 | + metadata: Self::KeyMetadata, |
| 191 | + ) -> Result<(), Self::Error>; |
| 192 | + |
| 193 | + /// Retrieve key data (if permitted) |
| 194 | + fn retrieve_key(&self, id: Self::KeyId) -> Result<Self::KeyData, Self::Error>; |
| 195 | + |
| 196 | + /// Get key metadata |
| 197 | + fn get_key_metadata(&self, id: Self::KeyId) -> Result<Self::KeyMetadata, Self::Error>; |
| 198 | + |
| 199 | + /// Update key metadata |
| 200 | + fn update_key_metadata( |
| 201 | + &mut self, |
| 202 | + id: Self::KeyId, |
| 203 | + metadata: Self::KeyMetadata, |
| 204 | + ) -> Result<(), Self::Error>; |
| 205 | +} |
| 206 | + |
| 207 | +/// Blanket trait implementation for types that implement key vsault setup, core operations, and locking |
| 208 | +pub trait KeyVault: KeyVaultSetup + KeyStore + KeyLocking {} |
| 209 | +impl<T> KeyVault for T where T: KeyVaultSetup + KeyStore + KeyLocking {} |
0 commit comments