commit ghc-tls for openSUSE:Factory
Hello community, here is the log from the commit of package ghc-tls for openSUSE:Factory checked in at 2017-02-01 09:52:28 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ghc-tls (Old) and /work/SRC/openSUSE:Factory/.ghc-tls.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "ghc-tls" Changes: -------- --- /work/SRC/openSUSE:Factory/ghc-tls/ghc-tls.changes 2016-07-20 09:20:15.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.ghc-tls.new/ghc-tls.changes 2017-02-03 17:40:18.222598923 +0100 @@ -1,0 +2,5 @@ +Wed Jan 18 09:00:21 UTC 2017 - psimons@suse.com + +- Update to version 1.3.9 with cabal2obs. + +------------------------------------------------------------------- Old: ---- tls-1.3.8.tar.gz New: ---- tls-1.3.9.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ghc-tls.spec ++++++ --- /var/tmp/diff_new_pack.PIEHad/_old 2017-02-03 17:40:18.602545145 +0100 +++ /var/tmp/diff_new_pack.PIEHad/_new 2017-02-03 17:40:18.606544579 +0100 @@ -1,7 +1,7 @@ # # spec file for package ghc-tls # -# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -19,15 +19,14 @@ %global pkg_name tls %bcond_with tests Name: ghc-%{pkg_name} -Version: 1.3.8 +Version: 1.3.9 Release: 0 Summary: TLS/SSL protocol native implementation (Server and Client) License: BSD-3-Clause -Group: System/Libraries +Group: Development/Languages/Other Url: https://hackage.haskell.org/package/%{pkg_name} Source0: https://hackage.haskell.org/package/%{pkg_name}-%{version}/%{pkg_name}-%{version}.tar.gz BuildRequires: ghc-Cabal-devel -# Begin cabal-rpm deps: BuildRequires: ghc-asn1-encoding-devel BuildRequires: ghc-asn1-types-devel BuildRequires: ghc-async-devel @@ -50,7 +49,6 @@ BuildRequires: ghc-tasty-devel BuildRequires: ghc-tasty-quickcheck-devel %endif -# End cabal-rpm deps %description Native Haskell TLS and SSL protocol implementation for server and client. @@ -80,20 +78,14 @@ %prep %setup -q -n %{pkg_name}-%{version} - %build %ghc_lib_build - %install %ghc_lib_install - %check -%if %{with tests} -%{cabal} test -%endif - +%cabal_test %post devel %ghc_pkg_recache ++++++ tls-1.3.8.tar.gz -> tls-1.3.9.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.3.8/CHANGELOG.md new/tls-1.3.9/CHANGELOG.md --- old/tls-1.3.8/CHANGELOG.md 2016-05-12 08:01:28.000000000 +0200 +++ new/tls-1.3.9/CHANGELOG.md 2016-05-14 18:46:17.000000000 +0200 @@ -1,3 +1,7 @@ +## Version 1.3.8 + +- Fix older GHC builds + ## Version 1.3.7 - Disable SHA384 based cipher, as they don't work properly yet. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.3.8/Network/TLS/Backend.hs new/tls-1.3.9/Network/TLS/Backend.hs --- old/tls-1.3.8/Network/TLS/Backend.hs 2016-05-12 08:01:28.000000000 +0200 +++ new/tls-1.3.9/Network/TLS/Backend.hs 2016-07-30 12:11:49.000000000 +0200 @@ -52,6 +52,23 @@ initializeBackend _ = return () getBackend = id +#if defined(__GLASGOW_HASKELL__) && WINDOWS +-- Socket recv and accept calls on Windows platform cannot be interrupted when compiled with -threaded. +-- See https://ghc.haskell.org/trac/ghc/ticket/5797 for details. +-- The following enables simple workaround +#define SOCKET_ACCEPT_RECV_WORKAROUND +#endif + +safeRecv :: Network.Socket -> Int -> IO ByteString +#ifndef SOCKET_ACCEPT_RECV_WORKAROUND +safeRecv = Network.recv +#else +safeRecv s buf = do + var <- newEmptyMVar + forkIO $ Network.recv s buf `E.catch` (\(_::IOException) -> return S8.empty) >>= putMVar var + takeMVar var +#endif + #ifdef INCLUDE_NETWORK instance HasBackend Network.Socket where initializeBackend _ = return () @@ -59,7 +76,7 @@ where recvAll n = B.concat `fmap` loop n where loop 0 = return [] loop left = do - r <- Network.recv sock left + r <- safeRecv sock left if B.null r then return [] else liftM (r:) (loop (left - B.length r)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.3.8/Network/TLS/Cipher.hs new/tls-1.3.9/Network/TLS/Cipher.hs --- old/tls-1.3.8/Network/TLS/Cipher.hs 2016-05-12 08:01:28.000000000 +0200 +++ new/tls-1.3.9/Network/TLS/Cipher.hs 2016-12-17 12:09:25.000000000 +0100 @@ -125,6 +125,7 @@ , cipherBulk :: Bulk , cipherKeyExchange :: CipherKeyExchangeType , cipherMinVer :: Maybe Version + , cipherPRFHash :: Maybe Hash } cipherKeyBlockSize :: Cipher -> Int diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.3.8/Network/TLS/Context/Internal.hs new/tls-1.3.9/Network/TLS/Context/Internal.hs --- old/tls-1.3.8/Network/TLS/Context/Internal.hs 2016-05-12 08:01:28.000000000 +0200 +++ new/tls-1.3.9/Network/TLS/Context/Internal.hs 2016-07-30 12:11:49.000000000 +0200 @@ -57,6 +57,7 @@ import Network.TLS.Backend import Network.TLS.Extension import Network.TLS.Cipher +import Network.TLS.Credentials (Credentials) import Network.TLS.Struct import Network.TLS.Compression (Compression) import Network.TLS.State @@ -89,7 +90,8 @@ { ctxConnection :: Backend -- ^ return the backend object associated with this context , ctxSupported :: Supported , ctxShared :: Shared - , ctxCiphers :: [Cipher] -- ^ prepared list of allowed ciphers according to parameters + , ctxCiphers :: Credentials -> [Cipher] -- ^ list of allowed ciphers according to parameters + -- and additional credentials , ctxState :: MVar TLSState , ctxMeasurement :: IORef Measurement , ctxEOF_ :: IORef Bool -- ^ has the handle EOFed or not. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.3.8/Network/TLS/Context.hs new/tls-1.3.9/Network/TLS/Context.hs --- old/tls-1.3.8/Network/TLS/Context.hs 2016-05-12 08:01:28.000000000 +0200 +++ new/tls-1.3.9/Network/TLS/Context.hs 2016-12-17 12:09:25.000000000 +0100 @@ -81,6 +81,7 @@ import Control.Concurrent.MVar import Control.Monad.State import Data.IORef +import Data.Monoid (mappend) -- deprecated imports #ifdef INCLUDE_NETWORK @@ -91,7 +92,7 @@ class TLSParams a where getTLSCommonParams :: a -> CommonParams getTLSRole :: a -> Role - getCiphers :: a -> [Cipher] + getCiphers :: a -> Credentials -> [Cipher] doHandshake :: a -> Context -> IO () doHandshakeWith :: a -> Context -> Handshake -> IO () @@ -101,7 +102,7 @@ , clientDebug cparams ) getTLSRole _ = ClientRole - getCiphers cparams = supportedCiphers $ clientSupported cparams + getCiphers cparams _ = supportedCiphers $ clientSupported cparams doHandshake = handshakeClient doHandshakeWith = handshakeClientWith @@ -113,7 +114,7 @@ getTLSRole _ = ServerRole -- on the server we filter our allowed ciphers here according -- to the credentials and DHE parameters loaded - getCiphers sparams = filter authorizedCKE (supportedCiphers $ serverSupported sparams) + getCiphers sparams extraCreds = filter authorizedCKE (supportedCiphers $ serverSupported sparams) where authorizedCKE cipher = case cipherKeyExchange cipher of CipherKeyExchange_RSA -> canEncryptRSA @@ -121,20 +122,24 @@ CipherKeyExchange_DHE_RSA -> canSignRSA && canDHE CipherKeyExchange_DHE_DSS -> canSignDSS && canDHE CipherKeyExchange_ECDHE_RSA -> canSignRSA - -- unimplemented: non ephemeral DH + -- unimplemented: EC + CipherKeyExchange_ECDHE_ECDSA -> False + -- unimplemented: non ephemeral DH & ECDH. + -- Note, these *should not* be implemented, and have + -- (for example) been removed in OpenSSL 1.1.0 + -- CipherKeyExchange_DH_DSS -> False CipherKeyExchange_DH_RSA -> False - -- unimplemented: EC CipherKeyExchange_ECDH_ECDSA -> False CipherKeyExchange_ECDH_RSA -> False - CipherKeyExchange_ECDHE_ECDSA -> False canDHE = isJust $ serverDHEParams sparams canSignDSS = SignatureDSS `elem` signingAlgs canSignRSA = SignatureRSA `elem` signingAlgs canEncryptRSA = isJust $ credentialsFindForDecrypting creds signingAlgs = credentialsListSigningAlgorithms creds - creds = sharedCredentials $ serverShared sparams + serverCreds = sharedCredentials $ serverShared sparams + creds = extraCreds `mappend` serverCreds doHandshake = handshakeServer doHandshakeWith = handshakeServerWith @@ -159,7 +164,9 @@ st = newTLSState rng role ciphers = getCiphers params - when (null ciphers) $ error "no ciphers available with those parameters" +-- we still might get some ciphers from SNI callback +-- If we could bail only on protocols which require the main cert?? +-- when (null (ciphers mempty)) $ error "no ciphers available with those parameters" stvar <- newMVar st eof <- newIORef False diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.3.8/Network/TLS/Core.hs new/tls-1.3.9/Network/TLS/Core.hs --- old/tls-1.3.8/Network/TLS/Core.hs 2016-05-12 08:01:28.000000000 +0200 +++ new/tls-1.3.9/Network/TLS/Core.hs 2016-12-04 07:54:32.000000000 +0100 @@ -54,7 +54,7 @@ bye :: MonadIO m => Context -> m () bye ctx = sendPacket ctx $ Alert [(AlertLevel_Warning, CloseNotify)] --- | If the Next Protocol Negotiation extension has been used, this will +-- | If the Next Protocol Negotiation or ALPN extensions have been used, this will -- return get the protocol agreed upon. getNegotiatedProtocol :: MonadIO m => Context -> m (Maybe B.ByteString) getNegotiatedProtocol ctx = liftIO $ usingState_ ctx S.getNegotiatedProtocol diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.3.8/Network/TLS/Crypto/ECDH.hs new/tls-1.3.9/Network/TLS/Crypto/ECDH.hs --- old/tls-1.3.8/Network/TLS/Crypto/ECDH.hs 2016-05-12 08:01:28.000000000 +0200 +++ new/tls-1.3.9/Network/TLS/Crypto/ECDH.hs 2016-12-04 07:54:32.000000000 +0100 @@ -15,7 +15,6 @@ , ecdhUnwrapPublic ) where -import Network.TLS.Util.Serialization (lengthBytes) import Network.TLS.Extension.EC import qualified Crypto.PubKey.ECC.DH as ECDH import qualified Crypto.PubKey.ECC.Types as ECDH @@ -72,5 +71,6 @@ ecdhUnwrapPublic _ = error "ecdhUnwrapPublic" pointSize :: ECDH.Curve -> Int -pointSize (ECDH.CurveFP curve) = lengthBytes $ ECDH.ecc_p curve -pointSize _ = error "pointSize" -- FIXME +pointSize = toBytes . ECDH.curveSizeBits + where + toBytes bits = (bits + 7) `div` 8 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.3.8/Network/TLS/Crypto.hs new/tls-1.3.9/Network/TLS/Crypto.hs --- old/tls-1.3.8/Network/TLS/Crypto.hs 2016-05-12 08:01:28.000000000 +0200 +++ new/tls-1.3.9/Network/TLS/Crypto.hs 2016-12-04 07:54:32.000000000 +0100 @@ -42,7 +42,6 @@ import qualified Crypto.PubKey.RSA as RSA import qualified Crypto.PubKey.RSA.PKCS15 as RSA import Crypto.Number.Serialize (os2ip) -import Crypto.Number.Basic (numBits) import Data.X509 (PrivKey(..), PubKey(..), PubKeyEC(..), SerializedPoint(..)) import Network.TLS.Crypto.DH @@ -215,7 +214,7 @@ Nothing -> Nothing Just (ptFormat, input) -> case ptFormat of - 4 -> if B.length bs == 2 * bytes + 4 -> if B.length input /= 2 * bytes then Nothing else let (x, y) = B.splitAt bytes input @@ -225,7 +224,7 @@ else Nothing -- 2 and 3 for compressed format. _ -> Nothing - where bits = numBits . ECC.ecc_n . ECC.common_curve $ curve + where bits = ECC.curveSizeBits curve bytes = (bits + 7) `div` 8 kxVerify _ _ _ _ = False diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.3.8/Network/TLS/Extension.hs new/tls-1.3.9/Network/TLS/Extension.hs --- old/tls-1.3.8/Network/TLS/Extension.hs 2016-05-12 08:01:28.000000000 +0200 +++ new/tls-1.3.9/Network/TLS/Extension.hs 2016-12-17 12:09:25.000000000 +0100 @@ -270,7 +270,7 @@ deriving (Show,Eq) availableEllipticCurves :: [NamedCurve] -availableEllipticCurves = [SEC SEC_p256r1, SEC SEC_p521r1] +availableEllipticCurves = [SEC SEC_p256r1, SEC SEC_p384r1, SEC SEC_p521r1] instance EnumSafe16 NamedCurve where fromEnumSafe16 NamedCurve_arbitrary_explicit_prime_curves = 0xFF01 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.3.8/Network/TLS/Extra/Cipher.hs new/tls-1.3.9/Network/TLS/Extra/Cipher.hs --- old/tls-1.3.8/Network/TLS/Extra/Cipher.hs 2016-05-12 08:01:28.000000000 +0200 +++ new/tls-1.3.9/Network/TLS/Extra/Cipher.hs 2016-12-17 12:09:25.000000000 +0100 @@ -10,7 +10,8 @@ module Network.TLS.Extra.Cipher ( -- * cipher suite - ciphersuite_all + ciphersuite_default + , ciphersuite_all , ciphersuite_medium , ciphersuite_strong , ciphersuite_unencrypted @@ -18,29 +19,38 @@ , ciphersuite_dhe_dss -- * individual ciphers , cipher_null_SHA1 - , cipher_null_MD5 - , cipher_RC4_128_MD5 - , cipher_RC4_128_SHA1 , cipher_AES128_SHA1 , cipher_AES256_SHA1 , cipher_AES128_SHA256 , cipher_AES256_SHA256 - , cipher_RSA_3DES_EDE_CBC_SHA1 + , cipher_AES128GCM_SHA256 + , cipher_AES256GCM_SHA384 , cipher_DHE_RSA_AES128_SHA1 , cipher_DHE_RSA_AES256_SHA1 , cipher_DHE_RSA_AES128_SHA256 , cipher_DHE_RSA_AES256_SHA256 , cipher_DHE_DSS_AES128_SHA1 , cipher_DHE_DSS_AES256_SHA1 - , cipher_DHE_DSS_RC4_SHA1 , cipher_DHE_RSA_AES128GCM_SHA256 + , cipher_DHE_RSA_AES256GCM_SHA384 , cipher_ECDHE_RSA_AES128GCM_SHA256 , cipher_ECDHE_RSA_AES256GCM_SHA384 , cipher_ECDHE_RSA_AES128CBC_SHA256 , cipher_ECDHE_RSA_AES128CBC_SHA , cipher_ECDHE_RSA_AES256CBC_SHA , cipher_ECDHE_RSA_AES256CBC_SHA384 + , cipher_ECDHE_ECDSA_AES128CBC_SHA + , cipher_ECDHE_ECDSA_AES256CBC_SHA + , cipher_ECDHE_ECDSA_AES128CBC_SHA256 + , cipher_ECDHE_ECDSA_AES256CBC_SHA384 , cipher_ECDHE_ECDSA_AES128GCM_SHA256 + , cipher_ECDHE_ECDSA_AES256GCM_SHA384 + -- * obsolete and non-standard ciphers + , cipher_RSA_3DES_EDE_CBC_SHA1 + , cipher_RC4_128_MD5 + , cipher_RC4_128_SHA1 + , cipher_null_MD5 + , cipher_DHE_DSS_RC4_SHA1 ) where import qualified Data.ByteString as B @@ -134,44 +144,82 @@ let (ctx', output) = RC4.combine ctx input in (output, BulkStream (combineRC4 ctx')) +-- | All AES ciphers supported ordered from strong to weak. This choice +-- of ciphersuites should satisfy most normal needs. For otherwise strong +-- ciphers we make little distinction between AES128 and AES256, and list +-- each but the weakest of the AES128 ciphers ahead of the corresponding AES256 +-- ciphers. +ciphersuite_default :: [Cipher] +ciphersuite_default = + [ -- First the PFS + GCM + SHA2 ciphers + cipher_ECDHE_ECDSA_AES128GCM_SHA256, cipher_ECDHE_ECDSA_AES256GCM_SHA384 + , cipher_ECDHE_RSA_AES128GCM_SHA256, cipher_ECDHE_RSA_AES256GCM_SHA384 + , cipher_DHE_RSA_AES128GCM_SHA256, cipher_DHE_RSA_AES256GCM_SHA384 + -- Next the PFS + CBC + SHA2 ciphers + , cipher_ECDHE_ECDSA_AES128CBC_SHA256, cipher_ECDHE_ECDSA_AES256CBC_SHA384 + , cipher_ECDHE_RSA_AES128CBC_SHA256, cipher_ECDHE_RSA_AES256CBC_SHA384 + , cipher_DHE_RSA_AES128_SHA256, cipher_DHE_RSA_AES256_SHA256 + -- Next the PFS + CBC + SHA1 ciphers + , cipher_ECDHE_ECDSA_AES128CBC_SHA, cipher_ECDHE_ECDSA_AES256CBC_SHA + , cipher_ECDHE_RSA_AES128CBC_SHA, cipher_ECDHE_RSA_AES256CBC_SHA + , cipher_DHE_RSA_AES128_SHA1, cipher_DHE_RSA_AES256_SHA1 + -- Next the non-PFS + GCM + SHA2 ciphers + , cipher_AES128GCM_SHA256, cipher_AES256GCM_SHA384 + -- Next the non-PFS + CBC + SHA2 ciphers + , cipher_AES256_SHA256, cipher_AES128_SHA256 + -- Next the non-PFS + CBC + SHA1 ciphers + , cipher_AES256_SHA1, cipher_AES128_SHA1 + -- Nobody uses or should use DSS, RC4, 3DES or MD5 + -- , cipher_DHE_DSS_AES256_SHA1, cipher_DHE_DSS_AES128_SHA1 + -- , cipher_DHE_DSS_RC4_SHA1, cipher_RC4_128_SHA1, cipher_RC4_128_MD5 + -- , cipher_RSA_3DES_EDE_CBC_SHA1 + ] --- | all encrypted ciphers supported ordered from strong to weak. --- this choice of ciphersuite should satisfy most normal need +-- | The default ciphersuites + some not recommended last resort ciphers. ciphersuite_all :: [Cipher] -ciphersuite_all = - [ cipher_ECDHE_RSA_AES128GCM_SHA256 - , cipher_ECDHE_RSA_AES256CBC_SHA - , cipher_ECDHE_ECDSA_AES128GCM_SHA256 - , cipher_DHE_RSA_AES256_SHA256, cipher_DHE_RSA_AES128_SHA256 - , cipher_DHE_RSA_AES256_SHA1, cipher_DHE_RSA_AES128_SHA1 - , cipher_DHE_DSS_AES256_SHA1, cipher_DHE_DSS_AES128_SHA1 - , cipher_AES128_SHA256, cipher_AES256_SHA256 - , cipher_AES128_SHA1, cipher_AES256_SHA1 - , cipher_DHE_DSS_RC4_SHA1, cipher_RC4_128_SHA1, cipher_RC4_128_MD5 +ciphersuite_all = ciphersuite_default ++ + [ cipher_DHE_DSS_AES256_SHA1, cipher_DHE_DSS_AES128_SHA1 , cipher_RSA_3DES_EDE_CBC_SHA1 - , cipher_DHE_RSA_AES128GCM_SHA256 + , cipher_RC4_128_SHA1 ] -- | list of medium ciphers. ciphersuite_medium :: [Cipher] -ciphersuite_medium = [cipher_RC4_128_MD5, cipher_RC4_128_SHA1, cipher_AES128_SHA1, cipher_AES256_SHA1] - --- | the strongest ciphers supported. +ciphersuite_medium = [ cipher_RC4_128_SHA1 + , cipher_AES128_SHA1 + ] + +-- | The strongest ciphers supported ciphers supported. For ciphers with PFS, +-- AEAD and SHA2, we list each AES128 variant right after the corresponding +-- AES256 variant. For weaker constructs, we use just the AES256 form. ciphersuite_strong :: [Cipher] ciphersuite_strong = - [ cipher_ECDHE_RSA_AES128GCM_SHA256 - , cipher_ECDHE_RSA_AES256CBC_SHA - , cipher_ECDHE_ECDSA_AES128GCM_SHA256 + [ -- If we have PFS + AEAD + SHA2, then allow AES128, else just 256 + cipher_ECDHE_ECDSA_AES256GCM_SHA384, cipher_ECDHE_ECDSA_AES128GCM_SHA256 + , cipher_ECDHE_RSA_AES256GCM_SHA384, cipher_ECDHE_RSA_AES128GCM_SHA256 + , cipher_DHE_RSA_AES256GCM_SHA384, cipher_DHE_RSA_AES128GCM_SHA256 + -- No AEAD + , cipher_ECDHE_ECDSA_AES256CBC_SHA384 + , cipher_ECDHE_RSA_AES256CBC_SHA384 , cipher_DHE_RSA_AES256_SHA256 + -- No SHA2 + , cipher_ECDHE_ECDSA_AES256CBC_SHA + , cipher_ECDHE_RSA_AES256CBC_SHA + , cipher_DHE_RSA_AES256_SHA1 + -- No PFS + , cipher_AES256GCM_SHA384 + -- Neither PFS nor AEAD, just SHA2 , cipher_AES256_SHA256 + -- Last resort no PFS, AEAD or SHA2 , cipher_AES256_SHA1 ] -- | DHE-RSA cipher suite ciphersuite_dhe_rsa :: [Cipher] -ciphersuite_dhe_rsa = [cipher_DHE_RSA_AES256_SHA256, cipher_DHE_RSA_AES128_SHA256 +ciphersuite_dhe_rsa = [ cipher_DHE_RSA_AES256GCM_SHA384, cipher_DHE_RSA_AES128GCM_SHA256 + , cipher_DHE_RSA_AES256_SHA256, cipher_DHE_RSA_AES128_SHA256 , cipher_DHE_RSA_AES256_SHA1, cipher_DHE_RSA_AES128_SHA1 - , cipher_DHE_RSA_AES128GCM_SHA256] + ] ciphersuite_dhe_dss :: [Cipher] ciphersuite_dhe_dss = [cipher_DHE_DSS_AES256_SHA1, cipher_DHE_DSS_AES128_SHA1, cipher_DHE_DSS_RC4_SHA1] @@ -260,6 +308,7 @@ , cipherName = "RSA-null-MD5" , cipherBulk = bulk_null , cipherHash = MD5 + , cipherPRFHash = Nothing , cipherKeyExchange = CipherKeyExchange_RSA , cipherMinVer = Nothing } @@ -271,6 +320,7 @@ , cipherName = "RSA-null-SHA1" , cipherBulk = bulk_null , cipherHash = SHA1 + , cipherPRFHash = Nothing , cipherKeyExchange = CipherKeyExchange_RSA , cipherMinVer = Nothing } @@ -282,6 +332,7 @@ , cipherName = "RSA-rc4-128-md5" , cipherBulk = bulk_rc4 , cipherHash = MD5 + , cipherPRFHash = Nothing , cipherKeyExchange = CipherKeyExchange_RSA , cipherMinVer = Nothing } @@ -293,6 +344,7 @@ , cipherName = "RSA-rc4-128-sha1" , cipherBulk = bulk_rc4 , cipherHash = SHA1 + , cipherPRFHash = Nothing , cipherKeyExchange = CipherKeyExchange_RSA , cipherMinVer = Nothing } @@ -304,6 +356,7 @@ , cipherName = "RSA-AES128-SHA1" , cipherBulk = bulk_aes128 , cipherHash = SHA1 + , cipherPRFHash = Nothing , cipherKeyExchange = CipherKeyExchange_RSA , cipherMinVer = Just SSL3 } @@ -315,6 +368,7 @@ , cipherName = "DHE-DSA-AES128-SHA1" , cipherBulk = bulk_aes128 , cipherHash = SHA1 + , cipherPRFHash = Nothing , cipherKeyExchange = CipherKeyExchange_DHE_DSS , cipherMinVer = Nothing } @@ -326,6 +380,7 @@ , cipherName = "DHE-RSA-AES128-SHA1" , cipherBulk = bulk_aes128 , cipherHash = SHA1 + , cipherPRFHash = Nothing , cipherKeyExchange = CipherKeyExchange_DHE_RSA , cipherMinVer = Nothing } @@ -337,6 +392,7 @@ , cipherName = "RSA-AES256-SHA1" , cipherBulk = bulk_aes256 , cipherHash = SHA1 + , cipherPRFHash = Nothing , cipherKeyExchange = CipherKeyExchange_RSA , cipherMinVer = Just SSL3 } @@ -364,6 +420,7 @@ , cipherName = "RSA-AES128-SHA256" , cipherBulk = bulk_aes128 , cipherHash = SHA256 + , cipherPRFHash = Just SHA256 , cipherKeyExchange = CipherKeyExchange_RSA , cipherMinVer = Just TLS12 } @@ -375,10 +432,36 @@ , cipherName = "RSA-AES256-SHA256" , cipherBulk = bulk_aes256 , cipherHash = SHA256 + , cipherPRFHash = Just SHA256 + , cipherKeyExchange = CipherKeyExchange_RSA + , cipherMinVer = Just TLS12 + } + +-- | AESGCM cipher (128 bit key), RSA key exchange. +-- The SHA256 digest is used as a PRF, not as a MAC. +cipher_AES128GCM_SHA256 :: Cipher +cipher_AES128GCM_SHA256 = Cipher + { cipherID = 0x9c + , cipherName = "RSA-AES128GCM-SHA256" + , cipherBulk = bulk_aes128gcm + , cipherHash = SHA256 + , cipherPRFHash = Just SHA256 , cipherKeyExchange = CipherKeyExchange_RSA , cipherMinVer = Just TLS12 } +-- | AESGCM cipher (256 bit key), RSA key exchange. +-- The SHA384 digest is used as a PRF, not as a MAC. +cipher_AES256GCM_SHA384 :: Cipher +cipher_AES256GCM_SHA384 = Cipher + { cipherID = 0x9d + , cipherName = "RSA-AES256GCM-SHA384" + , cipherBulk = bulk_aes256gcm + , cipherHash = SHA384 + , cipherPRFHash = Just SHA384 + , cipherKeyExchange = CipherKeyExchange_RSA + , cipherMinVer = Just TLS12 + } cipher_DHE_DSS_RC4_SHA1 :: Cipher cipher_DHE_DSS_RC4_SHA1 = cipher_DHE_DSS_AES128_SHA1 @@ -392,6 +475,7 @@ { cipherID = 0x67 , cipherName = "DHE-RSA-AES128-SHA256" , cipherHash = SHA256 + , cipherPRFHash = Just SHA256 , cipherMinVer = Just TLS12 } @@ -409,6 +493,7 @@ , cipherName = "RSA-3DES-EDE-CBC-SHA1" , cipherBulk = bulk_tripledes_ede , cipherHash = SHA1 + , cipherPRFHash = Nothing , cipherKeyExchange = CipherKeyExchange_RSA , cipherMinVer = Nothing } @@ -419,16 +504,51 @@ , cipherName = "DHE-RSA-AES128GCM-SHA256" , cipherBulk = bulk_aes128gcm , cipherHash = SHA256 + , cipherPRFHash = Just SHA256 , cipherKeyExchange = CipherKeyExchange_DHE_RSA , cipherMinVer = Just TLS12 -- RFC 5288 Sec 4 } +cipher_DHE_RSA_AES256GCM_SHA384 :: Cipher +cipher_DHE_RSA_AES256GCM_SHA384 = Cipher + { cipherID = 0x9f + , cipherName = "DHE-RSA-AES256GCM-SHA384" + , cipherBulk = bulk_aes256gcm + , cipherHash = SHA384 + , cipherPRFHash = Just SHA384 + , cipherKeyExchange = CipherKeyExchange_DHE_RSA + , cipherMinVer = Just TLS12 + } + +cipher_ECDHE_ECDSA_AES128CBC_SHA :: Cipher +cipher_ECDHE_ECDSA_AES128CBC_SHA = Cipher + { cipherID = 0xc009 + , cipherName = "ECDHE-ECDSA-AES128CBC-SHA" + , cipherBulk = bulk_aes128 + , cipherHash = SHA1 + , cipherPRFHash = Nothing + , cipherKeyExchange = CipherKeyExchange_ECDHE_RSA + , cipherMinVer = Just TLS10 + } + +cipher_ECDHE_ECDSA_AES256CBC_SHA :: Cipher +cipher_ECDHE_ECDSA_AES256CBC_SHA = Cipher + { cipherID = 0xc00A + , cipherName = "ECDHE-ECDSA-AES256CBC-SHA" + , cipherBulk = bulk_aes256 + , cipherHash = SHA1 + , cipherPRFHash = Nothing + , cipherKeyExchange = CipherKeyExchange_ECDHE_RSA + , cipherMinVer = Just TLS10 + } + cipher_ECDHE_RSA_AES128CBC_SHA :: Cipher cipher_ECDHE_RSA_AES128CBC_SHA = Cipher { cipherID = 0xc013 , cipherName = "ECDHE-RSA-AES128CBC-SHA" , cipherBulk = bulk_aes128 , cipherHash = SHA1 + , cipherPRFHash = Nothing , cipherKeyExchange = CipherKeyExchange_ECDHE_RSA , cipherMinVer = Just TLS10 } @@ -439,6 +559,7 @@ , cipherName = "ECDHE-RSA-AES256CBC-SHA" , cipherBulk = bulk_aes256 , cipherHash = SHA1 + , cipherPRFHash = Nothing , cipherKeyExchange = CipherKeyExchange_ECDHE_RSA , cipherMinVer = Just TLS10 } @@ -449,26 +570,62 @@ , cipherName = "ECDHE-RSA-AES128CBC-SHA256" , cipherBulk = bulk_aes128 , cipherHash = SHA256 + , cipherPRFHash = Just SHA256 , cipherKeyExchange = CipherKeyExchange_ECDHE_RSA , cipherMinVer = Just TLS12 -- RFC 5288 Sec 4 } cipher_ECDHE_RSA_AES256CBC_SHA384 :: Cipher cipher_ECDHE_RSA_AES256CBC_SHA384 = Cipher - { cipherID = 0xc027 + { cipherID = 0xc028 , cipherName = "ECDHE-RSA-AES256CBC-SHA384" , cipherBulk = bulk_aes256 , cipherHash = SHA384 + , cipherPRFHash = Just SHA384 , cipherKeyExchange = CipherKeyExchange_ECDHE_RSA , cipherMinVer = Just TLS12 -- RFC 5288 Sec 4 } +cipher_ECDHE_ECDSA_AES128CBC_SHA256 :: Cipher +cipher_ECDHE_ECDSA_AES128CBC_SHA256 = Cipher + { cipherID = 0xc023 + , cipherName = "ECDHE-ECDSA-AES128CBC-SHA256" + , cipherBulk = bulk_aes128 + , cipherHash = SHA256 + , cipherPRFHash = Just SHA256 + , cipherKeyExchange = CipherKeyExchange_ECDHE_ECDSA + , cipherMinVer = Just TLS12 -- RFC 5289 + } + +cipher_ECDHE_ECDSA_AES256CBC_SHA384 :: Cipher +cipher_ECDHE_ECDSA_AES256CBC_SHA384 = Cipher + { cipherID = 0xc024 + , cipherName = "ECDHE-ECDSA-AES256CBC-SHA384" + , cipherBulk = bulk_aes256 + , cipherHash = SHA384 + , cipherPRFHash = Just SHA384 + , cipherKeyExchange = CipherKeyExchange_ECDHE_ECDSA + , cipherMinVer = Just TLS12 -- RFC 5289 + } + cipher_ECDHE_ECDSA_AES128GCM_SHA256 :: Cipher cipher_ECDHE_ECDSA_AES128GCM_SHA256 = Cipher { cipherID = 0xc02b , cipherName = "ECDHE-ECDSA-AES128GCM-SHA256" , cipherBulk = bulk_aes128gcm , cipherHash = SHA256 + , cipherPRFHash = Just SHA256 + , cipherKeyExchange = CipherKeyExchange_ECDHE_ECDSA + , cipherMinVer = Just TLS12 -- RFC 5289 + } + +cipher_ECDHE_ECDSA_AES256GCM_SHA384 :: Cipher +cipher_ECDHE_ECDSA_AES256GCM_SHA384 = Cipher + { cipherID = 0xc02c + , cipherName = "ECDHE-ECDSA-AES256GCM-SHA384" + , cipherBulk = bulk_aes256gcm + , cipherHash = SHA384 + , cipherPRFHash = Just SHA384 , cipherKeyExchange = CipherKeyExchange_ECDHE_ECDSA , cipherMinVer = Just TLS12 -- RFC 5289 } @@ -479,6 +636,7 @@ , cipherName = "ECDHE-RSA-AES128GCM-SHA256" , cipherBulk = bulk_aes128gcm , cipherHash = SHA256 + , cipherPRFHash = Just SHA256 , cipherKeyExchange = CipherKeyExchange_ECDHE_RSA , cipherMinVer = Just TLS12 -- RFC 5288 Sec 4 } @@ -486,9 +644,10 @@ cipher_ECDHE_RSA_AES256GCM_SHA384 :: Cipher cipher_ECDHE_RSA_AES256GCM_SHA384 = Cipher { cipherID = 0xc030 - , cipherName = "ECDHE-RSA-AES256GCM-SHA256" + , cipherName = "ECDHE-RSA-AES256GCM-SHA384" , cipherBulk = bulk_aes256gcm , cipherHash = SHA384 + , cipherPRFHash = Just SHA384 , cipherKeyExchange = CipherKeyExchange_ECDHE_RSA , cipherMinVer = Just TLS12 -- RFC 5289 } @@ -525,6 +684,9 @@ CipherSuite TLS_DH_anon_WITH_DES_CBC_SHA = { 0x00,0x1A }; CipherSuite TLS_DH_anon_WITH_3DES_EDE_CBC_SHA = { 0x00,0x1B }; +TLS-RSA-WITH-AES-128-GCM-SHA256 {0x00,0x9C} +TLS-RSA-WITH-AES-256-GCM-SHA384 {0x00,0x9D} + TLS-DHE-RSA-WITH-AES-128-CBC-SHA {0x00,0x33} TLS-DHE-RSA-WITH-AES-256-CBC-SHA {0x00,0x39} TLS-DHE-RSA-WITH-AES-128-CBC-SHA256 {0x00,0x67} @@ -554,6 +716,13 @@ TLS-ECDHE-RSA-WITH-RC4-128-SHA {0xC0,0x11} TLS-ECDHE-RSA-WITH-NULL-SHA {0xC0,0x10} +TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA {0xC0,0x09} +TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA {0xC0,0x0A} +TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256 {0xC0,0x23} +TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384 {0xC0,0x24} +TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 {0xC0,0x2B} +TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384 {0xC0,0x2C} + TLS-PSK-WITH-RC4-128-SHA {0x00,0x8A} TLS-PSK-WITH-3DES-EDE-CBC-SHA {0x00,0x8B} TLS-PSK-WITH-AES-128-CBC-SHA {0x00,0x8C} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.3.8/Network/TLS/Handshake/Client.hs new/tls-1.3.9/Network/TLS/Handshake/Client.hs --- old/tls-1.3.8/Network/TLS/Handshake/Client.hs 2016-05-12 08:01:28.000000000 +0200 +++ new/tls-1.3.9/Network/TLS/Handshake/Client.hs 2016-07-30 12:11:49.000000000 +0200 @@ -111,7 +111,7 @@ startHandshake ctx highestVer crand usingState_ ctx $ setVersionIfUnset highestVer sendPacket ctx $ Handshake - [ ClientHello highestVer crand clientSession (map cipherID ciphers) + [ ClientHello highestVer crand clientSession (map cipherID (ciphers mempty)) (map compressionID compressions) extensions Nothing ] return $ map (\(ExtensionRaw i _) -> i) extensions @@ -291,7 +291,7 @@ Nothing -> throwCore $ Error_Protocol ("server version " ++ show rver ++ " is not supported", True, ProtocolVersion) Just _ -> return () -- find the compression and cipher methods that the server want to use. - cipherAlg <- case find ((==) cipher . cipherID) (ctxCiphers ctx) of + cipherAlg <- case find ((==) cipher . cipherID) (ctxCiphers ctx mempty) of Nothing -> throwCore $ Error_Protocol ("server choose unknown cipher", True, HandshakeFailure) Just alg -> return alg compressAlg <- case find ((==) compression . compressionID) (supportedCompressions $ ctxSupported ctx) of diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.3.8/Network/TLS/Handshake/Key.hs new/tls-1.3.9/Network/TLS/Handshake/Key.hs --- old/tls-1.3.8/Network/TLS/Handshake/Key.hs 2016-05-12 08:01:28.000000000 +0200 +++ new/tls-1.3.9/Network/TLS/Handshake/Key.hs 2016-12-17 12:09:25.000000000 +0100 @@ -9,9 +9,9 @@ -- module Network.TLS.Handshake.Key ( encryptRSA - , signRSA + , signPrivate , decryptRSA - , verifyRSA + , verifyPublic , generateDHE , generateECDHE ) where @@ -37,8 +37,8 @@ Left err -> fail ("rsa encrypt failed: " ++ show err) Right econtent -> return econtent -signRSA :: Context -> Role -> Hash -> ByteString -> IO ByteString -signRSA ctx _ hsh content = do +signPrivate :: Context -> Role -> Hash -> ByteString -> IO ByteString +signPrivate ctx _ hsh content = do privateKey <- usingHState ctx getLocalPrivateKey usingState_ ctx $ do r <- withRNG $ kxSign privateKey hsh content @@ -54,8 +54,8 @@ let cipher = if ver < TLS10 then econtent else B.drop 2 econtent withRNG $ kxDecrypt privateKey cipher -verifyRSA :: Context -> Role -> Hash -> ByteString -> ByteString -> IO Bool -verifyRSA ctx _ hsh econtent sign = do +verifyPublic :: Context -> Role -> Hash -> ByteString -> ByteString -> IO Bool +verifyPublic ctx _ hsh econtent sign = do publicKey <- usingHState ctx getRemotePublicKey return $ kxVerify publicKey hsh econtent sign diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.3.8/Network/TLS/Handshake/Server.hs new/tls-1.3.9/Network/TLS/Handshake/Server.hs --- old/tls-1.3.8/Network/TLS/Handshake/Server.hs 2016-05-12 08:01:28.000000000 +0200 +++ new/tls-1.3.9/Network/TLS/Handshake/Server.hs 2016-12-17 12:09:25.000000000 +0100 @@ -106,8 +106,6 @@ Nothing -> throwCore $ Error_Protocol ("client version " ++ show clientVersion ++ " is not supported", True, ProtocolVersion) Just v -> return v - when (commonCipherIDs == []) $ throwCore $ - Error_Protocol ("no cipher in common with the client", True, HandshakeFailure) when (null commonCompressions) $ throwCore $ Error_Protocol ("no compression in common with the client", True, HandshakeFailure) @@ -117,10 +115,18 @@ toHostName (ServerNameOther _) = Nothing _ -> Nothing - let ciphersFilteredVersion = filter (cipherAllowedForVersion chosenVersion) commonCiphers - usedCipher = (onCipherChoosing $ serverHooks sparams) chosenVersion ciphersFilteredVersion extraCreds <- (onServerNameIndication $ serverHooks sparams) serverName - let creds = extraCreds `mappend` (sharedCredentials $ ctxShared ctx) + + -- The shared cipherlist can become empty after filtering for compatible + -- creds, check now before calling onCipherChoosing, which does not handle + -- empty lists. + let ciphersFilteredVersion = filter (cipherAllowedForVersion chosenVersion) (commonCiphers extraCreds) + when (null ciphersFilteredVersion) $ throwCore $ + Error_Protocol ("no cipher in common with the client", True, HandshakeFailure) + + let usedCipher = (onCipherChoosing $ serverHooks sparams) chosenVersion ciphersFilteredVersion + creds = extraCreds `mappend` (sharedCredentials $ ctxShared ctx) + cred <- case cipherKeyExchange usedCipher of CipherKeyExchange_RSA -> return $ credentialsFindForDecrypting creds CipherKeyExchange_DH_Anon -> return $ Nothing @@ -152,10 +158,10 @@ doHandshake sparams cred ctx chosenVersion usedCipher usedCompression clientSession resumeSessionData exts where - commonCipherIDs = intersect ciphers (map cipherID $ ctxCiphers ctx) - commonCiphers = filter (flip elem commonCipherIDs . cipherID) (ctxCiphers ctx) - commonCompressions = compressionIntersectID (supportedCompressions $ ctxSupported ctx) compressions - usedCompression = head commonCompressions + commonCipherIDs extra = intersect ciphers (map cipherID $ (ctxCiphers ctx extra)) + commonCiphers extra = filter (flip elem (commonCipherIDs extra) . cipherID) (ctxCiphers ctx extra) + commonCompressions = compressionIntersectID (supportedCompressions $ ctxSupported ctx) compressions + usedCompression = head commonCompressions handshakeServerWith _ _ _ = throwCore $ Error_Protocol ("unexpected handshake message received in handshakeServerWith", True, HandshakeFailure) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.3.8/Network/TLS/Handshake/Signature.hs new/tls-1.3.9/Network/TLS/Handshake/Signature.hs --- old/tls-1.3.8/Network/TLS/Handshake/Signature.hs 2016-05-12 08:01:28.000000000 +0200 +++ new/tls-1.3.9/Network/TLS/Handshake/Signature.hs 2016-12-17 12:09:25.000000000 +0100 @@ -107,7 +107,7 @@ case (malg, hashAlg) of (Nothing, SHA1_MD5) -> hashFinal $ hashUpdate (hashInit SHA1_MD5) toSign _ -> toSign - DigitallySigned malg <$> signRSA ctx cc hashAlg signData + DigitallySigned malg <$> signPrivate ctx cc hashAlg signData signatureVerify :: Context -> DigitallySigned -> SignatureAlgorithm -> Bytes -> IO Bool signatureVerify ctx digSig@(DigitallySigned hashSigAlg _) sigAlgExpected toVerifyData = do @@ -133,9 +133,9 @@ signatureVerifyWithHashDescr ctx sigAlgExpected (DigitallySigned _ bs) (hashDescr, toVerify) = do cc <- usingState_ ctx $ isClientContext case sigAlgExpected of - SignatureRSA -> verifyRSA ctx cc hashDescr toVerify bs - SignatureDSS -> verifyRSA ctx cc hashDescr toVerify bs - SignatureECDSA -> verifyRSA ctx cc hashDescr toVerify bs + SignatureRSA -> verifyPublic ctx cc hashDescr toVerify bs + SignatureDSS -> verifyPublic ctx cc hashDescr toVerify bs + SignatureECDSA -> verifyPublic ctx cc hashDescr toVerify bs _ -> error "signature verification not implemented yet" digitallySignParams :: Context -> Bytes -> SignatureAlgorithm -> IO DigitallySigned diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.3.8/Network/TLS/Handshake/State.hs new/tls-1.3.9/Network/TLS/Handshake/State.hs --- old/tls-1.3.8/Network/TLS/Handshake/State.hs 2016-05-12 08:01:28.000000000 +0200 +++ new/tls-1.3.9/Network/TLS/Handshake/State.hs 2016-12-17 12:09:25.000000000 +0100 @@ -188,7 +188,8 @@ where gen hst = case hstHandshakeDigest hst of Right hashCtx -> let msecret = fromJust "master secret" $ hstMasterSecret hst - in generateFinish ver msecret hashCtx + cipher = fromJust "cipher" $ hstPendingCipher hst + in generateFinish ver cipher msecret hashCtx Left _ -> error "un-initialized handshake digest" generateFinish | role == ClientRole = generateClientFinished @@ -203,7 +204,8 @@ setMasterSecretFromPre ver role premasterSecret = do secret <- genSecret <$> get setMasterSecret ver role secret - where genSecret hst = generateMasterSecret ver + where genSecret hst = + generateMasterSecret ver (fromJust "cipher" $ hstPendingCipher hst) premasterSecret (hstClientRandom hst) (fromJust "server random" $ hstServerRandom hst) @@ -227,7 +229,7 @@ else 0 keySize = bulkKeySize bulk ivSize = bulkIVSize bulk - kb = generateKeyBlock ver (hstClientRandom hst) + kb = generateKeyBlock ver cipher (hstClientRandom hst) (fromJust "server random" $ hstServerRandom hst) masterSecret keyblockSize @@ -271,6 +273,14 @@ , hstPendingCompression = compression , hstHandshakeDigest = updateDigest $ hstHandshakeDigest hst } - where hashAlg = if ver < TLS12 then SHA1_MD5 else SHA256 + where hashAlg = getHash ver cipher updateDigest (Left bytes) = Right $ foldl hashUpdate (hashInit hashAlg) $ reverse bytes updateDigest (Right _) = error "cannot initialize digest with another digest" + +-- The TLS12 Hash is cipher specific, and some TLS12 algorithms use SHA384 +-- instead of the default SHA256. +getHash :: Version -> Cipher -> Hash +getHash ver ciph + | ver < TLS12 = SHA1_MD5 + | maybe True (< TLS12) (cipherMinVer ciph) = SHA256 + | otherwise = cipherHash ciph diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.3.8/Network/TLS/MAC.hs new/tls-1.3.9/Network/TLS/MAC.hs --- old/tls-1.3.8/Network/TLS/MAC.hs 2016-05-12 08:01:28.000000000 +0200 +++ new/tls-1.3.9/Network/TLS/MAC.hs 2016-12-17 12:09:25.000000000 +0100 @@ -11,10 +11,12 @@ , prf_MD5 , prf_SHA1 , prf_SHA256 + , prf_TLS , prf_MD5SHA1 ) where import Network.TLS.Crypto +import Network.TLS.Types import qualified Data.ByteString as B import Data.ByteString (ByteString) import Data.Bits (xor) @@ -71,3 +73,9 @@ prf_SHA256 :: ByteString -> ByteString -> Int -> ByteString prf_SHA256 secret seed len = B.concat $ hmacIter (hmac SHA256) secret seed seed len + +-- | For now we ignore the version, but perhaps some day the PRF will depend +-- not only on the cipher PRF algorithm, but also on the protocol version. +prf_TLS :: Version -> Hash -> ByteString -> ByteString -> Int -> ByteString +prf_TLS _ halg secret seed len = + B.concat $ hmacIter (hmac halg) secret seed seed len diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.3.8/Network/TLS/Packet.hs new/tls-1.3.9/Network/TLS/Packet.hs --- old/tls-1.3.8/Network/TLS/Packet.hs 2016-05-12 08:01:28.000000000 +0200 +++ new/tls-1.3.9/Network/TLS/Packet.hs 2016-12-17 12:09:25.000000000 +0100 @@ -71,7 +71,7 @@ import Data.X509 (CertificateChainRaw(..), encodeCertificateChain, decodeCertificateChain) import Network.TLS.Crypto import Network.TLS.MAC -import Network.TLS.Cipher (CipherKeyExchangeType(..)) +import Network.TLS.Cipher (CipherKeyExchangeType(..), Cipher(..)) import Network.TLS.Util.Serialization (os2ip,i2ospOf_) import Data.ByteString (ByteString) import qualified Data.ByteString as B @@ -380,9 +380,9 @@ putExtensions exts return () -encodeHandshakeContent (ServerHello version random session cipherID compressionID exts) = +encodeHandshakeContent (ServerHello version random session cipherid compressionID exts) = putVersion version >> putServerRandom32 random >> putSession session - >> putWord16 cipherID >> putWord8 compressionID + >> putWord16 cipherid >> putWord8 compressionID >> putExtensions exts >> return () encodeHandshakeContent (Certificates cc) = putOpaque24 (runPut $ mapM_ putOpaque24 certs) @@ -581,6 +581,14 @@ -} type PRF = Bytes -> Bytes -> Int -> Bytes +-- | The TLS12 PRF is cipher specific, and some TLS12 algorithms use SHA384 +-- instead of the default SHA256. +getPRF :: Version -> Cipher -> PRF +getPRF ver ciph + | ver < TLS12 = prf_MD5SHA1 + | maybe True (< TLS12) (cipherMinVer ciph) = prf_SHA256 + | otherwise = prf_TLS ver $ maybe SHA256 id $ cipherPRFHash ciph + generateMasterSecret_SSL :: ByteArrayAccess preMaster => preMaster -> ClientRandom -> ServerRandom -> Bytes generateMasterSecret_SSL premasterSecret (ClientRandom c) (ServerRandom s) = B.concat $ map (computeMD5) ["A","BB","CCC"] @@ -592,12 +600,16 @@ prf (B.convert premasterSecret) seed 48 where seed = B.concat [ "master secret", c, s ] -generateMasterSecret :: ByteArrayAccess preMaster => Version -> preMaster -> ClientRandom -> ServerRandom -> Bytes -generateMasterSecret SSL2 = generateMasterSecret_SSL -generateMasterSecret SSL3 = generateMasterSecret_SSL -generateMasterSecret TLS10 = generateMasterSecret_TLS prf_MD5SHA1 -generateMasterSecret TLS11 = generateMasterSecret_TLS prf_MD5SHA1 -generateMasterSecret TLS12 = generateMasterSecret_TLS prf_SHA256 +generateMasterSecret :: ByteArrayAccess preMaster + => Version + -> Cipher + -> preMaster + -> ClientRandom + -> ServerRandom + -> Bytes +generateMasterSecret SSL2 _ = generateMasterSecret_SSL +generateMasterSecret SSL3 _ = generateMasterSecret_SSL +generateMasterSecret v c = generateMasterSecret_TLS $ getPRF v c generateKeyBlock_TLS :: PRF -> ClientRandom -> ServerRandom -> Bytes -> Int -> Bytes generateKeyBlock_TLS prf (ClientRandom c) (ServerRandom s) mastersecret kbsize = @@ -610,12 +622,16 @@ computeMD5 label = hash MD5 $ B.concat [ mastersecret, computeSHA1 label ] computeSHA1 label = hash SHA1 $ B.concat [ label, mastersecret, s, c ] -generateKeyBlock :: Version -> ClientRandom -> ServerRandom -> Bytes -> Int -> Bytes -generateKeyBlock SSL2 = generateKeyBlock_SSL -generateKeyBlock SSL3 = generateKeyBlock_SSL -generateKeyBlock TLS10 = generateKeyBlock_TLS prf_MD5SHA1 -generateKeyBlock TLS11 = generateKeyBlock_TLS prf_MD5SHA1 -generateKeyBlock TLS12 = generateKeyBlock_TLS prf_SHA256 +generateKeyBlock :: Version + -> Cipher + -> ClientRandom + -> ServerRandom + -> Bytes + -> Int + -> Bytes +generateKeyBlock SSL2 _ = generateKeyBlock_SSL +generateKeyBlock SSL3 _ = generateKeyBlock_SSL +generateKeyBlock v c = generateKeyBlock_TLS $ getPRF v c generateFinished_TLS :: PRF -> Bytes -> Bytes -> HashCtx -> Bytes generateFinished_TLS prf label mastersecret hashctx = prf mastersecret seed 12 @@ -632,17 +648,23 @@ pad2 = B.replicate 48 0x5c pad1 = B.replicate 48 0x36 -generateClientFinished :: Version -> Bytes -> HashCtx -> Bytes -generateClientFinished ver +generateClientFinished :: Version + -> Cipher + -> Bytes + -> HashCtx + -> Bytes +generateClientFinished ver ciph | ver < TLS10 = generateFinished_SSL "CLNT" - | ver < TLS12 = generateFinished_TLS prf_MD5SHA1 "client finished" - | otherwise = generateFinished_TLS prf_SHA256 "client finished" + | otherwise = generateFinished_TLS (getPRF ver ciph) "client finished" -generateServerFinished :: Version -> Bytes -> HashCtx -> Bytes -generateServerFinished ver +generateServerFinished :: Version + -> Cipher + -> Bytes + -> HashCtx + -> Bytes +generateServerFinished ver ciph | ver < TLS10 = generateFinished_SSL "SRVR" - | ver < TLS12 = generateFinished_TLS prf_MD5SHA1 "server finished" - | otherwise = generateFinished_TLS prf_SHA256 "server finished" + | otherwise = generateFinished_TLS (getPRF ver ciph) "server finished" generateCertificateVerify_SSL :: Bytes -> HashCtx -> Bytes generateCertificateVerify_SSL = generateFinished_SSL "" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.3.8/Network/TLS/Parameters.hs new/tls-1.3.9/Network/TLS/Parameters.hs --- old/tls-1.3.8/Network/TLS/Parameters.hs 2016-05-12 08:01:28.000000000 +0200 +++ new/tls-1.3.9/Network/TLS/Parameters.hs 2016-12-17 12:09:25.000000000 +0100 @@ -88,6 +88,8 @@ , clientWantSessionResume :: Maybe (SessionID, SessionData) , clientShared :: Shared , clientHooks :: ClientHooks + -- | In this element, you'll need to override the default empty value of + -- of 'supportedCiphers' with a suitable cipherlist. , clientSupported :: Supported , clientDebug :: DebugParams } deriving (Show) @@ -144,7 +146,9 @@ -- On the client side, the highest version will be used to establish the connection. -- On the server side, the highest version that is less or equal than the client version will be chosed. supportedVersions :: [Version] - -- | Supported cipher methods + -- | Supported cipher methods. The default is empty, specify a suitable + -- cipher list. 'Network.TLS.Extra.Cipher.ciphersuite_default' is often + -- a good choice. , supportedCiphers :: [Cipher] -- | supported compressions methods , supportedCompressions :: [Compression] @@ -182,9 +186,11 @@ , supportedCiphers = [] , supportedCompressions = [nullCompression] , supportedHashSignatures = [ (Struct.HashSHA512, SignatureRSA) + , (Struct.HashSHA512, SignatureECDSA) , (Struct.HashSHA384, SignatureRSA) + , (Struct.HashSHA384, SignatureECDSA) , (Struct.HashSHA256, SignatureRSA) - , (Struct.HashSHA224, SignatureRSA) + , (Struct.HashSHA256, SignatureECDSA) , (Struct.HashSHA1, SignatureRSA) , (Struct.HashSHA1, SignatureDSS) ] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.3.8/Network/TLS.hs new/tls-1.3.9/Network/TLS.hs --- old/tls-1.3.8/Network/TLS.hs 2016-05-12 08:01:28.000000000 +0200 +++ new/tls-1.3.9/Network/TLS.hs 2016-09-16 08:04:43.000000000 +0200 @@ -10,13 +10,17 @@ ( -- * Context configuration ClientParams(..) + , HostName + , Bytes , ServerParams(..) , DebugParams(..) + , DHParams , ClientHooks(..) , ServerHooks(..) , Supported(..) , Shared(..) , Hooks(..) + , Handshake , Logging(..) , Measurement(..) , CertificateUsage(..) @@ -45,7 +49,7 @@ , Context , ctxConnection , TLSParams - , HasBackend + , HasBackend(..) -- * Creating a context , contextNew @@ -62,6 +66,9 @@ -- * Information gathering , Information(..) + , ClientRandom + , ServerRandom + , unClientRandom , unServerRandom , contextGetInformation @@ -120,13 +127,15 @@ , exceptionValidationCache ) where -import Network.TLS.Backend (Backend(..), HasBackend) +import Network.TLS.Backend (Backend(..), HasBackend(..)) import Network.TLS.Struct ( TLSError(..), TLSException(..) , HashAndSignatureAlgorithm, HashAlgorithm(..), SignatureAlgorithm(..) , Header(..), ProtocolType(..), CertificateType(..) , AlertDescription(..) - , ClientRandom(..), ServerRandom(..)) -import Network.TLS.Crypto (KxError(..)) + , ClientRandom(..), ServerRandom(..) + , Bytes + , Handshake) +import Network.TLS.Crypto (KxError(..), DHParams) import Network.TLS.Cipher import Network.TLS.Hooks import Network.TLS.Measurement diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.3.8/Tests/Connection.hs new/tls-1.3.9/Tests/Connection.hs --- old/tls-1.3.8/Tests/Connection.hs 2016-05-12 08:01:28.000000000 +0200 +++ new/tls-1.3.9/Tests/Connection.hs 2016-12-17 12:09:25.000000000 +0100 @@ -38,6 +38,7 @@ , bulkF = BulkBlockF $ \_ _ _ -> (\m -> (m, B.empty)) } , cipherHash = MD5 + , cipherPRFHash = Nothing , cipherKeyExchange = CipherKeyExchange_RSA , cipherMinVer = Nothing } @@ -56,6 +57,23 @@ , cipherKeyExchange = CipherKeyExchange_DHE_DSS } +blockCipherECDHE_RSA :: Cipher +blockCipherECDHE_RSA = blockCipher + { cipherID = 0xff16 + , cipherName = "ecdhe-rsa-id-const" + , cipherKeyExchange = CipherKeyExchange_ECDHE_RSA + } + +blockCipherECDHE_RSA_SHA384 :: Cipher +blockCipherECDHE_RSA_SHA384 = blockCipher + { cipherID = 0xff17 + , cipherName = "ecdhe-rsa-id-const-sha384" + , cipherKeyExchange = CipherKeyExchange_ECDHE_RSA + , cipherHash = SHA384 + , cipherPRFHash = Just SHA384 + , cipherMinVer = Just TLS12 + } + streamCipher :: Cipher streamCipher = blockCipher { cipherID = 0xff13 @@ -73,7 +91,13 @@ passThrough _ _ = BulkStream go where go inp = (inp, BulkStream go) knownCiphers :: [Cipher] -knownCiphers = [blockCipher,blockCipherDHE_RSA,blockCipherDHE_DSS,streamCipher] +knownCiphers = [ blockCipher + , blockCipherDHE_RSA + , blockCipherDHE_DSS + , blockCipherECDHE_RSA + , blockCipherECDHE_RSA_SHA384 + , streamCipher + ] knownVersions :: [Version] knownVersions = [SSL3,TLS10,TLS11,TLS12] @@ -86,10 +110,16 @@ return (CertificateChain [cert], priv) ) [ (pubKey, privKey), (dsaPub, dsaPriv) ] connectVersion <- elements knownVersions - let allowedVersions = [ v | v <- knownVersions, v <= connectVersion ] + serverCiphers <- arbitraryCiphers `suchThat` + (\cs -> or [maybe True (<= connectVersion) (cipherMinVer x) | x <- cs]) + clientCiphers <- oneof [arbitraryCiphers] `suchThat` + (\cs -> or [x `elem` serverCiphers && + maybe True (<= connectVersion) (cipherMinVer x) | x <- cs]) + -- The shared ciphers may set a floor on the compatible protocol versions + let allowedVersions = [ v | v <- knownVersions, + or [ x `elem` serverCiphers && + maybe True (<= v) (cipherMinVer x) | x <- clientCiphers ]] serAllowedVersions <- (:[]) `fmap` elements allowedVersions - serverCiphers <- arbitraryCiphers - clientCiphers <- oneof [arbitraryCiphers] `suchThat` (\cs -> or [x `elem` serverCiphers | x <- cs]) secNeg <- arbitrary @@ -155,10 +185,15 @@ (cCtx, sCtx) <- newPairContext pipe params - _ <- forkIO $ E.catch (tlsServer sCtx resultQueue) (printAndRaise "server") - _ <- forkIO $ E.catch (tlsClient startQueue cCtx) (printAndRaise "client") + _ <- forkIO $ E.catch (tlsServer sCtx resultQueue) + (printAndRaise "server" (serverSupported $ snd params)) + _ <- forkIO $ E.catch (tlsClient startQueue cCtx) + (printAndRaise "client" (clientSupported $ fst params)) return (startQueue, resultQueue) where - printAndRaise :: String -> E.SomeException -> IO () - printAndRaise s e = putStrLn (s ++ " exception: " ++ show e) >> E.throw e + printAndRaise :: String -> Supported -> E.SomeException -> IO () + printAndRaise s supported e = do + putStrLn $ s ++ " exception: " ++ show e ++ + ", supported: " ++ show supported + E.throw e diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.3.8/tls.cabal new/tls-1.3.9/tls.cabal --- old/tls-1.3.8/tls.cabal 2016-05-12 08:01:28.000000000 +0200 +++ new/tls-1.3.9/tls.cabal 2016-12-17 12:54:03.000000000 +0100 @@ -1,5 +1,5 @@ Name: tls -Version: 1.3.8 +Version: 1.3.9 Description: Native Haskell TLS and SSL protocol implementation for server and client. . @@ -23,7 +23,6 @@ Category: Network stability: experimental Cabal-Version: >=1.8 -Tested-With: GHC == 7.0.4, GHC == 7.4.2, GHC == 7.6.3, GHC == 7.8.4, GHC == 7.10.3, GHC == 8.0.1 Homepage: http://github.com/vincenthz/hs-tls extra-source-files: Tests/*.hs CHANGELOG.md @@ -49,13 +48,13 @@ , data-default-class -- crypto related , memory - , cryptonite >= 0.15 + , cryptonite >= 0.21 -- certificate related , asn1-types >= 0.2.0 , asn1-encoding - , x509 >= 1.6.2 && < 1.7.0 + , x509 >= 1.6.5 && < 1.7.0 , x509-store >= 1.6 - , x509-validation >= 1.6.3 && < 1.7.0 + , x509-validation >= 1.6.5 && < 1.7.0 , async if flag(network) Build-Depends: network @@ -122,6 +121,12 @@ type: exitcode-stdio-1.0 hs-source-dirs: Tests Main-is: Tests.hs + other-modules: Certificate + Ciphers + Connection + Marshalling + PipeChan + PubKey Build-Depends: base >= 3 && < 5 , mtl , cereal >= 0.3 @@ -157,5 +162,5 @@ source-repository head type: git - location: git://github.com/vincenthz/hs-tls + location: https://github.com/vincenthz/hs-tls subdir: core
participants (1)
-
root@hilbertn.suse.de