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