packages feed

cryptoids 0.2.0.0 → 0.3.0.0

raw patch · 4 files changed

+44/−11 lines, 4 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Data.CryptoID.ByteString: PlaintextIsWrongLength :: Int -> CryptoIDError
+ Data.CryptoID.Poly: PlaintextIsWrongLength :: Int -> CryptoIDError
- Data.CryptoID.ByteString: CiphertextConversionFailed :: CryptoIDError
+ Data.CryptoID.ByteString: CiphertextConversionFailed :: ByteString -> CryptoIDError
- Data.CryptoID.ByteString: DeserializationError :: (ByteString, ByteOffset, String) -> CryptoIDError
+ Data.CryptoID.ByteString: DeserializationError :: CryptoIDError
- Data.CryptoID.Poly: CiphertextConversionFailed :: CryptoIDError
+ Data.CryptoID.Poly: CiphertextConversionFailed :: ByteString -> CryptoIDError
- Data.CryptoID.Poly: DeserializationError :: (ByteString, ByteOffset, String) -> CryptoIDError
+ Data.CryptoID.Poly: DeserializationError :: CryptoIDError
- Data.CryptoID.Poly: encrypt :: forall a m c namespace. (KnownSymbol namespace, MonadThrow m, Binary a) => (ByteString -> m c) -> CryptoIDKey -> a -> m (CryptoID namespace c)
+ Data.CryptoID.Poly: encrypt :: forall a m c namespace. (KnownSymbol namespace, MonadThrow m, Binary a) => Maybe Int -> (ByteString -> m c) -> CryptoIDKey -> a -> m (CryptoID namespace c)

Files

changes.md view
@@ -1,3 +1,7 @@+# 0.3.0.0+    - Better exception type (does no longer leak private information)+    - 'Data.CryptoID.Poly' now supports padding the plaintext to a certain length before encryption+ # 0.2.0.0     - Rename 'Data.CryptoID.Poly' to 'Data.CryptoID.ByteString'     - Introduce 'Data.CryptoID.Poly' doing actual serialization@@ -12,3 +16,4 @@ # 0.0.0  First published version+
cryptoids.cabal view
@@ -1,5 +1,5 @@ name: cryptoids-version: 0.2.0.0+version: 0.3.0.0 cabal-version: >=1.10 build-type: Simple license: BSD3
src/Data/CryptoID/ByteString.hs view
@@ -29,6 +29,7 @@ import Data.Binary.Get  import Data.ByteString (ByteString)+import qualified Data.ByteString as ByteString import qualified Data.ByteString.Char8 as ByteString.Char  import qualified Data.ByteString.Lazy as Lazy (ByteString)@@ -100,10 +101,19 @@   -- | Error cases that can be encountered during 'encrypt' and 'decrypt'+--+-- Care has been taken to ensure that presenting values of 'CryptoIDError' to an+-- attacker leaks no plaintext (it does leak information about the length of the+-- plaintext). data CryptoIDError   = AlgorithmError CryptoError     -- ^ One of the underlying cryptographic algorithms     --   ('CryptoHash' or 'CryptoCipher') failed.+  | PlaintextIsWrongLength Int+    -- ^ The length of the plaintext is not a multiple of the block size of+    --   'CryptoCipher'+    --+    -- The length of the offending plaintext is included.   | NamespaceHashIsWrongLength ByteString     -- ^ The length of the digest produced by 'CryptoHash' does     --   not match the block size of 'CryptoCipher'.@@ -112,10 +122,12 @@     --     -- This error should not occur and is included primarily     -- for sake of totality.-  | CiphertextConversionFailed-    -- ^ The produced 'ByteString' is the wrong length for conversion into a-    --   ciphertext.-  | DeserializationError (Lazy.ByteString, ByteOffset, String)+  | CiphertextConversionFailed ByteString+    -- ^ The produced 'ByteString' is the wrong length for deserialization into+    --   a ciphertext.+    --+    -- The offending 'ByteString' is included.+  | DeserializationError     -- ^ The plaintext obtained by decrypting a ciphertext with the given     --   'CryptoIDKey' in the context of the @namespace@ could not be     --   deserialized into a value of the expected @payload@-type.@@ -183,8 +195,8 @@ encrypt (keyMaterial -> key) plaintext = do   cipher <- cryptoFailable (cipherInit key :: CryptoFailable CryptoCipher)   namespace <- namespace' (Proxy :: Proxy namespace)-  when (ByteArray.length plaintext `mod` blockSize cipher /= 0) $-    throwM CiphertextConversionFailed+  when (ByteString.length plaintext `mod` blockSize cipher /= 0) $+    throwM . PlaintextIsWrongLength $ ByteString.length plaintext   return . CryptoID $ cbcEncrypt cipher namespace plaintext  
src/Data/CryptoID/Poly.hs view
@@ -33,11 +33,15 @@  import Data.Binary +import Data.Monoid+ import Data.ByteString (ByteString)+import qualified Data.ByteString as ByteString import qualified Data.ByteString.Lazy as Lazy.ByteString  import GHC.TypeLits +import Control.Monad import Control.Monad.Catch (MonadThrow(..))    @@ -50,10 +54,22 @@            ( KnownSymbol namespace            , MonadThrow m            , Binary a-           ) => (ByteString -> m c) -> CryptoIDKey -> a -> m (CryptoID namespace c)-encrypt encode' key plaintext = do-  cID <- ByteString.encrypt key . Lazy.ByteString.toStrict $ encode plaintext+           ) => Maybe Int -- ^ Ensure the resulting ciphertext is of this size (needs to be a multiple of the block size of 'CryptoCipher' in bytes, otherwise an exception will be thrown at runtime)+        -> (ByteString -> m c)+        -> CryptoIDKey+        -> a+        -> m (CryptoID namespace c)+encrypt pLength encode' key plaintext = do+  cID <- ByteString.encrypt key <=< pad . Lazy.ByteString.toStrict $ encode plaintext   _ciphertext encode' cID+  where+    pad str+      | Just l <- pLength+      , l' <= l           = return $ str <> ByteString.replicate (l - l') 0+      | Just _ <- pLength = throwM $ CiphertextConversionFailed str+      | otherwise         = return str+      where+        l' = ByteString.length str   -- | Decrypt a serialized value@@ -67,7 +83,7 @@   plaintext <- Lazy.ByteString.fromStrict <$> ByteString.decrypt key cID'    case decodeOrFail plaintext of-    Left err -> throwM $ DeserializationError err+    Left _ -> throwM DeserializationError     Right (rem, _, res)       | Lazy.ByteString.all (== 0) rem -> return res       | otherwise -> throwM InvalidNamespaceDetected