Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RSA signature in CertificateVerify with TLS < 1.2 #189

Merged
merged 2 commits into from
Feb 25, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions core/Network/TLS/Handshake/Signature.hs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ certificateVerifyCreate :: Context
-> IO DigitallySigned
certificateVerifyCreate ctx usedVersion malg msgs =
prepareCertificateVerifySignatureData ctx usedVersion malg msgs >>=
signatureCreate ctx malg
signatureCreateWithHashDescr ctx malg

getHashAndASN1 :: MonadIO m => (HashAlgorithm, SignatureAlgorithm) -> m Hash
getHashAndASN1 hashSig = case hashSig of
Expand Down Expand Up @@ -101,13 +101,22 @@ signatureHashData sig _ = error ("unimplemented signature type: " ++ show sig)

--signatureCreate :: Context -> Maybe HashAndSignatureAlgorithm -> HashDescr -> Bytes -> IO DigitallySigned
signatureCreate :: Context -> Maybe HashAndSignatureAlgorithm -> CertVerifyData -> IO DigitallySigned
signatureCreate ctx malg (hashAlg, toSign) = do
cc <- usingState_ ctx $ isClientContext
signatureCreate ctx malg (hashAlg, toSign) =
-- in the case of TLS < 1.2, RSA signing, then the data need to be hashed first, as
-- the SHA_MD5 algorithm expect an already digested data
let signData =
case (malg, hashAlg) of
(Nothing, SHA1_MD5) -> hashFinal $ hashUpdate (hashInit SHA1_MD5) toSign
_ -> toSign
DigitallySigned malg <$> signPrivate ctx cc hashAlg signData
in signatureCreateWithHashDescr ctx malg (hashAlg, signData)

signatureCreateWithHashDescr :: Context
-> Maybe HashAndSignatureAlgorithm
-> CertVerifyData
-> IO DigitallySigned
signatureCreateWithHashDescr ctx malg (hashDescr, toSign) = do
cc <- usingState_ ctx $ isClientContext
DigitallySigned malg <$> signPrivate ctx cc hashDescr toSign

signatureVerify :: Context -> DigitallySigned -> SignatureAlgorithm -> Bytes -> IO Bool
signatureVerify ctx digSig@(DigitallySigned hashSigAlg _) sigAlgExpected toVerifyData = do
Expand Down
6 changes: 6 additions & 0 deletions core/Tests/Connection.hs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module Connection
( newPairContext
, arbitraryPairParams
, arbitraryClientCredential
, setPairParamsSessionManager
, setPairParamsSessionResuming
, establishDataPipe
Expand Down Expand Up @@ -147,6 +148,11 @@ arbitraryPairParams = do
where
arbitraryCiphers = resize (length knownCiphers + 1) $ listOf1 (elements knownCiphers)

arbitraryClientCredential = do
let (pubKey, privKey) = getGlobalRSAPair
cert <- arbitraryX509WithKey (PubKeyRSA pubKey, PrivKeyRSA privKey)
return (CertificateChain [cert], PrivKeyRSA privKey)

setPairParamsSessionManager :: SessionManager -> (ClientParams, ServerParams) -> (ClientParams, ServerParams)
setPairParamsSessionManager manager (clientState, serverState) = (nc,ns)
where nc = clientState { clientShared = updateSessionManager $ clientShared clientState }
Expand Down
29 changes: 29 additions & 0 deletions core/Tests/Tests.hs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,34 @@ prop_handshake_initiate = do
bye ctx
return ()

prop_handshake_client_auth_initiate :: PropertyM IO ()
prop_handshake_client_auth_initiate = do
(clientParam,serverParam) <- pick arbitraryPairParams
cred <- pick arbitraryClientCredential
let clientParam' = clientParam { clientHooks = (clientHooks clientParam)
{ onCertificateRequest = \_ -> return $ Just cred }
}
serverParam' = serverParam { serverWantClientCert = True
, serverHooks = (serverHooks serverParam)
{ onClientCertificate = validateChain cred }
}
params' = (clientParam',serverParam')
runTLSPipe params' tlsServer tlsClient
where tlsServer ctx queue = do
handshake ctx
d <- recvDataNonNull ctx
writeChan queue d
return ()
tlsClient queue ctx = do
handshake ctx
d <- readChan queue
sendData ctx (L.fromChunks [d])
bye ctx
return ()
validateChain cred chain
| chain == fst cred = return CertificateUsageAccept
| otherwise = return (CertificateUsageReject CertificateRejectUnknownCA)

prop_handshake_npn_initiate :: PropertyM IO ()
prop_handshake_npn_initiate = do
(clientParam,serverParam) <- pick arbitraryPairParams
Expand Down Expand Up @@ -182,6 +210,7 @@ main = defaultMain $ testGroup "tls"
tests_handshake = testGroup "Handshakes"
[ testProperty "setup" (monadicIO prop_pipe_work)
, testProperty "initiate" (monadicIO prop_handshake_initiate)
, testProperty "clientAuthInitiate" (monadicIO prop_handshake_client_auth_initiate)
, testProperty "npnInitiate" (monadicIO prop_handshake_npn_initiate)
, testProperty "renegociation" (monadicIO prop_handshake_renegociation)
, testProperty "resumption" (monadicIO prop_handshake_session_resumption)
Expand Down