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    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
315impl From<PeerMisbehaved> for Error {
316    #[inline]
317    fn from(e: PeerMisbehaved) -> Self {
318        Self::PeerMisbehaved(e)
319    }
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.
330pub 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
355impl From<PeerIncompatible> for Error {
356    #[inline]
357    fn from(e: PeerIncompatible) -> Self {
358        Self::PeerIncompatible(e)
359    }
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).
371pub 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
518impl PartialEq<Self> for CertificateError {
519    fn eq(&self, other: &Self) -> bool {
520        use CertificateError::*;
521        #[allow(clippy::match_like_matches_macro)]
522        match (self, other) {
523            (BadEncoding, BadEncoding) => true,
524            (Expired, Expired) => true,
525            (
526                ExpiredContext {
527                    time: left_time,
528                    not_after: left_not_after,
529                },
530                ExpiredContext {
531                    time: right_time,
532                    not_after: right_not_after,
533                },
534            ) => (left_time, left_not_after) == (right_time, right_not_after),
535            (NotValidYet, NotValidYet) => true,
536            (
537                NotValidYetContext {
538                    time: left_time,
539                    not_before: left_not_before,
540                },
541                NotValidYetContext {
542                    time: right_time,
543                    not_before: right_not_before,
544                },
545            ) => (left_time, left_not_before) == (right_time, right_not_before),
546            (Revoked, Revoked) => true,
547            (UnhandledCriticalExtension, UnhandledCriticalExtension) => true,
548            (UnknownIssuer, UnknownIssuer) => true,
549            (BadSignature, BadSignature) => true,
550            #[allow(deprecated)]
551            (UnsupportedSignatureAlgorithm, UnsupportedSignatureAlgorithm) => true,
552            (
553                UnsupportedSignatureAlgorithmContext {
554                    signature_algorithm_id: left_signature_algorithm_id,
555                    supported_algorithms: left_supported_algorithms,
556                },
557                UnsupportedSignatureAlgorithmContext {
558                    signature_algorithm_id: right_signature_algorithm_id,
559                    supported_algorithms: right_supported_algorithms,
560                },
561            ) => {
562                (left_signature_algorithm_id, left_supported_algorithms)
563                    == (right_signature_algorithm_id, right_supported_algorithms)
564            }
565            (
566                UnsupportedSignatureAlgorithmForPublicKeyContext {
567                    signature_algorithm_id: left_signature_algorithm_id,
568                    public_key_algorithm_id: left_public_key_algorithm_id,
569                },
570                UnsupportedSignatureAlgorithmForPublicKeyContext {
571                    signature_algorithm_id: right_signature_algorithm_id,
572                    public_key_algorithm_id: right_public_key_algorithm_id,
573                },
574            ) => {
575                (left_signature_algorithm_id, left_public_key_algorithm_id)
576                    == (right_signature_algorithm_id, right_public_key_algorithm_id)
577            }
578            (NotValidForName, NotValidForName) => true,
579            (
580                NotValidForNameContext {
581                    expected: left_expected,
582                    presented: left_presented,
583                },
584                NotValidForNameContext {
585                    expected: right_expected,
586                    presented: right_presented,
587                },
588            ) => (left_expected, left_presented) == (right_expected, right_presented),
589            (InvalidPurpose, InvalidPurpose) => true,
590            (
591                InvalidPurposeContext {
592                    required: left_required,
593                    presented: left_presented,
594                },
595                InvalidPurposeContext {
596                    required: right_required,
597                    presented: right_presented,
598                },
599            ) => (left_required, left_presented) == (right_required, right_presented),
600            (InvalidOcspResponse, InvalidOcspResponse) => true,
601            (ApplicationVerificationFailure, ApplicationVerificationFailure) => true,
602            (UnknownRevocationStatus, UnknownRevocationStatus) => true,
603            (ExpiredRevocationList, ExpiredRevocationList) => true,
604            (
605                ExpiredRevocationListContext {
606                    time: left_time,
607                    next_update: left_next_update,
608                },
609                ExpiredRevocationListContext {
610                    time: right_time,
611                    next_update: right_next_update,
612                },
613            ) => (left_time, left_next_update) == (right_time, right_next_update),
614            _ => false,
615        }
616    }
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)
622impl From<CertificateError> for AlertDescription {
623    fn from(e: CertificateError) -> Self {
624        use CertificateError::*;
625        match e {
626            BadEncoding
627            | UnhandledCriticalExtension
628            | NotValidForName
629            | 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                Self::CertificateExpired
635            }
636            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            | ExpiredRevocationListContext { .. } => Self::UnknownCA,
643            InvalidOcspResponse => Self::BadCertificateStatusResponse,
644            #[allow(deprecated)]
645            BadSignature
646            | UnsupportedSignatureAlgorithm
647            | UnsupportedSignatureAlgorithmContext { .. }
648            | UnsupportedSignatureAlgorithmForPublicKeyContext { .. } => Self::DecryptError,
649            InvalidPurpose | InvalidPurposeContext { .. } => Self::UnsupportedCertificate,
650            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            Other(..) => Self::CertificateUnknown,
656        }
657    }
658}
659
660impl fmt::Display for CertificateError {
661    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
662        match self {
663            #[cfg(feature = "std")]
664            Self::NotValidForNameContext {
665                expected,
666                presented,
667            } => {
668                write!(
669                    f,
670                    "certificate not valid for name {:?}; certificate ",
671                    expected.to_str()
672                )?;
673
674                match presented.as_slice() {
675                    &[] => write!(
676                        f,
677                        "is not valid for any names (according to its subjectAltName extension)"
678                    ),
679                    [one] => write!(f, "is only valid for {one}"),
680                    many => {
681                        write!(f, "is only valid for ")?;
682
683                        let n = many.len();
684                        let all_but_last = &many[..n - 1];
685                        let last = &many[n - 1];
686
687                        for (i, name) in all_but_last.iter().enumerate() {
688                            write!(f, "{name}")?;
689                            if i < n - 2 {
690                                write!(f, ", ")?;
691                            }
692                        }
693                        write!(f, " or {last}")
694                    }
695                }
696            }
697
698            Self::ExpiredContext { time, not_after } => write!(
699                f,
700                "certificate expired: verification time {} (UNIX), \
701                 but certificate is not valid after {} \
702                 ({} seconds ago)",
703                time.as_secs(),
704                not_after.as_secs(),
705                time.as_secs()
706                    .saturating_sub(not_after.as_secs())
707            ),
708
709            Self::NotValidYetContext { time, not_before } => write!(
710                f,
711                "certificate not valid yet: verification time {} (UNIX), \
712                 but certificate is not valid before {} \
713                 ({} seconds in future)",
714                time.as_secs(),
715                not_before.as_secs(),
716                not_before
717                    .as_secs()
718                    .saturating_sub(time.as_secs())
719            ),
720
721            Self::ExpiredRevocationListContext { time, next_update } => write!(
722                f,
723                "certificate revocation list expired: \
724                 verification time {} (UNIX), \
725                 but CRL is not valid after {} \
726                 ({} seconds ago)",
727                time.as_secs(),
728                next_update.as_secs(),
729                time.as_secs()
730                    .saturating_sub(next_update.as_secs())
731            ),
732
733            Self::InvalidPurposeContext {
734                required,
735                presented,
736            } => {
737                write!(
738                    f,
739                    "certificate does not allow extended key usage for {required}, allows "
740                )?;
741                for (i, eku) in presented.iter().enumerate() {
742                    if i > 0 {
743                        write!(f, ", ")?;
744                    }
745                    write!(f, "{eku}")?;
746                }
747                Ok(())
748            }
749
750            other => write!(f, "{other:?}"),
751        }
752    }
753}
754
755impl From<CertificateError> for Error {
756    #[inline]
757    fn from(e: CertificateError) -> Self {
758        Self::InvalidCertificate(e)
759    }
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)]
767pub 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
778impl ExtendedKeyPurpose {
779    pub(crate) fn for_values(values: impl Iterator<Item = usize>) -> Self {
780        let values = values.collect::<Vec<_>>();
781        match &*values {
782            KeyUsage::CLIENT_AUTH_REPR => Self::ClientAuth,
783            KeyUsage::SERVER_AUTH_REPR => Self::ServerAuth,
784            _ => Self::Other(values),
785        }
786    }
787}
788
789impl fmt::Display for ExtendedKeyPurpose {
790    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
791        match self {
792            Self::ClientAuth => write!(f, "client authentication"),
793            Self::ServerAuth => write!(f, "server authentication"),
794            Self::Other(values) => {
795                for (i, value) in values.iter().enumerate() {
796                    if i > 0 {
797                        write!(f, ", ")?;
798                    }
799                    write!(f, "{value}")?;
800                }
801                Ok(())
802            }
803        }
804    }
805}
806
807#[non_exhaustive]
808#[derive(Debug, Clone)]
809/// The ways in which a certificate revocation list (CRL) can be invalid.
810pub 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
874impl PartialEq<Self> for CertRevocationListError {
875    fn eq(&self, other: &Self) -> bool {
876        use CertRevocationListError::*;
877        #[allow(clippy::match_like_matches_macro)]
878        match (self, other) {
879            (BadSignature, BadSignature) => true,
880            #[allow(deprecated)]
881            (UnsupportedSignatureAlgorithm, UnsupportedSignatureAlgorithm) => true,
882            (
883                UnsupportedSignatureAlgorithmContext {
884                    signature_algorithm_id: left_signature_algorithm_id,
885                    supported_algorithms: left_supported_algorithms,
886                },
887                UnsupportedSignatureAlgorithmContext {
888                    signature_algorithm_id: right_signature_algorithm_id,
889                    supported_algorithms: right_supported_algorithms,
890                },
891            ) => {
892                (left_signature_algorithm_id, left_supported_algorithms)
893                    == (right_signature_algorithm_id, right_supported_algorithms)
894            }
895            (
896                UnsupportedSignatureAlgorithmForPublicKeyContext {
897                    signature_algorithm_id: left_signature_algorithm_id,
898                    public_key_algorithm_id: left_public_key_algorithm_id,
899                },
900                UnsupportedSignatureAlgorithmForPublicKeyContext {
901                    signature_algorithm_id: right_signature_algorithm_id,
902                    public_key_algorithm_id: right_public_key_algorithm_id,
903                },
904            ) => {
905                (left_signature_algorithm_id, left_public_key_algorithm_id)
906                    == (right_signature_algorithm_id, right_public_key_algorithm_id)
907            }
908            (InvalidCrlNumber, InvalidCrlNumber) => true,
909            (InvalidRevokedCertSerialNumber, InvalidRevokedCertSerialNumber) => true,
910            (IssuerInvalidForCrl, IssuerInvalidForCrl) => true,
911            (ParseError, ParseError) => true,
912            (UnsupportedCrlVersion, UnsupportedCrlVersion) => true,
913            (UnsupportedCriticalExtension, UnsupportedCriticalExtension) => true,
914            (UnsupportedDeltaCrl, UnsupportedDeltaCrl) => true,
915            (UnsupportedIndirectCrl, UnsupportedIndirectCrl) => true,
916            (UnsupportedRevocationReason, UnsupportedRevocationReason) => true,
917            _ => false,
918        }
919    }
920}
921
922impl From<CertRevocationListError> for Error {
923    #[inline]
924    fn from(e: CertRevocationListError) -> Self {
925        Self::InvalidCertRevocationList(e)
926    }
927}
928
929#[non_exhaustive]
930#[derive(Debug, Clone, Eq, PartialEq)]
931/// An error that occurred while handling Encrypted Client Hello (ECH).
932pub 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
941impl From<EncryptedClientHelloError> for Error {
942    #[inline]
943    fn from(e: EncryptedClientHelloError) -> Self {
944        Self::InvalidEncryptedClientHello(e)
945    }
946}
947
948fn join<T: fmt::Debug>(items: &[T]) -> String {
949    items
950        .iter()
951        .map(|x| format!("{x:?}"))
952        .collect::<Vec<String>>()
953        .join(" or ")
954}
955
956impl fmt::Display for Error {
957    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
958        match self {
959            Self::InappropriateMessage {
960                expect_types,
961                got_type,
962            } => write!(
963                f,
964                "received unexpected message: got {:?} when expecting {}",
965                got_type,
966                join::<ContentType>(expect_types)
967            ),
968            Self::InappropriateHandshakeMessage {
969                expect_types,
970                got_type,
971            } => write!(
972                f,
973                "received unexpected handshake message: got {:?} when expecting {}",
974                got_type,
975                join::<HandshakeType>(expect_types)
976            ),
977            Self::InvalidMessage(typ) => {
978                write!(f, "received corrupt message of type {typ:?}")
979            }
980            Self::PeerIncompatible(why) => write!(f, "peer is incompatible: {why:?}"),
981            Self::PeerMisbehaved(why) => write!(f, "peer misbehaved: {why:?}"),
982            Self::AlertReceived(alert) => write!(f, "received fatal alert: {alert:?}"),
983            Self::InvalidCertificate(err) => {
984                write!(f, "invalid peer certificate: {err}")
985            }
986            Self::InvalidCertRevocationList(err) => {
987                write!(f, "invalid certificate revocation list: {err:?}")
988            }
989            Self::NoCertificatesPresented => write!(f, "peer sent no certificates"),
990            Self::UnsupportedNameType => write!(f, "presented server name type wasn't supported"),
991            Self::DecryptError => write!(f, "cannot decrypt peer's message"),
992            Self::InvalidEncryptedClientHello(err) => {
993                write!(f, "encrypted client hello failure: {err:?}")
994            }
995            Self::EncryptError => write!(f, "cannot encrypt message"),
996            Self::PeerSentOversizedRecord => write!(f, "peer sent excess record size"),
997            Self::HandshakeNotComplete => write!(f, "handshake not complete"),
998            Self::NoApplicationProtocol => write!(f, "peer doesn't support any known protocol"),
999            Self::FailedToGetCurrentTime => write!(f, "failed to get current time"),
1000            Self::FailedToGetRandomBytes => write!(f, "failed to get random bytes"),
1001            Self::BadMaxFragmentSize => {
1002                write!(f, "the supplied max_fragment_size was too small or large")
1003            }
1004            Self::InconsistentKeys(why) => {
1005                write!(f, "keys may not be consistent: {why:?}")
1006            }
1007            Self::General(err) => write!(f, "unexpected error: {err}"),
1008            Self::Other(err) => write!(f, "other error: {err}"),
1009        }
1010    }
1011}
1012
1013#[cfg(feature = "std")]
1014impl From<SystemTimeError> for Error {
1015    #[inline]
1016    fn from(_: SystemTimeError) -> Self {
1017        Self::FailedToGetCurrentTime
1018    }
1019}
1020
1021#[cfg(feature = "std")]
1022impl std::error::Error for Error {}
1023
1024impl From<rand::GetRandomFailed> for Error {
1025    fn from(_: rand::GetRandomFailed) -> Self {
1026        Self::FailedToGetRandomBytes
1027    }
1028}
1029
1030mod 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        fn eq(&self, _other: &Self) -> bool {
1050            false
1051        }
1052    }
1053
1054    impl From<OtherError> for Error {
1055        fn from(value: OtherError) -> Self {
1056            Self::Other(value)
1057        }
1058    }
1059
1060    impl fmt::Display for OtherError {
1061        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1062            #[cfg(feature = "std")]
1063            {
1064                write!(f, "{}", self.0)
1065            }
1066            #[cfg(not(feature = "std"))]
1067            {
1068                f.write_str("no further information available")
1069            }
1070        }
1071    }
1072
1073    #[cfg(feature = "std")]
1074    impl StdError for OtherError {
1075        fn source(&self) -> Option<&(dyn StdError + 'static)> {
1076            Some(self.0.as_ref())
1077        }
1078    }
1079}
1080
1081pub use other_error::OtherError;
1082
1083#[cfg(test)]
1084mod 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}