Skip to main content

rustls/
error.rs

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