Skip to main content

rustls/error/
mod.rs

1//! Error types used throughout rustls.
2
3use alloc::format;
4use alloc::string::String;
5use alloc::vec::Vec;
6use core::fmt;
7#[cfg(feature = "std")]
8use std::time::SystemTimeError;
9
10use pki_types::{AlgorithmIdentifier, EchConfigListBytes, ServerName, UnixTime};
11#[cfg(feature = "webpki")]
12use webpki::ExtendedKeyUsage;
13
14use crate::crypto::kx::KeyExchangeAlgorithm;
15use crate::crypto::{CipherSuite, GetRandomFailed, InconsistentKeys};
16use crate::enums::{ContentType, HandshakeType};
17use crate::msgs::{Codec, EchConfigPayload};
18
19#[cfg(test)]
20mod tests;
21
22/// rustls reports protocol errors using this type.
23#[non_exhaustive]
24#[derive(Debug, PartialEq, Clone)]
25pub enum Error {
26    /// We received a TLS message that isn't valid right now.
27    /// `expect_types` lists the message types we can expect right now.
28    /// `got_type` is the type we found.  This error is typically
29    /// caused by a buggy TLS stack (the peer or this one), a broken
30    /// network, or an attack.
31    InappropriateMessage {
32        /// Which types we expected
33        expect_types: Vec<ContentType>,
34        /// What type we received
35        got_type: ContentType,
36    },
37
38    /// We received a TLS handshake message that isn't valid right now.
39    /// `expect_types` lists the handshake message types we can expect
40    /// right now.  `got_type` is the type we found.
41    InappropriateHandshakeMessage {
42        /// Which handshake type we expected
43        expect_types: Vec<HandshakeType>,
44        /// What handshake type we received
45        got_type: HandshakeType,
46    },
47
48    /// An error occurred while handling Encrypted Client Hello (ECH).
49    InvalidEncryptedClientHello(EncryptedClientHelloError),
50
51    /// The peer sent us a TLS message with invalid contents.
52    InvalidMessage(InvalidMessage),
53
54    /// The certificate verifier doesn't support the given type of name.
55    UnsupportedNameType,
56
57    /// We couldn't decrypt a message.  This is invariably fatal.
58    DecryptError,
59
60    /// We couldn't encrypt a message.
61    ///
62    /// This happens if the message was larger than the allowed message size (which should never
63    /// happen if the application is using valid record sizes), or if the traffic keys have been
64    /// used for as many records as the cipher suite's
65    /// [`confidentiality_limit`][crate::crypto::CipherSuiteCommon::confidentiality_limit] allows.
66    EncryptError,
67
68    /// The peer doesn't support a protocol version/feature we require.
69    /// The parameter gives a hint as to what version/feature it is.
70    PeerIncompatible(PeerIncompatible),
71
72    /// The peer deviated from the standard TLS protocol.
73    /// The parameter gives a hint where.
74    PeerMisbehaved(PeerMisbehaved),
75
76    /// We received a fatal alert.  This means the peer is unhappy.
77    AlertReceived(AlertDescription),
78
79    /// We saw an invalid certificate.
80    ///
81    /// The contained error is from the certificate validation trait
82    /// implementation.
83    InvalidCertificate(CertificateError),
84
85    /// A provided certificate revocation list (CRL) was invalid.
86    InvalidCertRevocationList(CertRevocationListError),
87
88    /// A catch-all error for unlikely errors.
89    General(String),
90
91    /// We failed to figure out what time it currently is.
92    FailedToGetCurrentTime,
93
94    /// We failed to acquire random bytes from the system.
95    FailedToGetRandomBytes,
96
97    /// This function doesn't work until the TLS handshake
98    /// is complete.
99    HandshakeNotComplete,
100
101    /// The peer sent an oversized record/fragment.
102    PeerSentOversizedRecord,
103
104    /// An incoming connection did not support any known application protocol.
105    NoApplicationProtocol,
106
107    /// The server certificate resolver didn't find an appropriate certificate.
108    NoSuitableCertificate,
109
110    /// The `max_fragment_size` value supplied in configuration was too small,
111    /// or too large.
112    BadMaxFragmentSize,
113
114    /// Specific failure cases from [`Credentials::new()`] or a
115    /// [`crate::crypto::SigningKey`] that cannot produce a corresponding public key.
116    ///
117    /// If encountered while building a [`Credentials`], consider if
118    /// [`Credentials::new_unchecked()`] might be appropriate for your use case.
119    ///
120    /// [`Credentials::new()`]: crate::crypto::Credentials::new()
121    /// [`Credentials`]: crate::crypto::Credentials
122    /// [`Credentials::new_unchecked()`]: crate::crypto::Credentials::new_unchecked()
123    InconsistentKeys(InconsistentKeys),
124
125    /// The server rejected encrypted client hello (ECH) negotiation
126    ///
127    /// It may have returned new ECH configurations that could be used to retry negotiation
128    /// with a fresh connection.
129    ///
130    /// See [`RejectedEch::can_retry()`] and [`crate::client::EchConfig::for_retry()`].
131    RejectedEch(RejectedEch),
132
133    /// Errors of this variant should never be produced by the library.
134    ///
135    /// Please file a bug if you see one.
136    Unreachable(&'static str),
137
138    /// The caller misused the API
139    ///
140    /// Generally we try to make error cases like this unnecessary by embedding
141    /// the constraints in the type system, so misuses simply do not compile.  But,
142    /// for cases where that is not possible or exceptionally costly, we return errors
143    /// of this variant.
144    ///
145    /// This only results from the ordering, dependencies or parameter values of calls,
146    /// so (assuming parameter values are fixed) these can be determined and fixed by
147    /// reading the code.  They are never caused by the values of untrusted data, or
148    /// other non-determinism.
149    ApiMisuse(ApiMisuse),
150
151    /// Any other error.
152    ///
153    /// This variant should only be used when the error is not better described by a more
154    /// specific variant. For example, if a custom crypto provider returns a
155    /// provider specific error.
156    ///
157    /// Enums holding this variant will never compare equal to each other.
158    Other(OtherError),
159}
160
161/// Determine which alert should be sent for a given error.
162///
163/// If this mapping fails, no alert is sent.
164impl TryFrom<&Error> for AlertDescription {
165    type Error = ();
166
167    fn try_from(error: &Error) -> Result<Self, Self::Error> {
168        Ok(match error {
169            Error::DecryptError => Self::BadRecordMac,
170            Error::InappropriateMessage { .. } | Error::InappropriateHandshakeMessage { .. } => {
171                Self::UnexpectedMessage
172            }
173            Error::InvalidCertificate(e) => Self::from(e),
174            Error::InvalidMessage(e) => Self::from(*e),
175            Error::NoApplicationProtocol => Self::NoApplicationProtocol,
176            Error::PeerMisbehaved(e) => Self::from(*e),
177            Error::PeerIncompatible(e) => Self::from(*e),
178            Error::PeerSentOversizedRecord => Self::RecordOverflow,
179            Error::RejectedEch(_) => Self::EncryptedClientHelloRequired,
180            Error::General(_) => Self::GeneralError,
181            Error::Other(_) => Self::InternalError,
182
183            _ => return Err(()),
184        })
185    }
186}
187
188impl fmt::Display for Error {
189    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
190        match self {
191            Self::InappropriateMessage {
192                expect_types,
193                got_type,
194            } => write!(
195                f,
196                "received unexpected message: got {:?} when expecting {}",
197                got_type,
198                join::<ContentType>(expect_types)
199            ),
200            Self::InappropriateHandshakeMessage {
201                expect_types,
202                got_type,
203            } => write!(
204                f,
205                "received unexpected handshake message: got {:?} when expecting {}",
206                got_type,
207                join::<HandshakeType>(expect_types)
208            ),
209            Self::InvalidMessage(typ) => {
210                write!(f, "received corrupt message of type {typ:?}")
211            }
212            Self::PeerIncompatible(why) => write!(f, "peer is incompatible: {why:?}"),
213            Self::PeerMisbehaved(why) => write!(f, "peer misbehaved: {why:?}"),
214            Self::AlertReceived(alert) => write!(f, "received fatal alert: the peer {alert}"),
215            Self::InvalidCertificate(err) => {
216                write!(f, "invalid peer certificate: {err}")
217            }
218            Self::InvalidCertRevocationList(err) => {
219                write!(f, "invalid certificate revocation list: {err:?}")
220            }
221            Self::UnsupportedNameType => write!(f, "presented server name type wasn't supported"),
222            Self::DecryptError => write!(f, "cannot decrypt peer's message"),
223            Self::InvalidEncryptedClientHello(err) => {
224                write!(f, "encrypted client hello failure: {err:?}")
225            }
226            Self::EncryptError => write!(f, "cannot encrypt message"),
227            Self::PeerSentOversizedRecord => write!(f, "peer sent excess record size"),
228            Self::HandshakeNotComplete => write!(f, "handshake not complete"),
229            Self::NoApplicationProtocol => write!(f, "peer doesn't support any known protocol"),
230            Self::NoSuitableCertificate => write!(f, "no suitable certificate found"),
231            Self::FailedToGetCurrentTime => write!(f, "failed to get current time"),
232            Self::FailedToGetRandomBytes => write!(f, "failed to get random bytes"),
233            Self::BadMaxFragmentSize => {
234                write!(f, "the supplied max_fragment_size was too small or large")
235            }
236            Self::InconsistentKeys(why) => {
237                write!(f, "keys may not be consistent: {why:?}")
238            }
239            Self::RejectedEch(why) => {
240                write!(
241                    f,
242                    "server rejected encrypted client hello (ECH) {} retry configs",
243                    if why.can_retry() { "with" } else { "without" }
244                )
245            }
246            Self::General(err) => write!(f, "unexpected error: {err}"),
247            Self::Unreachable(err) => write!(
248                f,
249                "unreachable condition: {err} (please file a bug in rustls)"
250            ),
251            Self::ApiMisuse(why) => write!(f, "API misuse: {why:?}"),
252            Self::Other(err) => write!(f, "other error: {err}"),
253        }
254    }
255}
256
257impl From<CertificateError> for Error {
258    #[inline]
259    fn from(e: CertificateError) -> Self {
260        Self::InvalidCertificate(e)
261    }
262}
263
264impl From<InvalidMessage> for Error {
265    #[inline]
266    fn from(e: InvalidMessage) -> Self {
267        Self::InvalidMessage(e)
268    }
269}
270
271impl From<PeerMisbehaved> for Error {
272    #[inline]
273    fn from(e: PeerMisbehaved) -> Self {
274        Self::PeerMisbehaved(e)
275    }
276}
277
278impl From<PeerIncompatible> for Error {
279    #[inline]
280    fn from(e: PeerIncompatible) -> Self {
281        Self::PeerIncompatible(e)
282    }
283}
284
285impl From<CertRevocationListError> for Error {
286    #[inline]
287    fn from(e: CertRevocationListError) -> Self {
288        Self::InvalidCertRevocationList(e)
289    }
290}
291
292impl From<EncryptedClientHelloError> for Error {
293    #[inline]
294    fn from(e: EncryptedClientHelloError) -> Self {
295        Self::InvalidEncryptedClientHello(e)
296    }
297}
298
299impl From<RejectedEch> for Error {
300    fn from(rejected_error: RejectedEch) -> Self {
301        Self::RejectedEch(rejected_error)
302    }
303}
304
305impl From<ApiMisuse> for Error {
306    fn from(e: ApiMisuse) -> Self {
307        Self::ApiMisuse(e)
308    }
309}
310
311impl From<OtherError> for Error {
312    fn from(value: OtherError) -> Self {
313        Self::Other(value)
314    }
315}
316
317impl From<InconsistentKeys> for Error {
318    #[inline]
319    fn from(e: InconsistentKeys) -> Self {
320        Self::InconsistentKeys(e)
321    }
322}
323
324#[cfg(feature = "std")]
325impl From<SystemTimeError> for Error {
326    #[inline]
327    fn from(_: SystemTimeError) -> Self {
328        Self::FailedToGetCurrentTime
329    }
330}
331
332impl From<GetRandomFailed> for Error {
333    fn from(_: GetRandomFailed) -> Self {
334        Self::FailedToGetRandomBytes
335    }
336}
337
338impl core::error::Error for Error {}
339
340/// The ways in which certificate validators can express errors.
341///
342/// Note that the rustls TLS protocol code interprets specifically these
343/// error codes to send specific TLS alerts.  Therefore, if a
344/// custom certificate validator uses incorrect errors the library as
345/// a whole will send alerts that do not match the standard (this is usually
346/// a minor issue, but could be misleading).
347#[non_exhaustive]
348#[derive(Debug, Clone)]
349pub enum CertificateError {
350    /// The certificate is not correctly encoded.
351    BadEncoding,
352
353    /// The current time is after the `notAfter` time in the certificate.
354    Expired,
355
356    /// The current time is after the `notAfter` time in the certificate.
357    ///
358    /// This variant is semantically the same as `Expired`, but includes
359    /// extra data to improve error reports.
360    ExpiredContext {
361        /// The validation time.
362        time: UnixTime,
363        /// The `notAfter` time of the certificate.
364        not_after: UnixTime,
365    },
366
367    /// The current time is before the `notBefore` time in the certificate.
368    NotValidYet,
369
370    /// The current time is before the `notBefore` time in the certificate.
371    ///
372    /// This variant is semantically the same as `NotValidYet`, but includes
373    /// extra data to improve error reports.
374    NotValidYetContext {
375        /// The validation time.
376        time: UnixTime,
377        /// The `notBefore` time of the certificate.
378        not_before: UnixTime,
379    },
380
381    /// The certificate has been revoked.
382    Revoked,
383
384    /// The certificate contains an extension marked critical, but it was
385    /// not processed by the certificate validator.
386    UnhandledCriticalExtension,
387
388    /// The certificate chain is not issued by a known root certificate.
389    UnknownIssuer,
390
391    /// The certificate's issuer lacks the `keyCertSign` keyUsage.
392    IssuerKeyUsageMissingCertSign,
393
394    /// The certificate's revocation status could not be determined.
395    UnknownRevocationStatus,
396
397    /// The certificate's revocation status could not be determined, because the CRL is expired.
398    ExpiredRevocationList,
399
400    /// The certificate's revocation status could not be determined, because the CRL is expired.
401    ///
402    /// This variant is semantically the same as `ExpiredRevocationList`, but includes
403    /// extra data to improve error reports.
404    ExpiredRevocationListContext {
405        /// The validation time.
406        time: UnixTime,
407        /// The nextUpdate time of the CRL.
408        next_update: UnixTime,
409    },
410
411    /// A certificate is not correctly signed by the key of its alleged
412    /// issuer.
413    BadSignature,
414
415    /// A certificate asked to verify a signature lacks the `digitalSignature` keyUsage.
416    KeyUsageMissingDigitalSignature,
417
418    /// A signature inside a certificate or on a handshake was made with an unsupported algorithm.
419    UnsupportedSignatureAlgorithm {
420        /// The signature algorithm OID that was unsupported.
421        signature_algorithm_id: Vec<u8>,
422        /// Supported algorithms that were available for signature verification.
423        supported_algorithms: Vec<AlgorithmIdentifier>,
424    },
425
426    /// A signature was made with an algorithm that doesn't match the relevant public key.
427    UnsupportedSignatureAlgorithmForPublicKey {
428        /// The signature algorithm OID.
429        signature_algorithm_id: Vec<u8>,
430        /// The public key algorithm OID.
431        public_key_algorithm_id: Vec<u8>,
432    },
433
434    /// The subject names in an end-entity certificate do not include
435    /// the expected name.
436    NotValidForName,
437
438    /// The subject names in an end-entity certificate do not include
439    /// the expected name.
440    ///
441    /// This variant is semantically the same as `NotValidForName`, but includes
442    /// extra data to improve error reports.
443    NotValidForNameContext {
444        /// Expected server name.
445        expected: ServerName<'static>,
446
447        /// The names presented in the end entity certificate.
448        ///
449        /// These are the subject names as present in the leaf certificate and may contain DNS names
450        /// with or without a wildcard label as well as IP address names.
451        presented: Vec<String>,
452    },
453
454    /// The certificate is being used for a different purpose than allowed.
455    InvalidPurpose,
456
457    /// The certificate is being used for a different purpose than allowed.
458    ///
459    /// This variant is semantically the same as `InvalidPurpose`, but includes
460    /// extra data to improve error reports.
461    InvalidPurposeContext {
462        /// Extended key purpose that was required by the application.
463        required: ExtendedKeyPurpose,
464        /// Extended key purposes that were presented in the peer's certificate.
465        presented: Vec<ExtendedKeyPurpose>,
466    },
467
468    /// The OCSP response provided to the verifier was invalid.
469    ///
470    /// This should be returned from [`ServerVerifier::verify_identity()`]
471    /// when a verifier checks its `ocsp_response` parameter and finds it invalid.
472    ///
473    /// This maps to [`AlertDescription::BadCertificateStatusResponse`].
474    ///
475    /// [`ServerVerifier::verify_identity()`]: crate::client::danger::ServerVerifier::verify_identity
476    InvalidOcspResponse,
477
478    /// The certificate is valid, but the handshake is rejected for other
479    /// reasons.
480    ApplicationVerificationFailure,
481
482    /// Any other error.
483    ///
484    /// This can be used by custom verifiers to expose the underlying error
485    /// (where they are not better described by the more specific errors
486    /// above).
487    ///
488    /// It is also used by the default verifier in case its error is
489    /// not covered by the above common cases.
490    ///
491    /// Enums holding this variant will never compare equal to each other.
492    Other(OtherError),
493}
494
495impl PartialEq<Self> for CertificateError {
496    fn eq(&self, other: &Self) -> bool {
497        use CertificateError::*;
498        match (self, other) {
499            (BadEncoding, BadEncoding) => true,
500            (Expired, Expired) => true,
501            (
502                ExpiredContext {
503                    time: left_time,
504                    not_after: left_not_after,
505                },
506                ExpiredContext {
507                    time: right_time,
508                    not_after: right_not_after,
509                },
510            ) => (left_time, left_not_after) == (right_time, right_not_after),
511            (NotValidYet, NotValidYet) => true,
512            (
513                NotValidYetContext {
514                    time: left_time,
515                    not_before: left_not_before,
516                },
517                NotValidYetContext {
518                    time: right_time,
519                    not_before: right_not_before,
520                },
521            ) => (left_time, left_not_before) == (right_time, right_not_before),
522            (Revoked, Revoked) => true,
523            (UnhandledCriticalExtension, UnhandledCriticalExtension) => true,
524            (UnknownIssuer, UnknownIssuer) => true,
525            (IssuerKeyUsageMissingCertSign, IssuerKeyUsageMissingCertSign) => true,
526            (BadSignature, BadSignature) => true,
527            (KeyUsageMissingDigitalSignature, KeyUsageMissingDigitalSignature) => true,
528            (
529                UnsupportedSignatureAlgorithm {
530                    signature_algorithm_id: left_signature_algorithm_id,
531                    supported_algorithms: left_supported_algorithms,
532                },
533                UnsupportedSignatureAlgorithm {
534                    signature_algorithm_id: right_signature_algorithm_id,
535                    supported_algorithms: right_supported_algorithms,
536                },
537            ) => {
538                (left_signature_algorithm_id, left_supported_algorithms)
539                    == (right_signature_algorithm_id, right_supported_algorithms)
540            }
541            (
542                UnsupportedSignatureAlgorithmForPublicKey {
543                    signature_algorithm_id: left_signature_algorithm_id,
544                    public_key_algorithm_id: left_public_key_algorithm_id,
545                },
546                UnsupportedSignatureAlgorithmForPublicKey {
547                    signature_algorithm_id: right_signature_algorithm_id,
548                    public_key_algorithm_id: right_public_key_algorithm_id,
549                },
550            ) => {
551                (left_signature_algorithm_id, left_public_key_algorithm_id)
552                    == (right_signature_algorithm_id, right_public_key_algorithm_id)
553            }
554            (NotValidForName, NotValidForName) => true,
555            (
556                NotValidForNameContext {
557                    expected: left_expected,
558                    presented: left_presented,
559                },
560                NotValidForNameContext {
561                    expected: right_expected,
562                    presented: right_presented,
563                },
564            ) => (left_expected, left_presented) == (right_expected, right_presented),
565            (InvalidPurpose, InvalidPurpose) => true,
566            (
567                InvalidPurposeContext {
568                    required: left_required,
569                    presented: left_presented,
570                },
571                InvalidPurposeContext {
572                    required: right_required,
573                    presented: right_presented,
574                },
575            ) => (left_required, left_presented) == (right_required, right_presented),
576            (InvalidOcspResponse, InvalidOcspResponse) => true,
577            (ApplicationVerificationFailure, ApplicationVerificationFailure) => true,
578            (UnknownRevocationStatus, UnknownRevocationStatus) => true,
579            (ExpiredRevocationList, ExpiredRevocationList) => true,
580            (
581                ExpiredRevocationListContext {
582                    time: left_time,
583                    next_update: left_next_update,
584                },
585                ExpiredRevocationListContext {
586                    time: right_time,
587                    next_update: right_next_update,
588                },
589            ) => (left_time, left_next_update) == (right_time, right_next_update),
590            _ => false,
591        }
592    }
593}
594
595// The following mapping are heavily referenced in:
596// * [OpenSSL Implementation](https://github.com/openssl/openssl/blob/45bb98bfa223efd3258f445ad443f878011450f0/ssl/statem/statem_lib.c#L1434)
597// * [BoringSSL Implementation](https://github.com/google/boringssl/blob/583c60bd4bf76d61b2634a58bcda99a92de106cb/ssl/ssl_x509.cc#L1323)
598impl From<&CertificateError> for AlertDescription {
599    fn from(e: &CertificateError) -> Self {
600        use CertificateError::*;
601        match e {
602            BadEncoding | UnhandledCriticalExtension | NotValidForName => Self::BadCertificate,
603            NotValidForNameContext { .. } => Self::BadCertificate,
604            // RFC 5246/RFC 9846
605            // certificate_expired
606            //  A certificate has expired or **is not currently valid**.
607            Expired | ExpiredContext { .. } | NotValidYet | NotValidYetContext { .. } => {
608                Self::CertificateExpired
609            }
610            Revoked => Self::CertificateRevoked,
611            // OpenSSL, BoringSSL and AWS-LC all generate an Unknown CA alert for
612            // the case where revocation status can not be determined, so we do the same here.
613            UnknownIssuer
614            | IssuerKeyUsageMissingCertSign
615            | UnknownRevocationStatus
616            | ExpiredRevocationList
617            | ExpiredRevocationListContext { .. } => Self::UnknownCa,
618            InvalidOcspResponse => Self::BadCertificateStatusResponse,
619            BadSignature
620            | UnsupportedSignatureAlgorithm { .. }
621            | UnsupportedSignatureAlgorithmForPublicKey { .. } => Self::DecryptError,
622            InvalidPurpose | InvalidPurposeContext { .. } | KeyUsageMissingDigitalSignature => {
623                Self::UnsupportedCertificate
624            }
625            ApplicationVerificationFailure => Self::AccessDenied,
626            // RFC 5246/RFC 9846
627            // certificate_unknown
628            //  Some other (unspecified) issue arose in processing the
629            //  certificate, rendering it unacceptable.
630            Other(..) => Self::CertificateUnknown,
631        }
632    }
633}
634
635impl fmt::Display for CertificateError {
636    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
637        match self {
638            #[cfg(feature = "std")]
639            Self::NotValidForNameContext {
640                expected,
641                presented,
642            } => {
643                write!(
644                    f,
645                    "certificate not valid for name {:?}; certificate ",
646                    expected.to_str()
647                )?;
648
649                match presented.as_slice() {
650                    &[] => write!(
651                        f,
652                        "is not valid for any names (according to its subjectAltName extension)"
653                    ),
654                    [one] => write!(f, "is only valid for {one}"),
655                    many => {
656                        write!(f, "is only valid for ")?;
657
658                        let n = many.len();
659                        let all_but_last = &many[..n - 1];
660                        let last = &many[n - 1];
661
662                        for (i, name) in all_but_last.iter().enumerate() {
663                            write!(f, "{name}")?;
664                            if i < n - 2 {
665                                write!(f, ", ")?;
666                            }
667                        }
668                        write!(f, " or {last}")
669                    }
670                }
671            }
672
673            Self::ExpiredContext { time, not_after } => write!(
674                f,
675                "certificate expired: verification time {} (UNIX), \
676                 but certificate is not valid after {} \
677                 ({} seconds ago)",
678                time.as_secs(),
679                not_after.as_secs(),
680                time.as_secs()
681                    .saturating_sub(not_after.as_secs())
682            ),
683
684            Self::NotValidYetContext { time, not_before } => write!(
685                f,
686                "certificate not valid yet: verification time {} (UNIX), \
687                 but certificate is not valid before {} \
688                 ({} seconds in future)",
689                time.as_secs(),
690                not_before.as_secs(),
691                not_before
692                    .as_secs()
693                    .saturating_sub(time.as_secs())
694            ),
695
696            Self::ExpiredRevocationListContext { time, next_update } => write!(
697                f,
698                "certificate revocation list expired: \
699                 verification time {} (UNIX), \
700                 but CRL is not valid after {} \
701                 ({} seconds ago)",
702                time.as_secs(),
703                next_update.as_secs(),
704                time.as_secs()
705                    .saturating_sub(next_update.as_secs())
706            ),
707
708            Self::InvalidPurposeContext {
709                required,
710                presented,
711            } => {
712                write!(
713                    f,
714                    "certificate does not allow extended key usage for {required}, allows "
715                )?;
716                for (i, eku) in presented.iter().enumerate() {
717                    if i > 0 {
718                        write!(f, ", ")?;
719                    }
720                    write!(f, "{eku}")?;
721                }
722                Ok(())
723            }
724
725            Self::Other(other) => write!(f, "{other}"),
726
727            other => write!(f, "{other:?}"),
728        }
729    }
730}
731
732enum_builder! {
733    /// The `AlertDescription` TLS protocol enum.  Values in this enum are taken
734    /// from the various RFCs covering TLS, and are listed by IANA.
735    ///
736    /// The list of alerts is available at
737    /// <https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-6>.
738    pub struct AlertDescription(pub u8);
739
740    enum AlertDescriptionName {
741        /// Notifies the recipient that the sender will not send any more messages on this connection.
742        ///
743        /// <https://www.rfc-editor.org/info/rfc9846/#section-6.1-2.2.1>
744        CloseNotify => 0x00,
745
746        /// An inappropriate message was received.
747        ///
748        /// E.g., the wrong handshake message, premature Application Data, etc.
749        /// This alert should never be observed in communication between proper implementations.
750        ///
751        /// <https://www.rfc-editor.org/info/rfc9846/#section-6.2-4.2.1>
752        UnexpectedMessage => 0x0a,
753
754        /// This alert is returned if a record is received which cannot be deprotected.
755        ///
756        /// Because AEAD algorithms combine decryption and verification,
757        /// and also to avoid side-channel attacks,
758        /// this alert is used for all deprotection failures.
759        /// This alert should never be observed in communication between proper implementations,
760        /// except when messages were corrupted in the network.
761        ///
762        /// <https://www.rfc-editor.org/info/rfc9846/#section-6.2-4.4.1>
763        BadRecordMac => 0x14,
764
765        /// Reserved. Used in TLS versions prior to 1.3.
766        ///
767        /// According to TLS 1.2 specification at <https://www.rfc-editor.org/info/rfc5246/>
768        /// "This alert was used in some earlier versions of TLS, and may have
769        /// permitted certain attacks against the CBC mode.
770        /// It MUST NOT be sent by compliant implementations."
771        DecryptionFailed => 0x15,
772
773        /// TLS record larger than the limit was received.
774        ///
775        /// A TLSCiphertext record was received that had a length more than 214 + 256 bytes,
776        /// or a record decrypted to a TLSPlaintext record with more than 214 bytes
777        /// (or some other negotiated limit).
778        /// This alert should never be observed in communication between proper implementations,
779        /// except when messages were corrupted in the network.
780        ///
781        /// <https://www.rfc-editor.org/info/rfc9846/#section-6.2-4.6.1>
782        RecordOverflow => 0x16,
783
784        /// Reserved. Used in TLS versions prior to 1.3.
785        ///
786        /// The decompression function received improper input
787        /// (e.g., data that would expand to excessive length).
788        /// This message is always fatal and should never be observed
789        /// in communication between proper implementations.
790        ///
791        /// <https://www.rfc-editor.org/info/rfc5246/>
792        DecompressionFailure => 0x1e,
793
794        /// The sender was unable to negotiate an acceptable set of security parameters.
795        ///
796        /// <https://www.rfc-editor.org/info/rfc9846/#section-6.2-4.8.1>
797        HandshakeFailure => 0x28,
798
799        /// Reserved. Used in SSLv3 but not in TLS.
800        NoCertificate => 0x29,
801
802        /// A certificate was corrupt, contained signatures that did not verify correctly, etc.
803        ///
804        /// <https://www.rfc-editor.org/info/rfc9846/#section-6.2-4.10.1>
805        BadCertificate => 0x2a,
806
807        /// A certificate was of an unsupported type.
808        ///
809        /// <https://www.rfc-editor.org/info/rfc9846/#section-6.2-4.12.1>
810        UnsupportedCertificate => 0x2b,
811
812        /// A certificate was revoked by its signer.
813        ///
814        /// <https://www.rfc-editor.org/info/rfc9846/#section-6.2-4.14.1>
815        CertificateRevoked => 0x2c,
816
817        /// A certificate has expired or is not currently valid.
818        ///
819        /// <https://www.rfc-editor.org/info/rfc9846/#section-6.2-4.16.1>
820        CertificateExpired => 0x2d,
821
822        /// Unspecified issue arose in processing the certificate, rendering it unacceptable.
823        ///
824        /// <https://www.rfc-editor.org/info/rfc9846/#section-6.2-4.18.1>
825        CertificateUnknown => 0x2e,
826
827        /// A field in the handshake was incorrect or inconsistent with other fields.
828        ///
829        /// This alert is used for errors which conform to the formal protocol syntax
830        /// but are otherwise incorrect.
831        ///
832        /// <https://www.rfc-editor.org/info/rfc9846/#section-6.2-4.20.1>
833        IllegalParameter => 0x2f,
834
835        /// The CA certificate could not be located or could not be matched with a known trust anchor.
836        ///
837        /// <https://www.rfc-editor.org/info/rfc9846/#section-6.2-4.22.1>
838        UnknownCa => 0x30,
839
840        /// A valid certificate or PSK was received, but did not pass access control.
841        ///
842        /// <https://www.rfc-editor.org/info/rfc9846/#section-6.2-4.24.1>
843        AccessDenied => 0x31,
844
845        /// A message could not be decoded.
846        ///
847        /// Some field was out of the specified range
848        /// or the length of the message was incorrect.
849        /// This alert is used for errors where the message does not conform
850        /// to the formal protocol syntax.
851        /// This alert should never be observed in communication between proper implementations,
852        /// except when messages were corrupted in the network.
853        ///
854        /// <https://www.rfc-editor.org/info/rfc9846/#section-6.2-4.26.1>
855        DecodeError => 0x32,
856
857        /// A handshake (not record layer) cryptographic operation failed.
858        ///
859        /// <https://www.rfc-editor.org/info/rfc9846/#section-6.2-4.28.1>
860        DecryptError => 0x33,
861
862        /// Reserved. Used in TLS 1.0 but not TLS 1.1 or later.
863        ExportRestriction => 0x3c,
864
865        /// Peer has attempted to negotiate a recognized but not supported protocol version.
866        ///
867        /// <https://www.rfc-editor.org/info/rfc9846/#section-6.2-4.30.1>
868        ProtocolVersion => 0x46,
869
870        /// The server requires parameters more secure than those supported by the client.
871        ///
872        /// <https://www.rfc-editor.org/info/rfc9846/#section-6.2-4.32.1>
873        InsufficientSecurity => 0x47,
874
875        /// An internal error unrelated to the peer or the correctness of the protocol.
876        ///
877        /// <https://www.rfc-editor.org/info/rfc9846/#section-6.2-4.34.1>
878        InternalError => 0x50,
879
880        /// Sent by a server in response to an invalid connection retry attempt from a client.
881        ///
882        /// <https://www.rfc-editor.org/info/rfc9846/#section-6.2-4.36.1>
883        InappropriateFallback => 0x56,
884
885        /// The sender is canceling the handshake for some reason unrelated to a protocol failure.
886        ///
887        /// <https://www.rfc-editor.org/info/rfc9846/#section-6.1-2.4.1>
888        UserCanceled => 0x5a,
889
890        /// Reserved. Used in TLS versions prior to 1.3.
891        ///
892        /// See TLS 1.2 specification at <https://www.rfc-editor.org/info/rfc5246/>
893        /// for the description.
894        NoRenegotiation => 0x64,
895
896        /// A handshake message does not contain an extension that is mandatory to send.
897        ///
898        /// <https://www.rfc-editor.org/info/rfc9846/#section-6.2-4.38.1>
899        MissingExtension => 0x6d,
900
901        /// Received an extension not offered in ClientHello or CertificateRequest.
902        ///
903        /// <https://www.rfc-editor.org/info/rfc9846/#section-6.2-4.38.1>
904        UnsupportedExtension => 0x6e,
905
906        /// The server is unable to obtain certificate sent as an URL by the client.
907        ///
908        /// <https://datatracker.ietf.org/doc/html/rfc6066>
909        CertificateUnobtainable => 0x6f,
910
911        /// The server does not recognize SNI sent by the client.
912        ///
913        /// <https://datatracker.ietf.org/doc/html/rfc6066>
914        UnrecognizedName => 0x70,
915
916        /// <https://datatracker.ietf.org/doc/html/rfc6066>
917        BadCertificateStatusResponse => 0x71,
918
919        /// Reserved. Used in TLS versions prior to 1.3.
920        ///
921        /// <https://datatracker.ietf.org/doc/html/rfc6066>
922        BadCertificateHashValue => 0x72,
923
924        /// The server does not recognize PSK identity.
925        ///
926        /// <https://datatracker.ietf.org/doc/html/rfc4279>
927        UnknownPskIdentity => 0x73,
928
929        /// A client certificate is desired but none was provided by the client.
930        ///
931        /// <https://datatracker.ietf.org/doc/html/rfc9846#section-6.2-4.48.1>
932        CertificateRequired => 0x74,
933
934        /// An error condition in cases when either no more specific error is available
935        /// or the sender wishes to conceal the specific error code.
936        ///
937        /// <https://datatracker.ietf.org/doc/html/rfc9846#section-6.2-4.49>
938        GeneralError => 0x75,
939
940        /// A client ALPN extension advertises only protocols that the server does not support.
941        ///
942        /// <https://datatracker.ietf.org/doc/html/rfc9846#section-6.2-4.52.1>
943        NoApplicationProtocol => 0x78,
944
945        /// Use of Encrypted Client Hello is required.
946        ///
947        /// <https://datatracker.ietf.org/doc/html/rfc9849#section-11.2>
948        EncryptedClientHelloRequired => 0x79,
949    }
950}
951
952impl fmt::Display for AlertDescription {
953    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
954        let Ok(known) = AlertDescriptionName::try_from(*self) else {
955            return write!(f, "sent an unknown alert (0x{:02x?})", self.0);
956        };
957
958        // these should be:
959        // - in past tense
960        // - be syntactically correct if prefaced with 'the peer' to describe
961        //   received alerts
962        match known {
963            // this is normal.
964            AlertDescriptionName::CloseNotify => write!(f, "cleanly closed the connection"),
965
966            // these are abnormal.  they are usually symptomatic of an interop failure.
967            // please file a bug report.
968            AlertDescriptionName::UnexpectedMessage => write!(f, "received an unexpected message"),
969            AlertDescriptionName::BadRecordMac => write!(f, "failed to verify a message"),
970            AlertDescriptionName::RecordOverflow => write!(f, "rejected an over-length message"),
971            AlertDescriptionName::IllegalParameter => write!(
972                f,
973                "rejected a message because a field was incorrect or inconsistent"
974            ),
975            AlertDescriptionName::DecodeError => write!(f, "failed to decode a message"),
976            AlertDescriptionName::DecryptError => {
977                write!(f, "failed to perform a handshake cryptographic operation")
978            }
979            AlertDescriptionName::InappropriateFallback => {
980                write!(f, "detected an attempted version downgrade")
981            }
982            AlertDescriptionName::MissingExtension => {
983                write!(f, "required a specific extension that was not provided")
984            }
985            AlertDescriptionName::UnsupportedExtension => {
986                write!(f, "rejected an unsolicited extension")
987            }
988            AlertDescriptionName::GeneralError => write!(f, "experienced a general error"),
989
990            // these are deprecated by TLS1.3 and should be very rare (but possible
991            // with TLS1.2 or earlier peers)
992            AlertDescriptionName::DecryptionFailed => write!(f, "failed to decrypt a message"),
993            AlertDescriptionName::DecompressionFailure => {
994                write!(f, "failed to decompress a message")
995            }
996            AlertDescriptionName::NoCertificate => write!(f, "found no certificate"),
997            AlertDescriptionName::ExportRestriction => {
998                write!(f, "refused due to export restrictions")
999            }
1000            AlertDescriptionName::NoRenegotiation => {
1001                write!(f, "rejected an attempt at renegotiation")
1002            }
1003            AlertDescriptionName::CertificateUnobtainable => {
1004                write!(f, "failed to retrieve its certificate")
1005            }
1006            AlertDescriptionName::BadCertificateHashValue => {
1007                write!(f, "rejected the `certificate_hash` extension")
1008            }
1009
1010            // this is fairly normal. it means a server cannot choose compatible parameters
1011            // given our offer.  please use ssllabs.com or similar to investigate what parameters
1012            // the server supports.
1013            AlertDescriptionName::HandshakeFailure => write!(
1014                f,
1015                "failed to negotiate an acceptable set of security parameters"
1016            ),
1017            AlertDescriptionName::ProtocolVersion => {
1018                write!(f, "did not support a suitable TLS version")
1019            }
1020            AlertDescriptionName::InsufficientSecurity => {
1021                write!(f, "required a higher security level than was offered")
1022            }
1023
1024            // these usually indicate a local misconfiguration, either in certificate selection
1025            // or issuance.
1026            AlertDescriptionName::BadCertificate => {
1027                write!(
1028                    f,
1029                    "rejected the certificate as corrupt or incorrectly signed"
1030                )
1031            }
1032            AlertDescriptionName::UnsupportedCertificate => {
1033                write!(f, "did not support the certificate")
1034            }
1035            AlertDescriptionName::CertificateRevoked => {
1036                write!(f, "found the certificate to be revoked")
1037            }
1038            AlertDescriptionName::CertificateExpired => {
1039                write!(f, "found the certificate to be expired")
1040            }
1041            AlertDescriptionName::CertificateUnknown => {
1042                write!(f, "rejected the certificate for an unspecified reason")
1043            }
1044            AlertDescriptionName::UnknownCa => {
1045                write!(f, "found the certificate was not issued by a trusted CA")
1046            }
1047            AlertDescriptionName::BadCertificateStatusResponse => {
1048                write!(f, "rejected the certificate status response")
1049            }
1050            // typically this means client authentication is required, in TLS1.2...
1051            AlertDescriptionName::AccessDenied => write!(f, "denied access"),
1052            // and in TLS1.3...
1053            AlertDescriptionName::CertificateRequired => {
1054                write!(f, "required a client certificate")
1055            }
1056
1057            AlertDescriptionName::InternalError => write!(f, "encountered an internal error"),
1058            AlertDescriptionName::UserCanceled => write!(f, "canceled the handshake"),
1059
1060            // rejection of SNI (uncommon; usually servers behave as if it was not sent)
1061            AlertDescriptionName::UnrecognizedName => {
1062                write!(f, "did not recognize a name in the `server_name` extension")
1063            }
1064
1065            // rejection of PSK connections (NYI in this library); indicates a local
1066            // misconfiguration.
1067            AlertDescriptionName::UnknownPskIdentity => {
1068                write!(f, "did not recognize any offered PSK identity")
1069            }
1070
1071            // rejection of ALPN (varying levels of support, but missing support is
1072            // often dangerous if the peers fail to agree on the same protocol)
1073            AlertDescriptionName::NoApplicationProtocol => write!(
1074                f,
1075                "did not support any of the offered application protocols"
1076            ),
1077
1078            // ECH requirement by clients, see
1079            // <https://datatracker.ietf.org/doc/html/rfc9849#name-update-of-the-tls-alert-reg>
1080            AlertDescriptionName::EncryptedClientHelloRequired => {
1081                write!(f, "required use of encrypted client hello")
1082            }
1083        }
1084    }
1085}
1086
1087/// A corrupt TLS message payload that resulted in an error.
1088#[non_exhaustive]
1089#[derive(Debug, Clone, Copy, PartialEq)]
1090pub enum InvalidMessage {
1091    /// A certificate payload exceeded rustls's 64KB limit
1092    CertificatePayloadTooLarge,
1093    /// An advertised message was larger then expected.
1094    HandshakePayloadTooLarge,
1095    /// The peer sent us a syntactically incorrect ChangeCipherSpec payload.
1096    InvalidCcs,
1097    /// An unknown content type was encountered during message decoding.
1098    InvalidContentType,
1099    /// A peer sent an invalid certificate status type
1100    InvalidCertificateStatusType,
1101    /// Context was incorrectly attached to a certificate request during a handshake.
1102    InvalidCertRequest,
1103    /// A peer's DH params could not be decoded
1104    InvalidDhParams,
1105    /// A message was zero-length when its record kind forbids it.
1106    InvalidEmptyPayload,
1107    /// A peer sent an unexpected key update request.
1108    InvalidKeyUpdate,
1109    /// A peer's server name could not be decoded
1110    InvalidServerName,
1111    /// A TLS message payload was larger then allowed by the specification.
1112    MessageTooLarge,
1113    /// Message is shorter than the expected length
1114    MessageTooShort,
1115    /// A peer sent a recognized extension type in a message where it is not permitted
1116    MisplacedExtension(u16),
1117    /// Missing data for the named handshake payload value
1118    MissingData(&'static str),
1119    /// A peer did not advertise its supported key exchange groups.
1120    MissingKeyExchange,
1121    /// A peer sent an empty list of signature schemes
1122    NoSignatureSchemes,
1123    /// Trailing data found for the named handshake payload value
1124    TrailingData(&'static str),
1125    /// A peer sent an unexpected message type.
1126    UnexpectedMessage(&'static str),
1127    /// An unknown TLS protocol was encountered during message decoding.
1128    UnknownProtocolVersion,
1129    /// A peer sent a non-null compression method.
1130    UnsupportedCompression,
1131    /// A peer sent an unknown elliptic curve type.
1132    UnsupportedCurveType,
1133    /// A peer sent an unsupported key exchange algorithm.
1134    UnsupportedKeyExchangeAlgorithm(KeyExchangeAlgorithm),
1135    /// A server sent an empty ticket
1136    EmptyTicketValue,
1137    /// A peer sent an empty list of items, but a non-empty list is required.
1138    ///
1139    /// The argument names the context.
1140    IllegalEmptyList(&'static str),
1141    /// A peer sent a message where a given extension type was repeated
1142    DuplicateExtension(u16),
1143    /// A peer sent a message with a PSK offer extension in wrong position
1144    PreSharedKeyIsNotFinalExtension,
1145    /// A server sent a HelloRetryRequest with an unknown extension
1146    UnknownHelloRetryRequestExtension,
1147    /// The peer sent a TLS1.3 Certificate with an unknown extension
1148    UnknownCertificateExtension,
1149    /// A peer sent an empty TLS1.3 `certificate_authorities` extension
1150    IllegalEmptyCertificateAuthoritiesExtension,
1151}
1152
1153impl From<InvalidMessage> for AlertDescription {
1154    fn from(e: InvalidMessage) -> Self {
1155        match e {
1156            InvalidMessage::PreSharedKeyIsNotFinalExtension => Self::IllegalParameter,
1157            InvalidMessage::DuplicateExtension(_) => Self::IllegalParameter,
1158            InvalidMessage::MisplacedExtension(_) => Self::IllegalParameter,
1159            InvalidMessage::UnsupportedCompression => Self::IllegalParameter,
1160            InvalidMessage::UnknownHelloRetryRequestExtension => Self::UnsupportedExtension,
1161            InvalidMessage::CertificatePayloadTooLarge => Self::BadCertificate,
1162            _ => Self::DecodeError,
1163        }
1164    }
1165}
1166
1167/// The set of cases where we failed to make a connection because we thought
1168/// the peer was misbehaving.
1169///
1170/// This is `non_exhaustive`: we might add or stop using items here in minor
1171/// versions.  We also don't document what they mean.  Generally a user of
1172/// rustls shouldn't vary its behaviour on these error codes, and there is
1173/// nothing it can do to improve matters.
1174///
1175/// Please file a bug against rustls if you see `Error::PeerMisbehaved` in
1176/// the wild.
1177#[expect(missing_docs)]
1178#[non_exhaustive]
1179#[derive(Clone, Copy, Debug, PartialEq)]
1180pub enum PeerMisbehaved {
1181    AttemptedDowngradeToTls12WhenTls13IsSupported,
1182    BadCertChainExtensions,
1183    CipherSuiteDifferedOnRetry,
1184    DisallowedEncryptedExtension,
1185    DuplicateClientHelloExtensions,
1186    DuplicateEncryptedExtensions,
1187    DuplicateHelloRetryRequestExtensions,
1188    DuplicateNewSessionTicketExtensions,
1189    DuplicateServerHelloExtensions,
1190    DuplicateServerNameTypes,
1191    EarlyDataAcceptedWithVariedApplicationProtocol,
1192    EarlyDataAttemptedInSecondClientHello,
1193    EarlyDataExtensionWithoutResumption,
1194    EarlyDataOfferedWithVariedCipherSuite,
1195    EchAcceptanceVariedAfterRetry,
1196    EmptyFragment,
1197    HandshakeHashVariedAfterRetry,
1198    /// Received an alert with an undefined level and the given [`AlertDescription`]
1199    IllegalAlertLevel(u8, AlertDescription),
1200    IllegalHelloRetryRequestWithEmptyCookie,
1201    IllegalHelloRetryRequestWithNoChanges,
1202    IllegalHelloRetryRequestWithOfferedGroup,
1203    IllegalHelloRetryRequestWithUnofferedCipherSuite,
1204    IllegalHelloRetryRequestWithUnofferedNamedGroup,
1205    IllegalHelloRetryRequestWithUnsupportedVersion,
1206    IllegalHelloRetryRequestWithWrongLegacyVersion,
1207    IllegalHelloRetryRequestWithWrongSessionId,
1208    IllegalHelloRetryRequestWithInvalidEch,
1209    IllegalMiddleboxChangeCipherSpec,
1210    IllegalTlsInnerPlaintext,
1211    /// Received a warning alert with the given [`AlertDescription`]
1212    IllegalWarningAlert(AlertDescription),
1213    IncorrectBinder,
1214    IncorrectFinished,
1215    InvalidCertCompression,
1216    InvalidMaxEarlyDataSize,
1217    InvalidKeyShare,
1218    KeyEpochWithPendingFragment,
1219    KeyUpdateReceivedInQuicConnection,
1220    MessageInterleavedWithHandshakeMessage,
1221    MissingBinderInPskExtension,
1222    MissingKeyShare,
1223    MissingPskExtensionInSecondClientHello,
1224    MissingPskModesExtension,
1225    MissingQuicTransportParameters,
1226    NoCertificatesPresented,
1227    NonEmptyRenegotiationInfo,
1228    OfferedDuplicateCertificateCompressions,
1229    OfferedDuplicateKeyShares,
1230    OfferedEarlyDataWithOldProtocolVersion,
1231    OfferedEmptyApplicationProtocol,
1232    OfferedIncorrectCompressions,
1233    PskExtensionMustBeLast,
1234    PskExtensionWithMismatchedIdsAndBinders,
1235    RefusedToFollowHelloRetryRequest,
1236    RejectedEarlyDataInterleavedWithHandshakeMessage,
1237    ResumptionAttemptedWithVariedEms,
1238    ResumptionOfferedWithVariedCipherSuite,
1239    ResumptionOfferedWithVariedEms,
1240    ResumptionOfferedWithIncompatibleCipherSuite,
1241    SelectedDifferentCipherSuiteAfterRetry,
1242    SelectedDifferentProtocolVersionAfterRetry,
1243    SelectedInvalidPsk,
1244    SelectedTls12UsingTls13VersionExtension,
1245    SelectedTls13UsingLegacyVersionField,
1246    SelectedUnofferedApplicationProtocol,
1247    SelectedUnofferedCertCompression,
1248    SelectedUnofferedCipherSuite,
1249    SelectedUnofferedCompression,
1250    SelectedUnofferedKxGroup,
1251    SelectedUnofferedPsk,
1252    ServerEchoedCompatibilitySessionId,
1253    ServerHelloMustOfferUncompressedEcPoints,
1254    ServerNameDifferedOnRetry,
1255    ServerNameMustContainOneHostName,
1256    SignedKxWithWrongAlgorithm,
1257    SignedHandshakeWithUnadvertisedSigScheme,
1258    TooManyEmptyFragments,
1259    TooManyConsecutiveHandshakeMessagesAfterHandshake,
1260    TooManyRenegotiationRequests,
1261    TooManyWarningAlertsReceived,
1262    TooMuchEarlyDataReceived,
1263    UnexpectedCleartextExtension,
1264    UnmatchedSessionId,
1265    UnsolicitedCertExtension,
1266    UnsolicitedEncryptedExtension,
1267    UnsolicitedSctList,
1268    UnsolicitedServerHelloExtension,
1269    WrongGroupForKeyShare,
1270    UnsolicitedEchExtension,
1271    IllegalTls13ContentType,
1272}
1273
1274impl From<PeerMisbehaved> for AlertDescription {
1275    fn from(e: PeerMisbehaved) -> Self {
1276        match e {
1277            PeerMisbehaved::DisallowedEncryptedExtension
1278            | PeerMisbehaved::IllegalHelloRetryRequestWithInvalidEch
1279            | PeerMisbehaved::UnexpectedCleartextExtension
1280            | PeerMisbehaved::UnsolicitedEchExtension
1281            | PeerMisbehaved::UnsolicitedEncryptedExtension
1282            | PeerMisbehaved::UnsolicitedServerHelloExtension => Self::UnsupportedExtension,
1283
1284            PeerMisbehaved::IllegalMiddleboxChangeCipherSpec
1285            | PeerMisbehaved::KeyEpochWithPendingFragment
1286            | PeerMisbehaved::KeyUpdateReceivedInQuicConnection
1287            | PeerMisbehaved::IllegalTls13ContentType => Self::UnexpectedMessage,
1288
1289            PeerMisbehaved::IllegalWarningAlert(_) => Self::DecodeError,
1290
1291            PeerMisbehaved::IncorrectBinder | PeerMisbehaved::IncorrectFinished => {
1292                Self::DecryptError
1293            }
1294
1295            PeerMisbehaved::InvalidCertCompression
1296            | PeerMisbehaved::SelectedUnofferedCertCompression => Self::BadCertificate,
1297
1298            PeerMisbehaved::MissingKeyShare
1299            | PeerMisbehaved::MissingPskExtensionInSecondClientHello
1300            | PeerMisbehaved::MissingPskModesExtension
1301            | PeerMisbehaved::MissingQuicTransportParameters => Self::MissingExtension,
1302
1303            PeerMisbehaved::NoCertificatesPresented => Self::CertificateRequired,
1304
1305            PeerMisbehaved::NonEmptyRenegotiationInfo => Self::HandshakeFailure,
1306
1307            PeerMisbehaved::IllegalHelloRetryRequestWithWrongLegacyVersion
1308            | PeerMisbehaved::SelectedTls13UsingLegacyVersionField => Self::ProtocolVersion,
1309
1310            _ => Self::IllegalParameter,
1311        }
1312    }
1313}
1314
1315/// The set of cases where we failed to make a connection because a peer
1316/// doesn't support a TLS version/feature we require.
1317///
1318/// This is `non_exhaustive`: we might add or stop using items here in minor
1319/// versions.
1320#[expect(missing_docs)]
1321#[non_exhaustive]
1322#[derive(Clone, Copy, Debug, PartialEq)]
1323pub enum PeerIncompatible {
1324    EcPointsExtensionRequired,
1325    ExtendedMainSecretExtensionRequired,
1326    IncorrectCertificateTypeExtension,
1327    KeyShareExtensionRequired,
1328    MultipleRawKeys,
1329    NamedGroupsExtensionRequired,
1330    NoCertificateRequestSignatureSchemesInCommon,
1331    NoCipherSuitesInCommon,
1332    NoEcPointFormatsInCommon,
1333    NoKxGroupsInCommon,
1334    NoSignatureSchemesInCommon,
1335    NoServerNameProvided,
1336    NullCompressionRequired,
1337    ServerDoesNotSupportTls12Or13,
1338    ServerSentHelloRetryRequestWithUnknownExtension,
1339    ServerTlsVersionIsDisabledByOurConfig,
1340    SignatureAlgorithmsExtensionRequired,
1341    SupportedVersionsExtensionRequired,
1342    Tls12NotOffered,
1343    Tls12NotOfferedOrEnabled,
1344    Tls13RequiredForQuic,
1345    UncompressedEcPointsRequired,
1346    UnknownCertificateType(u8),
1347    UnsolicitedCertificateTypeExtension,
1348}
1349
1350impl From<PeerIncompatible> for AlertDescription {
1351    fn from(e: PeerIncompatible) -> Self {
1352        match e {
1353            PeerIncompatible::NullCompressionRequired => Self::IllegalParameter,
1354
1355            PeerIncompatible::ServerTlsVersionIsDisabledByOurConfig
1356            | PeerIncompatible::SupportedVersionsExtensionRequired
1357            | PeerIncompatible::Tls12NotOffered
1358            | PeerIncompatible::Tls12NotOfferedOrEnabled
1359            | PeerIncompatible::Tls13RequiredForQuic => Self::ProtocolVersion,
1360
1361            PeerIncompatible::KeyShareExtensionRequired => Self::MissingExtension,
1362
1363            PeerIncompatible::UnknownCertificateType(_) => Self::UnsupportedCertificate,
1364
1365            _ => Self::HandshakeFailure,
1366        }
1367    }
1368}
1369
1370/// Extended Key Usage (EKU) purpose values.
1371///
1372/// These are usually represented as OID values in the certificate's extension (if present), but
1373/// we represent the values that are most relevant to rustls as named enum variants.
1374#[non_exhaustive]
1375#[derive(Clone, Debug, Eq, PartialEq)]
1376pub enum ExtendedKeyPurpose {
1377    /// Client authentication
1378    ClientAuth,
1379    /// Server authentication
1380    ServerAuth,
1381    /// Other EKU values
1382    ///
1383    /// Represented here as a `Vec<usize>` for human readability.
1384    Other(Vec<usize>),
1385}
1386
1387impl ExtendedKeyPurpose {
1388    #[cfg(feature = "webpki")]
1389    pub(crate) fn for_values(values: impl Iterator<Item = usize>) -> Self {
1390        let values = values.collect::<Vec<_>>();
1391        match &*values {
1392            ExtendedKeyUsage::CLIENT_AUTH_REPR => Self::ClientAuth,
1393            ExtendedKeyUsage::SERVER_AUTH_REPR => Self::ServerAuth,
1394            _ => Self::Other(values),
1395        }
1396    }
1397}
1398
1399impl fmt::Display for ExtendedKeyPurpose {
1400    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1401        match self {
1402            Self::ClientAuth => write!(f, "client authentication"),
1403            Self::ServerAuth => write!(f, "server authentication"),
1404            Self::Other(values) => {
1405                for (i, value) in values.iter().enumerate() {
1406                    if i > 0 {
1407                        write!(f, ", ")?;
1408                    }
1409                    write!(f, "{value}")?;
1410                }
1411                Ok(())
1412            }
1413        }
1414    }
1415}
1416
1417/// The ways in which a certificate revocation list (CRL) can be invalid.
1418#[non_exhaustive]
1419#[derive(Debug, Clone)]
1420pub enum CertRevocationListError {
1421    /// The CRL had a bad signature from its issuer.
1422    BadSignature,
1423
1424    /// The CRL's signature was made with an unsupported algorithm.
1425    UnsupportedSignatureAlgorithm {
1426        /// The signature algorithm OID that was unsupported.
1427        signature_algorithm_id: Vec<u8>,
1428        /// Supported algorithms that were available for signature verification.
1429        supported_algorithms: Vec<AlgorithmIdentifier>,
1430    },
1431
1432    /// A signature was made with an algorithm that doesn't match the relevant public key.
1433    UnsupportedSignatureAlgorithmForPublicKey {
1434        /// The signature algorithm OID.
1435        signature_algorithm_id: Vec<u8>,
1436        /// The public key algorithm OID.
1437        public_key_algorithm_id: Vec<u8>,
1438    },
1439
1440    /// The CRL contained an invalid CRL number.
1441    InvalidCrlNumber,
1442
1443    /// The CRL contained a revoked certificate with an invalid serial number.
1444    InvalidRevokedCertSerialNumber,
1445
1446    /// The CRL issuer does not specify the cRLSign key usage.
1447    IssuerInvalidForCrl,
1448
1449    /// The CRL is invalid for some other reason.
1450    ///
1451    /// Enums holding this variant will never compare equal to each other.
1452    Other(OtherError),
1453
1454    /// The CRL is not correctly encoded.
1455    ParseError,
1456
1457    /// The CRL is not a v2 X.509 CRL.
1458    UnsupportedCrlVersion,
1459
1460    /// The CRL, or a revoked certificate in the CRL, contained an unsupported critical extension.
1461    UnsupportedCriticalExtension,
1462
1463    /// The CRL is an unsupported delta CRL, containing only changes relative to another CRL.
1464    UnsupportedDeltaCrl,
1465
1466    /// The CRL is an unsupported indirect CRL, containing revoked certificates issued by a CA
1467    /// other than the issuer of the CRL.
1468    UnsupportedIndirectCrl,
1469
1470    /// The CRL contained a revoked certificate with an unsupported revocation reason.
1471    /// See RFC 5280 Section 5.3.1[^1] for a list of supported revocation reasons.
1472    ///
1473    /// [^1]: <https://www.rfc-editor.org/rfc/rfc5280#section-5.3.1>
1474    UnsupportedRevocationReason,
1475}
1476
1477impl PartialEq<Self> for CertRevocationListError {
1478    fn eq(&self, other: &Self) -> bool {
1479        use CertRevocationListError::*;
1480        match (self, other) {
1481            (BadSignature, BadSignature) => true,
1482            (
1483                UnsupportedSignatureAlgorithm {
1484                    signature_algorithm_id: left_signature_algorithm_id,
1485                    supported_algorithms: left_supported_algorithms,
1486                },
1487                UnsupportedSignatureAlgorithm {
1488                    signature_algorithm_id: right_signature_algorithm_id,
1489                    supported_algorithms: right_supported_algorithms,
1490                },
1491            ) => {
1492                (left_signature_algorithm_id, left_supported_algorithms)
1493                    == (right_signature_algorithm_id, right_supported_algorithms)
1494            }
1495            (
1496                UnsupportedSignatureAlgorithmForPublicKey {
1497                    signature_algorithm_id: left_signature_algorithm_id,
1498                    public_key_algorithm_id: left_public_key_algorithm_id,
1499                },
1500                UnsupportedSignatureAlgorithmForPublicKey {
1501                    signature_algorithm_id: right_signature_algorithm_id,
1502                    public_key_algorithm_id: right_public_key_algorithm_id,
1503                },
1504            ) => {
1505                (left_signature_algorithm_id, left_public_key_algorithm_id)
1506                    == (right_signature_algorithm_id, right_public_key_algorithm_id)
1507            }
1508            (InvalidCrlNumber, InvalidCrlNumber) => true,
1509            (InvalidRevokedCertSerialNumber, InvalidRevokedCertSerialNumber) => true,
1510            (IssuerInvalidForCrl, IssuerInvalidForCrl) => true,
1511            (ParseError, ParseError) => true,
1512            (UnsupportedCrlVersion, UnsupportedCrlVersion) => true,
1513            (UnsupportedCriticalExtension, UnsupportedCriticalExtension) => true,
1514            (UnsupportedDeltaCrl, UnsupportedDeltaCrl) => true,
1515            (UnsupportedIndirectCrl, UnsupportedIndirectCrl) => true,
1516            (UnsupportedRevocationReason, UnsupportedRevocationReason) => true,
1517            _ => false,
1518        }
1519    }
1520}
1521
1522/// An error that occurred while handling Encrypted Client Hello (ECH).
1523#[non_exhaustive]
1524#[derive(Debug, Clone, Eq, PartialEq)]
1525pub enum EncryptedClientHelloError {
1526    /// The provided ECH configuration list was invalid.
1527    InvalidConfigList,
1528    /// No compatible ECH configuration.
1529    NoCompatibleConfig,
1530    /// The client configuration has server name indication (SNI) disabled.
1531    SniRequired,
1532}
1533
1534/// The server rejected the request to enable Encrypted Client Hello (ECH)
1535///
1536/// If [`RejectedEch::can_retry()`] is true, then you may use this with
1537/// [`crate::client::EchConfig::for_retry()`] to build a new `EchConfig` for a fresh client
1538/// connection that will use a compatible ECH configuration provided by the server for a retry.
1539#[non_exhaustive]
1540#[derive(Debug, Clone, PartialEq)]
1541pub struct RejectedEch {
1542    pub(crate) retry_configs: Option<Vec<EchConfigPayload>>,
1543}
1544
1545impl RejectedEch {
1546    /// Returns true if the server provided new ECH configurations to use for a fresh retry connection
1547    ///
1548    /// The `RejectedEch` error can be provided to [`crate::client::EchConfig::for_retry()`]
1549    /// to build a new `EchConfig` for a fresh client connection that will use a compatible ECH
1550    /// configuration provided by the server for a retry.
1551    pub fn can_retry(&self) -> bool {
1552        self.retry_configs.is_some()
1553    }
1554
1555    /// Returns an `EchConfigListBytes` with the server's provided retry configurations (if any)
1556    pub fn retry_configs(&self) -> Option<EchConfigListBytes<'static>> {
1557        let Some(retry_configs) = &self.retry_configs else {
1558            return None;
1559        };
1560
1561        let mut tls_encoded_list = Vec::new();
1562        retry_configs.encode(&mut tls_encoded_list);
1563
1564        Some(EchConfigListBytes::from(tls_encoded_list))
1565    }
1566}
1567
1568fn join<T: fmt::Debug>(items: &[T]) -> String {
1569    items
1570        .iter()
1571        .map(|x| format!("{x:?}"))
1572        .collect::<Vec<String>>()
1573        .join(" or ")
1574}
1575
1576/// Describes cases of API misuse
1577///
1578/// Variants here should be sufficiently detailed that the action needed is clear.
1579#[non_exhaustive]
1580#[derive(Debug, Clone, PartialEq)]
1581pub enum ApiMisuse {
1582    /// Trying to resume a session with an unknown cipher suite.
1583    ResumingFromUnknownCipherSuite(CipherSuite),
1584
1585    /// The [`KeyingMaterialExporter`][] was already consumed or is not yet available.
1586    ///
1587    /// Methods that obtain an exporter (eg, [`Connection::exporter()`][]) can only
1588    /// be used once.  This error is returned on subsequent calls.
1589    ///
1590    /// [`KeyingMaterialExporter`]: crate::KeyingMaterialExporter
1591    /// [`Connection::exporter()`]: crate::Connection::exporter()
1592    ExporterNotAvailable,
1593
1594    /// The `context` parameter to [`KeyingMaterialExporter::derive()`][] was too long.
1595    ///
1596    /// For TLS1.2 connections (only) this parameter is limited to 64KB.
1597    ///
1598    /// [`KeyingMaterialExporter::derive()`]: crate::KeyingMaterialExporter::derive()
1599    ExporterContextTooLong,
1600
1601    /// The `output` object for [`KeyingMaterialExporter::derive()`][] was too long.
1602    ///
1603    /// For TLS1.3 connections this is limited to 255 times the hash output length.
1604    ///
1605    /// [`KeyingMaterialExporter::derive()`]: crate::KeyingMaterialExporter::derive()
1606    ExporterOutputTooLong,
1607
1608    /// The `output` object to [`KeyingMaterialExporter::derive()`][] was zero length.
1609    ///
1610    /// This doesn't make sense, so we explicitly return an error (rather than simply
1611    /// producing no output as requested.)
1612    ///
1613    /// [`KeyingMaterialExporter::derive()`]: crate::KeyingMaterialExporter::derive()
1614    ExporterOutputZeroLength,
1615
1616    /// Incorrect sample length provided to [`quic::HeaderProtectionKey::encrypt_in_place()`][]
1617    ///
1618    /// [`quic::HeaderProtectionKey::encrypt_in_place()`]: crate::quic::HeaderProtectionKey::encrypt_in_place()
1619    InvalidQuicHeaderProtectionSampleLength,
1620
1621    /// Incorrect relation between sample length and header number length provided to
1622    /// [`quic::HeaderProtectionKey::encrypt_in_place()`][]
1623    ///
1624    /// [`quic::HeaderProtectionKey::encrypt_in_place()`]: crate::quic::HeaderProtectionKey::encrypt_in_place()
1625    InvalidQuicHeaderProtectionPacketNumberLength,
1626
1627    /// Raw keys cannot be used with TLS 1.2.
1628    InvalidSignerForProtocolVersion,
1629
1630    /// QUIC attempted with a configuration that does not support TLS1.3.
1631    QuicRequiresTls13Support,
1632
1633    /// QUIC attempted with a configuration that does not support a ciphersuite that supports QUIC.
1634    NoQuicCompatibleCipherSuites,
1635
1636    /// An empty certificate chain was provided.
1637    EmptyCertificateChain,
1638
1639    /// QUIC attempted with unsupported [`ServerConfig::max_early_data_size`][]
1640    ///
1641    /// This field must be either zero or [`u32::MAX`] for QUIC.
1642    ///
1643    /// [`ServerConfig::max_early_data_size`]: crate::server::ServerConfig::max_early_data_size
1644    QuicRestrictsMaxEarlyDataSize,
1645
1646    /// A `CryptoProvider` must have at least one cipher suite.
1647    NoCipherSuitesConfigured,
1648
1649    /// A `CryptoProvider` must have at least one key exchange group.
1650    NoKeyExchangeGroupsConfigured,
1651
1652    /// An empty list of signature verification algorithms was provided.
1653    NoSignatureVerificationAlgorithms,
1654
1655    /// ECH attempted with a configuration that does not support TLS1.3.
1656    EchRequiresTls13Support,
1657
1658    /// ECH attempted with a configuration that also supports TLS1.2.
1659    EchForbidsTls12Support,
1660
1661    /// Secret extraction operation attempted without opting-in to secret extraction.
1662    ///
1663    /// This is possible from [`Connection::dangerous_extract_secrets()`][crate::Connection::dangerous_extract_secrets].
1664    ///
1665    /// You must set [`ServerConfig::enable_secret_extraction`][crate::server::ServerConfig::enable_secret_extraction] or
1666    /// [`ClientConfig::enable_secret_extraction`][crate::client::ClientConfig::enable_secret_extraction] to true before this
1667    /// is available.
1668    SecretExtractionRequiresPriorOptIn,
1669
1670    /// Attempt to verify a certificate with an unsupported type.
1671    ///
1672    /// A verifier indicated support for a certificate type but then failed to verify the peer's
1673    /// identity of that type.
1674    UnverifiableCertificateType,
1675
1676    /// A verifier or resolver implementation signalled that it does not support any certificate types.
1677    NoSupportedCertificateTypes,
1678
1679    /// [`Nonce::to_array()`][] called with incorrect array size.
1680    ///
1681    /// The nonce length does not match the requested array size `N`.
1682    ///
1683    /// [`Nonce::to_array()`]: crate::crypto::cipher::Nonce::to_array()
1684    NonceArraySizeMismatch {
1685        /// The expected array size (type parameter N)
1686        expected: usize,
1687        /// The actual nonce length
1688        actual: usize,
1689    },
1690
1691    /// [`Iv::new()`][] called with a value that exceeds the maximum IV length.
1692    ///
1693    /// The IV length must not exceed [`Iv::MAX_LEN`][].
1694    ///
1695    /// [`Iv::new()`]: crate::crypto::cipher::Iv::new()
1696    /// [`Iv::MAX_LEN`]: crate::crypto::cipher::Iv::MAX_LEN
1697    IvLengthExceedsMaximum {
1698        /// The actual IV length provided
1699        actual: usize,
1700        /// The maximum allowed IV length
1701        maximum: usize,
1702    },
1703
1704    /// Calling [`Connection::set_resumption_data()`] must be done before
1705    /// any resumption is offered.
1706    ///
1707    /// [`Connection::set_resumption_data()`]: crate::Connection::set_resumption_data()
1708    ResumptionDataProvidedTooLate,
1709
1710    /// [`Connection::set_resumption_data()`] is limited to 32KB of data.
1711    ///
1712    /// [`Connection::set_resumption_data()`]: crate::Connection::set_resumption_data()
1713    ResumptionDataTooLarge,
1714
1715    /// [`KernelConnection::update_tx_secret()`] and associated are not available for TLS1.2 connections.
1716    ///
1717    /// [`KernelConnection::update_tx_secret()`]: crate::conn::kernel::KernelConnection::update_tx_secret()
1718    KeyUpdateNotAvailableForTls12,
1719
1720    /// [`KernelConnection::handle_new_session_ticket()`] and associated are not available for TLS1.2 connections.
1721    ///
1722    /// [`KernelConnection::handle_new_session_ticket()`]: crate::conn::kernel::KernelConnection::handle_new_session_ticket()
1723    KernelSessionTicketHandlingNotAvailableForTls12,
1724
1725    /// [`Connection::split()`][crate::Connection::split()] called during handshake.
1726    SplitDuringHandshake,
1727
1728    /// Plaintext cannot be encrypted before the handshake is complete.
1729    WriteBeforeHandshakeComplete,
1730
1731    /// Plaintext cannot be encrypted after the send path has been closed.
1732    WriteAfterSendPathClosed,
1733
1734    /// Secret extraction attempted while send data was pending.
1735    KernelConnectionWithPendingSendData,
1736}
1737
1738impl fmt::Display for ApiMisuse {
1739    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1740        write!(f, "{self:?}")
1741    }
1742}
1743
1744impl core::error::Error for ApiMisuse {}
1745
1746mod other_error {
1747    use core::error::Error as StdError;
1748    use core::fmt;
1749
1750    use crate::sync::Arc;
1751
1752    /// Any other error that cannot be expressed by a more specific [`Error`][super::Error]
1753    /// variant.
1754    ///
1755    /// For example, an `OtherError` could be produced by a custom crypto provider
1756    /// exposing a provider specific error.
1757    ///
1758    /// Enums holding this type will never compare equal to each other.
1759    #[derive(Debug, Clone)]
1760    pub struct OtherError(Arc<dyn StdError + Send + Sync>);
1761
1762    impl OtherError {
1763        /// Create a new `OtherError` from any error type.
1764        pub fn new(err: impl StdError + Send + Sync + 'static) -> Self {
1765            Self(Arc::new(err))
1766        }
1767    }
1768
1769    impl PartialEq<Self> for OtherError {
1770        fn eq(&self, _other: &Self) -> bool {
1771            false
1772        }
1773    }
1774
1775    impl fmt::Display for OtherError {
1776        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1777            write!(f, "{}", self.0)
1778        }
1779    }
1780
1781    impl StdError for OtherError {
1782        fn source(&self) -> Option<&(dyn StdError + 'static)> {
1783            Some(self.0.as_ref())
1784        }
1785    }
1786}
1787
1788pub use other_error::OtherError;