• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

namib-project / dcaf-rs / 11935120896

20 Nov 2024 02:11PM UTC coverage: 86.555% (+1.3%) from 85.242%
11935120896

Pull #27

github

web-flow
Merge d2b3d706b into 383248641
Pull Request #27: ci: update grcov to latest stable version

6116 of 7066 relevant lines covered (86.56%)

167.28 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

52.6
/src/error/mod.rs
1
/*
2
 * Copyright (c) 2022, 2024 The NAMIB Project Developers.
3
 * Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4
 * https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5
 * <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6
 * option. This file may not be copied, modified, or distributed
7
 * except according to those terms.
8
 *
9
 * SPDX-License-Identifier: MIT OR Apache-2.0
10
 */
11

12
//! Contains error types used across this crate.
13

14
use alloc::collections::BTreeSet;
15
use alloc::vec::Vec;
16
use core::any::type_name;
17
use core::fmt::{Display, Formatter};
18

19
use ciborium::value::Value;
20
use coset::{
21
    Algorithm, CoseError, CoseKey, CoseRecipient, CoseSignature, KeyOperation, KeyType, Label,
22
};
23
use strum_macros::IntoStaticStr;
24

25
use {alloc::format, alloc::string::String, alloc::string::ToString};
26

27
use crate::token::cose::HeaderParam;
28
use crate::token::cose::{EllipticCurve, KeyParam};
29
use core::{marker::PhantomData, num::TryFromIntError};
30

31
/// Error type used when the parameter of the type `T` couldn't be
32
/// converted into [`expected_type`](WrongSourceTypeError::expected_type) because the received
33
/// type was [`actual_type`](WrongSourceTypeError::actual_type) instead.
34
///
35
/// `T` is the general type taken in the [`TryFrom`] conversion.
36
/// Used for [`TryFrom`] conversions from a general enum type to a specific member type.
37
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
38
pub struct WrongSourceTypeError<T> {
39
    /// The name of the specific type which [`TryFrom`] tried to convert to.
40
    pub expected_type: &'static str,
41
    /// The name of the actual type which [`TryFrom`] received.
42
    pub actual_type: &'static str,
43
    /// The general type taken in the [`TryFrom`] conversion.
44
    pub general_type: PhantomData<T>,
45
}
46

47
impl<T> Display for WrongSourceTypeError<T> {
48
    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
7✔
49
        write!(
7✔
50
            f,
7✔
51
            "the given {} is a {} variant (expected {} variant)",
7✔
52
            type_name::<T>(),
7✔
53
            self.actual_type,
7✔
54
            self.expected_type
7✔
55
        )
7✔
56
    }
7✔
57
}
58

59
impl<T> WrongSourceTypeError<T> {
60
    /// Creates a new instance of the error, taking `T` as the general type from which
61
    /// the conversion was tried and the `expected_type` as the target type which it was tried to
62
    /// convert it into, but failed because it was actually of the type named by `actual_type`.
63
    #[must_use]
64
    pub fn new(expected_type: &'static str, actual_type: &'static str) -> WrongSourceTypeError<T> {
15✔
65
        WrongSourceTypeError {
15✔
66
            expected_type,
15✔
67
            actual_type,
15✔
68
            general_type: PhantomData,
15✔
69
        }
15✔
70
    }
15✔
71
}
72

73
/// Error type used when a given CBOR map can't be converted to a specific type which implements
74
/// the [`ToCborMap`](crate::ToCborMap) trait.
75
///
76
/// **Note: This error type is not expected to be used by library clients!**
77
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
78
pub struct TryFromCborMapError {
79
    /// Error message describing why the conversion failed.
80
    message: String,
81
}
82

83
impl Display for TryFromCborMapError {
84
    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
5✔
85
        write!(f, "{}", self.message)
5✔
86
    }
5✔
87
}
88

89
impl TryFromCborMapError {
90
    /// Creates a new error with the given custom `message`.
91
    #[must_use]
92
    pub(crate) fn from_message<T>(message: T) -> TryFromCborMapError
9✔
93
    where
9✔
94
        T: Into<String>,
9✔
95
    {
9✔
96
        TryFromCborMapError {
9✔
97
            message: message.into(),
9✔
98
        }
9✔
99
    }
9✔
100

101
    /// Creates a new error with a message describing that an unknown field in
102
    /// the CBOR map with the given `key` was encountered.
103
    #[must_use]
104
    pub(crate) fn unknown_field(key: u8) -> TryFromCborMapError {
3✔
105
        TryFromCborMapError {
3✔
106
            message: format!("unknown field with key {key} encountered"),
3✔
107
        }
3✔
108
    }
3✔
109

110
    /// Creates a new error with a message describing that the target type could not be built,
111
    /// either due to a missing field or due to a validation error in the builder.
112
    #[must_use]
113
    pub(crate) fn build_failed<T>(name: &'static str, builder_error: T) -> TryFromCborMapError
4✔
114
    where
4✔
115
        T: Display,
4✔
116
    {
4✔
117
        TryFromCborMapError {
4✔
118
            message: format!("couldn't build {name}: {builder_error}"),
4✔
119
        }
4✔
120
    }
4✔
121
}
122

123
impl From<TryFromIntError> for TryFromCborMapError {
124
    fn from(e: TryFromIntError) -> Self {
×
125
        TryFromCborMapError::from_message(e.to_string())
×
126
    }
×
127
}
128

129
/// Error type used when a CBOR map does not use integers as its key type, but was expected to.
130
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
131
pub struct ValueIsNotIntegerError;
132

133
impl Display for ValueIsNotIntegerError {
134
    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
×
135
        write!(f, "CBOR map key must be an integer")
×
136
    }
×
137
}
138

139
/// Error type used when a [`TextEncodedScope`](crate::common::scope::TextEncodedScope)
140
/// does not conform to the specification given in RFC 6749.
141
#[derive(Debug, PartialEq, Eq, Clone, Hash, IntoStaticStr)]
142
pub enum InvalidTextEncodedScopeError {
143
    /// The scope starts with a separator (i.e. space).
144
    StartsWithSeparator,
145
    /// The scope ends with a separator (i.e. space).
146
    EndsWithSeparator,
147
    /// The scope contains two separators (i.e. spaces).
148
    ConsecutiveSeparators,
149
    /// The scope contains an empty element.
150
    EmptyElement,
151
    /// The scope is empty.
152
    EmptyScope,
153
    /// The scope contains illegal characters (i.e. a backslash (`\\`) or double-quote (`"`)).
154
    IllegalCharacters,
155
    /// The scope is invalid for another reason, which is specified in the message contained here.
156
    Other(&'static str),
157
}
158

159
impl Display for InvalidTextEncodedScopeError {
160
    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
48✔
161
        let message = match self {
48✔
162
            InvalidTextEncodedScopeError::StartsWithSeparator => "must not start with space",
2✔
163
            InvalidTextEncodedScopeError::EndsWithSeparator => "must not end with space",
7✔
164
            InvalidTextEncodedScopeError::ConsecutiveSeparators => {
165
                "must not contain consecutive spaces"
1✔
166
            }
167
            InvalidTextEncodedScopeError::EmptyElement => "must not contain empty elements",
2✔
168
            InvalidTextEncodedScopeError::EmptyScope => "must not be empty",
1✔
169
            InvalidTextEncodedScopeError::IllegalCharacters => {
170
                "must not contain illegal character '\\' or '\"'"
35✔
171
            }
172
            InvalidTextEncodedScopeError::Other(s) => s,
×
173
        };
174
        write!(
48✔
175
            f,
48✔
176
            "text-encoded scope must follow format specified in RFC 6749 ({message})"
48✔
177
        )
48✔
178
    }
48✔
179
}
180

181
/// Error type used when a [`BinaryEncodedScope`](crate::common::scope::BinaryEncodedScope)
182
/// does not conform to the specification given in RFC 6749 and RFC 9200.
183
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
184
pub enum InvalidBinaryEncodedScopeError {
185
    /// Scope starts with a separator, which is contained in the field here.
186
    StartsWithSeparator(u8),
187
    /// Scope ends with a separator, which is contained in the field here.
188
    EndsWithSeparator(u8),
189
    /// Scope contains two consecutive separators, which is contained in the field here.
190
    ConsecutiveSeparators(u8),
191
    /// Scope is empty.
192
    EmptyScope,
193
}
194

195
impl Display for InvalidBinaryEncodedScopeError {
196
    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
16✔
197
        match self {
16✔
198
            InvalidBinaryEncodedScopeError::StartsWithSeparator(s) => {
13✔
199
                write!(f, "scope may not start with separator '{s:#x}'")
13✔
200
            }
201
            InvalidBinaryEncodedScopeError::EndsWithSeparator(s) => {
2✔
202
                write!(f, "scope may not end with separator '{s:#x}'")
2✔
203
            }
204
            InvalidBinaryEncodedScopeError::ConsecutiveSeparators(s) => {
1✔
205
                write!(f, "scope may not contain separator '{s:#x}' twice in a row")
1✔
206
            }
207
            InvalidBinaryEncodedScopeError::EmptyScope => write!(f, "scope may not be empty"),
×
208
        }
209
    }
16✔
210
}
211

212
/// Error type used when an [`AifEncodedScope`](crate::common::scope::AifEncodedScope)
213
/// does not conform to the specification given in [RFC 6749](https://datatracker.ietf.org/doc/html/rfc6749) and
214
/// [RFC 9237](https://www.rfc-editor.org/rfc/rfc9237).
215
///
216
/// This is also used when a [`LibdcafEncodedScope`](crate::common::scope::LibdcafEncodedScope)
217
/// does not conform to the format specified in its documentation.
218
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
219
#[non_exhaustive]
220
pub enum InvalidAifEncodedScopeError {
221
    /// Scope's bitflags, representing an [AifRestMethodSet](crate::common::scope::AifRestMethodSet)
222
    /// were not valid, i.e., did not represent a valid combination of REST methods.
223
    InvalidRestMethodSet,
224

225
    /// Scope contained a malformed array, i.e., didn't conform to the specification.
226
    MalformedArray,
227
}
228

229
impl Display for InvalidAifEncodedScopeError {
230
    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
10✔
231
        match self {
10✔
232
            InvalidAifEncodedScopeError::InvalidRestMethodSet => {
233
                write!(f, "given REST method bitfield is invalid")
10✔
234
            }
235
            InvalidAifEncodedScopeError::MalformedArray => {
236
                write!(f, "given AIF CBOR array is malformed")
×
237
            }
238
        }
239
    }
10✔
240
}
241

242
/// Error type used when a [`EncryptCryptoBackend`](crate::token::cose::EncryptCryptoBackend),
243
/// [`SignCryptoBackend`](crate::token::cose::SignCryptoBackend), or
244
/// [`MacCryptoBackend`](crate::token::cose::MacCryptoBackend) fails to perform an operation.
245
///
246
/// `T` is the type of the nested error represented by the [`Other`](CoseCipherError::Other) variant.
247
#[derive(Debug, PartialEq, Clone)]
248
#[non_exhaustive]
249
pub enum CoseCipherError<T>
250
where
251
    T: Display,
252
{
253
    /// The given encrypted, signed or MAC-ed structure could not be verified and/or decrypted.
254
    VerificationFailure,
255
    /// Key type is not supported.
256
    UnsupportedKeyType(KeyType),
257
    /// Curve is not supported by coset or the chosen cryptographic backend.
258
    UnsupportedCurve(EllipticCurve),
259
    /// Algorithm is not supported by coset, the chosen cryptographic backend or dcaf-rs itself.
260
    UnsupportedAlgorithm(Algorithm),
261
    /// The cryptographic backend does not support deriving the public key from the private key, and
262
    /// the provided key does not provide the public key parts even though it is required for this
263
    /// operation.
264
    UnsupportedKeyDerivation,
265
    /// The algorithm has not explicitly been specified anywhere (protected headers, unprotected
266
    /// headers or the key itself).
267
    NoAlgorithmDeterminable,
268
    /// The provided key does not support the given operation.
269
    /// The first field specifies the operations provided by the key, the second one
270
    /// specifies the set of operations that would fulfill the requirements of the
271
    /// operation (only one of which must be provided by the key).
272
    KeyOperationNotPermitted(BTreeSet<KeyOperation>, BTreeSet<KeyOperation>),
273
    /// Key in given curve must be in different format.
274
    KeyTypeCurveMismatch(KeyType, EllipticCurve),
275
    /// Provided algorithm requires a different key type.
276
    KeyTypeAlgorithmMismatch(KeyType, Algorithm),
277
    /// Algorithm provided in key does not match algorithm selected for operation.
278
    /// The first field specifies the algorithm provided by the key, the second one
279
    /// specifies the algorithm provided in the headers.
280
    KeyAlgorithmMismatch(Algorithm, Algorithm),
281
    /// At least one header was provided both in the protected and the unprotected bucket
282
    /// simultaneously.
283
    DuplicateHeaders(Vec<Label>),
284
    /// A key parameter that is required for this type of key and/or algorithm is missing.
285
    ///
286
    /// If multiple key parameters are provided, at least one of them (but possibly more than one)
287
    /// is required (e.g. for EC keys, either D or (X and Y) must be set).
288
    MissingKeyParam(Vec<KeyParam>),
289
    /// A key parameter for this key has an invalid value.
290
    InvalidKeyParam(KeyParam, Value),
291
    /// A header parameter that is required for the selected algorithm is missing.
292
    MissingHeaderParam(HeaderParam),
293
    /// A header parameter has an invalid value.
294
    InvalidHeaderParam(HeaderParam, Value),
295
    /// Provided algorithm does not support additional authenticated data, but AAD was provided
296
    /// (either directly or the protected header bucket is not empty).
297
    AadUnsupported,
298
    /// No suitable key for verifying this structure was found.
299
    ///
300
    /// Either no matching key was provided or all provided keys had an error while attempting to
301
    /// verify.
302
    ///
303
    /// In the latter case, the error field will contain a list of all attempted keys and the
304
    /// corresponding error.
305
    NoMatchingKeyFound(Vec<(CoseKey, CoseCipherError<T>)>),
306
    /// For structures that are validated using a CEK encoded in [CoseRecipient] structures
307
    /// ([CoseEncrypt](coset::CoseEncrypt), [CoseMac](coset::CoseMac)): Unable to find a suitable
308
    /// recipient to decrypt.
309
    ///
310
    /// The first element provides the errors that occurred while decrypting each recipient, the
311
    /// second element describes the errors that occurred while attempting to decrypt the structure
312
    /// itself with any successfully decrypted CEKs.
313
    NoDecryptableRecipientFound(
314
        Vec<(CoseRecipient, CoseCipherError<T>)>,
315
        Vec<(CoseKey, CoseCipherError<T>)>,
316
    ),
317
    /// For structures with multiple signatures ([CoseSignature]): None of the signatures could be
318
    /// verified.
319
    ///
320
    /// The contained vector describes the error that occurred while validating each signature.
321
    NoValidSignatureFound(Vec<(CoseSignature, CoseCipherError<T>)>),
322
    /// Provided payload is not supported for this algorithm.
323
    ///
324
    /// For instance AES key wrap inputs must be a multiple of 64 bits.
325
    InvalidPayload(Vec<u8>),
326
    /// A different error has occurred. Details are provided in the contained error.
327
    Other(T),
328
}
329

330
impl<T> CoseCipherError<T>
331
where
332
    T: Display,
333
{
334
    /// Creates a new [`CoseCipherError`] of type
335
    /// [`Other`](CoseCipherError::Other) (i.e., an error type that doesn't fit any other
336
    /// [`CoseCipherError`] variant) containing the given nested error `other`.
337
    #[must_use]
338
    pub fn other_error(other: T) -> CoseCipherError<T> {
×
339
        CoseCipherError::Other(other)
×
340
    }
×
341
}
342

343
impl<T> Display for CoseCipherError<T>
344
where
345
    T: Display,
346
{
347
    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
×
348
        match self {
×
349
            // TODO (#14): this can probably be done better (use thiserror instead as soon as std::error::Error has been moved to core?)
350
            CoseCipherError::VerificationFailure => {
351
                write!(f, "data verification and/or decryption failed")
×
352
            }
353
            CoseCipherError::Other(s) => write!(f, "{s}"),
×
354
            CoseCipherError::UnsupportedKeyType(_) => write!(f, "unsupported key type"),
×
355
            CoseCipherError::UnsupportedCurve(_) => write!(f, "unsupported curve"),
×
356
            CoseCipherError::UnsupportedAlgorithm(_) => write!(f, "unsupported alorithm"),
×
357
            CoseCipherError::UnsupportedKeyDerivation => write!(
×
358
                f,
×
359
                "backend does not support public key derivation from private key"
×
360
            ),
×
361
            CoseCipherError::NoAlgorithmDeterminable => {
362
                write!(f, "no algorithm was provided in headers or key")
×
363
            }
364
            CoseCipherError::KeyOperationNotPermitted(_, _) => {
365
                write!(f, "key does not permit the requested operation")
×
366
            }
367
            CoseCipherError::KeyTypeCurveMismatch(_, _) => {
368
                write!(f, "key type is not supported for the given curve")
×
369
            }
370
            CoseCipherError::KeyTypeAlgorithmMismatch(_, _) => {
371
                write!(f, "key type is not supported for the given algorithm")
×
372
            }
373
            CoseCipherError::KeyAlgorithmMismatch(_, _) => {
374
                write!(f, "key does not support the given algorithm")
×
375
            }
376
            CoseCipherError::DuplicateHeaders(_) => write!(f, "duplicate headers"),
×
377
            CoseCipherError::MissingKeyParam(_) => write!(f, "required key parameter missing"),
×
378
            CoseCipherError::InvalidKeyParam(_, _) => write!(f, "key parameter has invalid value"),
×
379
            CoseCipherError::NoMatchingKeyFound(_) => {
380
                write!(f, "no suitable key was found for this operation")
×
381
            }
382
            CoseCipherError::MissingHeaderParam(_) => {
383
                write!(f, "header parameter missing")
×
384
            }
385
            CoseCipherError::InvalidHeaderParam(_, _) => {
386
                write!(f, "header parameter invalid")
×
387
            }
388
            CoseCipherError::AadUnsupported => {
389
                write!(
×
390
                    f,
×
391
                    "algorithm does not support additional authenticated data"
×
392
                )
×
393
            }
394
            CoseCipherError::NoDecryptableRecipientFound(_, _) => {
395
                write!(
×
396
                    f,
×
397
                    "could not decrypt any recipient with any of the provided keys"
×
398
                )
×
399
            }
400
            CoseCipherError::NoValidSignatureFound(_) => {
401
                write!(
×
402
                    f,
×
403
                    "could not validate any of the signatures with any of the provided keys"
×
404
                )
×
405
            }
406
            CoseCipherError::InvalidPayload(_) => {
407
                write!(f, "payload is invalid for the given algorithm")
×
408
            }
409
        }
410
    }
×
411
}
412

413
impl<T: Display> From<T> for CoseCipherError<T> {
414
    fn from(value: T) -> Self {
×
415
        CoseCipherError::other_error(value)
×
416
    }
×
417
}
418

419
/// Error type when a [`Value`] can't be converted to a Scope.
420
///
421
/// This can be because it isn't a scope, or because the scope is invalid.
422
#[derive(Debug, PartialEq, Clone)]
423
#[non_exhaustive]
424
pub enum ScopeFromValueError {
425
    /// The binary scope contained in the [`Value`] is invalid.
426
    ///
427
    /// Details are provided in the given [`InvalidBinaryEncodedScopeError`].
428
    InvalidBinaryEncodedScope(InvalidBinaryEncodedScopeError),
429

430
    /// The textual scope contained in the [`Value`] is invalid.
431
    ///
432
    /// Details are provided in the given [`InvalidTextEncodedScopeError`].
433
    InvalidTextEncodedScope(InvalidTextEncodedScopeError),
434

435
    /// The AIF-encoded scope contained in the [`Value`] is invalid.
436
    ///
437
    /// Details are provided in the given [`InvalidAifEncodedScopeError`].
438
    InvalidAifEncodedScope(InvalidAifEncodedScopeError),
439

440
    /// The [`Value`] isn't a scope, but something else.
441
    ///
442
    /// Details are provided in the given [`WrongSourceTypeError`].
443
    InvalidType(WrongSourceTypeError<Value>),
444
}
445

446
fn to_variant_name(value: &Value) -> &'static str {
7✔
447
    match value {
7✔
448
        Value::Integer(_) => "Integer",
1✔
449
        Value::Bytes(_) => "Bytes",
×
450
        Value::Float(_) => "Float",
1✔
451
        Value::Text(_) => "Text",
×
452
        Value::Bool(_) => "Bool",
2✔
453
        Value::Null => "Null",
1✔
454
        Value::Tag(_, _) => "Tag",
1✔
455
        Value::Array(_) => "Array",
×
456
        Value::Map(_) => "Map",
1✔
457
        _ => "Unknown",
×
458
    }
459
}
7✔
460

461
impl ScopeFromValueError {
462
    /// Creates a new [`InvalidType`](ScopeFromValueError::InvalidType) error from the given
463
    /// `actual` [`Value`].
464
    ///
465
    /// Should be used when a given [`Value`] is not a text or byte string.
466
    #[must_use]
467
    pub fn invalid_type(actual: &Value) -> ScopeFromValueError {
7✔
468
        ScopeFromValueError::from(WrongSourceTypeError::new(
7✔
469
            "Text or Bytes",
7✔
470
            to_variant_name(actual),
7✔
471
        ))
7✔
472
    }
7✔
473
}
474

475
impl From<InvalidTextEncodedScopeError> for ScopeFromValueError {
476
    fn from(err: InvalidTextEncodedScopeError) -> Self {
×
477
        ScopeFromValueError::InvalidTextEncodedScope(err)
×
478
    }
×
479
}
480

481
impl From<InvalidBinaryEncodedScopeError> for ScopeFromValueError {
482
    fn from(err: InvalidBinaryEncodedScopeError) -> Self {
×
483
        ScopeFromValueError::InvalidBinaryEncodedScope(err)
×
484
    }
×
485
}
486

487
impl From<InvalidAifEncodedScopeError> for ScopeFromValueError {
488
    fn from(err: InvalidAifEncodedScopeError) -> Self {
×
489
        ScopeFromValueError::InvalidAifEncodedScope(err)
×
490
    }
×
491
}
492

493
impl From<WrongSourceTypeError<Value>> for ScopeFromValueError {
494
    fn from(err: WrongSourceTypeError<Value>) -> Self {
7✔
495
        ScopeFromValueError::InvalidType(err)
7✔
496
    }
7✔
497
}
498

499
impl Display for ScopeFromValueError {
500
    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
7✔
501
        match self {
7✔
502
            ScopeFromValueError::InvalidBinaryEncodedScope(s) => {
×
503
                write!(f, "invalid binary-encoded scope: {s}")
×
504
            }
505
            ScopeFromValueError::InvalidTextEncodedScope(s) => {
×
506
                write!(f, "invalid text-encoded scope: {s}")
×
507
            }
508
            ScopeFromValueError::InvalidType(t) => write!(f, "invalid type: {t}"),
7✔
509
            ScopeFromValueError::InvalidAifEncodedScope(a) => {
×
510
                write!(f, "invalid AIF-encoded scope: {a}")
×
511
            }
512
        }
513
    }
7✔
514
}
515

516
/// Error type used when an operation creating or receiving an access token failed.
517
///
518
/// `T` is the type of the nested error possibly contained by the
519
/// [`CoseCipherError`](AccessTokenError::CoseCipherError) variant.
520
#[derive(Debug)]
521
#[non_exhaustive]
522
pub enum AccessTokenError<T>
523
where
524
    T: Display,
525
{
526
    /// A COSE specific error occurred.
527
    ///
528
    /// Details are contained in this field using coset's [`CoseError`].
529
    CoseError(CoseError),
530
    /// A cryptographic CoseCipher operation has failed.
531
    ///
532
    /// Details are contained in this field, represented by a [`CoseCipherError`].
533
    CoseCipherError(CoseCipherError<T>),
534
    /// Headers can't be extracted because the input data is neither a
535
    /// [`CoseEncrypt0`](coset::CoseEncrypt0), [`CoseSign1`](coset::CoseSign1),
536
    /// nor [`CoseMac0`](coset::CoseMac0).
537
    UnknownCoseStructure,
538
}
539

540
impl<T> Display for AccessTokenError<T>
541
where
542
    T: Display,
543
{
544
    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
×
545
        match self {
×
546
            AccessTokenError::CoseError(e) => write!(f, "{e}"),
×
547
            AccessTokenError::CoseCipherError(e) => write!(f, "cipher error: {e}"),
×
548
            AccessTokenError::UnknownCoseStructure => write!(
×
549
                f,
×
550
                "input is either invalid or none of CoseEncrypt0, CoseSign1 nor CoseMac0"
×
551
            ),
×
552
        }
553
    }
×
554
}
555

556
impl<T> From<CoseCipherError<T>> for AccessTokenError<T>
557
where
558
    T: Display,
559
{
560
    #[must_use]
561
    fn from(error: CoseCipherError<T>) -> Self {
6✔
562
        AccessTokenError::CoseCipherError(error)
6✔
563
    }
6✔
564
}
565

566
impl<T> From<CoseError> for AccessTokenError<T>
567
where
568
    T: Display,
569
{
570
    #[must_use]
571
    fn from(error: CoseError) -> Self {
×
572
        AccessTokenError::CoseError(error)
×
573
    }
×
574
}
575

576
#[cfg(feature = "std")]
577
mod std_error {
578
    use core::fmt::Debug;
579
    use std::error::Error;
580

581
    use crate::endpoints::creation_hint::AuthServerRequestCreationHintBuilderError;
582
    use crate::endpoints::token_req::AccessTokenRequestBuilderError;
583
    use crate::endpoints::token_req::AccessTokenResponseBuilderError;
584
    use crate::endpoints::token_req::ErrorResponseBuilderError;
585

586
    use super::*;
587

588
    impl<T> Error for WrongSourceTypeError<T> where T: Debug {}
589

590
    impl Error for TryFromCborMapError {}
591

592
    impl Error for ValueIsNotIntegerError {}
593

594
    impl Error for InvalidTextEncodedScopeError {}
595

596
    impl Error for InvalidBinaryEncodedScopeError {}
597

598
    impl Error for InvalidAifEncodedScopeError {}
599

600
    impl Error for ScopeFromValueError {}
601

602
    impl<T> Error for CoseCipherError<T> where T: Debug + Display {}
603

604
    impl<T> Error for AccessTokenError<T> where T: Debug + Display {}
605

606
    impl Error for AccessTokenRequestBuilderError {}
607

608
    impl Error for AccessTokenResponseBuilderError {}
609

610
    impl Error for ErrorResponseBuilderError {}
611

612
    impl Error for AuthServerRequestCreationHintBuilderError {}
613
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc