Safe Haskell | None |
---|---|
Language | Haskell2010 |
Hackage.Security.Server
Contents
Description
Main entry point into the Hackage Security framework for clients
Synopsis
- data DeserializationError
- data ReadJSON_Keys_Layout a
- data ReadJSON_Keys_NoLayout a
- data ReadJSON_NoKeys_NoLayout a
- parseJSON_Keys_Layout :: FromJSON ReadJSON_Keys_Layout a => KeyEnv -> RepoLayout -> ByteString -> Either DeserializationError a
- parseJSON_Keys_NoLayout :: FromJSON ReadJSON_Keys_NoLayout a => KeyEnv -> ByteString -> Either DeserializationError a
- parseJSON_NoKeys_NoLayout :: FromJSON ReadJSON_NoKeys_NoLayout a => ByteString -> Either DeserializationError a
- readJSON_Keys_Layout :: (FsRoot root, FromJSON ReadJSON_Keys_Layout a) => KeyEnv -> RepoLayout -> Path root -> IO (Either DeserializationError a)
- readJSON_Keys_NoLayout :: (FsRoot root, FromJSON ReadJSON_Keys_NoLayout a) => KeyEnv -> Path root -> IO (Either DeserializationError a)
- readJSON_NoKeys_NoLayout :: (FsRoot root, FromJSON ReadJSON_NoKeys_NoLayout a) => Path root -> IO (Either DeserializationError a)
- data WriteJSON a
- renderJSON :: ToJSON WriteJSON a => RepoLayout -> a -> ByteString
- renderJSON_NoLayout :: ToJSON Identity a => a -> ByteString
- writeJSON :: ToJSON WriteJSON a => RepoLayout -> Path Absolute -> a -> IO ()
- writeJSON_NoLayout :: ToJSON Identity a => Path Absolute -> a -> IO ()
- class ToJSON (m :: Type -> Type) a where
- class FromJSON (m :: Type -> Type) a where
- data Key a where
- KeyEd25519 :: PublicKey -> SecretKey -> Key Ed25519
- sign :: PrivateKey typ -> ByteString -> ByteString
- data PublicKey a where
- verify :: PublicKey typ -> ByteString -> ByteString -> Bool
- data Ed25519
- data PrivateKey a where
- data KeyType typ where
- somePublicKey :: Some Key -> Some PublicKey
- somePublicKeyType :: Some PublicKey -> Some KeyType
- someKeyId :: forall (key :: Type -> Type). HasKeyId key => Some key -> KeyId
- publicKey :: Key a -> PublicKey a
- privateKey :: Key a -> PrivateKey a
- createKey :: KeyType key -> IO (Key key)
- createKey' :: KeyType key -> IO (Some Key)
- newtype KeyId = KeyId {}
- class HasKeyId (key :: Type -> Type) where
- data Signed a = Signed {
- signed :: a
- signatures :: Signatures
- data Signature = Signature {}
- data IndexFile a where
- IndexPkgMetadata :: PackageIdentifier -> IndexFile (Signed Targets)
- IndexPkgCabal :: PackageIdentifier -> IndexFile ()
- IndexPkgPrefs :: PackageName -> IndexFile ()
- data FileMap
- data TargetPath
- data FileChange
- fileMapChanges :: FileMap -> FileMap -> Map TargetPath FileChange
- data FileInfo = FileInfo {}
- data Int54
- data Header = Header {}
- data Mirrors = Mirrors {}
- data Root = Root {}
- data Snapshot = Snapshot {}
- data Targets = Targets {}
- data Timestamp = Timestamp {}
- newtype FileLength = FileLength {
- fileLength :: Int54
- newtype Hash = Hash String
- newtype KeyThreshold = KeyThreshold Int54
- data HashFn
- fileInfo :: ByteString -> FileInfo
- computeFileInfo :: FsRoot root => Path root -> IO FileInfo
- compareTrustedFileInfo :: FileInfo -> FileInfo -> Bool
- knownFileInfoEqual :: FileInfo -> FileInfo -> Bool
- fileInfoSHA256 :: FileInfo -> Maybe Hash
- class HasHeader a where
- fileExpires :: Lens' a FileExpires
- fileVersion :: Lens' a FileVersion
- newtype FileVersion = FileVersion Int54
- newtype FileExpires = FileExpires (Maybe UTCTime)
- expiresInDays :: UTCTime -> Integer -> FileExpires
- expiresNever :: FileExpires
- isExpired :: UTCTime -> FileExpires -> Bool
- versionInitial :: FileVersion
- versionIncrement :: FileVersion -> FileVersion
- data CacheLayout = CacheLayout {}
- cabalCacheLayout :: CacheLayout
- data IndexLayout = IndexLayout {
- indexFileToPath :: forall dec. IndexFile dec -> IndexPath
- indexFileFromPath :: IndexPath -> Maybe (Some IndexFile)
- hackageIndexLayout :: IndexLayout
- indexLayoutPkgMetadata :: IndexLayout -> PackageIdentifier -> IndexPath
- indexLayoutPkgCabal :: IndexLayout -> PackageIdentifier -> IndexPath
- indexLayoutPkgPrefs :: IndexLayout -> PackageName -> IndexPath
- data RepoLayout = RepoLayout {}
- hackageRepoLayout :: RepoLayout
- cabalLocalRepoLayout :: RepoLayout
- data Mirror = Mirror {}
- data MirrorContent = MirrorFull
- type MirrorDescription = String
- describeMirror :: Mirror -> MirrorDescription
- data RepoRoot
- type RepoPath = Path RepoRoot
- anchorRepoPathLocally :: Path root -> RepoPath -> Path root
- anchorRepoPathRemotely :: Path Web -> RepoPath -> Path Web
- data IndexRoot
- type IndexPath = Path IndexRoot
- data CacheRoot
- type CachePath = Path CacheRoot
- anchorCachePath :: Path root -> CachePath -> Path root
- data Delegation = Delegation (Pattern a) (Replacement a)
- data RootRoles = RootRoles {}
- data RoleSpec a = RoleSpec {}
- newtype Signatures = Signatures [Signature]
- unsigned :: a -> Signed a
- withSignatures :: ToJSON WriteJSON a => RepoLayout -> [Some Key] -> a -> Signed a
- withSignatures' :: ToJSON Identity a => [Some Key] -> a -> Signed a
- signRendered :: [Some Key] -> ByteString -> Signatures
- verifySignature :: ByteString -> Signature -> Bool
- signedFromJSON :: (MonadKeys m, FromJSON m a) => JSValue -> m (Signed a)
- verifySignatures :: JSValue -> Signatures -> Bool
- data UninterpretedSignatures a = UninterpretedSignatures {}
- data PreSignature = PreSignature {}
- fromPreSignature :: MonadKeys m => PreSignature -> m Signature
- fromPreSignatures :: MonadKeys m => [PreSignature] -> m Signatures
- toPreSignature :: Signature -> PreSignature
- toPreSignatures :: Signatures -> [PreSignature]
- data Delegations = Delegations {}
- data DelegationSpec = DelegationSpec {}
- targetsLookup :: TargetPath -> Targets -> Maybe FileInfo
Re-exports
data DeserializationError #
Constructors
DeserializationErrorMalformed String | Malformed JSON has syntax errors in the JSON itself (i.e., we cannot even parse it to a JSValue) |
DeserializationErrorSchema String | Invalid JSON has valid syntax but invalid structure The string gives a hint about what we expected instead |
DeserializationErrorUnknownKey KeyId | The JSON file contains a key ID of an unknown key |
DeserializationErrorValidation String | Some verification step failed |
DeserializationErrorFileType String String | Wrong file type Records actual and expected types. |
Instances
data ReadJSON_Keys_Layout a #
Instances
data ReadJSON_Keys_NoLayout a #
Instances
data ReadJSON_NoKeys_NoLayout a #
Instances
parseJSON_Keys_Layout :: FromJSON ReadJSON_Keys_Layout a => KeyEnv -> RepoLayout -> ByteString -> Either DeserializationError a #
parseJSON_Keys_NoLayout :: FromJSON ReadJSON_Keys_NoLayout a => KeyEnv -> ByteString -> Either DeserializationError a #
parseJSON_NoKeys_NoLayout :: FromJSON ReadJSON_NoKeys_NoLayout a => ByteString -> Either DeserializationError a #
readJSON_Keys_Layout :: (FsRoot root, FromJSON ReadJSON_Keys_Layout a) => KeyEnv -> RepoLayout -> Path root -> IO (Either DeserializationError a) #
readJSON_Keys_NoLayout :: (FsRoot root, FromJSON ReadJSON_Keys_NoLayout a) => KeyEnv -> Path root -> IO (Either DeserializationError a) #
readJSON_NoKeys_NoLayout :: (FsRoot root, FromJSON ReadJSON_NoKeys_NoLayout a) => Path root -> IO (Either DeserializationError a) #
Instances
Applicative WriteJSON # | |
Functor WriteJSON # | |
Monad WriteJSON # | |
MonadReader RepoLayout WriteJSON # | |
Defined in Hackage.Security.JSON Methods ask :: WriteJSON RepoLayout # local :: (RepoLayout -> RepoLayout) -> WriteJSON a -> WriteJSON a # reader :: (RepoLayout -> a) -> WriteJSON a # |
renderJSON :: ToJSON WriteJSON a => RepoLayout -> a -> ByteString #
Render to canonical JSON format
renderJSON_NoLayout :: ToJSON Identity a => a -> ByteString #
Variation on renderJSON
for files that don't require the repo layout
class ToJSON (m :: Type -> Type) a where #
Instances
class FromJSON (m :: Type -> Type) a where #
Instances
Constructors
KeyEd25519 :: PublicKey -> SecretKey -> Key Ed25519 |
Instances
HasKeyId Key # | |
Defined in Hackage.Security.Key | |
SomeEq Key # | |
Defined in Hackage.Security.Key | |
SomeShow Key # | |
Defined in Hackage.Security.Key | |
ReportSchemaErrors m => FromJSON m (Some Key) # | |
Monad m => ToJSON m (Key typ) # | |
Defined in Hackage.Security.Key | |
Monad m => ToJSON m (Some Key) # | |
Show (Key typ) # | |
Eq (Key typ) # | |
sign :: PrivateKey typ -> ByteString -> ByteString #
Sign a bytestring and return the signature
TODO: It is unfortunate that we have to convert to a strict bytestring for ed25519
Constructors
PublicKeyEd25519 :: PublicKey -> PublicKey Ed25519 |
Instances
HasKeyId PublicKey # | |
Defined in Hackage.Security.Key | |
SomeEq PublicKey # | |
Defined in Hackage.Security.Key | |
SomeShow PublicKey # | |
Defined in Hackage.Security.Key | |
ReportSchemaErrors m => FromJSON m (Some PublicKey) # | |
Monad m => ToJSON m (PublicKey typ) # | |
Defined in Hackage.Security.Key | |
Monad m => ToJSON m (Some PublicKey) # | |
Show (PublicKey typ) # | |
Eq (PublicKey typ) # | |
verify :: PublicKey typ -> ByteString -> ByteString -> Bool #
data PrivateKey a where #
Constructors
PrivateKeyEd25519 :: SecretKey -> PrivateKey Ed25519 |
Instances
SomeEq PrivateKey # | |
Defined in Hackage.Security.Key Methods someEq :: DictEq (PrivateKey a) # | |
SomeShow PrivateKey # | |
Defined in Hackage.Security.Key Methods someShow :: DictShow (PrivateKey a) # | |
Show (PrivateKey typ) # | |
Defined in Hackage.Security.Key Methods showsPrec :: Int -> PrivateKey typ -> ShowS # show :: PrivateKey typ -> String # showList :: [PrivateKey typ] -> ShowS # | |
Eq (PrivateKey typ) # | |
Defined in Hackage.Security.Key Methods (==) :: PrivateKey typ -> PrivateKey typ -> Bool # (/=) :: PrivateKey typ -> PrivateKey typ -> Bool # |
Constructors
KeyTypeEd25519 :: KeyType Ed25519 |
Instances
privateKey :: Key a -> PrivateKey a #
The key ID of a key, by definition, is the hexdigest of the SHA-256 hash of the canonical JSON form of the key where the private object key is excluded.
NOTE: The FromJSON and ToJSON instances for KeyId are intentionally omitted. Use writeKeyAsId instead.
Constructors
KeyId | |
Fields |
Instances
Show KeyId # | |
Eq KeyId # | |
Ord KeyId # | |
Monad m => FromObjectKey m KeyId # | |
Defined in Hackage.Security.Key Methods fromObjectKey :: String -> m (Maybe KeyId) # | |
Monad m => ToObjectKey m KeyId # | |
Defined in Hackage.Security.Key Methods toObjectKey :: KeyId -> m String # |
Constructors
Signed | |
Fields
|
Instances
MonadKeys m => FromJSON m (Signed Mirrors) # | |
MonadKeys m => FromJSON m (Signed Root) # | We give an instance for Signed Root rather than Root because the key environment from the root data is necessary to resolve the explicit sharing in the signatures. |
(MonadKeys m, MonadReader RepoLayout m) => FromJSON m (Signed Snapshot) # | |
MonadKeys m => FromJSON m (Signed Targets) # | |
(MonadKeys m, MonadReader RepoLayout m) => FromJSON m (Signed Timestamp) # | |
(Monad m, ToJSON m a) => ToJSON m (Signed a) # | |
Defined in Hackage.Security.TUF.Signed |
Constructors
Signature | |
Fields |
Files that we might request from the index
The type index tells us the type of the decoded file, if any. For files for
which the library does not support decoding this will be ()
.
NOTE: Clients should NOT rely on this type index being ()
, or they might
break if we add support for parsing additional file formats in the future.
TODO: If we wanted to support legacy Hackage, we should also have a case for the global preferred-versions file. But supporting legacy Hackage will probably require more work anyway..
Constructors
IndexPkgMetadata :: PackageIdentifier -> IndexFile (Signed Targets) | |
IndexPkgCabal :: PackageIdentifier -> IndexFile () | |
IndexPkgPrefs :: PackageName -> IndexFile () |
Instances
SomePretty IndexFile # | |
Defined in Hackage.Security.TUF.Layout.Index Methods somePretty :: DictPretty (IndexFile a) # | |
SomeShow IndexFile # | |
Defined in Hackage.Security.TUF.Layout.Index | |
Show (IndexFile dec) # | |
Pretty (IndexFile dec) # | |
Defined in Hackage.Security.TUF.Layout.Index |
Mapping from paths to file info
File maps are used in target files; the paths are relative to the location of the target files containing the file map.
Instances
Show FileMap # | |
ReportSchemaErrors m => FromJSON m FileMap # | |
Defined in Hackage.Security.TUF.FileMap | |
Monad m => ToJSON m FileMap # | |
Defined in Hackage.Security.TUF.FileMap |
data TargetPath #
Entries in FileMap
either talk about the repository or the index
Constructors
TargetPathRepo RepoPath | |
TargetPathIndex IndexPath |
Instances
Show TargetPath # | |
Defined in Hackage.Security.TUF.FileMap Methods showsPrec :: Int -> TargetPath -> ShowS # show :: TargetPath -> String # showList :: [TargetPath] -> ShowS # | |
Eq TargetPath # | |
Defined in Hackage.Security.TUF.FileMap | |
Ord TargetPath # | |
Defined in Hackage.Security.TUF.FileMap Methods compare :: TargetPath -> TargetPath -> Ordering # (<) :: TargetPath -> TargetPath -> Bool # (<=) :: TargetPath -> TargetPath -> Bool # (>) :: TargetPath -> TargetPath -> Bool # (>=) :: TargetPath -> TargetPath -> Bool # max :: TargetPath -> TargetPath -> TargetPath # min :: TargetPath -> TargetPath -> TargetPath # | |
Pretty TargetPath # | |
Defined in Hackage.Security.TUF.FileMap Methods pretty :: TargetPath -> String # | |
ReportSchemaErrors m => FromObjectKey m TargetPath # | |
Defined in Hackage.Security.TUF.FileMap Methods fromObjectKey :: String -> m (Maybe TargetPath) # | |
Monad m => ToObjectKey m TargetPath # | |
Defined in Hackage.Security.TUF.FileMap Methods toObjectKey :: TargetPath -> m String # |
data FileChange #
Constructors
FileChanged FileInfo | File got added or modified; we record the new file info |
FileDeleted | File got deleted |
Instances
Show FileChange # | |
Defined in Hackage.Security.TUF.FileMap Methods showsPrec :: Int -> FileChange -> ShowS # show :: FileChange -> String # showList :: [FileChange] -> ShowS # |
Arguments
:: FileMap | Old |
-> FileMap | New |
-> Map TargetPath FileChange |
File information
This intentionally does not have an Eq
instance; see knownFileInfoEqual
and verifyFileInfo
instead.
NOTE: Throughout we compute file information always over the raw bytes.
For example, when timestamp.json
lists the hash of snapshot.json
, this
hash is computed over the actual snapshot.json
file (as opposed to the
canonical form of the embedded JSON). This brings it in line with the hash
computed over target files, where that is the only choice available.
Constructors
FileInfo | |
Fields |
Instances
Show FileInfo # | |
ReportSchemaErrors m => FromJSON m FileInfo # | |
Defined in Hackage.Security.TUF.FileInfo | |
Monad m => ToJSON m FileInfo # | |
Defined in Hackage.Security.TUF.FileInfo |
54-bit integer values
JavaScript can only safely represent numbers between -(2^53 - 1)
and
2^53 - 1
.
TODO: Although we introduce the type here, we don't actually do any bounds
checking and just inherit all type class instance from Int64. We should
probably define fromInteger
to do bounds checking, give different instances
for type classes such as Bounded
and FiniteBits
, etc.
Instances
Occasionally it is useful to read only a header from a file.
HeaderOnly
intentionally only has a FromJSON
instance (no ToJSON
).
Constructors
Header | |
Fields |
Instances
HasHeader Header # | |
Defined in Hackage.Security.TUF.Header | |
ReportSchemaErrors m => FromJSON m Header # | |
Defined in Hackage.Security.TUF.Header |
Constructors
Mirrors | |
Fields |
Instances
HasHeader Mirrors # | |
Defined in Hackage.Security.TUF.Mirrors | |
VerifyRole Mirrors # | |
Defined in Hackage.Security.Trusted Methods verifyRole :: Trusted Root -> TargetPath -> Maybe FileVersion -> Maybe UTCTime -> Signed Mirrors -> Either VerificationError (SignaturesVerified Mirrors) # | |
(MonadError DeserializationError m, ReportSchemaErrors m) => FromJSON m Mirrors # | |
Defined in Hackage.Security.TUF.Mirrors | |
Monad m => ToJSON m Mirrors # | |
Defined in Hackage.Security.TUF.Mirrors | |
MonadKeys m => FromJSON m (Signed Mirrors) # | |
The root metadata
NOTE: We must have the invariant that ALL keys (apart from delegation keys)
must be listed in rootKeys
. (Delegation keys satisfy a similar invariant,
see Targets.)
Constructors
Root | |
Fields
|
Instances
HasHeader Root # | |
Defined in Hackage.Security.TUF.Root | |
VerifyRole Root # | |
Defined in Hackage.Security.Trusted Methods verifyRole :: Trusted Root -> TargetPath -> Maybe FileVersion -> Maybe UTCTime -> Signed Root -> Either VerificationError (SignaturesVerified Root) # | |
Monad m => ToJSON m Root # | |
Defined in Hackage.Security.TUF.Root | |
MonadKeys m => FromJSON m (Signed Root) # | We give an instance for Signed Root rather than Root because the key environment from the root data is necessary to resolve the explicit sharing in the signatures. |
Constructors
Snapshot | |
Fields
|
Instances
HasHeader Snapshot # | |
Defined in Hackage.Security.TUF.Snapshot | |
VerifyRole Snapshot # | |
Defined in Hackage.Security.Trusted Methods verifyRole :: Trusted Root -> TargetPath -> Maybe FileVersion -> Maybe UTCTime -> Signed Snapshot -> Either VerificationError (SignaturesVerified Snapshot) # | |
(MonadReader RepoLayout m, MonadError DeserializationError m, ReportSchemaErrors m) => FromJSON m Snapshot # | |
Defined in Hackage.Security.TUF.Snapshot | |
MonadReader RepoLayout m => ToJSON m Snapshot # | |
Defined in Hackage.Security.TUF.Snapshot | |
(MonadKeys m, MonadReader RepoLayout m) => FromJSON m (Signed Snapshot) # | |
Target metadata
Most target files do not need expiry dates because they are not subject to change (and hence attacks like freeze attacks are not a concern).
Constructors
Targets | |
Constructors
Timestamp | |
Instances
HasHeader Timestamp # | |
Defined in Hackage.Security.TUF.Timestamp | |
VerifyRole Timestamp # | |
Defined in Hackage.Security.Trusted Methods verifyRole :: Trusted Root -> TargetPath -> Maybe FileVersion -> Maybe UTCTime -> Signed Timestamp -> Either VerificationError (SignaturesVerified Timestamp) # | |
(MonadReader RepoLayout m, MonadError DeserializationError m, ReportSchemaErrors m) => FromJSON m Timestamp # | |
Defined in Hackage.Security.TUF.Timestamp | |
MonadReader RepoLayout m => ToJSON m Timestamp # | |
Defined in Hackage.Security.TUF.Timestamp | |
(MonadKeys m, MonadReader RepoLayout m) => FromJSON m (Signed Timestamp) # | |
newtype FileLength #
File length
Having verified file length information means we can protect against endless data attacks and similar.
Constructors
FileLength | |
Fields
|
Instances
Show FileLength # | |
Defined in Hackage.Security.TUF.Common Methods showsPrec :: Int -> FileLength -> ShowS # show :: FileLength -> String # showList :: [FileLength] -> ShowS # | |
Eq FileLength # | |
Defined in Hackage.Security.TUF.Common | |
Ord FileLength # | |
Defined in Hackage.Security.TUF.Common Methods compare :: FileLength -> FileLength -> Ordering # (<) :: FileLength -> FileLength -> Bool # (<=) :: FileLength -> FileLength -> Bool # (>) :: FileLength -> FileLength -> Bool # (>=) :: FileLength -> FileLength -> Bool # max :: FileLength -> FileLength -> FileLength # min :: FileLength -> FileLength -> FileLength # | |
ReportSchemaErrors m => FromJSON m FileLength # | |
Defined in Hackage.Security.TUF.Common Methods fromJSON :: JSValue -> m FileLength # | |
Monad m => ToJSON m FileLength # | |
Defined in Hackage.Security.TUF.Common Methods toJSON :: FileLength -> m JSValue # |
File hash
newtype KeyThreshold #
Key threshold
The key threshold is the minimum number of keys a document must be signed
with. Key thresholds are specified in RoleSpec
or DelegationsSpec
.
Constructors
KeyThreshold Int54 |
Instances
Show KeyThreshold # | |
Defined in Hackage.Security.TUF.Common Methods showsPrec :: Int -> KeyThreshold -> ShowS # show :: KeyThreshold -> String # showList :: [KeyThreshold] -> ShowS # | |
Eq KeyThreshold # | |
Defined in Hackage.Security.TUF.Common | |
Ord KeyThreshold # | |
Defined in Hackage.Security.TUF.Common Methods compare :: KeyThreshold -> KeyThreshold -> Ordering # (<) :: KeyThreshold -> KeyThreshold -> Bool # (<=) :: KeyThreshold -> KeyThreshold -> Bool # (>) :: KeyThreshold -> KeyThreshold -> Bool # (>=) :: KeyThreshold -> KeyThreshold -> Bool # max :: KeyThreshold -> KeyThreshold -> KeyThreshold # min :: KeyThreshold -> KeyThreshold -> KeyThreshold # | |
ReportSchemaErrors m => FromJSON m KeyThreshold # | |
Defined in Hackage.Security.TUF.Common Methods fromJSON :: JSValue -> m KeyThreshold # | |
Monad m => ToJSON m KeyThreshold # | |
Defined in Hackage.Security.TUF.Common Methods toJSON :: KeyThreshold -> m JSValue # |
Constructors
HashFnSHA256 | |
HashFnMD5 |
Instances
Show HashFn # | |
Eq HashFn # | |
Ord HashFn # | |
ReportSchemaErrors m => FromObjectKey m HashFn # | |
Defined in Hackage.Security.TUF.FileInfo Methods fromObjectKey :: String -> m (Maybe HashFn) # | |
Monad m => ToObjectKey m HashFn # | |
Defined in Hackage.Security.TUF.FileInfo Methods toObjectKey :: HashFn -> m String # |
fileInfo :: ByteString -> FileInfo #
Compute FileInfo
TODO: Currently this will load the entire input bytestring into memory. We need to make this incremental, by computing the length and all hashes in a single traversal over the input.
knownFileInfoEqual :: FileInfo -> FileInfo -> Bool #
Methods
fileExpires :: Lens' a FileExpires #
File expiry date
fileVersion :: Lens' a FileVersion #
File version (monotonically increasing counter)
Instances
HasHeader Header # | |
Defined in Hackage.Security.TUF.Header | |
HasHeader Mirrors # | |
Defined in Hackage.Security.TUF.Mirrors | |
HasHeader Root # | |
Defined in Hackage.Security.TUF.Root | |
HasHeader Snapshot # | |
Defined in Hackage.Security.TUF.Snapshot | |
HasHeader Targets # | |
Defined in Hackage.Security.TUF.Targets | |
HasHeader Timestamp # | |
Defined in Hackage.Security.TUF.Timestamp |
newtype FileVersion #
File version
The file version is a flat integer which must monotonically increase on every file update.
Show
and Read
instance are defined in terms of the underlying Int
(this is used for example by Hackage during the backup process).
Constructors
FileVersion Int54 |
Instances
newtype FileExpires #
File expiry date
A Nothing
value here means no expiry. That makes it possible to set some
files to never expire. (Note that not having the Maybe in the type here still
allows that, because you could set an expiry date 2000 years into the future.
By having the Maybe here we avoid the _need_ for such encoding issues.)
Constructors
FileExpires (Maybe UTCTime) |
Instances
Show FileExpires # | |
Defined in Hackage.Security.TUF.Header Methods showsPrec :: Int -> FileExpires -> ShowS # show :: FileExpires -> String # showList :: [FileExpires] -> ShowS # | |
Eq FileExpires # | |
Defined in Hackage.Security.TUF.Header | |
Ord FileExpires # | |
Defined in Hackage.Security.TUF.Header Methods compare :: FileExpires -> FileExpires -> Ordering # (<) :: FileExpires -> FileExpires -> Bool # (<=) :: FileExpires -> FileExpires -> Bool # (>) :: FileExpires -> FileExpires -> Bool # (>=) :: FileExpires -> FileExpires -> Bool # max :: FileExpires -> FileExpires -> FileExpires # min :: FileExpires -> FileExpires -> FileExpires # | |
ReportSchemaErrors m => FromJSON m FileExpires # | |
Defined in Hackage.Security.TUF.Header Methods fromJSON :: JSValue -> m FileExpires # | |
Monad m => ToJSON m FileExpires # | |
Defined in Hackage.Security.TUF.Header Methods toJSON :: FileExpires -> m JSValue # |
expiresInDays :: UTCTime -> Integer -> FileExpires #
isExpired :: UTCTime -> FileExpires -> Bool #
data CacheLayout #
Location of the various files we cache
Although the generic TUF algorithms do not care how we organize the cache,
we nonetheless specify this here because as long as there are tools which
access files in the cache directly we need to define the cache layout.
See also comments for defaultCacheLayout
.
Constructors
CacheLayout | |
Fields
|
cabalCacheLayout :: CacheLayout #
The cache layout cabal-install uses
We cache the index as cache/00-index.tar
; this is important because
`cabal-install` expects to find it there (and does not currently go through
the hackage-security library to get files from the index).
data IndexLayout #
Layout of the files within the index tarball
Constructors
IndexLayout | |
Fields
|
hackageIndexLayout :: IndexLayout #
The layout of the index as maintained on Hackage
indexLayoutPkgPrefs :: IndexLayout -> PackageName -> IndexPath #
data RepoLayout #
Layout of a repository
Constructors
RepoLayout | |
Fields
|
Instances
MonadReader RepoLayout ReadJSON_Keys_Layout # | |
Defined in Hackage.Security.JSON Methods ask :: ReadJSON_Keys_Layout RepoLayout # local :: (RepoLayout -> RepoLayout) -> ReadJSON_Keys_Layout a -> ReadJSON_Keys_Layout a # reader :: (RepoLayout -> a) -> ReadJSON_Keys_Layout a # | |
MonadReader RepoLayout WriteJSON # | |
Defined in Hackage.Security.JSON Methods ask :: WriteJSON RepoLayout # local :: (RepoLayout -> RepoLayout) -> WriteJSON a -> WriteJSON a # reader :: (RepoLayout -> a) -> WriteJSON a # |
hackageRepoLayout :: RepoLayout #
The layout used on Hackage
cabalLocalRepoLayout :: RepoLayout #
Layout used by cabal for ("legacy") local repos
Obviously, such repos do not normally contain any of the TUF files, so their location is more or less arbitrary here.
Definition of a mirror
NOTE: Unlike the TUF specification, we require that all mirrors must have
the same format. That is, we omit metapath
and targetspath
.
Constructors
Mirror | |
Fields |
Instances
Show Mirror # | |
ReportSchemaErrors m => FromJSON m Mirror # | |
Defined in Hackage.Security.TUF.Mirrors | |
Monad m => ToJSON m Mirror # | |
Defined in Hackage.Security.TUF.Mirrors |
data MirrorContent #
Full versus partial mirrors
The TUF spec explicitly allows for partial mirrors, with the mirrors file specifying (through patterns) what is available from partial mirrors.
For now we only support full mirrors; if we wanted to add partial mirrors,
we would add a second MirrorPartial
constructor here with arguments
corresponding to TUF's metacontent
and targetscontent
fields.
Constructors
MirrorFull |
Instances
Show MirrorContent # | |
Defined in Hackage.Security.TUF.Mirrors Methods showsPrec :: Int -> MirrorContent -> ShowS # show :: MirrorContent -> String # showList :: [MirrorContent] -> ShowS # |
type MirrorDescription = String #
describeMirror :: Mirror -> MirrorDescription #
Give a human-readable description of a particular mirror
(for use in error messages)
The root of the repository
Repository roots can be anchored at a remote URL or a local directory.
Note that even for remote repos RepoRoot
is (potentially) different from
Web
-- for a repository located at, say, http://hackage.haskell.org
they happen to coincide, but for one location at
http://example.com/some/subdirectory
they do not.
anchorRepoPathLocally :: Path root -> RepoPath -> Path root #
The root of the index tarball
The cache directory
anchorCachePath :: Path root -> CachePath -> Path root #
Anchor a cache path to the location of the cache
data Delegation #
A delegation
A delegation is a pair of a pattern and a replacement.
See match
for an example.
Constructors
Delegation (Pattern a) (Replacement a) |
Instances
Show Delegation # | |
Defined in Hackage.Security.TUF.Patterns Methods showsPrec :: Int -> Delegation -> ShowS # show :: Delegation -> String # showList :: [Delegation] -> ShowS # | |
Lift Delegation # | |
Defined in Hackage.Security.TUF.Patterns Methods lift :: Quote m => Delegation -> m Exp # liftTyped :: forall (m :: Type -> Type). Quote m => Delegation -> Code m Delegation # |
Constructors
RootRoles | |
Role specification
The phantom type indicates what kind of type this role is meant to verify.
Constructors
RoleSpec | |
Fields |
newtype Signatures #
A list of signatures
Invariant: each signature must be made with a different key.
We enforce this invariant for incoming untrusted data (fromPreSignatures
)
but not for lists of signatures that we create in code.
Constructors
Signatures [Signature] |
Instances
MonadKeys m => FromJSON m Signatures # | |
Defined in Hackage.Security.TUF.Signed Methods fromJSON :: JSValue -> m Signatures # | |
Monad m => ToJSON m Signatures # | |
Defined in Hackage.Security.TUF.Signed Methods toJSON :: Signatures -> m JSValue # |
withSignatures :: ToJSON WriteJSON a => RepoLayout -> [Some Key] -> a -> Signed a #
Sign a document
withSignatures' :: ToJSON Identity a => [Some Key] -> a -> Signed a #
Variation on withSignatures
that doesn't need the repo layout
signRendered :: [Some Key] -> ByteString -> Signatures #
Construct signatures for already rendered value
verifySignature :: ByteString -> Signature -> Bool #
signedFromJSON :: (MonadKeys m, FromJSON m a) => JSValue -> m (Signed a) #
General FromJSON instance for signed datatypes
We don't give a general FromJSON instance for Signed because for some datatypes we need to do something special (datatypes where we need to read key environments); for instance, see the "Signed Root" instance.
verifySignatures :: JSValue -> Signatures -> Bool #
Signature verification
NOTES: 1. By definition, the signature must be verified against the canonical JSON format. This means we _must_ parse and then pretty print (as we do here) because the document as stored may or may not be in canonical format. 2. However, it is important that we NOT translate from the JSValue to whatever internal datatype we are using and then back to JSValue, because that may not roundtrip: we must allow for additional fields in the JSValue that we ignore (and would therefore lose when we attempt to roundtrip). 3. We verify that all signatures are valid, but we cannot verify (here) that these signatures are signed with the right key, or that we have a sufficient number of signatures. This will be the responsibility of the calling code.
data UninterpretedSignatures a #
File with uninterpreted signatures
Sometimes we want to be able to read a file without interpreting the signatures (that is, resolving the key IDs) or doing any kind of checks on them. One advantage of this is that this allows us to read many file types without any key environment at all, which is sometimes useful.
Constructors
UninterpretedSignatures | |
Fields |
Instances
(ReportSchemaErrors m, FromJSON m a) => FromJSON m (UninterpretedSignatures a) # | |
Defined in Hackage.Security.TUF.Signed Methods fromJSON :: JSValue -> m (UninterpretedSignatures a) # | |
(Monad m, ToJSON m a) => ToJSON m (UninterpretedSignatures a) # | |
Defined in Hackage.Security.TUF.Signed Methods toJSON :: UninterpretedSignatures a -> m JSValue # | |
Show a => Show (UninterpretedSignatures a) # | |
Defined in Hackage.Security.TUF.Signed Methods showsPrec :: Int -> UninterpretedSignatures a -> ShowS # show :: UninterpretedSignatures a -> String # showList :: [UninterpretedSignatures a] -> ShowS # |
data PreSignature #
A signature with a key ID (rather than an actual key)
This corresponds precisely to the TUF representation of a signature.
Constructors
PreSignature | |
Fields |
Instances
Show PreSignature # | |
Defined in Hackage.Security.TUF.Signed Methods showsPrec :: Int -> PreSignature -> ShowS # show :: PreSignature -> String # showList :: [PreSignature] -> ShowS # | |
ReportSchemaErrors m => FromJSON m PreSignature # | |
Defined in Hackage.Security.TUF.Signed Methods fromJSON :: JSValue -> m PreSignature # | |
Monad m => ToJSON m PreSignature # | |
Defined in Hackage.Security.TUF.Signed Methods toJSON :: PreSignature -> m JSValue # |
fromPreSignature :: MonadKeys m => PreSignature -> m Signature #
Convert a pre-signature to a signature
Verifies that the key type matches the advertised method.
fromPreSignatures :: MonadKeys m => [PreSignature] -> m Signatures #
Convert a list of PreSignature
s to a list of Signature
s
This verifies the invariant that all signatures are made with different keys. We do this on the presignatures rather than the signatures so that we can do the check on key IDs, rather than keys (the latter don't have an Ord instance).
toPreSignature :: Signature -> PreSignature #
Convert signature to pre-signature
toPreSignatures :: Signatures -> [PreSignature] #
Convert list of pre-signatures to a list of signatures
data Delegations #
Delegations
Much like the Root datatype, this must have an invariant that ALL used keys
(apart from the global keys, which are in the root key environment) must
be listed in delegationsKeys
.
Constructors
Delegations | |
Fields |
Instances
Show Delegations # | |
Defined in Hackage.Security.TUF.Targets Methods showsPrec :: Int -> Delegations -> ShowS # show :: Delegations -> String # showList :: [Delegations] -> ShowS # | |
MonadKeys m => FromJSON m Delegations # | |
Defined in Hackage.Security.TUF.Targets Methods fromJSON :: JSValue -> m Delegations # | |
Monad m => ToJSON m Delegations # | |
Defined in Hackage.Security.TUF.Targets Methods toJSON :: Delegations -> m JSValue # |
data DelegationSpec #
Delegation specification
NOTE: This is a close analogue of RoleSpec
.
Constructors
DelegationSpec | |
Fields |
Instances
Show DelegationSpec # | |
Defined in Hackage.Security.TUF.Targets Methods showsPrec :: Int -> DelegationSpec -> ShowS # show :: DelegationSpec -> String # showList :: [DelegationSpec] -> ShowS # | |
MonadKeys m => FromJSON m DelegationSpec # | |
Defined in Hackage.Security.TUF.Targets Methods fromJSON :: JSValue -> m DelegationSpec # | |
Monad m => ToJSON m DelegationSpec # | |
Defined in Hackage.Security.TUF.Targets Methods toJSON :: DelegationSpec -> m JSValue # |
targetsLookup :: TargetPath -> Targets -> Maybe FileInfo #