2013-07-28 08:19:28 +00:00
|
|
|
-- |
|
|
|
|
-- Module : Network.TLS.Handshake.Key
|
|
|
|
-- License : BSD-style
|
|
|
|
-- Maintainer : Vincent Hanquez <vincent@snarc.org>
|
|
|
|
-- Stability : experimental
|
|
|
|
-- Portability : unknown
|
|
|
|
--
|
|
|
|
-- functions for RSA operations
|
|
|
|
--
|
|
|
|
module Network.TLS.Handshake.Key
|
|
|
|
( encryptRSA
|
|
|
|
, signRSA
|
|
|
|
, decryptRSA
|
|
|
|
, verifyRSA
|
|
|
|
) where
|
|
|
|
|
|
|
|
import Control.Monad.State
|
|
|
|
|
|
|
|
import Data.ByteString (ByteString)
|
|
|
|
import qualified Data.ByteString as B
|
|
|
|
|
|
|
|
import Network.TLS.Util
|
2013-08-01 07:47:40 +00:00
|
|
|
import Network.TLS.Handshake.State
|
|
|
|
import Network.TLS.State (withRNG, getVersion)
|
2013-07-28 08:19:28 +00:00
|
|
|
import Network.TLS.Crypto
|
|
|
|
import Network.TLS.Types
|
2013-08-01 07:35:42 +00:00
|
|
|
import Network.TLS.Context
|
2013-07-28 08:19:28 +00:00
|
|
|
|
|
|
|
{- if the RSA encryption fails we just return an empty bytestring, and let the protocol
|
|
|
|
- fail by itself; however it would be probably better to just report it since it's an internal problem.
|
|
|
|
-}
|
2013-08-01 07:52:42 +00:00
|
|
|
encryptRSA :: Context -> ByteString -> IO ByteString
|
2013-08-01 07:43:48 +00:00
|
|
|
encryptRSA ctx content = do
|
|
|
|
rsakey <- return . fromJust "rsa public key" =<< handshakeGet ctx hstRSAPublicKey
|
|
|
|
usingState_ ctx $ do
|
|
|
|
v <- withRNG (\g -> kxEncrypt g rsakey content)
|
|
|
|
case v of
|
|
|
|
Left err -> fail ("rsa encrypt failed: " ++ show err)
|
|
|
|
Right econtent -> return econtent
|
2013-07-28 08:19:28 +00:00
|
|
|
|
2013-08-01 07:52:42 +00:00
|
|
|
signRSA :: Context -> HashDescr -> ByteString -> IO ByteString
|
2013-08-01 07:43:48 +00:00
|
|
|
signRSA ctx hsh content = do
|
|
|
|
rsakey <- return . fromJust "rsa client private key" =<< handshakeGet ctx hstRSAClientPrivateKey
|
|
|
|
usingState_ ctx $ do
|
|
|
|
r <- withRNG (\g -> kxSign g rsakey hsh content)
|
|
|
|
case r of
|
|
|
|
Left err -> fail ("rsa sign failed: " ++ show err)
|
|
|
|
Right econtent -> return econtent
|
2013-07-28 08:19:28 +00:00
|
|
|
|
2013-08-01 07:52:42 +00:00
|
|
|
decryptRSA :: Context -> ByteString -> IO (Either KxError ByteString)
|
2013-08-01 07:43:48 +00:00
|
|
|
decryptRSA ctx econtent = do
|
|
|
|
rsapriv <- return . fromJust "rsa private key" =<< handshakeGet ctx hstRSAPrivateKey
|
|
|
|
usingState_ ctx $ do
|
|
|
|
ver <- getVersion
|
|
|
|
let cipher = if ver < TLS10 then econtent else B.drop 2 econtent
|
|
|
|
withRNG (\g -> kxDecrypt g rsapriv cipher)
|
2013-07-28 08:19:28 +00:00
|
|
|
|
2013-08-01 07:52:42 +00:00
|
|
|
verifyRSA :: Context -> HashDescr -> ByteString -> ByteString -> IO Bool
|
2013-08-01 07:43:48 +00:00
|
|
|
verifyRSA ctx hsh econtent sign = do
|
|
|
|
rsapriv <- return . fromJust "rsa client public key" =<< handshakeGet ctx hstRSAClientPublicKey
|
2013-07-28 08:19:28 +00:00
|
|
|
return $ kxVerify rsapriv hsh econtent sign
|
|
|
|
|
2013-08-01 07:52:42 +00:00
|
|
|
handshakeGet :: Context -> (HandshakeState -> a) -> IO a
|
2013-08-01 07:43:48 +00:00
|
|
|
handshakeGet ctx f = usingHState ctx (gets f)
|