diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,74 @@
+# Changelog for http-client-tls
+
+## 0.4.0
+
+* For MD5 hashes in Base16 format, depend on packages `cryptohash-md5` and
+  `base16` rather than `crypton` and `memory` (the latter is unmaintained).
+
+## 0.3.6.4
+
+* data-default-class -> data-default [#546](https://github.com/snoyberg/http-client/pull/546/files)
+
+## 0.3.6.3
+
+* catching up to tls 1.8.0 [#515](https://github.com/snoyberg/http-client/pull/515)
+
+## 0.3.6.2
+
+* Migrate to `crypton`
+
+## 0.3.6.1
+
+* [#482](https://github.com/snoyberg/http-client/issues/482):
+  Raise lower bound on `http-client` to fix build.
+
+## 0.3.6
+
+* Allow making requests to raw IPv6 hosts [#477](https://github.com/snoyberg/http-client/pull/477)
+
+## 0.3.5.3
+
+* Fix `newTlsManager` [#325](https://github.com/snoyberg/http-client/issues/325)
+
+## 0.3.5.2
+
+* [#289](https://github.com/snoyberg/http-client/issues/289):
+  Keep original `TLSSettings` when creating a `Manager` using `newTlsManagerWith`.
+
+## 0.3.5.1
+
+* Also catch TLSError exceptions [#273](https://github.com/snoyberg/http-client/pull/273)
+
+## 0.3.5
+
+* Add `newTlsManagerWith`
+  [#278](https://github.com/snoyberg/http-client/issues/278), which
+  provides a variant of `newTlsManager` that takes a `ManagerSettings`
+  to base its settings off of.
+
+## 0.3.4.2
+
+* Never throw exceptions on 401 status in `applyDigestAuth`
+
+## 0.3.4.1
+
+* Better exception cleanup behavior
+
+## 0.3.4
+
+* Add 'newTlsManager'
+  [#263](https://github.com/snoyberg/http-client/issues/263), which adds
+  support for respecting `socks5://` and `socks5h://` `http_proxy` and
+  `https_proxy` environment variables.
+
+## 0.3.3.2
+
+* Better handling of internal exceptions
+
+## 0.3.3.1
+
+* Better exception safety via `bracketOnError`
+
 ## 0.3.3
 
 * Add `DigestAuthException` and generalize `applyDigestAuth`
diff --git a/Network/HTTP/Client/TLS.hs b/Network/HTTP/Client/TLS.hs
--- a/Network/HTTP/Client/TLS.hs
+++ b/Network/HTTP/Client/TLS.hs
@@ -11,6 +11,8 @@
       tlsManagerSettings
     , mkManagerSettings
     , mkManagerSettingsContext
+    , newTlsManager
+    , newTlsManagerWith
       -- * Digest authentication
     , applyDigestAuth
     , DigestAuthException (..)
@@ -21,7 +23,10 @@
     , setGlobalManager
     ) where
 
-import Data.Default.Class
+import Control.Applicative ((<|>))
+import Control.Arrow (first)
+import System.Environment (getEnvironment)
+import Data.Default
 import Network.HTTP.Client hiding (host, port)
 import Network.HTTP.Client.Internal hiding (host, port)
 import Control.Exception
@@ -36,11 +41,16 @@
 import qualified Data.CaseInsensitive as CI
 import Data.Maybe (fromMaybe, isJust)
 import Network.HTTP.Types (status401)
-import Crypto.Hash (hash, Digest, MD5)
+import qualified Crypto.Hash.MD5 as MD5
 import Control.Arrow ((***))
-import Data.ByteArray.Encoding (convertToBase, Base (Base16))
+import Data.Base16.Types (extractBase16)
+import Data.ByteString.Base16 (encodeBase16')
 import Data.Typeable (Typeable)
 import Control.Monad.Catch (MonadThrow, throwM)
+import qualified Data.Map as Map
+import qualified Data.Text as T
+import Data.Text.Read (decimal)
+import qualified Network.URI as U
 
 -- | Create a TLS-enabled 'ManagerSettings' with the given 'NC.TLSSettings' and
 -- 'NC.SockSettings'
@@ -62,27 +72,43 @@
     -> NC.TLSSettings
     -> Maybe NC.SockSettings
     -> ManagerSettings
-mkManagerSettingsContext mcontext tls sock = defaultManagerSettings
-    { managerTlsConnection = getTlsConnection mcontext (Just tls) sock
-    , managerTlsProxyConnection = getTlsProxyConnection mcontext tls sock
+mkManagerSettingsContext mcontext tls sock = mkManagerSettingsContext' defaultManagerSettings mcontext tls sock sock
+
+-- | Internal, allow different SockSettings for HTTP and HTTPS
+mkManagerSettingsContext'
+    :: ManagerSettings
+    -> Maybe NC.ConnectionContext
+    -> NC.TLSSettings
+    -> Maybe NC.SockSettings -- ^ insecure
+    -> Maybe NC.SockSettings -- ^ secure
+    -> ManagerSettings
+mkManagerSettingsContext' set mcontext tls sockHTTP sockHTTPS = set
+    { managerTlsConnection = getTlsConnection mcontext (Just tls) sockHTTPS
+    , managerTlsProxyConnection = getTlsProxyConnection mcontext tls sockHTTPS
     , managerRawConnection =
-        case sock of
+        case sockHTTP of
             Nothing -> managerRawConnection defaultManagerSettings
-            Just _ -> getTlsConnection mcontext Nothing sock
+            Just _ -> getTlsConnection mcontext Nothing sockHTTP
     , managerRetryableException = \e ->
         case () of
             ()
+#if MIN_VERSION_tls(1,8,0)
+                | ((fromException e)::(Maybe TLS.TLSException))==Just (TLS.PostHandshake TLS.Error_EOF) -> True
+#else
                 | ((fromException e)::(Maybe TLS.TLSError))==Just TLS.Error_EOF -> True
+#endif
                 | otherwise -> managerRetryableException defaultManagerSettings e
     , managerWrapException = \req ->
-        let wrapper se =
-                case fromException se of
-                    Just (_ :: IOException) -> se'
-                    Nothing -> case fromException se of
-                      Just TLS.Terminated{} -> se'
-                      Just TLS.HandshakeFailed{} -> se'
-                      Just TLS.ConnectionNotEstablished -> se'
-                      _ -> se
+        let wrapper se
+              | Just (_ :: IOException)          <- fromException se = se'
+              | Just (_ :: TLS.TLSException)     <- fromException se = se'
+#if !MIN_VERSION_tls(1,8,0)
+              | Just (_ :: TLS.TLSError)         <- fromException se = se'
+#endif
+              | Just (_ :: NC.LineTooLong)       <- fromException se = se'
+              | Just (_ :: NC.HostNotResolved)   <- fromException se = se'
+              | Just (_ :: NC.HostCannotConnect) <- fromException se = se'
+              | otherwise = se
               where
                 se' = toException $ HttpExceptionRequest req $ InternalException se
          in handle $ throwIO . wrapper
@@ -98,14 +124,15 @@
                  -> IO (Maybe HostAddress -> String -> Int -> IO Connection)
 getTlsConnection mcontext tls sock = do
     context <- maybe NC.initConnectionContext return mcontext
-    return $ \_ha host port -> do
-        conn <- NC.connectTo context NC.ConnectionParams
-            { NC.connectionHostname = host
+    return $ \_ha host port -> bracketOnError
+        (NC.connectTo context NC.ConnectionParams
+            { NC.connectionHostname = strippedHostName host
             , NC.connectionPort = fromIntegral port
             , NC.connectionUseSecure = tls
             , NC.connectionUseSocks = sock
-            }
-        convertConnection conn
+            })
+        NC.connectionClose
+        convertConnection
 
 getTlsProxyConnection
     :: Maybe NC.ConnectionContext
@@ -114,26 +141,26 @@
     -> IO (S.ByteString -> (Connection -> IO ()) -> String -> Maybe HostAddress -> String -> Int -> IO Connection)
 getTlsProxyConnection mcontext tls sock = do
     context <- maybe NC.initConnectionContext return mcontext
-    return $ \connstr checkConn serverName _ha host port -> do
-        --error $ show (connstr, host, port)
-        conn <- NC.connectTo context NC.ConnectionParams
-            { NC.connectionHostname = serverName
+    return $ \connstr checkConn serverName _ha host port -> bracketOnError
+        (NC.connectTo context NC.ConnectionParams
+            { NC.connectionHostname = strippedHostName serverName
             , NC.connectionPort = fromIntegral port
             , NC.connectionUseSecure = Nothing
             , NC.connectionUseSocks =
                 case sock of
                     Just _ -> error "Cannot use SOCKS and TLS proxying together"
-                    Nothing -> Just $ NC.OtherProxy host $ fromIntegral port
-            }
-
-        NC.connectionPut conn connstr
-        conn' <- convertConnection conn
+                    Nothing -> Just $ NC.OtherProxy (strippedHostName host) $ fromIntegral port
+            })
+        NC.connectionClose
+        $ \conn -> do
+            NC.connectionPut conn connstr
+            conn' <- convertConnection conn
 
-        checkConn conn'
+            checkConn conn'
 
-        NC.connectionSetSecure context conn tls
+            NC.connectionSetSecure context conn tls
 
-        return conn'
+            return conn'
 
 convertConnection :: NC.Connection -> IO Connection
 convertConnection conn = makeConnection
@@ -144,18 +171,84 @@
     -- already closed, and we get a @ResourceVanished@.
     (NC.connectionClose conn `Control.Exception.catch` \(_ :: IOException) -> return ())
 
+-- We may decide in the future to just have a global
+-- ConnectionContext and use it directly in tlsManagerSettings, at
+-- which point this can again be a simple (newManager
+-- tlsManagerSettings >>= newIORef). See:
+-- https://github.com/snoyberg/http-client/pull/227.
+globalConnectionContext :: NC.ConnectionContext
+globalConnectionContext = unsafePerformIO NC.initConnectionContext
+{-# NOINLINE globalConnectionContext #-}
+
+-- | Load up a new TLS manager with default settings, respecting proxy
+-- environment variables.
+--
+-- @since 0.3.4
+newTlsManager :: MonadIO m => m Manager
+newTlsManager = liftIO $ do
+    env <- getEnvironment
+    let lenv = Map.fromList $ map (first $ T.toLower . T.pack) env
+        msocksHTTP = parseSocksSettings env lenv "http_proxy"
+        msocksHTTPS = parseSocksSettings env lenv "https_proxy"
+        settings = mkManagerSettingsContext' defaultManagerSettings (Just globalConnectionContext) def msocksHTTP msocksHTTPS
+        settings' = maybe id (const $ managerSetInsecureProxy proxyFromRequest) msocksHTTP
+                  $ maybe id (const $ managerSetSecureProxy proxyFromRequest) msocksHTTPS
+                    settings
+    newManager settings'
+
+-- | Load up a new TLS manager based upon specified settings,
+-- respecting proxy environment variables.
+--
+-- @since 0.3.5
+newTlsManagerWith :: MonadIO m => ManagerSettings -> m Manager
+newTlsManagerWith set = liftIO $ do
+    env <- getEnvironment
+    let lenv = Map.fromList $ map (first $ T.toLower . T.pack) env
+        msocksHTTP = parseSocksSettings env lenv "http_proxy"
+        msocksHTTPS = parseSocksSettings env lenv "https_proxy"
+        settings = mkManagerSettingsContext' set (Just globalConnectionContext) def msocksHTTP msocksHTTPS
+        settings' = maybe id (const $ managerSetInsecureProxy proxyFromRequest) msocksHTTP
+                  $ maybe id (const $ managerSetSecureProxy proxyFromRequest) msocksHTTPS
+                    settings
+                        -- We want to keep the original TLS settings that were
+                        -- passed in. Sadly they aren't available as a record
+                        -- field on `ManagerSettings`. So instead we grab the
+                        -- fields that depend on the TLS settings.
+                        -- https://github.com/snoyberg/http-client/issues/289
+                        { managerTlsConnection = managerTlsConnection set
+                        , managerTlsProxyConnection = managerTlsProxyConnection set
+                        }
+    newManager settings'
+
+parseSocksSettings :: [(String, String)] -- ^ original environment
+                   -> Map.Map T.Text String -- ^ lower-cased keys
+                   -> T.Text -- ^ env name
+                   -> Maybe NC.SockSettings
+parseSocksSettings env lenv n = do
+  str <- lookup (T.unpack n) env <|> Map.lookup n lenv
+  let allowedScheme x = x == "socks5:" || x == "socks5h:"
+  uri <- U.parseURI str
+
+  guard $ allowedScheme $ U.uriScheme uri
+  guard $ null (U.uriPath uri) || U.uriPath uri == "/"
+  guard $ null $ U.uriQuery uri
+  guard $ null $ U.uriFragment uri
+
+  auth <- U.uriAuthority uri
+  port' <-
+      case U.uriPort auth of
+          "" -> Nothing -- should we use some default?
+          ':':rest ->
+              case decimal $ T.pack rest of
+                  Right (p, "") -> Just p
+                  _ -> Nothing
+          _ -> Nothing
+
+  Just $ NC.SockSettingsSimple (U.uriRegName auth) port'
+
 -- | Evil global manager, to make life easier for the common use case
 globalManager :: IORef Manager
-globalManager = unsafePerformIO $ do
-    -- We may decide in the future to just have a global
-    -- ConnectionContext and use it directly in tlsManagerSettings, at
-    -- which point this can again be a simple (newManager
-    -- tlsManagerSettings >>= newIORef). See:
-    -- https://github.com/snoyberg/http-client/pull/227.
-    context <- NC.initConnectionContext
-    let settings = mkManagerSettingsContext (Just context) def Nothing
-    manager <- newManager settings
-    newIORef manager
+globalManager = unsafePerformIO $ newTlsManager >>= newIORef
 {-# NOINLINE globalManager #-}
 
 -- | Get the current global 'Manager'
@@ -238,7 +331,7 @@
                 -> Request
                 -> Manager
                 -> m (n Request)
-applyDigestAuth user pass req man = liftIO $ do
+applyDigestAuth user pass req0 man = liftIO $ do
     res <- httpNoBody req man
     let throw' = throwM . DigestAuthException req res
     return $ do
@@ -269,7 +362,7 @@
                 -- we always use no qop or qop=auth
                 ha2 = md5 $ S.concat [method req, ":", path req]
 
-                md5 bs = convertToBase Base16 (hash bs :: Digest MD5)
+                md5 = extractBase16 . encodeBase16' . MD5.hash
             key = "Authorization"
             val = S.concat
                 [ "Digest username=\""
@@ -299,6 +392,10 @@
             , cookieJar = Just $ responseCookieJar res
             }
   where
+    -- Since we're expecting a non-200 response, ensure we do not
+    -- throw exceptions for such responses.
+    req = req0 { checkResponse = \_ _ -> return () }
+
     stripCI x y
         | CI.mk x == CI.mk (S.take len y) = Just $ S.drop len y
         | otherwise = Nothing
diff --git a/bench/Bench.hs b/bench/Bench.hs
--- a/bench/Bench.hs
+++ b/bench/Bench.hs
@@ -1,6 +1,11 @@
+{-# LANGUAGE CPP #-}
 module Main where
 
-import Criterion.Main
+#if MIN_VERSION_gauge(0, 2, 0)
+import Gauge
+#else
+import Gauge.Main
+#endif
 import Network.HTTP.Client
 import Network.HTTP.Client.TLS
 
diff --git a/http-client-tls.cabal b/http-client-tls.cabal
--- a/http-client-tls.cabal
+++ b/http-client-tls.cabal
@@ -1,5 +1,5 @@
 name:                http-client-tls
-version:             0.3.3
+version:             0.4.0
 synopsis:            http-client backend using the connection package and tls library
 description:         Hackage documentation generation is not reliable. For up to date documentation, please see: <https://www.stackage.org/package/http-client-tls>.
 homepage:            https://github.com/snoyberg/http-client
@@ -16,19 +16,22 @@
 library
   exposed-modules:     Network.HTTP.Client.TLS
   other-extensions:    ScopedTypeVariables
-  build-depends:       base >= 4 && < 5
-                     , data-default-class
-                     , http-client >= 0.5.0
-                     , connection >= 0.2.2
+  build-depends:       base >= 4.10 && < 5
+                     , base16 >= 1.0
+                     , cryptohash-md5
+                     , data-default
+                     , http-client >= 0.7.11
+                     , crypton-connection
                      , network
-                     , tls >= 1.2
+                     , tls >= 2.1.2
                      , bytestring
                      , case-insensitive
                      , transformers
                      , http-types
-                     , cryptonite
-                     , memory
                      , exceptions
+                     , containers
+                     , text
+                     , network-uri
   default-language:    Haskell2010
   ghc-options:         -Wall
 
@@ -42,6 +45,9 @@
                      , http-client
                      , http-client-tls
                      , http-types
+                     , crypton-connection
+                     , data-default
+                     , tls
 
 benchmark benchmark
   main-is:             Bench.hs
@@ -49,6 +55,6 @@
   hs-source-dirs:      bench
   default-language:    Haskell2010
   build-depends:       base
-                     , criterion
+                     , gauge
                      , http-client
                      , http-client-tls
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -1,12 +1,28 @@
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE OverloadedStrings #-}
 import Test.Hspec
+import Network.Connection
 import Network.HTTP.Client
-import Network.HTTP.Client.TLS
+import Network.HTTP.Client.TLS hiding (tlsManagerSettings)
 import Network.HTTP.Types
 import Control.Monad (join)
+import Data.Default
+import qualified Network.TLS as TLS
 
 main :: IO ()
 main = hspec $ do
+    let tlsSettings = def
+    -- Since the release of v2.0.0 of the `tls` package , the default value of
+    -- the `supportedExtendedMainSecret` parameter `is `RequireEMS`, this means
+    -- that all the connections to a server not supporting TLS1.2+EMS will fail.
+    -- The badssl.com service does not yet support TLS1.2+EMS connections, so
+    -- let's switch to the value `AllowEMS`, ie: TLS1.2 conenctions without EMS.
+#if MIN_VERSION_crypton_connection(0,4,0)
+            {settingClientSupported = def {TLS.supportedExtendedMainSecret = TLS.AllowEMS}}
+#endif
+
+    let tlsManagerSettings = mkManagerSettings tlsSettings Nothing
+
     it "make a TLS connection" $ do
         manager <- newManager tlsManagerSettings
         withResponse "https://httpbin.org/status/418" manager $ \res ->
@@ -27,3 +43,45 @@
         join (applyDigestAuth "user" "passwd" "http://httpbin.org/" man)
             `shouldThrow` \(DigestAuthException _ _ det) ->
                 det == UnexpectedStatusCode
+
+    it "BadSSL: expired" $ do
+        manager <- newManager tlsManagerSettings
+        let action = withResponse "https://expired.badssl.com/" manager (const (return ()))
+        action `shouldThrow` anyException
+
+    it "BadSSL: self-signed" $ do
+        manager <- newManager tlsManagerSettings
+        let action = withResponse "https://self-signed.badssl.com/" manager (const (return ()))
+        action `shouldThrow` anyException
+
+    it "BadSSL: wrong.host" $ do
+        manager <- newManager tlsManagerSettings
+        let action = withResponse "https://wrong.host.badssl.com/" manager (const (return ()))
+        action `shouldThrow` anyException
+
+    it "BadSSL: we do have case-insensitivity though" $ do
+        manager <- newManager $ tlsManagerSettings
+        withResponse "https://BADSSL.COM" manager $ \res ->
+            responseStatus res `shouldBe` status200
+
+    -- https://github.com/snoyberg/http-client/issues/289
+    it "accepts TLS settings" $ do
+        let
+          tlsSettings' = tlsSettings
+            { settingDisableCertificateValidation = True
+            , settingDisableSession = False
+            , settingUseServerName = False
+            }
+          socketSettings = Nothing
+          managerSettings = mkManagerSettings tlsSettings' socketSettings
+        manager <- newTlsManagerWith managerSettings
+        let url = "https://wrong.host.badssl.com"
+        request <- parseRequest url
+        response <- httpNoBody request manager
+        responseStatus response `shouldBe` status200
+
+    it "global supports TLS" $ do
+        manager <- getGlobalManager
+        request <- parseRequest "https://httpbin.org"
+        response <- httpNoBody request manager
+        responseStatus response `shouldBe` status200
