Coverage Report

Created: 2026-06-07 06:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/rustls-webpki-0.103.13/src/error.rs
Line
Count
Source
1
// Copyright 2015 Brian Smith.
2
//
3
// Permission to use, copy, modify, and/or distribute this software for any
4
// purpose with or without fee is hereby granted, provided that the above
5
// copyright notice and this permission notice appear in all copies.
6
//
7
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
8
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
10
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15
#[cfg(feature = "alloc")]
16
use alloc::string::String;
17
#[cfg(feature = "alloc")]
18
use alloc::vec::Vec;
19
use core::fmt;
20
use core::ops::ControlFlow;
21
22
use pki_types::UnixTime;
23
#[cfg(feature = "alloc")]
24
use pki_types::{AlgorithmIdentifier, ServerName};
25
26
use crate::verify_cert::RequiredEkuNotFoundContext;
27
28
/// An error that occurs during certificate validation or name validation.
29
#[derive(Clone, Debug, PartialEq, Eq)]
30
#[non_exhaustive]
31
pub enum Error {
32
    /// The encoding of some ASN.1 DER-encoded item is invalid.
33
    BadDer,
34
35
    /// The encoding of an ASN.1 DER-encoded time is invalid.
36
    BadDerTime,
37
38
    /// A CA certificate is being used as an end-entity certificate.
39
    CaUsedAsEndEntity,
40
41
    /// The certificate is expired; i.e. the time it is being validated for is
42
    /// later than the certificate's notAfter time.
43
    CertExpired {
44
        /// The validation time.
45
        time: UnixTime,
46
        /// The notAfter time of the certificate.
47
        not_after: UnixTime,
48
    },
49
50
    /// The certificate is not valid for the name it is being validated for.
51
    CertNotValidForName(InvalidNameContext),
52
53
    /// The certificate is not valid yet; i.e. the time it is being validated
54
    /// for is earlier than the certificate's notBefore time.
55
    CertNotValidYet {
56
        /// The validation time.
57
        time: UnixTime,
58
        /// The notBefore time of the certificate.
59
        not_before: UnixTime,
60
    },
61
62
    /// The certificate, or one of its issuers, has been revoked.
63
    CertRevoked,
64
65
    /// The CRL is expired; i.e. the verification time is not before the time
66
    /// in the CRL nextUpdate field.
67
    CrlExpired {
68
        /// The validation time.
69
        time: UnixTime,
70
        /// The nextUpdate time of the CRL.
71
        next_update: UnixTime,
72
    },
73
74
    /// The certificate has an Extended Key Usage extension without any EKU values.
75
    EmptyEkuExtension,
76
77
    /// An end-entity certificate is being used as a CA certificate.
78
    EndEntityUsedAsCa,
79
80
    /// An X.509 extension is invalid.
81
    ExtensionValueInvalid,
82
83
    /// The certificate validity period (notBefore, notAfter) is invalid; e.g.
84
    /// the notAfter time is earlier than the notBefore time.
85
    InvalidCertValidity,
86
87
    /// A CRL number extension was invalid:
88
    ///  - it was mis-encoded
89
    ///  - it was negative
90
    ///  - it was too long
91
    InvalidCrlNumber,
92
93
    /// A iPAddress name constraint was invalid:
94
    /// - it had a sparse network mask (ie, cannot be written in CIDR form).
95
    /// - it was too long or short
96
    InvalidNetworkMaskConstraint,
97
98
    /// A serial number was invalid:
99
    ///  - it was misencoded
100
    ///  - it was negative
101
    ///  - it was too long
102
    InvalidSerialNumber,
103
104
    /// The CRL signature is invalid for the issuer's public key.
105
    InvalidCrlSignatureForPublicKey,
106
107
    /// The signature is invalid for the given public key.
108
    InvalidSignatureForPublicKey,
109
110
    /// A CRL was signed by an issuer that has a KeyUsage bitstring that does not include
111
    /// the cRLSign key usage bit.
112
    IssuerNotCrlSigner,
113
114
    /// A presented or reference DNS identifier was malformed, potentially
115
    /// containing invalid characters or invalid labels.
116
    MalformedDnsIdentifier,
117
118
    /// The certificate extensions are malformed.
119
    ///
120
    /// In particular, webpki requires the DNS name(s) be in the subjectAltName
121
    /// extension as required by the CA/Browser Forum Baseline Requirements
122
    /// and as recommended by RFC6125.
123
    MalformedExtensions,
124
125
    /// A name constraint was malformed, potentially containing invalid characters or
126
    /// invalid labels.
127
    MalformedNameConstraint,
128
129
    /// The maximum number of name constraint comparisons has been reached.
130
    MaximumNameConstraintComparisonsExceeded,
131
132
    /// The maximum number of internal path building calls has been reached. Path complexity is too great.
133
    MaximumPathBuildCallsExceeded,
134
135
    /// The path search was terminated because it became too deep.
136
    MaximumPathDepthExceeded,
137
138
    /// The maximum number of signature checks has been reached. Path complexity is too great.
139
    MaximumSignatureChecksExceeded,
140
141
    /// The certificate violates one or more name constraints.
142
    NameConstraintViolation,
143
144
    /// The certificate violates one or more path length constraints.
145
    PathLenConstraintViolated,
146
147
    /// The certificate is not valid for the Extended Key Usage for which it is
148
    /// being validated.
149
    #[deprecated(since = "0.103.2", note = "use RequiredEkuNotFoundContext instead")]
150
    RequiredEkuNotFound,
151
152
    /// The certificate is not valid for the Extended Key Usage for which it is
153
    /// being validated.
154
    RequiredEkuNotFoundContext(RequiredEkuNotFoundContext),
155
156
    /// The algorithm in the TBSCertificate "signature" field of a certificate
157
    /// does not match the algorithm in the signature of the certificate.
158
    SignatureAlgorithmMismatch,
159
160
    /// Trailing data was found while parsing DER-encoded input for the named type.
161
    TrailingData(DerTypeId),
162
163
    /// A valid issuer for the certificate could not be found.
164
    UnknownIssuer,
165
166
    /// The certificate's revocation status could not be determined.
167
    UnknownRevocationStatus,
168
169
    /// The certificate is not a v3 X.509 certificate.
170
    ///
171
    /// This error may be also reported if the certificate version field
172
    /// is malformed.
173
    UnsupportedCertVersion,
174
175
    /// The certificate contains an unsupported critical extension.
176
    UnsupportedCriticalExtension,
177
178
    /// The CRL contains an issuing distribution point with no distribution point name,
179
    /// or a distribution point name relative to an issuer.
180
    UnsupportedCrlIssuingDistributionPoint,
181
182
    /// The CRL is not a v2 X.509 CRL.
183
    ///
184
    /// The RFC 5280 web PKI profile mandates only version 2 be used. See section
185
    /// 5.1.2.1 for more information.
186
    ///
187
    /// This error may also be reported if the CRL version field is malformed.
188
    UnsupportedCrlVersion,
189
190
    /// The CRL is an unsupported "delta" CRL.
191
    UnsupportedDeltaCrl,
192
193
    /// The CRL contains unsupported "indirect" entries.
194
    UnsupportedIndirectCrl,
195
196
    /// The `ServerName` contained an unsupported type of value.
197
    UnsupportedNameType,
198
199
    /// The revocation reason is not in the set of supported revocation reasons.
200
    UnsupportedRevocationReason,
201
202
    /// The CRL is partitioned by revocation reasons.
203
    UnsupportedRevocationReasonsPartitioning,
204
205
    /// The signature algorithm for a signature over a CRL is not in the set of supported
206
    /// signature algorithms given.
207
    #[deprecated(
208
        since = "0.103.4",
209
        note = "use UnsupportedCrlSignatureAlgorithmContext instead"
210
    )]
211
    UnsupportedCrlSignatureAlgorithm,
212
213
    /// The signature algorithm for a signature is not in the set of supported
214
    /// signature algorithms given.
215
    UnsupportedCrlSignatureAlgorithmContext(UnsupportedSignatureAlgorithmContext),
216
217
    /// The signature algorithm for a signature is not in the set of supported
218
    /// signature algorithms given.
219
    #[deprecated(
220
        since = "0.103.4",
221
        note = "use UnsupportedSignatureAlgorithmContext instead"
222
    )]
223
    UnsupportedSignatureAlgorithm,
224
225
    /// The signature algorithm for a signature is not in the set of supported
226
    /// signature algorithms given.
227
    UnsupportedSignatureAlgorithmContext(UnsupportedSignatureAlgorithmContext),
228
229
    /// The CRL signature's algorithm does not match the algorithm of the issuer
230
    /// public key it is being validated for. This may be because the public key
231
    /// algorithm's OID isn't recognized (e.g. DSA), or the public key
232
    /// algorithm's parameters don't match the supported parameters for that
233
    /// algorithm (e.g. ECC keys for unsupported curves), or the public key
234
    /// algorithm and the signature algorithm simply don't match (e.g.
235
    /// verifying an RSA signature with an ECC public key).
236
    #[deprecated(
237
        since = "0.103.4",
238
        note = "use UnsupportedCrlSignatureAlgorithmForPublicKeyContext instead"
239
    )]
240
    UnsupportedCrlSignatureAlgorithmForPublicKey,
241
242
    /// The signature's algorithm does not match the algorithm of the public
243
    /// key it is being validated for. This may be because the public key
244
    /// algorithm's OID isn't recognized (e.g. DSA), or the public key
245
    /// algorithm's parameters don't match the supported parameters for that
246
    /// algorithm (e.g. ECC keys for unsupported curves), or the public key
247
    /// algorithm and the signature algorithm simply don't match (e.g.
248
    /// verifying an RSA signature with an ECC public key).
249
    UnsupportedCrlSignatureAlgorithmForPublicKeyContext(
250
        UnsupportedSignatureAlgorithmForPublicKeyContext,
251
    ),
252
253
    /// The signature's algorithm does not match the algorithm of the public
254
    /// key it is being validated for. This may be because the public key
255
    /// algorithm's OID isn't recognized (e.g. DSA), or the public key
256
    /// algorithm's parameters don't match the supported parameters for that
257
    /// algorithm (e.g. ECC keys for unsupported curves), or the public key
258
    /// algorithm and the signature algorithm simply don't match (e.g.
259
    /// verifying an RSA signature with an ECC public key).
260
    #[deprecated(
261
        since = "0.103.4",
262
        note = "use UnsupportedSignatureAlgorithmForPublicKeyContext instead"
263
    )]
264
    UnsupportedSignatureAlgorithmForPublicKey,
265
266
    /// The signature's algorithm does not match the algorithm of the public
267
    /// key it is being validated for. This may be because the public key
268
    /// algorithm's OID isn't recognized (e.g. DSA), or the public key
269
    /// algorithm's parameters don't match the supported parameters for that
270
    /// algorithm (e.g. ECC keys for unsupported curves), or the public key
271
    /// algorithm and the signature algorithm simply don't match (e.g.
272
    /// verifying an RSA signature with an ECC public key).
273
    UnsupportedSignatureAlgorithmForPublicKeyContext(
274
        UnsupportedSignatureAlgorithmForPublicKeyContext,
275
    ),
276
}
277
278
impl Error {
279
    // Compare the Error with the new error by rank, returning the higher rank of the two as
280
    // the most specific error.
281
0
    pub(crate) fn most_specific(self, new: Self) -> Self {
282
        // Assign an error a numeric value ranking it by specificity.
283
0
        if self.rank() >= new.rank() { self } else { new }
284
0
    }
Unexecuted instantiation: <webpki::error::Error>::most_specific
Unexecuted instantiation: <webpki::error::Error>::most_specific
285
286
    // Return a numeric indication of how specific the error is, where an error with a higher rank
287
    // is considered more useful to an end user than an error with a lower rank. This is used by
288
    // Error::most_specific to compare two errors in order to return which is more specific.
289
    #[allow(clippy::as_conversions)] // We won't exceed u32 errors.
290
0
    pub(crate) fn rank(&self) -> u32 {
291
0
        match &self {
292
            // Errors related to certificate validity
293
0
            Self::CertNotValidYet { .. } | Self::CertExpired { .. } => 290,
294
0
            Self::CertNotValidForName(_) => 280,
295
0
            Self::CertRevoked | Self::UnknownRevocationStatus | Self::CrlExpired { .. } => 270,
296
0
            Self::InvalidCrlSignatureForPublicKey | Self::InvalidSignatureForPublicKey => 260,
297
0
            Self::SignatureAlgorithmMismatch => 250,
298
0
            Self::EmptyEkuExtension => 245,
299
            #[allow(deprecated)]
300
0
            Self::RequiredEkuNotFound | Self::RequiredEkuNotFoundContext(_) => 240,
301
0
            Self::NameConstraintViolation => 230,
302
0
            Self::PathLenConstraintViolated => 220,
303
0
            Self::CaUsedAsEndEntity | Self::EndEntityUsedAsCa => 210,
304
0
            Self::IssuerNotCrlSigner => 200,
305
306
            // Errors related to supported features used in an invalid way.
307
0
            Self::InvalidCertValidity => 190,
308
0
            Self::InvalidNetworkMaskConstraint => 180,
309
0
            Self::InvalidSerialNumber => 170,
310
0
            Self::InvalidCrlNumber => 160,
311
312
            // Errors related to unsupported features.
313
            #[allow(deprecated)]
314
            Self::UnsupportedCrlSignatureAlgorithmForPublicKey
315
            | Self::UnsupportedCrlSignatureAlgorithmForPublicKeyContext(_)
316
            | Self::UnsupportedSignatureAlgorithmForPublicKey
317
0
            | Self::UnsupportedSignatureAlgorithmForPublicKeyContext(_) => 150,
318
            #[allow(deprecated)]
319
            Self::UnsupportedCrlSignatureAlgorithm
320
            | Self::UnsupportedCrlSignatureAlgorithmContext(_)
321
            | Self::UnsupportedSignatureAlgorithm
322
0
            | Self::UnsupportedSignatureAlgorithmContext(_) => 140,
323
0
            Self::UnsupportedCriticalExtension => 130,
324
0
            Self::UnsupportedCertVersion => 130,
325
0
            Self::UnsupportedCrlVersion => 120,
326
0
            Self::UnsupportedDeltaCrl => 110,
327
0
            Self::UnsupportedIndirectCrl => 100,
328
0
            Self::UnsupportedNameType => 95,
329
0
            Self::UnsupportedRevocationReason => 90,
330
0
            Self::UnsupportedRevocationReasonsPartitioning => 80,
331
0
            Self::UnsupportedCrlIssuingDistributionPoint => 70,
332
0
            Self::MaximumPathDepthExceeded => 61,
333
334
            // Errors related to malformed data.
335
0
            Self::MalformedDnsIdentifier => 60,
336
0
            Self::MalformedNameConstraint => 50,
337
0
            Self::MalformedExtensions | Self::TrailingData(_) => 40,
338
0
            Self::ExtensionValueInvalid => 30,
339
340
            // Generic DER errors.
341
0
            Self::BadDerTime => 20,
342
0
            Self::BadDer => 10,
343
344
            // Special case errors - not subject to ranking.
345
0
            Self::MaximumSignatureChecksExceeded => 0,
346
0
            Self::MaximumPathBuildCallsExceeded => 0,
347
0
            Self::MaximumNameConstraintComparisonsExceeded => 0,
348
349
            // Default catch all error - should be renamed in the future.
350
0
            Self::UnknownIssuer => 0,
351
        }
352
0
    }
Unexecuted instantiation: <webpki::error::Error>::rank
Unexecuted instantiation: <webpki::error::Error>::rank
353
354
    /// Returns true for errors that should be considered fatal during path building. Errors of
355
    /// this class should halt any further path building and be returned immediately.
356
    #[inline]
357
0
    pub(crate) fn is_fatal(&self) -> bool {
358
0
        matches!(
359
0
            self,
360
            Self::MaximumSignatureChecksExceeded
361
                | Self::MaximumPathBuildCallsExceeded
362
                | Self::MaximumNameConstraintComparisonsExceeded
363
        )
364
0
    }
Unexecuted instantiation: <webpki::error::Error>::is_fatal
Unexecuted instantiation: <webpki::error::Error>::is_fatal
365
}
366
367
impl From<Error> for ControlFlow<Error, Error> {
368
0
    fn from(value: Error) -> Self {
369
0
        match value {
370
            // If an error is fatal, we've exhausted the potential for continued search.
371
0
            err if err.is_fatal() => Self::Break(err),
372
            // Otherwise we've rejected one candidate chain, but may continue to search for others.
373
0
            err => Self::Continue(err),
374
        }
375
0
    }
Unexecuted instantiation: <core::ops::control_flow::ControlFlow<webpki::error::Error, webpki::error::Error> as core::convert::From<webpki::error::Error>>::from
Unexecuted instantiation: <core::ops::control_flow::ControlFlow<webpki::error::Error, webpki::error::Error> as core::convert::From<webpki::error::Error>>::from
376
}
377
378
impl fmt::Display for Error {
379
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
380
0
        write!(f, "{self:?}")
381
0
    }
Unexecuted instantiation: <webpki::error::Error as core::fmt::Display>::fmt
Unexecuted instantiation: <webpki::error::Error as core::fmt::Display>::fmt
382
}
383
384
#[cfg(feature = "std")]
385
impl ::std::error::Error for Error {}
386
387
/// Additional context for the `CertNotValidForName` error variant.
388
///
389
/// The contents of this type depend on whether the `alloc` feature is enabled.
390
#[derive(Clone, Debug, PartialEq, Eq)]
391
pub struct InvalidNameContext {
392
    /// Expected server name.
393
    #[cfg(feature = "alloc")]
394
    pub expected: ServerName<'static>,
395
    /// The names presented in the end entity certificate.
396
    ///
397
    /// These are the subject names as present in the leaf certificate and may contain DNS names
398
    /// with or without a wildcard label as well as IP address names.
399
    #[cfg(feature = "alloc")]
400
    pub presented: Vec<String>,
401
}
402
403
/// Additional context for the `UnsupportedSignatureAlgorithmForPublicKey` error variant.
404
///
405
/// The contents of this type depend on whether the `alloc` feature is enabled.
406
#[derive(Clone, Debug, PartialEq, Eq)]
407
pub struct UnsupportedSignatureAlgorithmForPublicKeyContext {
408
    /// The signature algorithm OID.
409
    #[cfg(feature = "alloc")]
410
    pub signature_algorithm_id: Vec<u8>,
411
    /// The public key algorithm OID.
412
    #[cfg(feature = "alloc")]
413
    pub public_key_algorithm_id: Vec<u8>,
414
}
415
416
/// Additional context for the `UnsupportedSignatureAlgorithm` error variant.
417
///
418
/// The contents of this type depend on whether the `alloc` feature is enabled.
419
#[derive(Clone, Debug, PartialEq, Eq)]
420
pub struct UnsupportedSignatureAlgorithmContext {
421
    /// The signature algorithm OID that was unsupported.
422
    #[cfg(feature = "alloc")]
423
    pub signature_algorithm_id: Vec<u8>,
424
    /// Supported algorithms that were available for signature verification.
425
    #[cfg(feature = "alloc")]
426
    pub supported_algorithms: Vec<AlgorithmIdentifier>,
427
}
428
429
/// Trailing data was found while parsing DER-encoded input for the named type.
430
#[allow(missing_docs)]
431
#[non_exhaustive]
432
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
433
pub enum DerTypeId {
434
    BitString,
435
    Bool,
436
    Certificate,
437
    CertificateExtensions,
438
    CertificateTbsCertificate,
439
    CertRevocationList,
440
    CertRevocationListExtension,
441
    CrlDistributionPoint,
442
    CommonNameInner,
443
    CommonNameOuter,
444
    DistributionPointName,
445
    Extension,
446
    GeneralName,
447
    RevocationReason,
448
    Signature,
449
    SignatureAlgorithm,
450
    SignedData,
451
    SubjectPublicKeyInfo,
452
    Time,
453
    TrustAnchorV1,
454
    TrustAnchorV1TbsCertificate,
455
    U8,
456
    RevokedCertificate,
457
    RevokedCertificateExtension,
458
    RevokedCertEntry,
459
    IssuingDistributionPoint,
460
}