packages feed

network-simple-tls 0.3.2 → 0.4

raw patch · 4 files changed

+245/−173 lines, 4 filesdep +tls-session-managerdep ~tls

Dependencies added: tls-session-manager

Dependency ranges changed: tls

Files

LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2013-2018, Renzo Carbonara <renλren.zone>+Copyright (c) 2013-2019, Renzo Carbonara <renλren.zone>  All rights reserved. 
changelog.md view
@@ -1,3 +1,39 @@+# Version 0.4++* COMPILER ASSISTED BREAKING CHANGE: `ClientSettings` and `ServerSettings` are+  gone.  Instead, `ClientParams` and `ServerParams` from the `tls` package are+  now used throughout.++  The related functions `updateClientParams`, `clientParams`,+  `updateServerParams`, `serverParams` are gone.++  `makeClientSettings` was renamed to `makeClientParams`, which returns+  `ClientParams` and takes `[Credential]` rather than `Credentials`.++  `makeServerSettings` was renamed to `makeServerParams`, which returns+  `ServerParams`.++  `getDefaultClientSettings` was replaced by `newDefaultClientParams`, which adds+  an in-memory `SessionManager` to the `ClientParams`.++* COMPILER ASSISTED BREAKING CHANGE: `Credentials` from `Network.TLS` is not+  re-exported anymore.++* Added `newDefaultServerParams`, which creates a `ServerParams` with an+  in-memory `SessionManager`.++* Re-export `ServerParams`, `ClientParams` from `Network.TLS`.++* Export `credentialLoadX509`, which is the same as+  `Network.TLS.credentialLoadX509` but runs in `MonadIO`.++* Support TLS 1.3, TLS 1.2 and TLS 1.1 by default.++* Bump version dependency on `tls` to `>= 1.5`.++* Add dependency on `tls-session-manager`.++ # Version 0.3.2  * Added `sendLazy`.
network-simple-tls.cabal view
@@ -1,5 +1,5 @@ name:                network-simple-tls-version:             0.3.2+version:             0.4 synopsis:            Simple interface to TLS secured network sockets. description:         Simple interface to TLS secured network sockets. homepage:            https://github.com/k0001/network-simple-tls@@ -8,7 +8,7 @@ license-file:        LICENSE author:              Renzo Carbonara maintainer:          renλren.zone-copyright:           Copyright (c) Renzo Carbonara 2013-2018+copyright:           Copyright (c) Renzo Carbonara 2013-2019 category:            Network build-type:          Simple cabal-version:       >=1.8@@ -27,7 +27,8 @@                    , network                    , network-simple >=0.4.3                    , safe-exceptions-                   , tls+                   , tls >=1.5+                   , tls-session-manager                    , transformers                    , x509                    , x509-store
src/Network/Simple/TCP/TLS.hs view
@@ -6,14 +6,15 @@ -- connections, relevant to both the client side and server side of the -- connection. ----- This module re-exports some functions from the "Network.Simple.TCP" module--- in the @network-simple@ package. Consider using that module directly if you--- need a similar API without TLS support.+-- This module re-exports some functions from the "Network.Simple.TCP" module in+-- the [network-simple](https://hackage.haskell.org/package/network-simple)+-- package. Consider using that module directly if you need a similar API+-- without TLS support. -- -- This module uses 'MonadIO' and 'E.MonadMask' extensively so that you can -- reuse these functions in monads other than 'IO'. However, if you don't care--- about any of that, just pretend you are using the 'IO' monad all the time--- and everything will work as expected.+-- about any of that, just pretend you are using the 'IO' monad all the time and+-- everything will work as expected.  module Network.Simple.TCP.TLS (   -- * Server side@@ -24,20 +25,15 @@   , accept   , acceptFork   -- ** Server TLS Settings-  , ServerSettings-  , makeServerSettings-  , updateServerParams-  , serverParams+  , newDefaultServerParams+  , makeServerParams    -- * Client side   , connect   , connectOverSOCKS5   -- ** Client TLS Settings-  , ClientSettings-  , makeClientSettings-  , getDefaultClientSettings-  , updateClientParams-  , clientParams+  , newDefaultClientParams+  , makeClientParams    -- * Utils   , recv@@ -54,15 +50,30 @@   , makeClientContext   , makeServerContext -  -- * Note to Windows users-  , NS.withSocketsDo-   -- * Re-exports   -- $reexports-  , module Network.Simple.TCP-  , module Network.Socket-  , module Network.TLS-  , T.Credentials+  , NS.withSocketsDo+  , S.HostPreference(..)+  , NS.HostName+  , NS.ServiceName+    -- | A service port like @"80"@ or its name @"www"@.+  , NS.Socket+  , NS.SockAddr+  , T.Context+  , T.ClientParams+    -- | Please refer to the "Network.TLS" module for more documentation on+    -- 'T.ClientParams`.+    --+    -- There's plenty to be changed, but the documentation for+    -- 'T.ClientParams' is not rendered inside "Network.Simple.TCP.TLS" module.+  , T.ServerParams+    -- | Please refer to the "Network.TLS" module for more documentation on+    -- 'T.ServerParams`.+    --+    -- There's plenty to be changed, but the documentation for+    -- 'T.ServerParams' is not rendered inside "Network.Simple.TCP.TLS" module.+  , T.Credential+  , credentialLoadX509   ) where  @@ -81,12 +92,10 @@ import           Foreign.C.Error (Errno(Errno), ePIPE) import qualified GHC.IO.Exception as Eg import qualified Network.Simple.TCP as S-import           Network.Simple.TCP (HostPreference(Host, HostAny, HostIPv4, HostIPv6))-import           Network.Socket (HostName, ServiceName, Socket, SockAddr) import qualified Network.Socket as NS import qualified Network.TLS as T-import           Network.TLS (Context)-import           Network.TLS.Extra as TE+import qualified Network.TLS.SessionManager as TSM+import qualified Network.TLS.Extra as TE import           System.X509 (getSystemCertificateStore)  --------------------------------------------------------------------------------@@ -97,53 +106,81 @@ -- For your convenience, this module module also re-exports the following types -- from other modules: ----- [From "Network.Socket"] 'HostName', 'ServiceName', 'Socket', 'SockAddr'.+-- [From "Network.Socket"] 'NS.HostName', 'NS.ServiceName', 'NS.Socket',+--   'NS.SockAddr', 'NS.withSocketsDo'. -- -- [From "Network.Simple.TCP"]---   @'HostPreference'('Host','HostAny','HostIPv4','HostIPv6')@.+--   @'S.HostPreference'('S.Host','S.HostAny','S.HostIPv4','S.HostIPv6')@. ----- [From "Network.TLS"] 'Context'.+-- [From "Network.TLS"] 'T.Context', 'T.Credential', 'T.ServerParams',+--   'T.ClientParams', 'credentialLoadX509'.  -------------------------------------------------------------------------------- -- Client side TLS settings --- | Abstract type representing the configuration settings for a TLS client.+-- | Obtain new default 'T.ClientParams' for a particular 'X.ServiceID'. ----- Use 'makeClientSettings' or 'getDefaultClientSettings' to obtain a--- 'ClientSettings' value.-data ClientSettings = ClientSettings { unClientSettings :: T.ClientParams }---- | Get the system default 'ClientSettings' for a particular 'X.ServiceID'.+-- * No client credentials sumbitted to the server. ----- Defaults: No client credentials, system certificate store.+-- * Use system-wide CA certificate store. ----- See 'makeClientSettings' to better understand the default settings used.-getDefaultClientSettings :: MonadIO m => X.ServiceID -> m ClientSettings-getDefaultClientSettings sid = liftIO $ do-  makeClientSettings sid (T.Credentials []) <$> getSystemCertificateStore-+-- * Use an in-memory TLS session manager from the+-- [tls-session-manager](https://hackage.haskell.org/package/tls-session-manager)+-- package.+--+-- * Everything else as proposed by 'makeClientParams'.+newDefaultClientParams+  :: MonadIO m+  => X.ServiceID+  -- ^+  -- @+  -- 'X.ServiceID' ~ ('S.HostName', 'B.ByteString')+  -- @+  --+  -- Identification of the connection consisting of the fully qualified host+  -- name for the server (e.g. www.example.com) and an optional suffix.+  --+  -- It is important that the hostname part is properly filled for security+  -- reasons, as it allow to properly associate the remote side with the given+  -- certificate during a handshake.+  --+  -- The suffix is used to identity a certificate per service on a specific+  -- host. For example, a same host might have different certificates on+  -- differents ports (443 and 995). For TCP connections, it's recommended+  -- to use: @:port@, or @:service@ for the blob (e.g., \@":443"@, @\":https"@).+  -> m T.ClientParams+newDefaultClientParams sid = liftIO $ do+  cs <- getSystemCertificateStore+  sm <- TSM.newSessionManager TSM.defaultConfig+  let cp0 = makeClientParams sid [] cs+  pure $ cp0+    { T.clientShared = (T.clientShared cp0)+        { T.sharedSessionManager = sm }+    } --- | Make defaults 'ClientSettings'.+-- | Make defaults 'T.ClientParams'. ----- Certificate chain validation is done by 'X.validateDefault' from the+-- * Certificate chain validation is done by 'X.validateDefault' from the -- "Data.X509.Validation" module. ----- The Server Name Indication (SNI) TLS extension is enabled.+-- * The Server Name Indication (SNI) TLS extension is enabled. ----- The supported cipher suites are those enumerated by 'TE.ciphersuite_default',+-- * The supported cipher suites are those enumerated by 'TE.ciphersuite_default', -- in decreasing order of preference. ----- Secure renegotiation is enabled.+-- * Secure renegotiation is enabled. ----- Only the __TLS 1.1__ and __TLS 1.2__ protocols are supported by default.+-- * Only the __TLS 1.1__, __TLS 1.2__ and __TLS 1.3__ protocols are supported by default. ----- If you are unsatisfied with any of these settings, use 'updateClientParams'--- to change them.-makeClientSettings+-- If you are unsatisfied with any of these settings, please+-- please refer to the "Network.TLS" module for more documentation on+-- 'T.ClientParams`.+makeClientParams   :: X.ServiceID-  -- ^ @-  -- 'X.ServiceID' ~ ('HostName', 'B.ByteString')+  -- ^   -- @+  -- 'X.ServiceID' ~ ('S.HostName', 'B.ByteString')+  -- @   --   -- Identification of the connection consisting of the fully qualified host   -- name for the server (e.g. www.example.com) and an optional suffix.@@ -156,21 +193,21 @@   -- host. For example, a same host might have different certificates on   -- differents ports (443 and 995). For TCP connections, it's recommended   -- to use: @:port@, or @:service@ for the blob (e.g., \@":443"@, @\":https"@).-  -> T.Credentials+  -> [T.Credential]   -- ^ Credentials to provide to the server if requested. Only credentials   -- matching the server's 'X.DistinguishedName' will be submitted.   ---  -- Initial credentials can be loaded with 'T.credentialLoadX509'+  -- Can be loaded with 'credentialLoadX509' or similar functions.   -> X.CertificateStore   -- ^ CAs used to verify the server certificate.   --   -- Use 'getSystemCertificateStore' to obtain the operating system's defaults.-  -> ClientSettings-makeClientSettings (hn, sp) (T.Credentials creds) cStore =-    ClientSettings $ (T.defaultParamsClient hn sp)+  -> T.ClientParams+makeClientParams (hn, sp) creds cStore =+    (T.defaultParamsClient hn sp)       { T.clientUseServerNameIndication = True       , T.clientSupported = def-        { T.supportedVersions = [T.TLS12, T.TLS11]+        { T.supportedVersions = [T.TLS13, T.TLS12, T.TLS11]         , T.supportedCiphers = TE.ciphersuite_default         , T.supportedSecureRenegotiation = True         , T.supportedClientInitiatedRenegotiation = True }@@ -192,47 +229,28 @@         isSubject (X.CertificateChain cc, _) =           any (\c -> (X.certSubjectDN . X.getCertificate) c `elem` dns) cc --- | Update advanced TLS client configuration 'T.ClientParams'.------ See the "Network.TLS" module for details.-updateClientParams-  :: (T.ClientParams -> T.ClientParams) -> ClientSettings -> ClientSettings-updateClientParams f = ClientSettings . f . unClientSettings---- | A 'Control.Lens.Lens' into the TLS client configuration 'T.ClientParams'.------ See the "Network.TLS" and the @lens@ package for details.-clientParams-  :: Functor f-  => (T.ClientParams -> f T.ClientParams)-  -> (ClientSettings -> f ClientSettings)-clientParams f = fmap ClientSettings . f . unClientSettings- -------------------------------------------------------------------------------- -- Server side TLS settings --- | Abstract type representing the configuration settings for a TLS server.------ Use 'makeServerSettings' to construct a 'ServerSettings' value, and--- 'updateServerParams' to update it.-data ServerSettings = ServerSettings { unServerSettings :: T.ServerParams }---- | Make default 'ServerSettings'.+-- | Make default 'T.ServerParams'. ----- The supported cipher suites are those enumerated by 'TE.ciphersuite_strong',+-- * The supported cipher suites are those enumerated by 'TE.ciphersuite_strong', -- in decreasing order of preference. The cipher suite preferred by the server -- is used. ----- Secure renegotiation initiated by the server is enabled, but renegotiation+-- * Secure renegotiation initiated by the server is enabled, but renegotiation -- initiated by the client is disabled. ----- Only the __TLS 1.1__ and __TLS 1.2__ protocols are supported by default.+-- * Only the __TLS 1.1__, __TLS 1.2__ and __TLS 1.3__ protocols are supported by default. ----- If you are unsatisfied with any of these settings, use 'updateServerParams'--- to change them.-makeServerSettings+-- If you are unsatisfied with any of these settings, please+-- please refer to the "Network.TLS" module for more documentation on+-- 'T.ServerParams`.+makeServerParams   :: T.Credential   -- ^ Server credential.+  --+  -- Can be loaded with 'credentialLoadX509' or similar functions.   -> Maybe X.CertificateStore   -- ^ CAs used to verify the client certificate.   --@@ -240,15 +258,14 @@   -- handshake.   --   -- Use 'getSystemCertificateStore' to obtain the operating system's defaults.-  -> ServerSettings-makeServerSettings cred ycStore =-    ServerSettings $ def+  -> T.ServerParams+makeServerParams cred ycStore = def       { T.serverWantClientCert = isJust ycStore       , T.serverShared = def         { T.sharedCredentials = T.Credentials [cred] }       , T.serverCACertificates = []       , T.serverSupported = def-        { T.supportedVersions = [T.TLS12, T.TLS11]+        { T.supportedVersions = [T.TLS13, T.TLS12, T.TLS11]         , T.supportedCiphers = TE.ciphersuite_strong         , T.supportedSession = True         , T.supportedSecureRenegotiation = True@@ -272,20 +289,29 @@     chooseCipher :: T.Version -> [T.Cipher] -> T.Cipher     chooseCipher _ cCiphs = head (intersect TE.ciphersuite_strong cCiphs) --- | Update advanced TLS server configuration 'T.Params'.+-- | Obtain new default 'T.ServerParams' for a particular server 'T.Credential'. ----- See the "Network.TLS" module for details.-updateServerParams-  :: (T.ServerParams -> T.ServerParams) -> ServerSettings -> ServerSettings-updateServerParams f = ServerSettings . f . unServerSettings---- | A 'Control.Lens.Lens' into the TLS server configuration 'T.Params'.--- See the "Network.TLS" and the @lens@ package for details.-serverParams-  :: Functor f-  => (T.ServerParams -> f T.ServerParams)-  -> (ServerSettings -> f ServerSettings)-serverParams f = fmap ServerSettings . f . unServerSettings+-- * Don't require credentials from clients.+--+-- * Use an in-memory TLS session manager from the+-- [tls-session-manager](https://hackage.haskell.org/package/tls-session-manager)+-- package.+--+-- * Everything else as proposed by 'makeServerParams'.+newDefaultServerParams+  :: MonadIO m+  => T.Credential+  -- ^ Server credential.+  --+  -- Can be loaded with 'credentialLoadX509' or similar functions.+  -> m T.ServerParams+newDefaultServerParams cred = liftIO $ do+  sm <- TSM.newSessionManager TSM.defaultConfig+  let sp0 = makeServerParams cred Nothing+  pure $ sp0+    { T.serverShared = (T.serverShared sp0)+        { T.sharedSessionManager = sm }+    }  -------------------------------------------------------------------------------- @@ -299,10 +325,10 @@ -- of those steps manually. serve   :: MonadIO m-  => ServerSettings       -- ^TLS settings.+  => T.ServerParams       -- ^TLS settings.   -> S.HostPreference     -- ^Preferred host to bind.-  -> ServiceName          -- ^Service port to bind.-  -> ((Context, SockAddr) -> IO ())+  -> S.ServiceName          -- ^Service port to bind.+  -> ((T.Context, S.SockAddr) -> IO ())                           -- ^Computation to run in a different thread                           -- once an incomming connection is accepted and a                           -- TLS-secured communication is established. Takes the@@ -322,9 +348,9 @@ -- resources yourself, then use 'acceptTls' instead. accept   :: (MonadIO m, E.MonadMask m)-  => ServerSettings       -- ^TLS settings.-  -> Socket               -- ^Listening and bound socket.-  -> ((Context, SockAddr) -> m r)+  => T.ServerParams       -- ^TLS settings.+  -> S.Socket               -- ^Listening and bound socket.+  -> ((T.Context, S.SockAddr) -> m r)                           -- ^Computation to run in a different thread                           -- once an incomming connection is accepted and a                           -- TLS-secured communication is established. Takes the@@ -338,9 +364,9 @@ -- handshake and run the given computation. acceptFork   :: MonadIO m-  => ServerSettings       -- ^TLS settings.-  -> Socket               -- ^Listening and bound socket.-  -> ((Context, SockAddr) -> IO ())+  => T.ServerParams       -- ^TLS settings.+  -> S.Socket               -- ^Listening and bound socket.+  -> ((T.Context, S.SockAddr) -> IO ())                           -- ^Computation to run in a different thread                           -- once an incomming connection is accepted and a                           -- TLS-secured communication is established. Takes the@@ -361,10 +387,10 @@ -- resources yourself, then use 'connectTls' instead. connect   :: (MonadIO m, E.MonadMask m)-  => ClientSettings       -- ^ TLS settings.-  -> HostName             -- ^ Server hostname.-  -> ServiceName          -- ^ Destination server service port name or number.-  -> ((Context, SockAddr) -> m r)+  => T.ClientParams       -- ^ TLS settings.+  -> S.HostName             -- ^ Server hostname.+  -> S.ServiceName          -- ^ Destination server service port name or number.+  -> ((T.Context, S.SockAddr) -> m r)   -- ^ Computation to run after establishing TLS-secured TCP connection to the   -- remote server. Takes the TLS connection context and remote end address.   -> m r@@ -375,17 +401,17 @@ -- | Like 'connect', but connects to the destination server over a SOCKS5 proxy. connectOverSOCKS5   :: (MonadIO m, E.MonadMask m)-  => HostName     -- ^ SOCKS5 proxy server hostname or IP address.-  -> ServiceName  -- ^ SOCKS5 proxy server service port name or number.-  -> ClientSettings  -- ^ TLS settings.-  -> HostName+  => S.HostName        -- ^ SOCKS5 proxy server hostname or IP address.+  -> S.ServiceName     -- ^ SOCKS5 proxy server service port name or number.+  -> T.ClientParams  -- ^ TLS settings.+  -> S.HostName   -- ^ Destination server hostname or IP address. We connect to this host   -- /through/ the SOCKS5 proxy specified in the previous arguments.   ---  -- Note that if hostname resolution on this 'HostName' is necessary, it+  -- Note that if hostname resolution on this 'S.HostName' is necessary, it   -- will happen on the proxy side for security reasons, not locally.-  -> ServiceName -- ^ Destination server service port name or number.-  -> ((Context, SockAddr, SockAddr) -> m r)+  -> S.ServiceName -- ^ Destination server service port name or number.+  -> ((T.Context, S.SockAddr, S.SockAddr) -> m r)   -- ^ Computation to run after establishing TLS-secured TCP connection to the   -- remote server. Takes the TLS connection that can be used to interact with   -- the destination server, as well as the address of the SOCKS5 server and the@@ -401,22 +427,22 @@ --------------------------------------------------------------------------------  -- | Estalbishes a TCP connection to a remote server and returns a TLS--- 'Context' configured on top of it using the given 'ClientSettings'.+-- 'T.Context' configured on top of it using the given 'T.ClientParams'. -- The remote end address is also returned. ----- Prefer to use 'connect' if you will be using the obtained 'Context' within a+-- Prefer to use 'connect' if you will be using the obtained 'T.Context' within a -- limited scope. ----- You need to perform a TLS handshake on the resulting 'Context' before using+-- You need to perform a TLS handshake on the resulting 'T.Context' before using -- it for communication purposes, and gracefully close the TLS and TCP -- connections afterwards using. The 'useTls', 'useTlsThenClose' and -- 'useTlsThenCloseFork' can help you with that. connectTls   :: MonadIO m-  => ClientSettings       -- ^ TLS settings.-  -> HostName             -- ^ Server hostname.-  -> ServiceName          -- ^ Server service name or port number.-  -> m (Context, SockAddr)+  => T.ClientParams       -- ^ TLS settings.+  -> S.HostName             -- ^ Server hostname.+  -> S.ServiceName          -- ^ Server service name or port number.+  -> m (T.Context, S.SockAddr) connectTls cs host port = liftIO $ do     E.bracketOnError         (S.connectSock host port)@@ -429,18 +455,18 @@ -- proxy. connectTlsOverSOCKS5   :: MonadIO m-  => HostName     -- ^ SOCKS5 proxy server hostname or IP address.-  -> ServiceName  -- ^ SOCKS5 proxy server service port name or number.-  -> ClientSettings  -- ^ TLS settings.-  -> HostName+  => S.HostName        -- ^ SOCKS5 proxy server hostname or IP address.+  -> S.ServiceName     -- ^ SOCKS5 proxy server service port name or number.+  -> T.ClientParams  -- ^ TLS settings.+  -> S.HostName   -- ^ Destination server hostname or IP address. We connect to this host   -- /through/ the SOCKS5 proxy specified in the previous arguments.   ---  -- Note that if hostname resolution on this 'HostName' is necessary, it+  -- Note that if hostname resolution on this 'S.HostName' is necessary, it   -- will happen on the proxy side for security reasons, not locally.-  -> ServiceName -- ^ Destination server service port name or number.-  -> m (Context, SockAddr, SockAddr)-  -- ^ Returns the 'Context' that can be used to interact with the destination+  -> S.ServiceName -- ^ Destination server service port name or number.+  -> m (T.Context, S.SockAddr, S.SockAddr)+  -- ^ Returns the 'T.Context' that can be used to interact with the destination   -- server, as well as the address of the SOCKS5 server and the address of the   -- destination server, in that order. connectTlsOverSOCKS5 phn psn cs dhn dsn = liftIO $ do@@ -452,30 +478,29 @@           ctx <- makeClientContext cs psock           return (ctx, paddr, daddr)) --- | Make a client-side TLS 'Context' for the given settings, on top of the--- given TCP `Socket` connected to the remote end.-makeClientContext :: MonadIO m => ClientSettings -> Socket -> m Context-makeClientContext (ClientSettings params) sock = liftIO $ do-    T.contextNew sock params+-- | Make a client-side TLS 'T.Context' for the given settings, on top of the+-- given TCP `S.Socket` connected to the remote end.+makeClientContext :: MonadIO m => T.ClientParams -> S.Socket -> m T.Context+makeClientContext params sock = liftIO $ T.contextNew sock params  -------------------------------------------------------------------------------- --- | Accepts an incoming TCP connection and returns a TLS 'Context' configured--- on top of it using the given 'ServerSettings'. The remote end address is also+-- | Accepts an incoming TCP connection and returns a TLS 'T.Context' configured+-- on top of it using the given 'T.ServerParams'. The remote end address is also -- returned. ----- Prefer to use 'accept' if you will be using the obtained 'Context' within a+-- Prefer to use 'accept' if you will be using the obtained 'T.Context' within a -- limited scope. ----- You need to perform a TLS handshake on the resulting 'Context' before using+-- You need to perform a TLS handshake on the resulting 'T.Context' before using -- it for communication purposes, and gracefully close the TLS and TCP -- connections afterwards using. The 'useTls', 'useTlsThenClose' and -- 'useTlsThenCloseFork' can help you with that. acceptTls   :: MonadIO m-  => ServerSettings   -- ^TLS settings.-  -> Socket           -- ^Listening and bound socket.-  -> m (Context, SockAddr)+  => T.ServerParams   -- ^TLS settings.+  -> S.Socket           -- ^Listening and bound socket.+  -> m (T.Context, S.SockAddr) acceptTls sp lsock = liftIO $ do     E.bracketOnError         (NS.accept lsock)@@ -484,15 +509,14 @@              ctx <- makeServerContext sp sock              return (ctx, addr)) --- | Make a server-side TLS 'Context' for the given settings, on top of the--- given TCP `Socket` connected to the remote end.-makeServerContext :: MonadIO m => ServerSettings -> Socket -> m Context-makeServerContext (ServerSettings params) sock = liftIO $ do-    T.contextNew sock params+-- | Make a server-side TLS 'T.Context' for the given settings, on top of the+-- given TCP `S.Socket` connected to the remote end.+makeServerContext :: MonadIO m => T.ServerParams -> S.Socket -> m T.Context+makeServerContext params sock = liftIO $ T.contextNew sock params  -------------------------------------------------------------------------------- --- | Perform a TLS handshake on the given 'Context', then perform the+-- | Perform a TLS handshake on the given 'T.Context', then perform the -- given action and at last gracefully close the TLS session using `T.bye`. -- -- This function does not close the underlying TCP connection when done.@@ -500,8 +524,8 @@ -- behavior. Otherwise, you must call `T.contextClose` yourself at some point. useTls   :: (MonadIO m, E.MonadMask m)-  => ((Context, SockAddr) -> m a)-  -> ((Context, SockAddr) -> m a)+  => ((T.Context, S.SockAddr) -> m a)+  -> ((T.Context, S.SockAddr) -> m a) useTls k conn@(ctx,_) = E.bracket_ (T.handshake ctx)                                    (liftIO $ silentBye ctx)                                    (k conn)@@ -509,8 +533,8 @@ -- | Like 'useTls', except it also fully closes the TCP connection when done. useTlsThenClose   :: (MonadIO m, E.MonadMask m)-  => ((Context, SockAddr) -> m a)-  -> ((Context, SockAddr) -> m a)+  => ((T.Context, S.SockAddr) -> m a)+  -> ((T.Context, S.SockAddr) -> m a) useTlsThenClose k conn@(ctx,_) = do     useTls k conn `E.finally` liftIO (T.contextClose ctx) @@ -521,8 +545,8 @@ -- the right behavior. useTlsThenCloseFork   :: MonadIO m-  => ((Context, SockAddr) -> IO ())-  -> ((Context, SockAddr) -> m ThreadId)+  => ((T.Context, S.SockAddr) -> IO ())+  -> ((T.Context, S.SockAddr) -> m ThreadId) useTlsThenCloseFork k conn@(ctx,_) = liftIO $ do     forkFinally (E.bracket_ (T.handshake ctx) (silentBye ctx) (k conn))                 (\eu -> T.contextClose ctx >> either E.throwIO return eu)@@ -530,11 +554,11 @@ -------------------------------------------------------------------------------- -- Utils --- | Receives decrypted bytes from the given 'Context'. Returns 'Nothing'+-- | Receives decrypted bytes from the given 'T.Context'. Returns 'Nothing' -- on EOF. -- -- Up to @16384@ decrypted bytes will be received at once.-recv :: MonadIO m => Context -> m (Maybe B.ByteString)+recv :: MonadIO m => T.Context -> m (Maybe B.ByteString) recv ctx = liftIO $ do     E.handle (\T.Error_EOF -> return Nothing)              (do bs <- T.recvData ctx@@ -544,23 +568,34 @@ {-# INLINABLE recv #-}  -- | Encrypts the given strict 'B.ByteString' and sends it through the--- 'Context'.-send :: MonadIO m => Context -> B.ByteString -> m ()+-- 'T.Context'.+send :: MonadIO m => T.Context -> B.ByteString -> m () send ctx = \bs -> T.sendData ctx (BL.fromStrict bs) {-# INLINABLE send #-}  -- | Encrypts the given lazy 'BL.ByteString' and sends it through the--- 'Context'.-sendLazy :: MonadIO m => Context -> BL.ByteString -> m ()+-- 'T.Context'.+sendLazy :: MonadIO m => T.Context -> BL.ByteString -> m () sendLazy = T.sendData {-# INLINE sendLazy #-}  --------------------------------------------------------------------------------++-- | Try to create a new credential object from a public certificate and the+-- associated private key that are stored on the filesystem in PEM format.+credentialLoadX509+  :: MonadIO m+  => FilePath -- ^ Public certificate (X.509 format).+  -> FilePath -- ^ Private key associated with the certificate.+  -> m (Either String T.Credential)+credentialLoadX509 cert key = liftIO $ T.credentialLoadX509 cert key++-------------------------------------------------------------------------------- -- Internal utils  -- | Like 'T.bye' from the "Network.TLS" module, except it ignores 'ePIPE' -- errors which might happen if the remote peer closes the connection first.-silentBye :: Context -> IO ()+silentBye :: T.Context -> IO () silentBye ctx = do     E.catch (T.bye ctx) $ \e -> case e of         Eg.IOError{ Eg.ioe_type  = Eg.ResourceVanished