-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Reversable and secure encoding of object ids as filepaths -- -- Reversable and secure encoding of object ids as filepaths @package filepath-crypto @version 0.0.0.2 module Data.Binary.SerializationLength.TH -- | Shorthand for defining instances of -- HasFixedSerializationLength, morally: -- --
--   hasFixedSerializationLength typeName byteN = [d|
--       instance HasFixedSerializiationLength $(typeName) where
--         type SerializationLength $(typeName) = $(byteN)
--     |]
--   
hasFixedSerializationLength :: Name -> Integer -> DecsQ module Data.Binary.SerializationLength -- | The class of types for which the result of serialization with -- Data.Binary is known statically to be of a certain length class KnownNat (SerializationLength a) => HasFixedSerializationLength a where type SerializationLength a :: Nat where { type family SerializationLength a :: Nat; } instance Data.Binary.SerializationLength.Class.HasFixedSerializationLength GHC.Int.Int64 instance Data.Binary.SerializationLength.Class.HasFixedSerializationLength GHC.Int.Int32 instance Data.Binary.SerializationLength.Class.HasFixedSerializationLength GHC.Int.Int16 instance Data.Binary.SerializationLength.Class.HasFixedSerializationLength GHC.Int.Int8 instance Data.Binary.SerializationLength.Class.HasFixedSerializationLength GHC.Word.Word64 instance Data.Binary.SerializationLength.Class.HasFixedSerializationLength GHC.Word.Word32 instance Data.Binary.SerializationLength.Class.HasFixedSerializationLength GHC.Word.Word16 instance Data.Binary.SerializationLength.Class.HasFixedSerializationLength GHC.Word.Word8 -- | Given a value of a serializable type (like Int) we perform -- serialization and compute a cryptographic hash of the associated -- namespace (carried as a phantom type of kind Symbol). The -- serialized payload is encrypted using a symmetric cipher in CBC mode -- using the hashed namespace as an initialization vector (IV). -- -- The ciphertext is then base32-encoded and padding stripped. -- -- Rather than being indicated by the amount of padding, the length of -- the serialized plaintext is instead carried at the type level within -- CryptoFileName (analogously to the namespace). Mismatches in -- serialized plaintext length are checked for but are not -- guaranteed to cause runtime errors in all cases. -- -- Since the serialized payload is padded to the length of the next -- cipher block we can detect namespace mismatches by checking that all -- bytes expected to have been inserted during padding are nil. The -- probability of detecting a namespace mismatch is thus <math> -- where <math> is the length of the serialized payload and -- <math> the length of a ciphertext block (both in bits). module System.FilePath.Cryptographic newtype CryptoID (namespace :: Symbol) a :: Symbol -> * -> * CryptoID :: a -> CryptoID a [ciphertext] :: CryptoID a -> a type CryptoFileName (namespace :: Symbol) = CryptoID namespace (CI FilePath) -- | Encrypt an arbitrary serializable value -- -- We only expect to fail if the given value is not serialized in such a -- fashion that it meets the expected length given at type level. encrypt :: forall a m namespace. (KnownSymbol namespace, Binary a, MonadThrow m, HasFixedSerializationLength a) => CryptoIDKey -> a -> m (CryptoFileName namespace) -- | Decrypt an arbitrary serializable value -- -- Since no integrity guarantees can be made (we do not sign the values -- we encrypt) it is likely that deserialization will fail -- emitting DeserializationError or -- InvalidNamespaceDetected. decrypt :: forall a m namespace. (KnownSymbol namespace, Binary a, MonadThrow m, HasFixedSerializationLength a) => CryptoIDKey -> CryptoFileName namespace -> m a -- | 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 :: * -- | One of the underlying cryptographic algorithms (CryptoHash or -- CryptoCipher) failed. AlgorithmError :: CryptoError -> CryptoIDError -- | The length of the plaintext is not a multiple of the block size of -- CryptoCipher -- -- The length of the offending plaintext is included. PlaintextIsWrongLength :: Int -> CryptoIDError -- | The length of the digest produced by CryptoHash does not match -- the block size of CryptoCipher. -- -- The offending digest is included. -- -- This error should not occur and is included primarily for sake of -- totality. NamespaceHashIsWrongLength :: ByteString -> CryptoIDError -- | The produced ByteString is the wrong length for deserialization -- into a ciphertext. -- -- The offending ByteString is included. CiphertextConversionFailed :: ByteString -> CryptoIDError -- | 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. -- -- This is expected behaviour if the namespace or -- payload-type does not match the ones used during -- encryption or if the ciphertext was tempered with. DeserializationError :: CryptoIDError -- | We have determined that, allthough deserializion succeded, the -- ciphertext was likely modified during transit or created using a -- different namespace. InvalidNamespaceDetected :: CryptoIDError