network-simple-tls-0.3: Simple interface to TLS secured network sockets.

Safe HaskellNone
LanguageHaskell98

Network.Simple.TCP.TLS

Contents

Description

This module exports simple tools for establishing TLS-secured TCP 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 uses MonadIO and 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.

Synopsis

Server side

serve Source #

Arguments

:: MonadIO m 
=> ServerSettings

TLS settings.

-> HostPreference

Preferred host to bind.

-> ServiceName

Service port to bind.

-> ((Context, SockAddr) -> IO ())

Computation to run in a different thread once an incomming connection is accepted and a TLS-secured communication is established. Takes the TLS connection context and remote end address.

-> m () 

Start a TLS-secured TCP server that accepts incoming connections and handles each of them concurrently, in different threads.

Any acquired network resources are properly closed and discarded when done or in case of exceptions. This function binds a listening socket, accepts an incoming connection, performs a TLS handshake and then safely closes the connection when done or in case of exceptions. You don't need to perform any of those steps manually.

Listening

listen #

Arguments

:: (MonadIO m, MonadMask m) 
=> HostPreference

Preferred host to bind.

-> ServiceName

Service port to bind.

-> ((Socket, SockAddr) -> m r)

Computation taking the listening socket and the address it's bound to.

-> m r 

Bind a TCP listening socket and use it.

The listening socket is closed when done or in case of exceptions.

If you prefer to acquire and close the socket yourself, then use bindSock, closeSock and the listen function from Network.Socket instead.

Note: maxListenQueue is typically 128, which is too small for high performance servers. So, we use the maximum between maxListenQueue and 2048 as the default size of the listening queue. The NoDelay and ReuseAddr options are set on the socket.

Accepting

accept Source #

Arguments

:: (MonadIO m, MonadMask m) 
=> ServerSettings

TLS settings.

-> Socket

Listening and bound socket.

-> ((Context, 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 TLS connection context and remote end address.

-> m r 

Accepts a single incomming TLS-secured TCP connection and use it.

A TLS handshake is performed immediately after establishing the TCP connection and the TLS and TCP connections are properly closed when done or in case of exceptions. If you need to manage the lifetime of the connection resources yourself, then use acceptTls instead.

acceptFork Source #

Arguments

:: MonadIO m 
=> ServerSettings

TLS settings.

-> Socket

Listening and bound socket.

-> ((Context, SockAddr) -> IO ())

Computation to run in a different thread once an incomming connection is accepted and a TLS-secured communication is established. Takes the TLS connection context and remote end address.

-> m ThreadId 

Like accept, except it uses a different thread to performs the TLS handshake and run the given computation.

Server TLS Settings

data ServerSettings Source #

Abstract type representing the configuration settings for a TLS server.

Use makeServerSettings to construct a ServerSettings value, and updateServerParams to update it.

makeServerSettings Source #

Arguments

:: Credential

Server credential.

-> Maybe CertificateStore

CAs used to verify the client certificate.

If specified, then a valid client certificate will be expected during handshake.

Use getSystemCertificateStore to obtain the operating system's defaults.

-> ServerSettings 

Make default ServerSettings.

The supported cipher suites are those enumerated by 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 initiated by the client is disabled.

Only the TLS 1.1 and TLS 1.2 protocols are supported by default.

If you are unsatisfied with any of these settings, use updateServerParams to change them.

updateServerParams :: (ServerParams -> ServerParams) -> ServerSettings -> ServerSettings Source #

Update advanced TLS server configuration Params.

See the Network.TLS module for details.

serverParams :: Functor f => (ServerParams -> f ServerParams) -> ServerSettings -> f ServerSettings Source #

A Lens into the TLS server configuration Params. See the Network.TLS and the lens package for details.

Client side

connect Source #

Arguments

:: (MonadIO m, MonadMask m) 
=> ClientSettings

TLS settings.

-> HostName

Server hostname.

-> ServiceName

Server service port.

-> ((Context, 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 

Connect to a TLS-secured TCP server and use the connection

A TLS handshake is performed immediately after establishing the TCP connection and the TLS and TCP connections are properly closed when done or in case of exceptions. If you need to manage the lifetime of the connection resources yourself, then use connectTls instead.

Client TLS Settings

data ClientSettings Source #

Abstract type representing the configuration settings for a TLS client.

Use makeClientSettings or getDefaultClientSettings to obtain a ClientSettings value.

makeClientSettings Source #

Arguments

:: ServiceID
ServiceID ~ (HostName, 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"@).

-> Credentials

Credentials to provide to the server if requested. Only credentials matching the server's DistinguishedName will be submitted.

Initial credentials can be loaded with credentialLoadX509

-> CertificateStore

CAs used to verify the server certificate.

Use getSystemCertificateStore to obtain the operating system's defaults.

-> ClientSettings 

Make defaults ClientSettings.

Certificate chain validation is done by validateDefault from the Data.X509.Validation module.

The Server Name Indication (SNI) TLS extension is enabled.

The supported cipher suites are those enumerated by ciphersuite_default, in decreasing order of preference.

Secure renegotiation is enabled.

Only the TLS 1.1 and TLS 1.2 protocols are supported by default.

If you are unsatisfied with any of these settings, use updateClientParams to change them.

getDefaultClientSettings :: MonadIO m => ServiceID -> m ClientSettings Source #

Get the system default ClientSettings for a particular ServiceID.

Defaults: No client credentials, system certificate store.

See makeClientSettings to better understand the default settings used.

updateClientParams :: (ClientParams -> ClientParams) -> ClientSettings -> ClientSettings Source #

Update advanced TLS client configuration ClientParams.

See the Network.TLS module for details.

clientParams :: Functor f => (ClientParams -> f ClientParams) -> ClientSettings -> f ClientSettings Source #

A Lens into the TLS client configuration ClientParams.

See the Network.TLS and the lens package for details.

Utils

recv :: MonadIO m => Context -> m (Maybe ByteString) Source #

Receives decrypted bytes from the given Context. Returns Nothing on EOF.

Up to 16384 decrypted bytes will be received at once.

send :: MonadIO m => Context -> ByteString -> m () Source #

Encrypts the given strict ByteString and sends it through the Context.

Low level support

useTls :: (MonadIO m, MonadMask m) => ((Context, SockAddr) -> m a) -> (Context, SockAddr) -> m a Source #

Perform a TLS handshake on the given Context, then perform the given action and at last gracefully close the TLS session using bye.

This function does not close the underlying TCP connection when done. Prefer to use useTlsThenClose or useTlsThenCloseFork if you need that behavior. Otherwise, you must call contextClose yourself at some point.

useTlsThenClose :: (MonadIO m, MonadMask m) => ((Context, SockAddr) -> m a) -> (Context, SockAddr) -> m a Source #

Like useTls, except it also fully closes the TCP connection when done.

useTlsThenCloseFork :: MonadIO m => ((Context, SockAddr) -> IO ()) -> (Context, SockAddr) -> m ThreadId Source #

Similar to useTlsThenClose, except it performs the all the IO actions in a new thread.

Use this instead of forking useTlsThenClose yourself, as that won't give the right behavior.

connectTls Source #

Arguments

:: MonadIO m 
=> ClientSettings

TLS settings.

-> HostName

Server hostname.

-> ServiceName

Service port to bind.

-> m (Context, SockAddr) 

Estalbishes a TCP connection to a remote server and returns a TLS Context configured on top of it using the given ClientSettings. The remote end address is also returned.

Prefer to use connect if you will be using the obtained Context within a limited scope.

You need to perform a TLS handshake on the resulting 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 Source #

Arguments

:: MonadIO m 
=> ServerSettings

TLS settings.

-> Socket

Listening and bound socket.

-> m (Context, SockAddr) 

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 returned.

Prefer to use accept if you will be using the obtained Context within a limited scope.

You need to perform a TLS handshake on the resulting 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.

makeClientContext :: MonadIO m => ClientSettings -> Socket -> m Context Source #

Make a client-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 Source #

Make a server-side TLS Context for the given settings, on top of the given TCP Socket connected to the remote end.

Note to Windows users

withSocketsDo :: IO a -> IO a #

With older versions of the network library on Windows operating systems, the networking subsystem must be initialised using withSocketsDo before any networking operations can be used. eg.

main = withSocketsDo $ do {...}

It is fine to nest calls to withSocketsDo, and to perform networking operations after withSocketsDo has returned.

In newer versions of the network library it is only necessary to call withSocketsDo if you are calling the MkSocket constructor directly. However, for compatibility with older versions on Windows, it is good practice to always call withSocketsDo (it's very cheap).

Re-exports

For your convenience, this module module also re-exports the following types from other modules:

From Network.Socket
HostName, ServiceName, Socket, SockAddr.
From Network.Simple.TCP
HostPreference(Host,HostAny,HostIPv4,HostIPv6).
From Network.TLS
Context.