1use crate::enums::{AlertDescription, ContentType, HandshakeType};
2use crate::msgs::handshake::KeyExchangeAlgorithm;
3use crate::rand;
4
5use alloc::format;
6use alloc::string::String;
7use alloc::sync::Arc;
8use alloc::vec::Vec;
9use core::fmt;
10use std::error::Error as StdError;
11use std::time::SystemTimeError;
12
13/// rustls reports protocol errors using this type.
14#[non_exhaustive]
15#[derive(Debug, PartialEq, Clone)]
16pub enum Error {
17 /// We received a TLS message that isn't valid right now.
18 /// `expect_types` lists the message types we can expect right now.
19 /// `got_type` is the type we found. This error is typically
20 /// caused by a buggy TLS stack (the peer or this one), a broken
21 /// network, or an attack.
22 InappropriateMessage {
23 /// Which types we expected
24 expect_types: Vec<ContentType>,
25 /// What type we received
26 got_type: ContentType,
27 },
28
29 /// We received a TLS handshake message that isn't valid right now.
30 /// `expect_types` lists the handshake message types we can expect
31 /// right now. `got_type` is the type we found.
32 InappropriateHandshakeMessage {
33 /// Which handshake type we expected
34 expect_types: Vec<HandshakeType>,
35 /// What handshake type we received
36 got_type: HandshakeType,
37 },
38
39 /// The peer sent us a TLS message with invalid contents.
40 InvalidMessage(InvalidMessage),
41
42 /// The peer didn't give us any certificates.
43 NoCertificatesPresented,
44
45 /// The certificate verifier doesn't support the given type of name.
46 UnsupportedNameType,
47
48 /// We couldn't decrypt a message. This is invariably fatal.
49 DecryptError,
50
51 /// We couldn't encrypt a message because it was larger than the allowed message size.
52 /// This should never happen if the application is using valid record sizes.
53 EncryptError,
54
55 /// The peer doesn't support a protocol version/feature we require.
56 /// The parameter gives a hint as to what version/feature it is.
57 PeerIncompatible(PeerIncompatible),
58
59 /// The peer deviated from the standard TLS protocol.
60 /// The parameter gives a hint where.
61 PeerMisbehaved(PeerMisbehaved),
62
63 /// We received a fatal alert. This means the peer is unhappy.
64 AlertReceived(AlertDescription),
65
66 /// We saw an invalid certificate.
67 ///
68 /// The contained error is from the certificate validation trait
69 /// implementation.
70 InvalidCertificate(CertificateError),
71
72 /// A provided certificate revocation list (CRL) was invalid.
73 InvalidCertRevocationList(CertRevocationListError),
74
75 /// A catch-all error for unlikely errors.
76 General(String),
77
78 /// We failed to figure out what time it currently is.
79 FailedToGetCurrentTime,
80
81 /// We failed to acquire random bytes from the system.
82 FailedToGetRandomBytes,
83
84 /// This function doesn't work until the TLS handshake
85 /// is complete.
86 HandshakeNotComplete,
87
88 /// The peer sent an oversized record/fragment.
89 PeerSentOversizedRecord,
90
91 /// An incoming connection did not support any known application protocol.
92 NoApplicationProtocol,
93
94 /// The `max_fragment_size` value supplied in configuration was too small,
95 /// or too large.
96 BadMaxFragmentSize,
97
98 /// Any other error.
99 ///
100 /// This variant should only be used when the error is not better described by a more
101 /// specific variant. For example, if a custom crypto provider returns a
102 /// provider specific error.
103 ///
104 /// Enums holding this variant will never compare equal to each other.
105 Other(OtherError),
106}
107
108/// A corrupt TLS message payload that resulted in an error.
109#[non_exhaustive]
110#[derive(Debug, Clone, Copy, PartialEq)]
111
112pub enum InvalidMessage {
113 /// An advertised message was larger then expected.
114 HandshakePayloadTooLarge,
115 /// The peer sent us a syntactically incorrect ChangeCipherSpec payload.
116 InvalidCcs,
117 /// An unknown content type was encountered during message decoding.
118 InvalidContentType,
119 /// A peer sent an invalid certificate status type
120 InvalidCertificateStatusType,
121 /// Context was incorrectly attached to a certificate request during a handshake.
122 InvalidCertRequest,
123 /// A peer's DH params could not be decoded
124 InvalidDhParams,
125 /// A message was zero-length when its record kind forbids it.
126 InvalidEmptyPayload,
127 /// A peer sent an unexpected key update request.
128 InvalidKeyUpdate,
129 /// A peer's server name could not be decoded
130 InvalidServerName,
131 /// A TLS message payload was larger then allowed by the specification.
132 MessageTooLarge,
133 /// Message is shorter than the expected length
134 MessageTooShort,
135 /// Missing data for the named handshake payload value
136 MissingData(&'static str),
137 /// A peer did not advertise its supported key exchange groups.
138 MissingKeyExchange,
139 /// A peer sent an empty list of signature schemes
140 NoSignatureSchemes,
141 /// Trailing data found for the named handshake payload value
142 TrailingData(&'static str),
143 /// A peer sent an unexpected message type.
144 UnexpectedMessage(&'static str),
145 /// An unknown TLS protocol was encountered during message decoding.
146 UnknownProtocolVersion,
147 /// A peer sent a non-null compression method.
148 UnsupportedCompression,
149 /// A peer sent an unknown elliptic curve type.
150 UnsupportedCurveType,
151 /// A peer sent an unsupported key exchange algorithm.
152 UnsupportedKeyExchangeAlgorithm(KeyExchangeAlgorithm),
153}
154
155impl From<InvalidMessage> for Error {
156 #[inline]
157 fn from(e: InvalidMessage) -> Self {
158 Self::InvalidMessage(e)
159 }
160}
161
162#[non_exhaustive]
163#[allow(missing_docs)]
164#[derive(Debug, PartialEq, Clone)]
165/// The set of cases where we failed to make a connection because we thought
166/// the peer was misbehaving.
167///
168/// This is `non_exhaustive`: we might add or stop using items here in minor
169/// versions. We also don't document what they mean. Generally a user of
170/// rustls shouldn't vary its behaviour on these error codes, and there is
171/// nothing it can do to improve matters.
172///
173/// Please file a bug against rustls if you see `Error::PeerMisbehaved` in
174/// the wild.
175pub enum PeerMisbehaved {
176 AttemptedDowngradeToTls12WhenTls13IsSupported,
177 BadCertChainExtensions,
178 DisallowedEncryptedExtension,
179 DuplicateClientHelloExtensions,
180 DuplicateEncryptedExtensions,
181 DuplicateHelloRetryRequestExtensions,
182 DuplicateNewSessionTicketExtensions,
183 DuplicateServerHelloExtensions,
184 DuplicateServerNameTypes,
185 EarlyDataAttemptedInSecondClientHello,
186 EarlyDataExtensionWithoutResumption,
187 EarlyDataOfferedWithVariedCipherSuite,
188 HandshakeHashVariedAfterRetry,
189 IllegalHelloRetryRequestWithEmptyCookie,
190 IllegalHelloRetryRequestWithNoChanges,
191 IllegalHelloRetryRequestWithOfferedGroup,
192 IllegalHelloRetryRequestWithUnofferedCipherSuite,
193 IllegalHelloRetryRequestWithUnofferedNamedGroup,
194 IllegalHelloRetryRequestWithUnsupportedVersion,
195 IllegalHelloRetryRequestWithWrongSessionId,
196 IllegalMiddleboxChangeCipherSpec,
197 IllegalTlsInnerPlaintext,
198 IncorrectBinder,
199 InvalidMaxEarlyDataSize,
200 InvalidKeyShare,
201 KeyEpochWithPendingFragment,
202 KeyUpdateReceivedInQuicConnection,
203 MessageInterleavedWithHandshakeMessage,
204 MissingBinderInPskExtension,
205 MissingKeyShare,
206 MissingPskModesExtension,
207 MissingQuicTransportParameters,
208 OfferedDuplicateKeyShares,
209 OfferedEarlyDataWithOldProtocolVersion,
210 OfferedEmptyApplicationProtocol,
211 OfferedIncorrectCompressions,
212 PskExtensionMustBeLast,
213 PskExtensionWithMismatchedIdsAndBinders,
214 RefusedToFollowHelloRetryRequest,
215 RejectedEarlyDataInterleavedWithHandshakeMessage,
216 ResumptionAttemptedWithVariedEms,
217 ResumptionOfferedWithVariedCipherSuite,
218 ResumptionOfferedWithVariedEms,
219 ResumptionOfferedWithIncompatibleCipherSuite,
220 SelectedDifferentCipherSuiteAfterRetry,
221 SelectedInvalidPsk,
222 SelectedTls12UsingTls13VersionExtension,
223 SelectedUnofferedApplicationProtocol,
224 SelectedUnofferedCipherSuite,
225 SelectedUnofferedCompression,
226 SelectedUnofferedKxGroup,
227 SelectedUnofferedPsk,
228 SelectedUnusableCipherSuiteForVersion,
229 ServerHelloMustOfferUncompressedEcPoints,
230 ServerNameDifferedOnRetry,
231 ServerNameMustContainOneHostName,
232 SignedKxWithWrongAlgorithm,
233 SignedHandshakeWithUnadvertisedSigScheme,
234 TooMuchEarlyDataReceived,
235 UnexpectedCleartextExtension,
236 UnsolicitedCertExtension,
237 UnsolicitedEncryptedExtension,
238 UnsolicitedSctList,
239 UnsolicitedServerHelloExtension,
240 WrongGroupForKeyShare,
241}
242
243impl From<PeerMisbehaved> for Error {
244 #[inline]
245 fn from(e: PeerMisbehaved) -> Self {
246 Self::PeerMisbehaved(e)
247 }
248}
249
250#[non_exhaustive]
251#[allow(missing_docs)]
252#[derive(Debug, PartialEq, Clone)]
253/// The set of cases where we failed to make a connection because a peer
254/// doesn't support a TLS version/feature we require.
255///
256/// This is `non_exhaustive`: we might add or stop using items here in minor
257/// versions.
258pub enum PeerIncompatible {
259 EcPointsExtensionRequired,
260 KeyShareExtensionRequired,
261 NamedGroupsExtensionRequired,
262 NoCertificateRequestSignatureSchemesInCommon,
263 NoCipherSuitesInCommon,
264 NoEcPointFormatsInCommon,
265 NoKxGroupsInCommon,
266 NoSignatureSchemesInCommon,
267 NullCompressionRequired,
268 ServerDoesNotSupportTls12Or13,
269 ServerSentHelloRetryRequestWithUnknownExtension,
270 ServerTlsVersionIsDisabledByOurConfig,
271 SignatureAlgorithmsExtensionRequired,
272 SupportedVersionsExtensionRequired,
273 Tls12NotOffered,
274 Tls12NotOfferedOrEnabled,
275 Tls13RequiredForQuic,
276 UncompressedEcPointsRequired,
277}
278
279impl From<PeerIncompatible> for Error {
280 #[inline]
281 fn from(e: PeerIncompatible) -> Self {
282 Self::PeerIncompatible(e)
283 }
284}
285
286#[non_exhaustive]
287#[derive(Debug, Clone)]
288/// The ways in which certificate validators can express errors.
289///
290/// Note that the rustls TLS protocol code interprets specifically these
291/// error codes to send specific TLS alerts. Therefore, if a
292/// custom certificate validator uses incorrect errors the library as
293/// a whole will send alerts that do not match the standard (this is usually
294/// a minor issue, but could be misleading).
295pub enum CertificateError {
296 /// The certificate is not correctly encoded.
297 BadEncoding,
298
299 /// The current time is after the `notAfter` time in the certificate.
300 Expired,
301
302 /// The current time is before the `notBefore` time in the certificate.
303 NotValidYet,
304
305 /// The certificate has been revoked.
306 Revoked,
307
308 /// The certificate contains an extension marked critical, but it was
309 /// not processed by the certificate validator.
310 UnhandledCriticalExtension,
311
312 /// The certificate chain is not issued by a known root certificate.
313 UnknownIssuer,
314
315 /// The certificate's revocation status could not be determined.
316 UnknownRevocationStatus,
317
318 /// A certificate is not correctly signed by the key of its alleged
319 /// issuer.
320 BadSignature,
321
322 /// The subject names in an end-entity certificate do not include
323 /// the expected name.
324 NotValidForName,
325
326 /// The certificate is being used for a different purpose than allowed.
327 InvalidPurpose,
328
329 /// The certificate is valid, but the handshake is rejected for other
330 /// reasons.
331 ApplicationVerificationFailure,
332
333 /// Any other error.
334 ///
335 /// This can be used by custom verifiers to expose the underlying error
336 /// (where they are not better described by the more specific errors
337 /// above).
338 ///
339 /// It is also used by the default verifier in case its error is
340 /// not covered by the above common cases.
341 ///
342 /// Enums holding this variant will never compare equal to each other.
343 Other(OtherError),
344}
345
346impl PartialEq<Self> for CertificateError {
347 fn eq(&self, other: &Self) -> bool {
348 use CertificateError::*;
349 #[allow(clippy::match_like_matches_macro)]
350 match (self, other) {
351 (BadEncoding, BadEncoding) => true,
352 (Expired, Expired) => true,
353 (NotValidYet, NotValidYet) => true,
354 (Revoked, Revoked) => true,
355 (UnhandledCriticalExtension, UnhandledCriticalExtension) => true,
356 (UnknownIssuer, UnknownIssuer) => true,
357 (BadSignature, BadSignature) => true,
358 (NotValidForName, NotValidForName) => true,
359 (InvalidPurpose, InvalidPurpose) => true,
360 (ApplicationVerificationFailure, ApplicationVerificationFailure) => true,
361 _ => false,
362 }
363 }
364}
365
366// The following mapping are heavily referenced in:
367// * [OpenSSL Implementation](https://github.com/openssl/openssl/blob/45bb98bfa223efd3258f445ad443f878011450f0/ssl/statem/statem_lib.c#L1434)
368// * [BoringSSL Implementation](https://github.com/google/boringssl/blob/583c60bd4bf76d61b2634a58bcda99a92de106cb/ssl/ssl_x509.cc#L1323)
369impl From<CertificateError> for AlertDescription {
370 fn from(e: CertificateError) -> Self {
371 use CertificateError::*;
372 match e {
373 BadEncoding | UnhandledCriticalExtension | NotValidForName => Self::BadCertificate,
374 // RFC 5246/RFC 8446
375 // certificate_expired
376 // A certificate has expired or **is not currently valid**.
377 Expired | NotValidYet => Self::CertificateExpired,
378 Revoked => Self::CertificateRevoked,
379 // OpenSSL, BoringSSL and AWS-LC all generate an Unknown CA alert for
380 // the case where revocation status can not be determined, so we do the same here.
381 UnknownIssuer | UnknownRevocationStatus => Self::UnknownCA,
382 BadSignature => Self::DecryptError,
383 InvalidPurpose => Self::UnsupportedCertificate,
384 ApplicationVerificationFailure => Self::AccessDenied,
385 // RFC 5246/RFC 8446
386 // certificate_unknown
387 // Some other (unspecified) issue arose in processing the
388 // certificate, rendering it unacceptable.
389 Other(_) => Self::CertificateUnknown,
390 }
391 }
392}
393
394impl From<CertificateError> for Error {
395 #[inline]
396 fn from(e: CertificateError) -> Self {
397 Self::InvalidCertificate(e)
398 }
399}
400
401#[non_exhaustive]
402#[derive(Debug, Clone)]
403/// The ways in which a certificate revocation list (CRL) can be invalid.
404pub enum CertRevocationListError {
405 /// The CRL had a bad, or unsupported signature from its issuer.
406 BadSignature,
407
408 /// The CRL contained an invalid CRL number.
409 InvalidCrlNumber,
410
411 /// The CRL contained a revoked certificate with an invalid serial number.
412 InvalidRevokedCertSerialNumber,
413
414 /// The CRL issuer does not specify the cRLSign key usage.
415 IssuerInvalidForCrl,
416
417 /// The CRL is invalid for some other reason.
418 ///
419 /// Enums holding this variant will never compare equal to each other.
420 Other(OtherError),
421
422 /// The CRL is not correctly encoded.
423 ParseError,
424
425 /// The CRL is not a v2 X.509 CRL.
426 UnsupportedCrlVersion,
427
428 /// The CRL, or a revoked certificate in the CRL, contained an unsupported critical extension.
429 UnsupportedCriticalExtension,
430
431 /// The CRL is an unsupported delta CRL, containing only changes relative to another CRL.
432 UnsupportedDeltaCrl,
433
434 /// The CRL is an unsupported indirect CRL, containing revoked certificates issued by a CA
435 /// other than the issuer of the CRL.
436 UnsupportedIndirectCrl,
437
438 /// The CRL contained a revoked certificate with an unsupported revocation reason.
439 /// See RFC 5280 Section 5.3.1[^1] for a list of supported revocation reasons.
440 ///
441 /// [^1]: <https://www.rfc-editor.org/rfc/rfc5280#section-5.3.1>
442 UnsupportedRevocationReason,
443}
444
445impl PartialEq<Self> for CertRevocationListError {
446 fn eq(&self, other: &Self) -> bool {
447 use CertRevocationListError::*;
448 #[allow(clippy::match_like_matches_macro)]
449 match (self, other) {
450 (BadSignature, BadSignature) => true,
451 (InvalidCrlNumber, InvalidCrlNumber) => true,
452 (InvalidRevokedCertSerialNumber, InvalidRevokedCertSerialNumber) => true,
453 (IssuerInvalidForCrl, IssuerInvalidForCrl) => true,
454 (ParseError, ParseError) => true,
455 (UnsupportedCrlVersion, UnsupportedCrlVersion) => true,
456 (UnsupportedCriticalExtension, UnsupportedCriticalExtension) => true,
457 (UnsupportedDeltaCrl, UnsupportedDeltaCrl) => true,
458 (UnsupportedIndirectCrl, UnsupportedIndirectCrl) => true,
459 (UnsupportedRevocationReason, UnsupportedRevocationReason) => true,
460 _ => false,
461 }
462 }
463}
464
465impl From<CertRevocationListError> for Error {
466 #[inline]
467 fn from(e: CertRevocationListError) -> Self {
468 Self::InvalidCertRevocationList(e)
469 }
470}
471
472fn join<T: fmt::Debug>(items: &[T]) -> String {
473 items
474 .iter()
475 .map(|x| format!("{:?}", x))
476 .collect::<Vec<String>>()
477 .join(sep:" or ")
478}
479
480impl fmt::Display for Error {
481 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
482 match *self {
483 Self::InappropriateMessage {
484 ref expect_types,
485 ref got_type,
486 } => write!(
487 f,
488 "received unexpected message: got {:?} when expecting {}",
489 got_type,
490 join::<ContentType>(expect_types)
491 ),
492 Self::InappropriateHandshakeMessage {
493 ref expect_types,
494 ref got_type,
495 } => write!(
496 f,
497 "received unexpected handshake message: got {:?} when expecting {}",
498 got_type,
499 join::<HandshakeType>(expect_types)
500 ),
501 Self::InvalidMessage(ref typ) => {
502 write!(f, "received corrupt message of type {:?}", typ)
503 }
504 Self::PeerIncompatible(ref why) => write!(f, "peer is incompatible: {:?}", why),
505 Self::PeerMisbehaved(ref why) => write!(f, "peer misbehaved: {:?}", why),
506 Self::AlertReceived(ref alert) => write!(f, "received fatal alert: {:?}", alert),
507 Self::InvalidCertificate(ref err) => {
508 write!(f, "invalid peer certificate: {:?}", err)
509 }
510 Self::InvalidCertRevocationList(ref err) => {
511 write!(f, "invalid certificate revocation list: {:?}", err)
512 }
513 Self::NoCertificatesPresented => write!(f, "peer sent no certificates"),
514 Self::UnsupportedNameType => write!(f, "presented server name type wasn't supported"),
515 Self::DecryptError => write!(f, "cannot decrypt peer's message"),
516 Self::EncryptError => write!(f, "cannot encrypt message"),
517 Self::PeerSentOversizedRecord => write!(f, "peer sent excess record size"),
518 Self::HandshakeNotComplete => write!(f, "handshake not complete"),
519 Self::NoApplicationProtocol => write!(f, "peer doesn't support any known protocol"),
520 Self::FailedToGetCurrentTime => write!(f, "failed to get current time"),
521 Self::FailedToGetRandomBytes => write!(f, "failed to get random bytes"),
522 Self::BadMaxFragmentSize => {
523 write!(f, "the supplied max_fragment_size was too small or large")
524 }
525 Self::General(ref err) => write!(f, "unexpected error: {}", err),
526 Self::Other(ref err) => write!(f, "other error: {}", err),
527 }
528 }
529}
530
531impl From<SystemTimeError> for Error {
532 #[inline]
533 fn from(_: SystemTimeError) -> Self {
534 Self::FailedToGetCurrentTime
535 }
536}
537
538impl StdError for Error {}
539
540impl From<rand::GetRandomFailed> for Error {
541 fn from(_: rand::GetRandomFailed) -> Self {
542 Self::FailedToGetRandomBytes
543 }
544}
545
546/// Any other error that cannot be expressed by a more specific [`Error`] variant.
547///
548/// For example, an `OtherError` could be produced by a custom crypto provider
549/// exposing a provider specific error.
550///
551/// Enums holding this type will never compare equal to each other.
552#[derive(Debug, Clone)]
553pub struct OtherError(pub Arc<dyn StdError + Send + Sync>);
554
555impl PartialEq<Self> for OtherError {
556 fn eq(&self, _other: &Self) -> bool {
557 false
558 }
559}
560
561impl From<OtherError> for Error {
562 fn from(value: OtherError) -> Self {
563 Self::Other(value)
564 }
565}
566
567impl fmt::Display for OtherError {
568 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
569 write!(f, "{}", self.0)
570 }
571}
572
573impl StdError for OtherError {
574 fn source(&self) -> Option<&(dyn StdError + 'static)> {
575 Some(self.0.as_ref())
576 }
577}
578
579#[cfg(test)]
580mod tests {
581 use super::{Error, InvalidMessage};
582 use crate::error::{CertRevocationListError, OtherError};
583
584 #[test]
585 fn certificate_error_equality() {
586 use super::CertificateError::*;
587 assert_eq!(BadEncoding, BadEncoding);
588 assert_eq!(Expired, Expired);
589 assert_eq!(NotValidYet, NotValidYet);
590 assert_eq!(Revoked, Revoked);
591 assert_eq!(UnhandledCriticalExtension, UnhandledCriticalExtension);
592 assert_eq!(UnknownIssuer, UnknownIssuer);
593 assert_eq!(BadSignature, BadSignature);
594 assert_eq!(NotValidForName, NotValidForName);
595 assert_eq!(InvalidPurpose, InvalidPurpose);
596 assert_eq!(
597 ApplicationVerificationFailure,
598 ApplicationVerificationFailure
599 );
600 let other = Other(OtherError(alloc::sync::Arc::from(Box::from(""))));
601 assert_ne!(other, other);
602 assert_ne!(BadEncoding, Expired);
603 }
604
605 #[test]
606 fn crl_error_equality() {
607 use super::CertRevocationListError::*;
608 assert_eq!(BadSignature, BadSignature);
609 assert_eq!(InvalidCrlNumber, InvalidCrlNumber);
610 assert_eq!(
611 InvalidRevokedCertSerialNumber,
612 InvalidRevokedCertSerialNumber
613 );
614 assert_eq!(IssuerInvalidForCrl, IssuerInvalidForCrl);
615 assert_eq!(ParseError, ParseError);
616 assert_eq!(UnsupportedCriticalExtension, UnsupportedCriticalExtension);
617 assert_eq!(UnsupportedCrlVersion, UnsupportedCrlVersion);
618 assert_eq!(UnsupportedDeltaCrl, UnsupportedDeltaCrl);
619 assert_eq!(UnsupportedIndirectCrl, UnsupportedIndirectCrl);
620 assert_eq!(UnsupportedRevocationReason, UnsupportedRevocationReason);
621 let other = Other(OtherError(alloc::sync::Arc::from(Box::from(""))));
622 assert_ne!(other, other);
623 assert_ne!(BadSignature, InvalidCrlNumber);
624 }
625
626 #[test]
627 fn other_error_equality() {
628 let other_error = OtherError(alloc::sync::Arc::from(Box::from("")));
629 assert_ne!(other_error, other_error);
630 let other: Error = other_error.into();
631 assert_ne!(other, other);
632 }
633
634 #[test]
635 fn smoke() {
636 use crate::enums::{AlertDescription, ContentType, HandshakeType};
637
638 let all = vec![
639 Error::InappropriateMessage {
640 expect_types: vec![ContentType::Alert],
641 got_type: ContentType::Handshake,
642 },
643 Error::InappropriateHandshakeMessage {
644 expect_types: vec![HandshakeType::ClientHello, HandshakeType::Finished],
645 got_type: HandshakeType::ServerHello,
646 },
647 Error::InvalidMessage(InvalidMessage::InvalidCcs),
648 Error::NoCertificatesPresented,
649 Error::DecryptError,
650 super::PeerIncompatible::Tls12NotOffered.into(),
651 super::PeerMisbehaved::UnsolicitedCertExtension.into(),
652 Error::AlertReceived(AlertDescription::ExportRestriction),
653 super::CertificateError::Expired.into(),
654 Error::General("undocumented error".to_string()),
655 Error::FailedToGetCurrentTime,
656 Error::FailedToGetRandomBytes,
657 Error::HandshakeNotComplete,
658 Error::PeerSentOversizedRecord,
659 Error::NoApplicationProtocol,
660 Error::BadMaxFragmentSize,
661 Error::InvalidCertRevocationList(CertRevocationListError::BadSignature),
662 Error::Other(OtherError(alloc::sync::Arc::from(Box::from("")))),
663 ];
664
665 for err in all {
666 println!("{:?}:", err);
667 println!(" fmt '{}'", err);
668 }
669 }
670
671 #[test]
672 fn rand_error_mapping() {
673 use super::rand;
674 let err: Error = rand::GetRandomFailed.into();
675 assert_eq!(err, Error::FailedToGetRandomBytes);
676 }
677
678 #[test]
679 fn time_error_mapping() {
680 use std::time::SystemTime;
681
682 let time_error = SystemTime::UNIX_EPOCH
683 .duration_since(SystemTime::now())
684 .unwrap_err();
685 let err: Error = time_error.into();
686 assert_eq!(err, Error::FailedToGetCurrentTime);
687 }
688}
689