Coverage Report

Created: 2026-04-14 06:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/rustls-0.23.37/src/error.rs
Line
Count
Source
1
use alloc::format;
2
use alloc::string::String;
3
use alloc::vec::Vec;
4
use core::fmt;
5
#[cfg(feature = "std")]
6
use std::time::SystemTimeError;
7
8
use pki_types::{AlgorithmIdentifier, ServerName, UnixTime};
9
use webpki::KeyUsage;
10
11
use crate::enums::{AlertDescription, ContentType, HandshakeType};
12
use crate::msgs::handshake::{EchConfigPayload, KeyExchangeAlgorithm};
13
use crate::rand;
14
15
/// rustls reports protocol errors using this type.
16
#[non_exhaustive]
17
#[derive(Debug, PartialEq, Clone)]
18
pub enum Error {
19
    /// We received a TLS message that isn't valid right now.
20
    /// `expect_types` lists the message types we can expect right now.
21
    /// `got_type` is the type we found.  This error is typically
22
    /// caused by a buggy TLS stack (the peer or this one), a broken
23
    /// network, or an attack.
24
    InappropriateMessage {
25
        /// Which types we expected
26
        expect_types: Vec<ContentType>,
27
        /// What type we received
28
        got_type: ContentType,
29
    },
30
31
    /// We received a TLS handshake message that isn't valid right now.
32
    /// `expect_types` lists the handshake message types we can expect
33
    /// right now.  `got_type` is the type we found.
34
    InappropriateHandshakeMessage {
35
        /// Which handshake type we expected
36
        expect_types: Vec<HandshakeType>,
37
        /// What handshake type we received
38
        got_type: HandshakeType,
39
    },
40
41
    /// An error occurred while handling Encrypted Client Hello (ECH).
42
    InvalidEncryptedClientHello(EncryptedClientHelloError),
43
44
    /// The peer sent us a TLS message with invalid contents.
45
    InvalidMessage(InvalidMessage),
46
47
    /// The peer didn't give us any certificates.
48
    NoCertificatesPresented,
49
50
    /// The certificate verifier doesn't support the given type of name.
51
    UnsupportedNameType,
52
53
    /// We couldn't decrypt a message.  This is invariably fatal.
54
    DecryptError,
55
56
    /// We couldn't encrypt a message because it was larger than the allowed message size.
57
    /// This should never happen if the application is using valid record sizes.
58
    EncryptError,
59
60
    /// The peer doesn't support a protocol version/feature we require.
61
    /// The parameter gives a hint as to what version/feature it is.
62
    PeerIncompatible(PeerIncompatible),
63
64
    /// The peer deviated from the standard TLS protocol.
65
    /// The parameter gives a hint where.
66
    PeerMisbehaved(PeerMisbehaved),
67
68
    /// We received a fatal alert.  This means the peer is unhappy.
69
    AlertReceived(AlertDescription),
70
71
    /// We saw an invalid certificate.
72
    ///
73
    /// The contained error is from the certificate validation trait
74
    /// implementation.
75
    InvalidCertificate(CertificateError),
76
77
    /// A provided certificate revocation list (CRL) was invalid.
78
    InvalidCertRevocationList(CertRevocationListError),
79
80
    /// A catch-all error for unlikely errors.
81
    General(String),
82
83
    /// We failed to figure out what time it currently is.
84
    FailedToGetCurrentTime,
85
86
    /// We failed to acquire random bytes from the system.
87
    FailedToGetRandomBytes,
88
89
    /// This function doesn't work until the TLS handshake
90
    /// is complete.
91
    HandshakeNotComplete,
92
93
    /// The peer sent an oversized record/fragment.
94
    PeerSentOversizedRecord,
95
96
    /// An incoming connection did not support any known application protocol.
97
    NoApplicationProtocol,
98
99
    /// The `max_fragment_size` value supplied in configuration was too small,
100
    /// or too large.
101
    BadMaxFragmentSize,
102
103
    /// Specific failure cases from [`keys_match`] or a [`crate::crypto::signer::SigningKey`] that cannot produce a corresponding public key.
104
    ///
105
    /// [`keys_match`]: crate::crypto::signer::CertifiedKey::keys_match
106
    InconsistentKeys(InconsistentKeys),
107
108
    /// Any other error.
109
    ///
110
    /// This variant should only be used when the error is not better described by a more
111
    /// specific variant. For example, if a custom crypto provider returns a
112
    /// provider specific error.
113
    ///
114
    /// Enums holding this variant will never compare equal to each other.
115
    Other(OtherError),
116
}
117
118
/// Specific failure cases from [`keys_match`] or a [`crate::crypto::signer::SigningKey`] that cannot produce a corresponding public key.
119
///
120
/// [`keys_match`]: crate::crypto::signer::CertifiedKey::keys_match
121
#[non_exhaustive]
122
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
123
pub enum InconsistentKeys {
124
    /// The public key returned by the [`SigningKey`] does not match the public key information in the certificate.
125
    ///
126
    /// [`SigningKey`]: crate::crypto::signer::SigningKey
127
    KeyMismatch,
128
129
    /// The [`SigningKey`] cannot produce its corresponding public key.
130
    ///
131
    /// [`SigningKey`]: crate::crypto::signer::SigningKey
132
    Unknown,
133
}
134
135
impl From<InconsistentKeys> for Error {
136
    #[inline]
137
0
    fn from(e: InconsistentKeys) -> Self {
138
0
        Self::InconsistentKeys(e)
139
0
    }
140
}
141
142
/// A corrupt TLS message payload that resulted in an error.
143
#[non_exhaustive]
144
#[derive(Debug, Clone, Copy, PartialEq)]
145
pub enum InvalidMessage {
146
    /// A certificate payload exceeded rustls's 64KB limit
147
    CertificatePayloadTooLarge,
148
    /// An advertised message was larger then expected.
149
    HandshakePayloadTooLarge,
150
    /// The peer sent us a syntactically incorrect ChangeCipherSpec payload.
151
    InvalidCcs,
152
    /// An unknown content type was encountered during message decoding.
153
    InvalidContentType,
154
    /// A peer sent an invalid certificate status type
155
    InvalidCertificateStatusType,
156
    /// Context was incorrectly attached to a certificate request during a handshake.
157
    InvalidCertRequest,
158
    /// A peer's DH params could not be decoded
159
    InvalidDhParams,
160
    /// A message was zero-length when its record kind forbids it.
161
    InvalidEmptyPayload,
162
    /// A peer sent an unexpected key update request.
163
    InvalidKeyUpdate,
164
    /// A peer's server name could not be decoded
165
    InvalidServerName,
166
    /// A TLS message payload was larger then allowed by the specification.
167
    MessageTooLarge,
168
    /// Message is shorter than the expected length
169
    MessageTooShort,
170
    /// Missing data for the named handshake payload value
171
    MissingData(&'static str),
172
    /// A peer did not advertise its supported key exchange groups.
173
    MissingKeyExchange,
174
    /// A peer sent an empty list of signature schemes
175
    NoSignatureSchemes,
176
    /// Trailing data found for the named handshake payload value
177
    TrailingData(&'static str),
178
    /// A peer sent an unexpected message type.
179
    UnexpectedMessage(&'static str),
180
    /// An unknown TLS protocol was encountered during message decoding.
181
    UnknownProtocolVersion,
182
    /// A peer sent a non-null compression method.
183
    UnsupportedCompression,
184
    /// A peer sent an unknown elliptic curve type.
185
    UnsupportedCurveType,
186
    /// A peer sent an unsupported key exchange algorithm.
187
    UnsupportedKeyExchangeAlgorithm(KeyExchangeAlgorithm),
188
    /// A server sent an empty ticket
189
    EmptyTicketValue,
190
    /// A peer sent an empty list of items, but a non-empty list is required.
191
    ///
192
    /// The argument names the context.
193
    IllegalEmptyList(&'static str),
194
    /// A peer sent an empty value, but a non-empty value is required.
195
    IllegalEmptyValue,
196
    /// A peer sent a message where a given extension type was repeated
197
    DuplicateExtension(u16),
198
    /// A peer sent a message with a PSK offer extension in wrong position
199
    PreSharedKeyIsNotFinalExtension,
200
    /// A server sent a HelloRetryRequest with an unknown extension
201
    UnknownHelloRetryRequestExtension,
202
    /// The peer sent a TLS1.3 Certificate with an unknown extension
203
    UnknownCertificateExtension,
204
}
205
206
impl From<InvalidMessage> for Error {
207
    #[inline]
208
0
    fn from(e: InvalidMessage) -> Self {
209
0
        Self::InvalidMessage(e)
210
0
    }
211
}
212
213
impl From<InvalidMessage> for AlertDescription {
214
0
    fn from(e: InvalidMessage) -> Self {
215
0
        match e {
216
0
            InvalidMessage::PreSharedKeyIsNotFinalExtension => Self::IllegalParameter,
217
0
            InvalidMessage::DuplicateExtension(_) => Self::IllegalParameter,
218
0
            InvalidMessage::UnknownHelloRetryRequestExtension => Self::UnsupportedExtension,
219
0
            _ => Self::DecodeError,
220
        }
221
0
    }
222
}
223
224
#[non_exhaustive]
225
#[allow(missing_docs)]
226
#[derive(Debug, PartialEq, Clone)]
227
/// The set of cases where we failed to make a connection because we thought
228
/// the peer was misbehaving.
229
///
230
/// This is `non_exhaustive`: we might add or stop using items here in minor
231
/// versions.  We also don't document what they mean.  Generally a user of
232
/// rustls shouldn't vary its behaviour on these error codes, and there is
233
/// nothing it can do to improve matters.
234
///
235
/// Please file a bug against rustls if you see `Error::PeerMisbehaved` in
236
/// the wild.
237
pub enum PeerMisbehaved {
238
    AttemptedDowngradeToTls12WhenTls13IsSupported,
239
    BadCertChainExtensions,
240
    DisallowedEncryptedExtension,
241
    DuplicateClientHelloExtensions,
242
    DuplicateEncryptedExtensions,
243
    DuplicateHelloRetryRequestExtensions,
244
    DuplicateNewSessionTicketExtensions,
245
    DuplicateServerHelloExtensions,
246
    DuplicateServerNameTypes,
247
    EarlyDataAttemptedInSecondClientHello,
248
    EarlyDataExtensionWithoutResumption,
249
    EarlyDataOfferedWithVariedCipherSuite,
250
    HandshakeHashVariedAfterRetry,
251
    IllegalHelloRetryRequestWithEmptyCookie,
252
    IllegalHelloRetryRequestWithNoChanges,
253
    IllegalHelloRetryRequestWithOfferedGroup,
254
    IllegalHelloRetryRequestWithUnofferedCipherSuite,
255
    IllegalHelloRetryRequestWithUnofferedNamedGroup,
256
    IllegalHelloRetryRequestWithUnsupportedVersion,
257
    IllegalHelloRetryRequestWithWrongSessionId,
258
    IllegalHelloRetryRequestWithInvalidEch,
259
    IllegalMiddleboxChangeCipherSpec,
260
    IllegalTlsInnerPlaintext,
261
    IncorrectBinder,
262
    InvalidCertCompression,
263
    InvalidMaxEarlyDataSize,
264
    InvalidKeyShare,
265
    KeyEpochWithPendingFragment,
266
    KeyUpdateReceivedInQuicConnection,
267
    MessageInterleavedWithHandshakeMessage,
268
    MissingBinderInPskExtension,
269
    MissingKeyShare,
270
    MissingPskModesExtension,
271
    MissingQuicTransportParameters,
272
    OfferedDuplicateCertificateCompressions,
273
    OfferedDuplicateKeyShares,
274
    OfferedEarlyDataWithOldProtocolVersion,
275
    OfferedEmptyApplicationProtocol,
276
    OfferedIncorrectCompressions,
277
    PskExtensionMustBeLast,
278
    PskExtensionWithMismatchedIdsAndBinders,
279
    RefusedToFollowHelloRetryRequest,
280
    RejectedEarlyDataInterleavedWithHandshakeMessage,
281
    ResumptionAttemptedWithVariedEms,
282
    ResumptionOfferedWithVariedCipherSuite,
283
    ResumptionOfferedWithVariedEms,
284
    ResumptionOfferedWithIncompatibleCipherSuite,
285
    SelectedDifferentCipherSuiteAfterRetry,
286
    SelectedInvalidPsk,
287
    SelectedTls12UsingTls13VersionExtension,
288
    SelectedUnofferedApplicationProtocol,
289
    SelectedUnofferedCertCompression,
290
    SelectedUnofferedCipherSuite,
291
    SelectedUnofferedCompression,
292
    SelectedUnofferedKxGroup,
293
    SelectedUnofferedPsk,
294
    SelectedUnusableCipherSuiteForVersion,
295
    ServerEchoedCompatibilitySessionId,
296
    ServerHelloMustOfferUncompressedEcPoints,
297
    ServerNameDifferedOnRetry,
298
    ServerNameMustContainOneHostName,
299
    SignedKxWithWrongAlgorithm,
300
    SignedHandshakeWithUnadvertisedSigScheme,
301
    TooManyEmptyFragments,
302
    TooManyKeyUpdateRequests,
303
    TooManyRenegotiationRequests,
304
    TooManyWarningAlertsReceived,
305
    TooMuchEarlyDataReceived,
306
    UnexpectedCleartextExtension,
307
    UnsolicitedCertExtension,
308
    UnsolicitedEncryptedExtension,
309
    UnsolicitedSctList,
310
    UnsolicitedServerHelloExtension,
311
    WrongGroupForKeyShare,
312
    UnsolicitedEchExtension,
313
}
314
315
impl From<PeerMisbehaved> for Error {
316
    #[inline]
317
0
    fn from(e: PeerMisbehaved) -> Self {
318
0
        Self::PeerMisbehaved(e)
319
0
    }
320
}
321
322
#[non_exhaustive]
323
#[allow(missing_docs)]
324
#[derive(Debug, PartialEq, Clone)]
325
/// The set of cases where we failed to make a connection because a peer
326
/// doesn't support a TLS version/feature we require.
327
///
328
/// This is `non_exhaustive`: we might add or stop using items here in minor
329
/// versions.
330
pub enum PeerIncompatible {
331
    EcPointsExtensionRequired,
332
    ExtendedMasterSecretExtensionRequired,
333
    IncorrectCertificateTypeExtension,
334
    KeyShareExtensionRequired,
335
    NamedGroupsExtensionRequired,
336
    NoCertificateRequestSignatureSchemesInCommon,
337
    NoCipherSuitesInCommon,
338
    NoEcPointFormatsInCommon,
339
    NoKxGroupsInCommon,
340
    NoSignatureSchemesInCommon,
341
    NullCompressionRequired,
342
    ServerDoesNotSupportTls12Or13,
343
    ServerSentHelloRetryRequestWithUnknownExtension,
344
    ServerTlsVersionIsDisabledByOurConfig,
345
    SignatureAlgorithmsExtensionRequired,
346
    SupportedVersionsExtensionRequired,
347
    Tls12NotOffered,
348
    Tls12NotOfferedOrEnabled,
349
    Tls13RequiredForQuic,
350
    UncompressedEcPointsRequired,
351
    UnsolicitedCertificateTypeExtension,
352
    ServerRejectedEncryptedClientHello(Option<Vec<EchConfigPayload>>),
353
}
354
355
impl From<PeerIncompatible> for Error {
356
    #[inline]
357
0
    fn from(e: PeerIncompatible) -> Self {
358
0
        Self::PeerIncompatible(e)
359
0
    }
360
}
361
362
#[non_exhaustive]
363
#[derive(Debug, Clone)]
364
/// The ways in which certificate validators can express errors.
365
///
366
/// Note that the rustls TLS protocol code interprets specifically these
367
/// error codes to send specific TLS alerts.  Therefore, if a
368
/// custom certificate validator uses incorrect errors the library as
369
/// a whole will send alerts that do not match the standard (this is usually
370
/// a minor issue, but could be misleading).
371
pub enum CertificateError {
372
    /// The certificate is not correctly encoded.
373
    BadEncoding,
374
375
    /// The current time is after the `notAfter` time in the certificate.
376
    Expired,
377
378
    /// The current time is after the `notAfter` time in the certificate.
379
    ///
380
    /// This variant is semantically the same as `Expired`, but includes
381
    /// extra data to improve error reports.
382
    ExpiredContext {
383
        /// The validation time.
384
        time: UnixTime,
385
        /// The `notAfter` time of the certificate.
386
        not_after: UnixTime,
387
    },
388
389
    /// The current time is before the `notBefore` time in the certificate.
390
    NotValidYet,
391
392
    /// The current time is before the `notBefore` time in the certificate.
393
    ///
394
    /// This variant is semantically the same as `NotValidYet`, but includes
395
    /// extra data to improve error reports.
396
    NotValidYetContext {
397
        /// The validation time.
398
        time: UnixTime,
399
        /// The `notBefore` time of the certificate.
400
        not_before: UnixTime,
401
    },
402
403
    /// The certificate has been revoked.
404
    Revoked,
405
406
    /// The certificate contains an extension marked critical, but it was
407
    /// not processed by the certificate validator.
408
    UnhandledCriticalExtension,
409
410
    /// The certificate chain is not issued by a known root certificate.
411
    UnknownIssuer,
412
413
    /// The certificate's revocation status could not be determined.
414
    UnknownRevocationStatus,
415
416
    /// The certificate's revocation status could not be determined, because the CRL is expired.
417
    ExpiredRevocationList,
418
419
    /// The certificate's revocation status could not be determined, because the CRL is expired.
420
    ///
421
    /// This variant is semantically the same as `ExpiredRevocationList`, but includes
422
    /// extra data to improve error reports.
423
    ExpiredRevocationListContext {
424
        /// The validation time.
425
        time: UnixTime,
426
        /// The nextUpdate time of the CRL.
427
        next_update: UnixTime,
428
    },
429
430
    /// A certificate is not correctly signed by the key of its alleged
431
    /// issuer.
432
    BadSignature,
433
434
    /// A signature inside a certificate or on a handshake was made with an unsupported algorithm.
435
    #[deprecated(
436
        since = "0.23.29",
437
        note = "use `UnsupportedSignatureAlgorithmContext` instead"
438
    )]
439
    UnsupportedSignatureAlgorithm,
440
441
    /// A signature inside a certificate or on a handshake was made with an unsupported algorithm.
442
    UnsupportedSignatureAlgorithmContext {
443
        /// The signature algorithm OID that was unsupported.
444
        signature_algorithm_id: Vec<u8>,
445
        /// Supported algorithms that were available for signature verification.
446
        supported_algorithms: Vec<AlgorithmIdentifier>,
447
    },
448
449
    /// A signature was made with an algorithm that doesn't match the relevant public key.
450
    UnsupportedSignatureAlgorithmForPublicKeyContext {
451
        /// The signature algorithm OID.
452
        signature_algorithm_id: Vec<u8>,
453
        /// The public key algorithm OID.
454
        public_key_algorithm_id: Vec<u8>,
455
    },
456
457
    /// The subject names in an end-entity certificate do not include
458
    /// the expected name.
459
    NotValidForName,
460
461
    /// The subject names in an end-entity certificate do not include
462
    /// the expected name.
463
    ///
464
    /// This variant is semantically the same as `NotValidForName`, but includes
465
    /// extra data to improve error reports.
466
    NotValidForNameContext {
467
        /// Expected server name.
468
        expected: ServerName<'static>,
469
470
        /// The names presented in the end entity certificate.
471
        ///
472
        /// These are the subject names as present in the leaf certificate and may contain DNS names
473
        /// with or without a wildcard label as well as IP address names.
474
        presented: Vec<String>,
475
    },
476
477
    /// The certificate is being used for a different purpose than allowed.
478
    InvalidPurpose,
479
480
    /// The certificate is being used for a different purpose than allowed.
481
    ///
482
    /// This variant is semantically the same as `InvalidPurpose`, but includes
483
    /// extra data to improve error reports.
484
    InvalidPurposeContext {
485
        /// Extended key purpose that was required by the application.
486
        required: ExtendedKeyPurpose,
487
        /// Extended key purposes that were presented in the peer's certificate.
488
        presented: Vec<ExtendedKeyPurpose>,
489
    },
490
491
    /// The OCSP response provided to the verifier was invalid.
492
    ///
493
    /// This should be returned from [`ServerCertVerifier::verify_server_cert()`]
494
    /// when a verifier checks its `ocsp_response` parameter and finds it invalid.
495
    ///
496
    /// This maps to [`AlertDescription::BadCertificateStatusResponse`].
497
    ///
498
    /// [`ServerCertVerifier::verify_server_cert()`]: crate::client::danger::ServerCertVerifier::verify_server_cert
499
    InvalidOcspResponse,
500
501
    /// The certificate is valid, but the handshake is rejected for other
502
    /// reasons.
503
    ApplicationVerificationFailure,
504
505
    /// Any other error.
506
    ///
507
    /// This can be used by custom verifiers to expose the underlying error
508
    /// (where they are not better described by the more specific errors
509
    /// above).
510
    ///
511
    /// It is also used by the default verifier in case its error is
512
    /// not covered by the above common cases.
513
    ///
514
    /// Enums holding this variant will never compare equal to each other.
515
    Other(OtherError),
516
}
517
518
impl PartialEq<Self> for CertificateError {
519
0
    fn eq(&self, other: &Self) -> bool {
520
        use CertificateError::*;
521
        #[allow(clippy::match_like_matches_macro)]
522
0
        match (self, other) {
523
0
            (BadEncoding, BadEncoding) => true,
524
0
            (Expired, Expired) => true,
525
            (
526
                ExpiredContext {
527
0
                    time: left_time,
528
0
                    not_after: left_not_after,
529
                },
530
                ExpiredContext {
531
0
                    time: right_time,
532
0
                    not_after: right_not_after,
533
                },
534
0
            ) => (left_time, left_not_after) == (right_time, right_not_after),
535
0
            (NotValidYet, NotValidYet) => true,
536
            (
537
                NotValidYetContext {
538
0
                    time: left_time,
539
0
                    not_before: left_not_before,
540
                },
541
                NotValidYetContext {
542
0
                    time: right_time,
543
0
                    not_before: right_not_before,
544
                },
545
0
            ) => (left_time, left_not_before) == (right_time, right_not_before),
546
0
            (Revoked, Revoked) => true,
547
0
            (UnhandledCriticalExtension, UnhandledCriticalExtension) => true,
548
0
            (UnknownIssuer, UnknownIssuer) => true,
549
0
            (BadSignature, BadSignature) => true,
550
            #[allow(deprecated)]
551
0
            (UnsupportedSignatureAlgorithm, UnsupportedSignatureAlgorithm) => true,
552
            (
553
                UnsupportedSignatureAlgorithmContext {
554
0
                    signature_algorithm_id: left_signature_algorithm_id,
555
0
                    supported_algorithms: left_supported_algorithms,
556
                },
557
                UnsupportedSignatureAlgorithmContext {
558
0
                    signature_algorithm_id: right_signature_algorithm_id,
559
0
                    supported_algorithms: right_supported_algorithms,
560
                },
561
            ) => {
562
0
                (left_signature_algorithm_id, left_supported_algorithms)
563
0
                    == (right_signature_algorithm_id, right_supported_algorithms)
564
            }
565
            (
566
                UnsupportedSignatureAlgorithmForPublicKeyContext {
567
0
                    signature_algorithm_id: left_signature_algorithm_id,
568
0
                    public_key_algorithm_id: left_public_key_algorithm_id,
569
                },
570
                UnsupportedSignatureAlgorithmForPublicKeyContext {
571
0
                    signature_algorithm_id: right_signature_algorithm_id,
572
0
                    public_key_algorithm_id: right_public_key_algorithm_id,
573
                },
574
            ) => {
575
0
                (left_signature_algorithm_id, left_public_key_algorithm_id)
576
0
                    == (right_signature_algorithm_id, right_public_key_algorithm_id)
577
            }
578
0
            (NotValidForName, NotValidForName) => true,
579
            (
580
                NotValidForNameContext {
581
0
                    expected: left_expected,
582
0
                    presented: left_presented,
583
                },
584
                NotValidForNameContext {
585
0
                    expected: right_expected,
586
0
                    presented: right_presented,
587
                },
588
0
            ) => (left_expected, left_presented) == (right_expected, right_presented),
589
0
            (InvalidPurpose, InvalidPurpose) => true,
590
            (
591
                InvalidPurposeContext {
592
0
                    required: left_required,
593
0
                    presented: left_presented,
594
                },
595
                InvalidPurposeContext {
596
0
                    required: right_required,
597
0
                    presented: right_presented,
598
                },
599
0
            ) => (left_required, left_presented) == (right_required, right_presented),
600
0
            (InvalidOcspResponse, InvalidOcspResponse) => true,
601
0
            (ApplicationVerificationFailure, ApplicationVerificationFailure) => true,
602
0
            (UnknownRevocationStatus, UnknownRevocationStatus) => true,
603
0
            (ExpiredRevocationList, ExpiredRevocationList) => true,
604
            (
605
                ExpiredRevocationListContext {
606
0
                    time: left_time,
607
0
                    next_update: left_next_update,
608
                },
609
                ExpiredRevocationListContext {
610
0
                    time: right_time,
611
0
                    next_update: right_next_update,
612
                },
613
0
            ) => (left_time, left_next_update) == (right_time, right_next_update),
614
0
            _ => false,
615
        }
616
0
    }
617
}
618
619
// The following mapping are heavily referenced in:
620
// * [OpenSSL Implementation](https://github.com/openssl/openssl/blob/45bb98bfa223efd3258f445ad443f878011450f0/ssl/statem/statem_lib.c#L1434)
621
// * [BoringSSL Implementation](https://github.com/google/boringssl/blob/583c60bd4bf76d61b2634a58bcda99a92de106cb/ssl/ssl_x509.cc#L1323)
622
impl From<CertificateError> for AlertDescription {
623
0
    fn from(e: CertificateError) -> Self {
624
        use CertificateError::*;
625
0
        match e {
626
            BadEncoding
627
            | UnhandledCriticalExtension
628
            | NotValidForName
629
0
            | NotValidForNameContext { .. } => Self::BadCertificate,
630
            // RFC 5246/RFC 8446
631
            // certificate_expired
632
            //  A certificate has expired or **is not currently valid**.
633
            Expired | ExpiredContext { .. } | NotValidYet | NotValidYetContext { .. } => {
634
0
                Self::CertificateExpired
635
            }
636
0
            Revoked => Self::CertificateRevoked,
637
            // OpenSSL, BoringSSL and AWS-LC all generate an Unknown CA alert for
638
            // the case where revocation status can not be determined, so we do the same here.
639
            UnknownIssuer
640
            | UnknownRevocationStatus
641
            | ExpiredRevocationList
642
0
            | ExpiredRevocationListContext { .. } => Self::UnknownCA,
643
0
            InvalidOcspResponse => Self::BadCertificateStatusResponse,
644
            #[allow(deprecated)]
645
            BadSignature
646
            | UnsupportedSignatureAlgorithm
647
            | UnsupportedSignatureAlgorithmContext { .. }
648
0
            | UnsupportedSignatureAlgorithmForPublicKeyContext { .. } => Self::DecryptError,
649
0
            InvalidPurpose | InvalidPurposeContext { .. } => Self::UnsupportedCertificate,
650
0
            ApplicationVerificationFailure => Self::AccessDenied,
651
            // RFC 5246/RFC 8446
652
            // certificate_unknown
653
            //  Some other (unspecified) issue arose in processing the
654
            //  certificate, rendering it unacceptable.
655
0
            Other(..) => Self::CertificateUnknown,
656
        }
657
0
    }
658
}
659
660
impl fmt::Display for CertificateError {
661
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
662
0
        match self {
663
            #[cfg(feature = "std")]
664
            Self::NotValidForNameContext {
665
0
                expected,
666
0
                presented,
667
            } => {
668
0
                write!(
669
0
                    f,
670
0
                    "certificate not valid for name {:?}; certificate ",
671
0
                    expected.to_str()
672
0
                )?;
673
674
0
                match presented.as_slice() {
675
0
                    &[] => write!(
676
0
                        f,
677
0
                        "is not valid for any names (according to its subjectAltName extension)"
678
                    ),
679
0
                    [one] => write!(f, "is only valid for {one}"),
680
0
                    many => {
681
0
                        write!(f, "is only valid for ")?;
682
683
0
                        let n = many.len();
684
0
                        let all_but_last = &many[..n - 1];
685
0
                        let last = &many[n - 1];
686
687
0
                        for (i, name) in all_but_last.iter().enumerate() {
688
0
                            write!(f, "{name}")?;
689
0
                            if i < n - 2 {
690
0
                                write!(f, ", ")?;
691
0
                            }
692
                        }
693
0
                        write!(f, " or {last}")
694
                    }
695
                }
696
            }
697
698
0
            Self::ExpiredContext { time, not_after } => write!(
699
0
                f,
700
0
                "certificate expired: verification time {} (UNIX), \
701
0
                 but certificate is not valid after {} \
702
0
                 ({} seconds ago)",
703
0
                time.as_secs(),
704
0
                not_after.as_secs(),
705
0
                time.as_secs()
706
0
                    .saturating_sub(not_after.as_secs())
707
            ),
708
709
0
            Self::NotValidYetContext { time, not_before } => write!(
710
0
                f,
711
0
                "certificate not valid yet: verification time {} (UNIX), \
712
0
                 but certificate is not valid before {} \
713
0
                 ({} seconds in future)",
714
0
                time.as_secs(),
715
0
                not_before.as_secs(),
716
0
                not_before
717
0
                    .as_secs()
718
0
                    .saturating_sub(time.as_secs())
719
            ),
720
721
0
            Self::ExpiredRevocationListContext { time, next_update } => write!(
722
0
                f,
723
0
                "certificate revocation list expired: \
724
0
                 verification time {} (UNIX), \
725
0
                 but CRL is not valid after {} \
726
0
                 ({} seconds ago)",
727
0
                time.as_secs(),
728
0
                next_update.as_secs(),
729
0
                time.as_secs()
730
0
                    .saturating_sub(next_update.as_secs())
731
            ),
732
733
            Self::InvalidPurposeContext {
734
0
                required,
735
0
                presented,
736
            } => {
737
0
                write!(
738
0
                    f,
739
0
                    "certificate does not allow extended key usage for {required}, allows "
740
0
                )?;
741
0
                for (i, eku) in presented.iter().enumerate() {
742
0
                    if i > 0 {
743
0
                        write!(f, ", ")?;
744
0
                    }
745
0
                    write!(f, "{eku}")?;
746
                }
747
0
                Ok(())
748
            }
749
750
0
            other => write!(f, "{other:?}"),
751
        }
752
0
    }
753
}
754
755
impl From<CertificateError> for Error {
756
    #[inline]
757
0
    fn from(e: CertificateError) -> Self {
758
0
        Self::InvalidCertificate(e)
759
0
    }
760
}
761
762
/// Extended Key Usage (EKU) purpose values.
763
///
764
/// These are usually represented as OID values in the certificate's extension (if present), but
765
/// we represent the values that are most relevant to rustls as named enum variants.
766
#[derive(Clone, Debug, Eq, PartialEq)]
767
pub enum ExtendedKeyPurpose {
768
    /// Client authentication
769
    ClientAuth,
770
    /// Server authentication
771
    ServerAuth,
772
    /// Other EKU values
773
    ///
774
    /// Represented here as a `Vec<usize>` for human readability.
775
    Other(Vec<usize>),
776
}
777
778
impl ExtendedKeyPurpose {
779
0
    pub(crate) fn for_values(values: impl Iterator<Item = usize>) -> Self {
780
0
        let values = values.collect::<Vec<_>>();
781
0
        match &*values {
782
0
            KeyUsage::CLIENT_AUTH_REPR => Self::ClientAuth,
783
0
            KeyUsage::SERVER_AUTH_REPR => Self::ServerAuth,
784
0
            _ => Self::Other(values),
785
        }
786
0
    }
Unexecuted instantiation: <rustls::error::ExtendedKeyPurpose>::for_values::<alloc::vec::into_iter::IntoIter<usize>>
Unexecuted instantiation: <rustls::error::ExtendedKeyPurpose>::for_values::<webpki::verify_cert::OidDecoder>
787
}
788
789
impl fmt::Display for ExtendedKeyPurpose {
790
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
791
0
        match self {
792
0
            Self::ClientAuth => write!(f, "client authentication"),
793
0
            Self::ServerAuth => write!(f, "server authentication"),
794
0
            Self::Other(values) => {
795
0
                for (i, value) in values.iter().enumerate() {
796
0
                    if i > 0 {
797
0
                        write!(f, ", ")?;
798
0
                    }
799
0
                    write!(f, "{value}")?;
800
                }
801
0
                Ok(())
802
            }
803
        }
804
0
    }
805
}
806
807
#[non_exhaustive]
808
#[derive(Debug, Clone)]
809
/// The ways in which a certificate revocation list (CRL) can be invalid.
810
pub enum CertRevocationListError {
811
    /// The CRL had a bad signature from its issuer.
812
    BadSignature,
813
814
    /// The CRL had an unsupported signature from its issuer.
815
    #[deprecated(
816
        since = "0.23.29",
817
        note = "use `UnsupportedSignatureAlgorithmContext` instead"
818
    )]
819
    UnsupportedSignatureAlgorithm,
820
821
    /// A signature inside a certificate or on a handshake was made with an unsupported algorithm.
822
    UnsupportedSignatureAlgorithmContext {
823
        /// The signature algorithm OID that was unsupported.
824
        signature_algorithm_id: Vec<u8>,
825
        /// Supported algorithms that were available for signature verification.
826
        supported_algorithms: Vec<AlgorithmIdentifier>,
827
    },
828
829
    /// A signature was made with an algorithm that doesn't match the relevant public key.
830
    UnsupportedSignatureAlgorithmForPublicKeyContext {
831
        /// The signature algorithm OID.
832
        signature_algorithm_id: Vec<u8>,
833
        /// The public key algorithm OID.
834
        public_key_algorithm_id: Vec<u8>,
835
    },
836
837
    /// The CRL contained an invalid CRL number.
838
    InvalidCrlNumber,
839
840
    /// The CRL contained a revoked certificate with an invalid serial number.
841
    InvalidRevokedCertSerialNumber,
842
843
    /// The CRL issuer does not specify the cRLSign key usage.
844
    IssuerInvalidForCrl,
845
846
    /// The CRL is invalid for some other reason.
847
    ///
848
    /// Enums holding this variant will never compare equal to each other.
849
    Other(OtherError),
850
851
    /// The CRL is not correctly encoded.
852
    ParseError,
853
854
    /// The CRL is not a v2 X.509 CRL.
855
    UnsupportedCrlVersion,
856
857
    /// The CRL, or a revoked certificate in the CRL, contained an unsupported critical extension.
858
    UnsupportedCriticalExtension,
859
860
    /// The CRL is an unsupported delta CRL, containing only changes relative to another CRL.
861
    UnsupportedDeltaCrl,
862
863
    /// The CRL is an unsupported indirect CRL, containing revoked certificates issued by a CA
864
    /// other than the issuer of the CRL.
865
    UnsupportedIndirectCrl,
866
867
    /// The CRL contained a revoked certificate with an unsupported revocation reason.
868
    /// See RFC 5280 Section 5.3.1[^1] for a list of supported revocation reasons.
869
    ///
870
    /// [^1]: <https://www.rfc-editor.org/rfc/rfc5280#section-5.3.1>
871
    UnsupportedRevocationReason,
872
}
873
874
impl PartialEq<Self> for CertRevocationListError {
875
0
    fn eq(&self, other: &Self) -> bool {
876
        use CertRevocationListError::*;
877
        #[allow(clippy::match_like_matches_macro)]
878
0
        match (self, other) {
879
0
            (BadSignature, BadSignature) => true,
880
            #[allow(deprecated)]
881
0
            (UnsupportedSignatureAlgorithm, UnsupportedSignatureAlgorithm) => true,
882
            (
883
                UnsupportedSignatureAlgorithmContext {
884
0
                    signature_algorithm_id: left_signature_algorithm_id,
885
0
                    supported_algorithms: left_supported_algorithms,
886
                },
887
                UnsupportedSignatureAlgorithmContext {
888
0
                    signature_algorithm_id: right_signature_algorithm_id,
889
0
                    supported_algorithms: right_supported_algorithms,
890
                },
891
            ) => {
892
0
                (left_signature_algorithm_id, left_supported_algorithms)
893
0
                    == (right_signature_algorithm_id, right_supported_algorithms)
894
            }
895
            (
896
                UnsupportedSignatureAlgorithmForPublicKeyContext {
897
0
                    signature_algorithm_id: left_signature_algorithm_id,
898
0
                    public_key_algorithm_id: left_public_key_algorithm_id,
899
                },
900
                UnsupportedSignatureAlgorithmForPublicKeyContext {
901
0
                    signature_algorithm_id: right_signature_algorithm_id,
902
0
                    public_key_algorithm_id: right_public_key_algorithm_id,
903
                },
904
            ) => {
905
0
                (left_signature_algorithm_id, left_public_key_algorithm_id)
906
0
                    == (right_signature_algorithm_id, right_public_key_algorithm_id)
907
            }
908
0
            (InvalidCrlNumber, InvalidCrlNumber) => true,
909
0
            (InvalidRevokedCertSerialNumber, InvalidRevokedCertSerialNumber) => true,
910
0
            (IssuerInvalidForCrl, IssuerInvalidForCrl) => true,
911
0
            (ParseError, ParseError) => true,
912
0
            (UnsupportedCrlVersion, UnsupportedCrlVersion) => true,
913
0
            (UnsupportedCriticalExtension, UnsupportedCriticalExtension) => true,
914
0
            (UnsupportedDeltaCrl, UnsupportedDeltaCrl) => true,
915
0
            (UnsupportedIndirectCrl, UnsupportedIndirectCrl) => true,
916
0
            (UnsupportedRevocationReason, UnsupportedRevocationReason) => true,
917
0
            _ => false,
918
        }
919
0
    }
920
}
921
922
impl From<CertRevocationListError> for Error {
923
    #[inline]
924
0
    fn from(e: CertRevocationListError) -> Self {
925
0
        Self::InvalidCertRevocationList(e)
926
0
    }
927
}
928
929
#[non_exhaustive]
930
#[derive(Debug, Clone, Eq, PartialEq)]
931
/// An error that occurred while handling Encrypted Client Hello (ECH).
932
pub enum EncryptedClientHelloError {
933
    /// The provided ECH configuration list was invalid.
934
    InvalidConfigList,
935
    /// No compatible ECH configuration.
936
    NoCompatibleConfig,
937
    /// The client configuration has server name indication (SNI) disabled.
938
    SniRequired,
939
}
940
941
impl From<EncryptedClientHelloError> for Error {
942
    #[inline]
943
0
    fn from(e: EncryptedClientHelloError) -> Self {
944
0
        Self::InvalidEncryptedClientHello(e)
945
0
    }
946
}
947
948
0
fn join<T: fmt::Debug>(items: &[T]) -> String {
949
0
    items
950
0
        .iter()
951
0
        .map(|x| format!("{x:?}"))
Unexecuted instantiation: rustls::error::join::<rustls::enums::ContentType>::{closure#0}
Unexecuted instantiation: rustls::error::join::<rustls::enums::HandshakeType>::{closure#0}
952
0
        .collect::<Vec<String>>()
953
0
        .join(" or ")
954
0
}
Unexecuted instantiation: rustls::error::join::<rustls::enums::ContentType>
Unexecuted instantiation: rustls::error::join::<rustls::enums::HandshakeType>
955
956
impl fmt::Display for Error {
957
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
958
0
        match self {
959
            Self::InappropriateMessage {
960
0
                expect_types,
961
0
                got_type,
962
0
            } => write!(
963
0
                f,
964
0
                "received unexpected message: got {:?} when expecting {}",
965
                got_type,
966
0
                join::<ContentType>(expect_types)
967
            ),
968
            Self::InappropriateHandshakeMessage {
969
0
                expect_types,
970
0
                got_type,
971
0
            } => write!(
972
0
                f,
973
0
                "received unexpected handshake message: got {:?} when expecting {}",
974
                got_type,
975
0
                join::<HandshakeType>(expect_types)
976
            ),
977
0
            Self::InvalidMessage(typ) => {
978
0
                write!(f, "received corrupt message of type {typ:?}")
979
            }
980
0
            Self::PeerIncompatible(why) => write!(f, "peer is incompatible: {why:?}"),
981
0
            Self::PeerMisbehaved(why) => write!(f, "peer misbehaved: {why:?}"),
982
0
            Self::AlertReceived(alert) => write!(f, "received fatal alert: {alert:?}"),
983
0
            Self::InvalidCertificate(err) => {
984
0
                write!(f, "invalid peer certificate: {err}")
985
            }
986
0
            Self::InvalidCertRevocationList(err) => {
987
0
                write!(f, "invalid certificate revocation list: {err:?}")
988
            }
989
0
            Self::NoCertificatesPresented => write!(f, "peer sent no certificates"),
990
0
            Self::UnsupportedNameType => write!(f, "presented server name type wasn't supported"),
991
0
            Self::DecryptError => write!(f, "cannot decrypt peer's message"),
992
0
            Self::InvalidEncryptedClientHello(err) => {
993
0
                write!(f, "encrypted client hello failure: {err:?}")
994
            }
995
0
            Self::EncryptError => write!(f, "cannot encrypt message"),
996
0
            Self::PeerSentOversizedRecord => write!(f, "peer sent excess record size"),
997
0
            Self::HandshakeNotComplete => write!(f, "handshake not complete"),
998
0
            Self::NoApplicationProtocol => write!(f, "peer doesn't support any known protocol"),
999
0
            Self::FailedToGetCurrentTime => write!(f, "failed to get current time"),
1000
0
            Self::FailedToGetRandomBytes => write!(f, "failed to get random bytes"),
1001
            Self::BadMaxFragmentSize => {
1002
0
                write!(f, "the supplied max_fragment_size was too small or large")
1003
            }
1004
0
            Self::InconsistentKeys(why) => {
1005
0
                write!(f, "keys may not be consistent: {why:?}")
1006
            }
1007
0
            Self::General(err) => write!(f, "unexpected error: {err}"),
1008
0
            Self::Other(err) => write!(f, "other error: {err}"),
1009
        }
1010
0
    }
1011
}
1012
1013
#[cfg(feature = "std")]
1014
impl From<SystemTimeError> for Error {
1015
    #[inline]
1016
0
    fn from(_: SystemTimeError) -> Self {
1017
0
        Self::FailedToGetCurrentTime
1018
0
    }
1019
}
1020
1021
#[cfg(feature = "std")]
1022
impl std::error::Error for Error {}
1023
1024
impl From<rand::GetRandomFailed> for Error {
1025
0
    fn from(_: rand::GetRandomFailed) -> Self {
1026
0
        Self::FailedToGetRandomBytes
1027
0
    }
1028
}
1029
1030
mod other_error {
1031
    use core::fmt;
1032
    #[cfg(feature = "std")]
1033
    use std::error::Error as StdError;
1034
1035
    use super::Error;
1036
    #[cfg(feature = "std")]
1037
    use crate::sync::Arc;
1038
1039
    /// Any other error that cannot be expressed by a more specific [`Error`] variant.
1040
    ///
1041
    /// For example, an `OtherError` could be produced by a custom crypto provider
1042
    /// exposing a provider specific error.
1043
    ///
1044
    /// Enums holding this type will never compare equal to each other.
1045
    #[derive(Debug, Clone)]
1046
    pub struct OtherError(#[cfg(feature = "std")] pub Arc<dyn StdError + Send + Sync>);
1047
1048
    impl PartialEq<Self> for OtherError {
1049
0
        fn eq(&self, _other: &Self) -> bool {
1050
0
            false
1051
0
        }
1052
    }
1053
1054
    impl From<OtherError> for Error {
1055
0
        fn from(value: OtherError) -> Self {
1056
0
            Self::Other(value)
1057
0
        }
1058
    }
1059
1060
    impl fmt::Display for OtherError {
1061
0
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1062
            #[cfg(feature = "std")]
1063
            {
1064
0
                write!(f, "{}", self.0)
1065
            }
1066
            #[cfg(not(feature = "std"))]
1067
            {
1068
                f.write_str("no further information available")
1069
            }
1070
0
        }
1071
    }
1072
1073
    #[cfg(feature = "std")]
1074
    impl StdError for OtherError {
1075
0
        fn source(&self) -> Option<&(dyn StdError + 'static)> {
1076
0
            Some(self.0.as_ref())
1077
0
        }
1078
    }
1079
}
1080
1081
pub use other_error::OtherError;
1082
1083
#[cfg(test)]
1084
mod tests {
1085
    use core::time::Duration;
1086
    use std::prelude::v1::*;
1087
    use std::{println, vec};
1088
1089
    use pki_types::ServerName;
1090
1091
    use super::{
1092
        CertRevocationListError, Error, InconsistentKeys, InvalidMessage, OtherError, UnixTime,
1093
    };
1094
    #[cfg(feature = "std")]
1095
    use crate::sync::Arc;
1096
1097
    #[test]
1098
    fn certificate_error_equality() {
1099
        use super::CertificateError::*;
1100
        assert_eq!(BadEncoding, BadEncoding);
1101
        assert_eq!(Expired, Expired);
1102
        let context = ExpiredContext {
1103
            time: UnixTime::since_unix_epoch(Duration::from_secs(1234)),
1104
            not_after: UnixTime::since_unix_epoch(Duration::from_secs(123)),
1105
        };
1106
        assert_eq!(context, context);
1107
        assert_ne!(
1108
            context,
1109
            ExpiredContext {
1110
                time: UnixTime::since_unix_epoch(Duration::from_secs(12345)),
1111
                not_after: UnixTime::since_unix_epoch(Duration::from_secs(123)),
1112
            }
1113
        );
1114
        assert_ne!(
1115
            context,
1116
            ExpiredContext {
1117
                time: UnixTime::since_unix_epoch(Duration::from_secs(1234)),
1118
                not_after: UnixTime::since_unix_epoch(Duration::from_secs(1234)),
1119
            }
1120
        );
1121
        assert_eq!(NotValidYet, NotValidYet);
1122
        let context = NotValidYetContext {
1123
            time: UnixTime::since_unix_epoch(Duration::from_secs(123)),
1124
            not_before: UnixTime::since_unix_epoch(Duration::from_secs(1234)),
1125
        };
1126
        assert_eq!(context, context);
1127
        assert_ne!(
1128
            context,
1129
            NotValidYetContext {
1130
                time: UnixTime::since_unix_epoch(Duration::from_secs(1234)),
1131
                not_before: UnixTime::since_unix_epoch(Duration::from_secs(1234)),
1132
            }
1133
        );
1134
        assert_ne!(
1135
            context,
1136
            NotValidYetContext {
1137
                time: UnixTime::since_unix_epoch(Duration::from_secs(123)),
1138
                not_before: UnixTime::since_unix_epoch(Duration::from_secs(12345)),
1139
            }
1140
        );
1141
        assert_eq!(Revoked, Revoked);
1142
        assert_eq!(UnhandledCriticalExtension, UnhandledCriticalExtension);
1143
        assert_eq!(UnknownIssuer, UnknownIssuer);
1144
        assert_eq!(ExpiredRevocationList, ExpiredRevocationList);
1145
        assert_eq!(UnknownRevocationStatus, UnknownRevocationStatus);
1146
        let context = ExpiredRevocationListContext {
1147
            time: UnixTime::since_unix_epoch(Duration::from_secs(1234)),
1148
            next_update: UnixTime::since_unix_epoch(Duration::from_secs(123)),
1149
        };
1150
        assert_eq!(context, context);
1151
        assert_ne!(
1152
            context,
1153
            ExpiredRevocationListContext {
1154
                time: UnixTime::since_unix_epoch(Duration::from_secs(12345)),
1155
                next_update: UnixTime::since_unix_epoch(Duration::from_secs(123)),
1156
            }
1157
        );
1158
        assert_ne!(
1159
            context,
1160
            ExpiredRevocationListContext {
1161
                time: UnixTime::since_unix_epoch(Duration::from_secs(1234)),
1162
                next_update: UnixTime::since_unix_epoch(Duration::from_secs(1234)),
1163
            }
1164
        );
1165
        assert_eq!(BadSignature, BadSignature);
1166
        #[allow(deprecated)]
1167
        {
1168
            assert_eq!(UnsupportedSignatureAlgorithm, UnsupportedSignatureAlgorithm);
1169
        }
1170
        assert_eq!(
1171
            UnsupportedSignatureAlgorithmContext {
1172
                signature_algorithm_id: vec![1, 2, 3],
1173
                supported_algorithms: vec![]
1174
            },
1175
            UnsupportedSignatureAlgorithmContext {
1176
                signature_algorithm_id: vec![1, 2, 3],
1177
                supported_algorithms: vec![]
1178
            }
1179
        );
1180
        assert_eq!(
1181
            UnsupportedSignatureAlgorithmForPublicKeyContext {
1182
                signature_algorithm_id: vec![1, 2, 3],
1183
                public_key_algorithm_id: vec![4, 5, 6]
1184
            },
1185
            UnsupportedSignatureAlgorithmForPublicKeyContext {
1186
                signature_algorithm_id: vec![1, 2, 3],
1187
                public_key_algorithm_id: vec![4, 5, 6]
1188
            }
1189
        );
1190
        assert_eq!(NotValidForName, NotValidForName);
1191
        let context = NotValidForNameContext {
1192
            expected: ServerName::try_from("example.com")
1193
                .unwrap()
1194
                .to_owned(),
1195
            presented: vec!["other.com".into()],
1196
        };
1197
        assert_eq!(context, context);
1198
        assert_ne!(
1199
            context,
1200
            NotValidForNameContext {
1201
                expected: ServerName::try_from("example.com")
1202
                    .unwrap()
1203
                    .to_owned(),
1204
                presented: vec![]
1205
            }
1206
        );
1207
        assert_ne!(
1208
            context,
1209
            NotValidForNameContext {
1210
                expected: ServerName::try_from("huh.com")
1211
                    .unwrap()
1212
                    .to_owned(),
1213
                presented: vec!["other.com".into()],
1214
            }
1215
        );
1216
        assert_eq!(InvalidPurpose, InvalidPurpose);
1217
        assert_eq!(
1218
            ApplicationVerificationFailure,
1219
            ApplicationVerificationFailure
1220
        );
1221
        assert_eq!(InvalidOcspResponse, InvalidOcspResponse);
1222
        let other = Other(OtherError(
1223
            #[cfg(feature = "std")]
1224
            Arc::from(Box::from("")),
1225
        ));
1226
        assert_ne!(other, other);
1227
        assert_ne!(BadEncoding, Expired);
1228
    }
1229
1230
    #[test]
1231
    fn crl_error_equality() {
1232
        use super::CertRevocationListError::*;
1233
        assert_eq!(BadSignature, BadSignature);
1234
        #[allow(deprecated)]
1235
        {
1236
            assert_eq!(UnsupportedSignatureAlgorithm, UnsupportedSignatureAlgorithm);
1237
        }
1238
        assert_eq!(
1239
            UnsupportedSignatureAlgorithmContext {
1240
                signature_algorithm_id: vec![1, 2, 3],
1241
                supported_algorithms: vec![]
1242
            },
1243
            UnsupportedSignatureAlgorithmContext {
1244
                signature_algorithm_id: vec![1, 2, 3],
1245
                supported_algorithms: vec![]
1246
            }
1247
        );
1248
        assert_eq!(
1249
            UnsupportedSignatureAlgorithmForPublicKeyContext {
1250
                signature_algorithm_id: vec![1, 2, 3],
1251
                public_key_algorithm_id: vec![4, 5, 6]
1252
            },
1253
            UnsupportedSignatureAlgorithmForPublicKeyContext {
1254
                signature_algorithm_id: vec![1, 2, 3],
1255
                public_key_algorithm_id: vec![4, 5, 6]
1256
            }
1257
        );
1258
        assert_eq!(InvalidCrlNumber, InvalidCrlNumber);
1259
        assert_eq!(
1260
            InvalidRevokedCertSerialNumber,
1261
            InvalidRevokedCertSerialNumber
1262
        );
1263
        assert_eq!(IssuerInvalidForCrl, IssuerInvalidForCrl);
1264
        assert_eq!(ParseError, ParseError);
1265
        assert_eq!(UnsupportedCriticalExtension, UnsupportedCriticalExtension);
1266
        assert_eq!(UnsupportedCrlVersion, UnsupportedCrlVersion);
1267
        assert_eq!(UnsupportedDeltaCrl, UnsupportedDeltaCrl);
1268
        assert_eq!(UnsupportedIndirectCrl, UnsupportedIndirectCrl);
1269
        assert_eq!(UnsupportedRevocationReason, UnsupportedRevocationReason);
1270
        let other = Other(OtherError(
1271
            #[cfg(feature = "std")]
1272
            Arc::from(Box::from("")),
1273
        ));
1274
        assert_ne!(other, other);
1275
        assert_ne!(BadSignature, InvalidCrlNumber);
1276
    }
1277
1278
    #[test]
1279
    #[cfg(feature = "std")]
1280
    fn other_error_equality() {
1281
        let other_error = OtherError(Arc::from(Box::from("")));
1282
        assert_ne!(other_error, other_error);
1283
        let other: Error = other_error.into();
1284
        assert_ne!(other, other);
1285
    }
1286
1287
    #[test]
1288
    fn smoke() {
1289
        use crate::enums::{AlertDescription, ContentType, HandshakeType};
1290
1291
        let all = vec![
1292
            Error::InappropriateMessage {
1293
                expect_types: vec![ContentType::Alert],
1294
                got_type: ContentType::Handshake,
1295
            },
1296
            Error::InappropriateHandshakeMessage {
1297
                expect_types: vec![HandshakeType::ClientHello, HandshakeType::Finished],
1298
                got_type: HandshakeType::ServerHello,
1299
            },
1300
            Error::InvalidMessage(InvalidMessage::InvalidCcs),
1301
            Error::NoCertificatesPresented,
1302
            Error::DecryptError,
1303
            super::PeerIncompatible::Tls12NotOffered.into(),
1304
            super::PeerMisbehaved::UnsolicitedCertExtension.into(),
1305
            Error::AlertReceived(AlertDescription::ExportRestriction),
1306
            super::CertificateError::Expired.into(),
1307
            super::CertificateError::NotValidForNameContext {
1308
                expected: ServerName::try_from("example.com")
1309
                    .unwrap()
1310
                    .to_owned(),
1311
                presented: vec![],
1312
            }
1313
            .into(),
1314
            super::CertificateError::NotValidForNameContext {
1315
                expected: ServerName::try_from("example.com")
1316
                    .unwrap()
1317
                    .to_owned(),
1318
                presented: vec!["DnsName(\"hello.com\")".into()],
1319
            }
1320
            .into(),
1321
            super::CertificateError::NotValidForNameContext {
1322
                expected: ServerName::try_from("example.com")
1323
                    .unwrap()
1324
                    .to_owned(),
1325
                presented: vec![
1326
                    "DnsName(\"hello.com\")".into(),
1327
                    "DnsName(\"goodbye.com\")".into(),
1328
                ],
1329
            }
1330
            .into(),
1331
            super::CertificateError::NotValidYetContext {
1332
                time: UnixTime::since_unix_epoch(Duration::from_secs(300)),
1333
                not_before: UnixTime::since_unix_epoch(Duration::from_secs(320)),
1334
            }
1335
            .into(),
1336
            super::CertificateError::ExpiredContext {
1337
                time: UnixTime::since_unix_epoch(Duration::from_secs(320)),
1338
                not_after: UnixTime::since_unix_epoch(Duration::from_secs(300)),
1339
            }
1340
            .into(),
1341
            super::CertificateError::ExpiredRevocationListContext {
1342
                time: UnixTime::since_unix_epoch(Duration::from_secs(320)),
1343
                next_update: UnixTime::since_unix_epoch(Duration::from_secs(300)),
1344
            }
1345
            .into(),
1346
            super::CertificateError::InvalidOcspResponse.into(),
1347
            Error::General("undocumented error".to_string()),
1348
            Error::FailedToGetCurrentTime,
1349
            Error::FailedToGetRandomBytes,
1350
            Error::HandshakeNotComplete,
1351
            Error::PeerSentOversizedRecord,
1352
            Error::NoApplicationProtocol,
1353
            Error::BadMaxFragmentSize,
1354
            Error::InconsistentKeys(InconsistentKeys::KeyMismatch),
1355
            Error::InconsistentKeys(InconsistentKeys::Unknown),
1356
            Error::InvalidCertRevocationList(CertRevocationListError::BadSignature),
1357
            Error::Other(OtherError(
1358
                #[cfg(feature = "std")]
1359
                Arc::from(Box::from("")),
1360
            )),
1361
        ];
1362
1363
        for err in all {
1364
            println!("{err:?}:");
1365
            println!("  fmt '{err}'");
1366
        }
1367
    }
1368
1369
    #[test]
1370
    fn rand_error_mapping() {
1371
        use super::rand;
1372
        let err: Error = rand::GetRandomFailed.into();
1373
        assert_eq!(err, Error::FailedToGetRandomBytes);
1374
    }
1375
1376
    #[cfg(feature = "std")]
1377
    #[test]
1378
    fn time_error_mapping() {
1379
        use std::time::SystemTime;
1380
1381
        let time_error = SystemTime::UNIX_EPOCH
1382
            .duration_since(SystemTime::now())
1383
            .unwrap_err();
1384
        let err: Error = time_error.into();
1385
        assert_eq!(err, Error::FailedToGetCurrentTime);
1386
    }
1387
}