Chapter 6 ■ tLS/SSL
95
host identities. By default, your operating system TLS library or that of your web browser uses a standard worldwide
CA list of a few hundred certificates that represent organizations in the business of performing trusted site verification.
However, you can always provide a CA list of your own if you are not satisfied with the defaults or if you want to use a
private CA that your organization has generated for signing your own private host certificates for free. This is a popular
option when no outside clients are going to connect and you need to support connections only between your own
services.
The mathematical mark that a CA makes upon a certificate to demonstrate its approval is called a signature.
Your TLS library will verify the certificate’s signature against the public key of the corresponding CA certificate before
accepting that the certificate is valid.
Once TLS has verified that the body of the certificate was indeed submitted to and signed by the trusted third
party, it will examine the data fields of the certificate itself. Two kinds of fields will be of special interest. First,
certificates include a notBefore date and a notAfter date to bracket the time period in which they are valid so that
the certificates belonging to stolen private keys do not last forever. Your TLS stack will check these using your system
clock, which means that a bad or misconfigured clock can actually break your ability to communicate over TLS!
Second, the certificate’s common name should match the hostname to which you are trying to connect—after all, if
you want to connect to https://pypi.python.org, you are hardly going to be reassured if the site responds with a
certificate for a completely different hostname!
A single certificate can actually be shared among many hostnames. Modern certificates can supplement the
single-value common name in their subject field with additional names stored in their subjectAltName field. Also,
any of those names can include wildcards like *.python.org that match multiple hostnames instead of just one
hostname each. Modern TLS algorithms will perform such matching for you automatically, and the Python ssl
module has its own ability to do so as well.
Finally, the TLS agents on the client and server negotiate a shared secret key and cipher with which to encrypt
the actual data that passes over the connection. This is one final point at which TLS can fail because correctly
configured software will reject either a cipher or key length that it believes to be inadequate. In fact, this can happen
at two levels: TLS can fail either because the version of the TLS protocol that the other end wants to speak is too
hopelessly out-of-date and insecure or because the particular ciphers that the other end supports are not considered
strong enough to trust.
Once the cipher is agreed upon and both peers have generated the keys, both for encrypting data and also for
signing each block of data, control is handed back to the application at each end. Each chunk of data they transmit
is encrypted with the encryption key, and then the resulting block is signed with the signing key to prove to the other
end that it was really generated by the other peer and not someone who has jumped on to the network to attempt a
man-in-the-middle attack. Data can flow in both directions without any restriction, just as on a normal TCP socket,
until TLS shuts down and the socket either is closed or returns to plain-text mode.
In the sections that follow, you will learn how to control Python’s ssl library because it makes every one of the
major decisions outlined earlier. Please consult official references for further information, as well as resources such
as Bruce Schneier’s books, the Google Online Security blog, and blogs like Adam Langley’s. I myself found Hynek
Schlawack’s “The Sorry State Of SSL” talk at PyCon 2014 helpful, which you can watch online. If even more recent talks
on TLS have been featured at conferences by the time you read this book, they might be a good source of up-to-date
information on the dynamic practice of cryptography.
Generating Certificates
The Python Standard Library does not concern itself with private key generation or with certificate signing. If you
need to perform these steps, you will have to use other tools instead. One of the most widespread is the openssl
command-line tool. If you want to see several examples of how it is invoked, see the Makefile in the playground/
certs directory of this book’s source code repository.
https://github.com/brandon-rhodes/fopnp/tree/m/playground/certs