module Hackage.Security.TUF.FileInfo (
FileInfo(..)
, HashFn(..)
, Hash(..)
, fileInfo
, computeFileInfo
, knownFileInfoEqual
, fileInfoSHA256
, Int54
) 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 :: FsRoot root => Path root -> IO FileInfo
computeFileInfo fp = fileInfo <$> readLazyByteString fp
knownFileInfoEqual :: FileInfo -> FileInfo -> Bool
knownFileInfoEqual a b = (==) (fileInfoLength a, fileInfoHashes a)
(fileInfoLength b, fileInfoHashes b)
fileInfoSHA256 :: FileInfo -> Maybe Hash
fileInfoSHA256 FileInfo{..} = Map.lookup HashFnSHA256 fileInfoHashes
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{..}