    {-# LINE 1 "OpenSSL/ASN1.hsc" #-}
    {-# LANGUAGE CPP #-}
    {-# LANGUAGE EmptyDataDecls           #-}
    {-# LANGUAGE ForeignFunctionInterface #-}
    {-# LANGUAGE CApiFFI #-}
    module OpenSSL.ASN1
        ( ASN1_OBJECT
        , obj2nid
        , nid2sn
        , nid2ln

        , ASN1_STRING
        , peekASN1String

        , ASN1_INTEGER
        , peekASN1Integer
        , withASN1Integer

        , ASN1_TIME
        , peekASN1Time
        , withASN1Time
        )
        where

    import           Control.Exception
    import           Data.Time.Clock
    import           Data.Time.Clock.POSIX
    import           Data.Time.Format
    import           Foreign
    import           Foreign.C
    import           OpenSSL.BIO
    import           OpenSSL.BN
    import           OpenSSL.Utils

    {-# LINE 37 "OpenSSL/ASN1.hsc" #-}

    {- ASN1_OBJECT --------------------------------------------------------------- -}

    data {-# CTYPE "openssl/asn1.h" "ASN1_OBJECT" #-} ASN1_OBJECT

    foreign import capi unsafe "openssl/objects.h OBJ_obj2nid"
            obj2nid :: Ptr ASN1_OBJECT -> IO CInt

    foreign import capi unsafe "openssl/objects.h OBJ_nid2sn"
            _nid2sn :: CInt -> IO CString

    foreign import capi unsafe "openssl/objects.h OBJ_nid2ln"
            _nid2ln :: CInt -> IO CString

    nid2sn :: CInt -> IO String
    nid2sn :: CInt -> IO String
    nid2sn CInt
    nid = CInt -> IO CString
    _nid2sn CInt
    nid IO CString -> (CString -> IO String) -> IO String
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= CString -> IO String
    peekCString

    nid2ln :: CInt -> IO String
    nid2ln :: CInt -> IO String
    nid2ln CInt
    nid = CInt -> IO CString
    _nid2ln CInt
    nid IO CString -> (CString -> IO String) -> IO String
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= CString -> IO String
    peekCString

    {- ASN1_STRING --------------------------------------------------------------- -}

    data {-# CTYPE "openssl/asn1.h" "ASN1_STRING" #-} ASN1_STRING

    foreign import capi unsafe "openssl/asn1.h ASN1_STRING_get0_data"
            _ASN1_STRING_get0_data :: Ptr ASN1_STRING -> IO (Ptr CChar)

    foreign import capi unsafe "openssl/asn1.h ASN1_STRING_length"
            _ASN1_STRING_length :: Ptr ASN1_STRING -> IO CInt

    peekASN1String :: Ptr ASN1_STRING -> IO String
    peekASN1String :: Ptr ASN1_STRING -> IO String
    peekASN1String Ptr ASN1_STRING
    strPtr
        = do buf <- Ptr ASN1_STRING -> IO CString
    _ASN1_STRING_get0_data Ptr ASN1_STRING
    strPtr
             len <- _ASN1_STRING_length strPtr
             peekCStringLen (buf, fromIntegral len)

    {- ASN1_INTEGER -------------------------------------------------------------- -}

    data {-# CTYPE "openssl/asn1.h" "ASN1_INTEGER" #-} ASN1_INTEGER

    foreign import capi unsafe "HsOpenSSL.h HsOpenSSL_M_ASN1_INTEGER_new"
            _ASN1_INTEGER_new :: IO (Ptr ASN1_INTEGER)

    foreign import capi unsafe "HsOpenSSL.h HsOpenSSL_M_ASN1_INTEGER_free"
            _ASN1_INTEGER_free :: Ptr ASN1_INTEGER -> IO ()

    foreign import capi unsafe "openssl/asn1.h ASN1_INTEGER_to_BN"
            _ASN1_INTEGER_to_BN :: Ptr ASN1_INTEGER -> Ptr BIGNUM -> IO (Ptr BIGNUM)

    foreign import capi unsafe "openssl/asn1.h BN_to_ASN1_INTEGER"
            _BN_to_ASN1_INTEGER :: Ptr BIGNUM -> Ptr ASN1_INTEGER -> IO (Ptr ASN1_INTEGER)

    peekASN1Integer :: Ptr ASN1_INTEGER -> IO Integer
    peekASN1Integer :: Ptr ASN1_INTEGER -> IO Integer
    peekASN1Integer Ptr ASN1_INTEGER
    intPtr
        = (BigNum -> IO Integer) -> IO Integer
    forall a. (BigNum -> IO a) -> IO a
    allocaBN ((BigNum -> IO Integer) -> IO Integer)
    -> (BigNum -> IO Integer) -> IO Integer
    forall a b. (a -> b) -> a -> b
    $ \ BigNum
    bn ->
          do Ptr ASN1_INTEGER -> Ptr BIGNUM -> IO (Ptr BIGNUM)
    _ASN1_INTEGER_to_BN Ptr ASN1_INTEGER
    intPtr (BigNum -> Ptr BIGNUM
    unwrapBN BigNum
    bn)
                  IO (Ptr BIGNUM) -> (Ptr BIGNUM -> 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
    >>= Ptr BIGNUM -> IO ()
    forall a. Ptr a -> IO ()
    failIfNull_
             BigNum -> IO Integer
    peekBN BigNum
    bn

    allocaASN1Integer :: (Ptr ASN1_INTEGER -> IO a) -> IO a
    allocaASN1Integer :: forall a. (Ptr ASN1_INTEGER -> IO a) -> IO a
    allocaASN1Integer
        = IO (Ptr ASN1_INTEGER)
    -> (Ptr ASN1_INTEGER -> IO ())
    -> (Ptr ASN1_INTEGER -> IO a)
    -> IO a
    forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
    bracket IO (Ptr ASN1_INTEGER)
    _ASN1_INTEGER_new Ptr ASN1_INTEGER -> IO ()
    _ASN1_INTEGER_free

    withASN1Integer :: Integer -> (Ptr ASN1_INTEGER -> IO a) -> IO a
    withASN1Integer :: forall a. Integer -> (Ptr ASN1_INTEGER -> IO a) -> IO a
    withASN1Integer Integer
    int Ptr ASN1_INTEGER -> IO a
    m
        = Integer -> (BigNum -> IO a) -> IO a
    forall a. Integer -> (BigNum -> IO a) -> IO a
    withBN Integer
    int ((BigNum -> IO a) -> IO a) -> (BigNum -> IO a) -> IO a
    forall a b. (a -> b) -> a -> b
    $ \ BigNum
    bn ->
          (Ptr ASN1_INTEGER -> IO a) -> IO a
    forall a. (Ptr ASN1_INTEGER -> IO a) -> IO a
    allocaASN1Integer ((Ptr ASN1_INTEGER -> IO a) -> IO a)
    -> (Ptr ASN1_INTEGER -> IO a) -> IO a
    forall a b. (a -> b) -> a -> b
    $ \ Ptr ASN1_INTEGER
    intPtr ->
          do Ptr BIGNUM -> Ptr ASN1_INTEGER -> IO (Ptr ASN1_INTEGER)
    _BN_to_ASN1_INTEGER (BigNum -> Ptr BIGNUM
    unwrapBN BigNum
    bn) Ptr ASN1_INTEGER
    intPtr
                  IO (Ptr ASN1_INTEGER) -> (Ptr ASN1_INTEGER -> 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
    >>= Ptr ASN1_INTEGER -> IO ()
    forall a. Ptr a -> IO ()
    failIfNull_
             Ptr ASN1_INTEGER -> IO a
    m Ptr ASN1_INTEGER
    intPtr

    {- ASN1_TIME ---------------------------------------------------------------- -}

    data {-# CTYPE "openssl/asn1.h" "ASN1_TIME" #-} ASN1_TIME

    foreign import capi unsafe "HsOpenSSL.h HsOpenSSL_M_ASN1_TIME_new"
            _ASN1_TIME_new :: IO (Ptr ASN1_TIME)

    foreign import capi unsafe "HsOpenSSL.h HsOpenSSL_M_ASN1_TIME_free"
            _ASN1_TIME_free :: Ptr ASN1_TIME -> IO ()

    foreign import capi unsafe "openssl/asn1.h ASN1_TIME_set"
            _ASN1_TIME_set :: Ptr ASN1_TIME -> CTime -> IO (Ptr ASN1_TIME)

    foreign import capi unsafe "openssl/asn1.h ASN1_TIME_print"
            _ASN1_TIME_print :: Ptr BIO_ -> Ptr ASN1_TIME -> IO CInt

    peekASN1Time :: Ptr ASN1_TIME -> IO UTCTime -- asn1/t_x509.c
    peekASN1Time :: Ptr ASN1_TIME -> IO UTCTime
    peekASN1Time Ptr ASN1_TIME
    time
        = do bio <- IO BIO
    newMem
             withBioPtr bio $ \ Ptr BIO_
    bioPtr ->
                 Ptr BIO_ -> Ptr ASN1_TIME -> IO CInt
    _ASN1_TIME_print Ptr BIO_
    bioPtr Ptr ASN1_TIME
    time
                      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)
             timeStr <- bioRead bio

    {-# LINE 141 "OpenSSL/ASN1.hsc" #-}
             case parseTimeM True defaultTimeLocale "%b %e %H:%M:%S %Y %Z" timeStr of

    {-# LINE 145 "OpenSSL/ASN1.hsc" #-}
               Just UTCTime
    utc -> UTCTime -> IO UTCTime
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return UTCTime
    utc
               Maybe UTCTime
    Nothing  -> String -> IO UTCTime
    forall a. String -> IO a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail (String
    "peekASN1Time: failed to parse time string: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    timeStr)

    allocaASN1Time :: (Ptr ASN1_TIME -> IO a) -> IO a
    allocaASN1Time :: forall a. (Ptr ASN1_TIME -> IO a) -> IO a
    allocaASN1Time
        = IO (Ptr ASN1_TIME)
    -> (Ptr ASN1_TIME -> IO ()) -> (Ptr ASN1_TIME -> IO a) -> IO a
    forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
    bracket IO (Ptr ASN1_TIME)
    _ASN1_TIME_new Ptr ASN1_TIME -> IO ()
    _ASN1_TIME_free

    withASN1Time :: UTCTime -> (Ptr ASN1_TIME -> IO a) -> IO a
    withASN1Time :: forall a. UTCTime -> (Ptr ASN1_TIME -> IO a) -> IO a
    withASN1Time UTCTime
    utc Ptr ASN1_TIME -> IO a
    m
        = (Ptr ASN1_TIME -> IO a) -> IO a
    forall a. (Ptr ASN1_TIME -> IO a) -> IO a
    allocaASN1Time ((Ptr ASN1_TIME -> IO a) -> IO a)
    -> (Ptr ASN1_TIME -> IO a) -> IO a
    forall a b. (a -> b) -> a -> b
    $ \ Ptr ASN1_TIME
    time ->
          do Ptr ASN1_TIME -> CTime -> IO (Ptr ASN1_TIME)
    _ASN1_TIME_set Ptr ASN1_TIME
    time (Integer -> CTime
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (POSIXTime -> Integer
    forall b. Integral b => POSIXTime -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    round (POSIXTime -> Integer) -> POSIXTime -> Integer
    forall a b. (a -> b) -> a -> b
    $ UTCTime -> POSIXTime
    utcTimeToPOSIXSeconds UTCTime
    utc :: Integer))
                  IO (Ptr ASN1_TIME) -> (Ptr ASN1_TIME -> 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
    >>= Ptr ASN1_TIME -> IO ()
    forall a. Ptr a -> IO ()
    failIfNull_
             Ptr ASN1_TIME -> IO a
    m Ptr ASN1_TIME
    time