diff --git a/Examples/CheckCiphers.hs b/Examples/CheckCiphers.hs
--- a/Examples/CheckCiphers.hs
+++ b/Examples/CheckCiphers.hs
@@ -66,14 +66,19 @@
 fakeCipher cid = Cipher
 	{ cipherID           = cid
 	, cipherName         = "cipher-" ++ show cid
-	, cipherDigestSize   = 0
-	, cipherKeySize      = 0
-	, cipherIVSize       = 0
-	, cipherKeyBlockSize = 0
-	, cipherPaddingSize  = 0
+	, cipherBulk         = Bulk
+		{ bulkName         = "fake"
+		, bulkKeySize      = 0
+		, bulkIVSize       = 0
+		, bulkBlockSize    = 0
+		, bulkF            = undefined
+		}
 	, cipherKeyExchange  = CipherKeyExchange_RSA
-	, cipherMACHash      = (\_ -> undefined)
-	, cipherF            = undefined
+	, cipherHash         = Hash
+		{ hashName = "fake"
+		, hashSize = 0
+		, hashF    = undefined
+		}
 	, cipherMinVer       = Nothing
 	}
 
diff --git a/Examples/Stunnel.hs b/Examples/Stunnel.hs
--- a/Examples/Stunnel.hs
+++ b/Examples/Stunnel.hs
@@ -41,7 +41,7 @@
 		Right True  -> B.hGetNonBlocking h 4096
 		Right False -> return B.empty
 
-tlsclient :: Handle -> TLSCtx -> IO ()
+tlsclient :: Handle -> TLSCtx Handle -> IO ()
 tlsclient srchandle dsthandle = do
 	hSetBuffering srchandle NoBuffering
 
@@ -76,7 +76,7 @@
 		d <- recvData srchandle
 		putStrLn ("received: " ++ show d)
 		sendData srchandle (L.pack $ map (toEnum . fromEnum) "this is some data")
-		hFlush (ctxHandle srchandle)
+		hFlush (ctxConnection srchandle)
 		return False
 	putStrLn "end"
 
@@ -88,7 +88,7 @@
 		}
 
 	let serverstate = defaultParams
-		{ pAllowedVersions = [SSL3,TLS10,TLS11]
+		{ pAllowedVersions = [SSL3,TLS10,TLS11,TLS12]
 		, pCiphers         = ciphers
 		, pCertificates    = certs
 		, pWantClientCert  = False
@@ -229,7 +229,7 @@
 	let crecv = if validCert pargs then certificateVerifyChain else (\_ -> return CertificateUsageAccept)
 	let clientstate = defaultParams
 		{ pConnectVersion = TLS10
-		, pAllowedVersions = [ TLS10, TLS11 ]
+		, pAllowedVersions = [TLS10,TLS11,TLS12]
 		, pCiphers = ciphers
 		, pCertificates = []
 		, pLogging = logging
diff --git a/Network/TLS/Extra/Certificate.hs b/Network/TLS/Extra/Certificate.hs
--- a/Network/TLS/Extra/Certificate.hs
+++ b/Network/TLS/Extra/Certificate.hs
@@ -28,7 +28,7 @@
 import qualified Crypto.Cipher.RSA as RSA
 import qualified Crypto.Cipher.DSA as DSA
 
-import Data.Certificate.X509Cert (oidCommonName)
+import Data.Certificate.X509.Cert (oidCommonName)
 import Network.TLS (TLSCertificateUsage(..), TLSCertificateRejectReason(..))
 
 import Data.Time.Calendar
@@ -121,18 +121,17 @@
 --   md2WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 2 }
 --   md4WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 3 }
 --   md5WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 4 }
-verifyF SignatureALG_md2WithRSAEncryption (PubKeyRSA rsak) = rsaVerify MD2.hash asn1 (mkRSA rsak)
+verifyF (SignatureALG HashMD2 PubKeyALG_RSA) (PubKeyRSA rsak) = rsaVerify MD2.hash asn1 (mkRSA rsak)
 	where asn1 = "\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05\x05\x00\x02\x10"
 
-verifyF SignatureALG_md5WithRSAEncryption (PubKeyRSA rsak) = rsaVerify MD5.hash asn1 (mkRSA rsak)
+verifyF (SignatureALG HashMD5 PubKeyALG_RSA) (PubKeyRSA rsak) = rsaVerify MD5.hash asn1 (mkRSA rsak)
 	where asn1 = "\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05\x05\x00\x04\x10"
 
-verifyF SignatureALG_sha1WithRSAEncryption (PubKeyRSA rsak) = rsaVerify SHA1.hash asn1 (mkRSA rsak)
+verifyF (SignatureALG HashSHA1 PubKeyALG_RSA) (PubKeyRSA rsak) = rsaVerify SHA1.hash asn1 (mkRSA rsak)
 	where asn1 = "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14"
 
-verifyF SignatureALG_dsaWithSHA1 (PubKeyDSA (pub,p,q,g)) = dsaSHA1Verify pk
-	where
-		pk        = DSA.PublicKey { DSA.public_params = (p,g,q), DSA.public_y = pub }
+verifyF (SignatureALG HashSHA1 PubKeyALG_DSA) (PubKeyDSA (pub,p,q,g)) = dsaSHA1Verify pk
+	where pk = DSA.PublicKey { DSA.public_params = (p,g,q), DSA.public_y = pub }
 			
 verifyF _ _ = (\_ _ -> Left "unexpected/wrong signature")
 
diff --git a/Network/TLS/Extra/Cipher.hs b/Network/TLS/Extra/Cipher.hs
--- a/Network/TLS/Extra/Cipher.hs
+++ b/Network/TLS/Extra/Cipher.hs
@@ -92,19 +92,70 @@
 ciphersuite_unencrypted :: [Cipher]
 ciphersuite_unencrypted = [cipher_null_MD5, cipher_null_SHA1]
 
+bulk_null = Bulk
+	{ bulkName         = "null"
+	, bulkKeySize      = 0
+	, bulkIVSize       = 0
+	, bulkBlockSize    = 0
+	, bulkF            = BulkNoneF
+	}
+
+bulk_rc4 = Bulk
+	{ bulkName         = "RC4-128"
+	, bulkKeySize      = 16
+	, bulkIVSize       = 0
+	, bulkBlockSize    = 0
+	, bulkF            = BulkStreamF initF_rc4 encryptF_rc4 decryptF_rc4
+	}
+
+bulk_aes128 = Bulk
+	{ bulkName         = "AES128"
+	, bulkKeySize      = 16
+	, bulkIVSize       = 16
+	, bulkBlockSize    = 16
+	, bulkF            = BulkBlockF aes128_cbc_encrypt aes128_cbc_decrypt
+	}
+
+bulk_aes256 = Bulk
+	{ bulkName         = "AES256"
+	, bulkKeySize      = 32
+	, bulkIVSize       = 16
+	, bulkBlockSize    = 16
+	, bulkF            = BulkBlockF aes256_cbc_encrypt aes256_cbc_decrypt
+	}
+
+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
+	}
+
+hash_null = Hash
+	{ hashName = "null"
+	, hashSize = 0
+	, hashF    = const B.empty
+	}
+
 -- | this is not stricly a usable cipher; it's the initial cipher of a TLS connection
 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)
+	, cipherBulk         = bulk_null
+	, cipherHash         = hash_null
 	, cipherKeyExchange  = CipherKeyExchange_RSA
-	, cipherF            = CipherNoneF
 	, cipherMinVer       = Nothing
 	}
 
@@ -113,14 +164,9 @@
 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
+	, cipherBulk         = bulk_null
+	, cipherHash         = hash_md5
 	, cipherKeyExchange  = CipherKeyExchange_RSA
-	, cipherF            = CipherNoneF
 	, cipherMinVer       = Nothing
 	}
 
@@ -129,14 +175,9 @@
 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
+	, cipherBulk         = bulk_null
+	, cipherHash         = hash_sha1
 	, cipherKeyExchange  = CipherKeyExchange_RSA
-	, cipherF            = CipherNoneF
 	, cipherMinVer       = Nothing
 	}
 
@@ -145,14 +186,9 @@
 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
+	, cipherBulk         = bulk_rc4
+	, cipherHash         = hash_md5
 	, cipherKeyExchange  = CipherKeyExchange_RSA
-	, cipherF            = CipherStreamF initF_rc4 encryptF_rc4 decryptF_rc4
 	, cipherMinVer       = Nothing
 	}
 
@@ -161,14 +197,9 @@
 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
+	, cipherBulk         = bulk_rc4
+	, cipherHash         = hash_sha1
 	, cipherKeyExchange  = CipherKeyExchange_RSA
-	, cipherF            = CipherStreamF initF_rc4 encryptF_rc4 decryptF_rc4
 	, cipherMinVer       = Nothing
 	}
 
@@ -177,14 +208,9 @@
 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
+	, cipherBulk         = bulk_aes128
+	, cipherHash         = hash_sha1
 	, cipherKeyExchange  = CipherKeyExchange_RSA
-	, cipherF            = CipherBlockF aes128_cbc_encrypt aes128_cbc_decrypt
 	, cipherMinVer       = Just SSL3
 	}
 
@@ -193,14 +219,9 @@
 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
+	, cipherBulk         = bulk_aes256
+	, cipherHash         = hash_sha1
 	, cipherKeyExchange  = CipherKeyExchange_RSA
-	, cipherF            = CipherBlockF aes256_cbc_encrypt aes256_cbc_decrypt
 	, cipherMinVer       = Just SSL3
 	}
 
@@ -209,14 +230,9 @@
 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
+	, cipherBulk         = bulk_aes128
+	, cipherHash         = hash_sha256
 	, cipherKeyExchange  = CipherKeyExchange_RSA
-	, cipherF            = CipherBlockF aes128_cbc_encrypt aes128_cbc_decrypt
 	, cipherMinVer       = Just TLS12
 	}
 
@@ -225,14 +241,9 @@
 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
+	, cipherBulk         = bulk_aes256
+	, cipherHash         = hash_sha256
 	, cipherKeyExchange  = CipherKeyExchange_RSA
-	, cipherF            = CipherBlockF aes256_cbc_encrypt aes256_cbc_decrypt
 	, cipherMinVer       = Just TLS12
 	}
 
diff --git a/Network/TLS/Extra/Connection.hs b/Network/TLS/Extra/Connection.hs
--- a/Network/TLS/Extra/Connection.hs
+++ b/Network/TLS/Extra/Connection.hs
@@ -22,7 +22,7 @@
 
 -- | open a TCP client connection to a destination and port description (number or name)
 -- 
-connectionClient :: CryptoRandomGen g => String -> String -> TLSParams -> g -> IO TLSCtx
+connectionClient :: CryptoRandomGen g => String -> String -> TLSParams -> g -> IO (TLSCtx Handle)
 connectionClient s p params rng = do
 	pn <- if and $ map isDigit $ p
 		then return $ fromIntegral $ (read p :: Int)
diff --git a/tls-extra.cabal b/tls-extra.cabal
--- a/tls-extra.cabal
+++ b/tls-extra.cabal
@@ -1,5 +1,5 @@
 Name:                tls-extra
-Version:             0.3.1
+Version:             0.4.0
 Description:
    a set of extra definitions, default values and helpers for tls.
 License:             BSD3
@@ -28,7 +28,7 @@
 
 Library
   Build-Depends:     base > 3 && < 5
-                   , tls >= 0.7 && < 0.8
+                   , tls >= 0.8 && < 0.9
                    , mtl
                    , network >= 2.3
                    , cryptohash >= 0.6
@@ -36,7 +36,7 @@
                    , vector
                    , crypto-api >= 0.5
                    , cryptocipher >= 0.2.5
-                   , certificate >= 0.9 && < 1.0
+                   , certificate >= 0.9.3 && < 1.0
                    , text >= 0.5 && < 1.0
                    , time
   Exposed-modules:   Network.TLS.Extra
