The other day, I needed to implement a very simple remote service for something at work. Everything I was doing seemed to map well onto simple HTTP requests, and I had played with a while ago, so it seemed like a good chance to refresh that bit of my memory. Not too much later, I was adding @route decorators to some of my existing functions, and voila! The previously local code had become remotely accessible, almost like magic. That was cool and allowed me to finish what I was doing, but at some point I’ll need to make this – and some other things like it – more secure. So it was that I sat down and tried to figure out how to make this code do SSL. At first I thought this must be extremely well-trodden ground, covered in just about every relevant manual and tutorial, but apparently not. Weird. In any case, here’s what I came up with for a server and a test program.

What I’m mostly interested in here is authenticating the client, but I do both sides because doing only one side seems a bit rude. “You have to show me ID before you can talk to me, but I don’t have to show anything to you.” It kind of annoys me how most people obsess over authenticating servers while allowing clients to remain anonymous, so I’m not going to do the opposite. The key in any case is to wrap WSGIServer.server_activate, which seems to be the last thing that gets called before accept(), so that it can call ssl.wrap_socket with all of the appropriate configuration data. Then, if you want to authenticate clients, you need to wrap WSGIRequestHandler.handle and actually check the incoming client certificate there. Finally, both of these get wrapped up together in an adapter class for to use. Clear as mud, huh?

That’s really all there is. It’s no stunning work of genius, that’s for sure, but maybe the next guy searching for this should-be-well-known recipe will be able to save some time.