I am attempting to generate a self-signed cert with a SubjectAltName of type DirName. Other types of SubjectAltName like DNS work just fine, but DirName will not work. The code to reproduce fairly simple (python 3.8.5)
import string
from OpenSSL import crypto
def _create_csr():
key = crypto.PKey()
key.generate_key(crypto.TYPE_RSA, 2048)
csr = crypto.X509Req()
csr.set_pubkey(key)
works = "DNS:abc.xyz"
fails = "dirName:MyGeneratedCert"
csr.add_extensions([crypto.X509Extension(b"subjectAltName", False, fails.encode("ascii"))])
csr.sign(key, "sha256")
if __name__=="__main__":
_create_csr()
The exception I am receiving is as the following
Traceback (most recent call last):
File "tests/createcert.py", line 16, in <module>
_create_csr()
File "tests/createcert.py", line 12, in _create_csr
csr.add_extensions([crypto.X509Extension(b"subjectAltName", False, fails.encode("ascii"))])
File "/usr/lib/python3/dist-packages/OpenSSL/crypto.py", line 779, in __init__
_raise_current_error()
File "/usr/lib/python3/dist-packages/OpenSSL/_util.py", line 54, in exception_from_error_queue
raise exception_type(errors)
OpenSSL.crypto.Error: [('X509 V3 routines', 'X509V3_get_section', 'operation not defined'), ('X509 V3 routines', 'do_dirname', 'section not found'), ('X509 V3 routines', 'a2i_GENERAL_NAME', 'dirname error'), ('X509 V3 routines', 'X509V3_EXT_nconf', 'error in extension')]
The call is making it into OpenSSL's do_dirname function (stack trace). I assume that the value is not being passed in in correct way, but I cannot understand how to pass it as desired.
Any help would be appreciated.
You cannot, via python, because dirName references a value in the configuration database, but pyOpenSSL does not provide an interface to create a configuration database.
Background: dirName references a section in the database, which could be a config file. Reference the x509v3_config tool, for example (https://github.com/openssl/openssl/blob/master/doc/man5/x509v3_config.pod) where you may use a config file:
[extensions]
subjectAltName = dirName:dir_sect
[dir_sect]
C = UK
O = My Org
OU = My Unit
CN = My Name
Note how dirName simply refers to a different section in the configuration database.
But pyopenssl does not have a provision for creating such a database, so your dirName reference won't be found -- hence your error.
Note this is a known limitation. The Python code itself includes mention of lack of configuration database: See comment in code: https://github.com/pyca/pyopenssl/blob/master/src/OpenSSL/crypto.py, line approx 754:
# We have no configuration database - but perhaps we should (some
# extensions may require it).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With