09.11.2016 Views

Foundations of Python Network Programming 978-1-4302-3004-5

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

CHAPTER 6 ■ TLS AND SSL<br />

The Linksys router here at my house, by contrast, uses a self-signed certificate that can provide<br />

encryption but fails to provide a signature that can be verified against any <strong>of</strong> the famous CAs in the<br />

certfiles.crt file. So, with the conservative settings in our sslclient.py program, the connection fails:<br />

$ python sslclient.py ten22.rhodesmill.org<br />

Traceback (most recent call last):<br />

...<br />

ssl.SSLError: [Errno 1] _ssl.c:480: error:14090086:SSL<br />

routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed<br />

Interestingly, Google (as <strong>of</strong> this writing) provides a single www.google.com certificate not only for that<br />

specific domain name, but also for its google.com address since all that is hosted there is a redirect to the<br />

www name:<br />

$ python sslclient.py google.com<br />

Certificate error: hostname 'google.com' doesn't match u'www.google.com'<br />

$ python sslclient.py www.google.com<br />

The document https://www.google.com/ is 9014 bytes long<br />

Writing an SSL server looks much the same: code like that in Listing 3-1 is supplemented so that the<br />

client socket returned by each accept() call gets immediately wrapped with wrap_socket(), but with<br />

different options than are used with a client. In general, here are the three most popular ways <strong>of</strong> using<br />

wrap_socket() (see the ssl Standard Library documentation to learn about all <strong>of</strong> the rest <strong>of</strong> its options):<br />

The first form is the one shown in Listing 6–1, and is the most common form <strong>of</strong> the call seen in clients:<br />

wrap_socket(sock, ssl_version=ssl.PROTOCOL_SSLv3,<br />

» cert_reqs=ssl.CERT_REQUIRED, ca_certs=ca_certs_path)<br />

Here the client asserts no particular identity—at least, TLS provides no way for the server to know<br />

who is connecting. (Since the connection is now encrypted, <strong>of</strong> course, a password or cookie can now be<br />

passed safely to the server; but the TLS layer itself will not know who the client is.)<br />

Servers generally do not care whether clients connect with certificates, so the wrap_socket() calls<br />

that they make after an accept() use a different set <strong>of</strong> named parameters that provide the documents<br />

that establish their own identity. But they can neglect to provide a database <strong>of</strong> CA certificates, since they<br />

will not require the client to present a certificate:<br />

wrap_socket(sock, server_side=True, ssl_version=ssl.PROTOCOL_SSLv23,<br />

» cert_reqs=ssl.CERT_NONE,<br />

» keyfile="mykeyfile", certfile="mycertfile")<br />

Finally, there do exist situations where you want to run a server that checks the certificates <strong>of</strong> the<br />

clients that are connecting. This can be useful if the protocol that you are wrapping provides weak or<br />

even non-existent authentication, and the TLS layer will be providing the only assurance about who is<br />

connecting. You will use your CA to sign client certificates for each individual or machine that will be<br />

connecting, then have your server make a call like this:<br />

wrap_socket(sock, server_side=True, ssl_version=ssl.PROTOCOL_SSLv23,<br />

» cert_reqs=ssl.CERT_REQUIRED, ca_certs=ca_certs_path,<br />

» keyfile="mykeyfile", certfile="mycertfile")<br />

Again, consult the ssl chapter in the Standard Library if you need to delve into the options more<br />

deeply; the documentation there has been getting quite a bit better, and might cover edge cases that we<br />

have not had room to discuss here in this chapter.<br />

If you are writing clients and servers that need to talk only to each other, try using PROTOCOL_TLSv1 as<br />

your protocol. It is more modern and secure than any <strong>of</strong> the protocols that have SSL in their names. The<br />

only reason to use SSL protocols—as shown in the foregoing example calls, and which are also currently<br />

97

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!