tls-2.4.2: Network/TLS/Handshake/Server.hs
{-# LANGUAGE OverloadedStrings #-}
module Network.TLS.Handshake.Server (
handshakeServer,
handshakeServerWith,
requestCertificateServer,
keyUpdate,
updateKey,
KeyUpdateRequest (..),
) where
import Control.Monad.State.Strict
import Data.Maybe
import Network.TLS.Context.Internal
import Network.TLS.Handshake.Common
import Network.TLS.Handshake.Common13
import Network.TLS.Handshake.Server.ClientHello
import Network.TLS.Handshake.Server.ClientHello12
import Network.TLS.Handshake.Server.ClientHello13
import Network.TLS.Handshake.Server.ServerHello12
import Network.TLS.Handshake.Server.ServerHello13
import Network.TLS.Handshake.Server.TLS12
import Network.TLS.Handshake.Server.TLS13
import Network.TLS.Imports
import Network.TLS.Struct
-- Put the server context in handshake mode.
--
-- Expect to receive as first packet a client hello handshake message
--
-- This is just a helper to pop the next message from the recv layer,
-- and call handshakeServerWith.
handshakeServer :: ServerParams -> Context -> IO ()
handshakeServer sparams ctx = liftIO $ do
hbs <- recvPacketHandshake ctx
case hbs of
chb : _ -> handshake sparams ctx chb
_ -> unexpected (show $ fst $ unzip hbs) (Just "client hello")
handshakeServerWith
:: ServerParams -> Context -> HandshakeR -> IO ()
handshakeServerWith = handshake
-- | Put the server context in handshake mode.
--
-- Expect a client hello message as parameter.
-- This is useful when the client hello has been already popped from the recv layer to inspect the packet.
--
-- When the function returns, a new handshake has been successfully negotiated.
-- On any error, a HandshakeFailed exception is raised.
handshake :: ServerParams -> Context -> HandshakeR -> IO ()
handshake sparams ctx chb@(ClientHello ch, bs) = do
(chosenVersion, chI, mcrnd) <- processClientHello sparams ctx ch bs
if chosenVersion == TLS13
then do
-- fixme: we should check if the client random is the same as
-- that in the first client hello in the case of hello retry.
-- r0 :: Cipher, Hash, Bool
(keyShareResult, r0, r1) <-
processClientHello13 sparams ctx chI
case keyShareResult of
SelectKeyShareNotFound ->
throwCore $
Error_Protocol "no group in common with the client for HRR" HandshakeFailure
SelectKeyShareHRR g -> do
sendHRR ctx g r0 chI $ isJust mcrnd
-- Don't reset ctxEstablished since 0-RTT data
-- would be coming, which should be ignored.
handshakeServer sparams ctx
SelectKeyShareFound cliKeyShare -> do
unless (checkClientKeyShareKeyLength cliKeyShare) $
throwCore $
Error_Protocol "broken key_share" IllegalParameter
-- r2 :: ( SecretTriple ApplicationSecret
-- , ClientTrafficSecret HandshakeSecret
-- , Bool -- authenticated
-- , Bool) -- rtt0OK
r2 <-
sendServerHello13 sparams ctx cliKeyShare r0 r1 chI mcrnd
recvClientSecondFlight13 sparams ctx r2 chI
else do
r <-
processClientHello12 sparams ctx chI
updateTranscriptHash12 ctx chb
resumeSessionData <-
sendServerHello12 sparams ctx r chI
recvClientSecondFlight12 sparams ctx resumeSessionData
handshake _ _ _ = throwCore $ Error_Protocol "client Hello is expected" HandshakeFailure