Question

I have a valid certificate issued by the spanish authority (FNMT) and I want to play with it to learn more about it. The file has extension .p12

I would like to read the information in it (first and last name) and check if the certificate is valid. Is it possible to do that with pyOpenSSL? I guess I have to use the crypto module in OpenSSL. Any help or useful link? Trying reading here: http://packages.python.org/pyOpenSSL/openssl-crypto.html but not much information :-(

Was it helpful?

Solution

It's fairly straight-forward to use. This isn't tested, but should work:

# load OpenSSL.crypto
from OpenSSL import crypto

# open it, using password. Supply/read your own from stdin.
p12 = crypto.load_pkcs12(open("/path/to/cert.p12", 'rb').read(), passwd)

# get various properties of said file.
# note these are PyOpenSSL objects, not strings although you
# can convert them to PEM-encoded strings.
p12.get_certificate()     # (signed) certificate object
p12.get_privatekey()      # private key.
p12.get_ca_certificates() # ca chain.

For more examples, have a look through the unit test code of pyopenssl. Pretty much every way you might want to use the library is there

See also here or without adverts here.

OTHER TIPS

Maybe is wrong answering to an old Q, but I thought that it may help someone that find this Q after me. This solution work for python 3, and I think is a little bit better. I found it in the repo of zeep and is a class to encapsule the usage.

Class

import os
from OpenSSL import crypto

class PKCS12Manager():

    def __init__(self, p12file, passphrase):
        self.p12file = p12file
        self.unlock = passphrase
        self.webservices_dir = ''
        self.keyfile = ''
        self.certfile = ''

        # Get filename without extension
        ext = os.path.splitext(p12file)
        self.filebasename = os.path.basename(ext[0])

        self.createPrivateCertStore()
        self.p12topem()

    def getKey(self):
        return self.keyfile

    def getCert(self):
        return self.certfile

    def createPrivateCertStore(self):
        home = os.path.expanduser('~')
        webservices_dir = os.path.join(home, '.webservices')
        if not os.path.exists(webservices_dir):
            os.mkdir(webservices_dir)
        os.chmod(webservices_dir, 0o700)
        self.webservices_dir = webservices_dir

    def p12topem(self):
        p12 = crypto.load_pkcs12(open(self.p12file, 'rb').read(), bytes(self.unlock, 'utf-8'))

        # PEM formatted private key
        key = crypto.dump_privatekey(crypto.FILETYPE_PEM, p12.get_privatekey())

        self.keyfile = os.path.join(self.webservices_dir, self.filebasename + ".key.pem")
        open(self.keyfile, 'a').close()
        os.chmod(self.keyfile, 0o600)
        with open(self.keyfile, 'wb') as f:
            f.write(key)


        # PEM formatted certificate
        cert = crypto.dump_certificate(crypto.FILETYPE_PEM, p12.get_certificate())

        self.certfile = os.path.join(self.webservices_dir, self.filebasename + ".crt.pem")
        open(self.certfile, 'a').close()
        os.chmod(self.certfile, 0o644)
        with open(self.certfile, 'wb') as f:
            f.write(cert)

Usage

from requests import Session
from zeep import Client
from zeep.transports import Transport

# https://github.com/mvantellingen/python-zeep/issues/824
pkcs12 = PKCS12Manager('cert.p12', 'password_for_cert')
session = Session()
session.cert = (pkcs12.getCert(), pkcs12.getKey())

transport = Transport(session=session)
client = Client('url_service', transport=transport)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top