Hello community, here is the log from the commit of package ghc-tls for openSUSE:Factory checked in at 2015-06-23 11:59:30 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 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 2015-05-27 12:46:56.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.ghc-tls.new/ghc-tls.changes 2015-06-23 11:59:32.000000000 +0200 @@ -1,0 +2,8 @@ +Sun Jun 21 16:56:51 UTC 2015 - mimi...@gmail.com + +- update to 1.2.18 +* add more tests (network, local) +* cleanup cipher / bulk code, certificate verify / creation, and digitall signed handling +* fix handling of DHE ciphers with MS SSL stack that serialize leading zero. + +------------------------------------------------------------------- Old: ---- tls-1.2.17.tar.gz New: ---- tls-1.2.18.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ghc-tls.spec ++++++ --- /var/tmp/diff_new_pack.okzjLR/_old 2015-06-23 11:59:32.000000000 +0200 +++ /var/tmp/diff_new_pack.okzjLR/_new 2015-06-23 11:59:32.000000000 +0200 @@ -15,17 +15,18 @@ # Please submit bugfixes or comments via http://bugs.opensuse.org/ # + %global pkg_name tls %bcond_with tests -Name: ghc-%{pkg_name} -Version: 1.2.17 +Name: ghc-tls +Version: 1.2.18 Release: 0 Summary: TLS/SSL protocol native implementation (Server and Client) +License: BSD-3-Clause Group: System/Libraries -License: BSD-3-Clause Url: https://hackage.haskell.org/package/%{pkg_name} Source0: https://hackage.haskell.org/package/%{pkg_name}-%{version}/%{pkg_name}-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-build @@ -94,36 +95,28 @@ %prep %setup -q -n %{pkg_name}-%{version} - %build %ghc_lib_build - %install %ghc_lib_install - %check %if %{with tests} %cabal test %endif - %post devel %ghc_pkg_recache - %postun devel %ghc_pkg_recache - %files -f %{name}.files %defattr(-,root,root,-) %doc LICENSE - %files devel -f %{name}-devel.files %defattr(-,root,root,-) - %changelog ++++++ tls-1.2.17.tar.gz -> tls-1.2.18.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.2.17/CHANGELOG.md new/tls-1.2.18/CHANGELOG.md --- old/tls-1.2.17/CHANGELOG.md 2015-04-12 08:21:50.000000000 +0200 +++ new/tls-1.2.18/CHANGELOG.md 2015-06-19 15:56:01.000000000 +0200 @@ -1,3 +1,13 @@ +## Version 1.2.18 + +- add more tests (network, local) +- cleanup cipher / bulk code, certificate verify / creation, and digitall signed handling +- fix handling of DHE ciphers with MS SSL stack that serialize leading zero. + +## Version 1.2.17 + +- Fix an issue of type of key / hash that prevented connection with SChannel. + ## Version 1.2.16 - Fix an issue with stream cipher not correctly calculating the internal state, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.2.17/Network/TLS/Cipher.hs new/tls-1.2.18/Network/TLS/Cipher.hs --- old/tls-1.2.17/Network/TLS/Cipher.hs 2015-04-12 08:21:50.000000000 +0200 +++ new/tls-1.2.18/Network/TLS/Cipher.hs 2015-06-19 15:56:01.000000000 +0200 @@ -8,17 +8,23 @@ -- Portability : unknown -- module Network.TLS.Cipher - ( BulkFunctions(..) - , CipherKeyExchangeType(..) + ( CipherKeyExchangeType(..) , Bulk(..) + , BulkFunctions(..) + , BulkDirection(..) + , BulkState(..) + , BulkStream(..) + , BulkBlock + , BulkAEAD + , bulkInit , Hash(..) , Cipher(..) , CipherID - , Key - , IV - , Nonce - , AdditionalData , cipherKeyBlockSize + , BulkKey + , BulkIV + , BulkNonce + , BulkAdditionalData , cipherAllowedForVersion , cipherExchangeNeedMoreData , hasMAC @@ -28,29 +34,54 @@ import Crypto.Cipher.Types (AuthTag) import Network.TLS.Types (CipherID) import Network.TLS.Struct (Version(..)) +import Network.TLS.Crypto (Hash(..), hashDigestSize) import qualified Data.ByteString as B -- FIXME convert to newtype -type Key = B.ByteString -type IV = B.ByteString -type Nonce = B.ByteString -type AdditionalData = B.ByteString +type BulkKey = B.ByteString +type BulkIV = B.ByteString +type BulkNonce = B.ByteString +type BulkAdditionalData = B.ByteString + +data BulkState = + BulkStateStream BulkStream + | BulkStateBlock BulkBlock + | BulkStateAEAD BulkAEAD + | BulkStateUninitialized + +instance Show BulkState where + show (BulkStateStream _) = "BulkStateStream" + show (BulkStateBlock _) = "BulkStateBlock" + show (BulkStateAEAD _) = "BulkStateAEAD" + show (BulkStateUninitialized) = "BulkStateUninitialized" + +newtype BulkStream = BulkStream (B.ByteString -> (B.ByteString, BulkStream)) + +type BulkBlock = BulkIV -> B.ByteString -> (B.ByteString, BulkIV) + +type BulkAEAD = BulkNonce -> B.ByteString -> BulkAdditionalData -> (B.ByteString, AuthTag) + +data BulkDirection = BulkEncrypt | BulkDecrypt + deriving (Show,Eq) + +bulkInit :: Bulk -> BulkDirection -> BulkKey -> BulkState +bulkInit bulk direction key = + case bulkF bulk of + BulkBlockF ini -> BulkStateBlock (ini direction key) + BulkStreamF ini -> BulkStateStream (ini direction key) + BulkAeadF ini -> BulkStateAEAD (ini direction key) data BulkFunctions = - BulkBlockF (Key -> IV -> B.ByteString -> B.ByteString) - (Key -> IV -> B.ByteString -> B.ByteString) - | BulkStreamF (Key -> IV) - (IV -> B.ByteString -> (B.ByteString, IV)) - (IV -> B.ByteString -> (B.ByteString, IV)) - | BulkAeadF (Key -> Nonce -> B.ByteString -> AdditionalData -> (B.ByteString, AuthTag)) - (Key -> Nonce -> B.ByteString -> AdditionalData -> (B.ByteString, AuthTag)) + BulkBlockF (BulkDirection -> BulkKey -> BulkBlock) + | BulkStreamF (BulkDirection -> BulkKey -> BulkStream) + | BulkAeadF (BulkDirection -> BulkKey -> BulkAEAD) hasMAC,hasRecordIV :: BulkFunctions -> Bool -hasMAC (BulkBlockF _ _) = True -hasMAC (BulkStreamF _ _ _) = True -hasMAC (BulkAeadF _ _ ) = False +hasMAC (BulkBlockF _ ) = True +hasMAC (BulkStreamF _) = True +hasMAC (BulkAeadF _ ) = False hasRecordIV = hasMAC @@ -84,17 +115,6 @@ , bulkBlockSize b1 == bulkBlockSize b2 ] -data Hash = Hash - { hashName :: String - , hashSize :: Int - , hashF :: B.ByteString -> B.ByteString - } - -instance Show Hash where - show hash = hashName hash -instance Eq Hash where - h1 == h2 = hashName h1 == hashName h2 && hashSize h1 == hashSize h2 - -- | Cipher algorithm data Cipher = Cipher { cipherID :: CipherID @@ -106,7 +126,7 @@ } cipherKeyBlockSize :: Cipher -> Int -cipherKeyBlockSize cipher = 2 * (hashSize (cipherHash cipher) + bulkIVSize bulk + bulkKeySize bulk) +cipherKeyBlockSize cipher = 2 * (hashDigestSize (cipherHash cipher) + bulkIVSize bulk + bulkKeySize bulk) where bulk = cipherBulk cipher -- | Check if a specific 'Cipher' is allowed to be used diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.2.17/Network/TLS/Crypto/DH.hs new/tls-1.2.18/Network/TLS/Crypto/DH.hs --- old/tls-1.2.17/Network/TLS/Crypto/DH.hs 2015-04-12 08:21:50.000000000 +0200 +++ new/tls-1.2.18/Network/TLS/Crypto/DH.hs 2015-06-19 15:56:01.000000000 +0200 @@ -9,6 +9,8 @@ , dhPublic , dhPrivate , dhParams + , dhParamsGetP + , dhParamsGetG , dhGenerateKeyPair , dhGetShared , dhUnwrap @@ -49,5 +51,11 @@ dhUnwrap :: DHParams -> DHPublic -> [Integer] dhUnwrap (DH.Params p g) (DH.PublicNumber y) = [p,g,y] +dhParamsGetP :: DHParams -> Integer +dhParamsGetP (DH.Params p _) = p + +dhParamsGetG :: DHParams -> Integer +dhParamsGetG (DH.Params _ g) = g + dhUnwrapPublic :: DHPublic -> Integer dhUnwrapPublic (DH.PublicNumber y) = y diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.2.17/Network/TLS/Crypto.hs new/tls-1.2.18/Network/TLS/Crypto.hs --- old/tls-1.2.17/Network/TLS/Crypto.hs 2015-04-12 08:21:50.000000000 +0200 +++ new/tls-1.2.18/Network/TLS/Crypto.hs 2015-06-19 15:56:01.000000000 +0200 @@ -1,7 +1,8 @@ {-# OPTIONS_HADDOCK hide #-} {-# LANGUAGE ExistentialQuantification #-} module Network.TLS.Crypto - ( HashCtx(..) + ( HashContext + , HashCtx , hashInit , hashUpdate , hashUpdateSSL @@ -10,11 +11,12 @@ , module Network.TLS.Crypto.DH , module Network.TLS.Crypto.ECDH - -- * constructor - , hashMD5SHA1 - , hashSHA1 - , hashSHA256 - , hashSHA512 + -- * Hash + , hash + , Hash(..) + , hashName + , hashDigestSize + , hashBlockSize -- * key exchange generic interface , PubKey(..) @@ -29,11 +31,9 @@ , KxError(..) ) where -import qualified Crypto.Hash.SHA512 as SHA512 -import qualified Crypto.Hash.SHA256 as SHA256 -import qualified Crypto.Hash.SHA1 as SHA1 -import qualified Crypto.Hash.MD5 as MD5 +import qualified Crypto.Hash as H import qualified Data.ByteString as B +import qualified Data.Byteable as B import Data.ByteString (ByteString) import Crypto.PubKey.HashDescr import qualified Crypto.PubKey.DSA as DSA @@ -58,76 +58,74 @@ | KxUnsupported deriving (Show) -class HashCtxC a where - hashCName :: a -> String - hashCInit :: a -> a - hashCUpdate :: a -> B.ByteString -> a - hashCUpdateSSL :: a -> (B.ByteString,B.ByteString) -> a - hashCFinal :: a -> B.ByteString - -data HashCtx = forall h . HashCtxC h => HashCtx h - -instance Show HashCtx where - show (HashCtx c) = hashCName c - -{- MD5 & SHA1 joined -} -data HashMD5SHA1 = HashMD5SHA1 SHA1.Ctx MD5.Ctx - -instance HashCtxC HashMD5SHA1 where - hashCName _ = "MD5-SHA1" - hashCInit _ = HashMD5SHA1 SHA1.init MD5.init - hashCUpdate (HashMD5SHA1 sha1ctx md5ctx) b = HashMD5SHA1 (SHA1.update sha1ctx b) (MD5.update md5ctx b) - hashCUpdateSSL (HashMD5SHA1 sha1ctx md5ctx) (b1,b2) = HashMD5SHA1 (SHA1.update sha1ctx b2) (MD5.update md5ctx b1) - hashCFinal (HashMD5SHA1 sha1ctx md5ctx) = B.concat [MD5.finalize md5ctx, SHA1.finalize sha1ctx] - -newtype HashSHA1 = HashSHA1 SHA1.Ctx - -instance HashCtxC HashSHA1 where - hashCName _ = "SHA1" - hashCInit _ = HashSHA1 SHA1.init - hashCUpdate (HashSHA1 ctx) b = HashSHA1 (SHA1.update ctx b) - hashCUpdateSSL (HashSHA1 ctx) (_,b2) = HashSHA1 (SHA1.update ctx b2) - hashCFinal (HashSHA1 ctx) = SHA1.finalize ctx - -newtype HashSHA256 = HashSHA256 SHA256.Ctx - -instance HashCtxC HashSHA256 where - hashCName _ = "SHA256" - hashCInit _ = HashSHA256 SHA256.init - hashCUpdate (HashSHA256 ctx) b = HashSHA256 (SHA256.update ctx b) - hashCUpdateSSL _ _ = error "CUpdateSSL with HashSHA256" - hashCFinal (HashSHA256 ctx) = SHA256.finalize ctx - -newtype HashSHA512 = HashSHA512 SHA512.Ctx - -instance HashCtxC HashSHA512 where - hashCName _ = "SHA512" - hashCInit _ = HashSHA512 SHA512.init - hashCUpdate (HashSHA512 ctx) b = HashSHA512 (SHA512.update ctx b) - hashCUpdateSSL _ _ = error "CUpdateSSL with HashSHA512" - hashCFinal (HashSHA512 ctx) = SHA512.finalize ctx - -- functions to use the hidden class. -hashInit :: HashCtx -> HashCtx -hashInit (HashCtx h) = HashCtx $ hashCInit h - -hashUpdate :: HashCtx -> B.ByteString -> HashCtx -hashUpdate (HashCtx h) b = HashCtx $ hashCUpdate h b +hashInit :: Hash -> HashContext +hashInit MD5 = HashContext $ ContextSimple (H.hashInit :: H.Context H.MD5) +hashInit SHA1 = HashContext $ ContextSimple (H.hashInit :: H.Context H.SHA1) +hashInit SHA256 = HashContext $ ContextSimple (H.hashInit :: H.Context H.SHA256) +hashInit SHA512 = HashContext $ ContextSimple (H.hashInit :: H.Context H.SHA512) +hashInit SHA1_MD5 = HashContextSSL H.hashInit H.hashInit + +hashUpdate :: HashContext -> B.ByteString -> HashCtx +hashUpdate (HashContext (ContextSimple h)) b = HashContext $ ContextSimple (H.hashUpdate h b) +hashUpdate (HashContextSSL sha1Ctx md5Ctx) b = + HashContextSSL (H.hashUpdate sha1Ctx b) (H.hashUpdate md5Ctx b) hashUpdateSSL :: HashCtx -> (B.ByteString,B.ByteString) -- ^ (for the md5 context, for the sha1 context) -> HashCtx -hashUpdateSSL (HashCtx h) bs = HashCtx $ hashCUpdateSSL h bs +hashUpdateSSL (HashContext _) _ = error "internal error: update SSL without a SSL Context" +hashUpdateSSL (HashContextSSL sha1Ctx md5Ctx) (b1,b2) = + HashContextSSL (H.hashUpdate sha1Ctx b2) (H.hashUpdate md5Ctx b1) hashFinal :: HashCtx -> B.ByteString -hashFinal (HashCtx h) = hashCFinal h - --- real hash constructors -hashMD5SHA1, hashSHA1, hashSHA256, hashSHA512 :: HashCtx -hashMD5SHA1 = HashCtx (HashMD5SHA1 SHA1.init MD5.init) -hashSHA1 = HashCtx (HashSHA1 SHA1.init) -hashSHA256 = HashCtx (HashSHA256 SHA256.init) -hashSHA512 = HashCtx (HashSHA512 SHA512.init) +hashFinal (HashContext (ContextSimple h)) = B.toBytes $ H.hashFinalize h +hashFinal (HashContextSSL sha1Ctx md5Ctx) = + B.concat [B.toBytes (H.hashFinalize md5Ctx), B.toBytes (H.hashFinalize sha1Ctx)] + +data Hash = MD5 | SHA1 | SHA256 | SHA512 | SHA1_MD5 + deriving (Show,Eq) + +data HashContext = + HashContext ContextSimple + | HashContextSSL (H.Context H.SHA1) (H.Context H.MD5) + +instance Show HashContext where + show _ = "hash-context" + +data ContextSimple = forall alg . H.HashAlgorithm alg => ContextSimple (H.Context alg) + +type HashCtx = HashContext + +hash :: Hash -> B.ByteString -> B.ByteString +hash MD5 b = B.toBytes . (H.hash :: B.ByteString -> H.Digest H.MD5) $ b +hash SHA1 b = B.toBytes . (H.hash :: B.ByteString -> H.Digest H.SHA1) $ b +hash SHA256 b = B.toBytes . (H.hash :: B.ByteString -> H.Digest H.SHA256) $ b +hash SHA512 b = B.toBytes . (H.hash :: B.ByteString -> H.Digest H.SHA512) $ b +hash SHA1_MD5 b = + B.concat [B.toBytes (md5Hash b), B.toBytes (sha1Hash b)] + where + sha1Hash :: B.ByteString -> H.Digest H.SHA1 + sha1Hash = H.hash + md5Hash :: B.ByteString -> H.Digest H.MD5 + md5Hash = H.hash + +hashName :: Hash -> String +hashName = show + +hashDigestSize :: Hash -> Int +hashDigestSize MD5 = 16 +hashDigestSize SHA1 = 20 +hashDigestSize SHA256 = 32 +hashDigestSize SHA512 = 64 +hashDigestSize SHA1_MD5 = 36 + +hashBlockSize :: Hash -> Int +hashBlockSize MD5 = 64 +hashBlockSize SHA1 = 64 +hashBlockSize SHA256 = 64 +hashBlockSize SHA512 = 128 +hashBlockSize SHA1_MD5 = 64 {- key exchange methods encrypt and decrypt for each supported algorithm -} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.2.17/Network/TLS/ErrT.hs new/tls-1.2.18/Network/TLS/ErrT.hs --- old/tls-1.2.17/Network/TLS/ErrT.hs 2015-04-12 08:21:50.000000000 +0200 +++ new/tls-1.2.18/Network/TLS/ErrT.hs 2015-06-19 15:56:01.000000000 +0200 @@ -22,6 +22,7 @@ type ErrT = ExceptT #else import Control.Monad.Error +runErrT :: ErrorT e m a -> m (Either e a) runErrT = runErrorT type ErrT = ErrorT #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.2.17/Network/TLS/Extra/Cipher.hs new/tls-1.2.18/Network/TLS/Extra/Cipher.hs --- old/tls-1.2.17/Network/TLS/Extra/Cipher.hs 2015-04-12 08:21:50.000000000 +0200 +++ new/tls-1.2.18/Network/TLS/Extra/Cipher.hs 2015-06-19 15:56:01.000000000 +0200 @@ -43,62 +43,59 @@ import Network.TLS.Cipher import qualified "cipher-rc4" Crypto.Cipher.RC4 as RC4 -import qualified Crypto.Hash.SHA256 as SHA256 -import qualified Crypto.Hash.SHA1 as SHA1 -import qualified Crypto.Hash.MD5 as MD5 - import qualified "cipher-aes" Crypto.Cipher.AES as AES import Crypto.Cipher.TripleDES import Crypto.Cipher.Types (makeKey, makeIV, cipherInit, cbcEncrypt, cbcDecrypt) import qualified Crypto.Cipher.Types as T -aes_cbc_encrypt :: Key -> IV -> B.ByteString -> B.ByteString -aes_cbc_encrypt key iv d = AES.encryptCBC (AES.initAES key) iv d -aes_cbc_decrypt :: Key -> IV -> B.ByteString -> B.ByteString -aes_cbc_decrypt key iv d = AES.decryptCBC (AES.initAES key) iv d +takelast :: Int -> B.ByteString -> B.ByteString +takelast i b = B.drop (B.length b - i) b -aes128_cbc_encrypt - , aes128_cbc_decrypt - , aes256_cbc_encrypt - , aes256_cbc_decrypt :: Key -> IV -> B.ByteString -> B.ByteString -aes128_cbc_encrypt = aes_cbc_encrypt -aes128_cbc_decrypt = aes_cbc_decrypt -aes256_cbc_encrypt = aes_cbc_encrypt -aes256_cbc_decrypt = aes_cbc_decrypt - -aes128_gcm_encrypt, aes128_gcm_decrypt :: Key -> Nonce -> B.ByteString -> AdditionalData -> (B.ByteString, T.AuthTag) -aes128_gcm_encrypt key nonce d ad = AES.encryptGCM (AES.initAES key) nonce ad d -aes128_gcm_decrypt key nonce d ad = AES.decryptGCM (AES.initAES key) nonce ad d - -tripledes_ede_cbc_encrypt :: Key -> IV -> B.ByteString -> B.ByteString -tripledes_ede_cbc_encrypt key iv bs = - cbcEncrypt (cipherInit $ tripledes_key key) (tripledes_iv iv) bs - -tripledes_ede_cbc_decrypt :: Key -> IV -> B.ByteString -> B.ByteString -tripledes_ede_cbc_decrypt key iv bs = - cbcDecrypt (cipherInit $ tripledes_key key) (tripledes_iv iv) bs +aes128cbc :: BulkDirection -> BulkKey -> BulkBlock +aes128cbc BulkEncrypt key = + let ctx = AES.initAES key + in (\iv input -> let output = AES.encryptCBC ctx iv input in (output, takelast 16 output)) +aes128cbc BulkDecrypt key = + let ctx = AES.initAES key + in (\iv input -> let output = AES.decryptCBC ctx iv input in (output, takelast 16 input)) + +aes256cbc :: BulkDirection -> BulkKey -> BulkBlock +aes256cbc BulkEncrypt key = + let ctx = AES.initAES key + in (\iv input -> let output = AES.encryptCBC ctx iv input in (output, takelast 16 output)) +aes256cbc BulkDecrypt key = + let ctx = AES.initAES key + in (\iv input -> let output = AES.decryptCBC ctx iv input in (output, takelast 16 input)) + +aes128gcm :: BulkDirection -> BulkKey -> BulkAEAD +aes128gcm BulkEncrypt key = + let ctx = AES.initAES key + in (\nonce d ad -> AES.encryptGCM ctx nonce ad d) +aes128gcm BulkDecrypt key = + let ctx = AES.initAES key + in (\nonce d ad -> AES.decryptGCM ctx nonce ad d) + +tripledes_ede :: BulkDirection -> BulkKey -> BulkBlock +tripledes_ede BulkEncrypt key = + let ctx = cipherInit (tripledes_key key) + in (\iv input -> let output = cbcEncrypt ctx (tripledes_iv iv) input in (output, takelast 16 output)) +tripledes_ede BulkDecrypt key = + let ctx = cipherInit (tripledes_key key) + in (\iv input -> let output = cbcDecrypt ctx (tripledes_iv iv) input in (output, takelast 16 input)) -tripledes_key :: Key -> T.Key DES_EDE3 +tripledes_key :: BulkKey -> T.Key DES_EDE3 tripledes_key key = either (\ke -> error ("tripledes cipher key internal error: " ++ show ke)) id $ makeKey key -tripledes_iv :: IV -> T.IV DES_EDE3 +tripledes_iv :: BulkIV -> T.IV DES_EDE3 tripledes_iv iv = maybe (error "tripledes cipher iv internal error") id $ makeIV iv -toIV :: RC4.Ctx -> IV -toIV (RC4.Ctx ctx) = ctx - -toCtx :: IV -> RC4.Ctx -toCtx iv = RC4.Ctx iv - -initF_rc4 :: Key -> IV -initF_rc4 key = toIV $ RC4.initCtx key - -encryptF_rc4 :: IV -> B.ByteString -> (B.ByteString, IV) -encryptF_rc4 iv d = (\(ctx, e) -> (e, toIV ctx)) $ RC4.combine (toCtx iv) d - -decryptF_rc4 :: IV -> B.ByteString -> (B.ByteString, IV) -decryptF_rc4 iv e = (\(ctx, d) -> (d, toIV ctx)) $ RC4.combine (toCtx iv) e +rc4 :: BulkDirection -> BulkKey -> BulkStream +rc4 _ bulkKey = BulkStream (combineRC4 $ RC4.initCtx bulkKey) + where + combineRC4 ctx input = + let (ctx', output) = RC4.combine ctx input + in (output, BulkStream (combineRC4 ctx')) -- | all encrypted ciphers supported ordered from strong to weak. @@ -142,16 +139,17 @@ , bulkKeySize = 0 , bulkIVSize = 0 , bulkBlockSize = 0 - , bulkF = BulkStreamF (const B.empty) streamId streamId + , bulkF = BulkStreamF passThrough } - where streamId = \iv b -> (b,iv) + where + passThrough _ _ = BulkStream go where go inp = (inp, BulkStream go) bulk_rc4 = Bulk { bulkName = "RC4-128" , bulkKeySize = 16 , bulkIVSize = 0 , bulkBlockSize = 0 - , bulkF = BulkStreamF initF_rc4 encryptF_rc4 decryptF_rc4 + , bulkF = BulkStreamF rc4 } bulk_aes128 = Bulk @@ -159,7 +157,7 @@ , bulkKeySize = 16 , bulkIVSize = 16 , bulkBlockSize = 16 - , bulkF = BulkBlockF aes128_cbc_encrypt aes128_cbc_decrypt + , bulkF = BulkBlockF aes128cbc } bulk_aes128gcm = Bulk @@ -167,7 +165,7 @@ , bulkKeySize = 16 -- RFC 5116 Sec 5.1: K_LEN , bulkIVSize = 4 -- RFC 5288 GCMNonce.salt, fixed_iv_length , bulkBlockSize = 0 -- dummy, not used - , bulkF = BulkAeadF aes128_gcm_encrypt aes128_gcm_decrypt + , bulkF = BulkAeadF aes128gcm } bulk_aes256 = Bulk @@ -175,7 +173,7 @@ , bulkKeySize = 32 , bulkIVSize = 16 , bulkBlockSize = 16 - , bulkF = BulkBlockF aes256_cbc_encrypt aes256_cbc_decrypt + , bulkF = BulkBlockF aes256cbc } bulk_tripledes_ede = Bulk @@ -183,26 +181,7 @@ , bulkKeySize = 24 , bulkIVSize = 8 , bulkBlockSize = 8 - , bulkF = BulkBlockF tripledes_ede_cbc_encrypt tripledes_ede_cbc_decrypt - } - -hash_md5, hash_sha1, hash_sha256 :: Hash -hash_md5 = Hash - { hashName = "MD5" - , hashSize = 16 - , hashF = MD5.hash - } - -hash_sha1 = Hash - { hashName = "SHA1" - , hashSize = 20 - , hashF = SHA1.hash - } - -hash_sha256 = Hash - { hashName = "SHA256" - , hashSize = 32 - , hashF = SHA256.hash + , bulkF = BulkBlockF tripledes_ede } -- | unencrypted cipher using RSA for key exchange and MD5 for digest @@ -211,7 +190,7 @@ { cipherID = 0x1 , cipherName = "RSA-null-MD5" , cipherBulk = bulk_null - , cipherHash = hash_md5 + , cipherHash = MD5 , cipherKeyExchange = CipherKeyExchange_RSA , cipherMinVer = Nothing } @@ -222,7 +201,7 @@ { cipherID = 0x2 , cipherName = "RSA-null-SHA1" , cipherBulk = bulk_null - , cipherHash = hash_sha1 + , cipherHash = SHA1 , cipherKeyExchange = CipherKeyExchange_RSA , cipherMinVer = Nothing } @@ -233,7 +212,7 @@ { cipherID = 0x04 , cipherName = "RSA-rc4-128-md5" , cipherBulk = bulk_rc4 - , cipherHash = hash_md5 + , cipherHash = MD5 , cipherKeyExchange = CipherKeyExchange_RSA , cipherMinVer = Nothing } @@ -244,7 +223,7 @@ { cipherID = 0x05 , cipherName = "RSA-rc4-128-sha1" , cipherBulk = bulk_rc4 - , cipherHash = hash_sha1 + , cipherHash = SHA1 , cipherKeyExchange = CipherKeyExchange_RSA , cipherMinVer = Nothing } @@ -255,7 +234,7 @@ { cipherID = 0x2f , cipherName = "RSA-aes128-sha1" , cipherBulk = bulk_aes128 - , cipherHash = hash_sha1 + , cipherHash = SHA1 , cipherKeyExchange = CipherKeyExchange_RSA , cipherMinVer = Just SSL3 } @@ -266,7 +245,7 @@ { cipherID = 0x35 , cipherName = "RSA-aes256-sha1" , cipherBulk = bulk_aes256 - , cipherHash = hash_sha1 + , cipherHash = SHA1 , cipherKeyExchange = CipherKeyExchange_RSA , cipherMinVer = Just SSL3 } @@ -277,7 +256,7 @@ { cipherID = 0x3c , cipherName = "RSA-aes128-sha256" , cipherBulk = bulk_aes128 - , cipherHash = hash_sha256 + , cipherHash = SHA256 , cipherKeyExchange = CipherKeyExchange_RSA , cipherMinVer = Just TLS12 } @@ -288,7 +267,7 @@ { cipherID = 0x3d , cipherName = "RSA-aes256-sha256" , cipherBulk = bulk_aes256 - , cipherHash = hash_sha256 + , cipherHash = SHA256 , cipherKeyExchange = CipherKeyExchange_RSA , cipherMinVer = Just TLS12 } @@ -299,7 +278,7 @@ { cipherID = 0x33 , cipherName = "DHE-RSA-AES128-SHA1" , cipherBulk = bulk_aes128 - , cipherHash = hash_sha1 + , cipherHash = SHA1 , cipherKeyExchange = CipherKeyExchange_DHE_RSA , cipherMinVer = Nothing } @@ -318,7 +297,7 @@ { cipherID = 0x32 , cipherName = "DHE-DSA-AES128-SHA1" , cipherBulk = bulk_aes128 - , cipherHash = hash_sha1 + , cipherHash = SHA1 , cipherKeyExchange = CipherKeyExchange_DHE_DSS , cipherMinVer = Nothing } @@ -342,7 +321,7 @@ cipher_DHE_RSA_AES128_SHA256 = cipher_DHE_RSA_AES128_SHA1 { cipherID = 0x67 , cipherName = "DHE-RSA-AES128-SHA256" - , cipherHash = hash_sha256 + , cipherHash = SHA256 , cipherMinVer = Just TLS12 } @@ -359,7 +338,7 @@ { cipherID = 0x0a , cipherName = "RSA-3DES-EDE-CBC-SHA1" , cipherBulk = bulk_tripledes_ede - , cipherHash = hash_sha1 + , cipherHash = SHA1 , cipherKeyExchange = CipherKeyExchange_RSA , cipherMinVer = Nothing } @@ -369,7 +348,7 @@ { cipherID = 0x9e , cipherName = "DHE-RSA-AES128GCM-SHA256" , cipherBulk = bulk_aes128gcm - , cipherHash = hash_sha256 + , cipherHash = SHA256 , cipherKeyExchange = CipherKeyExchange_DHE_RSA , cipherMinVer = Just TLS12 -- RFC 5288 Sec 4 } @@ -379,7 +358,7 @@ { cipherID = 0xc02f , cipherName = "ECDHE-RSA-AES128GCM-SHA256" , cipherBulk = bulk_aes128gcm - , cipherHash = hash_sha256 + , cipherHash = SHA256 , cipherKeyExchange = CipherKeyExchange_ECDHE_RSA , cipherMinVer = Just TLS12 -- RFC 5288 Sec 4 } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.2.17/Network/TLS/Handshake/Client.hs new/tls-1.2.18/Network/TLS/Handshake/Client.hs --- old/tls-1.2.17/Network/TLS/Handshake/Client.hs 2015-04-12 08:21:50.000000000 +0200 +++ new/tls-1.2.18/Network/TLS/Handshake/Client.hs 2015-06-19 15:56:01.000000000 +0200 @@ -209,10 +209,12 @@ sendPacket ctx $ Handshake [ClientKeyXchg ckx] where getCKX_DHE = do xver <- usingState_ ctx getVersion - (ServerDHParams dhparams serverDHPub) <- fromJust <$> usingHState ctx (gets hstServerDHParams) - (clientDHPriv, clientDHPub) <- generateDHE ctx dhparams + serverParams <- fromJust <$> usingHState ctx (gets hstServerDHParams) + (clientDHPriv, clientDHPub) <- generateDHE ctx (serverDHParamsToParams serverParams) - let premaster = dhGetShared dhparams clientDHPriv serverDHPub + let premaster = dhGetShared (serverDHParamsToParams serverParams) + clientDHPriv + (serverDHParamsToPublic serverParams) usingHState ctx $ setMasterSecretFromPre xver ClientRole premaster return $ CKX_DH clientDHPub @@ -258,10 +260,8 @@ _ -> return Nothing -- Fetch all handshake messages up to now. - msgs <- usingHState ctx $ B.concat <$> getHandshakeMessages - (hashMethod, toSign) <- prepareCertificateVerifySignatureData ctx usedVersion malg msgs - - sigDig <- signatureCreate ctx malg hashMethod toSign + msgs <- usingHState ctx $ B.concat <$> getHandshakeMessages + sigDig <- certificateVerifyCreate ctx usedVersion malg msgs sendPacket ctx $ Handshake [CertVerify sigDig] _ -> return () @@ -389,15 +389,13 @@ (c,_) -> throwCore $ Error_Protocol ("unknown server key exchange received, expecting: " ++ show c, True, HandshakeFailure) doDHESignature dhparams signature signatureType = do -- TODO verify DHParams - expectedData <- generateSignedDHParams ctx dhparams - verified <- signatureVerify ctx signatureType expectedData signature - when (not verified) $ throwCore $ Error_Protocol ("bad " ++ show signatureType ++ " for dhparams", True, HandshakeFailure) + verified <- digitallySignDHParamsVerify ctx dhparams signatureType signature + when (not verified) $ throwCore $ Error_Protocol ("bad " ++ show signatureType ++ " for dhparams " ++ show dhparams, True, HandshakeFailure) usingHState ctx $ setServerDHParams dhparams doECDHESignature ecdhparams signature signatureType = do -- TODO verify DHParams - expectedData <- generateSignedECDHParams ctx ecdhparams - verified <- signatureVerify ctx signatureType expectedData signature + verified <- digitallySignECDHParamsVerify ctx ecdhparams signatureType signature when (not verified) $ throwCore $ Error_Protocol ("bad " ++ show signatureType ++ " for dhparams", True, HandshakeFailure) usingHState ctx $ setServerECDHParams ecdhparams diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.2.17/Network/TLS/Handshake/Process.hs new/tls-1.2.18/Network/TLS/Handshake/Process.hs --- old/tls-1.2.17/Network/TLS/Handshake/Process.hs 2015-04-12 08:21:50.000000000 +0200 +++ new/tls-1.2.18/Network/TLS/Handshake/Process.hs 2015-06-19 15:56:01.000000000 +0200 @@ -88,9 +88,9 @@ rver <- usingState_ ctx getVersion role <- usingState_ ctx isClientContext - (ServerDHParams dhparams _) <- fromJust "server dh params" <$> usingHState ctx (gets hstServerDHParams) - dhpriv <- fromJust "dh private" <$> usingHState ctx (gets hstDHPrivate) - let premaster = dhGetShared dhparams dhpriv clientDHValue + serverParams <- fromJust "server dh params" <$> usingHState ctx (gets hstServerDHParams) + dhpriv <- fromJust "dh private" <$> usingHState ctx (gets hstDHPrivate) + let premaster = dhGetShared (serverDHParamsToParams serverParams) dhpriv clientDHValue usingHState ctx $ setMasterSecretFromPre rver role premaster processClientKeyXchg ctx (CKX_ECDH clientECDHValue) = do diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.2.17/Network/TLS/Handshake/Server.hs new/tls-1.2.18/Network/TLS/Handshake/Server.hs --- old/tls-1.2.17/Network/TLS/Handshake/Server.hs 2015-04-12 08:21:50.000000000 +0200 +++ new/tls-1.2.18/Network/TLS/Handshake/Server.hs 2015-06-19 15:56:01.000000000 +0200 @@ -268,7 +268,7 @@ let dhparams = fromJust "server DHE Params" $ serverDHEParams sparams (priv, pub) <- generateDHE ctx dhparams - let serverParams = ServerDHParams dhparams pub + let serverParams = serverDHParamsFrom dhparams pub usingHState ctx $ setServerDHParams serverParams usingHState ctx $ modify $ \hst -> hst { hstDHPrivate = Just priv } @@ -276,17 +276,7 @@ generateSKX_DHE sigAlg = do serverParams <- setup_DHE - signatureData <- generateSignedDHParams ctx serverParams - - usedVersion <- usingState_ ctx getVersion - let mhash = case usedVersion of - TLS12 -> case filter ((==) sigAlg . snd) $ supportedHashSignatures $ ctxSupported ctx of - [] -> error ("no hash signature for " ++ show sigAlg) - x:_ -> Just (fst x) - _ -> Nothing - let hashDescr = signatureHashData sigAlg mhash - signed <- signatureCreate ctx (fmap (\h -> (h, sigAlg)) mhash) hashDescr signatureData - + signed <- digitallySignDHParams ctx serverParams sigAlg case sigAlg of SignatureRSA -> return $ SKX_DHE_RSA serverParams signed SignatureDSS -> return $ SKX_DHE_DSS serverParams signed @@ -311,22 +301,14 @@ -- There may be a better way to choose EC. nc = if null common then error "No common EllipticCurves" else maximum $ map fromEnumSafe16 common - serverParams <- setup_ECDHE nc - signatureData <- generateSignedECDHParams ctx serverParams - - usedVersion <- usingState_ ctx getVersion - let mhash = case usedVersion of - TLS12 -> case filter ((==) sigAlg . snd) $ supportedHashSignatures $ ctxSupported ctx of - [] -> error ("no hash signature for " ++ show sigAlg) - x:_ -> Just (fst x) - _ -> Nothing - let hashDescr = signatureHashData sigAlg mhash - signed <- signatureCreate ctx (fmap (\h -> (h, sigAlg)) mhash) hashDescr signatureData - + serverParams <- setup_ECDHE nc + signed <- digitallySignECDHParams ctx serverParams sigAlg case sigAlg of SignatureRSA -> return $ SKX_ECDHE_RSA serverParams signed _ -> error ("generate skx_dhe unsupported signature type: " ++ show sigAlg) + -- create a DigitallySigned objects for DHParams or ECDHParams. + -- | receive Client data in handshake until the Finished handshake. -- -- <- [certificate] @@ -376,11 +358,8 @@ usedVersion <- usingState_ ctx getVersion -- Fetch all handshake messages up to now. - msgs <- usingHState ctx $ B.concat <$> getHandshakeMessages - (hashMethod, toVerify) <- prepareCertificateVerifySignatureData ctx usedVersion mbHashSig msgs - - -- Verify the signature. - verif <- signatureVerifyWithHashDescr ctx SignatureRSA hashMethod toVerify dsig + msgs <- usingHState ctx $ B.concat <$> getHandshakeMessages + verif <- certificateVerifyCheck ctx usedVersion mbHashSig msgs dsig case verif of True -> do diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.2.17/Network/TLS/Handshake/Signature.hs new/tls-1.2.18/Network/TLS/Handshake/Signature.hs --- old/tls-1.2.17/Network/TLS/Handshake/Signature.hs 2015-04-12 08:21:50.000000000 +0200 +++ new/tls-1.2.18/Network/TLS/Handshake/Signature.hs 2015-06-19 15:56:01.000000000 +0200 @@ -7,14 +7,13 @@ -- Portability : unknown -- module Network.TLS.Handshake.Signature - ( getHashAndASN1 - , prepareCertificateVerifySignatureData - , signatureHashData - , signatureCreate - , signatureVerify - , signatureVerifyWithHashDescr - , generateSignedDHParams - , generateSignedECDHParams + ( + certificateVerifyCreate + , certificateVerifyCheck + , digitallySignDHParams + , digitallySignECDHParams + , digitallySignDHParamsVerify + , digitallySignECDHParamsVerify ) where import Crypto.PubKey.HashDescr @@ -22,6 +21,7 @@ import Network.TLS.Context.Internal import Network.TLS.Struct import Network.TLS.Packet (generateCertificateVerify_SSL, encodeSignedDHParams, encodeSignedECDHParams) +import Network.TLS.Parameters (supportedHashSignatures) import Network.TLS.State import Network.TLS.Handshake.State import Network.TLS.Handshake.Key @@ -30,6 +30,25 @@ import Control.Applicative import Control.Monad.State +certificateVerifyCheck :: Context + -> Version + -> Maybe HashAndSignatureAlgorithm + -> Bytes + -> DigitallySigned + -> IO Bool +certificateVerifyCheck ctx usedVersion malg msgs dsig = do + (hashMethod, toVerify) <- prepareCertificateVerifySignatureData ctx usedVersion malg msgs + signatureVerifyWithHashDescr ctx SignatureRSA hashMethod toVerify dsig + +certificateVerifyCreate :: Context + -> Version + -> Maybe HashAndSignatureAlgorithm + -> Bytes + -> IO DigitallySigned +certificateVerifyCreate ctx usedVersion malg msgs = do + (hashMethod, toSign) <- prepareCertificateVerifySignatureData ctx usedVersion malg msgs + signatureCreate ctx malg hashMethod toSign + getHashAndASN1 :: MonadIO m => (HashAlgorithm, SignatureAlgorithm) -> m HashDescr getHashAndASN1 hashSig = case hashSig of (HashSHA1, SignatureRSA) -> return hashDescrSHA1 @@ -47,11 +66,11 @@ prepareCertificateVerifySignatureData ctx usedVersion malg msgs | usedVersion == SSL3 = do Just masterSecret <- usingHState ctx $ gets hstMasterSecret - let digest = generateCertificateVerify_SSL masterSecret (hashUpdate (hashInit hashMD5SHA1) msgs) + let digest = generateCertificateVerify_SSL masterSecret (hashUpdate (hashInit SHA1_MD5) msgs) hsh = HashDescr id id return (hsh, digest) | usedVersion == TLS10 || usedVersion == TLS11 = do - let hashf bs = hashFinal (hashUpdate (hashInit hashMD5SHA1) bs) + let hashf bs = hashFinal (hashUpdate (hashInit SHA1_MD5) bs) hsh = HashDescr hashf id return (hsh, msgs) | otherwise = do @@ -65,7 +84,7 @@ Just HashSHA512 -> hashDescrSHA512 Just HashSHA256 -> hashDescrSHA256 Just HashSHA1 -> hashDescrSHA1 - Nothing -> HashDescr (hashFinal . hashUpdate (hashInit hashMD5SHA1)) id + Nothing -> HashDescr (hashFinal . hashUpdate (hashInit SHA1_MD5)) id _ -> error ("unimplemented signature hash type") signatureHashData SignatureDSS mhash = case mhash of @@ -103,14 +122,53 @@ SignatureDSS -> verifyRSA ctx cc hashDescr toVerify bs _ -> error "not implemented yet" -generateSignedDHParams :: Context -> ServerDHParams -> IO Bytes -generateSignedDHParams ctx serverParams = do - (cran, sran) <- usingHState ctx $ do - (,) <$> gets hstClientRandom <*> (fromJust "server random" <$> gets hstServerRandom) - return $ encodeSignedDHParams cran sran serverParams - -generateSignedECDHParams :: Context -> ServerECDHParams -> IO Bytes -generateSignedECDHParams ctx serverParams = do - (cran, sran) <- usingHState ctx $ do - (,) <$> gets hstClientRandom <*> (fromJust "server random" <$> gets hstServerRandom) - return $ encodeSignedECDHParams cran sran serverParams +digitallySignParams :: Context -> Bytes -> SignatureAlgorithm -> IO DigitallySigned +digitallySignParams ctx signatureData sigAlg = do + usedVersion <- usingState_ ctx getVersion + let mhash = case usedVersion of + TLS12 -> case filter ((==) sigAlg . snd) $ supportedHashSignatures $ ctxSupported ctx of + [] -> error ("no hash signature for " ++ show sigAlg) + x:_ -> Just (fst x) + _ -> Nothing + let hashDescr = signatureHashData sigAlg mhash + signatureCreate ctx (fmap (\h -> (h, sigAlg)) mhash) hashDescr signatureData + +digitallySignDHParams :: Context + -> ServerDHParams + -> SignatureAlgorithm + -> IO DigitallySigned +digitallySignDHParams ctx serverParams sigAlg = do + dhParamsData <- withClientAndServerRandom ctx $ encodeSignedDHParams serverParams + digitallySignParams ctx dhParamsData sigAlg + +digitallySignECDHParams :: Context + -> ServerECDHParams + -> SignatureAlgorithm + -> IO DigitallySigned +digitallySignECDHParams ctx serverParams sigAlg = do + ecdhParamsData <- withClientAndServerRandom ctx $ encodeSignedECDHParams serverParams + digitallySignParams ctx ecdhParamsData sigAlg + +digitallySignDHParamsVerify :: Context + -> ServerDHParams + -> SignatureAlgorithm + -> DigitallySigned + -> IO Bool +digitallySignDHParamsVerify ctx dhparams sigAlg signature = do + expectedData <- withClientAndServerRandom ctx $ encodeSignedDHParams dhparams + signatureVerify ctx sigAlg expectedData signature + +digitallySignECDHParamsVerify :: Context + -> ServerECDHParams + -> SignatureAlgorithm + -> DigitallySigned + -> IO Bool +digitallySignECDHParamsVerify ctx dhparams sigAlg signature = do + expectedData <- withClientAndServerRandom ctx $ encodeSignedECDHParams dhparams + signatureVerify ctx sigAlg expectedData signature + +withClientAndServerRandom :: Context -> (ClientRandom -> ServerRandom -> b) -> IO b +withClientAndServerRandom ctx f = do + (cran, sran) <- usingHState ctx $ (,) <$> gets hstClientRandom + <*> (fromJust "withClientAndServer : server random" <$> gets hstServerRandom) + return $ f cran sran diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.2.17/Network/TLS/Handshake/State.hs new/tls-1.2.18/Network/TLS/Handshake/State.hs --- old/tls-1.2.17/Network/TLS/Handshake/State.hs 2015-04-12 08:21:50.000000000 +0200 +++ new/tls-1.2.18/Network/TLS/Handshake/State.hs 2015-06-19 15:56:01.000000000 +0200 @@ -221,7 +221,7 @@ keyblockSize = cipherKeyBlockSize cipher bulk = cipherBulk cipher - digestSize = if hasMAC (bulkF bulk) then hashSize (cipherHash cipher) + digestSize = if hasMAC (bulkF bulk) then hashDigestSize (cipherHash cipher) else 0 keySize = bulkKeySize bulk ivSize = bulkIVSize bulk @@ -232,10 +232,10 @@ (cMACSecret, sMACSecret, cWriteKey, sWriteKey, cWriteIV, sWriteIV) = fromJust "p6" $ partition6 kb (digestSize, digestSize, keySize, keySize, ivSize, ivSize) - cstClient = CryptState { cstKey = cWriteKey + cstClient = CryptState { cstKey = bulkInit bulk (BulkEncrypt `orOnServer` BulkDecrypt) cWriteKey , cstIV = cWriteIV , cstMacSecret = cMACSecret } - cstServer = CryptState { cstKey = sWriteKey + cstServer = CryptState { cstKey = bulkInit bulk (BulkDecrypt `orOnServer` BulkEncrypt) sWriteKey , cstIV = sWriteIV , cstMacSecret = sMACSecret } msClient = MacState { msSequence = 0 } @@ -254,6 +254,9 @@ , stCompression = hstPendingCompression hst } + orOnServer f g = if cc == ClientRole then f else g + + setServerHelloParameters :: Version -- ^ chosen version -> ServerRandom -> Cipher @@ -266,6 +269,6 @@ , hstPendingCompression = compression , hstHandshakeDigest = updateDigest $ hstHandshakeDigest hst } - where initCtx = if ver < TLS12 then hashMD5SHA1 else hashSHA256 - updateDigest (Left bytes) = Right $ foldl hashUpdate initCtx $ reverse bytes + where hashAlg = if ver < TLS12 then SHA1_MD5 else SHA256 + updateDigest (Left bytes) = Right $ foldl hashUpdate (hashInit hashAlg) $ reverse bytes updateDigest (Right _) = error "cannot initialize digest with another digest" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.2.17/Network/TLS/MAC.hs new/tls-1.2.18/Network/TLS/MAC.hs --- old/tls-1.2.17/Network/TLS/MAC.hs 2015-04-12 08:21:50.000000000 +0200 +++ new/tls-1.2.18/Network/TLS/MAC.hs 2015-06-19 15:56:01.000000000 +0200 @@ -6,10 +6,7 @@ -- Portability : unknown -- module Network.TLS.MAC - ( hmacMD5 - , hmacSHA1 - , hmacSHA256 - , macSSL + ( macSSL , hmac , prf_MD5 , prf_SHA1 @@ -17,40 +14,39 @@ , prf_MD5SHA1 ) where -import qualified Crypto.Hash.MD5 as MD5 -import qualified Crypto.Hash.SHA1 as SHA1 -import qualified Crypto.Hash.SHA256 as SHA256 +import Network.TLS.Crypto import qualified Data.ByteString as B import Data.ByteString (ByteString) import Data.Bits (xor) type HMAC = ByteString -> ByteString -> ByteString -macSSL :: (ByteString -> ByteString) -> HMAC -macSSL f secret msg = f $! B.concat [ secret, B.replicate padlen 0x5c, - f $! B.concat [ secret, B.replicate padlen 0x36, msg ] ] - where -- get the type of algorithm out of the digest length by using the hash fct. - padlen = if (B.length $ f B.empty) == 16 then 48 else 40 - -hmac :: (ByteString -> ByteString) -> Int -> HMAC -hmac f bl secret msg = - f $! B.append opad (f $! B.append ipad msg) +macSSL :: Hash -> HMAC +macSSL alg secret msg = + f $! B.concat + [ secret + , B.replicate padLen 0x5c + , f $! B.concat [ secret, B.replicate padLen 0x36, msg ] + ] + where + padLen = case alg of + MD5 -> 48 + SHA1 -> 40 + _ -> error ("internal error: macSSL called with " ++ show alg) + f = hash alg + +hmac :: Hash -> HMAC +hmac alg secret msg = f $! B.append opad (f $! B.append ipad msg) where opad = B.map (xor 0x5c) k' ipad = B.map (xor 0x36) k' + f = hash alg + bl = hashBlockSize alg + k' = B.append kt pad where kt = if B.length secret > fromIntegral bl then f secret else secret pad = B.replicate (fromIntegral bl - B.length kt) 0 -hmacMD5 :: HMAC -hmacMD5 secret msg = hmac MD5.hash 64 secret msg - -hmacSHA1 :: HMAC -hmacSHA1 secret msg = hmac SHA1.hash 64 secret msg - -hmacSHA256 :: HMAC -hmacSHA256 secret msg = hmac SHA256.hash 64 secret msg - hmacIter :: HMAC -> ByteString -> ByteString -> ByteString -> Int -> [ByteString] hmacIter f secret seed aprev len = let an = f secret aprev in @@ -61,10 +57,10 @@ else out : hmacIter f secret seed an (len - digestsize) prf_SHA1 :: ByteString -> ByteString -> Int -> ByteString -prf_SHA1 secret seed len = B.concat $ hmacIter hmacSHA1 secret seed seed len +prf_SHA1 secret seed len = B.concat $ hmacIter (hmac SHA1) secret seed seed len prf_MD5 :: ByteString -> ByteString -> Int -> ByteString -prf_MD5 secret seed len = B.concat $ hmacIter hmacMD5 secret seed seed len +prf_MD5 secret seed len = B.concat $ hmacIter (hmac MD5) secret seed seed len prf_MD5SHA1 :: ByteString -> ByteString -> Int -> ByteString prf_MD5SHA1 secret seed len = @@ -74,4 +70,4 @@ s2 = B.drop (slen `div` 2) secret prf_SHA256 :: ByteString -> ByteString -> Int -> ByteString -prf_SHA256 secret seed len = B.concat $ hmacIter hmacSHA256 secret seed seed len +prf_SHA256 secret seed len = B.concat $ hmacIter (hmac SHA256) secret seed seed len diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.2.17/Network/TLS/Packet.hs new/tls-1.2.18/Network/TLS/Packet.hs --- old/tls-1.2.17/Network/TLS/Packet.hs 2015-04-12 08:21:50.000000000 +0200 +++ new/tls-1.2.18/Network/TLS/Packet.hs 2015-06-19 15:56:01.000000000 +0200 @@ -77,9 +77,6 @@ import qualified Data.ByteString as B import qualified Data.ByteString.Char8 as BC -import qualified Crypto.Hash.SHA1 as SHA1 -import qualified Crypto.Hash.MD5 as MD5 - data CurrentParams = CurrentParams { cParamsVersion :: Version -- ^ current protocol version , cParamsKeyXchgType :: Maybe CipherKeyExchangeType -- ^ current key exchange type @@ -486,14 +483,10 @@ putWord8 (valOfType h) >> putWord8 (valOfType s) getServerDHParams :: Get ServerDHParams -getServerDHParams = ServerDHParams <$> getDHParams <*> getDHPublic - where getDHParams = dhParams <$> getInteger16 -- p - <*> getInteger16 -- g - getDHPublic = dhPublic <$> getInteger16 -- y(server) +getServerDHParams = ServerDHParams <$> getBigNum16 <*> getBigNum16 <*> getBigNum16 putServerDHParams :: ServerDHParams -> Put -putServerDHParams (ServerDHParams dhparams dhpub) = - mapM_ putInteger16 $ dhUnwrap dhparams dhpub +putServerDHParams (ServerDHParams p g y) = mapM_ putBigNum16 [p,g,y] getServerECDHParams :: Get ServerECDHParams getServerECDHParams = do @@ -566,8 +559,8 @@ generateMasterSecret_SSL :: Bytes -> ClientRandom -> ServerRandom -> Bytes generateMasterSecret_SSL premasterSecret (ClientRandom c) (ServerRandom s) = B.concat $ map (computeMD5) ["A","BB","CCC"] - where computeMD5 label = MD5.hash $ B.concat [ premasterSecret, computeSHA1 label ] - computeSHA1 label = SHA1.hash $ B.concat [ label, premasterSecret, c, s ] + where computeMD5 label = hash MD5 $ B.concat [ premasterSecret, computeSHA1 label ] + computeSHA1 label = hash SHA1 $ B.concat [ label, premasterSecret, c, s ] generateMasterSecret_TLS :: PRF -> Bytes -> ClientRandom -> ServerRandom -> Bytes generateMasterSecret_TLS prf premasterSecret (ClientRandom c) (ServerRandom s) = @@ -589,8 +582,8 @@ generateKeyBlock_SSL (ClientRandom c) (ServerRandom s) mastersecret kbsize = B.concat $ map computeMD5 $ take ((kbsize `div` 16) + 1) labels where labels = [ uncurry BC.replicate x | x <- zip [1..] ['A'..'Z'] ] - computeMD5 label = MD5.hash $ B.concat [ mastersecret, computeSHA1 label ] - computeSHA1 label = SHA1.hash $ B.concat [ label, mastersecret, s, c ] + 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 @@ -605,8 +598,8 @@ generateFinished_SSL :: Bytes -> Bytes -> HashCtx -> Bytes generateFinished_SSL sender mastersecret hashctx = B.concat [md5hash, sha1hash] - where md5hash = MD5.hash $ B.concat [ mastersecret, pad2, md5left ] - sha1hash = SHA1.hash $ B.concat [ mastersecret, B.take 40 pad2, sha1left ] + where md5hash = hash MD5 $ B.concat [ mastersecret, pad2, md5left ] + sha1hash = hash SHA1 $ B.concat [ mastersecret, B.take 40 pad2, sha1left ] lefthash = hashFinal $ flip hashUpdateSSL (pad1, B.take 40 pad1) $ foldl hashUpdate hashctx [sender,mastersecret] @@ -629,13 +622,13 @@ generateCertificateVerify_SSL :: Bytes -> HashCtx -> Bytes generateCertificateVerify_SSL = generateFinished_SSL "" -encodeSignedDHParams :: ClientRandom -> ServerRandom -> ServerDHParams -> Bytes -encodeSignedDHParams cran sran dhparams = runPut $ +encodeSignedDHParams :: ServerDHParams -> ClientRandom -> ServerRandom -> Bytes +encodeSignedDHParams dhparams cran sran = runPut $ putClientRandom32 cran >> putServerRandom32 sran >> putServerDHParams dhparams -- Combination of RFC 5246 and 4492 is ambiguous. -- Let's assume ecdhe_rsa and ecdhe_dss are identical to -- dhe_rsa and dhe_dss. -encodeSignedECDHParams :: ClientRandom -> ServerRandom -> ServerECDHParams -> Bytes -encodeSignedECDHParams cran sran dhparams = runPut $ +encodeSignedECDHParams :: ServerECDHParams -> ClientRandom -> ServerRandom -> Bytes +encodeSignedECDHParams dhparams cran sran = runPut $ putClientRandom32 cran >> putServerRandom32 sran >> putServerECDHParams dhparams diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.2.17/Network/TLS/Record/Disengage.hs new/tls-1.2.18/Network/TLS/Record/Disengage.hs --- old/tls-1.2.17/Network/TLS/Record/Disengage.hs 2015-04-12 08:21:50.000000000 +0200 +++ new/tls-1.2.18/Network/TLS/Record/Disengage.hs 2015-06-19 15:56:01.000000000 +0200 @@ -23,6 +23,7 @@ import Network.TLS.Record.State import Network.TLS.Record.Types import Network.TLS.Cipher +import Network.TLS.Crypto import Network.TLS.Compression import Network.TLS.Util import Network.TLS.Wire @@ -68,12 +69,11 @@ return $ cipherDataContent cdata decryptData :: Version -> Record Ciphertext -> Bytes -> RecordState -> RecordM Bytes -decryptData ver record econtent tst = decryptOf (bulkF bulk) +decryptData ver record econtent tst = decryptOf (cstKey cst) where cipher = fromJust "cipher" $ stCipher tst bulk = cipherBulk cipher cst = stCryptState tst - macSize = hashSize $ cipherHash cipher - writekey = cstKey cst + macSize = hashDigestSize $ cipherHash cipher blockSize = bulkBlockSize bulk econtentLen = B.length econtent @@ -81,18 +81,17 @@ sanityCheckError = throwError (Error_Packet "encrypted content too small for encryption parameters") - decryptOf :: BulkFunctions -> RecordM Bytes - decryptOf (BulkBlockF _ decryptF) = do + decryptOf :: BulkState -> RecordM Bytes + decryptOf (BulkStateBlock decryptF) = do let minContent = (if explicitIV then bulkIVSize bulk else 0) + max (macSize + 1) blockSize when ((econtentLen `mod` blockSize) /= 0 || econtentLen < minContent) $ sanityCheckError {- update IV -} (iv, econtent') <- if explicitIV then get2 econtent (bulkIVSize bulk, econtentLen - bulkIVSize bulk) else return (cstIV cst, econtent) - let newiv = fromJust "new iv" $ takelast (bulkBlockSize bulk) econtent' - modify $ \txs -> txs { stCryptState = cst { cstIV = newiv } } + let (content', iv') = decryptF iv econtent' + modify $ \txs -> txs { stCryptState = cst { cstIV = iv' } } - let content' = decryptF writekey iv econtent' let paddinglength = fromIntegral (B.last content') + 1 let contentlen = B.length content' - paddinglength - macSize (content, mac, padding) <- get3 content' (contentlen, macSize, paddinglength) @@ -102,20 +101,20 @@ , cipherDataPadding = Just padding } - decryptOf (BulkStreamF initF _ decryptF) = do + decryptOf (BulkStateStream (BulkStream decryptF)) = do when (econtentLen < macSize) $ sanityCheckError - let (content', newiv) = decryptF (if cstIV cst /= B.empty then cstIV cst else initF writekey) econtent + let (content', bulkStream') = decryptF econtent {- update Ctx -} let contentlen = B.length content' - macSize (content, mac) <- get2 content' (contentlen, macSize) - modify $ \txs -> txs { stCryptState = cst { cstIV = newiv } } + modify $ \txs -> txs { stCryptState = cst { cstKey = BulkStateStream bulkStream' } } getCipherData record $ CipherData { cipherDataContent = content , cipherDataMAC = Just mac , cipherDataPadding = Nothing } - decryptOf (BulkAeadF _ decryptF) = do + decryptOf (BulkStateAEAD decryptF) = do let authtaglen = 16 -- FIXME: fixed_iv_length + record_iv_length nonceexplen = 8 -- FIXME: record_iv_length econtentlen = B.length econtent - authtaglen - nonceexplen @@ -125,7 +124,7 @@ hdr = Header typ v $ fromIntegral econtentlen ad = B.concat [ encodedSeq, encodeHeader hdr ] nonce = cstIV (stCryptState tst) `B.append` enonce - (content, authTag2) = decryptF writekey nonce econtent' ad + (content, authTag2) = decryptF nonce econtent' ad when (AuthTag authTag /= authTag2) $ throwError $ Error_Protocol ("bad record mac", True, BadRecordMac) @@ -133,5 +132,8 @@ modify incrRecordState return content + decryptOf BulkStateUninitialized = + throwError $ Error_Protocol ("decrypt state uninitialized", True, InternalError) + get3 s ls = maybe (throwError $ Error_Packet "record bad format") return $ partition3 s ls get2 s (d1,d2) = get3 s (d1,d2,0) >>= \(r1,r2,_) -> return (r1,r2) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.2.17/Network/TLS/Record/Engage.hs new/tls-1.2.18/Network/TLS/Record/Engage.hs --- old/tls-1.2.17/Network/TLS/Record/Engage.hs 2015-04-12 08:21:50.000000000 +0200 +++ new/tls-1.2.18/Network/TLS/Record/Engage.hs 2015-06-19 15:56:01.000000000 +0200 @@ -8,6 +8,7 @@ -- Engage a record into the Record layer. -- The record is compressed, added some integrity field, then encrypted. -- +{-# LANGUAGE BangPatterns #-} module Network.TLS.Record.Engage ( engageRecord ) where @@ -21,7 +22,6 @@ import Network.TLS.Record.Types import Network.TLS.Cipher import Network.TLS.Compression -import Network.TLS.Util import Network.TLS.Wire import Network.TLS.Packet import Data.ByteString (ByteString) @@ -48,22 +48,23 @@ encryptContent :: Record Compressed -> ByteString -> RecordM ByteString encryptContent record content = do + cst <- getCryptState bulk <- getBulk - case bulkF bulk of - BulkBlockF encryptF _ -> do + case cstKey cst of + BulkStateBlock encryptF -> do digest <- makeDigest (recordToHeader record) content let content' = B.concat [content, digest] encryptBlock encryptF content' bulk - BulkStreamF initF encryptF _ -> do + BulkStateStream encryptF -> do digest <- makeDigest (recordToHeader record) content let content' = B.concat [content, digest] - encryptStream encryptF content' initF - BulkAeadF encryptF _ -> + encryptStream encryptF content' + BulkStateAEAD encryptF -> encryptAead encryptF content record + BulkStateUninitialized -> + return content -encryptBlock :: (Key -> IV -> ByteString -> ByteString) - -> ByteString -> Bulk - -> RecordM ByteString +encryptBlock :: BulkBlock -> ByteString -> Bulk -> RecordM ByteString encryptBlock encryptF content bulk = do cst <- getCryptState ver <- getRecordVersion @@ -76,26 +77,22 @@ else B.empty - let e = encryptF (cstKey cst) (cstIV cst) $ B.concat [ content, padding ] + let (e, iv') = encryptF (cstIV cst) $ B.concat [ content, padding ] if hasExplicitBlockIV ver then return $ B.concat [cstIV cst,e] else do - let newiv = fromJust "new iv" $ takelast (bulkIVSize bulk) e - modify $ \tstate -> tstate { stCryptState = cst { cstIV = newiv } } + modify $ \tstate -> tstate { stCryptState = cst { cstIV = iv' } } return e -encryptStream :: (IV -> ByteString -> (ByteString, IV)) - -> ByteString -> (Key -> IV) - -> RecordM ByteString -encryptStream encryptF content initF = do +encryptStream :: BulkStream -> ByteString -> RecordM ByteString +encryptStream (BulkStream encryptF) content = do cst <- getCryptState - let iv = cstIV cst - (e, newiv) = encryptF (if iv /= B.empty then iv else initF (cstKey cst)) content - modify $ \tstate -> tstate { stCryptState = cst { cstIV = newiv } } + let (!e, !newBulkStream) = encryptF content + modify $ \tstate -> tstate { stCryptState = cst { cstKey = BulkStateStream newBulkStream } } return e -encryptAead :: (Key -> Nonce -> ByteString -> AdditionalData -> (ByteString, AuthTag)) +encryptAead :: BulkAEAD -> ByteString -> Record Compressed -> RecordM ByteString encryptAead encryptF content record = do @@ -108,7 +105,7 @@ processorNum = encodeWord32 1 -- FIXME counter = B.drop 4 encodedSeq -- FIXME: probably OK nonce = B.concat [salt, processorNum, counter] - let (e, AuthTag authtag) = encryptF (cstKey cst) nonce content ad + let (e, AuthTag authtag) = encryptF nonce content ad modify incrRecordState return $ B.concat [processorNum, counter, e, authtag] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.2.17/Network/TLS/Record/State.hs new/tls-1.2.18/Network/TLS/Record/State.hs --- old/tls-1.2.17/Network/TLS/Record/State.hs 2015-04-12 08:21:50.000000000 +0200 +++ new/tls-1.2.18/Network/TLS/Record/State.hs 2015-06-19 15:56:01.000000000 +0200 @@ -41,7 +41,7 @@ import qualified Data.ByteString as B data CryptState = CryptState - { cstKey :: !Bytes + { cstKey :: !BulkState , cstIV :: !Bytes , cstMacSecret :: !Bytes } deriving (Show) @@ -99,7 +99,7 @@ newRecordState = RecordState { stCipher = Nothing , stCompression = nullCompression - , stCryptState = CryptState B.empty B.empty B.empty + , stCryptState = CryptState BulkStateUninitialized B.empty B.empty , stMacState = MacState 0 } @@ -122,12 +122,12 @@ where digest = macF (cstMacSecret cst) msg cst = stCryptState tstate cipher = fromJust "cipher" $ stCipher tstate - hashf = hashF $ cipherHash cipher + hashA = cipherHash cipher encodedSeq = encodeWord64 $ msSequence $ stMacState tstate (macF, msg) - | ver < TLS10 = (macSSL hashf, B.concat [ encodedSeq, encodeHeaderNoVer hdr, content ]) - | otherwise = (hmac hashf 64, B.concat [ encodedSeq, encodeHeader hdr, content ]) + | ver < TLS10 = (macSSL hashA, B.concat [ encodedSeq, encodeHeaderNoVer hdr, content ]) + | otherwise = (hmac hashA, B.concat [ encodedSeq, encodeHeader hdr, content ]) makeDigest :: Header -> Bytes -> RecordM Bytes makeDigest hdr content = do diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.2.17/Network/TLS/Struct.hs new/tls-1.2.18/Network/TLS/Struct.hs --- old/tls-1.2.17/Network/TLS/Struct.hs 2015-04-12 08:21:50.000000000 +0200 +++ new/tls-1.2.18/Network/TLS/Struct.hs 2015-06-19 15:56:01.000000000 +0200 @@ -27,7 +27,13 @@ , TLSError(..) , TLSException(..) , DistinguishedName + , BigNum(..) + , bigNumToInteger + , bigNumFromInteger , ServerDHParams(..) + , serverDHParamsToParams + , serverDHParamsToPublic + , serverDHParamsFrom , ServerECDHParams(..) , ServerRSAParams(..) , ServerKeyXchgAlgorithmData(..) @@ -64,6 +70,7 @@ import Network.TLS.Types import Network.TLS.Crypto.DH import Network.TLS.Crypto.ECDH +import Network.TLS.Util.Serialization #if MIN_VERSION_mtl(2,2,1) #else import Control.Monad.Error @@ -234,9 +241,36 @@ | HandshakeType_NPN -- Next Protocol Negotiation extension deriving (Show,Eq) -data ServerDHParams = ServerDHParams DHParams {- (p,g) -} DHPublic {- y -} +newtype BigNum = BigNum Bytes deriving (Show,Eq) +bigNumToInteger :: BigNum -> Integer +bigNumToInteger (BigNum b) = os2ip b + +bigNumFromInteger :: Integer -> BigNum +bigNumFromInteger i = BigNum $ i2osp i + +data ServerDHParams = ServerDHParams + { serverDHParams_p :: BigNum + , serverDHParams_g :: BigNum + , serverDHParams_y :: BigNum + } deriving (Show,Eq) + +serverDHParamsFrom :: DHParams -> DHPublic -> ServerDHParams +serverDHParamsFrom params dhPub = + ServerDHParams (bigNumFromInteger $ dhParamsGetP params) + (bigNumFromInteger $ dhParamsGetG params) + (bigNumFromInteger $ dhUnwrapPublic dhPub) + +serverDHParamsToParams :: ServerDHParams -> DHParams +serverDHParamsToParams serverParams = + dhParams (bigNumToInteger $ serverDHParams_p serverParams) + (bigNumToInteger $ serverDHParams_g serverParams) + +serverDHParamsToPublic :: ServerDHParams -> DHPublic +serverDHParamsToPublic serverParams = + dhPublic (bigNumToInteger $ serverDHParams_y serverParams) + data ServerECDHParams = ServerECDHParams ECDHParams ECDHPublic deriving (Show,Eq) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.2.17/Network/TLS/Wire.hs new/tls-1.2.18/Network/TLS/Wire.hs --- old/tls-1.2.17/Network/TLS/Wire.hs 2015-04-12 08:21:50.000000000 +0200 +++ new/tls-1.2.18/Network/TLS/Wire.hs 2015-06-19 15:56:01.000000000 +0200 @@ -27,6 +27,7 @@ , getOpaque16 , getOpaque24 , getInteger16 + , getBigNum16 , getList , processBytes , isEmpty @@ -42,6 +43,7 @@ , putOpaque16 , putOpaque24 , putInteger16 + , putBigNum16 , encodeWord16 , encodeWord32 , encodeWord64 @@ -114,6 +116,9 @@ getInteger16 :: Get Integer getInteger16 = os2ip <$> getOpaque16 +getBigNum16 :: Get BigNum +getBigNum16 = BigNum <$> getOpaque16 + getList :: Int -> (Get (Int, a)) -> Get [a] getList totalLen getElement = isolate totalLen (getElements totalLen) where getElements len @@ -162,6 +167,9 @@ putInteger16 :: Integer -> Put putInteger16 = putOpaque16 . i2osp +putBigNum16 :: BigNum -> Put +putBigNum16 (BigNum b) = putOpaque16 b + encodeWord16 :: Word16 -> Bytes encodeWord16 = runPut . putWord16 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.2.17/Tests/Ciphers.hs new/tls-1.2.18/Tests/Ciphers.hs --- old/tls-1.2.17/Tests/Ciphers.hs 2015-04-12 08:21:50.000000000 +0200 +++ new/tls-1.2.18/Tests/Ciphers.hs 2015-06-19 15:56:01.000000000 +0200 @@ -29,15 +29,20 @@ propertyBulkFunctional :: BulkTest -> Bool propertyBulkFunctional (BulkTest bulk key iv t additional) = - case bulkF bulk of - BulkBlockF enc dec -> block enc dec - BulkStreamF ktoi enc dec -> stream ktoi enc dec - BulkAeadF enc dec -> aead enc dec + let enc = bulkInit bulk BulkEncrypt key + dec = bulkInit bulk BulkDecrypt key + in case (enc, dec) of + (BulkStateBlock encF, BulkStateBlock decF) -> block encF decF + (BulkStateAEAD encF, BulkStateAEAD decF) -> aead encF decF + (BulkStateStream (BulkStream encF), BulkStateStream (BulkStream decF)) -> stream encF decF + _ -> True where - block e d = (d key iv . e key iv) t == t - stream ktoi e d = (fst . d siv . fst . e siv) t == t - where siv = ktoi key + block e d = + let (etxt, e_iv) = e iv t + (dtxt, d_iv) = d iv etxt + in dtxt == t && d_iv == e_iv + stream e d = (fst . d . fst . e) t == t aead e d = - let (encrypted, at) = e key iv t additional - (decrypted, at2) = d key iv encrypted additional + let (encrypted, at) = e iv t additional + (decrypted, at2) = d iv encrypted additional in decrypted == t && at == at2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.2.17/Tests/Connection.hs new/tls-1.2.18/Tests/Connection.hs --- old/tls-1.2.17/Tests/Connection.hs 2015-04-12 08:21:50.000000000 +0200 +++ new/tls-1.2.18/Tests/Connection.hs 2015-06-19 15:56:01.000000000 +0200 @@ -34,13 +34,9 @@ , bulkKeySize = 16 , bulkIVSize = 16 , bulkBlockSize = 16 - , bulkF = BulkBlockF (\_ _ m -> m) (\_ _ m -> m) - } - , cipherHash = Hash - { hashName = "const-hash" - , hashSize = 16 - , hashF = (\_ -> B.replicate 16 1) + , bulkF = BulkBlockF $ \_ _ _ -> (\m -> (m, B.empty)) } + , cipherHash = MD5 , cipherKeyExchange = CipherKeyExchange_RSA , cipherMinVer = Nothing } @@ -67,9 +63,11 @@ , bulkKeySize = 16 , bulkIVSize = 0 , bulkBlockSize = 0 - , bulkF = BulkStreamF (\k -> k) (\i m -> (m,i)) (\i m -> (m,i)) + , bulkF = BulkStreamF passThrough } } + where + passThrough _ _ = BulkStream go where go inp = (inp, BulkStream go) knownCiphers :: [Cipher] knownCiphers = [blockCipher,blockCipherDHE_RSA,blockCipherDHE_DSS,streamCipher] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tls-1.2.17/tls.cabal new/tls-1.2.18/tls.cabal --- old/tls-1.2.17/tls.cabal 2015-04-12 08:21:50.000000000 +0200 +++ new/tls-1.2.18/tls.cabal 2015-06-19 15:56:01.000000000 +0200 @@ -1,5 +1,5 @@ Name: tls -Version: 1.2.17 +Version: 1.2.18 Description: Native Haskell TLS and SSL protocol implementation for server and client. .