09.11.2016 Views

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

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

CHAPTER 6 ■ TLS AND SSL<br />

Thus man-in-the-middle attacks are thwarted, and it does not matter what tricks an attacker might<br />

use to rewrite packets or try to get you to connect to his server instead <strong>of</strong> the one that you really want to<br />

talk to. If he does not return to you the server's real certificate, then it will not really have been signed by<br />

the CA and your TLS library will tell you he is a fake; or, if the attacker does return the server's<br />

certificate—since, after all, it is publicly transmitted on the network—then your client will indeed be<br />

willing to start talking. But the first thing that your TLS library sends back will be the encrypted<br />

symmetric key that will govern the rest <strong>of</strong> the conversation—a key, alas, that the attacker cannot decrypt,<br />

because he does not possess the private key that goes along with the public server certificate that he is<br />

fraudulently waving around.<br />

And, no, the little message that forms the digital signature does not really begin with the words “Go<br />

ahead” followed by the name <strong>of</strong> the server; instead, the server starts by creating a “certificate” that<br />

includes things like its name, an expiration date, and its public key, and the whole thing gets signed by<br />

the CA in a single step.<br />

But how do clients learn about CA certificates? The answer is: configuration. Either you have to<br />

manually load them one by one (they tend to live in files that end in .crt) using a call to your SSL library,<br />

or perhaps the library you are using will come with some built in or that are provided by your operating<br />

system. Web browsers support HTTPS by coming with several dozen CA certificates, one for each major<br />

public CA in existence. These companies stake their reputations on keeping their private keys absolutely<br />

safe, and signing server certificates only after making absolutely sure that the request really comes from<br />

the owner <strong>of</strong> a given domain.<br />

If you are setting up TLS servers that will be contacted only by clients that you configure, then you<br />

can save money by bypassing the public CAs and generating your own CA public-private key pair.<br />

Simply sign all <strong>of</strong> your server's certificates, and then put your new CA's public key in the configurations<br />

<strong>of</strong> all <strong>of</strong> your clients.<br />

Some people go one step cheaper, and give their server a “self-signed” certificate that only proves<br />

that the public key being <strong>of</strong>fered to the client indeed corresponds to a working private key. But a client<br />

that is willing to accept a self-signed certificate is throwing away one <strong>of</strong> the most important guarantees<br />

<strong>of</strong> TLS—that you are not talking to the wrong server—and so I strongly recommend that you set up your<br />

own simple CA in every case where spending money on “real” certificates from a public certificate<br />

authority does not make sense.<br />

Guides to creating your own certificate authority can be found through your favorite search engine<br />

on the Web, as can s<strong>of</strong>tware that automates the process so that you do not have to run all <strong>of</strong> those<br />

openssl command lines yourself.<br />

Supporting TLS in <strong>Python</strong><br />

So how can you use TLS in your own code?<br />

From the point <strong>of</strong> view <strong>of</strong> your network program, you start a TLS connection by turning control <strong>of</strong> a<br />

socket over to an SSL library. By doing so, you indicate that you want to stop using the socket for<br />

cleartext communication, and start using it for encrypted data under the control <strong>of</strong> the library.<br />

From that point on, you no longer use the raw socket; doing so will cause an error and break the<br />

connection. Instead, you will use routines provided by the library to perform all communication. Both<br />

client and server should turn their sockets over to SSL at the same time, after reading all pending data <strong>of</strong>f<br />

<strong>of</strong> the socket in both directions.<br />

There are two general approaches to using SSL.<br />

The most straightforward option is probably to use the ssl package that recent versions <strong>of</strong> <strong>Python</strong><br />

ship with the Standard Library.<br />

• The ssl package that comes with <strong>Python</strong> 3.2 includes everything that you need to<br />

communicate securely.<br />

94

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

Saved successfully!

Ooh no, something went wrong!