ActiveBlog

Python Crypto: State of the Art (Part 2)
by Mike Ivanov

Mike Ivanov, March 1, 2010

Open SSL


Let's take a closer look at some of the modules mentioned in the previous article.

M2Crypto: A Python crypto and SSL toolkit

Official description
M2Crypto is the most complete Python wrapper for OpenSSL featuring RSA, DSA, DH, HMACs, message digests, symmetric ciphers (including AES); SSL functionality to implement clients and servers; HTTPS extensions to Python's httplib, urllib, and xmlrpclib; unforgeable HMAC'ing AuthCookies for web session management; FTP/TLS client and server; S/MIME; ZServerSSL: A HTTPS server for Zope and ZSmime: An S/MIME messenger for Zope. M2Crypto can also be used to provide SSL for Twisted.

Home Page
http://chandlerproject.org/Projects/MeTooCrypto

Source repository
http://svn.osafoundation.org/m2crypto/

Documentation
http://www.heikkitoivonen.net/m2crypto/api/

http://chandlerproject.org/Projects/MeTooCrypto#Documentation
Mantainer
Heikki Toivonen

License
BSD-style

Latest version
0.20.2 (2009-10-07)

Discussion

M2Crypto is an offspring of the ambitious Chandler Project correction Despite the main project's death — nobody seems to be working on Chandler — M2Crypto is still alive and kicking. M2Crypto was started and mostly developed by Ng Pheng Siong. The current maintainer is Heikki Toivonen.

Even though the official OpenSSL documentation does not mention it, Elliptic Curve, AES and even GOST algorithms are presented in the OpenSSL source code and are exposed in M2Crypto. Access to those is tricky though.

Here we should note one peculiarity in the underlying OpenSSL library's architecture. OpenSSL, roughly, has two separate sets of low-level algorithms. One set includes "old" implementations of algorithms like RSA, RC4 and the Elliptic Curve stuff. The other set of "new" implementations includes algorithms like AES and GOST wrapped into pluggable engines. These engines are nothing more than loadable binary modules, invokable through some kind of a higher-level API. This API is called EVP which stands for, I guess, "EnVeloPe".

Those two algorithm sets are not matching, that is, not everything accessible through the EVP interface is available through the "old" low-level interface and vice versa. To add more fun, the two sets cannot be mixed together.

During the PyCon 2010 we had a set of open Python Crypto sessions. We discussed a lot of things, including whether OpenSSL is the right choice at all. A range of opinions was expressed, though the consensus was that OpenSSL is some kind of "necessary evil"; everyone hates it, but it is everywhere. This is one of the strongest points of OpenSSL: it is here forever.

Someone pointed out that OpenSSL was designed as a... well, an SSL implementation library with an architecture centric to secure communications. Indeed, OpenSSL is more or less well suited for client-server interaction programming, but it is not good at all for solving other tasks like secure data storage, secure document workflow, etc.

Another problem everyone agreed on is the lack of documentation. The original OpenSSL documentation is outrageously eclectic, to say the least. This is, by the way, directly related to the internal library architecture. The situation with M2Crypto documentation (with all the respect to Ng's and Heikki's hard work) is not any better than with OpenSSL itself, it's just automatically generated Epydoc stuff.

There is one more thing. Although OpenSSL, and consequently M2Crypto, support pluggable modules, those have to be written in C. That is, there is no way of substituting a core algorithm with a custom Python implementation. This problem, however, is common to all wrapper-type modules rather than specific to M2Crypto.

Python-nss: Python bindings for NSS/NSPR

Official description
Network Security Services (NSS) is a set of libraries supporting security-enabled client and server applications. Applications built with NSS can support SSL v2 and v3, TLS, PKCS #5, PKCS #7, PKCS #11, PKCS #12, S/MIME, X.509 v3 certificates, and other security standards. NSS has received FIPS 140 validation from NIST. The python-nss feature provides a Python binding to NSS and the NSPR support libraries.

Home Page
http://fedoraproject.org/wiki/Features/PythonNSS

Documentation
http://people.redhat.com/jdennis/python-nss/doc/api/html/index.html

Source repository
http://bonsai.mozilla.org/rview.cgi?dir=mozilla/security/python/nss&cvsroot=/cvsroot&module=SecurityServices

Mantainer
John Dennis

License
Mozilla Public License v1.1

Latest version
0.8 (2009-09-13)

Discussion

The python-nss package is a result of RedHat's engineering effort to hand code NSS bindings from scratch. The underlying library, NSS (Network Security Services), is a set of libraries designed to support cross-platform development of security-enabled client and server applications. NSS is a ten years old Mozilla.org project.

The good news about NSS is that documentation is abundant and luxuriously comprehensive. The python bindings documentation starts with a Getting Started section and a short example, and that's it. The rest of it is the same boring, automatically generated API reference — nothing that one couldn't see in the source code.

The NSS library architecture is clear and fairly straightforward, though it is quite a low-level API. Python bindings, as mentioned above, are not just SWIG's output, but rather a carefully crafted OO-styled interface. Algorithm coverage is quite impressive: both ECC and AES are there.

Now the worrisome things. First of all, I could not find a sign of any kind of plugin-type modularity; the library seems to be a monolith with no way to alter its behavior.

Another issue is the NSPR (Netscape Portable Runtime) library. This is an opinionated library, limiting the choice of socket implementations to just its own. The only way to create a secure socket with NSS is to use NSPR socket implementation. To make it worse, NSPR sockets are incompatible with existing Python I/O and cannot be passed to functions expecting Python sockets as arguments. This, particularly, makes non-blocking secure socket I/O impossible.

NSS has something in common with OpenSSL: the both are network-centric toolkits, which raises the same question whether NSS — while being an excellent network security tool — is a good cryptography package for general use.

(to be continued)

Subscribe to ActiveState Blogs by Email

Share this post:

About the Author: RSS

Mike Ivanov is a senior developer with significant experience building scalable web applications using Python, PostgreSQL and Linux, and a special interest in cloud computing and distributed systems. He has a Masters Degree in Computer Science (Large-Scale System Control) from the Krasnojarskij Gosudarstvennyj Tehniceskij university (really!).

Comments

2 comments for Python Crypto: State of the Art (Part 2)
Permalink

Minor corrections regarding M2Crypto. M2Crypto was started by Ng Pheng Siong before the Chandler project even became aware of it. When I joined the Chandler project in 2003, we needed a Python crypto module that could do SSL and some X.509 handling outside of SSL. At that time it seemed M2Crypto was the best option, so I started contributing to it to adapt it for Chandler needs. M2Crypto didn't have public source control repository, so OSAF offered one. Soon after Ng decided to pass the maintenance of M2Crypto to me.

Regarding documentation, the link above points to the generated API documentation, but the M2Crypto homepage has a documentation section that includes links to a handful of documents describing how to use SSL, SMIME etc. I think the unit tests count as good documentation/example as well. Personally I find the OpenSSL book to be a tremendous help in working with any OpenSSL or any of the libraries built on top of OpenSSL. But I do agree that the situation could be much, much better.

Finally, you made a typo with my last name ;)

Thanks for writing this series, by the way!

Permalink

Heikki, the typo is fixed and a link to the #Documentation is added. Thanks a lot for the comment!