Coder Social home page Coder Social logo

pem's Introduction

pem: Easy PEM file parsing

https://secure.travis-ci.org/hynek/pem.png

pem is an MIT-licensed Python module for parsing and splitting of PEM files, i.e. Base64 encoded DER keys and certificates.

It runs on Python 2.6, 2.7, 3.3, 3.4, and PyPy 2.0+, has no dependencies and does not attempt to interpret the certificate data in any way. pem is intended to ease the handling of PEM files in combination with PyOpenSSL and – by extension – Twisted.

It’s born from my personal need because of the inconsistent handling of chain certificates by various servers: some servers (like Apache) expect them to be a separate file while others (like nginx) expect them concatenated to the server certificate. Since I want my Python software to be universal and to be able to cope with both, pem was born.

The core API call is the function parse():

import pem

with open('cert.pem', 'rb') as f:
   certs = pem.parse(f.read())

The function returns a list of valid PEM objects found in the string supplied. Currently possible types are DHParameters, Certificate, and RSAPrivateKey. Both can be transformed using str() into plain strings for other APIs. They don’t offer any other public API at the moment.

Convenience

Since pem is mostly a convenience module, there are several helper functions.

Files

parse_file(file_name) reads the file file_name and parses its contents. So the following example is equivalent with the first one:

import pem

certs = pem.parse_file('cert.pem')

Twisted

A typical use case in Twisted with the APIs above would be:

import pem

from twisted.internet import ssl

key = pem.parse_file('key.pem')
cert, chain = pem.parse_file('cert_and_chain.pem')
cert = ssl.PrivateCertificate.loadPEM(str(key) + str(cert))
chainCert = ssl.Certificate.loadPEM(str(chain))

ctxFactory = ssl.CertificateOptions(
      privateKey=cert.privateKey.original,
      certificate=cert.original,
      extraCertChain=[chainCert.original],
)

Turns out, this is the major use case for me. Therefore it can be simplified to:

import pem

ctxFactory = pem.certificateOptionsFromFiles(
   'key.pem', 'cert_and_chain.pem',
)

The first certificate found will be used as the server certificate, the rest is passed as the chain. You can pass as many PEM files as you like. Therefore you can distribute your key, certificate, and chain certificates over a arbitrary number of files. A ValueError is raised if more than one key, no key, or no certificate are found. Any further keyword arguments will be passed to CertificateOptions.

If you want to load your PEM data from somewhere else, you can also use certificateOptionsFromPEMs to do the same thing with already-loaded Certificate, Key, and RSAPrivateKey objects, like so:

import pem

myPems = []
pems = pem.parse("""\
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
""")

ctxFactory = pem.certificateOptionsFromPEMs(pems)

Ephemeral Diffie-Hellman support

Starting with version 14.0.0, Twisted will support ephemeral Diffie-Hellman ciphersuites; you can pass an instance of twisted.internet.ssl.DiffieHellmanParameters as the dhParameters keyword argument to CertificateOptions. Since pem just passes keyword arguments to CertificateOptions verbatim, that will just work.

However, pem is also forward compatible. If your version of Twisted predates 14.0.0, pem lets you use the API described above anyway. You can just use pem.DiffieHellmanParameters: if your version of Twisted comes with that class, you just get the Twisted version; if it doesn't, you get a version from pem.

Just pass instances of that class as dhParameters to certificateOptionsFromFiles, and pem will make it magically work:

import pem

from twisted.python.filepath import FilePath

path = FilePath("/path/to/the/dh/params")
ctxFactory = pem.certificateOptionsFromFiles(
   'key.pem', 'cert_and_chain.pem',
   dhParameters=pem.DiffieHellmanParameters.fromFile(path)
)

Future

pem currently only supports the PyOpenSSL/Twisted combo because that’s what I’m using. I’d be more than happy to merge support for additional frameworks though!

pem's People

Contributors

bitdeli-chef avatar derwolfe avatar glyph avatar hynek avatar lvh avatar thedrow avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.