module Connection ( newPairContext , arbitraryPairParams , setPairParamsSessionManager , setPairParamsSessionResuming ) where import Test.QuickCheck import Certificate import PubKey import PipeChan import Network.TLS import qualified Crypto.Random.AESCtr as RNG import qualified Data.ByteString as B debug = False blockCipher :: Cipher blockCipher = Cipher { cipherID = 0xff12 , cipherName = "rsa-id-const" , cipherBulk = Bulk { bulkName = "id" , bulkKeySize = 16 , bulkIVSize = 16 , bulkBlockSize = 16 , bulkF = BulkBlockF (\_ _ m -> m) (\_ _ m -> m) } , cipherHash = Hash { hashName = "const-hash" , hashSize = 16 , hashF = (\_ -> B.replicate 16 1) } , cipherKeyExchange = CipherKeyExchange_RSA , cipherMinVer = Nothing } streamCipher = blockCipher { cipherID = 0xff13 , cipherBulk = Bulk { bulkName = "stream" , bulkKeySize = 16 , bulkIVSize = 0 , bulkBlockSize = 0 , bulkF = BulkStreamF (\k -> k) (\i m -> (m,i)) (\i m -> (m,i)) } } supportedCiphers :: [Cipher] supportedCiphers = [blockCipher,streamCipher] supportedVersions :: [Version] supportedVersions = [SSL3,TLS10,TLS11,TLS12] arbitraryPairParams = do let (pubKey, privKey) = getGlobalRSAPair servCert <- arbitraryX509WithPublicKey pubKey allowedVersions <- arbitraryVersions connectVersion <- elements supportedVersions `suchThat` (\c -> c `elem` allowedVersions) serverCiphers <- arbitraryCiphers clientCiphers <- oneof [arbitraryCiphers] `suchThat` (\cs -> or [x `elem` serverCiphers | x <- cs]) secNeg <- arbitrary let serverState = defaultParamsServer { pAllowedVersions = allowedVersions , pCiphers = serverCiphers , pCertificates = [(servCert, Just $ PrivRSA privKey)] , pUseSecureRenegotiation = secNeg , pLogging = logging "server: " } let clientState = defaultParamsClient { pConnectVersion = connectVersion , pAllowedVersions = allowedVersions , pCiphers = clientCiphers , pUseSecureRenegotiation = secNeg , pLogging = logging "client: " } return (clientState, serverState) where logging pre = if debug then defaultLogging { loggingPacketSent = putStrLn . ((pre ++ ">> ") ++) , loggingPacketRecv = putStrLn . ((pre ++ "<< ") ++) } else defaultLogging arbitraryVersions :: Gen [Version] arbitraryVersions = resize (length supportedVersions + 1) $ listOf1 (elements supportedVersions) arbitraryCiphers = resize (length supportedCiphers + 1) $ listOf1 (elements supportedCiphers) setPairParamsSessionManager :: SessionManager s => s -> (Params, Params) -> (Params, Params) setPairParamsSessionManager manager (clientState, serverState) = (nc,ns) where nc = setSessionManager manager clientState ns = setSessionManager manager serverState setPairParamsSessionResuming sessionStuff (clientState, serverState) = (nc,serverState) where nc = updateClientParams (\cparams -> cparams { clientWantSessionResume = Just sessionStuff }) clientState newPairContext pipe (cParams, sParams) = do let noFlush = return () let noClose = return () cRNG <- RNG.makeSystem sRNG <- RNG.makeSystem let cBackend = Backend noFlush noClose (writePipeA pipe) (readPipeA pipe) let sBackend = Backend noFlush noClose (writePipeB pipe) (readPipeB pipe) cCtx' <- contextNew cBackend cParams cRNG sCtx' <- contextNew sBackend sParams sRNG return (cCtx', sCtx')