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