Overview

This document describes how to use SSL in Twisted servers and clients. It
assumes that you know what SSL is, what some of the major reasons to use it
are, and how to generate your own SSL certificates, in particular self-signed
certificates. It also assumes that you are comfortable with creating TCP
servers and clients as described in the server howto
and client howto. After reading this
document you should be able to create servers and clients that can use SSL to
encrypt their connections, switch from using an unencrypted channel to an
encrypted one mid-connection, and require client authentication.

Using SSL in Twisted requires that you have
pyOpenSSL installed. A quick test to
verify that you do is to run from OpenSSL import SSL at a
python prompt and not get an error.

SSL connections require SSL contexts. These contexts are generated by a
ContextFactory that maintains state like the SSL method, private
key file name, and certificate file name.

Instead of using listenTCP and connectTCP to create a connection, use
listenSSL and
connectSSL for a
server and client respectively. These methods take a contextFactory as an
additional argument.

Those are the big immediate differences between TCP and SSL connections,
so let's look at an example. In it and all subsequent examples it is assumed
that keys and certificates for the server, certificate authority, and client
should they exist live in a keys/ subdirectory of the directory
containing the example code, and that the certificates are self-signed.

SSL echo server and client without client authentication

Authentication and encryption are two separate parts of the SSL protocol.
The server almost always needs a key and certificate to authenticate itself
to the client but is usually configured to allow encrypted connections with
unauthenticated clients who don't have certificates. This common case is
demonstrated first by adding SSL support to the echo client and server in
the core examples.

Contexts are created according to a specified method.
SSLv3_METHOD, SSLv23_METHOD, and
TLSv1_METHOD are the valid constants that represent SSL methods
to use when creating a context object. DefaultOpenSSLContextFactory and
ClientContextFactory default to using SSL.SSLv23_METHOD as their
method, and it is compatible for communication with all the other methods
listed above. An older method constant, SSLv2_METHOD, exists but
is explicitly disallowed in both DefaultOpenSSLContextFactory and
ClientContextFactory for being insecure by calling
set_options(SSL.OP_NO_SSLv2) on their contexts. See
twisted.internet.ssl for additional comments.

Using startTLS

If you want to switch from unencrypted to encrypted traffic
mid-connection, you'll need to turn on SSL with startTLS on both
ends of the connection at the same time via some agreed-upon signal like the
reception of a particular message. You can readily verify the switch to an
encrypted channel by examining the packet payloads with a tool like
Wireshark.

startTLS is a transport method that gets passed a context.
It is invoked at an agreed-upon time in the data reception method of the
client and server protocols. The ServerTLSContext and
ClientTLSContext classes used above inherit from the basic
server and client context factories used in the earlier echo examples and
illustrate two more ways of setting an SSL method.

Client authentication

Server and client-side changes to require client authentication fall
largely under the dominion of pyOpenSSL, but few examples seem to exist on
the web so for completeness a sample server and client are provided here.

Use the set_verify method to set the verification mode for a
context object and the verification callback. The mode is either
VERIFY_NONE or VERIFY_PEER. If
VERIFY_PEER is set, the mode can be augmented by
VERIFY_FAIL_IF_NO_PEER_CERT and/or
VERIFY_CLIENT_ONCE.

The callback takes as its arguments a connection object, X509 object,
error number, error depth, and return code. The purpose of the callback is
to allow you to enforce additional restrictions on the verification. Thus,
if the return code is False, you should return False; if the return code is
True and further verification passes, return True.