error.rs (5328B)
1 use crate::backend::RadrootsSecretBackendKind; 2 use alloc::string::String; 3 use core::fmt; 4 5 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 6 pub enum RadrootsHostVaultRequirement { 7 DeviceLocalOnly, 8 UserPresence, 9 HardwareBacked, 10 } 11 12 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 13 pub enum RadrootsSecretVaultError { 14 BackendUnavailable { 15 backend: RadrootsSecretBackendKind, 16 }, 17 FallbackDisallowed { 18 primary: RadrootsSecretBackendKind, 19 fallback: RadrootsSecretBackendKind, 20 }, 21 FallbackUnavailable { 22 primary: RadrootsSecretBackendKind, 23 fallback: RadrootsSecretBackendKind, 24 }, 25 HostVaultPolicyUnsupported { 26 requirement: RadrootsHostVaultRequirement, 27 }, 28 } 29 30 #[derive(Debug, Clone, PartialEq, Eq)] 31 pub enum RadrootsSecretVaultAccessError { 32 Backend(String), 33 } 34 35 impl fmt::Display for RadrootsHostVaultRequirement { 36 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 37 let value = match self { 38 Self::DeviceLocalOnly => "device_local_only", 39 Self::UserPresence => "user_presence", 40 Self::HardwareBacked => "hardware_backed", 41 }; 42 f.write_str(value) 43 } 44 } 45 46 impl fmt::Display for RadrootsSecretVaultAccessError { 47 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 48 match self { 49 Self::Backend(message) => write!(f, "secret vault access error: {message}"), 50 } 51 } 52 } 53 54 impl fmt::Display for RadrootsSecretVaultError { 55 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 56 match self { 57 Self::BackendUnavailable { backend } => { 58 write!(f, "secret backend {backend} is unavailable") 59 } 60 Self::FallbackDisallowed { primary, fallback } => write!( 61 f, 62 "secret backend {primary} may not silently downgrade to {fallback}" 63 ), 64 Self::FallbackUnavailable { primary, fallback } => write!( 65 f, 66 "secret backend {primary} fallback {fallback} is unavailable" 67 ), 68 Self::HostVaultPolicyUnsupported { requirement } => write!( 69 f, 70 "host vault does not satisfy the required {requirement} policy" 71 ), 72 } 73 } 74 } 75 76 impl fmt::Display for RadrootsSecretBackendKind { 77 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 78 let value = match self { 79 Self::HostVault => "host_vault", 80 Self::EncryptedFile => "encrypted_file", 81 Self::ExternalCommand => "external_command", 82 Self::Memory => "memory", 83 }; 84 f.write_str(value) 85 } 86 } 87 88 #[cfg(feature = "std")] 89 impl std::error::Error for RadrootsSecretVaultError {} 90 91 #[cfg(feature = "std")] 92 impl std::error::Error for RadrootsSecretVaultAccessError {} 93 94 #[cfg(test)] 95 mod tests { 96 use super::*; 97 use crate::backend::RadrootsSecretBackendKind; 98 use alloc::string::ToString; 99 100 #[test] 101 fn display_formats_requirements_backend_kinds_and_errors() { 102 assert_eq!( 103 RadrootsHostVaultRequirement::DeviceLocalOnly.to_string(), 104 "device_local_only" 105 ); 106 assert_eq!( 107 RadrootsHostVaultRequirement::UserPresence.to_string(), 108 "user_presence" 109 ); 110 assert_eq!( 111 RadrootsHostVaultRequirement::HardwareBacked.to_string(), 112 "hardware_backed" 113 ); 114 115 assert_eq!( 116 RadrootsSecretBackendKind::HostVault.to_string(), 117 "host_vault" 118 ); 119 assert_eq!( 120 RadrootsSecretBackendKind::EncryptedFile.to_string(), 121 "encrypted_file" 122 ); 123 assert_eq!( 124 RadrootsSecretBackendKind::ExternalCommand.to_string(), 125 "external_command" 126 ); 127 assert_eq!(RadrootsSecretBackendKind::Memory.to_string(), "memory"); 128 129 assert_eq!( 130 RadrootsSecretVaultAccessError::Backend("backend offline".into()).to_string(), 131 "secret vault access error: backend offline" 132 ); 133 assert_eq!( 134 RadrootsSecretVaultError::BackendUnavailable { 135 backend: RadrootsSecretBackendKind::HostVault, 136 } 137 .to_string(), 138 "secret backend host_vault is unavailable" 139 ); 140 assert_eq!( 141 RadrootsSecretVaultError::FallbackDisallowed { 142 primary: RadrootsSecretBackendKind::ExternalCommand, 143 fallback: RadrootsSecretBackendKind::EncryptedFile, 144 } 145 .to_string(), 146 "secret backend external_command may not silently downgrade to encrypted_file" 147 ); 148 assert_eq!( 149 RadrootsSecretVaultError::FallbackUnavailable { 150 primary: RadrootsSecretBackendKind::HostVault, 151 fallback: RadrootsSecretBackendKind::EncryptedFile, 152 } 153 .to_string(), 154 "secret backend host_vault fallback encrypted_file is unavailable" 155 ); 156 assert_eq!( 157 RadrootsSecretVaultError::HostVaultPolicyUnsupported { 158 requirement: RadrootsHostVaultRequirement::HardwareBacked, 159 } 160 .to_string(), 161 "host vault does not satisfy the required hardware_backed policy" 162 ); 163 } 164 }