0

I am trying to create a certificate in python that was previously built using the openssl ca command. Everything works flawless except one thing: I need to add the "nsCertType" extension, which seems to be deprecated. However, I could not find a way to add arbitrary certificate extensions. This guy is asking the same question for go, and even specifies a solution for python using OpenSSL, however I can not figure out how to do it without OpenSSL. Here is my code:

    inter_server_cert = x509.CertificateBuilder().subject_name(
    subject
).issuer_name(
    inter_ca_cert.issuer
).public_key(
    inter_server_key.public_key()
).serial_number(
    x509.random_serial_number
).not_valid_before(
    datetime.datetime.utcnow()
).not_valid_after(
    datetime.datetime.utcnow() + datetime.timedelta(days=duration_rootca)
).add_extension(
    x509.BasicConstraints(
        ca=False, path_length=0
    ),
    critical=True
).add_extension(
    x509.SubjectKeyIdentifier.from_public_key(inter_server_key.public_key()),
    critical=False
).add_extension(
    x509.AuthorityKeyIdentifier.from_issuer_subject_key_identifier(authority_key_identifier.value),
    critical=False
).add_extension(
    x509.KeyUsage(
        key_cert_sign=False,
        crl_sign=False,
        digital_signature=True,
        content_commitment=False,
        key_encipherment=True,
        data_encipherment=False,
        key_agreement=True,
        encipher_only=False,
        decipher_only=False
    ),
    critical=False
).add_extension(
    x509.ExtendedKeyUsage([x509.oid.ExtendedKeyUsageOID.SERVER_AUTH]),
    critical=False
).sign(inter_ca_key, hashes.SHA256(), default_backend())
Gasp0de
  • 1,199
  • 2
  • 12
  • 30

1 Answers1

3

You can encode arbitrary extensions in cryptography by using UnrecognizedExtension. This is not directly documented, but you can see an example of it in use in the tests (https://github.com/pyca/cryptography/blob/3367c18bf2e71639843e38498f5ad2159835122d/tests/x509/test_x509.py#L3327).

Note that you must supply the OID and the already DER encoded payload as bytes. If you have a sample certificate with the value you need you can parse that to obtain the correct sequence.

Paul Kehrer
  • 13,466
  • 4
  • 40
  • 57
  • Thank you, this worked exactly as expected. If anyone stumbles upon this in the future, the OID for nsCertType and the payload for the value "server" are: `x509.UnrecognizedExtension(oid=x509.ObjectIdentifier('2.16.840.1.113730.1.1'), value=b'\x03\x02\x06@')` – Gasp0de Sep 10 '20 at 09:55
  • Thank you Paul, exactly what I was looking for. – pixis Jun 23 '21 at 14:18