Functions for handling SSL connections. These functions use GHC specific
calls to cooperative the with the scheduler so that blocking functions
only actually block the Haskell thread, not a whole OS thread.

Contexts

An SSL context. Contexts carry configuration such as a server's private
key, root CA certiifcates etc. Contexts are stateful IO objects; they
start empty and various options are set on them by the functions in this
module. Note that an empty context will pretty much cause any operation to
fail since it doesn't even have any ciphers enabled.

Contexts are not thread safe so they carry a QSem with them which only
lets a single thread work inside them at a time. Thus, one must always use
withContext, not withForeignPtr directly.

Install a private key file in a context. The key is given as a path to the
file which contains the key. The file is parsed first as PEM and, if that
fails, as ASN1. If both fail, an exception is raised.

Install a certificate (public key) file in a context. The key is given as
a path to the file which contains the key. The file is parsed first as PEM
and, if that fails, as ASN1. If both fail, an exception is raised.

SSL connections

SSL objects are not thread safe, so they carry a QSem around with them
which only lets a single thread work inside them at a time. Thus, one must
always use withSSL, rather than withForeignPtr directly.

IO with SSL objects is non-blocking and many SSL functions return a error
code which signifies that it needs to read or write more data. We handle
these calls and call threadWaitRead and threadWaitWrite at the correct
times. Thus multiple OS threads can be blocked inside IO in the same SSL
object at a time, because they aren't really in the SSL object, they are
waiting for the RTS to wake the Haskell thread.

Wrap a Socket in an SSL connection. Reading and writing to the Socket
after this will cause weird errors in the SSL code. The SSL object
carries a handle to the Socket so you need not worry about the garbage
collector closing the file descriptor out from under you.

Write a lazy ByteString to the SSL connection. In contrast to
write, there is a chance that the string is written partway and
then an exception is raised for an error. The string doesn't
necessarily have to be finite.

Get the result of verifing the peer's certificate. This is mostly for
clients to verify the certificate of the server that they have connected
it. You must set a list of root CA certificates with contextSetCA... for
this to make sense.

Note that this returns True iff the peer's certificate has a valid chain
to a root CA. You also need to check that the certificate is correct (i.e.
has the correct hostname in it) with getPeerCertificate.

SSL Exceptions

The TLS/SSL connection has been closed. If the protocol version
is SSL 3.0 or TLS 1.0, this result code is returned only if a
closure alert has occurred in the protocol, i.e. if the connection
has been closed cleanly. Note that in this case
ConnectionCleanlyClosed does not necessarily indicate that the
underlying transport has been closed.

The operation did not complete; the same TLS/SSL I/O function
should be called again later. The underlying socket was not
connected yet to the peer and the call would block in
connect. The SSL function should be called again when the
connection is established. This message can only appear with
connect.

The operation did not complete; the same TLS/SSL I/O function
should be called again later. The underlying socket was not
connected yet to the peer and the call would block in accept. The
SSL function should be called again when the connection is
established. This message can only appear with accept.

The operation did not complete because an application callback
set by SSL_CTX_set_client_cert_cb() has asked to be called
again. The TLS/SSL I/O function should be called again
later. Details depend on the application.

Some I/O error occurred. The OpenSSL error queue may contain
more information on the error. If the error queue is empty
(i.e. ERR_get_error() returns 0), ret can be used to find out more
about the error: If ret == 0, an EOF was observed that violates the
protocol. If ret == -1, the underlying BIO reported an I/O error
(for socket I/O on Unix systems, consult errno for details).