rustls/
error.rs

1use crate::enums::{AlertDescription, ContentType, HandshakeType};
2use crate::msgs::handshake::KeyExchangeAlgorithm;
3use crate::rand;
4
5use alloc::format;
6use alloc::string::String;
7use alloc::sync::Arc;
8use alloc::vec::Vec;
9use core::fmt;
10use std::error::Error as StdError;
11use std::time::SystemTimeError;
12
13/// rustls reports protocol errors using this type.
14#[non_exhaustive]
15#[derive(Debug, PartialEq, Clone)]
16pub enum Error {
17    /// We received a TLS message that isn't valid right now.
18    /// `expect_types` lists the message types we can expect right now.
19    /// `got_type` is the type we found.  This error is typically
20    /// caused by a buggy TLS stack (the peer or this one), a broken
21    /// network, or an attack.
22    InappropriateMessage {
23        /// Which types we expected
24        expect_types: Vec<ContentType>,
25        /// What type we received
26        got_type: ContentType,
27    },
28
29    /// We received a TLS handshake message that isn't valid right now.
30    /// `expect_types` lists the handshake message types we can expect
31    /// right now.  `got_type` is the type we found.
32    InappropriateHandshakeMessage {
33        /// Which handshake type we expected
34        expect_types: Vec<HandshakeType>,
35        /// What handshake type we received
36        got_type: HandshakeType,
37    },
38
39    /// The peer sent us a TLS message with invalid contents.
40    InvalidMessage(InvalidMessage),
41
42    /// The peer didn't give us any certificates.
43    NoCertificatesPresented,
44
45    /// The certificate verifier doesn't support the given type of name.
46    UnsupportedNameType,
47
48    /// We couldn't decrypt a message.  This is invariably fatal.
49    DecryptError,
50
51    /// We couldn't encrypt a message because it was larger than the allowed message size.
52    /// This should never happen if the application is using valid record sizes.
53    EncryptError,
54
55    /// The peer doesn't support a protocol version/feature we require.
56    /// The parameter gives a hint as to what version/feature it is.
57    PeerIncompatible(PeerIncompatible),
58
59    /// The peer deviated from the standard TLS protocol.
60    /// The parameter gives a hint where.
61    PeerMisbehaved(PeerMisbehaved),
62
63    /// We received a fatal alert.  This means the peer is unhappy.
64    AlertReceived(AlertDescription),
65
66    /// We saw an invalid certificate.
67    ///
68    /// The contained error is from the certificate validation trait
69    /// implementation.
70    InvalidCertificate(CertificateError),
71
72    /// A provided certificate revocation list (CRL) was invalid.
73    InvalidCertRevocationList(CertRevocationListError),
74
75    /// A catch-all error for unlikely errors.
76    General(String),
77
78    /// We failed to figure out what time it currently is.
79    FailedToGetCurrentTime,
80
81    /// We failed to acquire random bytes from the system.
82    FailedToGetRandomBytes,
83
84    /// This function doesn't work until the TLS handshake
85    /// is complete.
86    HandshakeNotComplete,
87
88    /// The peer sent an oversized record/fragment.
89    PeerSentOversizedRecord,
90
91    /// An incoming connection did not support any known application protocol.
92    NoApplicationProtocol,
93
94    /// The `max_fragment_size` value supplied in configuration was too small,
95    /// or too large.
96    BadMaxFragmentSize,
97
98    /// Any other error.
99    ///
100    /// This variant should only be used when the error is not better described by a more
101    /// specific variant. For example, if a custom crypto provider returns a
102    /// provider specific error.
103    ///
104    /// Enums holding this variant will never compare equal to each other.
105    Other(OtherError),
106}
107
108/// A corrupt TLS message payload that resulted in an error.
109#[non_exhaustive]
110#[derive(Debug, Clone, Copy, PartialEq)]
111
112pub enum InvalidMessage {
113    /// An advertised message was larger then expected.
114    HandshakePayloadTooLarge,
115    /// The peer sent us a syntactically incorrect ChangeCipherSpec payload.
116    InvalidCcs,
117    /// An unknown content type was encountered during message decoding.
118    InvalidContentType,
119    /// A peer sent an invalid certificate status type
120    InvalidCertificateStatusType,
121    /// Context was incorrectly attached to a certificate request during a handshake.
122    InvalidCertRequest,
123    /// A peer's DH params could not be decoded
124    InvalidDhParams,
125    /// A message was zero-length when its record kind forbids it.
126    InvalidEmptyPayload,
127    /// A peer sent an unexpected key update request.
128    InvalidKeyUpdate,
129    /// A peer's server name could not be decoded
130    InvalidServerName,
131    /// A TLS message payload was larger then allowed by the specification.
132    MessageTooLarge,
133    /// Message is shorter than the expected length
134    MessageTooShort,
135    /// Missing data for the named handshake payload value
136    MissingData(&'static str),
137    /// A peer did not advertise its supported key exchange groups.
138    MissingKeyExchange,
139    /// A peer sent an empty list of signature schemes
140    NoSignatureSchemes,
141    /// Trailing data found for the named handshake payload value
142    TrailingData(&'static str),
143    /// A peer sent an unexpected message type.
144    UnexpectedMessage(&'static str),
145    /// An unknown TLS protocol was encountered during message decoding.
146    UnknownProtocolVersion,
147    /// A peer sent a non-null compression method.
148    UnsupportedCompression,
149    /// A peer sent an unknown elliptic curve type.
150    UnsupportedCurveType,
151    /// A peer sent an unsupported key exchange algorithm.
152    UnsupportedKeyExchangeAlgorithm(KeyExchangeAlgorithm),
153}
154
155impl From<InvalidMessage> for Error {
156    #[inline]
157    fn from(e: InvalidMessage) -> Self {
158        Self::InvalidMessage(e)
159    }
160}
161
162#[non_exhaustive]
163#[allow(missing_docs)]
164#[derive(Debug, PartialEq, Clone)]
165/// The set of cases where we failed to make a connection because we thought
166/// the peer was misbehaving.
167///
168/// This is `non_exhaustive`: we might add or stop using items here in minor
169/// versions.  We also don't document what they mean.  Generally a user of
170/// rustls shouldn't vary its behaviour on these error codes, and there is
171/// nothing it can do to improve matters.
172///
173/// Please file a bug against rustls if you see `Error::PeerMisbehaved` in
174/// the wild.
175pub enum PeerMisbehaved {
176    AttemptedDowngradeToTls12WhenTls13IsSupported,
177    BadCertChainExtensions,
178    DisallowedEncryptedExtension,
179    DuplicateClientHelloExtensions,
180    DuplicateEncryptedExtensions,
181    DuplicateHelloRetryRequestExtensions,
182    DuplicateNewSessionTicketExtensions,
183    DuplicateServerHelloExtensions,
184    DuplicateServerNameTypes,
185    EarlyDataAttemptedInSecondClientHello,
186    EarlyDataExtensionWithoutResumption,
187    EarlyDataOfferedWithVariedCipherSuite,
188    HandshakeHashVariedAfterRetry,
189    IllegalHelloRetryRequestWithEmptyCookie,
190    IllegalHelloRetryRequestWithNoChanges,
191    IllegalHelloRetryRequestWithOfferedGroup,
192    IllegalHelloRetryRequestWithUnofferedCipherSuite,
193    IllegalHelloRetryRequestWithUnofferedNamedGroup,
194    IllegalHelloRetryRequestWithUnsupportedVersion,
195    IllegalHelloRetryRequestWithWrongSessionId,
196    IllegalMiddleboxChangeCipherSpec,
197    IllegalTlsInnerPlaintext,
198    IncorrectBinder,
199    InvalidMaxEarlyDataSize,
200    InvalidKeyShare,
201    KeyEpochWithPendingFragment,
202    KeyUpdateReceivedInQuicConnection,
203    MessageInterleavedWithHandshakeMessage,
204    MissingBinderInPskExtension,
205    MissingKeyShare,
206    MissingPskModesExtension,
207    MissingQuicTransportParameters,
208    OfferedDuplicateKeyShares,
209    OfferedEarlyDataWithOldProtocolVersion,
210    OfferedEmptyApplicationProtocol,
211    OfferedIncorrectCompressions,
212    PskExtensionMustBeLast,
213    PskExtensionWithMismatchedIdsAndBinders,
214    RefusedToFollowHelloRetryRequest,
215    RejectedEarlyDataInterleavedWithHandshakeMessage,
216    ResumptionAttemptedWithVariedEms,
217    ResumptionOfferedWithVariedCipherSuite,
218    ResumptionOfferedWithVariedEms,
219    ResumptionOfferedWithIncompatibleCipherSuite,
220    SelectedDifferentCipherSuiteAfterRetry,
221    SelectedInvalidPsk,
222    SelectedTls12UsingTls13VersionExtension,
223    SelectedUnofferedApplicationProtocol,
224    SelectedUnofferedCipherSuite,
225    SelectedUnofferedCompression,
226    SelectedUnofferedKxGroup,
227    SelectedUnofferedPsk,
228    SelectedUnusableCipherSuiteForVersion,
229    ServerHelloMustOfferUncompressedEcPoints,
230    ServerNameDifferedOnRetry,
231    ServerNameMustContainOneHostName,
232    SignedKxWithWrongAlgorithm,
233    SignedHandshakeWithUnadvertisedSigScheme,
234    TooMuchEarlyDataReceived,
235    UnexpectedCleartextExtension,
236    UnsolicitedCertExtension,
237    UnsolicitedEncryptedExtension,
238    UnsolicitedSctList,
239    UnsolicitedServerHelloExtension,
240    WrongGroupForKeyShare,
241}
242
243impl From<PeerMisbehaved> for Error {
244    #[inline]
245    fn from(e: PeerMisbehaved) -> Self {
246        Self::PeerMisbehaved(e)
247    }
248}
249
250#[non_exhaustive]
251#[allow(missing_docs)]
252#[derive(Debug, PartialEq, Clone)]
253/// The set of cases where we failed to make a connection because a peer
254/// doesn't support a TLS version/feature we require.
255///
256/// This is `non_exhaustive`: we might add or stop using items here in minor
257/// versions.
258pub enum PeerIncompatible {
259    EcPointsExtensionRequired,
260    KeyShareExtensionRequired,
261    NamedGroupsExtensionRequired,
262    NoCertificateRequestSignatureSchemesInCommon,
263    NoCipherSuitesInCommon,
264    NoEcPointFormatsInCommon,
265    NoKxGroupsInCommon,
266    NoSignatureSchemesInCommon,
267    NullCompressionRequired,
268    ServerDoesNotSupportTls12Or13,
269    ServerSentHelloRetryRequestWithUnknownExtension,
270    ServerTlsVersionIsDisabledByOurConfig,
271    SignatureAlgorithmsExtensionRequired,
272    SupportedVersionsExtensionRequired,
273    Tls12NotOffered,
274    Tls12NotOfferedOrEnabled,
275    Tls13RequiredForQuic,
276    UncompressedEcPointsRequired,
277}
278
279impl From<PeerIncompatible> for Error {
280    #[inline]
281    fn from(e: PeerIncompatible) -> Self {
282        Self::PeerIncompatible(e)
283    }
284}
285
286#[non_exhaustive]
287#[derive(Debug, Clone)]
288/// The ways in which certificate validators can express errors.
289///
290/// Note that the rustls TLS protocol code interprets specifically these
291/// error codes to send specific TLS alerts.  Therefore, if a
292/// custom certificate validator uses incorrect errors the library as
293/// a whole will send alerts that do not match the standard (this is usually
294/// a minor issue, but could be misleading).
295pub enum CertificateError {
296    /// The certificate is not correctly encoded.
297    BadEncoding,
298
299    /// The current time is after the `notAfter` time in the certificate.
300    Expired,
301
302    /// The current time is before the `notBefore` time in the certificate.
303    NotValidYet,
304
305    /// The certificate has been revoked.
306    Revoked,
307
308    /// The certificate contains an extension marked critical, but it was
309    /// not processed by the certificate validator.
310    UnhandledCriticalExtension,
311
312    /// The certificate chain is not issued by a known root certificate.
313    UnknownIssuer,
314
315    /// The certificate's revocation status could not be determined.
316    UnknownRevocationStatus,
317
318    /// A certificate is not correctly signed by the key of its alleged
319    /// issuer.
320    BadSignature,
321
322    /// The subject names in an end-entity certificate do not include
323    /// the expected name.
324    NotValidForName,
325
326    /// The certificate is being used for a different purpose than allowed.
327    InvalidPurpose,
328
329    /// The certificate is valid, but the handshake is rejected for other
330    /// reasons.
331    ApplicationVerificationFailure,
332
333    /// Any other error.
334    ///
335    /// This can be used by custom verifiers to expose the underlying error
336    /// (where they are not better described by the more specific errors
337    /// above).
338    ///
339    /// It is also used by the default verifier in case its error is
340    /// not covered by the above common cases.
341    ///
342    /// Enums holding this variant will never compare equal to each other.
343    Other(OtherError),
344}
345
346impl PartialEq<Self> for CertificateError {
347    fn eq(&self, other: &Self) -> bool {
348        use CertificateError::*;
349        #[allow(clippy::match_like_matches_macro)]
350        match (self, other) {
351            (BadEncoding, BadEncoding) => true,
352            (Expired, Expired) => true,
353            (NotValidYet, NotValidYet) => true,
354            (Revoked, Revoked) => true,
355            (UnhandledCriticalExtension, UnhandledCriticalExtension) => true,
356            (UnknownIssuer, UnknownIssuer) => true,
357            (BadSignature, BadSignature) => true,
358            (NotValidForName, NotValidForName) => true,
359            (InvalidPurpose, InvalidPurpose) => true,
360            (ApplicationVerificationFailure, ApplicationVerificationFailure) => true,
361            _ => false,
362        }
363    }
364}
365
366// The following mapping are heavily referenced in:
367// * [OpenSSL Implementation](https://github.com/openssl/openssl/blob/45bb98bfa223efd3258f445ad443f878011450f0/ssl/statem/statem_lib.c#L1434)
368// * [BoringSSL Implementation](https://github.com/google/boringssl/blob/583c60bd4bf76d61b2634a58bcda99a92de106cb/ssl/ssl_x509.cc#L1323)
369impl From<CertificateError> for AlertDescription {
370    fn from(e: CertificateError) -> Self {
371        use CertificateError::*;
372        match e {
373            BadEncoding | UnhandledCriticalExtension | NotValidForName => Self::BadCertificate,
374            // RFC 5246/RFC 8446
375            // certificate_expired
376            //  A certificate has expired or **is not currently valid**.
377            Expired | NotValidYet => Self::CertificateExpired,
378            Revoked => Self::CertificateRevoked,
379            // OpenSSL, BoringSSL and AWS-LC all generate an Unknown CA alert for
380            // the case where revocation status can not be determined, so we do the same here.
381            UnknownIssuer | UnknownRevocationStatus => Self::UnknownCA,
382            BadSignature => Self::DecryptError,
383            InvalidPurpose => Self::UnsupportedCertificate,
384            ApplicationVerificationFailure => Self::AccessDenied,
385            // RFC 5246/RFC 8446
386            // certificate_unknown
387            //  Some other (unspecified) issue arose in processing the
388            //  certificate, rendering it unacceptable.
389            Other(_) => Self::CertificateUnknown,
390        }
391    }
392}
393
394impl From<CertificateError> for Error {
395    #[inline]
396    fn from(e: CertificateError) -> Self {
397        Self::InvalidCertificate(e)
398    }
399}
400
401#[non_exhaustive]
402#[derive(Debug, Clone)]
403/// The ways in which a certificate revocation list (CRL) can be invalid.
404pub enum CertRevocationListError {
405    /// The CRL had a bad, or unsupported signature from its issuer.
406    BadSignature,
407
408    /// The CRL contained an invalid CRL number.
409    InvalidCrlNumber,
410
411    /// The CRL contained a revoked certificate with an invalid serial number.
412    InvalidRevokedCertSerialNumber,
413
414    /// The CRL issuer does not specify the cRLSign key usage.
415    IssuerInvalidForCrl,
416
417    /// The CRL is invalid for some other reason.
418    ///
419    /// Enums holding this variant will never compare equal to each other.
420    Other(OtherError),
421
422    /// The CRL is not correctly encoded.
423    ParseError,
424
425    /// The CRL is not a v2 X.509 CRL.
426    UnsupportedCrlVersion,
427
428    /// The CRL, or a revoked certificate in the CRL, contained an unsupported critical extension.
429    UnsupportedCriticalExtension,
430
431    /// The CRL is an unsupported delta CRL, containing only changes relative to another CRL.
432    UnsupportedDeltaCrl,
433
434    /// The CRL is an unsupported indirect CRL, containing revoked certificates issued by a CA
435    /// other than the issuer of the CRL.
436    UnsupportedIndirectCrl,
437
438    /// The CRL contained a revoked certificate with an unsupported revocation reason.
439    /// See RFC 5280 Section 5.3.1[^1] for a list of supported revocation reasons.
440    ///
441    /// [^1]: <https://www.rfc-editor.org/rfc/rfc5280#section-5.3.1>
442    UnsupportedRevocationReason,
443}
444
445impl PartialEq<Self> for CertRevocationListError {
446    fn eq(&self, other: &Self) -> bool {
447        use CertRevocationListError::*;
448        #[allow(clippy::match_like_matches_macro)]
449        match (self, other) {
450            (BadSignature, BadSignature) => true,
451            (InvalidCrlNumber, InvalidCrlNumber) => true,
452            (InvalidRevokedCertSerialNumber, InvalidRevokedCertSerialNumber) => true,
453            (IssuerInvalidForCrl, IssuerInvalidForCrl) => true,
454            (ParseError, ParseError) => true,
455            (UnsupportedCrlVersion, UnsupportedCrlVersion) => true,
456            (UnsupportedCriticalExtension, UnsupportedCriticalExtension) => true,
457            (UnsupportedDeltaCrl, UnsupportedDeltaCrl) => true,
458            (UnsupportedIndirectCrl, UnsupportedIndirectCrl) => true,
459            (UnsupportedRevocationReason, UnsupportedRevocationReason) => true,
460            _ => false,
461        }
462    }
463}
464
465impl From<CertRevocationListError> for Error {
466    #[inline]
467    fn from(e: CertRevocationListError) -> Self {
468        Self::InvalidCertRevocationList(e)
469    }
470}
471
472fn join<T: fmt::Debug>(items: &[T]) -> String {
473    items
474        .iter()
475        .map(|x| format!("{:?}", x))
476        .collect::<Vec<String>>()
477        .join(" or ")
478}
479
480impl fmt::Display for Error {
481    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
482        match *self {
483            Self::InappropriateMessage {
484                ref expect_types,
485                ref got_type,
486            } => write!(
487                f,
488                "received unexpected message: got {:?} when expecting {}",
489                got_type,
490                join::<ContentType>(expect_types)
491            ),
492            Self::InappropriateHandshakeMessage {
493                ref expect_types,
494                ref got_type,
495            } => write!(
496                f,
497                "received unexpected handshake message: got {:?} when expecting {}",
498                got_type,
499                join::<HandshakeType>(expect_types)
500            ),
501            Self::InvalidMessage(ref typ) => {
502                write!(f, "received corrupt message of type {:?}", typ)
503            }
504            Self::PeerIncompatible(ref why) => write!(f, "peer is incompatible: {:?}", why),
505            Self::PeerMisbehaved(ref why) => write!(f, "peer misbehaved: {:?}", why),
506            Self::AlertReceived(ref alert) => write!(f, "received fatal alert: {:?}", alert),
507            Self::InvalidCertificate(ref err) => {
508                write!(f, "invalid peer certificate: {:?}", err)
509            }
510            Self::InvalidCertRevocationList(ref err) => {
511                write!(f, "invalid certificate revocation list: {:?}", err)
512            }
513            Self::NoCertificatesPresented => write!(f, "peer sent no certificates"),
514            Self::UnsupportedNameType => write!(f, "presented server name type wasn't supported"),
515            Self::DecryptError => write!(f, "cannot decrypt peer's message"),
516            Self::EncryptError => write!(f, "cannot encrypt message"),
517            Self::PeerSentOversizedRecord => write!(f, "peer sent excess record size"),
518            Self::HandshakeNotComplete => write!(f, "handshake not complete"),
519            Self::NoApplicationProtocol => write!(f, "peer doesn't support any known protocol"),
520            Self::FailedToGetCurrentTime => write!(f, "failed to get current time"),
521            Self::FailedToGetRandomBytes => write!(f, "failed to get random bytes"),
522            Self::BadMaxFragmentSize => {
523                write!(f, "the supplied max_fragment_size was too small or large")
524            }
525            Self::General(ref err) => write!(f, "unexpected error: {}", err),
526            Self::Other(ref err) => write!(f, "other error: {}", err),
527        }
528    }
529}
530
531impl From<SystemTimeError> for Error {
532    #[inline]
533    fn from(_: SystemTimeError) -> Self {
534        Self::FailedToGetCurrentTime
535    }
536}
537
538impl StdError for Error {}
539
540impl From<rand::GetRandomFailed> for Error {
541    fn from(_: rand::GetRandomFailed) -> Self {
542        Self::FailedToGetRandomBytes
543    }
544}
545
546/// Any other error that cannot be expressed by a more specific [`Error`] variant.
547///
548/// For example, an `OtherError` could be produced by a custom crypto provider
549/// exposing a provider specific error.
550///
551/// Enums holding this type will never compare equal to each other.
552#[derive(Debug, Clone)]
553pub struct OtherError(pub Arc<dyn StdError + Send + Sync>);
554
555impl PartialEq<Self> for OtherError {
556    fn eq(&self, _other: &Self) -> bool {
557        false
558    }
559}
560
561impl From<OtherError> for Error {
562    fn from(value: OtherError) -> Self {
563        Self::Other(value)
564    }
565}
566
567impl fmt::Display for OtherError {
568    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
569        write!(f, "{}", self.0)
570    }
571}
572
573impl StdError for OtherError {
574    fn source(&self) -> Option<&(dyn StdError + 'static)> {
575        Some(self.0.as_ref())
576    }
577}
578
579#[cfg(test)]
580mod tests {
581    use super::{Error, InvalidMessage};
582    use crate::error::{CertRevocationListError, OtherError};
583    use std::prelude::v1::*;
584    use std::{println, vec};
585
586    #[test]
587    fn certificate_error_equality() {
588        use super::CertificateError::*;
589        assert_eq!(BadEncoding, BadEncoding);
590        assert_eq!(Expired, Expired);
591        assert_eq!(NotValidYet, NotValidYet);
592        assert_eq!(Revoked, Revoked);
593        assert_eq!(UnhandledCriticalExtension, UnhandledCriticalExtension);
594        assert_eq!(UnknownIssuer, UnknownIssuer);
595        assert_eq!(BadSignature, BadSignature);
596        assert_eq!(NotValidForName, NotValidForName);
597        assert_eq!(InvalidPurpose, InvalidPurpose);
598        assert_eq!(
599            ApplicationVerificationFailure,
600            ApplicationVerificationFailure
601        );
602        let other = Other(OtherError(alloc::sync::Arc::from(Box::from(""))));
603        assert_ne!(other, other);
604        assert_ne!(BadEncoding, Expired);
605    }
606
607    #[test]
608    fn crl_error_equality() {
609        use super::CertRevocationListError::*;
610        assert_eq!(BadSignature, BadSignature);
611        assert_eq!(InvalidCrlNumber, InvalidCrlNumber);
612        assert_eq!(
613            InvalidRevokedCertSerialNumber,
614            InvalidRevokedCertSerialNumber
615        );
616        assert_eq!(IssuerInvalidForCrl, IssuerInvalidForCrl);
617        assert_eq!(ParseError, ParseError);
618        assert_eq!(UnsupportedCriticalExtension, UnsupportedCriticalExtension);
619        assert_eq!(UnsupportedCrlVersion, UnsupportedCrlVersion);
620        assert_eq!(UnsupportedDeltaCrl, UnsupportedDeltaCrl);
621        assert_eq!(UnsupportedIndirectCrl, UnsupportedIndirectCrl);
622        assert_eq!(UnsupportedRevocationReason, UnsupportedRevocationReason);
623        let other = Other(OtherError(alloc::sync::Arc::from(Box::from(""))));
624        assert_ne!(other, other);
625        assert_ne!(BadSignature, InvalidCrlNumber);
626    }
627
628    #[test]
629    fn other_error_equality() {
630        let other_error = OtherError(alloc::sync::Arc::from(Box::from("")));
631        assert_ne!(other_error, other_error);
632        let other: Error = other_error.into();
633        assert_ne!(other, other);
634    }
635
636    #[test]
637    fn smoke() {
638        use crate::enums::{AlertDescription, ContentType, HandshakeType};
639
640        let all = vec![
641            Error::InappropriateMessage {
642                expect_types: vec![ContentType::Alert],
643                got_type: ContentType::Handshake,
644            },
645            Error::InappropriateHandshakeMessage {
646                expect_types: vec![HandshakeType::ClientHello, HandshakeType::Finished],
647                got_type: HandshakeType::ServerHello,
648            },
649            Error::InvalidMessage(InvalidMessage::InvalidCcs),
650            Error::NoCertificatesPresented,
651            Error::DecryptError,
652            super::PeerIncompatible::Tls12NotOffered.into(),
653            super::PeerMisbehaved::UnsolicitedCertExtension.into(),
654            Error::AlertReceived(AlertDescription::ExportRestriction),
655            super::CertificateError::Expired.into(),
656            Error::General("undocumented error".to_string()),
657            Error::FailedToGetCurrentTime,
658            Error::FailedToGetRandomBytes,
659            Error::HandshakeNotComplete,
660            Error::PeerSentOversizedRecord,
661            Error::NoApplicationProtocol,
662            Error::BadMaxFragmentSize,
663            Error::InvalidCertRevocationList(CertRevocationListError::BadSignature),
664            Error::Other(OtherError(alloc::sync::Arc::from(Box::from("")))),
665        ];
666
667        for err in all {
668            println!("{:?}:", err);
669            println!("  fmt '{}'", err);
670        }
671    }
672
673    #[test]
674    fn rand_error_mapping() {
675        use super::rand;
676        let err: Error = rand::GetRandomFailed.into();
677        assert_eq!(err, Error::FailedToGetRandomBytes);
678    }
679
680    #[test]
681    fn time_error_mapping() {
682        use std::time::SystemTime;
683
684        let time_error = SystemTime::UNIX_EPOCH
685            .duration_since(SystemTime::now())
686            .unwrap_err();
687        let err: Error = time_error.into();
688        assert_eq!(err, Error::FailedToGetCurrentTime);
689    }
690}