Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

countryName is UTF8STRING when making a CSR #69

Closed
reynir opened this issue Oct 13, 2015 · 10 comments
Closed

countryName is UTF8STRING when making a CSR #69

reynir opened this issue Oct 13, 2015 · 10 comments

Comments

@reynir
Copy link
Contributor

reynir commented Oct 13, 2015

I made a CSR using ocaml-x509, and it wasn't accepted by openssl as country name "DK" is not the same as country name "DK". After being a bit puzzled by this error message I found out that ocaml-x509 encoded countryName as UTF8STRING while openssl generates and seemingly expects PrintableString.

@hannesm
Copy link
Member

hannesm commented Oct 13, 2015

you tried to sign the csr with openssl? is there something in your openssl config which requires the countryName to be a printableString (and/or to have an exact match)?

at the moment, the asn.1 combinators already strip the information which of the various string encodings was used, and translate this into a string. while writing, every string is translated into an utf8string (which according to the X.509 rfc is fine, but as you found out, implementations might assume other encodings).

@reynir
Copy link
Contributor Author

reynir commented Oct 13, 2015

Thank you for your very fast reply(!)

Yes, I tried to sign it with openssl which is configured to have countryName match "DK". It's not explicitly configured to have countryName be a PrintableString AFAIK.

I worked around this issue by setting the subject again with openssl req -in my.csr -subj 'C=DK/...' -out my.csr ← does not work :(

@hannesm
Copy link
Member

hannesm commented Oct 13, 2015

ok, and turns out a printableString is what is suggested by the standard here (RFC5280, appendix A.1) (omitting where utf8string is fine):

X520dnQualifier ::=     PrintableString
X520countryName ::=     PrintableString (SIZE (2))
X520SerialNumber ::=    PrintableString (SIZE (1..ub-serial-number))
DomainComponent ::=  IA5String
EmailAddress ::=     IA5String (SIZE (1..ub-emailaddress-length))

@pqwy this means we (you?!? ;) really need to expose the string encoding..

@paurkedal
Copy link
Contributor

I had a similar issue signing an ocaml-x509 CSR with an OpenSSL CA, though in my case the mismatch was due to domain components. Apart from the cited appendix, section 7.3 in the same document says that IA5String is to be used even for IDNs:

[...] As with the dNSName in the GeneralName type, the value of this attribute is defined as an IA5String. Each domainComponent attribute represents a single label. To represent a label from an IDN in the distinguished name, the implementation MUST perform the "ToASCII" label conversion specified in Section 4.1 of RFC 3490. [...]

@NightBlues
Copy link
Contributor

@hannesm as you mentioned, some attributes of distinguished name should not be utf8string. I've run into the same problem and saw that some programs don't show C and emailAddress correctly (for example gcr-viewer shows hex escape codes instead of email, though it has ascii only symbols), so i hacked a bit asn1 grammar of distinguished name: https://github.com/NightBlues/ocaml-x509/pull/2/files and now i can not see any "bads" neither with gcr-viewer nor with openssl cli utility. But I did not succeed in my use-case.

Here is what i'm trying to do:

  1. having ca.key, ca.crt, server.crt
  2. create client.key
  3. create client.csr
  4. sign client.csr with ca.crt to get client.crt
  5. pack cleint.key and client.crt into client.p12 container
  6. import client.p12 in firefox
  7. authorize with client.crt on web server (nginx)

If i use openssl cli - everything is fine, but if i use ocaml to create csr - firefox imports p12, but doesn't show it in user identity dialog (neither chrome does). If i create csr with ocaml and sign it with openssl cli - it signs successfully, but behavior is the same - firefox imports p12 but doesn't show it in dialog.

All these attempts make me think that there is something wrong with csr that ocaml-x509 generates, but i can't find what exactly - i'm using openssl cli to manually verify attributes of certificate, but it doesn't show asn1 datatypes, so everything looks the same with good and bad certs.

Can you please advice how to narrow down the problem? I have no proprietary asn1 viewers and even dont know its names :(

@hannesm
Copy link
Member

hannesm commented Dec 16, 2020

interesting, I use http://lapo.it/asn1js/ for debugging asn1 issues. I'd go as follows:

  • generate the certificate with openssl, use the pkcs12 packing from ocaml-x509, and see whether this works
  • look at the certificate extensions in more detail -- does openssl add some that your usage of ocaml-x509 does not? (basically check the signed certificate from openssl against the one signed by ocaml-x509)

before PR #114 I actually signed some certificates with ocaml-x509, and used openssl pkcs12 to pack them into pkcs12 containers -- and was successfully able to import them into firefox & chrome (NB: i have not tried #114 in respect to firefox / chrome compatibility).

@NightBlues
Copy link
Contributor

NightBlues commented Dec 17, 2020

generate the certificate with openssl, use the pkcs12 packing from ocaml-x509, and see whether this works

just checked - it works (and its actually how a checked ocaml p12 is working)

I use http://lapo.it/asn1js/ for debugging asn1 issues.

it helped! i've found that only difference is cert signature and commonName type (I hacked it with | CN x -> (X520.common_name, `C2 x ) while openssl's cert uses utf8string) So with https://github.com/NightBlues/ocaml-x509/pull/2/files everithing seems to be workin - firefox and chrome allows to import and login with such cert (p12 works too)

Thank you!

@NightBlues
Copy link
Contributor

before PR #114 I actually signed some certificates with ocaml-x509, and used openssl pkcs12 to pack them into pkcs12 containers -- and was successfully able to import them into firefox & chrome

I think its because your issuer cert was created with ocaml too, while mine with openssl cli, so you had utf8string both in issuer cert and issuer field of client cert, while i have utf8string in issuer DN and printable_name in client certs issuer field - it seems that firefox compares them in some type-safe way

@hannesm
Copy link
Member

hannesm commented Dec 17, 2020

you had utf8string both in issuer cert and issuer field of client cert, while i have utf8string in issuer DN and printable_name in client certs issuer field - it seems that firefox compares them in some type-safe way

ah, yes -- it is a good idea to have bit-wise equality "the subject of the CA cert" and "the issuer of the cert". this is not achieved by ocaml-x509 (yet) since the string tags are thrown away...

hannesm pushed a commit to NightBlues/ocaml-x509 that referenced this issue Apr 4, 2021
Earlier, each component was serialised to a UTF8String, which is wrong for
DomainComponent (IA5String), Serialnumber (PrintableString), CountryName
(PrintableString), DnQualifier (PrintableString), EMail (IA5String).

Reported in mirleft#69
@hannesm
Copy link
Member

hannesm commented Apr 4, 2021

Fixed by #140. Feels good to finally close this after > 5 years since the report.

@hannesm hannesm closed this as completed Apr 4, 2021
avsm pushed a commit to ocaml/opam-repository that referenced this issue Apr 6, 2021
CHANGES:

* FEATURE PKCS12 support (mirleft/ocaml-x509#114 by @hannesm)
* FEATURE ECDSA and EDDSA support via mirage-crypto-ec (mirleft/ocaml-x509#145 by @hannesm)
  This breaks some clients since the Private_key.t and Public_key.t variants
  are extended (may result in partial pattern matches of users of this library).
* CRL.is_revoked has `crls` as last parameter to avoid warning 16
  (4.12 compatibility) (mirleft/ocaml-x509#144 by @hannesm)
* Signing_request.sign: add optional labelled argument `~subject` to allow
  changing the subject when signing a signing request (mirleft/ocaml-x509#139 by @reynir)
* BUGFIX Encoding of Distinguished_name components (adhere to specification)
  DomainComponent and EMail are now serialised using a IA5String; Serialnumber,
  CountryName and DnQualifier as PrintableString (reported in mirleft/ocaml-x509#69, fixed mirleft/ocaml-x509#140
  by @NightBlues)
* BREAKING Remove `~sloppy` from Private_key.decode_{pem,der}. The seemingly
  bad RSA keys were valid and should have been accepted by mirage-crypto.
  (mirleft/ocaml-x509#142 by @psafont)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

4 participants