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