    -- |
    -- Module      : Data.X509.Validation.Fingerprint
    -- License     : BSD-style
    -- Maintainer  : Vincent Hanquez <vincent@snarc.org>
    -- Stability   : experimental
    -- Portability : unknown
    --
    {-# LANGUAGE GeneralizedNewtypeDeriving #-}
    module Data.X509.Validation.Fingerprint
        ( Fingerprint(..)
        , getFingerprint
        ) where

    import Crypto.Hash
    import Data.X509
    import Data.ASN1.Types
    import Data.ByteArray (convert, ByteArrayAccess)
    import Data.ByteString (ByteString)

    -- | Fingerprint of a certificate
    newtype Fingerprint = Fingerprint ByteString
        deriving (Int -> Fingerprint -> ShowS
    [Fingerprint] -> ShowS
    Fingerprint -> String
    (Int -> Fingerprint -> ShowS)
    -> (Fingerprint -> String)
    -> ([Fingerprint] -> ShowS)
    -> Show Fingerprint
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Fingerprint -> ShowS
    showsPrec :: Int -> Fingerprint -> ShowS
    $cshow :: Fingerprint -> String
    show :: Fingerprint -> String
    $cshowList :: [Fingerprint] -> ShowS
    showList :: [Fingerprint] -> ShowS
    Show,Fingerprint -> Fingerprint -> Bool
    (Fingerprint -> Fingerprint -> Bool)
    -> (Fingerprint -> Fingerprint -> Bool) -> Eq Fingerprint
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Fingerprint -> Fingerprint -> Bool
    == :: Fingerprint -> Fingerprint -> Bool
    $c/= :: Fingerprint -> Fingerprint -> Bool
    /= :: Fingerprint -> Fingerprint -> Bool
    Eq,Fingerprint -> Int
    (Fingerprint -> Int)
    -> (forall p a. Fingerprint -> (Ptr p -> IO a) -> IO a)
    -> (forall p. Fingerprint -> Ptr p -> IO ())
    -> ByteArrayAccess Fingerprint
    forall p. Fingerprint -> Ptr p -> IO ()
    forall ba.
    (ba -> Int)
    -> (forall p a. ba -> (Ptr p -> IO a) -> IO a)
    -> (forall p. ba -> Ptr p -> IO ())
    -> ByteArrayAccess ba
    forall p a. Fingerprint -> (Ptr p -> IO a) -> IO a
    $clength :: Fingerprint -> Int
    length :: Fingerprint -> Int
    $cwithByteArray :: forall p a. Fingerprint -> (Ptr p -> IO a) -> IO a
    withByteArray :: forall p a. Fingerprint -> (Ptr p -> IO a) -> IO a
    $ccopyByteArrayToPtr :: forall p. Fingerprint -> Ptr p -> IO ()
    copyByteArrayToPtr :: forall p. Fingerprint -> Ptr p -> IO ()
    ByteArrayAccess)

    -- | Get the fingerprint of the whole signed object
    -- using the hashing algorithm specified
    getFingerprint :: (Show a, Eq a, ASN1Object a)
                   => SignedExact a -- ^ object to fingerprint
                   -> HashALG       -- ^ algorithm to compute the fingerprint
                   -> Fingerprint   -- ^ fingerprint in binary form
    getFingerprint :: forall a.
    (Show a, Eq a, ASN1Object a) =>
    SignedExact a -> HashALG -> Fingerprint
    getFingerprint SignedExact a
    sobj HashALG
    halg = ByteString -> Fingerprint
    Fingerprint (ByteString -> Fingerprint) -> ByteString -> Fingerprint
    forall a b. (a -> b) -> a -> b
    $ HashALG -> ByteString -> ByteString
    forall {c} {a}.
    (ByteArray c, ByteArrayAccess a) =>
    HashALG -> a -> c
    mkHash HashALG
    halg (ByteString -> ByteString) -> ByteString -> ByteString
    forall a b. (a -> b) -> a -> b
    $ SignedExact a -> ByteString
    forall a.
    (Show a, Eq a, ASN1Object a) =>
    SignedExact a -> ByteString
    encodeSignedObject SignedExact a
    sobj
      where
        mkHash :: HashALG -> a -> c
    mkHash HashALG
    HashMD2    = Digest MD2 -> c
    forall bin bout.
    (ByteArrayAccess bin, ByteArray bout) =>
    bin -> bout
    convert (Digest MD2 -> c) -> (a -> Digest MD2) -> a -> c
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . MD2 -> a -> Digest MD2
    forall ba alg.
    (ByteArrayAccess ba, HashAlgorithm alg) =>
    alg -> ba -> Digest alg
    hashWith MD2
    MD2
        mkHash HashALG
    HashMD5    = Digest MD5 -> c
    forall bin bout.
    (ByteArrayAccess bin, ByteArray bout) =>
    bin -> bout
    convert (Digest MD5 -> c) -> (a -> Digest MD5) -> a -> c
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . MD5 -> a -> Digest MD5
    forall ba alg.
    (ByteArrayAccess ba, HashAlgorithm alg) =>
    alg -> ba -> Digest alg
    hashWith MD5
    MD5
        mkHash HashALG
    HashSHA1   = Digest SHA1 -> c
    forall bin bout.
    (ByteArrayAccess bin, ByteArray bout) =>
    bin -> bout
    convert (Digest SHA1 -> c) -> (a -> Digest SHA1) -> a -> c
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . SHA1 -> a -> Digest SHA1
    forall ba alg.
    (ByteArrayAccess ba, HashAlgorithm alg) =>
    alg -> ba -> Digest alg
    hashWith SHA1
    SHA1
        mkHash HashALG
    HashSHA224 = Digest SHA224 -> c
    forall bin bout.
    (ByteArrayAccess bin, ByteArray bout) =>
    bin -> bout
    convert (Digest SHA224 -> c) -> (a -> Digest SHA224) -> a -> c
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . SHA224 -> a -> Digest SHA224
    forall ba alg.
    (ByteArrayAccess ba, HashAlgorithm alg) =>
    alg -> ba -> Digest alg
    hashWith SHA224
    SHA224
        mkHash HashALG
    HashSHA256 = Digest SHA256 -> c
    forall bin bout.
    (ByteArrayAccess bin, ByteArray bout) =>
    bin -> bout
    convert (Digest SHA256 -> c) -> (a -> Digest SHA256) -> a -> c
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . SHA256 -> a -> Digest SHA256
    forall ba alg.
    (ByteArrayAccess ba, HashAlgorithm alg) =>
    alg -> ba -> Digest alg
    hashWith SHA256
    SHA256
        mkHash HashALG
    HashSHA384 = Digest SHA384 -> c
    forall bin bout.
    (ByteArrayAccess bin, ByteArray bout) =>
    bin -> bout
    convert (Digest SHA384 -> c) -> (a -> Digest SHA384) -> a -> c
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . SHA384 -> a -> Digest SHA384
    forall ba alg.
    (ByteArrayAccess ba, HashAlgorithm alg) =>
    alg -> ba -> Digest alg
    hashWith SHA384
    SHA384
        mkHash HashALG
    HashSHA512 = Digest SHA512 -> c
    forall bin bout.
    (ByteArrayAccess bin, ByteArray bout) =>
    bin -> bout
    convert (Digest SHA512 -> c) -> (a -> Digest SHA512) -> a -> c
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . SHA512 -> a -> Digest SHA512
    forall ba alg.
    (ByteArrayAccess ba, HashAlgorithm alg) =>
    alg -> ba -> Digest alg
    hashWith SHA512
    SHA512