rustls/
error.rs

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