module Signet.Unstable.Type.SignaturesTest where import qualified Crypto.Error as Error import qualified Crypto.Hash as Hash import qualified Crypto.PubKey.Ed25519 as Ed25519 import qualified Data.ByteString as ByteString import qualified Data.ByteString.Char8 as Ascii import qualified Signet.Unstable.Exception.InvalidAsymmetricSignature as InvalidAsymmetricSignature import qualified Signet.Unstable.Exception.InvalidSignature as InvalidSignature import qualified Signet.Unstable.Exception.InvalidSymmetricSignature as InvalidSymmetricSignature import qualified Signet.Unstable.Extra.Tasty as Tasty import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature import qualified Signet.Unstable.Type.Signature as Signature import qualified Signet.Unstable.Type.Signatures as Signatures import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature import qualified Signet.Unstable.Type.UnknownSignature as UnknownSignature import Test.Tasty.HUnit ((@?=)) spec :: Tasty.Spec spec :: Spec spec = TestName -> Spec -> Spec Tasty.describe TestName "Signet.Unstable.Type.Signatures" (Spec -> Spec) -> Spec -> Spec forall a b. (a -> b) -> a -> b $ do TestName -> Spec -> Spec Tasty.describe TestName "parse" (Spec -> Spec) -> Spec -> Spec forall a b. (a -> b) -> a -> b $ do TestName -> Assertion -> Spec Tasty.it TestName "succeeds with no signatures" (Assertion -> Spec) -> Assertion -> Spec forall a b. (a -> b) -> a -> b $ do ByteString -> Either InvalidSignature ([UnknownSignature], Signatures) Signatures.parse ByteString ByteString.empty Either InvalidSignature ([UnknownSignature], Signatures) -> Either InvalidSignature ([UnknownSignature], Signatures) -> Assertion forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion @?= ([UnknownSignature], Signatures) -> Either InvalidSignature ([UnknownSignature], Signatures) forall a b. b -> Either a b Right ([], [Signature] -> Signatures Signatures.MkSignatures []) TestName -> Assertion -> Spec Tasty.it TestName "succeeds with one signature" (Assertion -> Spec) -> Assertion -> Spec forall a b. (a -> b) -> a -> b $ do let signature :: Signature signature = SymmetricSignature -> Signature Signature.Symmetric (SymmetricSignature -> Signature) -> (Digest SHA256 -> SymmetricSignature) -> Digest SHA256 -> Signature forall b c a. (b -> c) -> (a -> b) -> a -> c . Digest SHA256 -> SymmetricSignature SymmetricSignature.MkSymmetricSignature (Digest SHA256 -> Signature) -> Digest SHA256 -> Signature forall a b. (a -> b) -> a -> b $ ByteString -> Digest SHA256 forall ba a. (ByteArrayAccess ba, HashAlgorithm a) => ba -> Digest a Hash.hash ByteString ByteString.empty let byteString :: ByteString byteString = TestName -> ByteString Ascii.pack TestName "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=" ByteString -> Either InvalidSignature ([UnknownSignature], Signatures) Signatures.parse ByteString byteString Either InvalidSignature ([UnknownSignature], Signatures) -> Either InvalidSignature ([UnknownSignature], Signatures) -> Assertion forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion @?= ([UnknownSignature], Signatures) -> Either InvalidSignature ([UnknownSignature], Signatures) forall a b. b -> Either a b Right ([], [Signature] -> Signatures Signatures.MkSignatures [Signature signature]) TestName -> Assertion -> Spec Tasty.it TestName "succeeds with many signatures" (Assertion -> Spec) -> Assertion -> Spec forall a b. (a -> b) -> a -> b $ do let symmetricSignature :: SymmetricSignature symmetricSignature = Digest SHA256 -> SymmetricSignature SymmetricSignature.MkSymmetricSignature (Digest SHA256 -> SymmetricSignature) -> Digest SHA256 -> SymmetricSignature forall a b. (a -> b) -> a -> b $ ByteString -> Digest SHA256 forall ba a. (ByteArrayAccess ba, HashAlgorithm a) => ba -> Digest a Hash.hash ByteString ByteString.empty AsymmetricSignature asymmetricSignature <- (Signature -> AsymmetricSignature) -> IO Signature -> IO AsymmetricSignature forall a b. (a -> b) -> IO a -> IO b forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap Signature -> AsymmetricSignature AsymmetricSignature.MkAsymmetricSignature (IO Signature -> IO AsymmetricSignature) -> (ByteString -> IO Signature) -> ByteString -> IO AsymmetricSignature forall b c a. (b -> c) -> (a -> b) -> a -> c . CryptoFailable Signature -> IO Signature forall a. CryptoFailable a -> IO a Error.throwCryptoErrorIO (CryptoFailable Signature -> IO Signature) -> (ByteString -> CryptoFailable Signature) -> ByteString -> IO Signature forall b c a. (b -> c) -> (a -> b) -> a -> c . ByteString -> CryptoFailable Signature forall ba. ByteArrayAccess ba => ba -> CryptoFailable Signature Ed25519.signature (ByteString -> IO AsymmetricSignature) -> ByteString -> IO AsymmetricSignature forall a b. (a -> b) -> a -> b $ TestName -> ByteString Ascii.pack TestName "ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789-abcdefghijklmnopqrstuvqxyz" let byteString :: ByteString byteString = TestName -> ByteString Ascii.pack TestName "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU= v1a,QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVotMDEyMzQ1Njc4OS1hYmNkZWZnaGlqa2xtbm9wcXJzdHV2cXh5eg==" let signatures :: Signatures signatures = [Signature] -> Signatures Signatures.MkSignatures [ SymmetricSignature -> Signature Signature.Symmetric SymmetricSignature symmetricSignature, AsymmetricSignature -> Signature Signature.Asymmetric AsymmetricSignature asymmetricSignature ] ByteString -> Either InvalidSignature ([UnknownSignature], Signatures) Signatures.parse ByteString byteString Either InvalidSignature ([UnknownSignature], Signatures) -> Either InvalidSignature ([UnknownSignature], Signatures) -> Assertion forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion @?= ([UnknownSignature], Signatures) -> Either InvalidSignature ([UnknownSignature], Signatures) forall a b. b -> Either a b Right ([], Signatures signatures) TestName -> Assertion -> Spec Tasty.it TestName "fails with an invalid symmetric signature" (Assertion -> Spec) -> Assertion -> Spec forall a b. (a -> b) -> a -> b $ do let x :: ByteString x = TestName -> ByteString Ascii.pack TestName "invalid" let byteString :: ByteString byteString = TestName -> ByteString Ascii.pack TestName "v1," ByteString -> ByteString -> ByteString forall a. Semigroup a => a -> a -> a <> ByteString x ByteString -> Either InvalidSignature ([UnknownSignature], Signatures) Signatures.parse ByteString byteString Either InvalidSignature ([UnknownSignature], Signatures) -> Either InvalidSignature ([UnknownSignature], Signatures) -> Assertion forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion @?= InvalidSignature -> Either InvalidSignature ([UnknownSignature], Signatures) forall a b. a -> Either a b Left (InvalidSymmetricSignature -> InvalidSignature InvalidSignature.InvalidSymmetricSignature (InvalidSymmetricSignature -> InvalidSignature) -> InvalidSymmetricSignature -> InvalidSignature forall a b. (a -> b) -> a -> b $ ByteString -> InvalidSymmetricSignature InvalidSymmetricSignature.MkInvalidSymmetricSignature ByteString x) TestName -> Assertion -> Spec Tasty.it TestName "fails with an invalid asymmetric signature" (Assertion -> Spec) -> Assertion -> Spec forall a b. (a -> b) -> a -> b $ do let x :: ByteString x = TestName -> ByteString Ascii.pack TestName "invalid" let byteString :: ByteString byteString = TestName -> ByteString Ascii.pack TestName "v1a," ByteString -> ByteString -> ByteString forall a. Semigroup a => a -> a -> a <> ByteString x ByteString -> Either InvalidSignature ([UnknownSignature], Signatures) Signatures.parse ByteString byteString Either InvalidSignature ([UnknownSignature], Signatures) -> Either InvalidSignature ([UnknownSignature], Signatures) -> Assertion forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion @?= InvalidSignature -> Either InvalidSignature ([UnknownSignature], Signatures) forall a b. a -> Either a b Left (InvalidAsymmetricSignature -> InvalidSignature InvalidSignature.InvalidAsymmetricSignature (InvalidAsymmetricSignature -> InvalidSignature) -> InvalidAsymmetricSignature -> InvalidSignature forall a b. (a -> b) -> a -> b $ ByteString -> InvalidAsymmetricSignature InvalidAsymmetricSignature.MkInvalidAsymmetricSignature ByteString x) TestName -> Assertion -> Spec Tasty.it TestName "succeeds with an unknown signature" (Assertion -> Spec) -> Assertion -> Spec forall a b. (a -> b) -> a -> b $ do let byteString :: ByteString byteString = TestName -> ByteString Ascii.pack TestName "unknown" ByteString -> Either InvalidSignature ([UnknownSignature], Signatures) Signatures.parse ByteString byteString Either InvalidSignature ([UnknownSignature], Signatures) -> Either InvalidSignature ([UnknownSignature], Signatures) -> Assertion forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion @?= ([UnknownSignature], Signatures) -> Either InvalidSignature ([UnknownSignature], Signatures) forall a b. b -> Either a b Right ([ByteString -> UnknownSignature UnknownSignature.MkUnknownSignature ByteString byteString], [Signature] -> Signatures Signatures.MkSignatures []) TestName -> Spec -> Spec Tasty.describe TestName "render" (Spec -> Spec) -> Spec -> Spec forall a b. (a -> b) -> a -> b $ do TestName -> Assertion -> Spec Tasty.it TestName "renders no signatures" (Assertion -> Spec) -> Assertion -> Spec forall a b. (a -> b) -> a -> b $ do let signatures :: Signatures signatures = [Signature] -> Signatures Signatures.MkSignatures [] Signatures -> ByteString Signatures.render Signatures signatures ByteString -> ByteString -> Assertion forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion @?= ByteString ByteString.empty TestName -> Assertion -> Spec Tasty.it TestName "renders one signature" (Assertion -> Spec) -> Assertion -> Spec forall a b. (a -> b) -> a -> b $ do let signatures :: Signatures signatures = [Signature] -> Signatures Signatures.MkSignatures ([Signature] -> Signatures) -> (Digest SHA256 -> [Signature]) -> Digest SHA256 -> Signatures forall b c a. (b -> c) -> (a -> b) -> a -> c . Signature -> [Signature] forall a. a -> [a] forall (f :: * -> *) a. Applicative f => a -> f a pure (Signature -> [Signature]) -> (Digest SHA256 -> Signature) -> Digest SHA256 -> [Signature] forall b c a. (b -> c) -> (a -> b) -> a -> c . SymmetricSignature -> Signature Signature.Symmetric (SymmetricSignature -> Signature) -> (Digest SHA256 -> SymmetricSignature) -> Digest SHA256 -> Signature forall b c a. (b -> c) -> (a -> b) -> a -> c . Digest SHA256 -> SymmetricSignature SymmetricSignature.MkSymmetricSignature (Digest SHA256 -> Signatures) -> Digest SHA256 -> Signatures forall a b. (a -> b) -> a -> b $ ByteString -> Digest SHA256 forall ba a. (ByteArrayAccess ba, HashAlgorithm a) => ba -> Digest a Hash.hash ByteString ByteString.empty Signatures -> ByteString Signatures.render Signatures signatures ByteString -> ByteString -> Assertion forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion @?= TestName -> ByteString Ascii.pack TestName "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=" TestName -> Assertion -> Spec Tasty.it TestName "renders many signatures" (Assertion -> Spec) -> Assertion -> Spec forall a b. (a -> b) -> a -> b $ do let symmetricSignature :: SymmetricSignature symmetricSignature = Digest SHA256 -> SymmetricSignature SymmetricSignature.MkSymmetricSignature (Digest SHA256 -> SymmetricSignature) -> Digest SHA256 -> SymmetricSignature forall a b. (a -> b) -> a -> b $ ByteString -> Digest SHA256 forall ba a. (ByteArrayAccess ba, HashAlgorithm a) => ba -> Digest a Hash.hash ByteString ByteString.empty AsymmetricSignature asymmetricSignature <- (Signature -> AsymmetricSignature) -> IO Signature -> IO AsymmetricSignature forall a b. (a -> b) -> IO a -> IO b forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap Signature -> AsymmetricSignature AsymmetricSignature.MkAsymmetricSignature (IO Signature -> IO AsymmetricSignature) -> (ByteString -> IO Signature) -> ByteString -> IO AsymmetricSignature forall b c a. (b -> c) -> (a -> b) -> a -> c . CryptoFailable Signature -> IO Signature forall a. CryptoFailable a -> IO a Error.throwCryptoErrorIO (CryptoFailable Signature -> IO Signature) -> (ByteString -> CryptoFailable Signature) -> ByteString -> IO Signature forall b c a. (b -> c) -> (a -> b) -> a -> c . ByteString -> CryptoFailable Signature forall ba. ByteArrayAccess ba => ba -> CryptoFailable Signature Ed25519.signature (ByteString -> IO AsymmetricSignature) -> ByteString -> IO AsymmetricSignature forall a b. (a -> b) -> a -> b $ TestName -> ByteString Ascii.pack TestName "ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789-abcdefghijklmnopqrstuvqxyz" let signatures :: Signatures signatures = [Signature] -> Signatures Signatures.MkSignatures [ SymmetricSignature -> Signature Signature.Symmetric SymmetricSignature symmetricSignature, AsymmetricSignature -> Signature Signature.Asymmetric AsymmetricSignature asymmetricSignature ] Signatures -> ByteString Signatures.render Signatures signatures ByteString -> ByteString -> Assertion forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion @?= TestName -> ByteString Ascii.pack TestName "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU= v1a,QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVotMDEyMzQ1Njc4OS1hYmNkZWZnaGlqa2xtbm9wcXJzdHV2cXh5eg=="