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 +5/−0
- cryptoids.cabal +1/−1
- src/Data/CryptoID/ByteString.hs +18/−6
- src/Data/CryptoID/Poly.hs +20/−4
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