SSL in Python 2.7

It has been almost two years since I wrote about the state of SSL in Python 2.6. If you haven’t read that yet, I suggest you read that first and then continue here, since I will mostly just be talking about things that have changed since then, or things that I have discovered since then.

The good news is that things have improved in the stdlib ssl module. The bad news is that it is still missing some critical pieces to make SSL secure.

Python 2.7 enables you to specify ciphers to use explicitly, rather than just relying on what comes default with the SSL version selection. Additionally, if you compile the ssl module with OpenSSL 1.0 and later, using ssl.PROTOCOL_SSLv23 is safe (as in, it will not pick the insecure SSLv2 protocol) as long as you don’t enable SSLv2 specific ciphers (see the ssl module documentation for details).


With that out of the way, there isn’t really much difference to how you would write a simple SSL server with Python 2.7 compared to what I wrote in 2008. If you know your ssl module was compiled with OpenSSL 1.0 you can pick ssl.PROTOCOL_SSLv23 for maximum compatibility. Otherwise you should stick with an explicit version other than v2.

The documentation for the ssl module in 2.7 has improved a lot, and includes good sample code for servers here.

The M2Crypto code hasn’t changed. The next M2Crypto release will add support for 0penSSL 1.0.


Checking the peer certificate’s hostname is still the weak point of the ssl module. The SSL version selection situation has improved slightly like I explained above. Othewise follow the example I wrote in 2008.

Again, the M2Crypto API hasn’t changed.

Lately I have been working with pycurl at Egnyte, so I decided to give a client example using that module.

import pycurl
c = pycurl.Curl()
c.setopt(pycurl.URL, '')
c.setopt(pycurl.HTTPGET, 1)
c.setopt(pycurl.SSL_VERIFYPEER, 1)
c.setopt(pycurl.CAINFO, 'ca.pem')
c.setopt(pycurl.SSL_VERIFYHOST, 2)

I am not a big fan of pycurl due to difficulties getting it compiled and the non-Pythonic API. But it is based on the very powerful curl library, so it comes full featured out of the box.

Other Resources

Besides the Python crypto libraries capable of doing SSL that I mentioned in my SSL in Python 2.6 article, I have found pycurl. Another find in the Python crypto front is cryptlib.

Mike Ivanov wrote a great series about crypto in Python: part 2, part 3 (link to part 1 seems to have rotted). Mike also produced a comparison of different Python crypto libraries (PDF).

The future is also looking bright for the ssl module. Already the upcoming Python 3.2 ssl module will include support for SSLContexts so that you can set options for multiple SSL connections at once, allows you to selectively disable SSL versions, and it allows you to check the OpenSSL version as well.

Space-Time Tradeoff

It is a pretty common strategy in programming circles to make programs run faster by making them use more space (for example, by caching some results from long computations so they don’t need to be done too often). But there is also another kind of space-time tradeoff: something not very elegant is taking a little too much space, but cleaning it up would take too much time and there are more important things to do. It occurred to me that I do this space-time tradeoff in my life outside of programming as well.

I have gathered piles and piles of once-important papers, magazines, books and so forth that I don’t think I will ever read. Likewise, I own a pile of clothes I will probably never wear again. I am sure I have lots of other things I basically never use, but I still have them stored somewhere, taking up unnecessary space. But if I wanted to get rid of all this stuff, I would need to spend quite a bit of time going through each potentially unneeded thing, deciding if I was ever going to use it, and if not, what should I do with it. So I reason that it is better to not worry about the unnecessary junk, as long as I have a place to put down a few important-for-now-at-least things…

Or it could just be that I am trying to rationalize being a pack-rat.

Bacon Rank Android App Details

Bacon Rank is currently my most ambitious Android project from UI and background processing point of view. It has custom UI controls and it deals gracefully with long running network operations.

Let’s start with the custom SeekBar first, which is used to select the number of strips of bacon you ate. When you have a touch screen device, especially with no physical keyboard, you want to avoid situations where the user is forced to type anything. In my case SeekBar works great, since you can’t eat that many strips of bacon at one sitting. To draw the SeekBar with custom images I created bacon_seekbar.xml in the drawable folder:

    android:drawable="@drawable/progress_mediumbacon" />
    android:drawable="@drawable/progress_rawbacon" />
    android:drawable="@drawable/progress_cookedbacon" />

The progress_* drawables are PNG images.

In the main layout I use the custom SeekBar and set a custom thumb (a PNG image of a skillet):


SeekBar has three states (if you count background), but I am really just using two. The weird part is that I thought I would use background and progress states, but I could not get that to work. Instead, I am using SecondaryProgress as background, and background is not visible anywhere. In onCreate I set up the SeekBar:

mSeekBar = (SeekBar)findViewById(;

In onProgressChanged method I update the amount in the UI and that is about it for the SeekBar. I think it looks pretty nice, but it would be better if I could make it look more 3D:

The trickiest part of the application was handling of the network activity while allowing for screen orientation changes. None of the tutorials I’ve read or the stackoverflow questions and answers regarding this seemed workable (or maybe I did not understand them). The problem is this: suppose in your activity you start an AsyncTask for the network activity. This is what is actually recommended pretty much everywhere. But suppose your user then changes the screen orientation. By default Android destroys and recreates the current activity. Your AsyncTask is still going, but it does not know about the new activity, and your new activity has no knowledge of the AsyncTask. So what is the fix?

It turns out you can create a custom application object, which will be available as long as your process is running. So in your activity you can start the AsyncTask as before, but keep a reference to the AsyncTask in the application object. The AsyncTask needs a reference to the current activity to draw on the screen, which your activity keeps up to date. Basically set it on AsyncTask creation, null it during screen orientation and activity destroy, and restore when the activity is recreated. We also want to run an indeterminate progress indicator in the UI while network activity is going. In code this looks something like this (I’m omitting many irrelevant details):

public class BaconApp extends Application {
    public BaconRank.SyncTask mSyncTask = null;
    // ...
public class BaconRank extends Activity implements SeekBar.OnSeekBarChangeListener {
    // ...
    public void onCreate(Bundle savedInstanceState) {
        // ...
    BaconRank.SyncTask getSyncTask() {
        return ((BaconApp)getApplication()).mSyncTask;
    void sync(String action) {
        ((BaconApp)getApplication()).mSyncTask = (SyncTask) new SyncTask(this).execute(getUserAgent(), mUserId,
    public void onSaveInstanceState(Bundle outState) {
        SyncTask syncTask = getSyncTask(); 
        if (syncTask != null) {
    public void onRestoreInstanceState(Bundle inState) {
        SyncTask syncTask = getSyncTask(); 
        if (syncTask != null) {
    public void onStop() {
        SyncTask syncTask = getSyncTask(); 
        if (syncTask != null) {
    public class SyncTask extends AsyncTask<String, Void, JSONObject> {
        // ...
        public SyncTask(BaconRank activity) {
            mActivity = activity;
        public void setActivity(BaconRank activity) {
            mActivity = activity;
        protected void onPreExecute() {
            if (mActivity != null) {
        protected void onCancelled() {
            // mActivity cannot be null
        void clearActivity() {
            // call in ui thread only
            ((BaconApp)mActivity.getApplication()).mSyncTask = null;            
        protected void onPostExecute(JSONObject result) {
            if (mActivity != null) {
                // Update UI
        protected JSONObject doInBackground(String... params) {
            // Do the network stuff
        // ...

You will also need to specify the custom application object in the AndroidManifest.xml:


And that wraps the Bacon Rank presentation. If you know how to do anything I presented above in a better way, please leave a comment. The application is also localizeable, so if you want to translate the app into your language let me know.

If you did not read it already, you might want to read about the application running, the server the Android application talks to. Powered by Turbogears 2

The website was written with the Turbogears 2 web application framework. It is pretty lightly modified from the quickstart project.

In the UI front the quickstart project used a lot of images to make rounded corners and so on to make everything look good in cross-platform way. I dislike this practice, so I decided to see if I could take the basic layout and not use any images for corners and backgrounds and the like. I think the result looks pretty good in modern browsers, including the default browser in Android 2.1. border-radius and -moz-linear-gradient did the bulk of the work. Which reminds me that I forgot to look for the equivalent of -moz-linear-gradient for other browsers…

The template language I used was Genshi, both because it is the default that comes with TG2 and the quickstart project, but also because I wanted to try out another template language as well. The thing I like about Genshi is that it guarantees I get well-formed output. However, its use of XPath can be a pretty steep learning curve to someone who doesn’t know XPath (like me). I did not see how to control the whitespace around elements: in some cases I have elements one on each row, other times they end up on the same row. I think I also could not get a comment to appear at the end of the document (to put in page rendering time, for example, although it turned out you’d need to hack tg2 itself to get the rendering time – unfortunately I lost the link).

I originally had bigger plans for the application, including forum, password recovery and so on, but canned those plans for now because I realized I could not find enough time to do all those and ship something before the summer. Part of that I did get in, although it is only exposed to the admin user. Being the security-minded geek that I am, I hacked the auth code to use bcrypt. I also learned about doing password comparison in a way that does not leak information due to timing.

I designed the small protocol that the Android client uses to communicate with the server. Most operations are covered by the following:

Initial sync:

POST /users

Location: /users/123

GET /users/123


Add bacon:

POST /users/123


Incidentally, if you'd like to write another client (iPhone anyone?), let me know...

I wanted to wrap the client API in its own class, but could not get that to work as a separate class so had to just settle with a method that does way too too much. Something I hope I can visit later.

I really wanted to like Turbogears 2 since it is based on my favorite, Pylons, but I actually felt that TG2 was getting in my way almost as often as it was helping me. I am happy that I did not have to write the auth code from scratch, and having the admin area almost as easy as in Django were big wins, but since I did not yet implement the forum (where I think I could really have used more of tg2's strengths) I would probably have been better off with plain Pylons. The documentation has been in flux the whole time I've been working on my app, some things working, some broken, and I had to resort to comments at the end of docs and doing web searches to try and figure things out. There were periods of time when the dependent packages were out of sync, and you could not even get a working quickstart project without setting version limits. I think that the controller methods not returning the actual string to render can be potentially big headache (for me, I just could not get the timing information output into the end of the returned HTML). I'd say TG2 has potential to be great, but right now things feel a little bit too unfinished. I know 2.1 will fix some of the issues I run into, but I don't know if anyone is looking at checking and cleaning up the documentation.

Bacon Rank Released

I am pleased to release Bacon Rank, the application you have been waiting for to count your bacon! (You may not have realized this, of course. I forgive you.)

I’ve been working on this application combo since last November, a few hours here and there. The server piece is a Turbogears 2 application, while the client piece is an Android application. As a whole, they form the Bacon Rank application ecosystem. The idea is that whenever you eat bacon, you submit the number of strips of bacon you ate, using the Android client, to the server. The server returns your statistics, including your rank compared to other users of the system. It is clearly a not very serious application, but it presented some interesting programming challenges.

I’ve been going through various Python web frameworks, and this time I wanted to learn about Turbogears 2. There isn’t anything especially groundbreaking about it, but I think it marks the first time I am actually running a real service. Of course it is also tied to the Android application, which makes it interesting.

The Android application is a bit more ambitious from engineering point of view. In the UI the trickiest piece was a customized SeekBar: uncooked bacon that becomes cooked as you move a skillet over it. I was also able to finally figure out how to make a background network request survive screen orientation change gracefully.

I am also experimenting with Twitter for the first time as a communications channel for the project.

In the next two posts I will explore the server and client pieces in more detail.

New Adventures

This news is a couple of weeks old, but I thought better late than never… For the past couple of years I was working at SpikeSource, on a variety of things ranging from Pylons and CherryPy applications to designing RESTful APIs and client libraries and even CakePHP and Java web applications (horror of horrors 😉 ). It was never a good fit culturally, though, so just before my two year anniversary came around I decided I needed a change.

I decided to be very focused on my search: Python web application development, startups, and ideally located from Sunnyvale to Palo Alto. I used mostly and for my search, with a couple of hints from friends. I applied to eight jobs, and got five interviews. I was quite surprised that there were so many companies matching my preferences within such a small area hiring at the time when I was looking! I was also pleasantly surprised that I got into as many interviews as I did; last time around I had a bit worse success rate. Hint: requirements aren’t necessarily requirements in job postings.

Unfortunately I learned I am bad at interviews aimed at Python web application developers. For some reason I find coding questions a lot easier to answer when they are in C. I was also badly prepared to answer a few questions related to web development; having not thought about something for a while makes a bad interview impression. Note to my future self: start practicing at least a week before interviews, practice in Python on problems designed to be solved in Python (maybe Python challenges, Facebook programming puzzles and the like), and check with friends for some common web developer questions. Assuming I were to look for that kind of job next time around, of course.

To make long story short, I decided to join Aahz at Egnyte. Egnyte provides cloud storage, backup and sharing services. My first task involves integrating new UI design to a CherryPy application using Cheetah templates. I am also working on a Mac after many years on Linux.

Nexus One Radio Follow-up

As you have probably gathered by now, my earlier announcement was an April Fools’ prank. Unfortunately I had forgotten to adjust my blog settings for Daylight Saving Time, so the URL and time on the post refer to the previous day, even thought it was posted a few minutes into April 1st.

I got the idea for the prank out of the blue around 11 pm, and had the application ready a few minutes before midnight, so I waited for that to pass to create the .apk and post it to Android Market. Most of the development time went into finding a suitable image of a radio and scaling and cropping it (as you can guess, Gimp gives me trouble). I used the Creative Commons search engine to find the image.

I was pretty satisfied with the results. According to Android Market statistics, the application was installed 10741245 times (although the real number is somewhat higher since the statistics don’t update in real time), has 7787 ratings with average around 3.5. Not bad for less than 24 hours of exposure. Some of my favorite comments were from people who were fully on board with the prank:

  • Pretty good. Can’t seem to tune below 88.9
  • OMG this best radio player ever. Pandora and Slacker don’t even come close.
  • nice hack 🙂 Will pre-sets be available in the future? :-p
  • would be a 5 if the dialer was more accurate. great job dev! 🙂

There were also others who seemed to have fully fallen for it without liking it ;):

  • Wasted about 2 minutes of my life. . Don’t bother, feeble prank !
  • I hate you.

Of course there were also a number of spoilsports who just gave one star and mentioned it was a prank app. Shame on you.

I got one support email asking if it would work on HTC Touch. Also the comment in the original blog post about collaborating on a droid project makes me wonder if I fooled that person or if they were in on it.

Seems like I also fooled some people on

Since this was a joke app just for today, I’ve unpublished the app from Android Market. So if you are one of the 300+ people who still got the app installed, you are suddenly the owner of a rarity 🙂

Nexus One Radio

If you have been wondering why I haven’t posted in a while, it is because I have been hard at work on my most ambitious Android project to date. When Google came out with the Nexus One phone I was quick to grab one. But one thing about the hardware has always bugged me. The Nexus One contains an FM radio, but there wasn’t any way to use it from software. Until now! I have painstakingly tracked down the hardware details and reverse engineered the API needed to get the radio to appear. The UI is pretty primitive. Go grab yourself an early build of Nexus One Radio (see ratings on Cyrket). Search for it in the Android Market!

Update: Please see the follow-up!