packages feed

tls-extra (empty) → 0.1.0

raw patch · 11 files changed

+810/−0 lines, 11 filesdep +HUnitdep +QuickCheckdep +basesetup-changed

Dependencies added: HUnit, QuickCheck, base, bytestring, certificate, cmdargs, crypto-api, cryptocipher, cryptohash, mtl, network, tls, vector

Files

+ Examples/CheckCiphers.hs view
@@ -0,0 +1,123 @@+{-# LANGUAGE ScopedTypeVariables, DeriveDataTypeable #-}++import Network.TLS.Internal+import Network.TLS.Cipher+import Network.TLS++import qualified Data.ByteString as B+import Data.Word+import Data.Char++import Network.Socket+import Network.BSD+import System.IO+import Control.Monad+import Control.Applicative ((<$>))+import Control.Concurrent+import Control.Exception (catch, SomeException(..))+import Prelude hiding (catch)++import Text.Printf++import System.Console.CmdArgs++fakeCipher cid = Cipher+	{ cipherID           = cid+	, cipherName         = "cipher-" ++ show cid+	, cipherDigestSize   = 0+	, cipherKeySize      = 0+	, cipherIVSize       = 0+	, cipherKeyBlockSize = 0+	, cipherPaddingSize  = 0+	, cipherKeyExchange  = CipherKeyExchangeRSA+	, cipherMACHash      = (\_ -> undefined)+	, cipherF            = undefined+	, cipherMinVer       = Nothing+	}++clienthello ciphers = ClientHello TLS10 (ClientRandom $ B.pack [0..31]) (Session Nothing) ciphers [0] Nothing++openConnection :: String -> String -> [Word16] -> IO (Maybe Word16)+openConnection s p ciphers = do+	pn     <- if and $ map isDigit $ p+			then return $ fromIntegral $ (read p :: Int)+			else do+				service <- getServiceByName p "tcp"+				return $ servicePort service+        he     <- getHostByName s+	sock   <- socket AF_INET Stream defaultProtocol+	connect sock (SockAddrInet pn (head $ hostAddresses he))+	handle <- socketToHandle sock ReadWriteMode++	(Right rng) <- makeSRandomGen+	let params = defaultParams { pCiphers = map fakeCipher ciphers }+	ctx <- client params rng handle+	sendPacket ctx $ Handshake $ clienthello ciphers+	catch (do+		rpkt <- recvPacket ctx+		ccid <- case rpkt of+			Right (h:_) -> case h of+				(Handshake (ServerHello _ _ _ i _ _)) -> return i+				_                                     -> error "didn't received serverhello"+			_                                           -> error ("packet received: " ++ show rpkt)+		bye ctx+		hClose handle+		return $ Just ccid+		) (\(_ :: SomeException) -> return Nothing)++connectRange :: String -> String -> Int -> [Word16] -> IO (Int, [Word16])+connectRange d p v r = do+	ccidopt <- openConnection d p r+	threadDelay v+	case ccidopt of+		Nothing   -> return (1, [])+		Just ccid -> do+			{-divide and conquer TLS-}+			let newr = filter ((/=) ccid) r+			let (lr, rr) = if length newr > 2+				then splitAt (length newr `div` 2) newr+				else (newr, [])+			(lc, ls) <- if length lr > 0+				then connectRange d p v lr +				else return (0,[])+			(rc, rs) <- if length rr > 0+				then connectRange d p v rr+				else return (0,[])+			return (1 + lc + rc, [ccid] ++ ls ++ rs)++connectBetween d p v chunkSize ep sp = concat <$> loop sp where+	loop a = liftM2 (:) (snd <$> connectRange d p v range)+	                    (if a + chunkSize > ep then return [] else loop (a+64))+		where+			range = if a + chunkSize > ep+				then [a..ep]+				else [a..sp+chunkSize]++data PArgs = PArgs+	{ destination :: String+	, port        :: String+	, speed       :: Int+	, start       :: Int+	, end         :: Int+	, nb          :: Int+	} deriving (Show, Data, Typeable)++progArgs = PArgs+	{ destination = "localhost" &= help "destination address to connect to" &= typ "address"+	, port        = "443"       &= help "destination port to connect to" &= typ "port"+	, speed       = 100         &= help "speed between queries, in milliseconds" &= typ "speed"+	, start       = 0           &= help "starting cipher number (between 0 and 65535)" &= typ "cipher"+	, end         = 0xff        &= help "end cipher number (between 0 and 65535)" &= typ "cipher"+	, nb          = 64          &= help "number of cipher to include per query " &= typ "range"+	} &= summary "CheckCiphers -- SSL/TLS remotely check supported cipher"+	&= details+		[ "check the supported cipher of a remote destination."+		, "Beware: this program make multiple connections to the destination"+		, "which might be taken by the remote side as aggressive behavior"+		]++main = do+	a <- cmdArgs progArgs+	_ <- printf "connecting to %s on port %s ...\n" (destination a) (port a)+	supported <- connectBetween (destination a) (port a) (speed a) (fromIntegral $ nb a) (fromIntegral $ end a) (fromIntegral $ start a)+	putStrLn $ show supported
+ Examples/Stunnel.hs view
@@ -0,0 +1,258 @@+{-# LANGUAGE DeriveDataTypeable #-}+import Network.BSD+import Network.Socket+import System.IO+import System.IO.Error hiding (try)+import System.Console.CmdArgs++import qualified Data.ByteString as B+import qualified Data.ByteString.Lazy as L++import Control.Concurrent (forkIO)+import Control.Exception (finally, try, throw)+import Control.Monad (when, forever)++import Data.Char (isDigit)++import Data.Certificate.PEM+import Data.Certificate.X509+import qualified Data.Certificate.KeyRSA as KeyRSA+import qualified Crypto.Cipher.RSA as RSA++import Network.TLS+import Network.TLS.Extra++ciphers :: [Cipher]+ciphers =+	[ cipher_AES128_SHA1+	, cipher_AES256_SHA1+	, cipher_RC4_128_MD5+	, cipher_RC4_128_SHA1+	]++loopUntil :: Monad m => m Bool -> m ()+loopUntil f = f >>= \v -> if v then return () else loopUntil f++readOne h = do+	r <- try $ hWaitForInput h (-1)+	case r of+		Left err    -> if isEOFError err then return B.empty else throw err+		Right True  -> B.hGetNonBlocking h 4096+		Right False -> return B.empty++tlsclient :: Handle -> TLSCtx -> IO ()+tlsclient srchandle dsthandle = do+	hSetBuffering srchandle NoBuffering++	handshake dsthandle++	loopUntil $ do+		b <- readOne srchandle+		putStrLn ("sending " ++ show b)+		if B.null b+			then do+				bye dsthandle+				return True+			else do+				sendData dsthandle (L.fromChunks [b])+				return False+	return ()++getRandomGen :: IO SRandomGen+getRandomGen = makeSRandomGen >>= either (fail . show) (return . id)++tlsserver srchandle dsthandle = do+	hSetBuffering dsthandle NoBuffering++	handshake srchandle++	loopUntil $ do+		d <- recvData srchandle+		putStrLn ("received: " ++ show d)+		sendData srchandle (L.pack $ map (toEnum . fromEnum) "this is some data")+		hFlush (ctxHandle srchandle)+		return False+	putStrLn "end"++clientProcess certs handle dsthandle _ = do+	rng <- getRandomGen++	let serverstate = defaultParams+		{ pAllowedVersions = [SSL3,TLS10,TLS11]+		, pCiphers         = ciphers+		, pCertificates    = certs+		, pWantClientCert  = False+		}+	ctx <- server serverstate rng handle+	tlsserver ctx dsthandle++readCertificate :: FilePath -> IO X509+readCertificate filepath = do+	content <- B.readFile filepath+	let certdata = case parsePEMCert content of+		Nothing -> error ("no valid certificate section")+		Just x  -> x+	let cert = case decodeCertificate $ L.fromChunks [certdata] of+		Left err -> error ("cannot decode certificate: " ++ err)+		Right x  -> x+	return cert++readPrivateKey :: FilePath -> IO PrivateKey+readPrivateKey filepath = do+	content <- B.readFile filepath+	let pkdata = case parsePEMKeyRSA content of+		Nothing -> error ("no valid RSA key section")+		Just x  -> L.fromChunks [x]+	let pk = case KeyRSA.decodePrivate pkdata of+		Left err -> error ("cannot decode key: " ++ err)+		Right x  -> PrivRSA $ RSA.PrivateKey+			{ RSA.private_sz   = fromIntegral $ KeyRSA.lenmodulus x+			, RSA.private_n    = KeyRSA.modulus x+			, RSA.private_d    = KeyRSA.private_exponant x+			, RSA.private_p    = KeyRSA.p1 x+			, RSA.private_q    = KeyRSA.p2 x+			, RSA.private_dP   = KeyRSA.exp1 x+			, RSA.private_dQ   = KeyRSA.exp2 x+			, RSA.private_qinv = KeyRSA.coef x+			}+	return pk++data Stunnel =+	  Client+		{ destinationType :: String+		, destination     :: String+		, sourceType      :: String+		, source          :: String }+	| Server+		{ destinationType :: String+		, destination     :: String+		, sourceType      :: String+		, source          :: String+		, certificate     :: FilePath+		, key             :: FilePath }+	deriving (Show, Data, Typeable)++clientOpts = Client+	{ destinationType = "tcp"             &= help "type of source (tcp, unix, fd)" &= typ "DESTTYPE"+	, destination     = "localhost:6061"  &= help "destination address influenced by destination type" &= typ "ADDRESS"+	, sourceType      = "tcp"             &= help "type of source (tcp, unix, fd)" &= typ "SOURCETYPE"+	, source          = "localhost:6060"  &= help "source address influenced by source type" &= typ "ADDRESS"+	}+	&= help "connect to a remote destination that use SSL/TLS"++serverOpts = Server+	{ destinationType = "tcp"             &= help "type of source (tcp, unix, fd)" &= typ "DESTTYPE"+	, destination     = "localhost:6060"  &= help "destination address influenced by destination type" &= typ "ADDRESS"+	, sourceType      = "tcp"             &= help "type of source (tcp, unix, fd)" &= typ "SOURCETYPE"+	, source          = "localhost:6061"  &= help "source address influenced by source type" &= typ "ADDRESS"+	, certificate     = "certificate.pem" &= help "X509 public certificate to use" &= typ "FILE"+	, key             = "certificate.key" &= help "private key linked to the certificate" &= typ "FILE"+	}+	&= help "listen for connection that use SSL/TLS and relay it to a different connection"++mode = cmdArgsMode $ modes [clientOpts,serverOpts]+	&= help "create SSL/TLS tunnel in client or server mode" &= program "stunnel" &= summary "Stunnel v0.1 (Haskell TLS)"++data StunnelAddr   =+	  AddrSocket Family SockAddr+	| AddrFD Handle Handle++data StunnelHandle =+	  StunnelSocket Socket+	| StunnelFd     Handle Handle++getAddressDescription :: String -> String -> IO StunnelAddr+getAddressDescription "tcp"  desc = do+	let (s, p) = break ((==) ':') desc+	when (p == "") (error "missing port: expecting [source]:port")+	pn <- if and $ map isDigit $ drop 1 p+		then return $ fromIntegral $ (read (drop 1 p) :: Int)+		else do+			service <- getServiceByName (drop 1 p) "tcp"+			return $ servicePort service+	he <- getHostByName s+	return $ AddrSocket AF_INET (SockAddrInet pn (head $ hostAddresses he))++getAddressDescription "unix" desc = do+	return $ AddrSocket AF_UNIX (SockAddrUnix desc)++getAddressDescription "fd" _  =+	return $ AddrFD stdin stdout++getAddressDescription _ _  = error "unrecognized source type (expecting tcp/unix/fd)"++connectAddressDescription (AddrSocket family sockaddr) = do+	sock <- socket family Stream defaultProtocol+	catch (connect sock sockaddr)+	      (\_ -> sClose sock >> error ("cannot open socket " ++ show sockaddr))+	return $ StunnelSocket sock++connectAddressDescription (AddrFD h1 h2) = do+	return $ StunnelFd h1 h2++listenAddressDescription (AddrSocket family sockaddr) = do+	sock <- socket family Stream defaultProtocol+	catch (bindSocket sock sockaddr >> listen sock 10 >> setSocketOption sock ReuseAddr 1)+	      (\_ -> sClose sock >> error ("cannot open socket " ++ show sockaddr))+	return $ StunnelSocket sock++listenAddressDescription (AddrFD _ _) = do+	error "cannot listen on fd"++doClient :: Stunnel -> IO ()+doClient pargs = do+	srcaddr <- getAddressDescription (sourceType pargs) (source pargs)+	dstaddr <- getAddressDescription (destinationType pargs) (destination pargs)++	let clientstate = defaultParams+		{ pConnectVersion = TLS10+		, pAllowedVersions = [ TLS10, TLS11 ]+		, pCiphers = ciphers+		, pCertificates = []+		}++	case srcaddr of+		AddrSocket _ _ -> do+			(StunnelSocket srcsocket) <- listenAddressDescription srcaddr+			forever $ do+				(s, _) <- accept srcsocket+				rng    <- getRandomGen+				srch   <- socketToHandle s ReadWriteMode++				(StunnelSocket dst)  <- connectAddressDescription dstaddr++				dsth <- socketToHandle dst ReadWriteMode+				dstctx <- client clientstate rng dsth+				_    <- forkIO $ finally+					(tlsclient srch dstctx)+					(hClose srch >> hClose dsth)+				return ()+		AddrFD _ _ -> error "bad error fd. not implemented"++doServer :: Stunnel -> IO ()+doServer pargs = do+	cert    <- readCertificate $ certificate pargs+	pk      <- readPrivateKey $ key pargs+	srcaddr <- getAddressDescription (sourceType pargs) (source pargs)+	dstaddr <- getAddressDescription (destinationType pargs) (destination pargs)++	case srcaddr of+		AddrSocket _ _ -> do+			(StunnelSocket srcsocket) <- listenAddressDescription srcaddr+			forever $ do+				(s, addr) <- accept srcsocket+				srch <- socketToHandle s ReadWriteMode+				(StunnelSocket dst) <- connectAddressDescription dstaddr+				dsth <- socketToHandle dst ReadWriteMode+				_ <- forkIO $ finally+					(clientProcess [(cert, Just pk)] srch dsth addr >> return ())+					(hClose srch >> hClose dsth)+				return ()+		AddrFD _ _ -> error "bad error fd. not implemented"++main :: IO ()+main = do+	x <- cmdArgsRun mode+	case x of+		Client _ _ _ _     -> doClient x+		Server _ _ _ _ _ _ -> doServer x
+ LICENSE view
@@ -0,0 +1,27 @@+Copyright (c) 2010 Vincent Hanquez <vincent@snarc.org>++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:+1. Redistributions of source code must retain the above copyright+   notice, this list of conditions and the following disclaimer.+2. Redistributions in binary form must reproduce the above copyright+   notice, this list of conditions and the following disclaimer in the+   documentation and/or other materials provided with the distribution.+3. Neither the name of the author nor the names of his contributors+   may be used to endorse or promote products derived from this software+   without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+SUCH DAMAGE.
+ Network/TLS/Extra.hs view
@@ -0,0 +1,5 @@+module Network.TLS.Extra +	( module Network.TLS.Extra.Cipher+	) where++import Network.TLS.Extra.Cipher
+ Network/TLS/Extra/Certificate.hs view
@@ -0,0 +1,67 @@+module Network.TLS.Extra.Certificate+	(+	) where+{-++import qualified Data.ByteString.Lazy as L+import qualified Data.ByteString.Lazy.Char8 as LC+import qualified Data.ByteString as B+--import qualified Data.Text.Lazy as T+--import Data.Text.Lazy.Encoding (decodeUtf8)++import Data.Certificate.PEM+import Data.Certificate.X509+import System.Certificate.X509 as SysCert++import Control.Monad+import Control.Applicative ((<$>))++-- for signing/verifying certificate+import qualified Crypto.Hash.SHA1 as SHA1+import qualified Crypto.Hash.MD2 as MD2+import qualified Crypto.Hash.MD5 as MD5+import qualified Crypto.Cipher.RSA as RSA+import qualified Crypto.Cipher.DSA as DSA++verifyCert x509@(X509.X509 cert _ sigalg sig) = do+	sysx509 <- SysCert.findCertificate (matchsysX509 cert)+	case sysx509 of+		Nothing                        -> putStrLn "couldn't find signing certificate"+		Just (X509.X509 syscert _ _ _) -> do+			verifyAlg (B.concat $ L.toChunks $ X509.getSigningData x509)+			          (B.pack sig)+			          sigalg+			          (X509.certPubKey syscert)++rsaVerify h hdesc pk a b = either (Left . show) (Right) $ RSA.verify h hdesc pk a b++verifyF X509.SignatureALG_md2WithRSAEncryption (X509.PubKeyRSA rsakey) =+	rsaVerify MD2.hash (B.pack [0x30,0x20,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x04,0x10]) (mkRSA rsakey)++verifyF X509.SignatureALG_md5WithRSAEncryption (X509.PubKeyRSA rsakey) =+	rsaVerify MD5.hash (B.pack [0x30,0x20,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x04,0x10]) (mkRSA rsakey)++verifyF X509.SignatureALG_sha1WithRSAEncryption (X509.PubKeyRSA rsakey) =+	rsaVerify SHA1.hash (B.pack [0x30,0x20,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x04,0x10]) (mkRSA rsakey)++verifyF X509.SignatureALG_dsaWithSHA1 (X509.PubKeyDSA (pub,p,q,g)) =+	(\_ _ -> Left "unimplemented DSA checking")++verifyF _ _ =+	(\_ _ -> Left "unexpected/wrong signature")++mkRSA (lenmodulus, modulus, e) =+	RSA.PublicKey { RSA.public_sz = lenmodulus, RSA.public_n = modulus, RSA.public_e = e }++verifyAlg toSign expectedSig sigalg pk =+	let f = verifyF sigalg pk in+	case f toSign expectedSig of+		Left err    -> putStrLn ("certificate couldn't be verified: something happened: " ++ show err)+		Right True  -> putStrLn "certificate verified"+		Right False -> putStrLn "certificate not verified"++matchsysX509 cert (X509.X509 syscert _ _ _) = do+	let x = X509.certSubjectDN syscert+	let y = X509.certIssuerDN cert+	x == y+-}
+ Network/TLS/Extra/Cipher.hs view
@@ -0,0 +1,234 @@+-- |+-- Module      : Network.TLS.Extra.Cipher+-- License     : BSD-style+-- Maintainer  : Vincent Hanquez <vincent@snarc.org>+-- Stability   : experimental+-- Portability : unknown+--+module Network.TLS.Extra.Cipher+	(+	  cipher_null_null+	, 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+	) where++import qualified Data.Vector.Unboxed as Vector (fromList, toList)+import qualified Data.ByteString as B++import Network.TLS (Version(..))+import Network.TLS.Cipher+import qualified Crypto.Cipher.AES as AES+import qualified 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++aes128_cbc_encrypt :: Key -> IV -> B.ByteString -> B.ByteString+aes128_cbc_encrypt key iv d = AES.encryptCBC pkey iv d+	where (Right pkey) = AES.initKey128 key++aes128_cbc_decrypt :: Key -> IV -> B.ByteString -> B.ByteString+aes128_cbc_decrypt key iv d = AES.decryptCBC pkey iv d+	where (Right pkey) = AES.initKey128 key++aes256_cbc_encrypt :: Key -> IV -> B.ByteString -> B.ByteString+aes256_cbc_encrypt key iv d = AES.encryptCBC pkey iv d+	where (Right pkey) = AES.initKey256 key++aes256_cbc_decrypt :: Key -> IV -> B.ByteString -> B.ByteString+aes256_cbc_decrypt key iv d = AES.decryptCBC pkey iv d+	where (Right pkey) = AES.initKey256 key++toIV :: RC4.Ctx -> IV+toIV (v, x, y) = B.pack (x : y : Vector.toList v)++toCtx :: IV -> RC4.Ctx+toCtx iv =+	case B.unpack iv of+		x:y:l -> (Vector.fromList l, x, y)+		_     -> (Vector.fromList [], 0, 0)++initF_rc4 :: Key -> IV+initF_rc4 key     = toIV $ RC4.initCtx (B.unpack key)++encryptF_rc4 :: IV -> B.ByteString -> (B.ByteString, IV)+encryptF_rc4 iv d = (\(ctx, e) -> (e, toIV ctx)) $ RC4.encrypt (toCtx iv) d++decryptF_rc4 :: IV -> B.ByteString -> (B.ByteString, IV)+decryptF_rc4 iv e = (\(ctx, d) -> (d, toIV ctx)) $ RC4.decrypt (toCtx iv) e+++cipher_null_null :: Cipher+cipher_null_null = Cipher+	{ cipherID           = 0x0+	, cipherName         = "null-null"+	, cipherDigestSize   = 0+	, cipherKeySize      = 0+	, cipherIVSize       = 0+	, cipherKeyBlockSize = 0+	, cipherPaddingSize  = 0+	, cipherMACHash      = (const B.empty)+	, cipherKeyExchange  = CipherKeyExchangeRSA+	, cipherF            = CipherNoneF+	, cipherMinVer       = Nothing+	}++cipher_null_MD5 :: Cipher+cipher_null_MD5 = Cipher+	{ cipherID           = 0x1+	, cipherName         = "RSA-null-MD5"+	, cipherDigestSize   = 16+	, cipherKeySize      = 0+	, cipherIVSize       = 0+	, cipherKeyBlockSize = 2 * (16 + 0 + 0)+	, cipherPaddingSize  = 0+	, cipherMACHash      = MD5.hash+	, cipherKeyExchange  = CipherKeyExchangeRSA+	, cipherF            = CipherNoneF+	, cipherMinVer       = Nothing+	}++cipher_null_SHA1 :: Cipher+cipher_null_SHA1 = Cipher+	{ cipherID           = 0x2+	, cipherName         = "RSA-null-SHA1"+	, cipherDigestSize   = 20+	, cipherKeySize      = 0+	, cipherIVSize       = 0+	, cipherKeyBlockSize = 2 * (20 + 0 + 0)+	, cipherPaddingSize  = 0+	, cipherMACHash      = SHA1.hash+	, cipherKeyExchange  = CipherKeyExchangeRSA+	, cipherF            = CipherNoneF+	, cipherMinVer       = Nothing+	}++cipher_RC4_128_MD5 :: Cipher+cipher_RC4_128_MD5 = Cipher+	{ cipherID           = 0x04+	, cipherName         = "RSA-rc4-128-md5"+	, cipherDigestSize   = 16+	, cipherKeySize      = 16+	, cipherIVSize       = 0+	, cipherKeyBlockSize = 2 * (16 + 16 + 0)+	, cipherPaddingSize  = 0+	, cipherMACHash      = MD5.hash+	, cipherKeyExchange  = CipherKeyExchangeRSA+	, cipherF            = CipherStreamF initF_rc4 encryptF_rc4 decryptF_rc4+	, cipherMinVer       = Nothing+	}++cipher_RC4_128_SHA1 :: Cipher+cipher_RC4_128_SHA1 = Cipher+	{ cipherID           = 0x05+	, cipherName         = "RSA-rc4-128-sha1"+	, cipherDigestSize   = 20+	, cipherKeySize      = 16+	, cipherIVSize       = 0+	, cipherKeyBlockSize = 2 * (20 + 16 + 0)+	, cipherPaddingSize  = 0+	, cipherMACHash      = SHA1.hash+	, cipherKeyExchange  = CipherKeyExchangeRSA+	, cipherF            = CipherStreamF initF_rc4 encryptF_rc4 decryptF_rc4+	, cipherMinVer       = Nothing+	}++cipher_AES128_SHA1 :: Cipher+cipher_AES128_SHA1 = Cipher+	{ cipherID           = 0x2f+	, cipherName         = "RSA-aes128-sha1"+	, cipherDigestSize   = 20+	, cipherKeySize      = 16+	, cipherIVSize       = 16+	, cipherKeyBlockSize = 2 * (20 + 16 + 16)+	, cipherPaddingSize  = 16+	, cipherMACHash      = SHA1.hash+	, cipherKeyExchange  = CipherKeyExchangeRSA+	, cipherF            = CipherBlockF aes128_cbc_encrypt aes128_cbc_decrypt+	, cipherMinVer       = Just SSL3+	}++cipher_AES256_SHA1 :: Cipher+cipher_AES256_SHA1 = Cipher+	{ cipherID           = 0x35+	, cipherName         = "RSA-aes256-sha1"+	, cipherDigestSize   = 20+	, cipherKeySize      = 32+	, cipherIVSize       = 16+	, cipherKeyBlockSize = 2 * (20 + 32 + 16)+	, cipherPaddingSize  = 16+	, cipherMACHash      = SHA1.hash+	, cipherKeyExchange  = CipherKeyExchangeRSA+	, cipherF            = CipherBlockF aes256_cbc_encrypt aes256_cbc_decrypt+	, cipherMinVer       = Just SSL3+	}++cipher_AES128_SHA256 :: Cipher+cipher_AES128_SHA256 = Cipher+	{ cipherID           = 0x3c+	, cipherName         = "RSA-aes128-sha256"+	, cipherDigestSize   = 32+	, cipherKeySize      = 16+	, cipherIVSize       = 16+	, cipherKeyBlockSize = 2 * (32 + 16 + 16)+	, cipherPaddingSize  = 16+	, cipherMACHash      = SHA256.hash+	, cipherKeyExchange  = CipherKeyExchangeRSA+	, cipherF            = CipherBlockF aes128_cbc_encrypt aes128_cbc_decrypt+	, cipherMinVer       = Just TLS12+	}++cipher_AES256_SHA256 :: Cipher+cipher_AES256_SHA256 = Cipher+	{ cipherID           = 0x3d+	, cipherName         = "RSA-aes256-sha256"+	, cipherDigestSize   = 32+	, cipherKeySize      = 32+	, cipherIVSize       = 16+	, cipherKeyBlockSize = 2 * (32 + 32 + 16)+	, cipherPaddingSize  = 16+	, cipherMACHash      = SHA256.hash+	, cipherKeyExchange  = CipherKeyExchangeRSA+	, cipherF            = CipherBlockF aes256_cbc_encrypt aes256_cbc_decrypt+	, cipherMinVer       = Just TLS12+	}++{-+TLS 1.0 ciphers definition++CipherSuite TLS_NULL_WITH_NULL_NULL               = { 0x00,0x00 };+CipherSuite TLS_RSA_WITH_NULL_MD5                 = { 0x00,0x01 };+CipherSuite TLS_RSA_WITH_NULL_SHA                 = { 0x00,0x02 };+CipherSuite TLS_RSA_EXPORT_WITH_RC4_40_MD5        = { 0x00,0x03 };+CipherSuite TLS_RSA_WITH_RC4_128_MD5              = { 0x00,0x04 };+CipherSuite TLS_RSA_WITH_RC4_128_SHA              = { 0x00,0x05 };+CipherSuite TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5    = { 0x00,0x06 };+CipherSuite TLS_RSA_WITH_IDEA_CBC_SHA             = { 0x00,0x07 };+CipherSuite TLS_RSA_EXPORT_WITH_DES40_CBC_SHA     = { 0x00,0x08 };+CipherSuite TLS_RSA_WITH_DES_CBC_SHA              = { 0x00,0x09 };+CipherSuite TLS_RSA_WITH_3DES_EDE_CBC_SHA         = { 0x00,0x0A };+CipherSuite TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA  = { 0x00,0x0B };+CipherSuite TLS_DH_DSS_WITH_DES_CBC_SHA           = { 0x00,0x0C };+CipherSuite TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA      = { 0x00,0x0D };+CipherSuite TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA  = { 0x00,0x0E };+CipherSuite TLS_DH_RSA_WITH_DES_CBC_SHA           = { 0x00,0x0F };+CipherSuite TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA      = { 0x00,0x10 };+CipherSuite TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x11 };+CipherSuite TLS_DHE_DSS_WITH_DES_CBC_SHA          = { 0x00,0x12 };+CipherSuite TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA     = { 0x00,0x13 };+CipherSuite TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x14 };+CipherSuite TLS_DHE_RSA_WITH_DES_CBC_SHA          = { 0x00,0x15 };+CipherSuite TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA     = { 0x00,0x16 };+CipherSuite TLS_DH_anon_EXPORT_WITH_RC4_40_MD5    = { 0x00,0x17 };+CipherSuite TLS_DH_anon_WITH_RC4_128_MD5          = { 0x00,0x18 };+CipherSuite TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x19 };+CipherSuite TLS_DH_anon_WITH_DES_CBC_SHA          = { 0x00,0x1A };+CipherSuite TLS_DH_anon_WITH_3DES_EDE_CBC_SHA     = { 0x00,0x1B };+-}
+ Network/TLS/Extra/Compression.hs view
@@ -0,0 +1,5 @@+module Network.TLS.Extra.Compression+	(+	) where++import Network.TLS.Compression
+ Network/TLS/Extra/Thread.hs view
@@ -0,0 +1,3 @@+module Network.TLS.Extra.Thread+	(+	) where
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ Tests.hs view
@@ -0,0 +1,8 @@+{-# LANGUAGE CPP #-}++import qualified Tests.Connection as Connection+import qualified Tests.Ciphers as Ciphers++main = do+	Ciphers.runTests+	Connection.runTests
+ tls-extra.cabal view
@@ -0,0 +1,78 @@+Name:                tls-extra+Version:             0.1.0+Description:+   a set of extra definitions, default values and helpers for tls.+License:             BSD3+License-file:        LICENSE+Copyright:           Vincent Hanquez <vincent@snarc.org>+Author:              Vincent Hanquez <vincent@snarc.org>+Maintainer:          Vincent Hanquez <vincent@snarc.org>+Synopsis:            TLS extra default values and helpers+Build-Type:          Simple+Category:            Network+stability:           experimental+Cabal-Version:       >=1.6+Homepage:            http://github.com/vincenthz/hs-tls-extra++Flag test+  Description:       Build unit test+  Default:           False++Flag bench+  Description:       Build benchmarks+  Default:           False++Flag executable+  Description:       Build the executable+  Default:           False++Library+  Build-Depends:     tls >= 0.5 && < 0.6+                   , mtl+                   , cryptohash >= 0.6+                   , bytestring+                   , vector+                   , crypto-api >= 0.5+                   , cryptocipher >= 0.2.5+                   , certificate >= 0.7 && < 0.8+  Exposed-modules:   Network.TLS.Extra+  other-modules:     Network.TLS.Extra.Certificate+                     Network.TLS.Extra.Cipher+                     Network.TLS.Extra.Compression+                     Network.TLS.Extra.Thread+  ghc-options:       -Wall++Executable           stunnel+  Main-is:           Examples/Stunnel.hs+  if flag(executable)+    Build-Depends:   network+                   , cmdargs+    Buildable:       True+  else+    Buildable:       False+  ghc-options:       -Wall -fno-warn-missing-signatures++Executable           checkciphers+  Main-is:           Examples/CheckCiphers.hs+  if flag(executable)+    Build-Depends:   network+                   , cmdargs+    Buildable:       True+  else+    Buildable:       False+  ghc-options:       -Wall -fno-warn-missing-signatures++executable           Tests+  Main-is:           Tests.hs+  if flag(test)+    Buildable:       True+    Build-Depends:   base >= 3 && < 5+                   , HUnit+                   , QuickCheck >= 2+                   , bytestring+  else+    Buildable:       False++source-repository head+  type: git+  location: git://github.com/vincenthz/hs-tls-extra