distinguished name order

135 views
Skip to first unread message

Mike

unread,
Jul 29, 2025, 6:22:06 PMJul 29
to openss...@openssl.org
ITU X.501 (10/19) <https://www.itu.int/rec/T-REC-X.501-201910-I/en>,
section 9.2 says that the `RDNSequence` that makes up a `DistinguishedName`
"start[s] with the root" RDN.

RFC 4514, section 2.1 <https://datatracker.ietf.org/doc/html/rfc4514#section-2.1>
says that sequence is converted to a string in the reverse order, "starting
with the last element of the sequence and moving backwards towards the first".

So a DN represented as a string "ST = California, C = US" would be in the
proper order, because the `countryName` would normally be seen as a parent to
the `stateOrProvinceName`.

What I find that seems to work in practice in OpenSSL, though, is the reverse
of that expected representation. For example, if I define a
`distinguished_name` section in a config file as:

distinguished_name = req_distinguished_name

[ req_distinguished_name ]
C = US
ST = California
CN = foo

and in the CA config, a name constraint:

nameConstraints = critical, @name_constraints

[ name_constraints ]
permitted;dirName = dir_section

[ dir_section ]
C = US
ST = California

the certificate chain verifies. But not if I reverse the order of all the
RDN lines.

Is this correct as is? Is it a known issue? The manual pages don't really
talk about it. I'm not familiar with the historical LDAP usages.

Viktor Dukhovni

unread,
Jul 30, 2025, 3:05:30 AMJul 30
to openss...@openssl.org
On Tue, Jul 29, 2025 at 10:19:05PM +0000, Mike wrote:

> ITU X.501 (10/19) <https://www.itu.int/rec/T-REC-X.501-201910-I/en>,
> section 9.2 says that the `RDNSequence` that makes up a `DistinguishedName`
> "start[s] with the root" RDN.

This recommends a "wire form" (ASN.1 SEQUENCE) order of RDN components
within a DN. That order can be important if the DN refers to an actual
directory in which it represents the name name of some object. Thus
LDAP DNs do have to be properly ordered and the ASN.1 (wire) form
of such DNs does have "C" first, then "ST", then "L", ... "O" before
"OU", and has its "DC" DNS name components ordered with the TLD first!

In case it is helpful, here's Gemini's response to a prompt that
solicits confirmation of this fact.

https://g.co/gemini/share/2d4618fd872a

In an X.509 certificate, one is of course free to order the components
however one sees fit, which mostly doesn't matter, unless there are
relevant name constraints in scope (actual X.509 name constaints on
Directory Names are not at all common). Hypothentical name constraints
aside, X.509 DNs are matched against expected values in their original
order, whatever it might be.

> RFC 4514, section 2.1 <https://datatracker.ietf.org/doc/html/rfc4514#section-2.1>
> says that sequence is converted to a string in the reverse order, "starting
> with the last element of the sequence and moving backwards towards the first".

This specifies a human-readable "presentation form" for LDAP DNs, that
puts the most specific RDNs first. Thus one might see "C=AU" last, and
DC components in the usual DNS order "DC=host, DC=example, DC=com".

That form is not the "oneline" form historically used by OpenSSL, which
uses "/" rather than "," as a separator, does not reverse the RDN order,
and IIRC may not always round-trip faithfully when parsed in the "-subj"
option of openssl-req(1), openssl-x509(1) and openssl-ca(1).

> So a DN represented as a string "ST = California, C = US" would be in the
> proper order, because the `countryName` would normally be seen as a parent to
> the `stateOrProvinceName`.

That's RFC4514, not X509_NAME_oneline(3).

> What I find that seems to work in practice in OpenSSL, though, is the reverse
> of that expected representation. For example, if I define a
> `distinguished_name` section in a config file as:
>
> distinguished_name = req_distinguished_name
>
> [ req_distinguished_name ]
> C = US
> ST = California
> CN = foo

Well, now you're not looking at neither RFC4514, nor the oneline form.
Instead this this is "config section" syntax to *specify* (rather than
display) a DN, and the order of RDNs is the order in which they'll end
up in the ASN.1 DER sequence. This is consistent with other "section"
forms such as:

subjectAltName = @altNames

[altNames]
DNS.1 = foo.example.com
DNS.2 = bar.example.org
...

> and in the CA config, a name constraint:
>
> nameConstraints = critical, @name_constraints
>
> [ name_constraints ]
> permitted;dirName = dir_section
>
> [ dir_section ]
> C = US
> ST = California

And now the mythical dirName name constraints, again specified in their
physical (DER encoding) order, this is not a display form.

> the certificate chain verifies. But not if I reverse the order of all the
> RDN lines.

That would not be correct. I hope the above helps to make clear why.

> Is this correct as is? Is it a known issue? The manual pages don't really
> talk about it. I'm not familiar with the historical LDAP usages.

We're actually working on switching to RFC4514 as the display form
(which will require parsing that in "-subj" options when the value does
not start with a "/", with the legacy oneline form as a fallback).

--
Viktor. 🇺🇦 Слава Україні!

Jochen Bern

unread,
Jul 30, 2025, 3:54:22 AMJul 30
to openss...@openssl.org
On 30.07.25 00:19, Mike wrote:
[about ordering of elements within the DN]
> Is this correct as is? Is it a known issue? The manual pages don't really
> talk about it. I'm not familiar with the historical LDAP usages.

All talk about *current* standards aside, if you plan to run things in
the long term, you'll need to be prepared to see these standards change.
The current two *nominal* root CA certs of our company both have
ultimately been created with OpenSSL (of their time), and lo:

> $ ChainCat RootCA-?/root_ca.crt
>
> ### RootCA-A/root_ca.crt ###
>
> CERTIFICATE:
> subject=CN=Root CA, O=pawisda systems GmbH, L=Weiterstadt, ST=Hessen, C=DE
> issuer=CN=Root CA, O=pawisda systems GmbH, L=Weiterstadt, ST=Hessen, C=DE
> notBefore=Oct 18 22:00:00 2012 GMT
> notAfter=Oct 5 22:00:00 2028 GMT
>
> ### RootCA-B/root_ca.crt ###
>
> CERTIFICATE:
> subject=C=DE, ST=Hessen, L=Weiterstadt, O=Binect GmbH, CN=Root CA - B, emailAddress=tec...@binect.de
> issuer=C=DE, ST=Hessen, L=Weiterstadt, O=Binect GmbH, CN=Root CA - B, emailAddress=tec...@binect.de
> notBefore=Oct 7 16:19:21 2020 GMT
> notAfter=Sep 26 16:19:21 2036 GMT

Kind regards,
--
Jochen Bern
Systemingenieur

Binect GmbH

Mike

unread,
Jul 30, 2025, 1:47:25 PMJul 30
to openss...@openssl.org
Thanks, that clears it up.

Viktor Dukhovni wrote:
> And now the mythical dirName name constraints

Yeah, is there anywhere that it's described what's actually supported in the
wild? I'm finding that Golang's crypto/x509 library comes up short in
recognizing certain critical-marked extensions. (IDK which ones yet. Using
trail and error to find out.)

Michael Richardson

unread,
Jul 30, 2025, 2:07:19 PMJul 30
to openss...@openssl.org
This would make a good OpenSSL conference talk.
Maybe even a LAMPS BCP.
Maybe even advise to mark some extensions as never-usefully-deployed.
Or not useful for the Internet, or outside of a very controlled ecosystem.

I think US federal agencies use all sorts of things that just aren't
implemented outside of the RFPs that supply them. Maybe this also applies
across many governments. Maybe there is an interesting common subset of
extnesions that would help everyone, if only we could depend upon them.

Name Constraints definitely falls into this category to me.

--
Michael Richardson <mcr+...@sandelman.ca> . o O ( IPv6 IøT consulting )
Sandelman Software Works Inc, Ottawa and Worldwide




signature.asc

Mike

unread,
Jul 30, 2025, 6:30:46 PMJul 30
to openss...@openssl.org
> I'm finding that Golang's crypto/x509 library comes up short in
> recognizing certain critical-marked extensions. (IDK which ones yet. Using
> trail and error to find out.)

So...`email`, `DNS` and `IP` are all understood by Golang, the mythical
`dirName` is not.

Mike

unread,
Jul 30, 2025, 7:26:37 PMJul 30
to openss...@openssl.org
This was in Helm 3.18.4, which uses Go 1.24.4. This probably sums it up:
<https://go.dev/src/crypto/x509/x509.go#L1052>

Viktor Dukhovni

unread,
Jul 31, 2025, 12:26:56 AMJul 31
to openss...@openssl.org
The relevant code starts at:

https://go.dev/src/crypto/x509/verify.go#L647

Go only bothers with names in SANs, there is no longer any support for
names in the CN (or other) element of the DN, and no DN constraints are
implemented. This is by now quite reasonable.

Bottom line, in an X.509 context the order of subject DN components is a
private matter for the issuer, and only matters to the extent that the
subject is itself a CA, and then that name has to be copied verbatim
into the issuer field of its issued certificates.

However, if one is maintaining an LDAP directory, then the order of DN
components matters in searchBase specifications and chasing indirect
references.

This being an OpenSSL (rather than an LDAP) users list, the take away is
that any order is fine, so long as it is used *consistently*. The
legacy presentation form matches the "wire" ASN.1 sequence form, and
some day in the not too distant future OpenSSL may switch to RFC4514
(LDAP) presentation form, which reverses the order, uses commas as
separators, and should have more reliable "round-trip" behaviour.

The legacy form will continue to be recognised in the "-subj" option.

--
Viktor. 🇺🇦 Слава Україні!
Reply all
Reply to author
Forward
0 new messages