The eGenix.com pyOpenSSL Distribution includes everything you need to get started with the SSL protocol and its OpenSSL implementation in Python.
The distribution comes with an easy to use installer that includes the most recent OpenSSL library versions in pre-compiled form, pyOpenSSL to access the SSL parts, which allows writing SSL-aware networking applications as as certificate managment tools and a few additional tools to make working with SSL easy and safe in Python.
It uses the OpenSSL is a performant and robust open-source library implementation of the SSL protocol.
The current version of pyOpenSSL shipped with the eGenix.com pyOpenSSL Distribution can always be determined by looking at the first part of the distribution file version number. The current version of OpenSSL is encoded in the second part of the distribution file version number.
As example, version 0.13.1.1.0.1.5 means that we have taken pyOpenSSL 0.13 and added OpenSSL 1.0.1e (the letter is converted into a number a=1, b=2, etc.). Since we've added a new module to pyOpenSSL, we've bumped the version number to 0.13.1, instead of using 0.13.0. Please see the change log for details.
In some cases, we have to release distribution updates, which we then signal by attaching an additional version integer to the end of the version string, e.g. 0.13.1.1.0.1.5.1.
To avoid patent issues, we have excluded the following algorithms from OpenSSL via its config options: IDEA, MDC2 and RC5. We also removed the Kerberos5 support, since it's not needed for SSL-based communication.
Starting with version 0.13.1.1.0.1.5, we always include the most recent certificate authority (CA) certificate bundle derived from the from Mozilla Firefox browser code base
as CRT file with the distribution and also include a helper module
OpenSSL.ca_bundle
to easily access this embedded CA
certificate list for
verification purposes. The CA bundle is updated with each new release of
the eGenix pyOpenSSL distribution, but also make it available as separate download.
The documentation for pyOpenSSL is available from the pyOpenSSL web-site.
pyOpenSSL Package Documentation
The manual includes a reference of the available programming interfaces. All APIs live in the top-level OpenSSL Python package.
Unfortunately, the OpenSSL documentation is not very complete. Most parts of the OpenSSL API are documented in form of man pages. The SSL API is documented in ssh (3) and the referenced man pages. The crypto API, which is not exposed by pyOpenSSL but includes useful information regarding available hashes and ciphers, is documented in crypto (3).
openssl Command Line Interface
The
openssl
command line interface is included with the eGenix pyOpenSSL Distribution.In the current release, there is no direct Python interface to the tool yet, but you can find it by looking up the
OpenSSL/
package directory.
We have included a few useful additions in our eGenix pyOpenSSL Distribution. This sections documents these additions.
Helper to load the included CA bundle, derived from the official Mozilla CA root trust file located at:
http://mxr.mozilla.org/mozilla-release/source/security/nss/lib/ckfw/builtins
/certdata.txt?raw=1
Provides access to the data stored for each certificate in the CA bundle.
certificate = ''
Certificate in PEM format.
description = ''
Text description.
name = ''
Name of the certificate.
sha1 = ''
SHA1 fingerprint using 2-digit-hex colon separated format (the OpenSSL format used by .digest())
.__init__(self, name, sha1, description, certificate)
Create a new CARootCertificate instance from the CA bundle data. See the attribute descriptions for details on the parameter meanings.
.get_x509(self)
Return the certificate as pyOpenSSL X509 object.
.hexdigest(self)
Return the SHA1 fingerprint in the Python .hexdigest() format (two digit lower case hex numbers).
get_ca_bundle(path='
Return the CA root certificate bundle as text.
path defaults to the path of the included CA root certificate
bundle, if not given.
get_ca_bundle_path()
Return the absolute file path to the CA root certificate
bundle file.
This can be passed to the pyOpenSSL Context method
.load_verify_locations(pemfile, capath) as pemfile.
iter_ca_bundle(bundle=None)
Iterate over all certificates in the CA root certificate
bundle and return them as CARootCertificate instances.
bundle defaults to the included CA root certificate bundle, if
not given.
iter_ca_bundle_x509(bundle=None)
Iterate over all certificates in the CA root certificate
bundle and return them as x509 instances.
bundle defaults to the included CA root certificate bundle, if
not given.
This can be used to load trusted certificates into the
pyOpenSSL Context certificate store and provides a way to load
the certificates without going through the file system.
The source distribution of the
eGenix pyOpenSSL Distribution contains an example script which show how
to use the ca_bundle module to setup server certificate validation: examples/https_client.py
.
The example script sets up a socket for SSL communication and then reads the first 500 bytes from the homepage of a server.
In order to have OpenSSL verify the server side certificate, two things have to be done:
Here's the essential part of the SSL context setup:
from OpenSSL import SSL, ca_bundle ... context = SSL.Context(SSL.TLSv1_METHOD)
# Set client key pair to use
context.use_certificate_file(certificate)
context.use_privatekey_file(private_key)
# Double-check certificate/key pair
context.check_privatekey()
# Enable peer certificate verification
context.load_verify_locations(ca_bundle.get_ca_bundle_path(), None)
context.set_verify(SSL.VERIFY_PEER |
SSL.VERIFY_FAIL_IF_NO_PEER_CERT |
SSL.VERIFY_CLIENT_ONCE,
verify_callback)
context.set_verify_depth(10)
With this SSL context, all connections using this context will verify the server (aka peer) certificates against the embedded CA bundle file.
In order to run the example script, you need to provide a client-side certificate/key pair. The examples/
directory already contains a demo certificate/key pair called cert.pem
and pkey.pem
which you can use.
If you want to run the example
script, you can use the included openssl
command line to create a new
self-signed key/certificate pair:
cd examples/
# Create a private key file with 2048 bits (also includes the public key)
openssl genrsa -out pkey.pem 2048
# Create a self-signed certificate, valid for 10 years using the key file;
# the tool will ask a few questions about the certificate owner
openssl req -new -x509 -days 3650 -key pkey.pem -out cert.pem
# Print the certificate
openssl x509 -text -in cert.pem
There is a little known detail about the underlying OpenSSL engine that can cause problems in multi-threaded applications:
OpenSSL does not support sharing connections between threads. If you do, you are likely going to cause OpenSSL and thus pyOpenSSL to get into an unstable state which could result in anything from lost data to corrupted data and in some situations even lead to segfaults.
pyOpenSSL includes an undocumented tsafe.py module which wraps connection objects with a thread lock to work around the problem.
Other than this limitation, OpenSSL and pyOpenSSL work just fine in a multi-threaded environment.
The OpenSSL libraries use a configuration file for definition of
default configuration settings, locations of certificates, keys, etc.
The file is usually called openssl.cnf
and searched for by the libraries in the OpenSSL configuration directory, which has to be set at compilation time.
Please note that pyOpenSSL itself currently does not use the openssl.cnf
file.
The library is not calling the needed APIs for OpenSSL to automatically
read the configuration file and doesn't expose these APIs in Python
either. This may change in a future version.
The eGenix pyOpenSSL distribution uses these OpenSSL default directories/file locations:
Linux:
/etc/ssl/openssl.cnf (configuration)
/etc/ssl (base config dir)
/etc/ssl/certs/ (certificate dir)
/etc/ssl/private/ (private key dir)
Mac OS X:
/System/Library/OpenSSL/openssl.cnf (configuration)
/System/Library/OpenSSL/
(base config dir)/System/Library/OpenSSL/
certs/ (certificate dir)/System/Library/OpenSSL/
private/ (private key dir)
Windows:
c:\openssl\
openssl.cnf (configuration)
c:\openssl\
(base config dir)
c:\openssl\
certs\ (certificate dir)
c:\openssl\
private\ (private key dir)
You can override the locations using the environment variables OPENSSL_CONF
(pathname of openssl.cnf), SSL_CERT_DIR
(certificate dir) and SSL_CERT_FILE
(certificate bundle file).
This normally happens automatically, but there are a few things to consider on Linux and Mac OS X:
If you want to make sure the Python process does indeed load the embedded OpenSSL libraries and not the system provided ones, make sure you load pyOpenSSL before the Python socket or ssl module (or any other Python module which uses these modules). The library load gets triggered by loading the top-level OpenSSL module:
import OpenSSL
Please note that you either need egenix-mx-base version 3.1 or later, or the Python ctypes
module
installed for this to work. The module will fall back to the system
libraries in case loading the embedded libraries fails. You can set the
environment variable EGENIX_PYOPENSSL_DEBUG
to 1 if you want to debug the automatic import of the embedded library files.
Another option is adding the OpenSSL package directory to the LD_LIBRARY_PATH
environment variable.
On Windows, no additional Python modules are needed, since the linker will find the embedded libraries automatically.
eGenix offers these support options:
Professional level support for this product as well as all other eGenix products and Python itself is available directly from the developers at eGenix.com.
eGenix.com offers professional consulting services for all questions and tasks around this product, including customized modifications, help with integration and on-site problem solving. Please contact sales@egenix.com for details.
In order for our users to keep in touch and be able to help themselves, we have created the egenix-users user mailing list.
This product includes cryptographic software written by Eric Young (eay@cryptsoft.com). This product includes software written by Tim Hudson (tjh@cryptsoft.com). This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit. (http://www.openssl.org/)