{-# LANGUAGE CPP #-}
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE CApiFFI #-}
module OpenSSL.EVP.Open
( open
, openBS
, openLBS
)
where
import qualified Data.ByteString.Char8 as B8
import qualified Data.ByteString.Lazy.Char8 as L8
import qualified Data.ByteString.Unsafe as B8
import Foreign.C.String (CString)
#if MIN_VERSION_base(4,5,0)
import Foreign.C.Types (CChar(..), CInt(..))
#else
import Foreign.C.Types (CChar, CInt)
#endif
import Foreign.Ptr (Ptr)
import OpenSSL.EVP.Cipher hiding (cipher)
import OpenSSL.EVP.PKey
import OpenSSL.EVP.Internal
import OpenSSL.Utils
import System.IO.Unsafe (unsafePerformIO)
foreign import capi unsafe "openssl/evp.h EVP_OpenInit"
_OpenInit :: Ptr EVP_CIPHER_CTX
-> Cipher
-> Ptr CChar
-> CInt
-> CString
-> Ptr EVP_PKEY
-> IO CInt
openInit :: KeyPair key =>
Cipher
-> B8.ByteString
-> B8.ByteString
-> key
-> IO CipherCtx
openInit :: forall key.
KeyPair key =>
Cipher -> ByteString -> ByteString -> key -> IO CipherCtx
openInit Cipher
cipher ByteString
encKey ByteString
iv key
pkey
= 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 -> (CStringLen -> IO ()) -> IO ()
forall a. ByteString -> (CStringLen -> IO a) -> IO a
B8.unsafeUseAsCStringLen ByteString
encKey ((CStringLen -> IO ()) -> IO ()) -> (CStringLen -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ (Ptr CChar
encKeyPtr, Int
encKeyLen) ->
ByteString -> (Ptr CChar -> IO ()) -> IO ()
forall a. ByteString -> (Ptr CChar -> IO a) -> IO a
B8.unsafeUseAsCString ByteString
iv ((Ptr CChar -> IO ()) -> IO ()) -> (Ptr CChar -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ Ptr CChar
ivPtr ->
key -> (Ptr EVP_PKEY -> IO ()) -> IO ()
forall k a. PKey k => k -> (Ptr EVP_PKEY -> IO a) -> IO a
withPKeyPtr' key
pkey ((Ptr EVP_PKEY -> IO ()) -> IO ())
-> (Ptr EVP_PKEY -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ Ptr EVP_PKEY
pkeyPtr ->
Ptr EVP_CIPHER_CTX
-> Cipher
-> Ptr CChar
-> CInt
-> Ptr CChar
-> Ptr EVP_PKEY
-> IO CInt
_OpenInit Ptr EVP_CIPHER_CTX
ctxPtr Cipher
cipher Ptr CChar
encKeyPtr (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
encKeyLen) Ptr CChar
ivPtr Ptr EVP_PKEY
pkeyPtr
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)
CipherCtx -> IO CipherCtx
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return CipherCtx
ctx
open :: KeyPair key =>
Cipher
-> String
-> String
-> key
-> String
-> String
{-# DEPRECATED open "Use openBS or openLBS instead." #-}
open :: forall key.
KeyPair key =>
Cipher -> String -> String -> key -> String -> String
open Cipher
cipher String
encKey String
iv key
pkey String
input
= ByteString -> String
L8.unpack (ByteString -> String) -> ByteString -> String
forall a b. (a -> b) -> a -> b
$ Cipher
-> ByteString -> ByteString -> key -> ByteString -> ByteString
forall key.
KeyPair key =>
Cipher
-> ByteString -> ByteString -> key -> ByteString -> ByteString
openLBS Cipher
cipher (String -> ByteString
B8.pack String
encKey) (String -> ByteString
B8.pack String
iv) key
pkey (String -> ByteString
L8.pack String
input)
openBS :: KeyPair key =>
Cipher
-> B8.ByteString
-> B8.ByteString
-> key
-> B8.ByteString
-> B8.ByteString
openBS :: forall key.
KeyPair key =>
Cipher
-> ByteString -> ByteString -> key -> ByteString -> ByteString
openBS Cipher
cipher ByteString
encKey ByteString
iv key
pkey ByteString
input
= IO ByteString -> ByteString
forall a. IO a -> a
unsafePerformIO (IO ByteString -> ByteString) -> IO ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$
do CipherCtx
ctx <- Cipher -> ByteString -> ByteString -> key -> IO CipherCtx
forall key.
KeyPair key =>
Cipher -> ByteString -> ByteString -> key -> IO CipherCtx
openInit Cipher
cipher ByteString
encKey ByteString
iv key
pkey
CipherCtx -> ByteString -> IO ByteString
cipherStrictly CipherCtx
ctx ByteString
input
openLBS :: KeyPair key =>
Cipher
-> B8.ByteString
-> B8.ByteString
-> key
-> L8.ByteString
-> L8.ByteString
openLBS :: forall key.
KeyPair key =>
Cipher
-> ByteString -> ByteString -> key -> ByteString -> ByteString
openLBS Cipher
cipher ByteString
encKey ByteString
iv key
pkey ByteString
input
= IO ByteString -> ByteString
forall a. IO a -> a
unsafePerformIO (IO ByteString -> ByteString) -> IO ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$
do CipherCtx
ctx <- Cipher -> ByteString -> ByteString -> key -> IO CipherCtx
forall key.
KeyPair key =>
Cipher -> ByteString -> ByteString -> key -> IO CipherCtx
openInit Cipher
cipher ByteString
encKey ByteString
iv key
pkey
CipherCtx -> ByteString -> IO ByteString
cipherLazily CipherCtx
ctx ByteString
input