1use alloc::format;
2use alloc::string::String;
3use alloc::vec::Vec;
4use core::fmt;
5#[cfg(feature = "std")]
6use std::time::SystemTimeError;
7
8use pki_types::{ServerName, UnixTime};
9use webpki::KeyUsage;
10
11use crate::enums::{AlertDescription, ContentType, HandshakeType};
12use crate::msgs::handshake::{EchConfigPayload, KeyExchangeAlgorithm};
13use crate::rand;
14
15#[non_exhaustive]
17#[derive(Debug, PartialEq, Clone)]
18pub enum Error {
19 InappropriateMessage {
25 expect_types: Vec<ContentType>,
27 got_type: ContentType,
29 },
30
31 InappropriateHandshakeMessage {
35 expect_types: Vec<HandshakeType>,
37 got_type: HandshakeType,
39 },
40
41 InvalidEncryptedClientHello(EncryptedClientHelloError),
43
44 InvalidMessage(InvalidMessage),
46
47 NoCertificatesPresented,
49
50 UnsupportedNameType,
52
53 DecryptError,
55
56 EncryptError,
59
60 PeerIncompatible(PeerIncompatible),
63
64 PeerMisbehaved(PeerMisbehaved),
67
68 AlertReceived(AlertDescription),
70
71 InvalidCertificate(CertificateError),
76
77 InvalidCertRevocationList(CertRevocationListError),
79
80 General(String),
82
83 FailedToGetCurrentTime,
85
86 FailedToGetRandomBytes,
88
89 HandshakeNotComplete,
92
93 PeerSentOversizedRecord,
95
96 NoApplicationProtocol,
98
99 BadMaxFragmentSize,
102
103 InconsistentKeys(InconsistentKeys),
107
108 Other(OtherError),
116}
117
118#[non_exhaustive]
122#[derive(Clone, Copy, Debug, Eq, PartialEq)]
123pub enum InconsistentKeys {
124 KeyMismatch,
128
129 Unknown,
133}
134
135impl From<InconsistentKeys> for Error {
136 #[inline]
137 fn from(e: InconsistentKeys) -> Self {
138 Self::InconsistentKeys(e)
139 }
140}
141
142#[non_exhaustive]
144#[derive(Debug, Clone, Copy, PartialEq)]
145
146pub enum InvalidMessage {
147 CertificatePayloadTooLarge,
149 HandshakePayloadTooLarge,
151 InvalidCcs,
153 InvalidContentType,
155 InvalidCertificateStatusType,
157 InvalidCertRequest,
159 InvalidDhParams,
161 InvalidEmptyPayload,
163 InvalidKeyUpdate,
165 InvalidServerName,
167 MessageTooLarge,
169 MessageTooShort,
171 MissingData(&'static str),
173 MissingKeyExchange,
175 NoSignatureSchemes,
177 TrailingData(&'static str),
179 UnexpectedMessage(&'static str),
181 UnknownProtocolVersion,
183 UnsupportedCompression,
185 UnsupportedCurveType,
187 UnsupportedKeyExchangeAlgorithm(KeyExchangeAlgorithm),
189 EmptyTicketValue,
191 IllegalEmptyList(&'static str),
195 IllegalEmptyValue,
197}
198
199impl From<InvalidMessage> for Error {
200 #[inline]
201 fn from(e: InvalidMessage) -> Self {
202 Self::InvalidMessage(e)
203 }
204}
205
206impl From<InvalidMessage> for AlertDescription {
207 fn from(_: InvalidMessage) -> Self {
208 Self::DecodeError
209 }
210}
211
212#[non_exhaustive]
213#[allow(missing_docs)]
214#[derive(Debug, PartialEq, Clone)]
215pub enum PeerMisbehaved {
226 AttemptedDowngradeToTls12WhenTls13IsSupported,
227 BadCertChainExtensions,
228 DisallowedEncryptedExtension,
229 DuplicateClientHelloExtensions,
230 DuplicateEncryptedExtensions,
231 DuplicateHelloRetryRequestExtensions,
232 DuplicateNewSessionTicketExtensions,
233 DuplicateServerHelloExtensions,
234 DuplicateServerNameTypes,
235 EarlyDataAttemptedInSecondClientHello,
236 EarlyDataExtensionWithoutResumption,
237 EarlyDataOfferedWithVariedCipherSuite,
238 HandshakeHashVariedAfterRetry,
239 IllegalHelloRetryRequestWithEmptyCookie,
240 IllegalHelloRetryRequestWithNoChanges,
241 IllegalHelloRetryRequestWithOfferedGroup,
242 IllegalHelloRetryRequestWithUnofferedCipherSuite,
243 IllegalHelloRetryRequestWithUnofferedNamedGroup,
244 IllegalHelloRetryRequestWithUnsupportedVersion,
245 IllegalHelloRetryRequestWithWrongSessionId,
246 IllegalHelloRetryRequestWithInvalidEch,
247 IllegalMiddleboxChangeCipherSpec,
248 IllegalTlsInnerPlaintext,
249 IncorrectBinder,
250 InvalidCertCompression,
251 InvalidMaxEarlyDataSize,
252 InvalidKeyShare,
253 KeyEpochWithPendingFragment,
254 KeyUpdateReceivedInQuicConnection,
255 MessageInterleavedWithHandshakeMessage,
256 MissingBinderInPskExtension,
257 MissingKeyShare,
258 MissingPskModesExtension,
259 MissingQuicTransportParameters,
260 OfferedDuplicateCertificateCompressions,
261 OfferedDuplicateKeyShares,
262 OfferedEarlyDataWithOldProtocolVersion,
263 OfferedEmptyApplicationProtocol,
264 OfferedIncorrectCompressions,
265 PskExtensionMustBeLast,
266 PskExtensionWithMismatchedIdsAndBinders,
267 RefusedToFollowHelloRetryRequest,
268 RejectedEarlyDataInterleavedWithHandshakeMessage,
269 ResumptionAttemptedWithVariedEms,
270 ResumptionOfferedWithVariedCipherSuite,
271 ResumptionOfferedWithVariedEms,
272 ResumptionOfferedWithIncompatibleCipherSuite,
273 SelectedDifferentCipherSuiteAfterRetry,
274 SelectedInvalidPsk,
275 SelectedTls12UsingTls13VersionExtension,
276 SelectedUnofferedApplicationProtocol,
277 SelectedUnofferedCertCompression,
278 SelectedUnofferedCipherSuite,
279 SelectedUnofferedCompression,
280 SelectedUnofferedKxGroup,
281 SelectedUnofferedPsk,
282 SelectedUnusableCipherSuiteForVersion,
283 ServerEchoedCompatibilitySessionId,
284 ServerHelloMustOfferUncompressedEcPoints,
285 ServerNameDifferedOnRetry,
286 ServerNameMustContainOneHostName,
287 SignedKxWithWrongAlgorithm,
288 SignedHandshakeWithUnadvertisedSigScheme,
289 TooManyEmptyFragments,
290 TooManyKeyUpdateRequests,
291 TooManyRenegotiationRequests,
292 TooManyWarningAlertsReceived,
293 TooMuchEarlyDataReceived,
294 UnexpectedCleartextExtension,
295 UnsolicitedCertExtension,
296 UnsolicitedEncryptedExtension,
297 UnsolicitedSctList,
298 UnsolicitedServerHelloExtension,
299 WrongGroupForKeyShare,
300 UnsolicitedEchExtension,
301}
302
303impl From<PeerMisbehaved> for Error {
304 #[inline]
305 fn from(e: PeerMisbehaved) -> Self {
306 Self::PeerMisbehaved(e)
307 }
308}
309
310#[non_exhaustive]
311#[allow(missing_docs)]
312#[derive(Debug, PartialEq, Clone)]
313pub enum PeerIncompatible {
319 EcPointsExtensionRequired,
320 ExtendedMasterSecretExtensionRequired,
321 IncorrectCertificateTypeExtension,
322 KeyShareExtensionRequired,
323 NamedGroupsExtensionRequired,
324 NoCertificateRequestSignatureSchemesInCommon,
325 NoCipherSuitesInCommon,
326 NoEcPointFormatsInCommon,
327 NoKxGroupsInCommon,
328 NoSignatureSchemesInCommon,
329 NullCompressionRequired,
330 ServerDoesNotSupportTls12Or13,
331 ServerSentHelloRetryRequestWithUnknownExtension,
332 ServerTlsVersionIsDisabledByOurConfig,
333 SignatureAlgorithmsExtensionRequired,
334 SupportedVersionsExtensionRequired,
335 Tls12NotOffered,
336 Tls12NotOfferedOrEnabled,
337 Tls13RequiredForQuic,
338 UncompressedEcPointsRequired,
339 UnsolicitedCertificateTypeExtension,
340 ServerRejectedEncryptedClientHello(Option<Vec<EchConfigPayload>>),
341}
342
343impl From<PeerIncompatible> for Error {
344 #[inline]
345 fn from(e: PeerIncompatible) -> Self {
346 Self::PeerIncompatible(e)
347 }
348}
349
350#[non_exhaustive]
351#[derive(Debug, Clone)]
352pub enum CertificateError {
360 BadEncoding,
362
363 Expired,
365
366 ExpiredContext {
371 time: UnixTime,
373 not_after: UnixTime,
375 },
376
377 NotValidYet,
379
380 NotValidYetContext {
385 time: UnixTime,
387 not_before: UnixTime,
389 },
390
391 Revoked,
393
394 UnhandledCriticalExtension,
397
398 UnknownIssuer,
400
401 UnknownRevocationStatus,
403
404 ExpiredRevocationList,
406
407 ExpiredRevocationListContext {
412 time: UnixTime,
414 next_update: UnixTime,
416 },
417
418 BadSignature,
421
422 UnsupportedSignatureAlgorithm,
424
425 NotValidForName,
428
429 NotValidForNameContext {
435 expected: ServerName<'static>,
437
438 presented: Vec<String>,
443 },
444
445 InvalidPurpose,
447
448 InvalidPurposeContext {
453 required: ExtendedKeyPurpose,
455 presented: Vec<ExtendedKeyPurpose>,
457 },
458
459 ApplicationVerificationFailure,
462
463 Other(OtherError),
474}
475
476impl PartialEq<Self> for CertificateError {
477 fn eq(&self, other: &Self) -> bool {
478 use CertificateError::*;
479 #[allow(clippy::match_like_matches_macro)]
480 match (self, other) {
481 (BadEncoding, BadEncoding) => true,
482 (Expired, Expired) => true,
483 (
484 ExpiredContext {
485 time: left_time,
486 not_after: left_not_after,
487 },
488 ExpiredContext {
489 time: right_time,
490 not_after: right_not_after,
491 },
492 ) => (left_time, left_not_after) == (right_time, right_not_after),
493 (NotValidYet, NotValidYet) => true,
494 (
495 NotValidYetContext {
496 time: left_time,
497 not_before: left_not_before,
498 },
499 NotValidYetContext {
500 time: right_time,
501 not_before: right_not_before,
502 },
503 ) => (left_time, left_not_before) == (right_time, right_not_before),
504 (Revoked, Revoked) => true,
505 (UnhandledCriticalExtension, UnhandledCriticalExtension) => true,
506 (UnknownIssuer, UnknownIssuer) => true,
507 (BadSignature, BadSignature) => true,
508 (UnsupportedSignatureAlgorithm, UnsupportedSignatureAlgorithm) => true,
509 (NotValidForName, NotValidForName) => true,
510 (
511 NotValidForNameContext {
512 expected: left_expected,
513 presented: left_presented,
514 },
515 NotValidForNameContext {
516 expected: right_expected,
517 presented: right_presented,
518 },
519 ) => (left_expected, left_presented) == (right_expected, right_presented),
520 (InvalidPurpose, InvalidPurpose) => true,
521 (
522 InvalidPurposeContext {
523 required: left_required,
524 presented: left_presented,
525 },
526 InvalidPurposeContext {
527 required: right_required,
528 presented: right_presented,
529 },
530 ) => (left_required, left_presented) == (right_required, right_presented),
531 (ApplicationVerificationFailure, ApplicationVerificationFailure) => true,
532 (UnknownRevocationStatus, UnknownRevocationStatus) => true,
533 (ExpiredRevocationList, ExpiredRevocationList) => true,
534 (
535 ExpiredRevocationListContext {
536 time: left_time,
537 next_update: left_next_update,
538 },
539 ExpiredRevocationListContext {
540 time: right_time,
541 next_update: right_next_update,
542 },
543 ) => (left_time, left_next_update) == (right_time, right_next_update),
544 _ => false,
545 }
546 }
547}
548
549impl From<CertificateError> for AlertDescription {
553 fn from(e: CertificateError) -> Self {
554 use CertificateError::*;
555 match e {
556 BadEncoding
557 | UnhandledCriticalExtension
558 | NotValidForName
559 | NotValidForNameContext { .. } => Self::BadCertificate,
560 Expired | ExpiredContext { .. } | NotValidYet | NotValidYetContext { .. } => {
564 Self::CertificateExpired
565 }
566 Revoked => Self::CertificateRevoked,
567 UnknownIssuer
570 | UnknownRevocationStatus
571 | ExpiredRevocationList
572 | ExpiredRevocationListContext { .. } => Self::UnknownCA,
573 BadSignature | UnsupportedSignatureAlgorithm => Self::DecryptError,
574 InvalidPurpose | InvalidPurposeContext { .. } => Self::UnsupportedCertificate,
575 ApplicationVerificationFailure => Self::AccessDenied,
576 Other(..) => Self::CertificateUnknown,
581 }
582 }
583}
584
585impl fmt::Display for CertificateError {
586 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
587 match self {
588 #[cfg(feature = "std")]
589 Self::NotValidForNameContext {
590 expected,
591 presented,
592 } => {
593 write!(
594 f,
595 "certificate not valid for name {:?}; certificate ",
596 expected.to_str()
597 )?;
598
599 match presented.as_slice() {
600 &[] => write!(
601 f,
602 "is not valid for any names (according to its subjectAltName extension)"
603 ),
604 [one] => write!(f, "is only valid for {one}"),
605 many => {
606 write!(f, "is only valid for ")?;
607
608 let n = many.len();
609 let all_but_last = &many[..n - 1];
610 let last = &many[n - 1];
611
612 for (i, name) in all_but_last.iter().enumerate() {
613 write!(f, "{name}")?;
614 if i < n - 2 {
615 write!(f, ", ")?;
616 }
617 }
618 write!(f, " or {last}")
619 }
620 }
621 }
622
623 Self::ExpiredContext { time, not_after } => write!(
624 f,
625 "certificate expired: verification time {} (UNIX), \
626 but certificate is not valid after {} \
627 ({} seconds ago)",
628 time.as_secs(),
629 not_after.as_secs(),
630 time.as_secs()
631 .saturating_sub(not_after.as_secs())
632 ),
633
634 Self::NotValidYetContext { time, not_before } => write!(
635 f,
636 "certificate not valid yet: verification time {} (UNIX), \
637 but certificate is not valid before {} \
638 ({} seconds in future)",
639 time.as_secs(),
640 not_before.as_secs(),
641 not_before
642 .as_secs()
643 .saturating_sub(time.as_secs())
644 ),
645
646 Self::ExpiredRevocationListContext { time, next_update } => write!(
647 f,
648 "certificate revocation list expired: \
649 verification time {} (UNIX), \
650 but CRL is not valid after {} \
651 ({} seconds ago)",
652 time.as_secs(),
653 next_update.as_secs(),
654 time.as_secs()
655 .saturating_sub(next_update.as_secs())
656 ),
657
658 Self::InvalidPurposeContext {
659 required,
660 presented,
661 } => {
662 write!(
663 f,
664 "certificate does not allow extended key usage for {required}, allows "
665 )?;
666 for (i, eku) in presented.iter().enumerate() {
667 if i > 0 {
668 write!(f, ", ")?;
669 }
670 write!(f, "{eku}")?;
671 }
672 Ok(())
673 }
674
675 other => write!(f, "{other:?}"),
676 }
677 }
678}
679
680impl From<CertificateError> for Error {
681 #[inline]
682 fn from(e: CertificateError) -> Self {
683 Self::InvalidCertificate(e)
684 }
685}
686
687#[derive(Clone, Debug, Eq, PartialEq)]
692pub enum ExtendedKeyPurpose {
693 ClientAuth,
695 ServerAuth,
697 Other(Vec<usize>),
701}
702
703impl ExtendedKeyPurpose {
704 pub(crate) fn for_values(values: impl Iterator<Item = usize>) -> Self {
705 let values = values.collect::<Vec<_>>();
706 match &*values {
707 KeyUsage::CLIENT_AUTH_REPR => Self::ClientAuth,
708 KeyUsage::SERVER_AUTH_REPR => Self::ServerAuth,
709 _ => Self::Other(values),
710 }
711 }
712}
713
714impl fmt::Display for ExtendedKeyPurpose {
715 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
716 match self {
717 Self::ClientAuth => write!(f, "client authentication"),
718 Self::ServerAuth => write!(f, "server authentication"),
719 Self::Other(values) => {
720 for (i, value) in values.iter().enumerate() {
721 if i > 0 {
722 write!(f, ", ")?;
723 }
724 write!(f, "{value}")?;
725 }
726 Ok(())
727 }
728 }
729 }
730}
731
732#[non_exhaustive]
733#[derive(Debug, Clone)]
734pub enum CertRevocationListError {
736 BadSignature,
738
739 UnsupportedSignatureAlgorithm,
741
742 InvalidCrlNumber,
744
745 InvalidRevokedCertSerialNumber,
747
748 IssuerInvalidForCrl,
750
751 Other(OtherError),
755
756 ParseError,
758
759 UnsupportedCrlVersion,
761
762 UnsupportedCriticalExtension,
764
765 UnsupportedDeltaCrl,
767
768 UnsupportedIndirectCrl,
771
772 UnsupportedRevocationReason,
777}
778
779impl PartialEq<Self> for CertRevocationListError {
780 fn eq(&self, other: &Self) -> bool {
781 use CertRevocationListError::*;
782 #[allow(clippy::match_like_matches_macro)]
783 match (self, other) {
784 (BadSignature, BadSignature) => true,
785 (UnsupportedSignatureAlgorithm, UnsupportedSignatureAlgorithm) => true,
786 (InvalidCrlNumber, InvalidCrlNumber) => true,
787 (InvalidRevokedCertSerialNumber, InvalidRevokedCertSerialNumber) => true,
788 (IssuerInvalidForCrl, IssuerInvalidForCrl) => true,
789 (ParseError, ParseError) => true,
790 (UnsupportedCrlVersion, UnsupportedCrlVersion) => true,
791 (UnsupportedCriticalExtension, UnsupportedCriticalExtension) => true,
792 (UnsupportedDeltaCrl, UnsupportedDeltaCrl) => true,
793 (UnsupportedIndirectCrl, UnsupportedIndirectCrl) => true,
794 (UnsupportedRevocationReason, UnsupportedRevocationReason) => true,
795 _ => false,
796 }
797 }
798}
799
800impl From<CertRevocationListError> for Error {
801 #[inline]
802 fn from(e: CertRevocationListError) -> Self {
803 Self::InvalidCertRevocationList(e)
804 }
805}
806
807#[non_exhaustive]
808#[derive(Debug, Clone, Eq, PartialEq)]
809pub enum EncryptedClientHelloError {
811 InvalidConfigList,
813 NoCompatibleConfig,
815 SniRequired,
817}
818
819impl From<EncryptedClientHelloError> for Error {
820 #[inline]
821 fn from(e: EncryptedClientHelloError) -> Self {
822 Self::InvalidEncryptedClientHello(e)
823 }
824}
825
826fn join<T: fmt::Debug>(items: &[T]) -> String {
827 items
828 .iter()
829 .map(|x| format!("{x:?}"))
830 .collect::<Vec<String>>()
831 .join(" or ")
832}
833
834impl fmt::Display for Error {
835 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
836 match self {
837 Self::InappropriateMessage {
838 expect_types,
839 got_type,
840 } => write!(
841 f,
842 "received unexpected message: got {:?} when expecting {}",
843 got_type,
844 join::<ContentType>(expect_types)
845 ),
846 Self::InappropriateHandshakeMessage {
847 expect_types,
848 got_type,
849 } => write!(
850 f,
851 "received unexpected handshake message: got {:?} when expecting {}",
852 got_type,
853 join::<HandshakeType>(expect_types)
854 ),
855 Self::InvalidMessage(typ) => {
856 write!(f, "received corrupt message of type {typ:?}")
857 }
858 Self::PeerIncompatible(why) => write!(f, "peer is incompatible: {why:?}"),
859 Self::PeerMisbehaved(why) => write!(f, "peer misbehaved: {why:?}"),
860 Self::AlertReceived(alert) => write!(f, "received fatal alert: {alert:?}"),
861 Self::InvalidCertificate(err) => {
862 write!(f, "invalid peer certificate: {err}")
863 }
864 Self::InvalidCertRevocationList(err) => {
865 write!(f, "invalid certificate revocation list: {err:?}")
866 }
867 Self::NoCertificatesPresented => write!(f, "peer sent no certificates"),
868 Self::UnsupportedNameType => write!(f, "presented server name type wasn't supported"),
869 Self::DecryptError => write!(f, "cannot decrypt peer's message"),
870 Self::InvalidEncryptedClientHello(err) => {
871 write!(f, "encrypted client hello failure: {err:?}")
872 }
873 Self::EncryptError => write!(f, "cannot encrypt message"),
874 Self::PeerSentOversizedRecord => write!(f, "peer sent excess record size"),
875 Self::HandshakeNotComplete => write!(f, "handshake not complete"),
876 Self::NoApplicationProtocol => write!(f, "peer doesn't support any known protocol"),
877 Self::FailedToGetCurrentTime => write!(f, "failed to get current time"),
878 Self::FailedToGetRandomBytes => write!(f, "failed to get random bytes"),
879 Self::BadMaxFragmentSize => {
880 write!(f, "the supplied max_fragment_size was too small or large")
881 }
882 Self::InconsistentKeys(why) => {
883 write!(f, "keys may not be consistent: {why:?}")
884 }
885 Self::General(err) => write!(f, "unexpected error: {err}"),
886 Self::Other(err) => write!(f, "other error: {err}"),
887 }
888 }
889}
890
891#[cfg(feature = "std")]
892impl From<SystemTimeError> for Error {
893 #[inline]
894 fn from(_: SystemTimeError) -> Self {
895 Self::FailedToGetCurrentTime
896 }
897}
898
899#[cfg(feature = "std")]
900impl std::error::Error for Error {}
901
902impl From<rand::GetRandomFailed> for Error {
903 fn from(_: rand::GetRandomFailed) -> Self {
904 Self::FailedToGetRandomBytes
905 }
906}
907
908mod other_error {
909 use core::fmt;
910 #[cfg(feature = "std")]
911 use std::error::Error as StdError;
912
913 use super::Error;
914 #[cfg(feature = "std")]
915 use crate::sync::Arc;
916
917 #[derive(Debug, Clone)]
924 pub struct OtherError(#[cfg(feature = "std")] pub Arc<dyn StdError + Send + Sync>);
925
926 impl PartialEq<Self> for OtherError {
927 fn eq(&self, _other: &Self) -> bool {
928 false
929 }
930 }
931
932 impl From<OtherError> for Error {
933 fn from(value: OtherError) -> Self {
934 Self::Other(value)
935 }
936 }
937
938 impl fmt::Display for OtherError {
939 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
940 #[cfg(feature = "std")]
941 {
942 write!(f, "{}", self.0)
943 }
944 #[cfg(not(feature = "std"))]
945 {
946 f.write_str("no further information available")
947 }
948 }
949 }
950
951 #[cfg(feature = "std")]
952 impl StdError for OtherError {
953 fn source(&self) -> Option<&(dyn StdError + 'static)> {
954 Some(self.0.as_ref())
955 }
956 }
957}
958
959pub use other_error::OtherError;
960
961#[cfg(test)]
962mod tests {
963 use core::time::Duration;
964 use std::prelude::v1::*;
965 use std::{println, vec};
966
967 use pki_types::ServerName;
968
969 use super::{
970 CertRevocationListError, Error, InconsistentKeys, InvalidMessage, OtherError, UnixTime,
971 };
972 #[cfg(feature = "std")]
973 use crate::sync::Arc;
974
975 #[test]
976 fn certificate_error_equality() {
977 use super::CertificateError::*;
978 assert_eq!(BadEncoding, BadEncoding);
979 assert_eq!(Expired, Expired);
980 let context = ExpiredContext {
981 time: UnixTime::since_unix_epoch(Duration::from_secs(1234)),
982 not_after: UnixTime::since_unix_epoch(Duration::from_secs(123)),
983 };
984 assert_eq!(context, context);
985 assert_ne!(
986 context,
987 ExpiredContext {
988 time: UnixTime::since_unix_epoch(Duration::from_secs(12345)),
989 not_after: UnixTime::since_unix_epoch(Duration::from_secs(123)),
990 }
991 );
992 assert_ne!(
993 context,
994 ExpiredContext {
995 time: UnixTime::since_unix_epoch(Duration::from_secs(1234)),
996 not_after: UnixTime::since_unix_epoch(Duration::from_secs(1234)),
997 }
998 );
999 assert_eq!(NotValidYet, NotValidYet);
1000 let context = NotValidYetContext {
1001 time: UnixTime::since_unix_epoch(Duration::from_secs(123)),
1002 not_before: UnixTime::since_unix_epoch(Duration::from_secs(1234)),
1003 };
1004 assert_eq!(context, context);
1005 assert_ne!(
1006 context,
1007 NotValidYetContext {
1008 time: UnixTime::since_unix_epoch(Duration::from_secs(1234)),
1009 not_before: UnixTime::since_unix_epoch(Duration::from_secs(1234)),
1010 }
1011 );
1012 assert_ne!(
1013 context,
1014 NotValidYetContext {
1015 time: UnixTime::since_unix_epoch(Duration::from_secs(123)),
1016 not_before: UnixTime::since_unix_epoch(Duration::from_secs(12345)),
1017 }
1018 );
1019 assert_eq!(Revoked, Revoked);
1020 assert_eq!(UnhandledCriticalExtension, UnhandledCriticalExtension);
1021 assert_eq!(UnknownIssuer, UnknownIssuer);
1022 assert_eq!(ExpiredRevocationList, ExpiredRevocationList);
1023 assert_eq!(UnknownRevocationStatus, UnknownRevocationStatus);
1024 let context = ExpiredRevocationListContext {
1025 time: UnixTime::since_unix_epoch(Duration::from_secs(1234)),
1026 next_update: UnixTime::since_unix_epoch(Duration::from_secs(123)),
1027 };
1028 assert_eq!(context, context);
1029 assert_ne!(
1030 context,
1031 ExpiredRevocationListContext {
1032 time: UnixTime::since_unix_epoch(Duration::from_secs(12345)),
1033 next_update: UnixTime::since_unix_epoch(Duration::from_secs(123)),
1034 }
1035 );
1036 assert_ne!(
1037 context,
1038 ExpiredRevocationListContext {
1039 time: UnixTime::since_unix_epoch(Duration::from_secs(1234)),
1040 next_update: UnixTime::since_unix_epoch(Duration::from_secs(1234)),
1041 }
1042 );
1043 assert_eq!(BadSignature, BadSignature);
1044 assert_eq!(UnsupportedSignatureAlgorithm, UnsupportedSignatureAlgorithm);
1045 assert_eq!(NotValidForName, NotValidForName);
1046 let context = NotValidForNameContext {
1047 expected: ServerName::try_from("example.com")
1048 .unwrap()
1049 .to_owned(),
1050 presented: vec!["other.com".into()],
1051 };
1052 assert_eq!(context, context);
1053 assert_ne!(
1054 context,
1055 NotValidForNameContext {
1056 expected: ServerName::try_from("example.com")
1057 .unwrap()
1058 .to_owned(),
1059 presented: vec![]
1060 }
1061 );
1062 assert_ne!(
1063 context,
1064 NotValidForNameContext {
1065 expected: ServerName::try_from("huh.com")
1066 .unwrap()
1067 .to_owned(),
1068 presented: vec!["other.com".into()],
1069 }
1070 );
1071 assert_eq!(InvalidPurpose, InvalidPurpose);
1072 assert_eq!(
1073 ApplicationVerificationFailure,
1074 ApplicationVerificationFailure
1075 );
1076 let other = Other(OtherError(
1077 #[cfg(feature = "std")]
1078 Arc::from(Box::from("")),
1079 ));
1080 assert_ne!(other, other);
1081 assert_ne!(BadEncoding, Expired);
1082 }
1083
1084 #[test]
1085 fn crl_error_equality() {
1086 use super::CertRevocationListError::*;
1087 assert_eq!(BadSignature, BadSignature);
1088 assert_eq!(UnsupportedSignatureAlgorithm, UnsupportedSignatureAlgorithm);
1089 assert_eq!(InvalidCrlNumber, InvalidCrlNumber);
1090 assert_eq!(
1091 InvalidRevokedCertSerialNumber,
1092 InvalidRevokedCertSerialNumber
1093 );
1094 assert_eq!(IssuerInvalidForCrl, IssuerInvalidForCrl);
1095 assert_eq!(ParseError, ParseError);
1096 assert_eq!(UnsupportedCriticalExtension, UnsupportedCriticalExtension);
1097 assert_eq!(UnsupportedCrlVersion, UnsupportedCrlVersion);
1098 assert_eq!(UnsupportedDeltaCrl, UnsupportedDeltaCrl);
1099 assert_eq!(UnsupportedIndirectCrl, UnsupportedIndirectCrl);
1100 assert_eq!(UnsupportedRevocationReason, UnsupportedRevocationReason);
1101 let other = Other(OtherError(
1102 #[cfg(feature = "std")]
1103 Arc::from(Box::from("")),
1104 ));
1105 assert_ne!(other, other);
1106 assert_ne!(BadSignature, InvalidCrlNumber);
1107 }
1108
1109 #[test]
1110 #[cfg(feature = "std")]
1111 fn other_error_equality() {
1112 let other_error = OtherError(Arc::from(Box::from("")));
1113 assert_ne!(other_error, other_error);
1114 let other: Error = other_error.into();
1115 assert_ne!(other, other);
1116 }
1117
1118 #[test]
1119 fn smoke() {
1120 use crate::enums::{AlertDescription, ContentType, HandshakeType};
1121
1122 let all = vec![
1123 Error::InappropriateMessage {
1124 expect_types: vec![ContentType::Alert],
1125 got_type: ContentType::Handshake,
1126 },
1127 Error::InappropriateHandshakeMessage {
1128 expect_types: vec![HandshakeType::ClientHello, HandshakeType::Finished],
1129 got_type: HandshakeType::ServerHello,
1130 },
1131 Error::InvalidMessage(InvalidMessage::InvalidCcs),
1132 Error::NoCertificatesPresented,
1133 Error::DecryptError,
1134 super::PeerIncompatible::Tls12NotOffered.into(),
1135 super::PeerMisbehaved::UnsolicitedCertExtension.into(),
1136 Error::AlertReceived(AlertDescription::ExportRestriction),
1137 super::CertificateError::Expired.into(),
1138 super::CertificateError::NotValidForNameContext {
1139 expected: ServerName::try_from("example.com")
1140 .unwrap()
1141 .to_owned(),
1142 presented: vec![],
1143 }
1144 .into(),
1145 super::CertificateError::NotValidForNameContext {
1146 expected: ServerName::try_from("example.com")
1147 .unwrap()
1148 .to_owned(),
1149 presented: vec!["DnsName(\"hello.com\")".into()],
1150 }
1151 .into(),
1152 super::CertificateError::NotValidForNameContext {
1153 expected: ServerName::try_from("example.com")
1154 .unwrap()
1155 .to_owned(),
1156 presented: vec![
1157 "DnsName(\"hello.com\")".into(),
1158 "DnsName(\"goodbye.com\")".into(),
1159 ],
1160 }
1161 .into(),
1162 super::CertificateError::NotValidYetContext {
1163 time: UnixTime::since_unix_epoch(Duration::from_secs(300)),
1164 not_before: UnixTime::since_unix_epoch(Duration::from_secs(320)),
1165 }
1166 .into(),
1167 super::CertificateError::ExpiredContext {
1168 time: UnixTime::since_unix_epoch(Duration::from_secs(320)),
1169 not_after: UnixTime::since_unix_epoch(Duration::from_secs(300)),
1170 }
1171 .into(),
1172 super::CertificateError::ExpiredRevocationListContext {
1173 time: UnixTime::since_unix_epoch(Duration::from_secs(320)),
1174 next_update: UnixTime::since_unix_epoch(Duration::from_secs(300)),
1175 }
1176 .into(),
1177 Error::General("undocumented error".to_string()),
1178 Error::FailedToGetCurrentTime,
1179 Error::FailedToGetRandomBytes,
1180 Error::HandshakeNotComplete,
1181 Error::PeerSentOversizedRecord,
1182 Error::NoApplicationProtocol,
1183 Error::BadMaxFragmentSize,
1184 Error::InconsistentKeys(InconsistentKeys::KeyMismatch),
1185 Error::InconsistentKeys(InconsistentKeys::Unknown),
1186 Error::InvalidCertRevocationList(CertRevocationListError::BadSignature),
1187 Error::Other(OtherError(
1188 #[cfg(feature = "std")]
1189 Arc::from(Box::from("")),
1190 )),
1191 ];
1192
1193 for err in all {
1194 println!("{err:?}:");
1195 println!(" fmt '{err}'");
1196 }
1197 }
1198
1199 #[test]
1200 fn rand_error_mapping() {
1201 use super::rand;
1202 let err: Error = rand::GetRandomFailed.into();
1203 assert_eq!(err, Error::FailedToGetRandomBytes);
1204 }
1205
1206 #[cfg(feature = "std")]
1207 #[test]
1208 fn time_error_mapping() {
1209 use std::time::SystemTime;
1210
1211 let time_error = SystemTime::UNIX_EPOCH
1212 .duration_since(SystemTime::now())
1213 .unwrap_err();
1214 let err: Error = time_error.into();
1215 assert_eq!(err, Error::FailedToGetCurrentTime);
1216 }
1217}