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