CSR submitted to IIS CA fails due to ASN1 value

1

I have generated a private key / CSR from pyOpenSSL - code snippet below:

Key:

key = crypto.PKey()
key.generate_key(type, bits)
if os.path.exists(_keyfile):
    print "Certificate file exists, aborting."
    print " ", _keyfile
    sys.exit(1)
else:
    f = open(_keyfile, "w")
    f.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, key))
    f.close()
return key

CSR:

req = crypto.X509Req()
# Return an X509Name object representing the subject of the certificate.
req.get_subject().countryName = country
req.get_subject().stateOrProvinceName = state
req.get_subject().localityName = location
req.get_subject().organizationName = organisation
req.get_subject().organizationalUnitName = organisational_unit
req.get_subject().CN = nodename
# Add in extensions
#base_constraints = ([
#    crypto.X509Extension("keyUsage", False, "Digital Signature, Non Repudiation, Key Encipherment"),
#    crypto.X509Extension("basicConstraints", False, "CA:FALSE"),
#])
#x509_extensions = ([])
x509_extensions = []
# If there are SAN entries, append the base_constraints to include them.
if ss:
    san_constraint = crypto.X509Extension("subjectAltName", False, ss)
    x509_extensions.append(san_constraint)
req.add_extensions(x509_extensions)
# Set the public key of the certificate to pkey.
req.set_pubkey(key)
# Sign the certificate, using the key pkey and the message digest algorithm identified by the string digest.
req.sign(key, "sha1")
# Dump the certificate request req into a buffer string encoded with the type type.
if os.path.exists(_csrfile):
    print "Certificate file exists, aborting."
    print " ", _csrfile
    sys.exit(1)
else:
    f = open(_csrfile, "w")
    f.write(crypto.dump_certificate_request(crypto.FILETYPE_PEM, req))
    f.close()

The error that I get back from the IIS CA is:

ASN1 bad tag value met. 0x8009310b (ASN: 267)

According to Microsoft this is caused by:

This behavior occurs when certificate request is stored in a file in Unicode encoding. Microsoft Certificate Services do not support Unicode-encoded files request files. Only ANSI encoding is supported.

I know that if I generate a CSR from openssl on the command line it is accepted and issued by the IIS CA RESTful webservice without error.

I want to know if there is some way I can generate 'ANSI' encoded files from pyOpenSSL - I am not sure if it is the keyfile or the CSR that is signed with the keyfile that is causing the issues.

python
unicode
openssl
csr
pyopenssl
asked on Stack Overflow Apr 21, 2015 by ilium007 • edited Apr 22, 2015 by ilium007

1 Answer

1

I have solved it with the help of this stackoverflow question thanks to @yodatg.

The problem occurs due to a bug in pyOpenSSL that has been fixed.

By issuing:

openssl asn1parse -in certificates/cert.csr

I could see the ASN1 value:

8:d=2  hl=2 l=   1 prim: INTEGER           :01

In a working CSR it looks like this:

8:d=2  hl=2 l=   1 prim: INTEGER           :00

I then changed my code to include a set_version call on the req object prior to signing:

#set version - IIS CA required this
req.set_version(0)

# Set the public key of the certificate to pkey.
req.set_pubkey(priv_key)

This is now resolved.

answered on Stack Overflow Apr 22, 2015 by ilium007 • edited May 23, 2017 by Community

User contributions licensed under CC BY-SA 3.0