1use alloc::format;
2use alloc::string::String;
3use alloc::vec::Vec;
4use core::fmt;
5use pki_types::{ServerName, UnixTime};
6#[cfg(feature = "std")]
7use std::time::SystemTimeError;
8
9use crate::enums::{AlertDescription, ContentType, HandshakeType};
10use crate::msgs::handshake::{EchConfigPayload, KeyExchangeAlgorithm};
11use crate::rand;
12
13#[non_exhaustive]
15#[derive(Debug, PartialEq, Clone)]
16pub enum Error {
17 InappropriateMessage {
23 expect_types: Vec<ContentType>,
25 got_type: ContentType,
27 },
28
29 InappropriateHandshakeMessage {
33 expect_types: Vec<HandshakeType>,
35 got_type: HandshakeType,
37 },
38
39 InvalidEncryptedClientHello(EncryptedClientHelloError),
41
42 InvalidMessage(InvalidMessage),
44
45 NoCertificatesPresented,
47
48 UnsupportedNameType,
50
51 DecryptError,
53
54 EncryptError,
57
58 PeerIncompatible(PeerIncompatible),
61
62 PeerMisbehaved(PeerMisbehaved),
65
66 AlertReceived(AlertDescription),
68
69 InvalidCertificate(CertificateError),
74
75 InvalidCertRevocationList(CertRevocationListError),
77
78 General(String),
80
81 FailedToGetCurrentTime,
83
84 FailedToGetRandomBytes,
86
87 HandshakeNotComplete,
90
91 PeerSentOversizedRecord,
93
94 NoApplicationProtocol,
96
97 BadMaxFragmentSize,
100
101 InconsistentKeys(InconsistentKeys),
105
106 Other(OtherError),
114}
115
116#[non_exhaustive]
120#[derive(Clone, Copy, Debug, Eq, PartialEq)]
121pub enum InconsistentKeys {
122 KeyMismatch,
126
127 Unknown,
131}
132
133impl From<InconsistentKeys> for Error {
134 #[inline]
135 fn from(e: InconsistentKeys) -> Self {
136 Self::InconsistentKeys(e)
137 }
138}
139
140#[non_exhaustive]
142#[derive(Debug, Clone, Copy, PartialEq)]
143
144pub enum InvalidMessage {
145 CertificatePayloadTooLarge,
147 HandshakePayloadTooLarge,
149 InvalidCcs,
151 InvalidContentType,
153 InvalidCertificateStatusType,
155 InvalidCertRequest,
157 InvalidDhParams,
159 InvalidEmptyPayload,
161 InvalidKeyUpdate,
163 InvalidServerName,
165 MessageTooLarge,
167 MessageTooShort,
169 MissingData(&'static str),
171 MissingKeyExchange,
173 NoSignatureSchemes,
175 TrailingData(&'static str),
177 UnexpectedMessage(&'static str),
179 UnknownProtocolVersion,
181 UnsupportedCompression,
183 UnsupportedCurveType,
185 UnsupportedKeyExchangeAlgorithm(KeyExchangeAlgorithm),
187}
188
189impl From<InvalidMessage> for Error {
190 #[inline]
191 fn from(e: InvalidMessage) -> Self {
192 Self::InvalidMessage(e)
193 }
194}
195
196#[non_exhaustive]
197#[allow(missing_docs)]
198#[derive(Debug, PartialEq, Clone)]
199pub enum PeerMisbehaved {
210 AttemptedDowngradeToTls12WhenTls13IsSupported,
211 BadCertChainExtensions,
212 DisallowedEncryptedExtension,
213 DuplicateClientHelloExtensions,
214 DuplicateEncryptedExtensions,
215 DuplicateHelloRetryRequestExtensions,
216 DuplicateNewSessionTicketExtensions,
217 DuplicateServerHelloExtensions,
218 DuplicateServerNameTypes,
219 EarlyDataAttemptedInSecondClientHello,
220 EarlyDataExtensionWithoutResumption,
221 EarlyDataOfferedWithVariedCipherSuite,
222 HandshakeHashVariedAfterRetry,
223 IllegalHelloRetryRequestWithEmptyCookie,
224 IllegalHelloRetryRequestWithNoChanges,
225 IllegalHelloRetryRequestWithOfferedGroup,
226 IllegalHelloRetryRequestWithUnofferedCipherSuite,
227 IllegalHelloRetryRequestWithUnofferedNamedGroup,
228 IllegalHelloRetryRequestWithUnsupportedVersion,
229 IllegalHelloRetryRequestWithWrongSessionId,
230 IllegalHelloRetryRequestWithInvalidEch,
231 IllegalMiddleboxChangeCipherSpec,
232 IllegalTlsInnerPlaintext,
233 IncorrectBinder,
234 InvalidCertCompression,
235 InvalidMaxEarlyDataSize,
236 InvalidKeyShare,
237 KeyEpochWithPendingFragment,
238 KeyUpdateReceivedInQuicConnection,
239 MessageInterleavedWithHandshakeMessage,
240 MissingBinderInPskExtension,
241 MissingKeyShare,
242 MissingPskModesExtension,
243 MissingQuicTransportParameters,
244 OfferedDuplicateCertificateCompressions,
245 OfferedDuplicateKeyShares,
246 OfferedEarlyDataWithOldProtocolVersion,
247 OfferedEmptyApplicationProtocol,
248 OfferedIncorrectCompressions,
249 PskExtensionMustBeLast,
250 PskExtensionWithMismatchedIdsAndBinders,
251 RefusedToFollowHelloRetryRequest,
252 RejectedEarlyDataInterleavedWithHandshakeMessage,
253 ResumptionAttemptedWithVariedEms,
254 ResumptionOfferedWithVariedCipherSuite,
255 ResumptionOfferedWithVariedEms,
256 ResumptionOfferedWithIncompatibleCipherSuite,
257 SelectedDifferentCipherSuiteAfterRetry,
258 SelectedInvalidPsk,
259 SelectedTls12UsingTls13VersionExtension,
260 SelectedUnofferedApplicationProtocol,
261 SelectedUnofferedCertCompression,
262 SelectedUnofferedCipherSuite,
263 SelectedUnofferedCompression,
264 SelectedUnofferedKxGroup,
265 SelectedUnofferedPsk,
266 SelectedUnusableCipherSuiteForVersion,
267 ServerEchoedCompatibilitySessionId,
268 ServerHelloMustOfferUncompressedEcPoints,
269 ServerNameDifferedOnRetry,
270 ServerNameMustContainOneHostName,
271 SignedKxWithWrongAlgorithm,
272 SignedHandshakeWithUnadvertisedSigScheme,
273 TooManyEmptyFragments,
274 TooManyKeyUpdateRequests,
275 TooManyRenegotiationRequests,
276 TooManyWarningAlertsReceived,
277 TooMuchEarlyDataReceived,
278 UnexpectedCleartextExtension,
279 UnsolicitedCertExtension,
280 UnsolicitedEncryptedExtension,
281 UnsolicitedSctList,
282 UnsolicitedServerHelloExtension,
283 WrongGroupForKeyShare,
284 UnsolicitedEchExtension,
285}
286
287impl From<PeerMisbehaved> for Error {
288 #[inline]
289 fn from(e: PeerMisbehaved) -> Self {
290 Self::PeerMisbehaved(e)
291 }
292}
293
294#[non_exhaustive]
295#[allow(missing_docs)]
296#[derive(Debug, PartialEq, Clone)]
297pub enum PeerIncompatible {
303 EcPointsExtensionRequired,
304 ExtendedMasterSecretExtensionRequired,
305 IncorrectCertificateTypeExtension,
306 KeyShareExtensionRequired,
307 NamedGroupsExtensionRequired,
308 NoCertificateRequestSignatureSchemesInCommon,
309 NoCipherSuitesInCommon,
310 NoEcPointFormatsInCommon,
311 NoKxGroupsInCommon,
312 NoSignatureSchemesInCommon,
313 NullCompressionRequired,
314 ServerDoesNotSupportTls12Or13,
315 ServerSentHelloRetryRequestWithUnknownExtension,
316 ServerTlsVersionIsDisabledByOurConfig,
317 SignatureAlgorithmsExtensionRequired,
318 SupportedVersionsExtensionRequired,
319 Tls12NotOffered,
320 Tls12NotOfferedOrEnabled,
321 Tls13RequiredForQuic,
322 UncompressedEcPointsRequired,
323 UnsolicitedCertificateTypeExtension,
324 ServerRejectedEncryptedClientHello(Option<Vec<EchConfigPayload>>),
325}
326
327impl From<PeerIncompatible> for Error {
328 #[inline]
329 fn from(e: PeerIncompatible) -> Self {
330 Self::PeerIncompatible(e)
331 }
332}
333
334#[non_exhaustive]
335#[derive(Debug, Clone)]
336pub enum CertificateError {
344 BadEncoding,
346
347 Expired,
349
350 ExpiredContext {
355 time: UnixTime,
357 not_after: UnixTime,
359 },
360
361 NotValidYet,
363
364 NotValidYetContext {
369 time: UnixTime,
371 not_before: UnixTime,
373 },
374
375 Revoked,
377
378 UnhandledCriticalExtension,
381
382 UnknownIssuer,
384
385 UnknownRevocationStatus,
387
388 ExpiredRevocationList,
390
391 ExpiredRevocationListContext {
396 time: UnixTime,
398 next_update: UnixTime,
400 },
401
402 BadSignature,
405
406 NotValidForName,
409
410 NotValidForNameContext {
416 expected: ServerName<'static>,
418
419 presented: Vec<String>,
424 },
425
426 InvalidPurpose,
428
429 ApplicationVerificationFailure,
432
433 Other(OtherError),
444}
445
446impl PartialEq<Self> for CertificateError {
447 fn eq(&self, other: &Self) -> bool {
448 use CertificateError::*;
449 #[allow(clippy::match_like_matches_macro)]
450 match (self, other) {
451 (BadEncoding, BadEncoding) => true,
452 (Expired, Expired) => true,
453 (
454 ExpiredContext {
455 time: left_time,
456 not_after: left_not_after,
457 },
458 ExpiredContext {
459 time: right_time,
460 not_after: right_not_after,
461 },
462 ) => (left_time, left_not_after) == (right_time, right_not_after),
463 (NotValidYet, NotValidYet) => true,
464 (
465 NotValidYetContext {
466 time: left_time,
467 not_before: left_not_before,
468 },
469 NotValidYetContext {
470 time: right_time,
471 not_before: right_not_before,
472 },
473 ) => (left_time, left_not_before) == (right_time, right_not_before),
474 (Revoked, Revoked) => true,
475 (UnhandledCriticalExtension, UnhandledCriticalExtension) => true,
476 (UnknownIssuer, UnknownIssuer) => true,
477 (BadSignature, BadSignature) => true,
478 (NotValidForName, NotValidForName) => true,
479 (
480 NotValidForNameContext {
481 expected: left_expected,
482 presented: left_presented,
483 },
484 NotValidForNameContext {
485 expected: right_expected,
486 presented: right_presented,
487 },
488 ) => (left_expected, left_presented) == (right_expected, right_presented),
489 (InvalidPurpose, InvalidPurpose) => true,
490 (ApplicationVerificationFailure, ApplicationVerificationFailure) => true,
491 (UnknownRevocationStatus, UnknownRevocationStatus) => true,
492 (ExpiredRevocationList, ExpiredRevocationList) => true,
493 (
494 ExpiredRevocationListContext {
495 time: left_time,
496 next_update: left_next_update,
497 },
498 ExpiredRevocationListContext {
499 time: right_time,
500 next_update: right_next_update,
501 },
502 ) => (left_time, left_next_update) == (right_time, right_next_update),
503 _ => false,
504 }
505 }
506}
507
508impl From<CertificateError> for AlertDescription {
512 fn from(e: CertificateError) -> Self {
513 use CertificateError::*;
514 match e {
515 BadEncoding
516 | UnhandledCriticalExtension
517 | NotValidForName
518 | NotValidForNameContext { .. } => Self::BadCertificate,
519 Expired | ExpiredContext { .. } | NotValidYet | NotValidYetContext { .. } => {
523 Self::CertificateExpired
524 }
525 Revoked => Self::CertificateRevoked,
526 UnknownIssuer
529 | UnknownRevocationStatus
530 | ExpiredRevocationList
531 | ExpiredRevocationListContext { .. } => Self::UnknownCA,
532 BadSignature => Self::DecryptError,
533 InvalidPurpose => Self::UnsupportedCertificate,
534 ApplicationVerificationFailure => Self::AccessDenied,
535 Other(..) => Self::CertificateUnknown,
540 }
541 }
542}
543
544impl fmt::Display for CertificateError {
545 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
546 match self {
547 #[cfg(feature = "std")]
548 Self::NotValidForNameContext {
549 expected,
550 presented,
551 } => {
552 write!(
553 f,
554 "certificate not valid for name {:?}; certificate ",
555 expected.to_str()
556 )?;
557
558 match presented.as_slice() {
559 &[] => write!(
560 f,
561 "is not valid for any names (according to its subjectAltName extension)"
562 ),
563 [one] => write!(f, "is only valid for {}", one),
564 many => {
565 write!(f, "is only valid for ")?;
566
567 let n = many.len();
568 let all_but_last = &many[..n - 1];
569 let last = &many[n - 1];
570
571 for (i, name) in all_but_last.iter().enumerate() {
572 write!(f, "{}", name)?;
573 if i < n - 2 {
574 write!(f, ", ")?;
575 }
576 }
577 write!(f, " or {}", last)
578 }
579 }
580 }
581
582 Self::ExpiredContext { time, not_after } => write!(
583 f,
584 "certificate expired: verification time {} (UNIX), \
585 but certificate is not valid after {} \
586 ({} seconds ago)",
587 time.as_secs(),
588 not_after.as_secs(),
589 time.as_secs()
590 .saturating_sub(not_after.as_secs())
591 ),
592
593 Self::NotValidYetContext { time, not_before } => write!(
594 f,
595 "certificate not valid yet: verification time {} (UNIX), \
596 but certificate is not valid before {} \
597 ({} seconds in future)",
598 time.as_secs(),
599 not_before.as_secs(),
600 not_before
601 .as_secs()
602 .saturating_sub(time.as_secs())
603 ),
604
605 Self::ExpiredRevocationListContext { time, next_update } => write!(
606 f,
607 "certificate revocation list expired: \
608 verification time {} (UNIX), \
609 but CRL is not valid after {} \
610 ({} seconds ago)",
611 time.as_secs(),
612 next_update.as_secs(),
613 time.as_secs()
614 .saturating_sub(next_update.as_secs())
615 ),
616
617 other => write!(f, "{:?}", other),
618 }
619 }
620}
621
622impl From<CertificateError> for Error {
623 #[inline]
624 fn from(e: CertificateError) -> Self {
625 Self::InvalidCertificate(e)
626 }
627}
628
629#[non_exhaustive]
630#[derive(Debug, Clone)]
631pub enum CertRevocationListError {
633 BadSignature,
635
636 InvalidCrlNumber,
638
639 InvalidRevokedCertSerialNumber,
641
642 IssuerInvalidForCrl,
644
645 Other(OtherError),
649
650 ParseError,
652
653 UnsupportedCrlVersion,
655
656 UnsupportedCriticalExtension,
658
659 UnsupportedDeltaCrl,
661
662 UnsupportedIndirectCrl,
665
666 UnsupportedRevocationReason,
671}
672
673impl PartialEq<Self> for CertRevocationListError {
674 fn eq(&self, other: &Self) -> bool {
675 use CertRevocationListError::*;
676 #[allow(clippy::match_like_matches_macro)]
677 match (self, other) {
678 (BadSignature, BadSignature) => true,
679 (InvalidCrlNumber, InvalidCrlNumber) => true,
680 (InvalidRevokedCertSerialNumber, InvalidRevokedCertSerialNumber) => true,
681 (IssuerInvalidForCrl, IssuerInvalidForCrl) => true,
682 (ParseError, ParseError) => true,
683 (UnsupportedCrlVersion, UnsupportedCrlVersion) => true,
684 (UnsupportedCriticalExtension, UnsupportedCriticalExtension) => true,
685 (UnsupportedDeltaCrl, UnsupportedDeltaCrl) => true,
686 (UnsupportedIndirectCrl, UnsupportedIndirectCrl) => true,
687 (UnsupportedRevocationReason, UnsupportedRevocationReason) => true,
688 _ => false,
689 }
690 }
691}
692
693impl From<CertRevocationListError> for Error {
694 #[inline]
695 fn from(e: CertRevocationListError) -> Self {
696 Self::InvalidCertRevocationList(e)
697 }
698}
699
700#[non_exhaustive]
701#[derive(Debug, Clone, Eq, PartialEq)]
702pub enum EncryptedClientHelloError {
704 InvalidConfigList,
706 NoCompatibleConfig,
708 SniRequired,
710}
711
712impl From<EncryptedClientHelloError> for Error {
713 #[inline]
714 fn from(e: EncryptedClientHelloError) -> Self {
715 Self::InvalidEncryptedClientHello(e)
716 }
717}
718
719fn join<T: fmt::Debug>(items: &[T]) -> String {
720 items
721 .iter()
722 .map(|x| format!("{:?}", x))
723 .collect::<Vec<String>>()
724 .join(" or ")
725}
726
727impl fmt::Display for Error {
728 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
729 match self {
730 Self::InappropriateMessage {
731 expect_types,
732 got_type,
733 } => write!(
734 f,
735 "received unexpected message: got {:?} when expecting {}",
736 got_type,
737 join::<ContentType>(expect_types)
738 ),
739 Self::InappropriateHandshakeMessage {
740 expect_types,
741 got_type,
742 } => write!(
743 f,
744 "received unexpected handshake message: got {:?} when expecting {}",
745 got_type,
746 join::<HandshakeType>(expect_types)
747 ),
748 Self::InvalidMessage(typ) => {
749 write!(f, "received corrupt message of type {:?}", typ)
750 }
751 Self::PeerIncompatible(why) => write!(f, "peer is incompatible: {:?}", why),
752 Self::PeerMisbehaved(why) => write!(f, "peer misbehaved: {:?}", why),
753 Self::AlertReceived(alert) => write!(f, "received fatal alert: {:?}", alert),
754 Self::InvalidCertificate(err) => {
755 write!(f, "invalid peer certificate: {}", err)
756 }
757 Self::InvalidCertRevocationList(err) => {
758 write!(f, "invalid certificate revocation list: {:?}", err)
759 }
760 Self::NoCertificatesPresented => write!(f, "peer sent no certificates"),
761 Self::UnsupportedNameType => write!(f, "presented server name type wasn't supported"),
762 Self::DecryptError => write!(f, "cannot decrypt peer's message"),
763 Self::InvalidEncryptedClientHello(err) => {
764 write!(f, "encrypted client hello failure: {:?}", err)
765 }
766 Self::EncryptError => write!(f, "cannot encrypt message"),
767 Self::PeerSentOversizedRecord => write!(f, "peer sent excess record size"),
768 Self::HandshakeNotComplete => write!(f, "handshake not complete"),
769 Self::NoApplicationProtocol => write!(f, "peer doesn't support any known protocol"),
770 Self::FailedToGetCurrentTime => write!(f, "failed to get current time"),
771 Self::FailedToGetRandomBytes => write!(f, "failed to get random bytes"),
772 Self::BadMaxFragmentSize => {
773 write!(f, "the supplied max_fragment_size was too small or large")
774 }
775 Self::InconsistentKeys(why) => {
776 write!(f, "keys may not be consistent: {:?}", why)
777 }
778 Self::General(err) => write!(f, "unexpected error: {}", err),
779 Self::Other(err) => write!(f, "other error: {}", err),
780 }
781 }
782}
783
784#[cfg(feature = "std")]
785impl From<SystemTimeError> for Error {
786 #[inline]
787 fn from(_: SystemTimeError) -> Self {
788 Self::FailedToGetCurrentTime
789 }
790}
791
792#[cfg(feature = "std")]
793impl std::error::Error for Error {}
794
795impl From<rand::GetRandomFailed> for Error {
796 fn from(_: rand::GetRandomFailed) -> Self {
797 Self::FailedToGetRandomBytes
798 }
799}
800
801mod other_error {
802 use core::fmt;
803 #[cfg(feature = "std")]
804 use std::error::Error as StdError;
805
806 use super::Error;
807 #[cfg(feature = "std")]
808 use crate::sync::Arc;
809
810 #[derive(Debug, Clone)]
817 pub struct OtherError(#[cfg(feature = "std")] pub Arc<dyn StdError + Send + Sync>);
818
819 impl PartialEq<Self> for OtherError {
820 fn eq(&self, _other: &Self) -> bool {
821 false
822 }
823 }
824
825 impl From<OtherError> for Error {
826 fn from(value: OtherError) -> Self {
827 Self::Other(value)
828 }
829 }
830
831 impl fmt::Display for OtherError {
832 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
833 #[cfg(feature = "std")]
834 {
835 write!(f, "{}", self.0)
836 }
837 #[cfg(not(feature = "std"))]
838 {
839 f.write_str("no further information available")
840 }
841 }
842 }
843
844 #[cfg(feature = "std")]
845 impl StdError for OtherError {
846 fn source(&self) -> Option<&(dyn StdError + 'static)> {
847 Some(self.0.as_ref())
848 }
849 }
850}
851
852pub use other_error::OtherError;
853
854#[cfg(test)]
855mod tests {
856 use core::time::Duration;
857 use std::prelude::v1::*;
858 use std::{println, vec};
859
860 use super::{
861 CertRevocationListError, Error, InconsistentKeys, InvalidMessage, OtherError, UnixTime,
862 };
863 #[cfg(feature = "std")]
864 use crate::sync::Arc;
865 use pki_types::ServerName;
866
867 #[test]
868 fn certificate_error_equality() {
869 use super::CertificateError::*;
870 assert_eq!(BadEncoding, BadEncoding);
871 assert_eq!(Expired, Expired);
872 let context = ExpiredContext {
873 time: UnixTime::since_unix_epoch(Duration::from_secs(1234)),
874 not_after: UnixTime::since_unix_epoch(Duration::from_secs(123)),
875 };
876 assert_eq!(context, context);
877 assert_ne!(
878 context,
879 ExpiredContext {
880 time: UnixTime::since_unix_epoch(Duration::from_secs(12345)),
881 not_after: UnixTime::since_unix_epoch(Duration::from_secs(123)),
882 }
883 );
884 assert_ne!(
885 context,
886 ExpiredContext {
887 time: UnixTime::since_unix_epoch(Duration::from_secs(1234)),
888 not_after: UnixTime::since_unix_epoch(Duration::from_secs(1234)),
889 }
890 );
891 assert_eq!(NotValidYet, NotValidYet);
892 let context = NotValidYetContext {
893 time: UnixTime::since_unix_epoch(Duration::from_secs(123)),
894 not_before: UnixTime::since_unix_epoch(Duration::from_secs(1234)),
895 };
896 assert_eq!(context, context);
897 assert_ne!(
898 context,
899 NotValidYetContext {
900 time: UnixTime::since_unix_epoch(Duration::from_secs(1234)),
901 not_before: UnixTime::since_unix_epoch(Duration::from_secs(1234)),
902 }
903 );
904 assert_ne!(
905 context,
906 NotValidYetContext {
907 time: UnixTime::since_unix_epoch(Duration::from_secs(123)),
908 not_before: UnixTime::since_unix_epoch(Duration::from_secs(12345)),
909 }
910 );
911 assert_eq!(Revoked, Revoked);
912 assert_eq!(UnhandledCriticalExtension, UnhandledCriticalExtension);
913 assert_eq!(UnknownIssuer, UnknownIssuer);
914 assert_eq!(ExpiredRevocationList, ExpiredRevocationList);
915 assert_eq!(UnknownRevocationStatus, UnknownRevocationStatus);
916 let context = ExpiredRevocationListContext {
917 time: UnixTime::since_unix_epoch(Duration::from_secs(1234)),
918 next_update: UnixTime::since_unix_epoch(Duration::from_secs(123)),
919 };
920 assert_eq!(context, context);
921 assert_ne!(
922 context,
923 ExpiredRevocationListContext {
924 time: UnixTime::since_unix_epoch(Duration::from_secs(12345)),
925 next_update: UnixTime::since_unix_epoch(Duration::from_secs(123)),
926 }
927 );
928 assert_ne!(
929 context,
930 ExpiredRevocationListContext {
931 time: UnixTime::since_unix_epoch(Duration::from_secs(1234)),
932 next_update: UnixTime::since_unix_epoch(Duration::from_secs(1234)),
933 }
934 );
935 assert_eq!(BadSignature, BadSignature);
936 assert_eq!(NotValidForName, NotValidForName);
937 let context = NotValidForNameContext {
938 expected: ServerName::try_from("example.com")
939 .unwrap()
940 .to_owned(),
941 presented: vec!["other.com".into()],
942 };
943 assert_eq!(context, context);
944 assert_ne!(
945 context,
946 NotValidForNameContext {
947 expected: ServerName::try_from("example.com")
948 .unwrap()
949 .to_owned(),
950 presented: vec![]
951 }
952 );
953 assert_ne!(
954 context,
955 NotValidForNameContext {
956 expected: ServerName::try_from("huh.com")
957 .unwrap()
958 .to_owned(),
959 presented: vec!["other.com".into()],
960 }
961 );
962 assert_eq!(InvalidPurpose, InvalidPurpose);
963 assert_eq!(
964 ApplicationVerificationFailure,
965 ApplicationVerificationFailure
966 );
967 let other = Other(OtherError(
968 #[cfg(feature = "std")]
969 Arc::from(Box::from("")),
970 ));
971 assert_ne!(other, other);
972 assert_ne!(BadEncoding, Expired);
973 }
974
975 #[test]
976 fn crl_error_equality() {
977 use super::CertRevocationListError::*;
978 assert_eq!(BadSignature, BadSignature);
979 assert_eq!(InvalidCrlNumber, InvalidCrlNumber);
980 assert_eq!(
981 InvalidRevokedCertSerialNumber,
982 InvalidRevokedCertSerialNumber
983 );
984 assert_eq!(IssuerInvalidForCrl, IssuerInvalidForCrl);
985 assert_eq!(ParseError, ParseError);
986 assert_eq!(UnsupportedCriticalExtension, UnsupportedCriticalExtension);
987 assert_eq!(UnsupportedCrlVersion, UnsupportedCrlVersion);
988 assert_eq!(UnsupportedDeltaCrl, UnsupportedDeltaCrl);
989 assert_eq!(UnsupportedIndirectCrl, UnsupportedIndirectCrl);
990 assert_eq!(UnsupportedRevocationReason, UnsupportedRevocationReason);
991 let other = Other(OtherError(
992 #[cfg(feature = "std")]
993 Arc::from(Box::from("")),
994 ));
995 assert_ne!(other, other);
996 assert_ne!(BadSignature, InvalidCrlNumber);
997 }
998
999 #[test]
1000 #[cfg(feature = "std")]
1001 fn other_error_equality() {
1002 let other_error = OtherError(Arc::from(Box::from("")));
1003 assert_ne!(other_error, other_error);
1004 let other: Error = other_error.into();
1005 assert_ne!(other, other);
1006 }
1007
1008 #[test]
1009 fn smoke() {
1010 use crate::enums::{AlertDescription, ContentType, HandshakeType};
1011
1012 let all = vec![
1013 Error::InappropriateMessage {
1014 expect_types: vec![ContentType::Alert],
1015 got_type: ContentType::Handshake,
1016 },
1017 Error::InappropriateHandshakeMessage {
1018 expect_types: vec![HandshakeType::ClientHello, HandshakeType::Finished],
1019 got_type: HandshakeType::ServerHello,
1020 },
1021 Error::InvalidMessage(InvalidMessage::InvalidCcs),
1022 Error::NoCertificatesPresented,
1023 Error::DecryptError,
1024 super::PeerIncompatible::Tls12NotOffered.into(),
1025 super::PeerMisbehaved::UnsolicitedCertExtension.into(),
1026 Error::AlertReceived(AlertDescription::ExportRestriction),
1027 super::CertificateError::Expired.into(),
1028 super::CertificateError::NotValidForNameContext {
1029 expected: ServerName::try_from("example.com")
1030 .unwrap()
1031 .to_owned(),
1032 presented: vec![],
1033 }
1034 .into(),
1035 super::CertificateError::NotValidForNameContext {
1036 expected: ServerName::try_from("example.com")
1037 .unwrap()
1038 .to_owned(),
1039 presented: vec!["DnsName(\"hello.com\")".into()],
1040 }
1041 .into(),
1042 super::CertificateError::NotValidForNameContext {
1043 expected: ServerName::try_from("example.com")
1044 .unwrap()
1045 .to_owned(),
1046 presented: vec![
1047 "DnsName(\"hello.com\")".into(),
1048 "DnsName(\"goodbye.com\")".into(),
1049 ],
1050 }
1051 .into(),
1052 super::CertificateError::NotValidYetContext {
1053 time: UnixTime::since_unix_epoch(Duration::from_secs(300)),
1054 not_before: UnixTime::since_unix_epoch(Duration::from_secs(320)),
1055 }
1056 .into(),
1057 super::CertificateError::ExpiredContext {
1058 time: UnixTime::since_unix_epoch(Duration::from_secs(320)),
1059 not_after: UnixTime::since_unix_epoch(Duration::from_secs(300)),
1060 }
1061 .into(),
1062 super::CertificateError::ExpiredRevocationListContext {
1063 time: UnixTime::since_unix_epoch(Duration::from_secs(320)),
1064 next_update: UnixTime::since_unix_epoch(Duration::from_secs(300)),
1065 }
1066 .into(),
1067 Error::General("undocumented error".to_string()),
1068 Error::FailedToGetCurrentTime,
1069 Error::FailedToGetRandomBytes,
1070 Error::HandshakeNotComplete,
1071 Error::PeerSentOversizedRecord,
1072 Error::NoApplicationProtocol,
1073 Error::BadMaxFragmentSize,
1074 Error::InconsistentKeys(InconsistentKeys::KeyMismatch),
1075 Error::InconsistentKeys(InconsistentKeys::Unknown),
1076 Error::InvalidCertRevocationList(CertRevocationListError::BadSignature),
1077 Error::Other(OtherError(
1078 #[cfg(feature = "std")]
1079 Arc::from(Box::from("")),
1080 )),
1081 ];
1082
1083 for err in all {
1084 println!("{:?}:", err);
1085 println!(" fmt '{}'", err);
1086 }
1087 }
1088
1089 #[test]
1090 fn rand_error_mapping() {
1091 use super::rand;
1092 let err: Error = rand::GetRandomFailed.into();
1093 assert_eq!(err, Error::FailedToGetRandomBytes);
1094 }
1095
1096 #[cfg(feature = "std")]
1097 #[test]
1098 fn time_error_mapping() {
1099 use std::time::SystemTime;
1100
1101 let time_error = SystemTime::UNIX_EPOCH
1102 .duration_since(SystemTime::now())
1103 .unwrap_err();
1104 let err: Error = time_error.into();
1105 assert_eq!(err, Error::FailedToGetCurrentTime);
1106 }
1107}