{-# LINE 1 "OpenSSL/EVP/Internal.hsc" #-}
{-# LANGUAGE EmptyDataDecls           #-}
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE CApiFFI                  #-}
module OpenSSL.EVP.Internal (
    Cipher(..),
    EVP_CIPHER,
    withCipherPtr,

    cipherIvLength,

    CipherCtx(..),
    EVP_CIPHER_CTX,
    newCipherCtx,
    withCipherCtxPtr,
    withNewCipherCtxPtr,

    CryptoMode(..),
    cipherSetPadding,
    cipherInitBS,
    cipherUpdateBS,
    cipherFinalBS,
    cipherStrictly,
    cipherLazily,

    Digest(..),
    EVP_MD,
    withMDPtr,

    DigestCtx(..),
    EVP_MD_CTX,
    withDigestCtxPtr,

    digestUpdateBS,
    digestFinalBS,
    digestFinal,
    digestStrictly,
    digestLazily,

    HmacCtx(..),
    HMAC_CTX,
    withHmacCtxPtr,

    hmacUpdateBS,
    hmacFinalBS,
    hmacLazily,

    VaguePKey(..),
    EVP_PKEY,
    PKey(..),
    createPKey,
    wrapPKeyPtr,
    withPKeyPtr,
    withPKeyPtr',
    unsafePKeyToPtr,
    touchPKey
  ) where



import qualified Data.ByteString.Internal as B8
import qualified Data.ByteString.Unsafe as B8
import qualified Data.ByteString.Char8 as B8
import qualified Data.ByteString.Lazy.Char8 as L8
import qualified Data.ByteString.Lazy.Internal as L8

{-# LINE 68 "OpenSSL/EVP/Internal.hsc" #-}
import Control.Exception (mask, mask_, bracket, onException)
import Foreign.C.Types (CChar)

{-# LINE 71 "OpenSSL/EVP/Internal.hsc" #-}
import Foreign.C.Types (CInt(..), CUInt(..), CSize(..))

{-# LINE 75 "OpenSSL/EVP/Internal.hsc" #-}
import Foreign.Ptr (Ptr, castPtr, FunPtr)
import Foreign.C.String (CString, peekCStringLen)
import Foreign.ForeignPtr

{-# LINE 79 "OpenSSL/EVP/Internal.hsc" #-}
import Foreign.ForeignPtr.Unsafe as Unsafe

{-# LINE 83 "OpenSSL/EVP/Internal.hsc" #-}
import Foreign.Storable (Storable(..))
import Foreign.Marshal.Alloc (alloca)
import Foreign.Marshal.Array (allocaArray)
import System.IO.Unsafe (unsafeInterleaveIO)
import OpenSSL.Utils


{- EVP_CIPHER ---------------------------------------------------------------- -}

-- |@Cipher@ is an opaque object that represents an algorithm of
-- symmetric cipher.
newtype Cipher     = Cipher (Ptr EVP_CIPHER)
data {-# CTYPE "openssl/evp.h" "EVP_CIPHER" #-} EVP_CIPHER

withCipherPtr :: Cipher -> (Ptr EVP_CIPHER -> IO a) -> IO a
withCipherPtr :: forall a. Cipher -> (Ptr EVP_CIPHER -> IO a) -> IO a
withCipherPtr (Cipher Ptr EVP_CIPHER
cipherPtr) Ptr EVP_CIPHER -> IO a
f = Ptr EVP_CIPHER -> IO a
f Ptr EVP_CIPHER
cipherPtr

foreign import capi unsafe "HsOpenSSL.h HsOpenSSL_EVP_CIPHER_iv_length"
        _iv_length :: Ptr EVP_CIPHER -> CInt

cipherIvLength :: Cipher -> Int
cipherIvLength :: Cipher -> Int
cipherIvLength (Cipher Ptr EVP_CIPHER
cipherPtr) = CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CInt -> Int) -> CInt -> Int
forall a b. (a -> b) -> a -> b
$ Ptr EVP_CIPHER -> CInt
_iv_length Ptr EVP_CIPHER
cipherPtr

{- EVP_CIPHER_CTX ------------------------------------------------------------ -}

newtype CipherCtx      = CipherCtx (ForeignPtr EVP_CIPHER_CTX)
data {-# CTYPE "openssl/evp.h" "EVP_CIPHER_CTX" #-} EVP_CIPHER_CTX

foreign import capi unsafe "openssl/evp.h EVP_CIPHER_CTX_new"
  _cipher_ctx_new :: IO (Ptr EVP_CIPHER_CTX)


{-# LINE 115 "OpenSSL/EVP/Internal.hsc" #-}
foreign import capi unsafe "openssl/evp.h EVP_CIPHER_CTX_reset"
  _cipher_ctx_reset :: Ptr EVP_CIPHER_CTX -> IO ()

{-# LINE 121 "OpenSSL/EVP/Internal.hsc" #-}

foreign import capi unsafe "openssl/evp.h &EVP_CIPHER_CTX_free"
  _cipher_ctx_free :: FunPtr (Ptr EVP_CIPHER_CTX -> IO ())

foreign import capi unsafe "openssl/evp.h EVP_CIPHER_CTX_free"
  _cipher_ctx_free' :: Ptr EVP_CIPHER_CTX -> IO ()

foreign import capi unsafe "HsOpenSSL.h HsOpenSSL_EVP_CIPHER_CTX_block_size"
  _cipher_ctx_block_size :: Ptr EVP_CIPHER_CTX -> CInt

newCipherCtx :: IO CipherCtx
newCipherCtx :: IO CipherCtx
newCipherCtx = IO CipherCtx -> IO CipherCtx
forall a. IO a -> IO a
mask_ (IO CipherCtx -> IO CipherCtx) -> IO CipherCtx -> IO CipherCtx
forall a b. (a -> b) -> a -> b
$ do
  ForeignPtr EVP_CIPHER_CTX
ctx <- FinalizerPtr EVP_CIPHER_CTX
-> Ptr EVP_CIPHER_CTX -> IO (ForeignPtr EVP_CIPHER_CTX)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr EVP_CIPHER_CTX
_cipher_ctx_free (Ptr EVP_CIPHER_CTX -> IO (ForeignPtr EVP_CIPHER_CTX))
-> IO (Ptr EVP_CIPHER_CTX) -> IO (ForeignPtr EVP_CIPHER_CTX)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr EVP_CIPHER_CTX -> IO (Ptr EVP_CIPHER_CTX)
forall a. Ptr a -> IO (Ptr a)
failIfNull (Ptr EVP_CIPHER_CTX -> IO (Ptr EVP_CIPHER_CTX))
-> IO (Ptr EVP_CIPHER_CTX) -> IO (Ptr EVP_CIPHER_CTX)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IO (Ptr EVP_CIPHER_CTX)
_cipher_ctx_new
  ForeignPtr EVP_CIPHER_CTX -> (Ptr EVP_CIPHER_CTX -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr EVP_CIPHER_CTX
ctx Ptr EVP_CIPHER_CTX -> IO ()
_cipher_ctx_reset
  CipherCtx -> IO CipherCtx
forall (m :: * -> *) a. Monad m => a -> m a
return (CipherCtx -> IO CipherCtx) -> CipherCtx -> IO CipherCtx
forall a b. (a -> b) -> a -> b
$ ForeignPtr EVP_CIPHER_CTX -> CipherCtx
CipherCtx ForeignPtr EVP_CIPHER_CTX
ctx

withCipherCtxPtr :: CipherCtx -> (Ptr EVP_CIPHER_CTX -> IO a) -> IO a
withCipherCtxPtr :: forall a. CipherCtx -> (Ptr EVP_CIPHER_CTX -> IO a) -> IO a
withCipherCtxPtr (CipherCtx ForeignPtr EVP_CIPHER_CTX
ctx) = ForeignPtr EVP_CIPHER_CTX -> (Ptr EVP_CIPHER_CTX -> IO a) -> IO a
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr EVP_CIPHER_CTX
ctx

withNewCipherCtxPtr :: (Ptr EVP_CIPHER_CTX -> IO a) -> IO a
withNewCipherCtxPtr :: forall a. (Ptr EVP_CIPHER_CTX -> IO a) -> IO a
withNewCipherCtxPtr Ptr EVP_CIPHER_CTX -> IO a
f =
  IO (Ptr EVP_CIPHER_CTX)
-> (Ptr EVP_CIPHER_CTX -> IO ())
-> (Ptr EVP_CIPHER_CTX -> IO a)
-> IO a
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket (Ptr EVP_CIPHER_CTX -> IO (Ptr EVP_CIPHER_CTX)
forall a. Ptr a -> IO (Ptr a)
failIfNull (Ptr EVP_CIPHER_CTX -> IO (Ptr EVP_CIPHER_CTX))
-> IO (Ptr EVP_CIPHER_CTX) -> IO (Ptr EVP_CIPHER_CTX)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IO (Ptr EVP_CIPHER_CTX)
_cipher_ctx_new) Ptr EVP_CIPHER_CTX -> IO ()
_cipher_ctx_free' ((Ptr EVP_CIPHER_CTX -> IO a) -> IO a)
-> (Ptr EVP_CIPHER_CTX -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \ Ptr EVP_CIPHER_CTX
p -> do
    Ptr EVP_CIPHER_CTX -> IO ()
_cipher_ctx_reset Ptr EVP_CIPHER_CTX
p
    Ptr EVP_CIPHER_CTX -> IO a
f Ptr EVP_CIPHER_CTX
p

{- encrypt/decrypt ----------------------------------------------------------- -}

-- |@CryptoMode@ represents instruction to 'cipher' and such like.
data CryptoMode = Encrypt | Decrypt

fromCryptoMode :: Num a => CryptoMode -> a
fromCryptoMode :: forall a. Num a => CryptoMode -> a
fromCryptoMode CryptoMode
Encrypt = a
1
fromCryptoMode CryptoMode
Decrypt = a
0

foreign import capi unsafe "openssl/evp.h EVP_CIPHER_CTX_set_padding"
  _SetPadding :: Ptr EVP_CIPHER_CTX -> CInt -> IO CInt

cipherSetPadding :: CipherCtx -> Int -> IO CipherCtx
cipherSetPadding :: CipherCtx -> Int -> IO CipherCtx
cipherSetPadding CipherCtx
ctx Int
pad
  = do CipherCtx -> (Ptr EVP_CIPHER_CTX -> IO ()) -> IO ()
forall a. CipherCtx -> (Ptr EVP_CIPHER_CTX -> IO a) -> IO a
withCipherCtxPtr CipherCtx
ctx ((Ptr EVP_CIPHER_CTX -> IO ()) -> IO ())
-> (Ptr EVP_CIPHER_CTX -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr EVP_CIPHER_CTX
ctxPtr ->
           Ptr EVP_CIPHER_CTX -> CInt -> IO CInt
_SetPadding Ptr EVP_CIPHER_CTX
ctxPtr (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
pad)
               IO CInt -> (CInt -> IO ()) -> IO ()
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)
       CipherCtx -> IO CipherCtx
forall (m :: * -> *) a. Monad m => a -> m a
return CipherCtx
ctx

foreign import capi unsafe "openssl/evp.h EVP_CipherInit"
        _CipherInit :: Ptr EVP_CIPHER_CTX
                    -> Ptr EVP_CIPHER
                    -> CString
                    -> CString
                    -> CInt
                    -> IO CInt

cipherInitBS :: Cipher
             -> B8.ByteString -- ^ key
             -> B8.ByteString -- ^ IV
             -> CryptoMode
             -> IO CipherCtx
cipherInitBS :: Cipher -> ByteString -> ByteString -> CryptoMode -> IO CipherCtx
cipherInitBS (Cipher Ptr EVP_CIPHER
c) ByteString
key ByteString
iv CryptoMode
mode
    = do CipherCtx
ctx <- IO CipherCtx
newCipherCtx
         CipherCtx -> (Ptr EVP_CIPHER_CTX -> IO ()) -> IO ()
forall a. CipherCtx -> (Ptr EVP_CIPHER_CTX -> IO a) -> IO a
withCipherCtxPtr CipherCtx
ctx ((Ptr EVP_CIPHER_CTX -> IO ()) -> IO ())
-> (Ptr EVP_CIPHER_CTX -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ Ptr EVP_CIPHER_CTX
ctxPtr ->
             ByteString -> (CString -> IO ()) -> IO ()
forall a. ByteString -> (CString -> IO a) -> IO a
B8.unsafeUseAsCString ByteString
key ((CString -> IO ()) -> IO ()) -> (CString -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ CString
keyPtr ->
                 ByteString -> (CString -> IO ()) -> IO ()
forall a. ByteString -> (CString -> IO a) -> IO a
B8.unsafeUseAsCString ByteString
iv ((CString -> IO ()) -> IO ()) -> (CString -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ CString
ivPtr ->
                     Ptr EVP_CIPHER_CTX
-> Ptr EVP_CIPHER -> CString -> CString -> CInt -> IO CInt
_CipherInit Ptr EVP_CIPHER_CTX
ctxPtr Ptr EVP_CIPHER
c CString
keyPtr CString
ivPtr (CryptoMode -> CInt
forall a. Num a => CryptoMode -> a
fromCryptoMode CryptoMode
mode)
                          IO CInt -> (CInt -> IO ()) -> IO ()
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)
         CipherCtx -> IO CipherCtx
forall (m :: * -> *) a. Monad m => a -> m a
return CipherCtx
ctx

foreign import capi unsafe "openssl/evp.h EVP_CipherUpdate"
  _CipherUpdate :: Ptr EVP_CIPHER_CTX -> Ptr CChar -> Ptr CInt
                -> Ptr CChar -> CInt -> IO CInt

cipherUpdateBS :: CipherCtx -> B8.ByteString -> IO B8.ByteString
cipherUpdateBS :: CipherCtx -> ByteString -> IO ByteString
cipherUpdateBS CipherCtx
ctx ByteString
inBS =
  CipherCtx -> (Ptr EVP_CIPHER_CTX -> IO ByteString) -> IO ByteString
forall a. CipherCtx -> (Ptr EVP_CIPHER_CTX -> IO a) -> IO a
withCipherCtxPtr CipherCtx
ctx ((Ptr EVP_CIPHER_CTX -> IO ByteString) -> IO ByteString)
-> (Ptr EVP_CIPHER_CTX -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr EVP_CIPHER_CTX
ctxPtr ->
    ByteString -> (CStringLen -> IO ByteString) -> IO ByteString
forall a. ByteString -> (CStringLen -> IO a) -> IO a
B8.unsafeUseAsCStringLen ByteString
inBS ((CStringLen -> IO ByteString) -> IO ByteString)
-> (CStringLen -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \(CString
inBuf, Int
inLen) ->
      let len :: Int
len = Int
inLen Int -> Int -> Int
forall a. Num a => a -> a -> a
+ CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Ptr EVP_CIPHER_CTX -> CInt
_cipher_ctx_block_size Ptr EVP_CIPHER_CTX
ctxPtr) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1 in
        Int -> (Ptr Word8 -> IO Int) -> IO ByteString
B8.createAndTrim Int
len ((Ptr Word8 -> IO Int) -> IO ByteString)
-> (Ptr Word8 -> IO Int) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
outBuf ->
          (Ptr CInt -> IO Int) -> IO Int
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CInt -> IO Int) -> IO Int) -> (Ptr CInt -> IO Int) -> IO Int
forall a b. (a -> b) -> a -> b
$ \Ptr CInt
outLenPtr ->
            Ptr EVP_CIPHER_CTX
-> CString -> Ptr CInt -> CString -> CInt -> IO CInt
_CipherUpdate Ptr EVP_CIPHER_CTX
ctxPtr (Ptr Word8 -> CString
forall a b. Ptr a -> Ptr b
castPtr Ptr Word8
outBuf) Ptr CInt
outLenPtr CString
inBuf
                          (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
inLen)
              IO CInt -> (CInt -> IO CInt) -> IO CInt
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 Int -> IO Int
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>  CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CInt -> Int) -> IO CInt -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CInt -> IO CInt
forall a. Storable a => Ptr a -> IO a
peek Ptr CInt
outLenPtr

foreign import capi unsafe "openssl/evp.h EVP_CipherFinal"
  _CipherFinal :: Ptr EVP_CIPHER_CTX -> Ptr CChar -> Ptr CInt -> IO CInt

cipherFinalBS :: CipherCtx -> IO B8.ByteString
cipherFinalBS :: CipherCtx -> IO ByteString
cipherFinalBS CipherCtx
ctx =
  CipherCtx -> (Ptr EVP_CIPHER_CTX -> IO ByteString) -> IO ByteString
forall a. CipherCtx -> (Ptr EVP_CIPHER_CTX -> IO a) -> IO a
withCipherCtxPtr CipherCtx
ctx ((Ptr EVP_CIPHER_CTX -> IO ByteString) -> IO ByteString)
-> (Ptr EVP_CIPHER_CTX -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr EVP_CIPHER_CTX
ctxPtr ->
    let len :: Int
len = CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CInt -> Int) -> CInt -> Int
forall a b. (a -> b) -> a -> b
$ Ptr EVP_CIPHER_CTX -> CInt
_cipher_ctx_block_size Ptr EVP_CIPHER_CTX
ctxPtr in
      Int -> (Ptr Word8 -> IO Int) -> IO ByteString
B8.createAndTrim Int
len ((Ptr Word8 -> IO Int) -> IO ByteString)
-> (Ptr Word8 -> IO Int) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
outBuf ->
        (Ptr CInt -> IO Int) -> IO Int
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CInt -> IO Int) -> IO Int) -> (Ptr CInt -> IO Int) -> IO Int
forall a b. (a -> b) -> a -> b
$ \Ptr CInt
outLenPtr ->
          Ptr EVP_CIPHER_CTX -> CString -> Ptr CInt -> IO CInt
_CipherFinal Ptr EVP_CIPHER_CTX
ctxPtr (Ptr Word8 -> CString
forall a b. Ptr a -> Ptr b
castPtr Ptr Word8
outBuf) Ptr CInt
outLenPtr
            IO CInt -> (CInt -> IO CInt) -> IO CInt
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 Int -> IO Int
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>  CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CInt -> Int) -> IO CInt -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CInt -> IO CInt
forall a. Storable a => Ptr a -> IO a
peek Ptr CInt
outLenPtr

cipherStrictly :: CipherCtx -> B8.ByteString -> IO B8.ByteString
cipherStrictly :: CipherCtx -> ByteString -> IO ByteString
cipherStrictly CipherCtx
ctx ByteString
input = do
  ByteString
output'  <- CipherCtx -> ByteString -> IO ByteString
cipherUpdateBS CipherCtx
ctx ByteString
input
  ByteString
output'' <- CipherCtx -> IO ByteString
cipherFinalBS CipherCtx
ctx
  ByteString -> IO ByteString
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString -> IO ByteString) -> ByteString -> IO ByteString
forall a b. (a -> b) -> a -> b
$ ByteString -> ByteString -> ByteString
B8.append ByteString
output' ByteString
output''

cipherLazily :: CipherCtx -> L8.ByteString -> IO L8.ByteString
cipherLazily :: CipherCtx -> ByteString -> IO ByteString
cipherLazily CipherCtx
ctx (ByteString
L8.Empty) =
  CipherCtx -> IO ByteString
cipherFinalBS CipherCtx
ctx IO ByteString -> (ByteString -> IO ByteString) -> IO ByteString
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ByteString -> IO ByteString
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString -> IO ByteString)
-> (ByteString -> ByteString) -> ByteString -> IO ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> ByteString
L8.fromChunks ([ByteString] -> ByteString)
-> (ByteString -> [ByteString]) -> ByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> [ByteString]
forall (m :: * -> *) a. Monad m => a -> m a
return
cipherLazily CipherCtx
ctx (L8.Chunk ByteString
x ByteString
xs) = do
  ByteString
y  <- CipherCtx -> ByteString -> IO ByteString
cipherUpdateBS CipherCtx
ctx ByteString
x
  ByteString
ys <- IO ByteString -> IO ByteString
forall a. IO a -> IO a
unsafeInterleaveIO (IO ByteString -> IO ByteString) -> IO ByteString -> IO ByteString
forall a b. (a -> b) -> a -> b
$ CipherCtx -> ByteString -> IO ByteString
cipherLazily CipherCtx
ctx ByteString
xs
  ByteString -> IO ByteString
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString -> IO ByteString) -> ByteString -> IO ByteString
forall a b. (a -> b) -> a -> b
$ ByteString -> ByteString -> ByteString
L8.Chunk ByteString
y ByteString
ys

{- EVP_MD -------------------------------------------------------------------- -}

-- |@Digest@ is an opaque object that represents an algorithm of
-- message digest.
newtype Digest = Digest (Ptr EVP_MD)
data {-# CTYPE "openssl/evp.h" "EVP_MD" #-} EVP_MD

withMDPtr :: Digest -> (Ptr EVP_MD -> IO a) -> IO a
withMDPtr :: forall a. Digest -> (Ptr EVP_MD -> IO a) -> IO a
withMDPtr (Digest Ptr EVP_MD
mdPtr) Ptr EVP_MD -> IO a
f = Ptr EVP_MD -> IO a
f Ptr EVP_MD
mdPtr

{- EVP_MD_CTX ---------------------------------------------------------------- -}

newtype DigestCtx  = DigestCtx (ForeignPtr EVP_MD_CTX)
data {-# CTYPE "openssl/evp.h" "EVP_MD_CTX" #-}  EVP_MD_CTX



{-# LINE 247 "OpenSSL/EVP/Internal.hsc" #-}
foreign import capi unsafe "openssl/evp.h EVP_MD_CTX_new"
  _md_ctx_new :: IO (Ptr EVP_MD_CTX)
foreign import capi unsafe "openssl/evp.h EVP_MD_CTX_reset"
  _md_ctx_reset :: Ptr EVP_MD_CTX -> IO ()
foreign import capi unsafe "openssl/evp.h &EVP_MD_CTX_free"
  _md_ctx_free :: FunPtr (Ptr EVP_MD_CTX -> IO ())

{-# LINE 261 "OpenSSL/EVP/Internal.hsc" #-}

newDigestCtx :: IO DigestCtx
newDigestCtx :: IO DigestCtx
newDigestCtx = IO DigestCtx -> IO DigestCtx
forall a. IO a -> IO a
mask_ (IO DigestCtx -> IO DigestCtx) -> IO DigestCtx -> IO DigestCtx
forall a b. (a -> b) -> a -> b
$ do
  ForeignPtr EVP_MD_CTX
ctx <- FinalizerPtr EVP_MD_CTX
-> Ptr EVP_MD_CTX -> IO (ForeignPtr EVP_MD_CTX)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr EVP_MD_CTX
_md_ctx_free (Ptr EVP_MD_CTX -> IO (ForeignPtr EVP_MD_CTX))
-> IO (Ptr EVP_MD_CTX) -> IO (ForeignPtr EVP_MD_CTX)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr EVP_MD_CTX -> IO (Ptr EVP_MD_CTX)
forall a. Ptr a -> IO (Ptr a)
failIfNull (Ptr EVP_MD_CTX -> IO (Ptr EVP_MD_CTX))
-> IO (Ptr EVP_MD_CTX) -> IO (Ptr EVP_MD_CTX)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IO (Ptr EVP_MD_CTX)
_md_ctx_new
  ForeignPtr EVP_MD_CTX -> (Ptr EVP_MD_CTX -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr EVP_MD_CTX
ctx Ptr EVP_MD_CTX -> IO ()
_md_ctx_reset
  DigestCtx -> IO DigestCtx
forall (m :: * -> *) a. Monad m => a -> m a
return (DigestCtx -> IO DigestCtx) -> DigestCtx -> IO DigestCtx
forall a b. (a -> b) -> a -> b
$ ForeignPtr EVP_MD_CTX -> DigestCtx
DigestCtx ForeignPtr EVP_MD_CTX
ctx

withDigestCtxPtr :: DigestCtx -> (Ptr EVP_MD_CTX -> IO a) -> IO a
withDigestCtxPtr :: forall a. DigestCtx -> (Ptr EVP_MD_CTX -> IO a) -> IO a
withDigestCtxPtr (DigestCtx ForeignPtr EVP_MD_CTX
ctx) = ForeignPtr EVP_MD_CTX -> (Ptr EVP_MD_CTX -> IO a) -> IO a
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr EVP_MD_CTX
ctx

{- digest -------------------------------------------------------------------- -}

foreign import capi unsafe "openssl/evp.h EVP_DigestInit"
  _DigestInit :: Ptr EVP_MD_CTX -> Ptr EVP_MD -> IO CInt

digestInit :: Digest -> IO DigestCtx
digestInit :: Digest -> IO DigestCtx
digestInit (Digest Ptr EVP_MD
md) = do
  DigestCtx
ctx <- IO DigestCtx
newDigestCtx
  DigestCtx -> (Ptr EVP_MD_CTX -> IO DigestCtx) -> IO DigestCtx
forall a. DigestCtx -> (Ptr EVP_MD_CTX -> IO a) -> IO a
withDigestCtxPtr DigestCtx
ctx ((Ptr EVP_MD_CTX -> IO DigestCtx) -> IO DigestCtx)
-> (Ptr EVP_MD_CTX -> IO DigestCtx) -> IO DigestCtx
forall a b. (a -> b) -> a -> b
$ \Ptr EVP_MD_CTX
ctxPtr ->
    Ptr EVP_MD_CTX -> Ptr EVP_MD -> IO CInt
_DigestInit Ptr EVP_MD_CTX
ctxPtr Ptr EVP_MD
md
      IO CInt -> (CInt -> IO ()) -> IO ()
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)
      IO () -> IO DigestCtx -> IO DigestCtx
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>  DigestCtx -> IO DigestCtx
forall (m :: * -> *) a. Monad m => a -> m a
return DigestCtx
ctx

foreign import capi unsafe "openssl/evp.h EVP_DigestUpdate"
  _DigestUpdate :: Ptr EVP_MD_CTX -> Ptr CChar -> CSize -> IO CInt

digestUpdateBS :: DigestCtx -> B8.ByteString -> IO ()
digestUpdateBS :: DigestCtx -> ByteString -> IO ()
digestUpdateBS DigestCtx
ctx ByteString
bs =
  DigestCtx -> (Ptr EVP_MD_CTX -> IO ()) -> IO ()
forall a. DigestCtx -> (Ptr EVP_MD_CTX -> IO a) -> IO a
withDigestCtxPtr DigestCtx
ctx ((Ptr EVP_MD_CTX -> IO ()) -> IO ())
-> (Ptr EVP_MD_CTX -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr EVP_MD_CTX
ctxPtr ->
    ByteString -> (CStringLen -> IO ()) -> IO ()
forall a. ByteString -> (CStringLen -> IO a) -> IO a
B8.unsafeUseAsCStringLen ByteString
bs ((CStringLen -> IO ()) -> IO ()) -> (CStringLen -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \(CString
buf, Int
len) ->
      Ptr EVP_MD_CTX -> CString -> CSize -> IO CInt
_DigestUpdate Ptr EVP_MD_CTX
ctxPtr CString
buf (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len)
        IO CInt -> (CInt -> IO CInt) -> IO CInt
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 (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>  () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

foreign import capi unsafe "openssl/evp.h EVP_DigestFinal"
  _DigestFinal :: Ptr EVP_MD_CTX -> Ptr CChar -> Ptr CUInt -> IO CInt

digestFinalBS :: DigestCtx -> IO B8.ByteString
digestFinalBS :: DigestCtx -> IO ByteString
digestFinalBS DigestCtx
ctx =
  DigestCtx -> (Ptr EVP_MD_CTX -> IO ByteString) -> IO ByteString
forall a. DigestCtx -> (Ptr EVP_MD_CTX -> IO a) -> IO a
withDigestCtxPtr DigestCtx
ctx ((Ptr EVP_MD_CTX -> IO ByteString) -> IO ByteString)
-> (Ptr EVP_MD_CTX -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr EVP_MD_CTX
ctxPtr ->
    Int -> (Ptr Word8 -> IO Int) -> IO ByteString
B8.createAndTrim (Int
64) ((Ptr Word8 -> IO Int) -> IO ByteString)
-> (Ptr Word8 -> IO Int) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
bufPtr ->
{-# LINE 302 "OpenSSL/EVP/Internal.hsc" #-}
      alloca $ \bufLenPtr -> do
        _DigestFinal ctxPtr (castPtr bufPtr) bufLenPtr >>= failIf_ (/= 1)
        fromIntegral <$> peek bufLenPtr

digestFinal :: DigestCtx -> IO String
digestFinal :: DigestCtx -> IO String
digestFinal DigestCtx
ctx =
  DigestCtx -> (Ptr EVP_MD_CTX -> IO String) -> IO String
forall a. DigestCtx -> (Ptr EVP_MD_CTX -> IO a) -> IO a
withDigestCtxPtr DigestCtx
ctx ((Ptr EVP_MD_CTX -> IO String) -> IO String)
-> (Ptr EVP_MD_CTX -> IO String) -> IO String
forall a b. (a -> b) -> a -> b
$ \Ptr EVP_MD_CTX
ctxPtr ->
    Int -> (CString -> IO String) -> IO String
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray (Int
64) ((CString -> IO String) -> IO String)
-> (CString -> IO String) -> IO String
forall a b. (a -> b) -> a -> b
$ \CString
bufPtr ->
{-# LINE 310 "OpenSSL/EVP/Internal.hsc" #-}
      alloca $ \bufLenPtr -> do
        _DigestFinal ctxPtr bufPtr bufLenPtr >>= failIf_ (/= 1)
        bufLen <- fromIntegral <$> peek bufLenPtr
        peekCStringLen (bufPtr, bufLen)

digestStrictly :: Digest -> B8.ByteString -> IO DigestCtx
digestStrictly :: Digest -> ByteString -> IO DigestCtx
digestStrictly Digest
md ByteString
input = do
  DigestCtx
ctx <- Digest -> IO DigestCtx
digestInit Digest
md
  DigestCtx -> ByteString -> IO ()
digestUpdateBS DigestCtx
ctx ByteString
input
  DigestCtx -> IO DigestCtx
forall (m :: * -> *) a. Monad m => a -> m a
return DigestCtx
ctx

digestLazily :: Digest -> L8.ByteString -> IO DigestCtx
digestLazily :: Digest -> ByteString -> IO DigestCtx
digestLazily Digest
md ByteString
lbs = do
  DigestCtx
ctx <- Digest -> IO DigestCtx
digestInit Digest
md
  (ByteString -> IO ()) -> [ByteString] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (DigestCtx -> ByteString -> IO ()
digestUpdateBS DigestCtx
ctx) ([ByteString] -> IO ()) -> [ByteString] -> IO ()
forall a b. (a -> b) -> a -> b
$ ByteString -> [ByteString]
L8.toChunks ByteString
lbs
  DigestCtx -> IO DigestCtx
forall (m :: * -> *) a. Monad m => a -> m a
return DigestCtx
ctx

{- HMAC ---------------------------------------------------------------------- -}
newtype HmacCtx = HmacCtx (ForeignPtr HMAC_CTX)
data {-# CTYPE "openssl/hmac.h" "HMAC_CTX" #-} HMAC_CTX

foreign import capi unsafe "HsOpenSSL.h HsOpenSSL_HMAC_CTX_new"
  _hmac_ctx_new :: IO (Ptr HMAC_CTX)

foreign import capi unsafe "openssl/hmac.h HMAC_Init"
  _hmac_init :: Ptr HMAC_CTX -> Ptr () -> CInt -> Ptr EVP_MD -> IO CInt

foreign import capi unsafe "openssl/hmac.h HMAC_Update"
  _hmac_update :: Ptr HMAC_CTX -> Ptr CChar -> CInt -> IO CInt

foreign import capi unsafe "openssl/hmac.h HMAC_Final"
  _hmac_final :: Ptr HMAC_CTX -> Ptr CChar -> Ptr CInt -> IO CUInt

foreign import capi unsafe "HsOpenSSL &HsOpenSSL_HMAC_CTX_free"
  _hmac_ctx_free :: FunPtr (Ptr HMAC_CTX -> IO ())

newHmacCtx :: IO HmacCtx
newHmacCtx :: IO HmacCtx
newHmacCtx = do
    Ptr HMAC_CTX
ctxPtr <- IO (Ptr HMAC_CTX)
_hmac_ctx_new
    ForeignPtr HMAC_CTX -> HmacCtx
HmacCtx (ForeignPtr HMAC_CTX -> HmacCtx)
-> IO (ForeignPtr HMAC_CTX) -> IO HmacCtx
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FinalizerPtr HMAC_CTX -> Ptr HMAC_CTX -> IO (ForeignPtr HMAC_CTX)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr HMAC_CTX
_hmac_ctx_free Ptr HMAC_CTX
ctxPtr

withHmacCtxPtr :: HmacCtx -> (Ptr HMAC_CTX -> IO a) -> IO a
withHmacCtxPtr :: forall a. HmacCtx -> (Ptr HMAC_CTX -> IO a) -> IO a
withHmacCtxPtr (HmacCtx ForeignPtr HMAC_CTX
ctx) = ForeignPtr HMAC_CTX -> (Ptr HMAC_CTX -> IO a) -> IO a
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr HMAC_CTX
ctx

hmacInit :: Digest -> B8.ByteString -> IO HmacCtx
hmacInit :: Digest -> ByteString -> IO HmacCtx
hmacInit (Digest Ptr EVP_MD
md) ByteString
key = do
  HmacCtx
ctx <- IO HmacCtx
newHmacCtx
  HmacCtx -> (Ptr HMAC_CTX -> IO HmacCtx) -> IO HmacCtx
forall a. HmacCtx -> (Ptr HMAC_CTX -> IO a) -> IO a
withHmacCtxPtr HmacCtx
ctx ((Ptr HMAC_CTX -> IO HmacCtx) -> IO HmacCtx)
-> (Ptr HMAC_CTX -> IO HmacCtx) -> IO HmacCtx
forall a b. (a -> b) -> a -> b
$ \Ptr HMAC_CTX
ctxPtr ->
    ByteString -> (CStringLen -> IO HmacCtx) -> IO HmacCtx
forall a. ByteString -> (CStringLen -> IO a) -> IO a
B8.unsafeUseAsCStringLen ByteString
key ((CStringLen -> IO HmacCtx) -> IO HmacCtx)
-> (CStringLen -> IO HmacCtx) -> IO HmacCtx
forall a b. (a -> b) -> a -> b
$ \(CString
keyPtr, Int
keyLen) ->
      Ptr HMAC_CTX -> Ptr () -> CInt -> Ptr EVP_MD -> IO CInt
_hmac_init Ptr HMAC_CTX
ctxPtr (CString -> Ptr ()
forall a b. Ptr a -> Ptr b
castPtr CString
keyPtr) (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
keyLen) Ptr EVP_MD
md
        IO CInt -> (CInt -> IO ()) -> IO ()
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)
        IO () -> IO HmacCtx -> IO HmacCtx
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> HmacCtx -> IO HmacCtx
forall (m :: * -> *) a. Monad m => a -> m a
return HmacCtx
ctx

hmacUpdateBS :: HmacCtx -> B8.ByteString -> IO ()
hmacUpdateBS :: HmacCtx -> ByteString -> IO ()
hmacUpdateBS HmacCtx
ctx ByteString
bs = HmacCtx -> (Ptr HMAC_CTX -> IO ()) -> IO ()
forall a. HmacCtx -> (Ptr HMAC_CTX -> IO a) -> IO a
withHmacCtxPtr HmacCtx
ctx ((Ptr HMAC_CTX -> IO ()) -> IO ())
-> (Ptr HMAC_CTX -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr HMAC_CTX
ctxPtr -> do
  ByteString -> (CStringLen -> IO ()) -> IO ()
forall a. ByteString -> (CStringLen -> IO a) -> IO a
B8.unsafeUseAsCStringLen ByteString
bs ((CStringLen -> IO ()) -> IO ()) -> (CStringLen -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \(CString
buf, Int
len) ->
    Ptr HMAC_CTX -> CString -> CInt -> IO CInt
_hmac_update Ptr HMAC_CTX
ctxPtr (CString -> CString
forall a b. Ptr a -> Ptr b
castPtr CString
buf) (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len)
      IO CInt -> (CInt -> IO ()) -> IO ()
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)

hmacFinalBS :: HmacCtx -> IO B8.ByteString
hmacFinalBS :: HmacCtx -> IO ByteString
hmacFinalBS HmacCtx
ctx =
  HmacCtx -> (Ptr HMAC_CTX -> IO ByteString) -> IO ByteString
forall a. HmacCtx -> (Ptr HMAC_CTX -> IO a) -> IO a
withHmacCtxPtr HmacCtx
ctx ((Ptr HMAC_CTX -> IO ByteString) -> IO ByteString)
-> (Ptr HMAC_CTX -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr HMAC_CTX
ctxPtr ->
    Int -> (Ptr Word8 -> IO Int) -> IO ByteString
B8.createAndTrim (Int
64) ((Ptr Word8 -> IO Int) -> IO ByteString)
-> (Ptr Word8 -> IO Int) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
bufPtr ->
{-# LINE 373 "OpenSSL/EVP/Internal.hsc" #-}
      alloca $ \bufLenPtr -> do
        _hmac_final ctxPtr (castPtr bufPtr) bufLenPtr >>= failIf_ (/= 1)
        fromIntegral <$> peek bufLenPtr

hmacLazily :: Digest -> B8.ByteString -> L8.ByteString -> IO HmacCtx
hmacLazily :: Digest -> ByteString -> ByteString -> IO HmacCtx
hmacLazily Digest
md ByteString
key ByteString
lbs = do
  HmacCtx
ctx <- Digest -> ByteString -> IO HmacCtx
hmacInit Digest
md ByteString
key
  (ByteString -> IO ()) -> [ByteString] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (HmacCtx -> ByteString -> IO ()
hmacUpdateBS HmacCtx
ctx) ([ByteString] -> IO ()) -> [ByteString] -> IO ()
forall a b. (a -> b) -> a -> b
$ ByteString -> [ByteString]
L8.toChunks ByteString
lbs
  HmacCtx -> IO HmacCtx
forall (m :: * -> *) a. Monad m => a -> m a
return HmacCtx
ctx

{- EVP_PKEY ------------------------------------------------------------------ -}

-- | VaguePKey is a 'ForeignPtr' to 'EVP_PKEY', that is either public
-- key or a ker pair. We can't tell which at compile time.
newtype VaguePKey = VaguePKey (ForeignPtr EVP_PKEY)
data {-# CTYPE "openssl/evp.h" "EVP_PKEY" #-} EVP_PKEY

-- | Instances of class 'PKey' can be converted back and forth to
-- 'VaguePKey'.
class PKey k where
    -- | Wrap the key (i.g. RSA) into 'EVP_PKEY'.
    toPKey        :: k -> IO VaguePKey

    -- | Extract the concrete key from the 'EVP_PKEY'. Returns
    -- 'Nothing' if the type mismatches.
    fromPKey      :: VaguePKey -> IO (Maybe k)

    -- | Do the same as EVP_PKEY_size().
    pkeySize      :: k -> Int

    -- | Return the default digesting algorithm for the key.
    pkeyDefaultMD :: k -> IO Digest

foreign import capi unsafe "openssl/evp.h EVP_PKEY_new"
  _pkey_new :: IO (Ptr EVP_PKEY)

foreign import capi unsafe "openssl/evp.h &EVP_PKEY_free"
  _pkey_free :: FunPtr (Ptr EVP_PKEY -> IO ())

foreign import capi unsafe "openssl/evp.h EVP_PKEY_free"
  _pkey_free' :: Ptr EVP_PKEY -> IO ()

wrapPKeyPtr :: Ptr EVP_PKEY -> IO VaguePKey
wrapPKeyPtr :: Ptr EVP_PKEY -> IO VaguePKey
wrapPKeyPtr = (ForeignPtr EVP_PKEY -> VaguePKey)
-> IO (ForeignPtr EVP_PKEY) -> IO VaguePKey
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ForeignPtr EVP_PKEY -> VaguePKey
VaguePKey (IO (ForeignPtr EVP_PKEY) -> IO VaguePKey)
-> (Ptr EVP_PKEY -> IO (ForeignPtr EVP_PKEY))
-> Ptr EVP_PKEY
-> IO VaguePKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FinalizerPtr EVP_PKEY -> Ptr EVP_PKEY -> IO (ForeignPtr EVP_PKEY)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr EVP_PKEY
_pkey_free

createPKey :: (Ptr EVP_PKEY -> IO a) -> IO VaguePKey
createPKey :: forall a. (Ptr EVP_PKEY -> IO a) -> IO VaguePKey
createPKey Ptr EVP_PKEY -> IO a
f = ((forall a. IO a -> IO a) -> IO VaguePKey) -> IO VaguePKey
forall b. ((forall a. IO a -> IO a) -> IO b) -> IO b
mask (((forall a. IO a -> IO a) -> IO VaguePKey) -> IO VaguePKey)
-> ((forall a. IO a -> IO a) -> IO VaguePKey) -> IO VaguePKey
forall a b. (a -> b) -> a -> b
$ \forall a. IO a -> IO a
restore -> do
  Ptr EVP_PKEY
ptr <- IO (Ptr EVP_PKEY)
_pkey_new IO (Ptr EVP_PKEY)
-> (Ptr EVP_PKEY -> IO (Ptr EVP_PKEY)) -> IO (Ptr EVP_PKEY)
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 () -> IO ()
forall a. IO a -> IO a
restore (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ Ptr EVP_PKEY -> IO a
f Ptr EVP_PKEY
ptr IO a -> IO () -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()) IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO a
`onException` Ptr EVP_PKEY -> IO ()
_pkey_free' Ptr EVP_PKEY
ptr
  Ptr EVP_PKEY -> IO VaguePKey
wrapPKeyPtr Ptr EVP_PKEY
ptr

withPKeyPtr :: VaguePKey -> (Ptr EVP_PKEY -> IO a) -> IO a
withPKeyPtr :: forall a. VaguePKey -> (Ptr EVP_PKEY -> IO a) -> IO a
withPKeyPtr (VaguePKey ForeignPtr EVP_PKEY
pkey) = ForeignPtr EVP_PKEY -> (Ptr EVP_PKEY -> IO a) -> IO a
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr EVP_PKEY
pkey

withPKeyPtr' :: PKey k => k -> (Ptr EVP_PKEY -> IO a) -> IO a
withPKeyPtr' :: forall k a. PKey k => k -> (Ptr EVP_PKEY -> IO a) -> IO a
withPKeyPtr' k
k Ptr EVP_PKEY -> IO a
f = do
  VaguePKey
pk <- k -> IO VaguePKey
forall k. PKey k => k -> IO VaguePKey
toPKey k
k
  VaguePKey -> (Ptr EVP_PKEY -> IO a) -> IO a
forall a. VaguePKey -> (Ptr EVP_PKEY -> IO a) -> IO a
withPKeyPtr VaguePKey
pk Ptr EVP_PKEY -> IO a
f

unsafePKeyToPtr :: VaguePKey -> Ptr EVP_PKEY
unsafePKeyToPtr :: VaguePKey -> Ptr EVP_PKEY
unsafePKeyToPtr (VaguePKey ForeignPtr EVP_PKEY
pkey) = ForeignPtr EVP_PKEY -> Ptr EVP_PKEY
forall a. ForeignPtr a -> Ptr a
Unsafe.unsafeForeignPtrToPtr ForeignPtr EVP_PKEY
pkey

touchPKey :: VaguePKey -> IO ()
touchPKey :: VaguePKey -> IO ()
touchPKey (VaguePKey ForeignPtr EVP_PKEY
pkey) = ForeignPtr EVP_PKEY -> IO ()
forall a. ForeignPtr a -> IO ()
touchForeignPtr ForeignPtr EVP_PKEY
pkey