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