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