简体   繁体   中英

Python pyOpenSSL sign certificate with a given extension set

Given a CA file containing these extension sets:

[ usr_cert ]
# Extensions for client certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = client, email
nsComment = "OpenSSL Generated Client Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, emailProtection

[ server_cert ]
# Extensions for server certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth

Using "regular" openssl I can create a cert given a CSR and the following statement:

openssl ca -config intermediate/openssl.cnf -extensions server_cert -days 375 -notext -md sha256 -in intermediate/csr/www.example.com.csr.pem -out intermediate/certs/www.example.com.cert.pem

I'd like to do the same using pyOpenSSL, however, I can't find a method on the crypto.X509() class that allows me to do this:

cert = crypto.X509()
cert.set_issuer(caCert.get_subject())
cert.set_serial_number(1)
cert.set_notAfter("20170201000000Z")
cert.set_notBefore("20160201000000Z")
cert.set_subject(deviceCsr.get_subject())
cert.set_issuer(issuer=caCert.get_issuer())
cert.set_pubkey(deviceCsr.get_pubkey())
cert.sign(CAprivatekey, "sha1")

I can see a cert.add_extensions, but that doesn't seem to allow adding a "template", but rather exlicit extensions such as critical, digitalSignature, keyEncipherment etc.

Is there a way I can specify the "template"/extension set in pyOpenSSL when creating a cert?

EDIT: Thinking about this more, I realize that pyOpenSSL doesn't care about the ca.conf file at all, it just uses the ca cert to sign the new server cert in question and that's it. So I gues my question should rather be: Is there a way to have pyopenssl use the config from the ca.conf file at all, or do I have to create all the options in code? if true then it certainly looks like it's easier to just have python shell out to openssl in order to generate the cert.

Here is an example on how to set various extensions. Each extension has a different data/payload.

You got the extension name, they critical flag and last is the extension data.

extensions = [
    crypto.X509Extension(b'basicConstraints', False, b'CA:FALSE'),
    crypto.X509Extension(b'keyUsage', 'digitalSignature, nonRepudiation', keyusage),
    crypto.X509Extension(b'extendedKeyUsage', True, b'serverAuth'),
    crypto.X509Extension(b'subjectAltName', False, b'DNS:www.ex.com,IP:1.2.3.4')
    ]
cert.add_extensions(extensions)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM