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