1use std::sync::PoisonError;
2
3pub type Result<T> = std::result::Result<T, WebauthnCError>;
4
5#[derive(Debug, PartialEq, Eq)]
6pub enum WebauthnCError {
7 Json,
8 Cbor,
9 Unknown,
10 Security,
11 NotSupported,
12 PlatformAuthenticator,
13 Internal,
14 ParseNOMFailure,
15 OpenSSL(String),
16 ApduConstruction,
17 ApduTransmission,
18 InvalidAlgorithm,
19 InvalidAssertion,
20 InvalidRegistration,
21 MessageTooLarge,
22 MessageTooShort,
23 InvalidMessageLength,
25 Cancelled,
26 Ctap(CtapError),
27 PinTooShort,
29 PinTooLong,
31 PinContainsNull,
33 NoSelectedToken,
34 MissingRequiredField,
37 FriendlyNameTooLong,
39 #[cfg(feature = "usb")]
40 HidError(fido_hid_rs::HidError),
41 #[cfg(feature = "nfc")]
42 PcscError(pcsc::Error),
43 NoHidDevices,
46 PoisonedMutex,
48 Checksum,
50 StorageCard,
52 IoError(String),
53 InvalidCableUrl,
54 #[cfg(feature = "cable")]
55 Base10(crate::cable::DecodeError),
56 BluetoothError(String),
57 NoBluetoothAdapter,
58 Closed,
61 WebsocketError(String),
62 NonceOverflow,
64 PermissionDenied,
65 UserVerificationRequired,
69 UnexpectedState,
73 #[cfg(feature = "usb")]
74 U2F(crate::transport::types::U2FError),
75}
76
77#[cfg(feature = "nfc")]
78impl From<pcsc::Error> for WebauthnCError {
79 fn from(e: pcsc::Error) -> Self {
80 Self::PcscError(e)
81 }
82}
83
84#[cfg(feature = "usb")]
85impl From<fido_hid_rs::HidError> for WebauthnCError {
86 fn from(e: fido_hid_rs::HidError) -> Self {
87 Self::HidError(e)
88 }
89}
90
91impl<T> From<PoisonError<T>> for WebauthnCError {
92 fn from(_: PoisonError<T>) -> Self {
93 Self::PoisonedMutex
94 }
95}
96
97#[cfg(feature = "ctap2")]
98impl From<crate::transport::iso7816::Error> for WebauthnCError {
99 fn from(v: crate::transport::iso7816::Error) -> Self {
100 use crate::transport::iso7816::Error::*;
101 match v {
102 ResponseTooShort => WebauthnCError::MessageTooShort,
103 DataTooLong => WebauthnCError::MessageTooLarge,
104 _ => WebauthnCError::Internal,
105 }
106 }
107}
108
109#[cfg(feature = "crypto")]
110impl From<openssl::error::ErrorStack> for WebauthnCError {
111 fn from(v: openssl::error::ErrorStack) -> Self {
112 Self::OpenSSL(v.to_string())
113 }
114}
115
116impl From<std::io::Error> for WebauthnCError {
117 fn from(v: std::io::Error) -> Self {
118 Self::IoError(v.to_string())
119 }
120}
121
122#[cfg(feature = "cable")]
123impl From<crate::cable::DecodeError> for WebauthnCError {
124 fn from(v: crate::cable::DecodeError) -> Self {
125 Self::Base10(v)
126 }
127}
128
129#[cfg(feature = "cable")]
130impl From<tokio_tungstenite::tungstenite::error::Error> for WebauthnCError {
131 fn from(v: tokio_tungstenite::tungstenite::error::Error) -> Self {
132 Self::WebsocketError(v.to_string())
133 }
134}
135
136#[cfg(any(feature = "bluetooth", feature = "cable"))]
137impl From<btleplug::Error> for WebauthnCError {
138 fn from(v: btleplug::Error) -> Self {
139 use btleplug::Error::*;
140 match v {
141 PermissionDenied => WebauthnCError::PermissionDenied,
142 _ => Self::BluetoothError(v.to_string()),
143 }
144 }
145}
146
147#[cfg(feature = "usb")]
148impl From<crate::transport::types::U2FError> for WebauthnCError {
149 fn from(value: crate::transport::types::U2FError) -> Self {
150 Self::U2F(value)
151 }
152}
153
154#[derive(Debug, PartialEq, Eq)]
156pub enum CtapError {
157 Ok,
159 Ctap1InvalidCommand,
161 Ctap1InvalidParameter,
163 Ctap1InvalidLength,
165 Ctap1InvalidSeq,
167 Ctap1Timeout,
169 Ctap1ChannelBusy,
172 Ctap1LockRequired,
174 Ctap1InvalidChannel,
176 Ctap2CborUnexpectedType,
177 Ctap2InvalidCBOR,
178 Ctap2MissingParameter,
179 Ctap2LimitExceeded,
180 Ctap2FingerprintDatabaseFull,
181 Ctap2LargeBlobStorageFull,
182 Ctap2CredentialExcluded,
183 Ctap2Processing,
184 Ctap2InvalidCredential,
185 Ctap2UserActionPending,
186 Ctap2OperationPending,
187 Ctap2NoOperations,
188 Ctap2UnsupportedAlgorithm,
189 Ctap2OperationDenied,
190 Ctap2KeyStoreFull,
191 Ctap2UnsupportedOption,
192 Ctap2InvalidOption,
193 Ctap2KeepAliveCancel,
194 Ctap2NoCredentials,
195 Ctap2UserActionTimeout,
196 Ctap2NotAllowed,
197 Ctap2PinInvalid,
198 Ctap2PinBlocked,
199 Ctap2PinAuthInvalid,
200 Ctap2PinAuthBlocked,
201 Ctap2PinNotSet,
202 Ctap2PUATRequired,
203 Ctap2PinPolicyViolation,
204 Ctap2RequestTooLarge,
205 Ctap2ActionTimeout,
206 Ctap2UserPresenceRequired,
207 Ctap2UserVerificationBlocked,
208 Ctap2IntegrityFailure,
209 Ctap2InvalidSubcommand,
210 Ctap2UserVerificationInvalid,
211 Ctap2UnauthorizedPermission,
212 Ctap1Unspecified,
213 Ctap2LastError,
214 Unknown(u8),
216}
217
218impl CtapError {
219 pub fn is_ok(&self) -> bool {
220 *self == CtapError::Ok
221 }
222}
223
224impl From<u8> for CtapError {
225 fn from(e: u8) -> Self {
226 use CtapError::*;
227 match e {
228 0x00 => Ok,
229 0x01 => Ctap1InvalidCommand,
230 0x02 => Ctap1InvalidParameter,
231 0x03 => Ctap1InvalidLength,
232 0x04 => Ctap1InvalidSeq,
233 0x05 => Ctap1Timeout,
234 0x06 => Ctap1ChannelBusy,
235 0x0a => Ctap1LockRequired,
236 0x0b => Ctap1InvalidChannel,
237 0x11 => Ctap2CborUnexpectedType,
238 0x12 => Ctap2InvalidCBOR,
239 0x14 => Ctap2MissingParameter,
240 0x15 => Ctap2LimitExceeded,
241 0x17 => Ctap2FingerprintDatabaseFull,
242 0x18 => Ctap2LargeBlobStorageFull,
243 0x19 => Ctap2CredentialExcluded,
244 0x21 => Ctap2Processing,
245 0x22 => Ctap2InvalidCredential,
246 0x23 => Ctap2UserActionPending,
247 0x24 => Ctap2OperationPending,
248 0x25 => Ctap2NoOperations,
249 0x26 => Ctap2UnsupportedAlgorithm,
250 0x27 => Ctap2OperationDenied,
251 0x28 => Ctap2KeyStoreFull,
252 0x2b => Ctap2UnsupportedOption,
253 0x2c => Ctap2InvalidOption,
254 0x2d => Ctap2KeepAliveCancel,
255 0x2e => Ctap2NoCredentials,
256 0x2f => Ctap2UserActionTimeout,
257 0x30 => Ctap2NotAllowed,
258 0x31 => Ctap2PinInvalid,
259 0x32 => Ctap2PinBlocked,
260 0x33 => Ctap2PinAuthInvalid,
261 0x34 => Ctap2PinAuthBlocked,
262 0x35 => Ctap2PinNotSet,
263 0x36 => Ctap2PUATRequired,
264 0x37 => Ctap2PinPolicyViolation,
265 0x39 => Ctap2RequestTooLarge,
266 0x3a => Ctap2ActionTimeout,
267 0x3b => Ctap2UserPresenceRequired,
268 0x3c => Ctap2UserVerificationBlocked,
269 0x3d => Ctap2IntegrityFailure,
270 0x3e => Ctap2InvalidSubcommand,
271 0x3f => Ctap2UserVerificationInvalid,
272 0x40 => Ctap2UnauthorizedPermission,
273 0x7f => Ctap1Unspecified,
274 0xdf => Ctap2LastError,
275 e => Unknown(e),
276 }
277 }
278}
279
280impl From<CtapError> for u8 {
281 fn from(e: CtapError) -> Self {
282 use CtapError::*;
283 match e {
284 Ok => 0x00,
285 Ctap1InvalidCommand => 0x01,
286 Ctap1InvalidParameter => 0x02,
287 Ctap1InvalidLength => 0x03,
288 Ctap1InvalidSeq => 0x04,
289 Ctap1Timeout => 0x05,
290 Ctap1ChannelBusy => 0x06,
291 Ctap1LockRequired => 0x0a,
292 Ctap1InvalidChannel => 0x0b,
293 Ctap2CborUnexpectedType => 0x11,
294 Ctap2InvalidCBOR => 0x12,
295 Ctap2MissingParameter => 0x14,
296 Ctap2LimitExceeded => 0x15,
297 Ctap2FingerprintDatabaseFull => 0x17,
298 Ctap2LargeBlobStorageFull => 0x18,
299 Ctap2CredentialExcluded => 0x19,
300 Ctap2Processing => 0x21,
301 Ctap2InvalidCredential => 0x22,
302 Ctap2UserActionPending => 0x23,
303 Ctap2OperationPending => 0x24,
304 Ctap2NoOperations => 0x25,
305 Ctap2UnsupportedAlgorithm => 0x26,
306 Ctap2OperationDenied => 0x27,
307 Ctap2KeyStoreFull => 0x28,
308 Ctap2UnsupportedOption => 0x2b,
309 Ctap2InvalidOption => 0x2c,
310 Ctap2KeepAliveCancel => 0x2d,
311 Ctap2NoCredentials => 0x2e,
312 Ctap2UserActionTimeout => 0x2f,
313 Ctap2NotAllowed => 0x30,
314 Ctap2PinInvalid => 0x31,
315 Ctap2PinBlocked => 0x32,
316 Ctap2PinAuthInvalid => 0x33,
317 Ctap2PinAuthBlocked => 0x34,
318 Ctap2PinNotSet => 0x35,
319 Ctap2PUATRequired => 0x36,
320 Ctap2PinPolicyViolation => 0x37,
321 Ctap2RequestTooLarge => 0x39,
322 Ctap2ActionTimeout => 0x3a,
323 Ctap2UserPresenceRequired => 0x3b,
324 Ctap2UserVerificationBlocked => 0x3c,
325 Ctap2IntegrityFailure => 0x3d,
326 Ctap2InvalidSubcommand => 0x3e,
327 Ctap2UserVerificationInvalid => 0x3f,
328 Ctap2UnauthorizedPermission => 0x40,
329 Ctap1Unspecified => 0x7f,
330 Ctap2LastError => 0xdf,
331 Unknown(e) => e,
332 }
333 }
334}
335
336impl From<CtapError> for WebauthnCError {
337 fn from(e: CtapError) -> Self {
338 Self::Ctap(e)
339 }
340}