module OpenSSL.EVP.Sign
( sign
, signBS
, signLBS
)
where
import qualified Data.ByteString.Char8 as B8
import qualified Data.ByteString.Internal as B8
import qualified Data.ByteString.Lazy.Char8 as L8
import Control.Applicative ((<$>))
import Foreign
import Foreign.C
import OpenSSL.EVP.Digest
import OpenSSL.EVP.PKey
import OpenSSL.EVP.Internal
import OpenSSL.Utils
foreign import ccall unsafe "EVP_SignFinal"
_SignFinal :: Ptr EVP_MD_CTX -> Ptr Word8 -> Ptr CUInt
-> Ptr EVP_PKEY -> IO CInt
signFinal :: KeyPair k => DigestCtx -> k -> IO B8.ByteString
signFinal ctx k = do
let maxLen = pkeySize k
withDigestCtxPtr ctx $ \ ctxPtr ->
withPKeyPtr' k $ \ pkeyPtr ->
B8.createAndTrim maxLen $ \ bufPtr ->
alloca $ \ bufLenPtr -> do
failIf_ (/= 1) =<< _SignFinal ctxPtr bufPtr bufLenPtr pkeyPtr
fromIntegral <$> peek bufLenPtr
sign :: KeyPair key =>
Digest
-> key
-> String
-> IO String
sign md pkey input
= fmap L8.unpack $ signLBS md pkey $ L8.pack input
signBS :: KeyPair key =>
Digest
-> key
-> B8.ByteString
-> IO B8.ByteString
signBS md pkey input
= do ctx <- digestStrictly md input
signFinal ctx pkey
signLBS :: KeyPair key =>
Digest
-> key
-> L8.ByteString
-> IO L8.ByteString
signLBS md pkey input
= do ctx <- digestLazily md input
sig <- signFinal ctx pkey
return $ L8.fromChunks [sig]