module Hackage.Security.TUF.FileInfo (
FileInfo(..)
, HashFn(..)
, Hash(..)
, fileInfo
, computeFileInfo
, knownFileInfoEqual
) where
import Prelude hiding (lookup)
import Data.Map (Map)
import qualified Crypto.Hash as CH
import qualified Data.Map as Map
import qualified Data.ByteString.Lazy as BS.L
import Hackage.Security.JSON
import Hackage.Security.TUF.Common
import Hackage.Security.Util.Path
data HashFn = HashFnSHA256
deriving (Show, Eq, Ord)
data FileInfo = FileInfo {
fileInfoLength :: FileLength
, fileInfoHashes :: Map HashFn Hash
}
deriving (Show)
fileInfo :: BS.L.ByteString -> FileInfo
fileInfo bs = FileInfo {
fileInfoLength = FileLength . fromIntegral $ BS.L.length bs
, fileInfoHashes = Map.fromList [
(HashFnSHA256, Hash $ show (CH.hashlazy bs :: CH.Digest CH.SHA256))
]
}
computeFileInfo :: IsFileSystemRoot root => Path (Rooted root) -> IO FileInfo
computeFileInfo fp = fileInfo <$> readLazyByteString fp
knownFileInfoEqual :: FileInfo -> FileInfo -> Bool
knownFileInfoEqual a b = (==) (fileInfoLength a, fileInfoHashes a)
(fileInfoLength b, fileInfoHashes b)
instance Monad m => ToObjectKey m HashFn where
toObjectKey HashFnSHA256 = return "sha256"
instance ReportSchemaErrors m => FromObjectKey m HashFn where
fromObjectKey "sha256" = return HashFnSHA256
fromObjectKey str = expected "valid hash function" (Just str)
instance Monad m => ToJSON m FileInfo where
toJSON FileInfo{..} = mkObject [
("length", toJSON fileInfoLength)
, ("hashes", toJSON fileInfoHashes)
]
instance ReportSchemaErrors m => FromJSON m FileInfo where
fromJSON enc = do
fileInfoLength <- fromJSField enc "length"
fileInfoHashes <- fromJSField enc "hashes"
return FileInfo{..}