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