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