    {-# LINE 1 "OpenSSL/X509.hsc" #-}
    {-# LANGUAGE EmptyDataDecls           #-}
    {-# LANGUAGE ForeignFunctionInterface #-}
    {-# LANGUAGE CApiFFI                  #-}
    {-# OPTIONS_HADDOCK prune             #-}
    -- |An interface to X.509 certificate.
    module OpenSSL.X509
        ( -- * Type
          X509(..)
        , X509_

          -- * Functions to manipulate certificate
        , newX509
        , wrapX509 -- private
        , withX509Ptr -- private
        , withX509Stack -- private
        , unsafeX509ToPtr -- private
        , touchX509 -- private

        , writeDerX509
        , readDerX509
        , compareX509

        , signX509
        , verifyX509

        , printX509

          -- * Accessors
        , getVersion
        , setVersion

        , getSerialNumber
        , setSerialNumber

        , getIssuerName
        , setIssuerName

        , getSubjectName
        , setSubjectName

        , getNotBefore
        , setNotBefore

        , getNotAfter
        , setNotAfter

        , getPublicKey
        , setPublicKey

        , getSubjectEmail
        )
        where

    import Control.Monad
    import Data.Time.Clock
    import Data.Maybe
    import Foreign.ForeignPtr

    {-# LINE 59 "OpenSSL/X509.hsc" #-}
    import Foreign.ForeignPtr.Unsafe as Unsafe

    {-# LINE 63 "OpenSSL/X509.hsc" #-}
    import Foreign.Ptr
    import Foreign.C
    import OpenSSL.ASN1
    import OpenSSL.BIO
    import OpenSSL.EVP.Digest
    import OpenSSL.EVP.PKey
    import OpenSSL.EVP.Verify
    import OpenSSL.EVP.Internal
    import OpenSSL.Utils
    import OpenSSL.Stack
    import OpenSSL.X509.Name
    import Data.ByteString.Lazy (ByteString)

    -- |@'X509'@ is an opaque object that represents X.509 certificate.
    newtype X509  = X509 (ForeignPtr X509_)
    data {-# CTYPE "openssl/x509.h" "X509" #-} X509_

    foreign import capi unsafe "openssl/x509.h X509_new"
            _new :: IO (Ptr X509_)

    foreign import capi unsafe "openssl/x509.h &X509_free"
            _free :: FunPtr (Ptr X509_ -> IO ())

    foreign import capi unsafe "openssl/x509.h X509_print"
            _print :: Ptr BIO_ -> Ptr X509_ -> IO CInt

    foreign import capi unsafe "openssl/x509.h X509_cmp"
            _cmp :: Ptr X509_ -> Ptr X509_ -> IO CInt

    foreign import capi unsafe "HsOpenSSL.h HsOpenSSL_X509_get_version"
            _get_version :: Ptr X509_ -> IO CLong

    foreign import capi unsafe "openssl/x509.h X509_set_version"
            _set_version :: Ptr X509_ -> CLong -> IO CInt

    foreign import capi unsafe "openssl/x509.h X509_get_serialNumber"
            _get_serialNumber :: Ptr X509_ -> IO (Ptr ASN1_INTEGER)

    foreign import capi unsafe "openssl/x509.h X509_set_serialNumber"
            _set_serialNumber :: Ptr X509_ -> Ptr ASN1_INTEGER -> IO CInt

    foreign import capi unsafe "openssl/x509.h X509_get_issuer_name"
            _get_issuer_name :: Ptr X509_ -> IO (Ptr X509_NAME)

    foreign import capi unsafe "openssl/x509.h X509_set_issuer_name"
            _set_issuer_name :: Ptr X509_ -> Ptr X509_NAME -> IO CInt

    foreign import capi unsafe "openssl/x509.h X509_get_subject_name"
            _get_subject_name :: Ptr X509_ -> IO (Ptr X509_NAME)

    foreign import capi unsafe "openssl/x509.h X509_set_subject_name"
            _set_subject_name :: Ptr X509_ -> Ptr X509_NAME -> IO CInt

    foreign import capi unsafe "HsOpenSSL.h HsOpenSSL_X509_get_notBefore"
            _get_notBefore :: Ptr X509_ -> IO (Ptr ASN1_TIME)

    foreign import capi unsafe "HsOpenSSL.h HsOpenSSL_X509_get_notAfter"
            _get_notAfter :: Ptr X509_ -> IO (Ptr ASN1_TIME)

    {-# LINE 124 "OpenSSL/X509.hsc" #-}
    foreign import capi unsafe "openssl/x509.h X509_set1_notBefore"
            _set_notBefore :: Ptr X509_ -> Ptr ASN1_TIME -> IO CInt

    foreign import capi unsafe "openssl/x509.h X509_set1_notAfter"
            _set_notAfter :: Ptr X509_ -> Ptr ASN1_TIME -> IO CInt

    {-# LINE 136 "OpenSSL/X509.hsc" #-}

    foreign import capi unsafe "openssl/x509.h X509_get_pubkey"
            _get_pubkey :: Ptr X509_ -> IO (Ptr EVP_PKEY)

    foreign import capi unsafe "openssl/x509.h X509_set_pubkey"
            _set_pubkey :: Ptr X509_ -> Ptr EVP_PKEY -> IO CInt

    foreign import capi unsafe "openssl/x509v3.h X509_get1_email"
            _get1_email :: Ptr X509_ -> IO (Ptr STACK)

    foreign import capi unsafe "openssl/x509v3.h X509_email_free"
            _email_free :: Ptr STACK -> IO ()

    foreign import capi unsafe "openssl/x509.h X509_sign"
            _sign :: Ptr X509_ -> Ptr EVP_PKEY -> Ptr EVP_MD -> IO CInt

    foreign import capi unsafe "openssl/x509.h X509_verify"
            _verify :: Ptr X509_ -> Ptr EVP_PKEY -> IO CInt

    foreign import capi safe "openssl/x509.h i2d_X509_bio"
            _write_bio_X509 :: Ptr BIO_
                            -> Ptr X509_
                            -> IO CInt

    foreign import capi safe "openssl/x509.h d2i_X509_bio"
            _read_bio_X509 :: Ptr BIO_
                           -> Ptr (Ptr X509_)
                           -> IO (Ptr X509_)

    -- |@'newX509'@ creates an empty certificate. You must set the
    -- following properties to and sign it (see 'signX509') to actually
    -- use the certificate.
    --
    --   [/Version/] See 'setVersion'.
    --
    --   [/Serial number/] See 'setSerialNumber'.
    --
    --   [/Issuer name/] See 'setIssuerName'.
    --
    --   [/Subject name/] See 'setSubjectName'.
    --
    --   [/Validity/] See 'setNotBefore' and 'setNotAfter'.
    --
    --   [/Public Key/] See 'setPublicKey'.
    --
    newX509 :: IO X509
    newX509 :: IO X509
    newX509 = IO (Ptr X509_)
    _new IO (Ptr X509_) -> (Ptr X509_ -> IO (Ptr X509_)) -> IO (Ptr X509_)
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Ptr X509_ -> IO (Ptr X509_)
    forall a. Ptr a -> IO (Ptr a)
    failIfNull IO (Ptr X509_) -> (Ptr X509_ -> IO X509) -> IO X509
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Ptr X509_ -> IO X509
    wrapX509

    wrapX509 :: Ptr X509_ -> IO X509
    wrapX509 :: Ptr X509_ -> IO X509
    wrapX509 = (ForeignPtr X509_ -> X509) -> IO (ForeignPtr X509_) -> IO X509
    forall a b. (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ForeignPtr X509_ -> X509
    X509 (IO (ForeignPtr X509_) -> IO X509)
    -> (Ptr X509_ -> IO (ForeignPtr X509_)) -> Ptr X509_ -> IO X509
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . FinalizerPtr X509_ -> Ptr X509_ -> IO (ForeignPtr X509_)
    forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
    newForeignPtr FinalizerPtr X509_
    _free

    withX509Ptr :: X509 -> (Ptr X509_ -> IO a) -> IO a
    withX509Ptr :: forall a. X509 -> (Ptr X509_ -> IO a) -> IO a
    withX509Ptr (X509 ForeignPtr X509_
    x509) = ForeignPtr X509_ -> (Ptr X509_ -> IO a) -> IO a
    forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
    withForeignPtr ForeignPtr X509_
    x509

    withX509Stack :: [X509] -> (Ptr STACK -> IO a) -> IO a
    withX509Stack :: forall a. [X509] -> (Ptr STACK -> IO a) -> IO a
    withX509Stack = (X509 -> Ptr X509_)
    -> (X509 -> IO ()) -> [X509] -> (Ptr STACK -> IO a) -> IO a
    forall fp obj ret.
    (fp -> Ptr obj)
    -> (fp -> IO ()) -> [fp] -> (Ptr STACK -> IO ret) -> IO ret
    withForeignStack X509 -> Ptr X509_
    unsafeX509ToPtr X509 -> IO ()
    touchX509

    unsafeX509ToPtr :: X509 -> Ptr X509_
    unsafeX509ToPtr :: X509 -> Ptr X509_
    unsafeX509ToPtr (X509 ForeignPtr X509_
    x509) = ForeignPtr X509_ -> Ptr X509_
    forall a. ForeignPtr a -> Ptr a
    Unsafe.unsafeForeignPtrToPtr ForeignPtr X509_
    x509

    touchX509 :: X509 -> IO ()
    touchX509 :: X509 -> IO ()
    touchX509 (X509 ForeignPtr X509_
    x509) = ForeignPtr X509_ -> IO ()
    forall a. ForeignPtr a -> IO ()
    touchForeignPtr ForeignPtr X509_
    x509

    writeX509' :: BIO -> X509 -> IO ()
    writeX509' :: BIO -> X509 -> IO ()
    writeX509' BIO
    bio X509
    x509
        = BIO -> (Ptr BIO_ -> IO ()) -> IO ()
    forall a. BIO -> (Ptr BIO_ -> IO a) -> IO a
    withBioPtr BIO
    bio   ((Ptr BIO_ -> IO ()) -> IO ()) -> (Ptr BIO_ -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \ Ptr BIO_
    bioPtr ->
          X509 -> (Ptr X509_ -> IO ()) -> IO ()
    forall a. X509 -> (Ptr X509_ -> IO a) -> IO a
    withX509Ptr X509
    x509 ((Ptr X509_ -> IO ()) -> IO ()) -> (Ptr X509_ -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \ Ptr X509_
    x509Ptr ->
          Ptr BIO_ -> Ptr X509_ -> IO CInt
    _write_bio_X509 Ptr BIO_
    bioPtr Ptr X509_
    x509Ptr
               IO CInt -> (CInt -> IO CInt) -> IO CInt
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (CInt -> Bool) -> CInt -> IO CInt
    forall a. (a -> Bool) -> a -> IO a
    failIf (CInt -> CInt -> Bool
    forall a. Ord a => a -> a -> Bool
    < CInt
    0)
               IO CInt -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >>  () -> IO ()
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

    -- |@'writeDerX509' cert@ writes an X.509 certificate to DER string.
    writeDerX509 :: X509 -> IO ByteString
    writeDerX509 :: X509 -> IO ByteString
    writeDerX509 X509
    x509
        = do mem <- IO BIO
    newMem
             writeX509' mem x509
             bioReadLBS mem

    readX509' :: BIO -> IO X509
    readX509' :: BIO -> IO X509
    readX509' BIO
    bio
        = BIO -> (Ptr BIO_ -> IO X509) -> IO X509
    forall a. BIO -> (Ptr BIO_ -> IO a) -> IO a
    withBioPtr BIO
    bio ((Ptr BIO_ -> IO X509) -> IO X509)
    -> (Ptr BIO_ -> IO X509) -> IO X509
    forall a b. (a -> b) -> a -> b
    $ \ Ptr BIO_
    bioPtr ->
          Ptr BIO_ -> Ptr (Ptr X509_) -> IO (Ptr X509_)
    _read_bio_X509 Ptr BIO_
    bioPtr Ptr (Ptr X509_)
    forall a. Ptr a
    nullPtr
               IO (Ptr X509_) -> (Ptr X509_ -> IO (Ptr X509_)) -> IO (Ptr X509_)
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Ptr X509_ -> IO (Ptr X509_)
    forall a. Ptr a -> IO (Ptr a)
    failIfNull
               IO (Ptr X509_) -> (Ptr X509_ -> IO X509) -> IO X509
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Ptr X509_ -> IO X509
    wrapX509

    -- |@'readDerX509' der@ reads in a certificate.
    readDerX509 :: ByteString -> IO X509
    readDerX509 :: ByteString -> IO X509
    readDerX509 ByteString
    derStr
        = ByteString -> IO BIO
    newConstMemLBS ByteString
    derStr IO BIO -> (BIO -> IO X509) -> IO X509
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= BIO -> IO X509
    readX509'

    -- |@'compareX509' cert1 cert2@ compares two certificates.
    compareX509 :: X509 -> X509 -> IO Ordering
    compareX509 :: X509 -> X509 -> IO Ordering
    compareX509 X509
    cert1 X509
    cert2
        = X509 -> (Ptr X509_ -> IO Ordering) -> IO Ordering
    forall a. X509 -> (Ptr X509_ -> IO a) -> IO a
    withX509Ptr X509
    cert1 ((Ptr X509_ -> IO Ordering) -> IO Ordering)
    -> (Ptr X509_ -> IO Ordering) -> IO Ordering
    forall a b. (a -> b) -> a -> b
    $ \ Ptr X509_
    cert1Ptr ->
          X509 -> (Ptr X509_ -> IO Ordering) -> IO Ordering
    forall a. X509 -> (Ptr X509_ -> IO a) -> IO a
    withX509Ptr X509
    cert2 ((Ptr X509_ -> IO Ordering) -> IO Ordering)
    -> (Ptr X509_ -> IO Ordering) -> IO Ordering
    forall a b. (a -> b) -> a -> b
    $ \ Ptr X509_
    cert2Ptr ->
          (CInt -> Ordering) -> IO CInt -> IO Ordering
    forall a b. (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap CInt -> Ordering
    interpret (Ptr X509_ -> Ptr X509_ -> IO CInt
    _cmp Ptr X509_
    cert1Ptr Ptr X509_
    cert2Ptr)
        where
          interpret :: CInt -> Ordering
          interpret :: CInt -> Ordering
    interpret CInt
    n
              | CInt
    n CInt -> CInt -> Bool
    forall a. Ord a => a -> a -> Bool
    > CInt
    0     = Ordering
    GT
              | CInt
    n CInt -> CInt -> Bool
    forall a. Ord a => a -> a -> Bool
    < CInt
    0     = Ordering
    LT
              | Bool
    otherwise = Ordering
    EQ

    -- |@'signX509'@ signs a certificate with an issuer private key.
    signX509 :: KeyPair key =>
                X509         -- ^ The certificate to be signed.
             -> key          -- ^ The private key to sign with.
             -> Maybe Digest -- ^ A hashing algorithm to use. If @Nothing@
                             --   the most suitable algorithm for the key
                             --   is automatically used.
             -> IO ()
    signX509 :: forall key. KeyPair key => X509 -> key -> Maybe Digest -> IO ()
    signX509 X509
    x509 key
    key Maybe Digest
    mDigest
        = X509 -> (Ptr X509_ -> IO ()) -> IO ()
    forall a. X509 -> (Ptr X509_ -> IO a) -> IO a
    withX509Ptr X509
    x509 ((Ptr X509_ -> IO ()) -> IO ()) -> (Ptr X509_ -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \ Ptr X509_
    x509Ptr ->
          key -> (Ptr EVP_PKEY -> IO ()) -> IO ()
    forall k a. PKey k => k -> (Ptr EVP_PKEY -> IO a) -> IO a
    withPKeyPtr' key
    key ((Ptr EVP_PKEY -> IO ()) -> IO ())
    -> (Ptr EVP_PKEY -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \ Ptr EVP_PKEY
    pkeyPtr ->
          do dig <- case Maybe Digest
    mDigest of
                      Just Digest
    md -> Digest -> IO Digest
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Digest
    md
                      Maybe Digest
    Nothing -> key -> IO Digest
    forall k. PKey k => k -> IO Digest
    pkeyDefaultMD key
    key
             withMDPtr dig $ \ Ptr EVP_MD
    digestPtr ->
                 Ptr X509_ -> Ptr EVP_PKEY -> Ptr EVP_MD -> IO CInt
    _sign Ptr X509_
    x509Ptr Ptr EVP_PKEY
    pkeyPtr Ptr EVP_MD
    digestPtr
                      IO CInt -> (CInt -> IO ()) -> IO ()
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (CInt -> Bool) -> CInt -> IO ()
    forall a. (a -> Bool) -> a -> IO ()
    failIf_ (CInt -> CInt -> Bool
    forall a. Eq a => a -> a -> Bool
    == CInt
    0)
             return ()

    -- |@'verifyX509'@ verifies a signature of certificate with an issuer
    -- public key.
    verifyX509 :: PublicKey key =>
                  X509 -- ^ The certificate to be verified.
               -> key  -- ^ The public key to verify with.
               -> IO VerifyStatus
    verifyX509 :: forall key. PublicKey key => X509 -> key -> IO VerifyStatus
    verifyX509 X509
    x509 key
    key
        = X509 -> (Ptr X509_ -> IO VerifyStatus) -> IO VerifyStatus
    forall a. X509 -> (Ptr X509_ -> IO a) -> IO a
    withX509Ptr X509
    x509 ((Ptr X509_ -> IO VerifyStatus) -> IO VerifyStatus)
    -> (Ptr X509_ -> IO VerifyStatus) -> IO VerifyStatus
    forall a b. (a -> b) -> a -> b
    $ \ Ptr X509_
    x509Ptr ->
          key -> (Ptr EVP_PKEY -> IO VerifyStatus) -> IO VerifyStatus
    forall k a. PKey k => k -> (Ptr EVP_PKEY -> IO a) -> IO a
    withPKeyPtr' key
    key ((Ptr EVP_PKEY -> IO VerifyStatus) -> IO VerifyStatus)
    -> (Ptr EVP_PKEY -> IO VerifyStatus) -> IO VerifyStatus
    forall a b. (a -> b) -> a -> b
    $ \ Ptr EVP_PKEY
    pkeyPtr ->
          Ptr X509_ -> Ptr EVP_PKEY -> IO CInt
    _verify Ptr X509_
    x509Ptr Ptr EVP_PKEY
    pkeyPtr
               IO CInt -> (CInt -> IO VerifyStatus) -> IO VerifyStatus
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= CInt -> IO VerifyStatus
    interpret
        where
          interpret :: CInt -> IO VerifyStatus
          interpret :: CInt -> IO VerifyStatus
    interpret CInt
    1 = VerifyStatus -> IO VerifyStatus
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return VerifyStatus
    VerifySuccess
          interpret CInt
    0 = do
            IO ()
    clearErrorStack
            VerifyStatus -> IO VerifyStatus
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return VerifyStatus
    VerifyFailure
          interpret CInt
    _ = IO VerifyStatus
    forall a. IO a
    raiseOpenSSLError

    -- |@'printX509' cert@ translates a certificate into human-readable
    -- format.
    printX509 :: X509 -> IO String
    printX509 :: X509 -> IO String
    printX509 X509
    x509
        = do mem <- IO BIO
    newMem
             withX509Ptr x509 $ \ Ptr X509_
    x509Ptr ->
                 BIO -> (Ptr BIO_ -> IO ()) -> IO ()
    forall a. BIO -> (Ptr BIO_ -> IO a) -> IO a
    withBioPtr BIO
    mem ((Ptr BIO_ -> IO ()) -> IO ()) -> (Ptr BIO_ -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \ Ptr BIO_
    memPtr ->
                     Ptr BIO_ -> Ptr X509_ -> IO CInt
    _print Ptr BIO_
    memPtr Ptr X509_
    x509Ptr
                          IO CInt -> (CInt -> IO ()) -> IO ()
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (CInt -> Bool) -> CInt -> IO ()
    forall a. (a -> Bool) -> a -> IO ()
    failIf_ (CInt -> CInt -> Bool
    forall a. Eq a => a -> a -> Bool
    /= CInt
    1)
             bioRead mem

    -- |@'getVersion' cert@ returns the version number of certificate. It
    -- seems the number is 0-origin: version 2 means X.509 v3.
    getVersion :: X509 -> IO Int
    getVersion :: X509 -> IO Int
    getVersion X509
    x509
        = X509 -> (Ptr X509_ -> IO Int) -> IO Int
    forall a. X509 -> (Ptr X509_ -> IO a) -> IO a
    withX509Ptr X509
    x509 ((Ptr X509_ -> IO Int) -> IO Int)
    -> (Ptr X509_ -> IO Int) -> IO Int
    forall a b. (a -> b) -> a -> b
    $ \ Ptr X509_
    x509Ptr ->
          (CLong -> Int) -> IO CLong -> IO Int
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
    liftM CLong -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (IO CLong -> IO Int) -> IO CLong -> IO Int
    forall a b. (a -> b) -> a -> b
    $ Ptr X509_ -> IO CLong
    _get_version Ptr X509_
    x509Ptr

    -- |@'setVersion' cert ver@ updates the version number of certificate.
    setVersion :: X509 -> Int -> IO ()
    setVersion :: X509 -> Int -> IO ()
    setVersion X509
    x509 Int
    ver
        = X509 -> (Ptr X509_ -> IO ()) -> IO ()
    forall a. X509 -> (Ptr X509_ -> IO a) -> IO a
    withX509Ptr X509
    x509 ((Ptr X509_ -> IO ()) -> IO ()) -> (Ptr X509_ -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \ Ptr X509_
    x509Ptr ->
          Ptr X509_ -> CLong -> IO CInt
    _set_version Ptr X509_
    x509Ptr (Int -> CLong
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    ver)
               IO CInt -> (CInt -> IO CInt) -> IO CInt
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (CInt -> Bool) -> CInt -> IO CInt
    forall a. (a -> Bool) -> a -> IO a
    failIf (CInt -> CInt -> Bool
    forall a. Eq a => a -> a -> Bool
    /= CInt
    1)
               IO CInt -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >>  () -> IO ()
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

    -- |@'getSerialNumber' cert@ returns the serial number of certificate.
    getSerialNumber :: X509 -> IO Integer
    getSerialNumber :: X509 -> IO Integer
    getSerialNumber X509
    x509
        = X509 -> (Ptr X509_ -> IO Integer) -> IO Integer
    forall a. X509 -> (Ptr X509_ -> IO a) -> IO a
    withX509Ptr X509
    x509 ((Ptr X509_ -> IO Integer) -> IO Integer)
    -> (Ptr X509_ -> IO Integer) -> IO Integer
    forall a b. (a -> b) -> a -> b
    $ \ Ptr X509_
    x509Ptr ->
          Ptr X509_ -> IO (Ptr ASN1_INTEGER)
    _get_serialNumber Ptr X509_
    x509Ptr
               IO (Ptr ASN1_INTEGER)
    -> (Ptr ASN1_INTEGER -> IO Integer) -> IO Integer
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Ptr ASN1_INTEGER -> IO Integer
    peekASN1Integer

    -- |@'setSerialNumber' cert num@ updates the serial number of
    -- certificate.
    setSerialNumber :: X509 -> Integer -> IO ()
    setSerialNumber :: X509 -> Integer -> IO ()
    setSerialNumber X509
    x509 Integer
    serial
        = X509 -> (Ptr X509_ -> IO ()) -> IO ()
    forall a. X509 -> (Ptr X509_ -> IO a) -> IO a
    withX509Ptr X509
    x509 ((Ptr X509_ -> IO ()) -> IO ()) -> (Ptr X509_ -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \ Ptr X509_
    x509Ptr ->
          Integer -> (Ptr ASN1_INTEGER -> IO ()) -> IO ()
    forall a. Integer -> (Ptr ASN1_INTEGER -> IO a) -> IO a
    withASN1Integer Integer
    serial ((Ptr ASN1_INTEGER -> IO ()) -> IO ())
    -> (Ptr ASN1_INTEGER -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \ Ptr ASN1_INTEGER
    serialPtr ->
          Ptr X509_ -> Ptr ASN1_INTEGER -> IO CInt
    _set_serialNumber Ptr X509_
    x509Ptr Ptr ASN1_INTEGER
    serialPtr
               IO CInt -> (CInt -> IO CInt) -> IO CInt
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (CInt -> Bool) -> CInt -> IO CInt
    forall a. (a -> Bool) -> a -> IO a
    failIf (CInt -> CInt -> Bool
    forall a. Eq a => a -> a -> Bool
    /= CInt
    1)
               IO CInt -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >>  () -> IO ()
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

    -- |@'getIssuerName'@ returns the issuer name of certificate.
    getIssuerName :: X509 -- ^ The certificate to examine.
                  -> Bool -- ^ @True@ if you want the keys of each parts
                          --   to be of long form (e.g. \"commonName\"),
                          --   or @False@ if you don't (e.g. \"CN\").
                  -> IO [(String, String)] -- ^ Pairs of key and value,
                                           -- for example \[(\"C\",
                                           -- \"JP\"), (\"ST\",
                                           -- \"Some-State\"), ...\].
    getIssuerName :: X509 -> Bool -> IO [(String, String)]
    getIssuerName X509
    x509 Bool
    wantLongName
        = X509
    -> (Ptr X509_ -> IO [(String, String)]) -> IO [(String, String)]
    forall a. X509 -> (Ptr X509_ -> IO a) -> IO a
    withX509Ptr X509
    x509 ((Ptr X509_ -> IO [(String, String)]) -> IO [(String, String)])
    -> (Ptr X509_ -> IO [(String, String)]) -> IO [(String, String)]
    forall a b. (a -> b) -> a -> b
    $ \ Ptr X509_
    x509Ptr ->
          do namePtr <- Ptr X509_ -> IO (Ptr X509_NAME)
    _get_issuer_name Ptr X509_
    x509Ptr
             peekX509Name namePtr wantLongName

    -- |@'setIssuerName' cert name@ updates the issuer name of
    -- certificate. Keys of each parts may be of either long form or short
    -- form. See 'getIssuerName'.
    setIssuerName :: X509 -> [(String, String)] -> IO ()
    setIssuerName :: X509 -> [(String, String)] -> IO ()
    setIssuerName X509
    x509 [(String, String)]
    issuer
        = X509 -> (Ptr X509_ -> IO ()) -> IO ()
    forall a. X509 -> (Ptr X509_ -> IO a) -> IO a
    withX509Ptr X509
    x509 ((Ptr X509_ -> IO ()) -> IO ()) -> (Ptr X509_ -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \ Ptr X509_
    x509Ptr ->
          [(String, String)] -> (Ptr X509_NAME -> IO ()) -> IO ()
    forall a. [(String, String)] -> (Ptr X509_NAME -> IO a) -> IO a
    withX509Name [(String, String)]
    issuer ((Ptr X509_NAME -> IO ()) -> IO ())
    -> (Ptr X509_NAME -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \ Ptr X509_NAME
    namePtr ->
          Ptr X509_ -> Ptr X509_NAME -> IO CInt
    _set_issuer_name Ptr X509_
    x509Ptr Ptr X509_NAME
    namePtr
               IO CInt -> (CInt -> IO CInt) -> IO CInt
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (CInt -> Bool) -> CInt -> IO CInt
    forall a. (a -> Bool) -> a -> IO a
    failIf (CInt -> CInt -> Bool
    forall a. Eq a => a -> a -> Bool
    /= CInt
    1)
               IO CInt -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >>  () -> IO ()
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

    -- |@'getSubjectName' cert wantLongName@ returns the subject name of
    -- certificate. See 'getIssuerName'.
    getSubjectName :: X509 -> Bool -> IO [(String, String)]
    getSubjectName :: X509 -> Bool -> IO [(String, String)]
    getSubjectName X509
    x509 Bool
    wantLongName
        = X509
    -> (Ptr X509_ -> IO [(String, String)]) -> IO [(String, String)]
    forall a. X509 -> (Ptr X509_ -> IO a) -> IO a
    withX509Ptr X509
    x509 ((Ptr X509_ -> IO [(String, String)]) -> IO [(String, String)])
    -> (Ptr X509_ -> IO [(String, String)]) -> IO [(String, String)]
    forall a b. (a -> b) -> a -> b
    $ \ Ptr X509_
    x509Ptr ->
          do namePtr <- Ptr X509_ -> IO (Ptr X509_NAME)
    _get_subject_name Ptr X509_
    x509Ptr
             peekX509Name namePtr wantLongName

    -- |@'setSubjectName' cert name@ updates the subject name of
    -- certificate. See 'setIssuerName'.
    setSubjectName :: X509 -> [(String, String)] -> IO ()
    setSubjectName :: X509 -> [(String, String)] -> IO ()
    setSubjectName X509
    x509 [(String, String)]
    subject
        = X509 -> (Ptr X509_ -> IO ()) -> IO ()
    forall a. X509 -> (Ptr X509_ -> IO a) -> IO a
    withX509Ptr X509
    x509 ((Ptr X509_ -> IO ()) -> IO ()) -> (Ptr X509_ -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \ Ptr X509_
    x509Ptr ->
          [(String, String)] -> (Ptr X509_NAME -> IO ()) -> IO ()
    forall a. [(String, String)] -> (Ptr X509_NAME -> IO a) -> IO a
    withX509Name [(String, String)]
    subject ((Ptr X509_NAME -> IO ()) -> IO ())
    -> (Ptr X509_NAME -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \ Ptr X509_NAME
    namePtr ->
          Ptr X509_ -> Ptr X509_NAME -> IO CInt
    _set_subject_name Ptr X509_
    x509Ptr Ptr X509_NAME
    namePtr
               IO CInt -> (CInt -> IO CInt) -> IO CInt
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (CInt -> Bool) -> CInt -> IO CInt
    forall a. (a -> Bool) -> a -> IO a
    failIf (CInt -> CInt -> Bool
    forall a. Eq a => a -> a -> Bool
    /= CInt
    1)
               IO CInt -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >>  () -> IO ()
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

    -- |@'getNotBefore' cert@ returns the time when the certificate begins
    -- to be valid.
    getNotBefore :: X509 -> IO UTCTime
    getNotBefore :: X509 -> IO UTCTime
    getNotBefore X509
    x509
        = X509 -> (Ptr X509_ -> IO UTCTime) -> IO UTCTime
    forall a. X509 -> (Ptr X509_ -> IO a) -> IO a
    withX509Ptr X509
    x509 ((Ptr X509_ -> IO UTCTime) -> IO UTCTime)
    -> (Ptr X509_ -> IO UTCTime) -> IO UTCTime
    forall a b. (a -> b) -> a -> b
    $ \ Ptr X509_
    x509Ptr ->
          Ptr X509_ -> IO (Ptr ASN1_TIME)
    _get_notBefore Ptr X509_
    x509Ptr
               IO (Ptr ASN1_TIME) -> (Ptr ASN1_TIME -> IO UTCTime) -> IO UTCTime
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Ptr ASN1_TIME -> IO UTCTime
    peekASN1Time

    -- |@'setNotBefore' cert utc@ updates the time when the certificate
    -- begins to be valid.
    setNotBefore :: X509 -> UTCTime -> IO ()
    setNotBefore :: X509 -> UTCTime -> IO ()
    setNotBefore X509
    x509 UTCTime
    utc
        = X509 -> (Ptr X509_ -> IO ()) -> IO ()
    forall a. X509 -> (Ptr X509_ -> IO a) -> IO a
    withX509Ptr X509
    x509 ((Ptr X509_ -> IO ()) -> IO ()) -> (Ptr X509_ -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \ Ptr X509_
    x509Ptr ->
          UTCTime -> (Ptr ASN1_TIME -> IO ()) -> IO ()
    forall a. UTCTime -> (Ptr ASN1_TIME -> IO a) -> IO a
    withASN1Time UTCTime
    utc ((Ptr ASN1_TIME -> IO ()) -> IO ())
    -> (Ptr ASN1_TIME -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \ Ptr ASN1_TIME
    time ->
          Ptr X509_ -> Ptr ASN1_TIME -> IO CInt
    _set_notBefore Ptr X509_
    x509Ptr Ptr ASN1_TIME
    time
               IO CInt -> (CInt -> IO CInt) -> IO CInt
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (CInt -> Bool) -> CInt -> IO CInt
    forall a. (a -> Bool) -> a -> IO a
    failIf (CInt -> CInt -> Bool
    forall a. Eq a => a -> a -> Bool
    /= CInt
    1)
               IO CInt -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >>  () -> IO ()
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

    -- |@'getNotAfter' cert@ returns the time when the certificate
    -- expires.
    getNotAfter :: X509 -> IO UTCTime
    getNotAfter :: X509 -> IO UTCTime
    getNotAfter X509
    x509
        = X509 -> (Ptr X509_ -> IO UTCTime) -> IO UTCTime
    forall a. X509 -> (Ptr X509_ -> IO a) -> IO a
    withX509Ptr X509
    x509 ((Ptr X509_ -> IO UTCTime) -> IO UTCTime)
    -> (Ptr X509_ -> IO UTCTime) -> IO UTCTime
    forall a b. (a -> b) -> a -> b
    $ \ Ptr X509_
    x509Ptr ->
          Ptr X509_ -> IO (Ptr ASN1_TIME)
    _get_notAfter Ptr X509_
    x509Ptr
               IO (Ptr ASN1_TIME) -> (Ptr ASN1_TIME -> IO UTCTime) -> IO UTCTime
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Ptr ASN1_TIME -> IO UTCTime
    peekASN1Time

    -- |@'setNotAfter' cert utc@ updates the time when the certificate
    -- expires.
    setNotAfter :: X509 -> UTCTime -> IO ()
    setNotAfter :: X509 -> UTCTime -> IO ()
    setNotAfter X509
    x509 UTCTime
    utc
        = X509 -> (Ptr X509_ -> IO ()) -> IO ()
    forall a. X509 -> (Ptr X509_ -> IO a) -> IO a
    withX509Ptr X509
    x509 ((Ptr X509_ -> IO ()) -> IO ()) -> (Ptr X509_ -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \ Ptr X509_
    x509Ptr ->
          UTCTime -> (Ptr ASN1_TIME -> IO ()) -> IO ()
    forall a. UTCTime -> (Ptr ASN1_TIME -> IO a) -> IO a
    withASN1Time UTCTime
    utc ((Ptr ASN1_TIME -> IO ()) -> IO ())
    -> (Ptr ASN1_TIME -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \ Ptr ASN1_TIME
    time ->
          Ptr X509_ -> Ptr ASN1_TIME -> IO CInt
    _set_notAfter Ptr X509_
    x509Ptr Ptr ASN1_TIME
    time
               IO CInt -> (CInt -> IO CInt) -> IO CInt
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (CInt -> Bool) -> CInt -> IO CInt
    forall a. (a -> Bool) -> a -> IO a
    failIf (CInt -> CInt -> Bool
    forall a. Eq a => a -> a -> Bool
    /= CInt
    1)
               IO CInt -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >>  () -> IO ()
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

    -- |@'getPublicKey' cert@ returns the public key of the subject of
    -- certificate.
    getPublicKey :: X509 -> IO SomePublicKey
    getPublicKey :: X509 -> IO SomePublicKey
    getPublicKey X509
    x509
        = X509 -> (Ptr X509_ -> IO SomePublicKey) -> IO SomePublicKey
    forall a. X509 -> (Ptr X509_ -> IO a) -> IO a
    withX509Ptr X509
    x509 ((Ptr X509_ -> IO SomePublicKey) -> IO SomePublicKey)
    -> (Ptr X509_ -> IO SomePublicKey) -> IO SomePublicKey
    forall a b. (a -> b) -> a -> b
    $ \ Ptr X509_
    x509Ptr ->
          (Maybe SomePublicKey -> SomePublicKey)
    -> IO (Maybe SomePublicKey) -> IO SomePublicKey
    forall a b. (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Maybe SomePublicKey -> SomePublicKey
    forall a. HasCallStack => Maybe a -> a
    fromJust ( Ptr X509_ -> IO (Ptr EVP_PKEY)
    _get_pubkey Ptr X509_
    x509Ptr
                          IO (Ptr EVP_PKEY)
    -> (Ptr EVP_PKEY -> IO (Ptr EVP_PKEY)) -> IO (Ptr EVP_PKEY)
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Ptr EVP_PKEY -> IO (Ptr EVP_PKEY)
    forall a. Ptr a -> IO (Ptr a)
    failIfNull
                          IO (Ptr EVP_PKEY) -> (Ptr EVP_PKEY -> IO VaguePKey) -> IO VaguePKey
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Ptr EVP_PKEY -> IO VaguePKey
    wrapPKeyPtr
                          IO VaguePKey
    -> (VaguePKey -> IO (Maybe SomePublicKey))
    -> IO (Maybe SomePublicKey)
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= VaguePKey -> IO (Maybe SomePublicKey)
    forall k. PKey k => VaguePKey -> IO (Maybe k)
    fromPKey
                        )

    -- |@'setPublicKey' cert pubkey@ updates the public key of the subject
    -- of certificate.
    setPublicKey :: PublicKey key => X509 -> key -> IO ()
    setPublicKey :: forall key. PublicKey key => X509 -> key -> IO ()
    setPublicKey X509
    x509 key
    key
        = X509 -> (Ptr X509_ -> IO ()) -> IO ()
    forall a. X509 -> (Ptr X509_ -> IO a) -> IO a
    withX509Ptr X509
    x509 ((Ptr X509_ -> IO ()) -> IO ()) -> (Ptr X509_ -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \ Ptr X509_
    x509Ptr ->
          key -> (Ptr EVP_PKEY -> IO ()) -> IO ()
    forall k a. PKey k => k -> (Ptr EVP_PKEY -> IO a) -> IO a
    withPKeyPtr' key
    key ((Ptr EVP_PKEY -> IO ()) -> IO ())
    -> (Ptr EVP_PKEY -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \ Ptr EVP_PKEY
    pkeyPtr ->
          Ptr X509_ -> Ptr EVP_PKEY -> IO CInt
    _set_pubkey Ptr X509_
    x509Ptr Ptr EVP_PKEY
    pkeyPtr
               IO CInt -> (CInt -> IO CInt) -> IO CInt
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (CInt -> Bool) -> CInt -> IO CInt
    forall a. (a -> Bool) -> a -> IO a
    failIf (CInt -> CInt -> Bool
    forall a. Eq a => a -> a -> Bool
    /= CInt
    1)
               IO CInt -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >>  () -> IO ()
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

    -- |@'getSubjectEmail' cert@ returns every subject email addresses in
    -- the certificate.
    getSubjectEmail :: X509 -> IO [String]
    getSubjectEmail :: X509 -> IO [String]
    getSubjectEmail X509
    x509
        = X509 -> (Ptr X509_ -> IO [String]) -> IO [String]
    forall a. X509 -> (Ptr X509_ -> IO a) -> IO a
    withX509Ptr X509
    x509 ((Ptr X509_ -> IO [String]) -> IO [String])
    -> (Ptr X509_ -> IO [String]) -> IO [String]
    forall a b. (a -> b) -> a -> b
    $ \ Ptr X509_
    x509Ptr ->
          do st   <- Ptr X509_ -> IO (Ptr STACK)
    _get1_email Ptr X509_
    x509Ptr
             list <- mapStack peekCString st
             _email_free st
             return list