1{-# LANGUAGE OverloadedStrings #-}
2-- |
3-- Module      : Network.TLS.Handshake.Server
4-- License     : BSD-style
5-- Maintainer  : Vincent Hanquez <vincent@snarc.org>
6-- Stability   : experimental
7-- Portability : unknown
8--
9module Network.TLS.Handshake.Server
10    ( handshakeServer
11    , handshakeServerWith
12    , requestCertificateServer
13    , postHandshakeAuthServerWith
14    ) where
15
16import Network.TLS.Parameters
17import Network.TLS.Imports
18import Network.TLS.Context.Internal
19import Network.TLS.Session
20import Network.TLS.Struct
21import Network.TLS.Struct13
22import Network.TLS.Cipher
23import Network.TLS.Compression
24import Network.TLS.Credentials
25import Network.TLS.Crypto
26import Network.TLS.Extension
27import Network.TLS.Util (bytesEq, catchException, fromJust)
28import Network.TLS.IO
29import Network.TLS.Types
30import Network.TLS.State
31import Network.TLS.Handshake.Control
32import Network.TLS.Handshake.State
33import Network.TLS.Handshake.Process
34import Network.TLS.Handshake.Key
35import Network.TLS.Handshake.Random
36import Network.TLS.Measurement
37import qualified Data.ByteString as B
38import Data.X509 (ExtKeyUsageFlag(..))
39
40import Control.Monad.State.Strict
41import Control.Exception (bracket)
42
43import Network.TLS.Handshake.Signature
44import Network.TLS.Handshake.Common
45import Network.TLS.Handshake.Certificate
46import Network.TLS.X509
47import Network.TLS.Handshake.State13
48import Network.TLS.Handshake.Common13
49
50-- Put the server context in handshake mode.
51--
52-- Expect to receive as first packet a client hello handshake message
53--
54-- This is just a helper to pop the next message from the recv layer,
55-- and call handshakeServerWith.
56handshakeServer :: ServerParams -> Context -> IO ()
57handshakeServer sparams ctx = liftIO $ do
58    hss <- recvPacketHandshake ctx
59    case hss of
60        [ch] -> handshakeServerWith sparams ctx ch
61        _    -> unexpected (show hss) (Just "client hello")
62
63-- | Put the server context in handshake mode.
64--
65-- Expect a client hello message as parameter.
66-- This is useful when the client hello has been already poped from the recv layer to inspect the packet.
67--
68-- When the function returns, a new handshake has been succesfully negociated.
69-- On any error, a HandshakeFailed exception is raised.
70--
71-- handshake protocol (<- receiving, -> sending, [] optional):
72--    (no session)           (session resumption)
73--      <- client hello       <- client hello
74--      -> server hello       -> server hello
75--      -> [certificate]
76--      -> [server key xchg]
77--      -> [cert request]
78--      -> hello done
79--      <- [certificate]
80--      <- client key xchg
81--      <- [cert verify]
82--      <- change cipher      -> change cipher
83--      <- finish             -> finish
84--      -> change cipher      <- change cipher
85--      -> finish             <- finish
86--
87handshakeServerWith :: ServerParams -> Context -> Handshake -> IO ()
88handshakeServerWith sparams ctx clientHello@(ClientHello legacyVersion _ clientSession ciphers compressions exts _) = do
89    established <- ctxEstablished ctx
90    -- renego is not allowed in TLS 1.3
91    when (established /= NotEstablished) $ do
92        ver <- usingState_ ctx (getVersionWithDefault TLS10)
93        when (ver == TLS13) $ throwCore $ Error_Protocol ("renegotiation is not allowed in TLS 1.3", True, UnexpectedMessage)
94    -- rejecting client initiated renegotiation to prevent DOS.
95    eof <- ctxEOF ctx
96    let renegotiation = established == Established && not eof
97    when (renegotiation && not (supportedClientInitiatedRenegotiation $ ctxSupported ctx)) $
98        throwCore $ Error_Protocol ("renegotiation is not allowed", False, NoRenegotiation)
99    -- check if policy allow this new handshake to happens
100    handshakeAuthorized <- withMeasure ctx (onNewHandshake $ serverHooks sparams)
101    unless handshakeAuthorized (throwCore $ Error_HandshakePolicy "server: handshake denied")
102    updateMeasure ctx incrementNbHandshakes
103
104    -- Handle Client hello
105    processHandshake ctx clientHello
106
107    -- rejecting SSL2. RFC 6176
108    when (legacyVersion == SSL2) $ throwCore $ Error_Protocol ("SSL 2.0 is not supported", True, ProtocolVersion)
109    -- rejecting SSL3. RFC 7568
110    -- when (legacyVersion == SSL3) $ throwCore $ Error_Protocol ("SSL 3.0 is not supported", True, ProtocolVersion)
111
112    -- Fallback SCSV: RFC7507
113    -- TLS_FALLBACK_SCSV: {0x56, 0x00}
114    when (supportedFallbackScsv (ctxSupported ctx) &&
115          (0x5600 `elem` ciphers) &&
116          legacyVersion < TLS12) $
117        throwCore $ Error_Protocol ("fallback is not allowed", True, InappropriateFallback)
118    -- choosing TLS version
119    let clientVersions = case extensionLookup extensionID_SupportedVersions exts >>= extensionDecode MsgTClientHello of
120            Just (SupportedVersionsClientHello vers) -> vers
121            _                                        -> []
122        clientVersion = min TLS12 legacyVersion
123        serverVersions
124            | renegotiation = filter (< TLS13) (supportedVersions $ ctxSupported ctx)
125            | otherwise     = supportedVersions $ ctxSupported ctx
126        mVersion = debugVersionForced $ serverDebug sparams
127    chosenVersion <- case mVersion of
128      Just cver -> return cver
129      Nothing   ->
130        if (TLS13 `elem` serverVersions) && clientVersions /= [] then case findHighestVersionFrom13 clientVersions serverVersions of
131                  Nothing -> throwCore $ Error_Protocol ("client versions " ++ show clientVersions ++ " is not supported", True, ProtocolVersion)
132                  Just v  -> return v
133           else case findHighestVersionFrom clientVersion serverVersions of
134                  Nothing -> throwCore $ Error_Protocol ("client version " ++ show clientVersion ++ " is not supported", True, ProtocolVersion)
135                  Just v  -> return v
136
137    -- SNI (Server Name Indication)
138    let serverName = case extensionLookup extensionID_ServerName exts >>= extensionDecode MsgTClientHello of
139            Just (ServerName ns) -> listToMaybe (mapMaybe toHostName ns)
140                where toHostName (ServerNameHostName hostName) = Just hostName
141                      toHostName (ServerNameOther _)           = Nothing
142            _                    -> Nothing
143    maybe (return ()) (usingState_ ctx . setClientSNI) serverName
144
145    -- TLS version dependent
146    if chosenVersion <= TLS12 then
147        handshakeServerWithTLS12 sparams ctx chosenVersion exts ciphers serverName clientVersion compressions clientSession
148      else do
149        mapM_ ensureNullCompression compressions
150        -- fixme: we should check if the client random is the same as
151        -- that in the first client hello in the case of hello retry.
152        handshakeServerWithTLS13 sparams ctx chosenVersion exts ciphers serverName clientSession
153handshakeServerWith _ _ _ = throwCore $ Error_Protocol ("unexpected handshake message received in handshakeServerWith", True, HandshakeFailure)
154
155-- TLS 1.2 or earlier
156handshakeServerWithTLS12 :: ServerParams
157                         -> Context
158                         -> Version
159                         -> [ExtensionRaw]
160                         -> [CipherID]
161                         -> Maybe String
162                         -> Version
163                         -> [CompressionID]
164                         -> Session
165                         -> IO ()
166handshakeServerWithTLS12 sparams ctx chosenVersion exts ciphers serverName clientVersion compressions clientSession = do
167    extraCreds <- onServerNameIndication (serverHooks sparams) serverName
168    let allCreds = filterCredentials (isCredentialAllowed chosenVersion exts) $
169                       extraCreds `mappend` sharedCredentials (ctxShared ctx)
170
171    -- If compression is null, commonCompressions should be [0].
172    when (null commonCompressions) $ throwCore $
173        Error_Protocol ("no compression in common with the client", True, HandshakeFailure)
174
175    -- When selecting a cipher we must ensure that it is allowed for the
176    -- TLS version but also that all its key-exchange requirements
177    -- will be met.
178
179    -- Some ciphers require a signature and a hash.  With TLS 1.2 the hash
180    -- algorithm is selected from a combination of server configuration and
181    -- the client "supported_signatures" extension.  So we cannot pick
182    -- such a cipher if no hash is available for it.  It's best to skip this
183    -- cipher and pick another one (with another key exchange).
184
185    -- Cipher selection is performed in two steps: first server credentials
186    -- are flagged as not suitable for signature if not compatible with
187    -- negotiated signature parameters.  Then ciphers are evalutated from
188    -- the resulting credentials.
189
190    let possibleGroups   = negotiatedGroupsInCommon ctx exts
191        possibleECGroups = possibleGroups `intersect` availableECGroups
192        possibleFFGroups = possibleGroups `intersect` availableFFGroups
193        hasCommonGroupForECDHE = not (null possibleECGroups)
194        hasCommonGroupForFFDHE = not (null possibleFFGroups)
195        hasCustomGroupForFFDHE = isJust (serverDHEParams sparams)
196        canFFDHE = hasCustomGroupForFFDHE || hasCommonGroupForFFDHE
197        hasCommonGroup cipher =
198            case cipherKeyExchange cipher of
199                CipherKeyExchange_DH_Anon      -> canFFDHE
200                CipherKeyExchange_DHE_RSA      -> canFFDHE
201                CipherKeyExchange_DHE_DSS      -> canFFDHE
202                CipherKeyExchange_ECDHE_RSA    -> hasCommonGroupForECDHE
203                CipherKeyExchange_ECDHE_ECDSA  -> hasCommonGroupForECDHE
204                _                              -> True -- group not used
205
206        -- Ciphers are selected according to TLS version, availability of
207        -- (EC)DHE group and credential depending on key exchange.
208        cipherAllowed cipher   = cipherAllowedForVersion chosenVersion cipher && hasCommonGroup cipher
209        selectCipher credentials signatureCredentials = filter cipherAllowed (commonCiphers credentials signatureCredentials)
210
211        (creds, signatureCreds, ciphersFilteredVersion)
212            = case chosenVersion of
213                  TLS12 -> let -- Build a list of all hash/signature algorithms in common between
214                               -- client and server.
215                               possibleHashSigAlgs = hashAndSignaturesInCommon ctx exts
216
217                               -- Check that a candidate signature credential will be compatible with
218                               -- client & server hash/signature algorithms.  This returns Just Int
219                               -- in order to sort credentials according to server hash/signature
220                               -- preference.  When the certificate has no matching hash/signature in
221                               -- 'possibleHashSigAlgs' the result is Nothing, and the credential will
222                               -- not be used to sign.  This avoids a failure later in 'decideHashSig'.
223                               signingRank cred =
224                                   case credentialDigitalSignatureKey cred of
225                                       Just pub -> findIndex (pub `signatureCompatible`) possibleHashSigAlgs
226                                       Nothing  -> Nothing
227
228                               -- Finally compute credential lists and resulting cipher list.
229                               --
230                               -- We try to keep certificates supported by the client, but
231                               -- fallback to all credentials if this produces no suitable result
232                               -- (see RFC 5246 section 7.4.2 and RFC 8446 section 4.4.2.2).
233                               -- The condition is based on resulting (EC)DHE ciphers so that
234                               -- filtering credentials does not give advantage to a less secure
235                               -- key exchange like CipherKeyExchange_RSA or CipherKeyExchange_DH_Anon.
236                               cltCreds    = filterCredentialsWithHashSignatures exts allCreds
237                               sigCltCreds = filterSortCredentials signingRank cltCreds
238                               sigAllCreds = filterSortCredentials signingRank allCreds
239                               cltCiphers  = selectCipher cltCreds sigCltCreds
240                               allCiphers  = selectCipher allCreds sigAllCreds
241
242                               resultTuple = if cipherListCredentialFallback cltCiphers
243                                                 then (allCreds, sigAllCreds, allCiphers)
244                                                 else (cltCreds, sigCltCreds, cltCiphers)
245                            in resultTuple
246                  _     ->
247                    let sigAllCreds = filterCredentials (isJust . credentialDigitalSignatureKey) allCreds
248                        allCiphers  = selectCipher allCreds sigAllCreds
249                     in (allCreds, sigAllCreds, allCiphers)
250
251    -- The shared cipherlist can become empty after filtering for compatible
252    -- creds, check now before calling onCipherChoosing, which does not handle
253    -- empty lists.
254    when (null ciphersFilteredVersion) $ throwCore $
255        Error_Protocol ("no cipher in common with the client", True, HandshakeFailure)
256
257    let usedCipher = onCipherChoosing (serverHooks sparams) chosenVersion ciphersFilteredVersion
258
259    cred <- case cipherKeyExchange usedCipher of
260                CipherKeyExchange_RSA       -> return $ credentialsFindForDecrypting creds
261                CipherKeyExchange_DH_Anon   -> return   Nothing
262                CipherKeyExchange_DHE_RSA   -> return $ credentialsFindForSigning KX_RSA signatureCreds
263                CipherKeyExchange_DHE_DSS   -> return $ credentialsFindForSigning KX_DSS signatureCreds
264                CipherKeyExchange_ECDHE_RSA -> return $ credentialsFindForSigning KX_RSA signatureCreds
265                CipherKeyExchange_ECDHE_ECDSA -> return $ credentialsFindForSigning KX_ECDSA signatureCreds
266                _                           -> throwCore $ Error_Protocol ("key exchange algorithm not implemented", True, HandshakeFailure)
267
268    ems <- processExtendedMasterSec ctx chosenVersion MsgTClientHello exts
269    resumeSessionData <- case clientSession of
270            (Session (Just clientSessionId)) -> do
271                let resume = liftIO $ sessionResume (sharedSessionManager $ ctxShared ctx) clientSessionId
272                resume >>= validateSession serverName ems
273            (Session Nothing)                -> return Nothing
274
275    -- Currently, we don't send back EcPointFormats. In this case,
276    -- the client chooses EcPointFormat_Uncompressed.
277    case extensionLookup extensionID_EcPointFormats exts >>= extensionDecode MsgTClientHello of
278        Just (EcPointFormatsSupported fs) -> usingState_ ctx $ setClientEcPointFormatSuggest fs
279        _ -> return ()
280
281    doHandshake sparams cred ctx chosenVersion usedCipher usedCompression clientSession resumeSessionData exts
282
283  where
284        commonCiphers creds sigCreds = filter ((`elem` ciphers) . cipherID) (getCiphers sparams creds sigCreds)
285        commonCompressions    = compressionIntersectID (supportedCompressions $ ctxSupported ctx) compressions
286        usedCompression       = head commonCompressions
287
288        validateSession _   _   Nothing                     = return Nothing
289        validateSession sni ems m@(Just sd)
290            -- SessionData parameters are assumed to match the local server configuration
291            -- so we need to compare only to ClientHello inputs.  Abbreviated handshake
292            -- uses the same server_name than full handshake so the same
293            -- credentials (and thus ciphers) are available.
294            | clientVersion < sessionVersion sd             = return Nothing
295            | sessionCipher sd `notElem` ciphers            = return Nothing
296            | sessionCompression sd `notElem` compressions  = return Nothing
297            | isJust sni && sessionClientSNI sd /= sni      = return Nothing
298            | ems && not emsSession                         = return Nothing
299            | not ems && emsSession                         =
300                let err = "client resumes an EMS session without EMS"
301                 in throwCore $ Error_Protocol (err, True, HandshakeFailure)
302            | otherwise                                     = return m
303          where emsSession = SessionEMS `elem` sessionFlags sd
304
305doHandshake :: ServerParams -> Maybe Credential -> Context -> Version -> Cipher
306            -> Compression -> Session -> Maybe SessionData
307            -> [ExtensionRaw] -> IO ()
308doHandshake sparams mcred ctx chosenVersion usedCipher usedCompression clientSession resumeSessionData exts = do
309    case resumeSessionData of
310        Nothing -> do
311            handshakeSendServerData
312            liftIO $ contextFlush ctx
313            -- Receive client info until client Finished.
314            recvClientData sparams ctx
315            sendChangeCipherAndFinish ctx ServerRole
316        Just sessionData -> do
317            usingState_ ctx (setSession clientSession True)
318            serverhello <- makeServerHello clientSession
319            sendPacket ctx $ Handshake [serverhello]
320            let masterSecret = sessionSecret sessionData
321            usingHState ctx $ setMasterSecret chosenVersion ServerRole masterSecret
322            logKey ctx (MasterSecret masterSecret)
323            sendChangeCipherAndFinish ctx ServerRole
324            recvChangeCipherAndFinish ctx
325    handshakeTerminate ctx
326  where
327        ---
328        -- When the client sends a certificate, check whether
329        -- it is acceptable for the application.
330        --
331        ---
332        makeServerHello session = do
333            srand <- serverRandom ctx chosenVersion $ supportedVersions $ serverSupported sparams
334            case mcred of
335                Just cred          -> storePrivInfoServer ctx cred
336                _                  -> return () -- return a sensible error
337
338            -- in TLS12, we need to check as well the certificates we are sending if they have in the extension
339            -- the necessary bits set.
340            secReneg   <- usingState_ ctx getSecureRenegotiation
341            secRengExt <- if secReneg
342                    then do
343                            vf <- usingState_ ctx $ do
344                                    cvf <- getVerifiedData ClientRole
345                                    svf <- getVerifiedData ServerRole
346                                    return $ extensionEncode (SecureRenegotiation cvf $ Just svf)
347                            return [ ExtensionRaw extensionID_SecureRenegotiation vf ]
348                    else return []
349            ems <- usingHState ctx getExtendedMasterSec
350            let emsExt | ems = let raw = extensionEncode ExtendedMasterSecret
351                                in [ ExtensionRaw extensionID_ExtendedMasterSecret raw ]
352                       | otherwise = []
353            protoExt <- applicationProtocol ctx exts sparams
354            sniExt   <- do
355                resuming <- usingState_ ctx isSessionResuming
356                if resuming
357                  then return []
358                  else do
359                    msni <- usingState_ ctx getClientSNI
360                    case msni of
361                      -- RFC6066: In this event, the server SHALL include
362                      -- an extension of type "server_name" in the
363                      -- (extended) server hello. The "extension_data"
364                      -- field of this extension SHALL be empty.
365                      Just _  -> return [ ExtensionRaw extensionID_ServerName ""]
366                      Nothing -> return []
367            let extensions = sharedHelloExtensions (serverShared sparams)
368                          ++ secRengExt ++ emsExt ++ protoExt ++ sniExt
369            usingState_ ctx (setVersion chosenVersion)
370            usingHState ctx $ setServerHelloParameters chosenVersion srand usedCipher usedCompression
371            return $ ServerHello chosenVersion srand session (cipherID usedCipher)
372                                               (compressionID usedCompression) extensions
373
374        handshakeSendServerData = do
375            serverSession <- newSession ctx
376            usingState_ ctx (setSession serverSession False)
377            serverhello   <- makeServerHello serverSession
378            -- send ServerHello & Certificate & ServerKeyXchg & CertReq
379            let certMsg = case mcred of
380                            Just (srvCerts, _) -> Certificates srvCerts
381                            _                  -> Certificates $ CertificateChain []
382            sendPacket ctx $ Handshake [ serverhello, certMsg ]
383
384            -- send server key exchange if needed
385            skx <- case cipherKeyExchange usedCipher of
386                        CipherKeyExchange_DH_Anon -> Just <$> generateSKX_DH_Anon
387                        CipherKeyExchange_DHE_RSA -> Just <$> generateSKX_DHE KX_RSA
388                        CipherKeyExchange_DHE_DSS -> Just <$> generateSKX_DHE KX_DSS
389                        CipherKeyExchange_ECDHE_RSA -> Just <$> generateSKX_ECDHE KX_RSA
390                        CipherKeyExchange_ECDHE_ECDSA -> Just <$> generateSKX_ECDHE KX_ECDSA
391                        _                         -> return Nothing
392            maybe (return ()) (sendPacket ctx . Handshake . (:[]) . ServerKeyXchg) skx
393
394            -- FIXME we don't do this on a Anonymous server
395
396            -- When configured, send a certificate request with the DNs of all
397            -- configured CA certificates.
398            --
399            -- Client certificates MUST NOT be accepted if not requested.
400            --
401            when (serverWantClientCert sparams) $ do
402                usedVersion <- usingState_ ctx getVersion
403                let defaultCertTypes = [ CertificateType_RSA_Sign
404                                       , CertificateType_DSS_Sign
405                                       , CertificateType_ECDSA_Sign
406                                       ]
407                    (certTypes, hashSigs)
408                        | usedVersion < TLS12 = (defaultCertTypes, Nothing)
409                        | otherwise =
410                            let as = supportedHashSignatures $ ctxSupported ctx
411                             in (nub $ mapMaybe hashSigToCertType as, Just as)
412                    creq = CertRequest certTypes hashSigs
413                               (map extractCAname $ serverCACertificates sparams)
414                usingHState ctx $ setCertReqSent True
415                sendPacket ctx (Handshake [creq])
416
417            -- Send HelloDone
418            sendPacket ctx (Handshake [ServerHelloDone])
419
420        setup_DHE = do
421            let possibleFFGroups = negotiatedGroupsInCommon ctx exts `intersect` availableFFGroups
422            (dhparams, priv, pub) <-
423                    case possibleFFGroups of
424                        []  ->
425                            let dhparams = fromJust "server DHE Params" $ serverDHEParams sparams
426                             in case findFiniteFieldGroup dhparams of
427                                    Just g  -> do
428                                        usingHState ctx $ setNegotiatedGroup g
429                                        generateFFDHE ctx g
430                                    Nothing -> do
431                                        (priv, pub) <- generateDHE ctx dhparams
432                                        return (dhparams, priv, pub)
433                        g:_ -> do
434                            usingHState ctx $ setNegotiatedGroup g
435                            generateFFDHE ctx g
436
437            let serverParams = serverDHParamsFrom dhparams pub
438
439            usingHState ctx $ setServerDHParams serverParams
440            usingHState ctx $ setDHPrivate priv
441            return serverParams
442
443        -- Choosing a hash algorithm to sign (EC)DHE parameters
444        -- in ServerKeyExchange. Hash algorithm is not suggested by
445        -- the chosen cipher suite. So, it should be selected based on
446        -- the "signature_algorithms" extension in a client hello.
447        -- If RSA is also used for key exchange, this function is
448        -- not called.
449        decideHashSig pubKey = do
450            usedVersion <- usingState_ ctx getVersion
451            case usedVersion of
452              TLS12 -> do
453                  let hashSigs = hashAndSignaturesInCommon ctx exts
454                  case filter (pubKey `signatureCompatible`) hashSigs of
455                      []  -> error ("no hash signature for " ++ pubkeyType pubKey)
456                      x:_ -> return $ Just x
457              _     -> return Nothing
458
459        generateSKX_DHE kxsAlg = do
460            serverParams  <- setup_DHE
461            pubKey <- getLocalPublicKey ctx
462            mhashSig <- decideHashSig pubKey
463            signed <- digitallySignDHParams ctx serverParams pubKey mhashSig
464            case kxsAlg of
465                KX_RSA -> return $ SKX_DHE_RSA serverParams signed
466                KX_DSS -> return $ SKX_DHE_DSS serverParams signed
467                _      -> error ("generate skx_dhe unsupported key exchange signature: " ++ show kxsAlg)
468
469        generateSKX_DH_Anon = SKX_DH_Anon <$> setup_DHE
470
471        setup_ECDHE grp = do
472            usingHState ctx $ setNegotiatedGroup grp
473            (srvpri, srvpub) <- generateECDHE ctx grp
474            let serverParams = ServerECDHParams grp srvpub
475            usingHState ctx $ setServerECDHParams serverParams
476            usingHState ctx $ setGroupPrivate srvpri
477            return serverParams
478
479        generateSKX_ECDHE kxsAlg = do
480            let possibleECGroups = negotiatedGroupsInCommon ctx exts `intersect` availableECGroups
481            grp <- case possibleECGroups of
482                     []  -> throwCore $ Error_Protocol ("no common group", True, HandshakeFailure)
483                     g:_ -> return g
484            serverParams <- setup_ECDHE grp
485            pubKey <- getLocalPublicKey ctx
486            mhashSig <- decideHashSig pubKey
487            signed <- digitallySignECDHParams ctx serverParams pubKey mhashSig
488            case kxsAlg of
489                KX_RSA   -> return $ SKX_ECDHE_RSA serverParams signed
490                KX_ECDSA -> return $ SKX_ECDHE_ECDSA serverParams signed
491                _        -> error ("generate skx_ecdhe unsupported key exchange signature: " ++ show kxsAlg)
492
493        -- create a DigitallySigned objects for DHParams or ECDHParams.
494
495-- | receive Client data in handshake until the Finished handshake.
496--
497--      <- [certificate]
498--      <- client key xchg
499--      <- [cert verify]
500--      <- change cipher
501--      <- finish
502--
503recvClientData :: ServerParams -> Context -> IO ()
504recvClientData sparams ctx = runRecvState ctx (RecvStateHandshake processClientCertificate)
505  where processClientCertificate (Certificates certs) = do
506            clientCertificate sparams ctx certs
507
508            -- FIXME: We should check whether the certificate
509            -- matches our request and that we support
510            -- verifying with that certificate.
511
512            return $ RecvStateHandshake processClientKeyExchange
513
514        processClientCertificate p = processClientKeyExchange p
515
516        -- cannot use RecvStateHandshake, as the next message could be a ChangeCipher,
517        -- so we must process any packet, and in case of handshake call processHandshake manually.
518        processClientKeyExchange (ClientKeyXchg _) = return $ RecvStateNext processCertificateVerify
519        processClientKeyExchange p                 = unexpected (show p) (Just "client key exchange")
520
521        -- Check whether the client correctly signed the handshake.
522        -- If not, ask the application on how to proceed.
523        --
524        processCertificateVerify (Handshake [hs@(CertVerify dsig)]) = do
525            processHandshake ctx hs
526
527            certs <- checkValidClientCertChain ctx "change cipher message expected"
528
529            usedVersion <- usingState_ ctx getVersion
530            -- Fetch all handshake messages up to now.
531            msgs  <- usingHState ctx $ B.concat <$> getHandshakeMessages
532
533            pubKey <- usingHState ctx getRemotePublicKey
534            checkDigitalSignatureKey usedVersion pubKey
535
536            verif <- checkCertificateVerify ctx usedVersion pubKey msgs dsig
537            clientCertVerify sparams ctx certs verif
538            return $ RecvStateNext expectChangeCipher
539
540        processCertificateVerify p = do
541            chain <- usingHState ctx getClientCertChain
542            case chain of
543                Just cc | isNullCertificateChain cc -> return ()
544                        | otherwise                 -> throwCore $ Error_Protocol ("cert verify message missing", True, UnexpectedMessage)
545                Nothing -> return ()
546            expectChangeCipher p
547
548        expectChangeCipher ChangeCipherSpec = do
549            return $ RecvStateHandshake expectFinish
550
551        expectChangeCipher p                = unexpected (show p) (Just "change cipher")
552
553        expectFinish (Finished _) = return RecvStateDone
554        expectFinish p            = unexpected (show p) (Just "Handshake Finished")
555
556checkValidClientCertChain :: MonadIO m => Context -> String -> m CertificateChain
557checkValidClientCertChain ctx errmsg = do
558    chain <- usingHState ctx getClientCertChain
559    let throwerror = Error_Protocol (errmsg , True, UnexpectedMessage)
560    case chain of
561        Nothing -> throwCore throwerror
562        Just cc | isNullCertificateChain cc -> throwCore throwerror
563                | otherwise                 -> return cc
564
565hashAndSignaturesInCommon :: Context -> [ExtensionRaw] -> [HashAndSignatureAlgorithm]
566hashAndSignaturesInCommon ctx exts =
567    let cHashSigs = case extensionLookup extensionID_SignatureAlgorithms exts >>= extensionDecode MsgTClientHello of
568            -- See Section 7.4.1.4.1 of RFC 5246.
569            Nothing -> [(HashSHA1, SignatureECDSA)
570                       ,(HashSHA1, SignatureRSA)
571                       ,(HashSHA1, SignatureDSS)]
572            Just (SignatureAlgorithms sas) -> sas
573        sHashSigs = supportedHashSignatures $ ctxSupported ctx
574        -- The values in the "signature_algorithms" extension
575        -- are in descending order of preference.
576        -- However here the algorithms are selected according
577        -- to server preference in 'supportedHashSignatures'.
578     in sHashSigs `intersect` cHashSigs
579
580negotiatedGroupsInCommon :: Context -> [ExtensionRaw] -> [Group]
581negotiatedGroupsInCommon ctx exts = case extensionLookup extensionID_NegotiatedGroups exts >>= extensionDecode MsgTClientHello of
582    Just (NegotiatedGroups clientGroups) ->
583        let serverGroups = supportedGroups (ctxSupported ctx)
584        in serverGroups `intersect` clientGroups
585    _                                    -> []
586
587credentialDigitalSignatureKey :: Credential -> Maybe PubKey
588credentialDigitalSignatureKey cred
589    | isDigitalSignaturePair keys = Just pubkey
590    | otherwise = Nothing
591  where keys@(pubkey, _) = credentialPublicPrivateKeys cred
592
593filterCredentials :: (Credential -> Bool) -> Credentials -> Credentials
594filterCredentials p (Credentials l) = Credentials (filter p l)
595
596filterSortCredentials :: Ord a => (Credential -> Maybe a) -> Credentials -> Credentials
597filterSortCredentials rankFun (Credentials creds) =
598    let orderedPairs = sortOn fst [ (rankFun cred, cred) | cred <- creds ]
599     in Credentials [ cred | (Just _, cred) <- orderedPairs ]
600
601isCredentialAllowed :: Version -> [ExtensionRaw] -> Credential -> Bool
602isCredentialAllowed ver exts cred =
603    pubkey `versionCompatible` ver && satisfiesEcPredicate p pubkey
604  where
605    (pubkey, _) = credentialPublicPrivateKeys cred
606    -- ECDSA keys are tested against supported elliptic curves until TLS12 but
607    -- not after.  With TLS13, the curve is linked to the signature algorithm
608    -- and client support is tested with signatureCompatible13.
609    p | ver < TLS13 = case extensionLookup extensionID_NegotiatedGroups exts >>= extensionDecode MsgTClientHello of
610          Nothing                    -> const True
611          Just (NegotiatedGroups sg) -> (`elem` sg)
612      | otherwise   = const True
613
614-- Filters a list of candidate credentials with credentialMatchesHashSignatures.
615--
616-- Algorithms to filter with are taken from "signature_algorithms_cert"
617-- extension when it exists, else from "signature_algorithms" when clients do
618-- not implement the new extension (see RFC 8446 section 4.2.3).
619--
620-- Resulting credential list can be used as input to the hybrid cipher-and-
621-- certificate selection for TLS12, or to the direct certificate selection
622-- simplified with TLS13.  As filtering credential signatures with client-
623-- advertised algorithms is not supposed to cause negotiation failure, in case
624-- of dead end with the subsequent selection process, this process should always
625-- be restarted with the unfiltered credential list as input (see fallback
626-- certificate chains, described in same RFC section).
627--
628-- Calling code should not forget to apply constraints of extension
629-- "signature_algorithms" to any signature-based key exchange derived from the
630-- output credentials.  Respecting client constraints on KX signatures is
631-- mandatory but not implemented by this function.
632filterCredentialsWithHashSignatures :: [ExtensionRaw] -> Credentials -> Credentials
633filterCredentialsWithHashSignatures exts =
634    case withExt extensionID_SignatureAlgorithmsCert of
635        Just (SignatureAlgorithmsCert sas) -> withAlgs sas
636        Nothing ->
637            case withExt extensionID_SignatureAlgorithms of
638                Nothing                        -> id
639                Just (SignatureAlgorithms sas) -> withAlgs sas
640  where
641    withExt extId = extensionLookup extId exts >>= extensionDecode MsgTClientHello
642    withAlgs sas = filterCredentials (credentialMatchesHashSignatures sas)
643
644-- returns True if certificate filtering with "signature_algorithms_cert" /
645-- "signature_algorithms" produced no ephemeral D-H nor TLS13 cipher (so
646-- handshake with lower security)
647cipherListCredentialFallback :: [Cipher] -> Bool
648cipherListCredentialFallback = all nonDH
649  where
650    nonDH x = case cipherKeyExchange x of
651        CipherKeyExchange_DHE_RSA     -> False
652        CipherKeyExchange_DHE_DSS     -> False
653        CipherKeyExchange_ECDHE_RSA   -> False
654        CipherKeyExchange_ECDHE_ECDSA -> False
655        CipherKeyExchange_TLS13       -> False
656        _                             -> True
657
658storePrivInfoServer :: MonadIO m => Context -> Credential -> m ()
659storePrivInfoServer ctx (cc, privkey) = void (storePrivInfo ctx cc privkey)
660
661-- TLS 1.3 or later
662handshakeServerWithTLS13 :: ServerParams
663                         -> Context
664                         -> Version
665                         -> [ExtensionRaw]
666                         -> [CipherID]
667                         -> Maybe String
668                         -> Session
669                         -> IO ()
670handshakeServerWithTLS13 sparams ctx chosenVersion exts clientCiphers _serverName clientSession = do
671    when (any (\(ExtensionRaw eid _) -> eid == extensionID_PreSharedKey) $ init exts) $
672        throwCore $ Error_Protocol ("extension pre_shared_key must be last", True, IllegalParameter)
673    -- Deciding cipher.
674    -- The shared cipherlist can become empty after filtering for compatible
675    -- creds, check now before calling onCipherChoosing, which does not handle
676    -- empty lists.
677    when (null ciphersFilteredVersion) $ throwCore $
678        Error_Protocol ("no cipher in common with the client", True, HandshakeFailure)
679    let usedCipher = onCipherChoosing (serverHooks sparams) chosenVersion ciphersFilteredVersion
680        usedHash = cipherHash usedCipher
681        rtt0 = case extensionLookup extensionID_EarlyData exts >>= extensionDecode MsgTClientHello of
682                 Just (EarlyDataIndication _) -> True
683                 Nothing                      -> False
684    when rtt0 $
685        -- mark a 0-RTT attempt before a possible HRR, and before updating the
686        -- status again if 0-RTT successful
687        setEstablished ctx (EarlyDataNotAllowed 3) -- hardcoding
688    -- Deciding key exchange from key shares
689    keyShares <- case extensionLookup extensionID_KeyShare exts >>= extensionDecode MsgTClientHello of
690          Just (KeyShareClientHello kses) -> return kses
691          Just _                          -> error "handshakeServerWithTLS13: invalid KeyShare value"
692          _                               -> throwCore $ Error_Protocol ("key exchange not implemented, expected key_share extension", True, HandshakeFailure)
693    case findKeyShare keyShares serverGroups of
694      Nothing -> helloRetryRequest sparams ctx chosenVersion usedCipher exts serverGroups clientSession
695      Just keyShare -> doHandshake13 sparams ctx chosenVersion usedCipher exts usedHash keyShare clientSession rtt0
696  where
697    ciphersFilteredVersion = filter ((`elem` clientCiphers) . cipherID) serverCiphers
698    serverCiphers = filter (cipherAllowedForVersion chosenVersion) (supportedCiphers $ serverSupported sparams)
699    serverGroups = supportedGroups (ctxSupported ctx)
700    findKeyShare _      [] = Nothing
701    findKeyShare ks (g:gs) = case find (\ent -> keyShareEntryGroup ent == g) ks of
702      Just k  -> Just k
703      Nothing -> findKeyShare ks gs
704
705doHandshake13 :: ServerParams -> Context -> Version
706              -> Cipher -> [ExtensionRaw]
707              -> Hash -> KeyShareEntry
708              -> Session -> Bool
709              -> IO ()
710doHandshake13 sparams ctx chosenVersion usedCipher exts usedHash clientKeyShare clientSession rtt0 = do
711    newSession ctx >>= \ss -> usingState_ ctx $ do
712        setSession ss False
713        setClientSupportsPHA supportsPHA
714    usingHState ctx $ setNegotiatedGroup $ keyShareEntryGroup clientKeyShare
715    srand <- setServerParameter
716    -- ALPN is used in choosePSK
717    protoExt <- applicationProtocol ctx exts sparams
718    (psk, binderInfo, is0RTTvalid) <- choosePSK
719    earlyKey <- calculateEarlySecret ctx choice (Left psk) True
720    let earlySecret = pairBase earlyKey
721        clientEarlySecret = pairClient earlyKey
722    extensions <- checkBinder earlySecret binderInfo
723    hrr <- usingState_ ctx getTLS13HRR
724    let authenticated = isJust binderInfo
725        rtt0OK = authenticated && not hrr && rtt0 && rtt0accept && is0RTTvalid
726    extraCreds <- usingState_ ctx getClientSNI >>= onServerNameIndication (serverHooks sparams)
727    let allCreds = filterCredentials (isCredentialAllowed chosenVersion exts) $
728                       extraCreds `mappend` sharedCredentials (ctxShared ctx)
729    ----------------------------------------------------------------
730    established <- ctxEstablished ctx
731    if established /= NotEstablished then
732         if rtt0OK then do
733             usingHState ctx $ setTLS13HandshakeMode RTT0
734             usingHState ctx $ setTLS13RTT0Status RTT0Accepted
735           else do
736             usingHState ctx $ setTLS13HandshakeMode RTT0
737             usingHState ctx $ setTLS13RTT0Status RTT0Rejected
738       else
739         if authenticated then
740             usingHState ctx $ setTLS13HandshakeMode PreSharedKey
741           else
742             -- FullHandshake or HelloRetryRequest
743             return ()
744    mCredInfo <- if authenticated then return Nothing else decideCredentialInfo allCreds
745    (ecdhe,keyShare) <- makeServerKeyShare ctx clientKeyShare
746    ensureRecvComplete ctx
747    (clientHandshakeSecret, handSecret) <- runPacketFlight ctx $ do
748        sendServerHello keyShare srand extensions
749        sendChangeCipherSpec13 ctx
750    ----------------------------------------------------------------
751        handKey <- liftIO $ calculateHandshakeSecret ctx choice earlySecret ecdhe
752        let serverHandshakeSecret = triServer handKey
753            clientHandshakeSecret = triClient handKey
754            handSecret = triBase handKey
755        liftIO $ do
756            if rtt0OK && not (ctxQUICMode ctx)
757                then setRxState ctx usedHash usedCipher clientEarlySecret
758                else setRxState ctx usedHash usedCipher clientHandshakeSecret
759            setTxState ctx usedHash usedCipher serverHandshakeSecret
760            let mEarlySecInfo
761                 | rtt0OK      = Just $ EarlySecretInfo usedCipher clientEarlySecret
762                 | otherwise   = Nothing
763                handSecInfo = HandshakeSecretInfo usedCipher (clientHandshakeSecret,serverHandshakeSecret)
764            contextSync ctx $ SendServerHello exts mEarlySecInfo handSecInfo
765    ----------------------------------------------------------------
766        sendExtensions rtt0OK protoExt
767        case mCredInfo of
768            Nothing              -> return ()
769            Just (cred, hashSig) -> sendCertAndVerify cred hashSig
770        let ServerTrafficSecret shs = serverHandshakeSecret
771        rawFinished <- makeFinished ctx usedHash shs
772        loadPacket13 ctx $ Handshake13 [rawFinished]
773        return (clientHandshakeSecret, handSecret)
774    sfSentTime <- getCurrentTimeFromBase
775    ----------------------------------------------------------------
776    hChSf <- transcriptHash ctx
777    appKey <- calculateApplicationSecret ctx choice handSecret hChSf
778    let clientApplicationSecret0 = triClient appKey
779        serverApplicationSecret0 = triServer appKey
780        applicationSecret = triBase appKey
781    setTxState ctx usedHash usedCipher serverApplicationSecret0
782    let appSecInfo = ApplicationSecretInfo (clientApplicationSecret0,serverApplicationSecret0)
783    contextSync ctx $ SendServerFinished appSecInfo
784    ----------------------------------------------------------------
785    if rtt0OK then
786        setEstablished ctx (EarlyDataAllowed rtt0max)
787      else when (established == NotEstablished) $
788        setEstablished ctx (EarlyDataNotAllowed 3) -- hardcoding
789
790    let expectFinished hChBeforeCf (Finished13 verifyData) = liftIO $ do
791            let ClientTrafficSecret chs = clientHandshakeSecret
792            checkFinished usedHash chs hChBeforeCf verifyData
793            handshakeTerminate13 ctx
794            setRxState ctx usedHash usedCipher clientApplicationSecret0
795            sendNewSessionTicket applicationSecret sfSentTime
796        expectFinished _ hs = unexpected (show hs) (Just "finished 13")
797
798    let expectEndOfEarlyData EndOfEarlyData13 =
799            setRxState ctx usedHash usedCipher clientHandshakeSecret
800        expectEndOfEarlyData hs = unexpected (show hs) (Just "end of early data")
801
802    if not authenticated && serverWantClientCert sparams then
803        runRecvHandshake13 $ do
804          skip <- recvHandshake13 ctx expectCertificate
805          unless skip $ recvHandshake13hash ctx (expectCertVerify sparams ctx)
806          recvHandshake13hash ctx expectFinished
807          ensureRecvComplete ctx
808      else if rtt0OK && not (ctxQUICMode ctx) then
809        setPendingActions ctx [PendingAction True expectEndOfEarlyData
810                              ,PendingActionHash True expectFinished]
811      else
812        runRecvHandshake13 $ do
813          recvHandshake13hash ctx expectFinished
814          ensureRecvComplete ctx
815  where
816    choice = makeCipherChoice chosenVersion usedCipher
817
818    setServerParameter = do
819        srand <- serverRandom ctx chosenVersion $ supportedVersions $ serverSupported sparams
820        usingState_ ctx $ setVersion chosenVersion
821        failOnEitherError $ usingHState ctx $ setHelloParameters13 usedCipher
822        return srand
823
824    supportsPHA = case extensionLookup extensionID_PostHandshakeAuth exts >>= extensionDecode MsgTClientHello of
825        Just PostHandshakeAuth -> True
826        Nothing                -> False
827
828    choosePSK = case extensionLookup extensionID_PreSharedKey exts >>= extensionDecode MsgTClientHello of
829      Just (PreSharedKeyClientHello (PskIdentity sessionId obfAge:_) bnds@(bnd:_)) -> do
830          when (null dhModes) $
831              throwCore $ Error_Protocol ("no psk_key_exchange_modes extension", True, MissingExtension)
832          if PSK_DHE_KE `elem` dhModes then do
833              let len = sum (map (\x -> B.length x + 1) bnds) + 2
834                  mgr = sharedSessionManager $ serverShared sparams
835              msdata <- if rtt0 then sessionResumeOnlyOnce mgr sessionId
836                                else sessionResume mgr sessionId
837              case msdata of
838                Just sdata -> do
839                    let Just tinfo = sessionTicketInfo sdata
840                        psk = sessionSecret sdata
841                    isFresh <- checkFreshness tinfo obfAge
842                    (isPSKvalid, is0RTTvalid) <- checkSessionEquality sdata
843                    if isPSKvalid && isFresh then
844                        return (psk, Just (bnd,0::Int,len),is0RTTvalid)
845                      else
846                        -- fall back to full handshake
847                        return (zero, Nothing, False)
848                _      -> return (zero, Nothing, False)
849              else return (zero, Nothing, False)
850      _ -> return (zero, Nothing, False)
851
852    checkSessionEquality sdata = do
853        msni <- usingState_ ctx getClientSNI
854        malpn <- usingState_ ctx getNegotiatedProtocol
855        let isSameSNI = sessionClientSNI sdata == msni
856            isSameCipher = sessionCipher sdata == cipherID usedCipher
857            ciphers = supportedCiphers $ serverSupported sparams
858            isSameKDF = case find (\c -> cipherID c == sessionCipher sdata) ciphers of
859                Nothing -> False
860                Just c  -> cipherHash c == cipherHash usedCipher
861            isSameVersion = chosenVersion == sessionVersion sdata
862            isSameALPN = sessionALPN sdata == malpn
863            isPSKvalid = isSameKDF && isSameSNI -- fixme: SNI is not required
864            is0RTTvalid = isSameVersion && isSameCipher && isSameALPN
865        return (isPSKvalid, is0RTTvalid)
866
867    rtt0max = safeNonNegative32 $ serverEarlyDataSize sparams
868    rtt0accept = serverEarlyDataSize sparams > 0
869
870    checkBinder _ Nothing = return []
871    checkBinder earlySecret (Just (binder,n,tlen)) = do
872        binder' <- makePSKBinder ctx earlySecret usedHash tlen Nothing
873        unless (binder `bytesEq` binder') $
874            decryptError "PSK binder validation failed"
875        let selectedIdentity = extensionEncode $ PreSharedKeyServerHello $ fromIntegral n
876        return [ExtensionRaw extensionID_PreSharedKey selectedIdentity]
877
878    decideCredentialInfo allCreds = do
879        cHashSigs <- case extensionLookup extensionID_SignatureAlgorithms exts >>= extensionDecode MsgTClientHello of
880            Nothing -> throwCore $ Error_Protocol ("no signature_algorithms extension", True, MissingExtension)
881            Just (SignatureAlgorithms sas) -> return sas
882        -- When deciding signature algorithm and certificate, we try to keep
883        -- certificates supported by the client, but fallback to all credentials
884        -- if this produces no suitable result (see RFC 5246 section 7.4.2 and
885        -- RFC 8446 section 4.4.2.2).
886        let sHashSigs = filter isHashSignatureValid13 $ supportedHashSignatures $ ctxSupported ctx
887            hashSigs = sHashSigs `intersect` cHashSigs
888            cltCreds = filterCredentialsWithHashSignatures exts allCreds
889        case credentialsFindForSigning13 hashSigs cltCreds of
890            Nothing ->
891                case credentialsFindForSigning13 hashSigs allCreds of
892                    Nothing -> throwCore $ Error_Protocol ("credential not found", True, HandshakeFailure)
893                    mcs -> return mcs
894            mcs -> return mcs
895
896    sendServerHello keyShare srand extensions = do
897        let serverKeyShare = extensionEncode $ KeyShareServerHello keyShare
898            selectedVersion = extensionEncode $ SupportedVersionsServerHello chosenVersion
899            extensions' = ExtensionRaw extensionID_KeyShare serverKeyShare
900                        : ExtensionRaw extensionID_SupportedVersions selectedVersion
901                        : extensions
902            helo = ServerHello13 srand clientSession (cipherID usedCipher) extensions'
903        loadPacket13 ctx $ Handshake13 [helo]
904
905    sendCertAndVerify cred@(certChain, _) hashSig = do
906        storePrivInfoServer ctx cred
907        when (serverWantClientCert sparams) $ do
908            let certReqCtx = "" -- this must be zero length here.
909                certReq = makeCertRequest sparams ctx certReqCtx
910            loadPacket13 ctx $ Handshake13 [certReq]
911            usingHState ctx $ setCertReqSent True
912
913        let CertificateChain cs = certChain
914            ess = replicate (length cs) []
915        loadPacket13 ctx $ Handshake13 [Certificate13 "" certChain ess]
916        hChSc <- transcriptHash ctx
917        pubkey <- getLocalPublicKey ctx
918        vrfy <- makeCertVerify ctx pubkey hashSig hChSc
919        loadPacket13 ctx $ Handshake13 [vrfy]
920
921    sendExtensions rtt0OK protoExt = do
922        msni <- liftIO $ usingState_ ctx getClientSNI
923        let sniExtension = case msni of
924              -- RFC6066: In this event, the server SHALL include
925              -- an extension of type "server_name" in the
926              -- (extended) server hello. The "extension_data"
927              -- field of this extension SHALL be empty.
928              Just _  -> Just $ ExtensionRaw extensionID_ServerName ""
929              Nothing -> Nothing
930        mgroup <- usingHState ctx getNegotiatedGroup
931        let serverGroups = supportedGroups (ctxSupported ctx)
932            groupExtension
933              | null serverGroups = Nothing
934              | maybe True (== head serverGroups) mgroup = Nothing
935              | otherwise = Just $ ExtensionRaw extensionID_NegotiatedGroups $ extensionEncode (NegotiatedGroups serverGroups)
936        let earlyDataExtension
937              | rtt0OK = Just $ ExtensionRaw extensionID_EarlyData $ extensionEncode (EarlyDataIndication Nothing)
938              | otherwise = Nothing
939        let extensions = sharedHelloExtensions (serverShared sparams)
940                      ++ catMaybes [earlyDataExtension
941                                   ,groupExtension
942                                   ,sniExtension
943                                   ]
944                      ++ protoExt
945        loadPacket13 ctx $ Handshake13 [EncryptedExtensions13 extensions]
946
947    sendNewSessionTicket applicationSecret sfSentTime = when sendNST $ do
948        cfRecvTime <- getCurrentTimeFromBase
949        let rtt = cfRecvTime - sfSentTime
950        nonce <- getStateRNG ctx 32
951        resumptionMasterSecret <- calculateResumptionSecret ctx choice applicationSecret
952        let life = toSeconds $ serverTicketLifetime sparams
953            psk = derivePSK choice resumptionMasterSecret nonce
954        (label, add) <- generateSession life psk rtt0max rtt
955        let nst = createNewSessionTicket life add nonce label rtt0max
956        sendPacket13 ctx $ Handshake13 [nst]
957      where
958        sendNST = PSK_DHE_KE `elem` dhModes
959        generateSession life psk maxSize rtt = do
960            Session (Just sessionId) <- newSession ctx
961            tinfo <- createTLS13TicketInfo life (Left ctx) (Just rtt)
962            sdata <- getSessionData13 ctx usedCipher tinfo maxSize psk
963            let mgr = sharedSessionManager $ serverShared sparams
964            sessionEstablish mgr sessionId sdata
965            return (sessionId, ageAdd tinfo)
966        createNewSessionTicket life add nonce label maxSize =
967            NewSessionTicket13 life add nonce label extensions
968          where
969            tedi = extensionEncode $ EarlyDataIndication $ Just $ fromIntegral maxSize
970            extensions = [ExtensionRaw extensionID_EarlyData tedi]
971        toSeconds i | i < 0      = 0
972                    | i > 604800 = 604800
973                    | otherwise  = fromIntegral i
974
975    dhModes = case extensionLookup extensionID_PskKeyExchangeModes exts >>= extensionDecode MsgTClientHello of
976      Just (PskKeyExchangeModes ms) -> ms
977      Nothing                       -> []
978
979    expectCertificate :: Handshake13 -> RecvHandshake13M IO Bool
980    expectCertificate (Certificate13 certCtx certs _ext) = liftIO $ do
981        when (certCtx /= "") $ throwCore $ Error_Protocol ("certificate request context MUST be empty", True, IllegalParameter)
982        -- fixme checking _ext
983        clientCertificate sparams ctx certs
984        return $ isNullCertificateChain certs
985    expectCertificate hs = unexpected (show hs) (Just "certificate 13")
986
987    hashSize = hashDigestSize usedHash
988    zero = B.replicate hashSize 0
989
990expectCertVerify :: MonadIO m => ServerParams -> Context -> ByteString -> Handshake13 -> m ()
991expectCertVerify sparams ctx hChCc (CertVerify13 sigAlg sig) = liftIO $ do
992    certs@(CertificateChain cc) <- checkValidClientCertChain ctx "finished 13 message expected"
993    pubkey <- case cc of
994                [] -> throwCore $ Error_Protocol ("client certificate missing", True, HandshakeFailure)
995                c:_ -> return $ certPubKey $ getCertificate c
996    ver <- usingState_ ctx getVersion
997    checkDigitalSignatureKey ver pubkey
998    usingHState ctx $ setPublicKey pubkey
999    verif <- checkCertVerify ctx pubkey sigAlg sig hChCc
1000    clientCertVerify sparams ctx certs verif
1001expectCertVerify _ _ _ hs = unexpected (show hs) (Just "certificate verify 13")
1002
1003helloRetryRequest :: ServerParams -> Context -> Version -> Cipher -> [ExtensionRaw] -> [Group] -> Session -> IO ()
1004helloRetryRequest sparams ctx chosenVersion usedCipher exts serverGroups clientSession = do
1005    twice <- usingState_ ctx getTLS13HRR
1006    when twice $
1007        throwCore $ Error_Protocol ("Hello retry not allowed again", True, HandshakeFailure)
1008    usingState_ ctx $ setTLS13HRR True
1009    failOnEitherError $ usingHState ctx $ setHelloParameters13 usedCipher
1010    let clientGroups = case extensionLookup extensionID_NegotiatedGroups exts >>= extensionDecode MsgTClientHello of
1011          Just (NegotiatedGroups gs) -> gs
1012          Nothing                    -> []
1013        possibleGroups = serverGroups `intersect` clientGroups
1014    case possibleGroups of
1015      [] -> throwCore $ Error_Protocol ("no group in common with the client for HRR", True, HandshakeFailure)
1016      g:_ -> do
1017          let serverKeyShare = extensionEncode $ KeyShareHRR g
1018              selectedVersion = extensionEncode $ SupportedVersionsServerHello chosenVersion
1019              extensions = [ExtensionRaw extensionID_KeyShare serverKeyShare
1020                           ,ExtensionRaw extensionID_SupportedVersions selectedVersion]
1021              hrr = ServerHello13 hrrRandom clientSession (cipherID usedCipher) extensions
1022          usingHState ctx $ setTLS13HandshakeMode HelloRetryRequest
1023          runPacketFlight ctx $ do
1024                loadPacket13 ctx $ Handshake13 [hrr]
1025                sendChangeCipherSpec13 ctx
1026          handshakeServer sparams ctx
1027
1028findHighestVersionFrom :: Version -> [Version] -> Maybe Version
1029findHighestVersionFrom clientVersion allowedVersions =
1030    case filter (clientVersion >=) $ sortOn Down allowedVersions of
1031        []  -> Nothing
1032        v:_ -> Just v
1033
1034-- We filter our allowed ciphers here according to dynamic credential lists.
1035-- Credentials 'creds' come from server parameters but also SNI callback.
1036-- When the key exchange requires a signature, we use a
1037-- subset of this list named 'sigCreds'.  This list has been filtered in order
1038-- to remove certificates that are not compatible with hash/signature
1039-- restrictions (TLS 1.2).
1040getCiphers :: ServerParams -> Credentials -> Credentials -> [Cipher]
1041getCiphers sparams creds sigCreds = filter authorizedCKE (supportedCiphers $ serverSupported sparams)
1042      where authorizedCKE cipher =
1043                case cipherKeyExchange cipher of
1044                    CipherKeyExchange_RSA         -> canEncryptRSA
1045                    CipherKeyExchange_DH_Anon     -> True
1046                    CipherKeyExchange_DHE_RSA     -> canSignRSA
1047                    CipherKeyExchange_DHE_DSS     -> canSignDSS
1048                    CipherKeyExchange_ECDHE_RSA   -> canSignRSA
1049                    CipherKeyExchange_ECDHE_ECDSA -> canSignECDSA
1050                    -- unimplemented: non ephemeral DH & ECDH.
1051                    -- Note, these *should not* be implemented, and have
1052                    -- (for example) been removed in OpenSSL 1.1.0
1053                    --
1054                    CipherKeyExchange_DH_DSS      -> False
1055                    CipherKeyExchange_DH_RSA      -> False
1056                    CipherKeyExchange_ECDH_ECDSA  -> False
1057                    CipherKeyExchange_ECDH_RSA    -> False
1058                    CipherKeyExchange_TLS13       -> False -- not reached
1059
1060            canSignDSS    = KX_DSS `elem` signingAlgs
1061            canSignRSA    = KX_RSA `elem` signingAlgs
1062            canSignECDSA  = KX_ECDSA `elem` signingAlgs
1063            canEncryptRSA = isJust $ credentialsFindForDecrypting creds
1064            signingAlgs   = credentialsListSigningAlgorithms sigCreds
1065
1066findHighestVersionFrom13 :: [Version] -> [Version] -> Maybe Version
1067findHighestVersionFrom13 clientVersions serverVersions = case svs `intersect` cvs of
1068        []  -> Nothing
1069        v:_ -> Just v
1070  where
1071    svs = sortOn Down serverVersions
1072    cvs = sortOn Down clientVersions
1073
1074applicationProtocol :: Context -> [ExtensionRaw] -> ServerParams -> IO [ExtensionRaw]
1075applicationProtocol ctx exts sparams = do
1076    -- ALPN (Application Layer Protocol Negotiation)
1077    case extensionLookup extensionID_ApplicationLayerProtocolNegotiation exts >>= extensionDecode MsgTClientHello of
1078        Nothing -> return []
1079        Just (ApplicationLayerProtocolNegotiation protos) -> do
1080            case onALPNClientSuggest $ serverHooks sparams of
1081                Just io -> do
1082                    proto <- io protos
1083                    when (proto == "") $
1084                        throwCore $ Error_Protocol ("no supported application protocols", True, NoApplicationProtocol)
1085                    usingState_ ctx $ do
1086                        setExtensionALPN True
1087                        setNegotiatedProtocol proto
1088                    return [ ExtensionRaw extensionID_ApplicationLayerProtocolNegotiation
1089                                            (extensionEncode $ ApplicationLayerProtocolNegotiation [proto]) ]
1090                _ -> return []
1091
1092credentialsFindForSigning13 :: [HashAndSignatureAlgorithm] -> Credentials -> Maybe (Credential, HashAndSignatureAlgorithm)
1093credentialsFindForSigning13 hss0 creds = loop hss0
1094  where
1095    loop  []       = Nothing
1096    loop  (hs:hss) = case credentialsFindForSigning13' hs creds of
1097        Nothing   -> credentialsFindForSigning13 hss creds
1098        Just cred -> Just (cred, hs)
1099
1100-- See credentialsFindForSigning.
1101credentialsFindForSigning13' :: HashAndSignatureAlgorithm -> Credentials -> Maybe Credential
1102credentialsFindForSigning13' sigAlg (Credentials l) = find forSigning l
1103  where
1104    forSigning cred = case credentialDigitalSignatureKey cred of
1105        Nothing  -> False
1106        Just pub -> pub `signatureCompatible13` sigAlg
1107
1108clientCertificate :: ServerParams -> Context -> CertificateChain -> IO ()
1109clientCertificate sparams ctx certs = do
1110    -- run certificate recv hook
1111    ctxWithHooks ctx (`hookRecvCertificates` certs)
1112    -- Call application callback to see whether the
1113    -- certificate chain is acceptable.
1114    --
1115    usage <- liftIO $ catchException (onClientCertificate (serverHooks sparams) certs) rejectOnException
1116    case usage of
1117        CertificateUsageAccept        -> verifyLeafKeyUsage [KeyUsage_digitalSignature] certs
1118        CertificateUsageReject reason -> certificateRejected reason
1119
1120    -- Remember cert chain for later use.
1121    --
1122    usingHState ctx $ setClientCertChain certs
1123
1124clientCertVerify :: ServerParams -> Context -> CertificateChain -> Bool -> IO ()
1125clientCertVerify sparams ctx certs verif = do
1126    if verif then do
1127        -- When verification succeeds, commit the
1128        -- client certificate chain to the context.
1129        --
1130        usingState_ ctx $ setClientCertificateChain certs
1131        return ()
1132      else do
1133        -- Either verification failed because of an
1134        -- invalid format (with an error message), or
1135        -- the signature is wrong.  In either case,
1136        -- ask the application if it wants to
1137        -- proceed, we will do that.
1138        res <- liftIO $ onUnverifiedClientCert (serverHooks sparams)
1139        if res then do
1140                -- When verification fails, but the
1141                -- application callbacks accepts, we
1142                -- also commit the client certificate
1143                -- chain to the context.
1144                usingState_ ctx $ setClientCertificateChain certs
1145                else decryptError "verification failed"
1146
1147newCertReqContext :: Context -> IO CertReqContext
1148newCertReqContext ctx = getStateRNG ctx 32
1149
1150requestCertificateServer :: ServerParams -> Context -> IO Bool
1151requestCertificateServer sparams ctx = do
1152    tls13 <- tls13orLater ctx
1153    supportsPHA <- usingState_ ctx getClientSupportsPHA
1154    let ok = tls13 && supportsPHA
1155    when ok $ do
1156        certReqCtx <- newCertReqContext ctx
1157        let certReq = makeCertRequest sparams ctx certReqCtx
1158        bracket (saveHState ctx) (restoreHState ctx) $ \_ -> do
1159            addCertRequest13 ctx certReq
1160            sendPacket13 ctx $ Handshake13 [certReq]
1161    return ok
1162
1163postHandshakeAuthServerWith :: ServerParams -> Context -> Handshake13 -> IO ()
1164postHandshakeAuthServerWith sparams ctx h@(Certificate13 certCtx certs _ext) = do
1165    mCertReq <- getCertRequest13 ctx certCtx
1166    when (isNothing mCertReq) $ throwCore $ Error_Protocol ("unknown certificate request context", True, DecodeError)
1167    let certReq = fromJust "certReq" mCertReq
1168
1169    -- fixme checking _ext
1170    clientCertificate sparams ctx certs
1171
1172    baseHState <- saveHState ctx
1173    processHandshake13 ctx certReq
1174    processHandshake13 ctx h
1175
1176    (usedHash, _, level, applicationSecretN) <- getRxState ctx
1177    unless (level == CryptApplicationSecret) $
1178        throwCore $ Error_Protocol ("tried post-handshake authentication without application traffic secret", True, InternalError)
1179
1180    let expectFinished hChBeforeCf (Finished13 verifyData) = do
1181            checkFinished usedHash applicationSecretN hChBeforeCf verifyData
1182            void $ restoreHState ctx baseHState
1183        expectFinished _ hs = unexpected (show hs) (Just "finished 13")
1184
1185    -- Note: here the server could send updated NST too, however the library
1186    -- currently has no API to handle resumption and client authentication
1187    -- together, see discussion in #133
1188    if isNullCertificateChain certs
1189        then setPendingActions ctx [ PendingActionHash False expectFinished ]
1190        else setPendingActions ctx [ PendingActionHash False (expectCertVerify sparams ctx)
1191                                   , PendingActionHash False expectFinished
1192                                   ]
1193
1194postHandshakeAuthServerWith _ _ _ =
1195    throwCore $ Error_Protocol ("unexpected handshake message received in postHandshakeAuthServerWith", True, UnexpectedMessage)
1196
1197contextSync :: Context -> ServerState -> IO ()
1198contextSync ctx ctl = case ctxHandshakeSync ctx of
1199    HandshakeSync _ sync -> sync ctx ctl
1200