hOpenPGP 1.2 → 1.2.1
raw patch · 7 files changed
+32/−23 lines, 7 filesdep +conduit-extradep ~conduitdep ~resourcetPVP ok
version bump matches the API change (PVP)
Dependencies added: conduit-extra
Dependency ranges changed: conduit, resourcet
API changes (from Hackage documentation)
Files
- Data/Conduit/OpenPGP/Compression.hs +2/−1
- Data/Conduit/OpenPGP/Decrypt.hs +4/−3
- Data/Conduit/OpenPGP/Filter.hs +1/−0
- Data/Conduit/OpenPGP/Keyring.hs +2/−1
- Data/Conduit/OpenPGP/Verify.hs +1/−0
- hOpenPGP.cabal +7/−4
- tests/suite.hs +15/−14
Data/Conduit/OpenPGP/Compression.hs view
@@ -1,5 +1,5 @@ -- Compression.hs: OpenPGP (RFC4880) compression conduits--- Copyright © 2012-2013 Clint Adams+-- Copyright © 2012-2014 Clint Adams -- This software is released under the terms of the Expat license. -- (See the LICENSE file). @@ -12,6 +12,7 @@ import Codec.Encryption.OpenPGP.Types import Data.Conduit import qualified Data.Conduit.List as CL+import Control.Monad.Trans.Resource (MonadThrow) conduitCompress :: MonadThrow m => CompressionAlgorithm -> Conduit Pkt m Pkt conduitCompress algo = CL.consume >>= \ps -> yield (compressPkts algo ps)
Data/Conduit/OpenPGP/Decrypt.hs view
@@ -1,5 +1,5 @@ -- Decrypt.hs: OpenPGP (RFC4880) recursive packet decryption--- Copyright © 2013 Clint Adams+-- Copyright © 2013-2014 Clint Adams -- This software is released under the terms of the Expat license. -- (See the LICENSE file). @@ -11,6 +11,7 @@ import Control.Monad (when) import Control.Monad.IO.Class (MonadIO(..))+import Control.Monad.Trans.Resource (MonadBaseControl, MonadResource, MonadThrow, runResourceT) import qualified Control.Monad.Trans.State.Lazy as S import qualified Crypto.Hash.SHA1 as SHA1 import qualified Data.ByteString as B@@ -63,7 +64,7 @@ ldpCheck l@(LiteralDataPkt {}) = S.get >>= \o -> S.put o { _lastLDP = Just . fromPkt $ l } ldpCheck _ = return () -decryptSEDP :: (MonadBaseControl IO m, MonadIO m, MonadThrow m, MonadUnsafeIO m) => Int -> InputCallback IO -> SKESK -> B.ByteString -> m [Pkt]+decryptSEDP :: (MonadBaseControl IO m, MonadIO m, MonadThrow m) => Int -> InputCallback IO -> SKESK -> B.ByteString -> m [Pkt] decryptSEDP depth cb skesk bs = do -- FIXME: this shouldn't pass the whole SKESK passphrase <- liftIO $ cb "Input the passphrase I want" let key = skesk2Key skesk passphrase@@ -72,7 +73,7 @@ Right x -> x runResourceT $ CB.sourceLbs (BL.fromStrict decrypted) $= conduitGet get $= conduitDecompress $= conduitDecrypt' depth cb $$ CL.consume -decryptSEIPDP :: (MonadBaseControl IO m, MonadIO m, MonadThrow m, MonadUnsafeIO m) => Int -> InputCallback IO -> SKESK -> B.ByteString -> m [Pkt]+decryptSEIPDP :: (MonadBaseControl IO m, MonadIO m, MonadThrow m) => Int -> InputCallback IO -> SKESK -> B.ByteString -> m [Pkt] decryptSEIPDP depth cb skesk bs = do -- FIXME: this shouldn't pass the whole SKESK passphrase <- liftIO $ cb "Input the passphrase I want" let key = skesk2Key skesk passphrase
Data/Conduit/OpenPGP/Filter.hs view
@@ -22,6 +22,7 @@ ) where import Control.Error.Util (hush)+import Control.Monad.Trans.Resource (MonadResource) import qualified Data.ByteString as B import Data.Conduit import qualified Data.Conduit.List as CL
Data/Conduit/OpenPGP/Keyring.hs view
@@ -10,6 +10,7 @@ ) where import Control.Applicative (many, (<$>), (<|>))+import Control.Monad.Trans.Resource (MonadResource) import Data.Conduit import qualified Data.Conduit.List as CL import Data.IxSet (empty, insert)@@ -28,7 +29,7 @@ conduitToTKsDropping :: MonadResource m => Conduit Pkt m TK conduitToTKsDropping = conduitToTKs' False -fakecmAccum :: Monad m => (accum -> (accum, [b])) -> (a -> accum -> (accum, [b])) -> accum -> Conduit a m b+fakecmAccum :: MonadResource m => (accum -> (accum, [b])) -> (a -> accum -> (accum, [b])) -> accum -> Conduit a m b fakecmAccum finalizer f = loop where
Data/Conduit/OpenPGP/Verify.hs view
@@ -7,6 +7,7 @@ conduitVerify ) where +import Control.Monad.Trans.Resource (MonadResource) import Data.Conduit import Data.Time.Clock (UTCTime)
hOpenPGP.cabal view
@@ -1,5 +1,5 @@ Name: hOpenPGP-Version: 1.2+Version: 1.2.1 Synopsis: native Haskell implementation of OpenPGP (RFC4880) Description: native Haskell implementation of OpenPGP (RFC4880) Homepage: http://floss.scru.org/hOpenPGP/@@ -172,7 +172,8 @@ , bzlib , cereal , cereal-conduit >= 0.6 && < 0.8- , conduit >= 0.5 && < 1.1+ , conduit >= 0.5 && < 1.2+ , conduit-extra >= 1.1 , containers , crypto-cipher-types , crypto-pubkey >= 0.1.4@@ -188,6 +189,7 @@ , mtl , nettle , openpgp-asciiarmor >= 0.1+ , resourcet > 0.4 , securemem , split , text@@ -210,6 +212,7 @@ , cereal , cereal-conduit , conduit+ , conduit-extra , containers , crypto-cipher-types , crypto-pubkey >= 0.1.4@@ -235,7 +238,7 @@ , tasty-quickcheck , QuickCheck , quickcheck-instances- , resourcet > 0.4 && < 0.5+ , resourcet > 0.4 default-language: Haskell2010 source-repository head@@ -245,4 +248,4 @@ source-repository this type: git location: git://git.debian.org/users/clint/hOpenPGP.git- tag: v1.2+ tag: v1.2.1
tests/suite.hs view
@@ -21,6 +21,7 @@ import Codec.Encryption.OpenPGP.Signatures (verifyTKWith, verifySigWith, verifyAgainstKeys) import Codec.Encryption.OpenPGP.Types import Control.Error.Util (isRight)+import Control.Monad.Trans.Resource (MonadResource, ResourceT, runResourceT) import Crypto.PubKey.RSA (PrivateKey(private_pub)) import Data.Conduit.Cereal (conduitGet) import Data.Conduit.OpenPGP.Compression (conduitCompress, conduitDecompress)@@ -67,12 +68,12 @@ else assertEqual ("for " ++ fpr) firstpass secondpass -counter :: (DC.MonadResource m) => DC.Sink a m Int+counter :: (MonadResource m) => DC.Sink a m Int counter = CL.fold (const . (1+)) 0 -testConduitOutputLength :: FilePath -> DC.Conduit B.ByteString (DC.ResourceT IO) b -> Int -> Assertion+testConduitOutputLength :: FilePath -> DC.Conduit B.ByteString (ResourceT IO) b -> Int -> Assertion testConduitOutputLength fpr c target = do- len <- DC.runResourceT $ CB.sourceFile ("tests/data/" ++ fpr) DC.$= c DC.$$ counter+ len <- runResourceT $ CB.sourceFile ("tests/data/" ++ fpr) DC.$= c DC.$$ counter assertEqual ("expected length " ++ show target) target len testKeyIDandFingerprint :: FilePath -> String -> Assertion@@ -85,26 +86,26 @@ testKeyringLookup :: FilePath -> String -> Bool -> Assertion testKeyringLookup fpr eok expected = do- kr <- DC.runResourceT $ CB.sourceFile ("tests/data/" ++ fpr) DC.$= conduitGet get DC.$= conduitToTKs DC.$$ sinkKeyringMap+ kr <- runResourceT $ CB.sourceFile ("tests/data/" ++ fpr) DC.$= conduitGet get DC.$= conduitToTKs DC.$$ sinkKeyringMap let key = getOne (kr @= (read eok :: EightOctetKeyId)) assertEqual (eok ++ " in " ++ fpr) expected (isJust key) testVerifyMessage :: FilePath -> FilePath -> [TwentyOctetFingerprint] -> Assertion testVerifyMessage keyring message issuers = do- kr <- DC.runResourceT $ CB.sourceFile ("tests/data/" ++ keyring) DC.$= conduitGet get DC.$= conduitToTKs DC.$$ sinkKeyringMap- verification <- DC.runResourceT $ CB.sourceFile ("tests/data/" ++ message) DC.$= conduitGet get DC.$= conduitDecompress DC.$= conduitVerify kr Nothing DC.$$ CL.consume+ kr <- runResourceT $ CB.sourceFile ("tests/data/" ++ keyring) DC.$= conduitGet get DC.$= conduitToTKs DC.$$ sinkKeyringMap+ verification <- runResourceT $ CB.sourceFile ("tests/data/" ++ message) DC.$= conduitGet get DC.$= conduitDecompress DC.$= conduitVerify kr Nothing DC.$$ CL.consume let verification' = map (fmap (fingerprint . _verificationSigner)) verification assertEqual (keyring ++ " for " ++ message) (map Right issuers) verification' testKeysSelfVerification :: Bool -> FilePath -> Assertion testKeysSelfVerification expectsuccess keyfile = do- ks <- DC.runResourceT $ CB.sourceFile ("tests/data/" ++ keyfile) DC.$= conduitGet get DC.$= conduitToTKs DC.$$ CL.consume+ ks <- runResourceT $ CB.sourceFile ("tests/data/" ++ keyfile) DC.$= conduitGet get DC.$= conduitToTKs DC.$$ CL.consume let verifieds = mapM (verifyTKWith (verifySigWith (verifyAgainstKeys ks)) Nothing) ks assertEqual (keyfile ++ " self-verification") expectsuccess (isRight verifieds) testKeysExpiration :: Bool -> FilePath -> Assertion testKeysExpiration expectsuccess keyfile = do- ks <- DC.runResourceT $ CB.sourceFile ("tests/data/" ++ keyfile) DC.$= conduitGet get DC.$= conduitToTKs DC.$$ CL.consume+ ks <- runResourceT $ CB.sourceFile ("tests/data/" ++ keyfile) DC.$= conduitGet get DC.$= conduitToTKs DC.$$ CL.consume let Right verifieds = mapM (verifyTKWith (verifySigWith (verifyAgainstKeys ks)) Nothing) ks tvalid = all (isTKTimeValid (posixSecondsToUTCTime (realToFrac 1400000000))) verifieds assertEqual (keyfile ++ " key expiration") expectsuccess tvalid@@ -114,7 +115,7 @@ testSymmetricEncryption encfile passfile cleartext = do passphrase <- BL.readFile $ "tests/data/" ++ passfile -- get parse tree- pt <- DC.runResourceT $ CB.sourceFile ("tests/data/" ++ encfile) DC.$= conduitGet get DC.$$ CL.consume+ pt <- runResourceT $ CB.sourceFile ("tests/data/" ++ encfile) DC.$= conduitGet get DC.$$ CL.consume -- assert parse tree has exactly two packets: skesk, encdata assertEqual "wrong number of packets" 2 (length pt) let skesk = fromPkt.head $ pt@@ -124,7 +125,7 @@ -- and the type system chokes before we hit them: assertEqual "first packet should be SKESK" SKESKType (packetType skesk) assertEqual "second packet should be encrypted data" SymEncIntegrityProtectedDataType (packetType d)- decrypted <- DC.runResourceT $ CL.sourceList pt DC.$= conduitDecrypt (fakeCallback passphrase) DC.$$ CL.consume+ decrypted <- runResourceT $ CL.sourceList pt DC.$= conduitDecrypt (fakeCallback passphrase) DC.$$ CL.consume let payload = _literalDataPayload . fromPkt . head $ decrypted assertEqual ("cleartext for " ++ encfile) cleartext payload where@@ -134,7 +135,7 @@ testSecretKeyDecryption :: FilePath -> FilePath -> Assertion testSecretKeyDecryption keyfile passfile = do passphrase <- BL.readFile $ "tests/data/" ++ passfile- kr <- DC.runResourceT $ CB.sourceFile ("tests/data/" ++ keyfile) DC.$= conduitGet get DC.$$ CL.consume+ kr <- runResourceT $ CB.sourceFile ("tests/data/" ++ keyfile) DC.$= conduitGet get DC.$$ CL.consume let SecretKey pkp ska = fromPkt . head $ kr SUUnencrypted (RSAPrivateKey dpk) _ = decryptPrivateKey (pkp, ska) passphrase -- FIXME: better API for multiple keytypes RSAPubKey pk = _pubkey pkp@@ -144,8 +145,8 @@ testSecretKeyEncryption :: FilePath -> FilePath -> Assertion testSecretKeyEncryption keyfile passfile = do passphrase <- BL.readFile $ "tests/data/" ++ passfile- kr <- DC.runResourceT $ CB.sourceFile ("tests/data/" ++ keyfile) DC.$= conduitGet get DC.$$ CL.consume- gkr <- DC.runResourceT $ CB.sourceFile ("tests/data/" ++ "aes256-sha512.seckey") DC.$= conduitGet get DC.$$ CL.consume+ kr <- runResourceT $ CB.sourceFile ("tests/data/" ++ keyfile) DC.$= conduitGet get DC.$$ CL.consume+ gkr <- runResourceT $ CB.sourceFile ("tests/data/" ++ "aes256-sha512.seckey") DC.$= conduitGet get DC.$$ CL.consume let SecretKey pkp ska = fromPkt . head $ kr newska = encryptPrivateKey "\226~\197\a\202#\"G" "\187\219\253I\236\204\t5D\196\NAK>;\202\185\t" ska passphrase newtruck = toPkt (SecretKey pkp newska):tail kr@@ -346,7 +347,7 @@ \uid -> Right (uid :: UserId) == runGet get (runPut (put uid)) ] -cgp :: DC.Conduit B.ByteString (DC.ResourceT IO) Pkt+cgp :: DC.Conduit B.ByteString (ResourceT IO) Pkt cgp = conduitGet (get :: Get Pkt) fp :: Text -> TwentyOctetFingerprint