Search code examples
pythonx509pyopenssl

Extract the value of a X.509 certificate custom extension using PyOpenSSL


Using Python and PyOpenSSL, is there a way to retrieve the value of a custom extension? By custom extension, I mean an extension encoded using the arbitrary extension format described under ARBITRARY EXTENSIONS at http://www.openssl.org/docs/apps/x509v3_config.html.

Also, is it possible to create a certificate that contains such an extension using PyOpenSSL?

If the answer to either of these is "no", I would also be interested in pointers on how to do this with any other Python library. I do not want to perform system calls to the OpenSSL command line app.


Solution

  • You can get any and all extensions on an X.509 certificate you've loaded using pyOpenSSL. For example:

    >>> from OpenSSL import crypto as c
    >>> cert = c.load_certificate(c.FILETYPE_PEM, file('server.pem').read())
    >>> cert.get_extension_count()
    4L
    >>> ext = cert.get_extension(0)
    >>> ext.get_short_name()
    'basicConstraints'
    >>> ext.get_data()
    '0\x00'
    >>> 
    

    The data comes out in its raw format (some encoding of ASN.1, perhaps depending on the specific extension).

    You can also add extensions.

    >>> newext = c.X509Extension('nsComment', 0, 'tacos are delicious')
    >>> cert.add_extensions([newext])
    >>> cert.get_extension_count()
    5L
    >>> cert.get_extension(4)
    <X509Extension object at 0x7f74db7c2290>
    >>> cert.get_extension(4).get_data()
    '\x16\x13tacos are delicious'
    >>> 
    

    However, note the slight asymmetry. The extension data must be a string and is encoded using ASN.1 automatically. This seems to preclude the possibility of adding arbitrary non-string extension data.