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