packages feed

tls 0.1.1 → 0.1.2

raw patch · 11 files changed

+126/−70 lines, 11 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

+ Network.TLS.Cipher: Cipher :: Word16 -> String -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> CipherKeyExchangeType -> (ByteString -> ByteString -> ByteString) -> CipherTypeFunctions -> Maybe Version -> Cipher
+ Network.TLS.Cipher: CipherBlockF :: (Key -> IV -> ByteString -> ByteString) -> (Key -> IV -> ByteString -> ByteString) -> CipherTypeFunctions
+ Network.TLS.Cipher: CipherKeyExchangeDHE_DSS :: CipherKeyExchangeType
+ Network.TLS.Cipher: CipherKeyExchangeDHE_RSA :: CipherKeyExchangeType
+ Network.TLS.Cipher: CipherKeyExchangeDH_DSS :: CipherKeyExchangeType
+ Network.TLS.Cipher: CipherKeyExchangeDH_RSA :: CipherKeyExchangeType
+ Network.TLS.Cipher: CipherKeyExchangeECDHE_ECDSA :: CipherKeyExchangeType
+ Network.TLS.Cipher: CipherKeyExchangeECDHE_RSA :: CipherKeyExchangeType
+ Network.TLS.Cipher: CipherKeyExchangeECDH_ECDSA :: CipherKeyExchangeType
+ Network.TLS.Cipher: CipherKeyExchangeECDH_RSA :: CipherKeyExchangeType
+ Network.TLS.Cipher: CipherKeyExchangeRSA :: CipherKeyExchangeType
+ Network.TLS.Cipher: CipherNoneF :: CipherTypeFunctions
+ Network.TLS.Cipher: CipherStreamF :: (Key -> IV) -> (IV -> ByteString -> (ByteString, IV)) -> (IV -> ByteString -> (ByteString, IV)) -> CipherTypeFunctions
+ Network.TLS.Cipher: cipherDigestSize :: Cipher -> Word8
+ Network.TLS.Cipher: cipherExchangeNeedMoreData :: CipherKeyExchangeType -> Bool
+ Network.TLS.Cipher: cipherF :: Cipher -> CipherTypeFunctions
+ Network.TLS.Cipher: cipherHMAC :: Cipher -> ByteString -> ByteString -> ByteString
+ Network.TLS.Cipher: cipherID :: Cipher -> Word16
+ Network.TLS.Cipher: cipherIVSize :: Cipher -> Word8
+ Network.TLS.Cipher: cipherKeyBlockSize :: Cipher -> Word8
+ Network.TLS.Cipher: cipherKeyExchange :: Cipher -> CipherKeyExchangeType
+ Network.TLS.Cipher: cipherKeySize :: Cipher -> Word8
+ Network.TLS.Cipher: cipherMinVer :: Cipher -> Maybe Version
+ Network.TLS.Cipher: cipherName :: Cipher -> String
+ Network.TLS.Cipher: cipherPaddingSize :: Cipher -> Word8
+ Network.TLS.Cipher: cipher_AES128_SHA1 :: Cipher
+ Network.TLS.Cipher: cipher_AES128_SHA256 :: Cipher
+ Network.TLS.Cipher: cipher_AES256_SHA1 :: Cipher
+ Network.TLS.Cipher: cipher_AES256_SHA256 :: Cipher
+ Network.TLS.Cipher: cipher_RC4_128_MD5 :: Cipher
+ Network.TLS.Cipher: cipher_RC4_128_SHA1 :: Cipher
+ Network.TLS.Cipher: cipher_null_null :: Cipher
+ Network.TLS.Cipher: data Cipher
+ Network.TLS.Cipher: data CipherKeyExchangeType
+ Network.TLS.Cipher: data CipherTypeFunctions
+ Network.TLS.Cipher: instance Show Cipher
+ Network.TLS.Client: TLSClient :: StateT TLSStateClient m a -> TLSClient m a
+ Network.TLS.Client: TLSClientCallbacks :: Maybe ([Certificate] -> IO Bool) -> TLSClientCallbacks
+ Network.TLS.Client: cbCertificates :: TLSClientCallbacks -> Maybe ([Certificate] -> IO Bool)
+ Network.TLS.Client: cpCallbacks :: TLSClientParams -> TLSClientCallbacks
+ Network.TLS.Client: data TLSClientCallbacks
+ Network.TLS.Client: instance Show TLSClientCallbacks
+ Network.TLS.Client: newtype TLSClient m a
+ Network.TLS.Client: runTLSC :: TLSClient m a -> StateT TLSStateClient m a
+ Network.TLS.MAC: hmacMD5 :: ByteString -> ByteString -> ByteString
+ Network.TLS.MAC: hmacSHA1 :: ByteString -> ByteString -> ByteString
+ Network.TLS.MAC: hmacSHA256 :: ByteString -> ByteString -> ByteString
+ Network.TLS.MAC: prf_MD5 :: ByteString -> ByteString -> Int -> ByteString
+ Network.TLS.MAC: prf_MD5SHA1 :: ByteString -> ByteString -> Int -> ByteString
+ Network.TLS.MAC: prf_SHA1 :: ByteString -> ByteString -> Int -> ByteString
+ Network.TLS.SRandom: getRandomByte :: SRandomGen -> (Word8, SRandomGen)
+ Network.TLS.SRandom: getRandomBytes :: SRandomGen -> Int -> ([Word8], SRandomGen)
+ Network.TLS.SRandom: makeSRandomGen :: Int -> SRandomGen
+ Network.TLS.SRandom: type SRandomGen = StdGen
+ Network.TLS.Server: TLSServerCallbacks :: Maybe ([Certificate] -> IO Bool) -> TLSServerCallbacks
+ Network.TLS.Server: cbCertificates :: TLSServerCallbacks -> Maybe ([Certificate] -> IO Bool)
+ Network.TLS.Server: data TLSServerCallbacks
+ Network.TLS.Server: instance Show TLSServerCallbacks
+ Network.TLS.Server: spCallbacks :: TLSServerParams -> TLSServerCallbacks
+ Network.TLS.Struct: ClientKeyData :: [Word8] -> ClientKeyData
+ Network.TLS.Struct: instance Eq ClientKeyData
+ Network.TLS.Struct: instance Show ClientKeyData
+ Network.TLS.Struct: newtype ClientKeyData
- Network.TLS.Client: TLSClientParams :: Version -> [Version] -> Maybe [Word8] -> [Cipher] -> Maybe Certificate -> TLSClientParams
+ Network.TLS.Client: TLSClientParams :: Version -> [Version] -> Maybe [Word8] -> [Cipher] -> Maybe Certificate -> TLSClientCallbacks -> TLSClientParams
- Network.TLS.Client: connect :: Handle -> ClientRandom -> [Word8] -> TLSClient IO ()
+ Network.TLS.Client: connect :: Handle -> ClientRandom -> ClientKeyData -> TLSClient IO ()
- Network.TLS.Server: TLSServerParams :: [Version] -> [[Word8]] -> [Cipher] -> Maybe TLSServerCert -> Bool -> TLSServerParams
+ Network.TLS.Server: TLSServerParams :: [Version] -> [[Word8]] -> [Cipher] -> Maybe TLSServerCert -> Bool -> TLSServerCallbacks -> TLSServerParams
- Network.TLS.Struct: ClientKeyXchg :: Version -> [Word8] -> Handshake
+ Network.TLS.Struct: ClientKeyXchg :: Version -> ClientKeyData -> Handshake

Files

Network/TLS/Client.hs view
@@ -12,7 +12,9 @@ -- module Network.TLS.Client 	( TLSClientParams(..)+	, TLSClientCallbacks(..) 	, TLSStateClient+	, TLSClient (..) 	, runTLSClient 	-- * low level packet sending receiving. 	, recvPacket@@ -26,6 +28,7 @@  import Data.Maybe import Data.Word+import Control.Applicative ((<$>)) import Control.Monad.Trans import Control.Monad.State import Data.Certificate.X509@@ -40,12 +43,20 @@ import System.IO (Handle, hFlush) import Data.List (find) +data TLSClientCallbacks = TLSClientCallbacks+	{ cbCertificates :: Maybe ([Certificate] -> IO Bool) -- ^ optional callback to verify certificates+	}++instance Show TLSClientCallbacks where+	show _ = "[callbacks]"+ data TLSClientParams = TLSClientParams-	{ cpConnectVersion  :: Version           -- ^ client version we're sending by default-	, cpAllowedVersions :: [Version]         -- ^ allowed versions from the server-	, cpSession         :: Maybe [Word8]     -- ^ session for this connection-	, cpCiphers         :: [Cipher]          -- ^ all ciphers for this connection-	, cpCertificate     :: Maybe Certificate -- ^ an optional client certificate+	{ cpConnectVersion  :: Version            -- ^ client version we're sending by default+	, cpAllowedVersions :: [Version]          -- ^ allowed versions from the server+	, cpSession         :: Maybe [Word8]      -- ^ session for this connection+	, cpCiphers         :: [Cipher]           -- ^ all ciphers for this connection+	, cpCertificate     :: Maybe Certificate  -- ^ an optional client certificate+	, cpCallbacks       :: TLSClientCallbacks -- ^ user callbacks 	} deriving (Show)  data TLSStateClient = TLSStateClient@@ -92,8 +103,9 @@  recvServerHello :: Handle -> TLSClient IO () recvServerHello handle = do-	ciphers <- fmap (cpCiphers . scParams) get-	allowedvers <- fmap (cpAllowedVersions . scParams) get+	ciphers <- cpCiphers . scParams <$> get+	allowedvers <- cpAllowedVersions . scParams <$> get+	callbacks <- cpCallbacks . scParams <$> get 	pkt <- recvPacket handle 	let hs = case pkt of 		Right (Handshake h) -> h@@ -109,27 +121,30 @@ 				Nothing -> error "no cipher in common with the server" 				Just c  -> setCipher c 			recvServerHello handle-		CertRequest _ _ _ -> modify (\sc -> sc { scCertRequested = True }) >> recvServerHello handle-		Certificates _    -> recvServerHello handle-		ServerHelloDone   -> return ()-		_                 -> error "unexpected handshake message received in server hello messages"+		CertRequest _ _ _  -> modify (\sc -> sc { scCertRequested = True }) >> recvServerHello handle+		Certificates certs -> do+			valid <- lift $ maybe (return True) (\cb -> cb certs) (cbCertificates callbacks)+			unless valid $ error "certificates received deemed invalid by user"+			recvServerHello handle+		ServerHelloDone    -> return ()+		_                  -> error "unexpected handshake message received in server hello messages"  connectSendClientHello :: Handle -> ClientRandom -> TLSClient IO () connectSendClientHello handle crand = do-	ver <- fmap (cpConnectVersion . scParams) get-	ciphers <- fmap (cpCiphers . scParams) get+	ver <- cpConnectVersion . scParams <$> get+	ciphers <- cpCiphers . scParams <$> get 	sendPacket handle $ Handshake (ClientHello ver crand (Session Nothing) (map cipherID ciphers) [ 0 ] Nothing)  connectSendClientCertificate :: Handle -> TLSClient IO () connectSendClientCertificate handle = do-	certRequested <- fmap scCertRequested get+	certRequested <- scCertRequested <$> get 	when certRequested $ do-		clientCert <- fmap (cpCertificate . scParams) get+		clientCert <- cpCertificate . scParams <$> get 		sendPacket handle $ Handshake (Certificates $ maybe [] (:[]) clientCert) -connectSendClientKeyXchg :: Handle -> [Word8] -> TLSClient IO ()+connectSendClientKeyXchg :: Handle -> ClientKeyData -> TLSClient IO () connectSendClientKeyXchg handle prerand = do-	ver <- fmap (cpConnectVersion . scParams) get+	ver <- cpConnectVersion . scParams <$> get 	sendPacket handle $ Handshake (ClientKeyXchg ver prerand)  connectSendFinish :: Handle -> TLSClient IO ()@@ -138,7 +153,7 @@ 	sendPacket handle (Handshake $ Finished $ L.unpack cf)  {- | connect through a handle as a new TLS connection. -}-connect :: Handle -> ClientRandom -> [Word8] -> TLSClient IO ()+connect :: Handle -> ClientRandom -> ClientKeyData -> TLSClient IO () connect handle crand premasterRandom = do 	connectSendClientHello handle crand 	recvServerHello handle@@ -194,7 +209,7 @@ 			let (premaster, rng'') = getRandomBytes rng' 46 			putTLSState $ st { stRandomGen = rng'' } 			let crand = fromJust $ clientRandom bytes-			connect handle crand premaster+			connect handle crand (ClientKeyData premaster) 			recvData handle 		Left err          -> error ("error received: " ++ show err) 		_                 -> error "unexpected item"
Network/TLS/Packet.hs view
@@ -40,6 +40,7 @@ import Network.TLS.Wire import Data.Either (partitionEithers) import Data.Maybe (fromJust, isNothing)+import Control.Applicative ((<$>)) import Control.Monad import Control.Monad.Error import Network.TLS.Struct@@ -167,19 +168,19 @@ getSignatureHashAlgorithm :: Int -> Get [ (HashAlgorithm, SignatureAlgorithm) ] getSignatureHashAlgorithm 0   = return [] getSignatureHashAlgorithm len = do-	h <- fmap (fromJust . valToType) getWord8-	s <- fmap (fromJust . valToType) getWord8+	h <- fromJust . valToType <$> getWord8+	s <- fromJust . valToType <$> getWord8 	xs <- getSignatureHashAlgorithm (len - 2) 	return ((h, s) : xs)  decodeCertRequest :: Version -> Get Handshake decodeCertRequest ver = do-	certTypes <- fmap (map (fromJust . valToType . fromIntegral)) getWords8+	certTypes <- map (fromJust . valToType . fromIntegral) <$> getWords8  	sigHashAlgs <- if ver >= TLS12 		then do 			sighashlen <- getWord16-			fmap Just $ getSignatureHashAlgorithm $ fromIntegral sighashlen+			Just <$> getSignatureHashAlgorithm (fromIntegral sighashlen) 		else return Nothing 	dNameLen <- getWord16 	when (ver < TLS12 && dNameLen < 3) $ throwError (Error_Misc "certrequest distinguishname not of the correct size")@@ -194,7 +195,7 @@ decodeClientKeyXchg :: Get Handshake decodeClientKeyXchg = do 	ver <- getVersion-	ran <- getRandom46+	ran <- getClientKeyData46 	return $ ClientKeyXchg ver ran  -- FIXME need to work out how we marshall an opaque number@@ -260,7 +261,7 @@  encodeHandshakeContent (ClientKeyXchg version random) = do 	putVersion version-	putRandom46 random+	putClientKeyData46 random  encodeHandshakeContent (ServerKeyXchg _) = do 	-- FIXME@@ -295,13 +296,13 @@  {- FIXME make sure it return error if not 32 available -} getRandom32 :: Get [Word8]-getRandom32 = fmap B.unpack $ getBytes 32+getRandom32 = B.unpack <$> getBytes 32  getServerRandom32 :: Get ServerRandom-getServerRandom32 = fmap ServerRandom getRandom32+getServerRandom32 = ServerRandom <$> getRandom32  getClientRandom32 :: Get ClientRandom-getClientRandom32 = fmap ClientRandom getRandom32+getClientRandom32 = ClientRandom <$> getRandom32  putRandom32 :: [Word8] -> Put putRandom32 = mapM_ putWord8@@ -312,18 +313,18 @@ putServerRandom32 :: ServerRandom -> Put putServerRandom32 (ServerRandom r) = putRandom32 r -getRandom46 :: Get [Word8]-getRandom46 = fmap B.unpack $ getBytes 46+getClientKeyData46 :: Get ClientKeyData+getClientKeyData46 = ClientKeyData . B.unpack <$> getBytes 46 -putRandom46 :: [Word8] -> Put-putRandom46 = mapM_ putWord8+putClientKeyData46 :: ClientKeyData -> Put+putClientKeyData46 (ClientKeyData d) = mapM_ putWord8 d  getSession :: Get Session getSession = do 	len8 <- getWord8 	case fromIntegral len8 of 		0   -> return $ Session Nothing-		len -> fmap (Session . Just . B.unpack) $ getBytes len+		len -> Session . Just . B.unpack <$> getBytes len  putSession :: Session -> Put putSession (Session session) =
Network/TLS/Receiving.hs view
@@ -14,6 +14,7 @@ 	readPacket 	) where +import Control.Applicative ((<$>)) import Control.Monad.State import Control.Monad.Error import Data.Maybe@@ -53,7 +54,7 @@  readPacket :: MonadTLSState m => Header -> EncryptedData -> m (Either TLSError Packet) readPacket hdr@(Header ProtocolType_AppData _ _) content =-	runTLSRead (fmap AppData $ decryptContent hdr content)+	runTLSRead (AppData <$> decryptContent hdr content)  readPacket hdr@(Header ProtocolType_Alert _ _)   content = 	runTLSRead (decryptContent hdr content >>= returnEither . decodeAlert >>= return . Alert)@@ -109,7 +110,7 @@ 			return econtent 	hs <- case (ty, decodeHandshake ver ty content) of 		(_, Right x)                            -> return x-		(HandshakeType_ClientKeyXchg, Left _)   -> return $ ClientKeyXchg SSL2 []+		(HandshakeType_ClientKeyXchg, Left _)   -> return $ ClientKeyXchg SSL2 (ClientKeyData $ replicate 0xff 46) 		(_, Left err)                           -> throwError err 	clientmode <- isClientContext 	case hs of@@ -118,7 +119,7 @@ 		ServerHello sver ran _ _ _ _ -> when clientmode $ do 			setServerRandom ran 			setVersion sver-		Certificates [cert]          -> when clientmode $ do processCertificate cert+		Certificates certs           -> when clientmode $ do processCertificates certs 		ClientKeyXchg cver _         -> unless clientmode $ do 			processClientKeyXchg cver content 		Finished fdata               -> processClientFinished fdata@@ -185,9 +186,9 @@ 			else contentpadded 	return content -processCertificate :: Certificate -> TLSRead ()-processCertificate cert = do-	case certPubKey cert of+processCertificates :: [Certificate] -> TLSRead ()+processCertificates certs = do+	case certPubKey $ head certs of 		PubKey _ (PubKeyRSA (lm, m, e)) -> do 			let pk = PublicKey { public_size = fromIntegral lm, public_n = m, public_e = e } 			setPublicKey pk
Network/TLS/Sending.hs view
@@ -97,7 +97,7 @@ 	let g = stRandomGen st 	let rsakey = fromJust $ hstRSAPublicKey $ fromJust $ stHandshake st 	case rsaEncrypt g rsakey content of-		Nothing             -> return L.empty+		Nothing             -> fail "no RSA key selected" 		Just (econtent, g') -> do 			putTLSState (st { stRandomGen = g' }) 			return econtent
Network/TLS/Server.hs view
@@ -12,6 +12,7 @@  module Network.TLS.Server 	( TLSServerParams(..)+	, TLSServerCallbacks(..) 	, TLSStateServer 	, runTLSServer 	-- * low level packet sending receiving.@@ -44,12 +45,20 @@  type TLSServerCert = (L.ByteString, Certificate, CertificateKey.PrivateKey) +data TLSServerCallbacks = TLSServerCallbacks+	{ cbCertificates :: Maybe ([Certificate] -> IO Bool) -- ^ optional callback to verify certificates+	}++instance Show TLSServerCallbacks where+	show _ = "[callbacks]"+ data TLSServerParams = TLSServerParams 	{ spAllowedVersions :: [Version]           -- ^ allowed versions that we can use 	, spSessions        :: [[Word8]]           -- ^ placeholder for futur known sessions 	, spCiphers         :: [Cipher]            -- ^ all ciphers that the server side support 	, spCertificate     :: Maybe TLSServerCert -- ^ the certificate we serve to the client 	, spWantClientCert  :: Bool                -- ^ configure if we do a cert request to the client+	, spCallbacks       :: TLSServerCallbacks  -- ^ user callbacks 	}  data TLSStateServer = TLSStateServer
Network/TLS/Struct.hs view
@@ -25,6 +25,7 @@ 	, Header(..) 	, ServerRandom(..) 	, ClientRandom(..)+	, ClientKeyData(..) 	, serverRandom 	, clientRandom 	, FinishedData@@ -108,6 +109,7 @@  newtype ServerRandom = ServerRandom [Word8] deriving (Show, Eq) newtype ClientRandom = ClientRandom [Word8] deriving (Show, Eq)+newtype ClientKeyData = ClientKeyData [Word8] deriving (Show, Eq) newtype Session = Session (Maybe [Word8]) deriving (Show, Eq) type CipherID = Word16 type CompressionID = Word8@@ -196,7 +198,7 @@ 	| Certificates [Certificate] 	| HelloRequest 	| ServerHelloDone-	| ClientKeyXchg Version [Word8]+	| ClientKeyXchg Version ClientKeyData 	| ServerKeyXchg ServerKeyXchgAlgorithmData 	| CertRequest [CertificateType] (Maybe [ (HashAlgorithm, SignatureAlgorithm) ]) [Word8] 	| CertVerify [Word8]
Network/TLS/Wire.hs view
@@ -39,6 +39,7 @@ import Data.Binary.Put import Data.ByteString (ByteString) import qualified Data.ByteString.Lazy as L+import Control.Applicative ((<$>)) import Control.Monad.Error import Data.Word import Data.Bits@@ -61,10 +62,10 @@ runGet f b = Bin.runGet (runErrorT (runGE f)) b  remaining :: Get Int-remaining = fmap fromIntegral $ liftGet Bin.remaining+remaining = fromIntegral <$> liftGet Bin.remaining  bytesRead :: Get Int-bytesRead = fmap fromIntegral $ liftGet Bin.bytesRead+bytesRead = fromIntegral <$> liftGet Bin.bytesRead  getWord8 :: Get Word8 getWord8 = liftGet Bin.getWord8@@ -80,9 +81,9 @@  getWord24 :: Get Int getWord24 = do-	a <- fmap fromIntegral getWord8-	b <- fmap fromIntegral getWord8-	c <- fmap fromIntegral getWord8+	a <- fromIntegral <$> getWord8+	b <- fromIntegral <$> getWord8+	c <- fromIntegral <$> getWord8 	return $ (a `shiftL` 16) .|. (b `shiftL` 8) .|. c  getBytes :: Int -> Get ByteString
Stunnel.hs view
@@ -1,29 +1,36 @@ import Network import System.IO import System+ import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as L import qualified Data.ByteString.Lazy.Char8 as LC +import Control.Applicative ((<$>))+import Control.Concurrent (forkIO) import Control.Exception (bracket)-import Network.TLS.Cipher-import qualified Network.TLS.Client as C-import qualified Network.TLS.Server as S-import Network.TLS.SRandom-import Network.TLS.Struct-import Network.TLS.MAC+import Control.Monad (forM_, when, replicateM)+import Control.Monad.Trans (lift)+ import Data.Word import Data.Bits import Data.Maybe-import Control.Monad (forM_, when, replicateM)-import Control.Monad.Trans (lift)-import Random-import qualified Codec.Crypto.AES.Random as AESRand-import Control.Concurrent (forkIO)+ import Data.Certificate.PEM import Data.Certificate.X509 import Data.Certificate.Key +import Network.TLS.Cipher+import Network.TLS.SRandom+import Network.TLS.Struct+import Network.TLS.MAC++import qualified Network.TLS.Client as C+import qualified Network.TLS.Server as S++import Random+import qualified Codec.Crypto.AES.Random as AESRand+ ciphers :: [Cipher] ciphers = 	[ cipher_AES128_SHA1@@ -52,13 +59,13 @@ mainClient :: String -> Int -> IO () mainClient host port = do 	{- generate some random stuff ready to be used after skipping some byte for no particular reason -}-	ranByte <- fmap B.head $ AESRand.randBytes 1+	ranByte <- B.head <$> AESRand.randBytes 1 	_ <- AESRand.randBytes (fromIntegral ranByte)-	clientRandom <- fmap (fromJust . clientRandom . B.unpack) $ AESRand.randBytes 32-	premasterRandom <- fmap B.unpack $ AESRand.randBytes 46-	seqInit <- fmap (conv . B.unpack) $ AESRand.randBytes 4+	clientRandom <- fromJust . clientRandom . B.unpack <$> AESRand.randBytes 32+	premasterRandom <- (ClientKeyData . B.unpack) <$> AESRand.randBytes 46+	seqInit <- conv . B.unpack <$> AESRand.randBytes 4 -	handle <- connectTo host (PortNumber 6061)+	handle <- connectTo host (PortNumber $ fromIntegral port) 	hSetBuffering handle NoBuffering  	let clientstate = C.TLSClientParams@@ -67,6 +74,9 @@ 		, C.cpSession = Nothing 		, C.cpCiphers = ciphers 		, C.cpCertificate = Nothing+		, C.cpCallbacks = C.TLSClientCallbacks+			{ C.cbCertificates = Nothing+			} 		} 	C.runTLSClient (tlsclient handle clientRandom premasterRandom) clientstate (makeSRandomGen seqInit) @@ -80,8 +90,8 @@ 	lift $ putStrLn "end"  clientProcess ((certdata, cert), pk) (handle, src) = do-	serverRandom <- fmap (fromJust . serverRandom . B.unpack) $ AESRand.randBytes 32-	seqInit <- fmap (conv . B.unpack) $ AESRand.randBytes 4+	serverRandom <- fromJust . serverRandom . B.unpack <$> AESRand.randBytes 32+	seqInit <- conv . B.unpack <$> AESRand.randBytes 4  	let serverstate = S.TLSServerParams 		{ S.spAllowedVersions = [TLS10]@@ -89,6 +99,8 @@ 		, S.spCiphers = ciphers 		, S.spCertificate = Just (certdata, cert, pk) 		, S.spWantClientCert = False+		, S.spCallbacks = S.TLSServerCallbacks+			{ S.cbCertificates = Nothing } 		}  	S.runTLSServer (tlsserver handle serverRandom) serverstate (makeSRandomGen seqInit)
TODO view
@@ -4,7 +4,6 @@ - implement Certificate Verify / Certificate Request - add Client Certificates - add check for non-self signed certificate-- don't fail straight away if clientkeyxchg failed. required for security - alert correctly on errors - process session as they should - put 4 bytes of time in client/server random
Tests.hs view
@@ -45,6 +45,9 @@ instance Arbitrary ServerRandom where 	arbitrary = ServerRandom `fmap` someWords8 32 +instance Arbitrary ClientKeyData where+	arbitrary = ClientKeyData `fmap` someWords8 46+ instance Arbitrary Session where 	arbitrary = do 		i <- choose (1,2) :: Gen Int@@ -58,12 +61,25 @@ arbitraryCompressionIDs :: Gen [Word8] arbitraryCompressionIDs = choose (0,200) >>= someWords8 +instance Arbitrary CertificateType where+	arbitrary = elements+		[ CertificateType_RSA_Sign, CertificateType_DSS_Sign+		, CertificateType_RSA_Fixed_DH, CertificateType_DSS_Fixed_DH+		, CertificateType_RSA_Ephemeral_dh, CertificateType_DSS_Ephemeral_dh+		, CertificateType_fortezza_dms ]+ instance Arbitrary Handshake where 	arbitrary = oneof 		[ liftM6 ClientHello arbitrary arbitrary arbitrary arbitraryCiphersIDs arbitraryCompressionIDs (return Nothing) 		, liftM6 ServerHello arbitrary arbitrary arbitrary arbitrary arbitrary (return Nothing)+		, return (Certificates []) 		, return HelloRequest 		, return ServerHelloDone+		, liftM2 ClientKeyXchg arbitrary arbitrary+		--, liftM  ServerKeyXchg+		--, liftM3 CertRequest arbitrary (return Nothing) (return [])+		--, liftM CertVerify (return [])+		, liftM Finished (someWords8 12) 		]  {- quickcheck property -}
tls.cabal view
@@ -1,5 +1,5 @@ Name:                tls-Version:             0.1.1+Version:             0.1.2 Description:    Implementation of the TLS protocol, focusing on purity and more type-checking.    .@@ -39,15 +39,15 @@   Exposed-modules:   Network.TLS.Client                      Network.TLS.Server                      Network.TLS.Struct-  other-modules:     Network.TLS.Cipher-                     Network.TLS.Compression-                     Network.TLS.Crypto+                     Network.TLS.Cipher+                     Network.TLS.SRandom                      Network.TLS.MAC+  other-modules:     Network.TLS.Compression+                     Network.TLS.Crypto                      Network.TLS.Packet                      Network.TLS.State                      Network.TLS.Sending                      Network.TLS.Receiving-                     Network.TLS.SRandom                      Network.TLS.Wire   ghc-options:       -Wall