HsOpenSSL-0.8: OpenSSL/EVP/Sign.hsc
{- -*- haskell -*- -}
-- |Message signing using asymmetric cipher and message digest
-- algorithm. This is an opposite of "OpenSSL.EVP.Verify".
module OpenSSL.EVP.Sign
( sign
, signBS
, signLBS
, signFinal -- private
)
where
import Control.Monad
import qualified Data.ByteString.Char8 as B8
import qualified Data.ByteString.Internal as B8
import qualified Data.ByteString.Lazy.Char8 as L8
import Foreign
import Foreign.C
import OpenSSL.EVP.Digest
import OpenSSL.EVP.PKey
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
liftM fromIntegral $ peek bufLenPtr
-- |@'sign'@ generates a signature from a stream of data. The string
-- must not contain any letters which aren't in the range of U+0000 -
-- U+00FF.
sign :: KeyPair key =>
Digest -- ^ message digest algorithm to use
-> key -- ^ private key to sign the message digest
-> String -- ^ input string
-> IO String -- ^ the result signature
sign md pkey input
= liftM L8.unpack $ signLBS md pkey $ L8.pack input
-- |@'signBS'@ generates a signature from a chunk of data.
signBS :: KeyPair key =>
Digest -- ^ message digest algorithm to use
-> key -- ^ private key to sign the message digest
-> B8.ByteString -- ^ input string
-> IO B8.ByteString -- ^ the result signature
signBS md pkey input
= do ctx <- digestStrictly md input
signFinal ctx pkey
-- |@'signLBS'@ generates a signature from a stream of data.
signLBS :: KeyPair key =>
Digest -- ^ message digest algorithm to use
-> key -- ^ private key to sign the message digest
-> L8.ByteString -- ^ input string
-> IO L8.ByteString -- ^ the result signature
signLBS md pkey input
= do ctx <- digestLazily md input
sig <- signFinal ctx pkey
return $ L8.fromChunks [sig]