certificationRequestToPem produces "printable" encoded DN components
I use certificationRequestToPem() to create a CSR. However, when I try to use openssl ca to sign the request (where the signing policy for organizationName is 'match'), I get a mismatch error, even though the organizationName appears the same -- except the CSR organizationName appears as "PRINTABLE", where my CA cert's organizationName is UTF8STRING,
Curiously, using openssl asn1parse, I'm able to see that the CA cert I created (using openssl) uses PRINTABLESTRING for countryName, but UTF8STRING for all other DN components.
How can I get certificationRequestToPem() to produce strings that will match the CA cert?
Thanks
Upon further research (http://openssl.6102.n7.nabble.com/stateOrProvinceName-field-problem-when-signing-CSR-td26124.html), this is probably an issue with the openssl ca utility. It should compare a PRINTABLESTRING and UTF8STRING appropriately.
The workaround is to set the openssl ca policy to "supplied" or "optional" and do a manual check for matching where required. Or, re-create the ca cert with string_mask = "default" instead of "utf8only", then all the DN fields end up as PRINTABLE string, just as certificationRequestToPem() does.
The saga continues... PRINTABLESTRING can contain only a pretty-limited set of characters: https://en.wikipedia.org/wiki/PrintableString, which is not ideal.
So, how can I get certificationRequestToPem() to produce UTF8STRING-encoded strings?
It would help to see a minimal runnable example that doesn't work, commands you are running, and what you'd like to see as output.
generate-csr.js uses node-forge to create a CSR whose OU contains "R&D" (note illegal PRINTABLE string character "&"), which node-forge does not complain about. When I attempt to sign it later using openssl, I get:
Using configuration from openssl-ca.cnf
Enter pass phrase for ./cakey.pem:
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName :PRINTABLE:'test.example.com'
countryName :PRINTABLE:'US'
stateOrProvinceName :PRINTABLE:'Massachusetts'
localityName :PRINTABLE:'Boston'
organizationName :PRINTABLE:'Me'
The string contains characters that are illegal for the ASN.1 type
(It's complaining about the OU field).
I would like all DN fields to be coded as UTF8STRING so they can support all characters. Note, however, that when I create a CSR with the same OU name using openssl, it encodes just that one field as T61STRING. It sets the encoding of each field based on its content?
Let me know if you need anything else.
// create a self-signed CA cert openssl req -x509 -config openssl-ca.cnf -newkey rsa:4096 -sha256 -out cacert.cer -outform PEM -days 3560
// generate CSR using node-forge node generate-csr.js
// view ASN.1 encoded strings openssl asn1parse -in mytest.csr
// sign the CSR openssl ca -config openssl-ca.cnf -extensions signing_req -in mytest.csr -out mycert.pem
// openssl-ca.cnf: openssl-ca.cnf.txt // node.js code generate-csr.js.txt // CSR that's generated mytest.csr.txt
I'm not sure if this is the cause of your problem or not, but I needed to generate a csr where one of the values is a utf8 string. This is what I've done:
csr.setSubject([{
name: 'commonName',
valueTagClass: forge.asn1.Type.UTF8,
value: nome
}, ... other attrs ...])
and then openssl showed UTF8STRING as the attribute type.
I'm not sure if this is the cause of your problem or not, but I needed to generate a csr where one of the values is a utf8 string. This is what I've done:
csr.setSubject([{ name: 'commonName', valueTagClass: forge.asn1.Type.UTF8, value: nome }, ... other attrs ...])and then openssl showed UTF8STRING as the attribute type.
Thanks @brunovianarezende, this helped me address what I originally thought was a Python cryptography issue.
The solution I'm working on now supports UTF-8 characters for common names and organizations. :-)