Opened 10 years ago

Last modified 15 months ago

#386 new Bug / Defect

Cryptoapicert SUBJ: selector doc

Reported by: tlhackque Owned by:
Priority: minor Milestone:
Component: Documentation Version: OpenVPN 2.2.2 (Community Ed)
Severity: Not set (select this one, unless your'e a OpenVPN developer) Keywords: windows
Cc: Selva Nair

Description

I got --cryptoapicert to work with "SUBJ:" selectors. The documentation for the "SUBJ:" form of the option is a bit lacking.

Consider this subject (as viewed in IE tools->options->content):

E = john@…
CN = John Smith
OU = Group A
OU = Department
O = Minicorp
L = City
S = State
C = US

To match the whole thing (as John Smith may have more than one cert), one needs:

"SUBJ:US, State, City, Minicorp, Department, Group, John Smith, john@…"

This is what Microsoft calls a CERT_SIMPLE_NAME_STR - the doc for which is astoundingly opaque.

The required ordering is not what IE presents for the RDN, but one can get it from openssl:

openssl x509 -in john.cer -noout -subject
subject= /C=US/ST=State/L=City/O=Minicorp/OU=Department/OU=Group/CN=John Smith/emailAddress=john@…

The above is one line, but mail will probably wrap it.

I'm not sure if simply reversing the MS presentation is reliable.

Further, the MS documentation suggest that a 'plus space' delimiter is used for multiple attributes. It's not clear what that means.

Change History (5)

comment:1 Changed 10 years ago by Gert Döring

Ummm. Can you provide text for our documentation to, well, improve it?

comment:2 Changed 10 years ago by tlhackque

Ummm. Can you provide text for our documentation to, well, improve it?

Actually, no. At least, not satisfactorily. The problem is that I could not find clear MS documentation of the CERT_SIMPLE_NAME_STR! I hope that the people who wrote the OpenVPN code have the MSDN RTL sources and can look. (I do not.) I also hoped that they understood it better than I when they chose to use this MS API...

What I have observed is in what I wrote, but here is a somewhat more formal version - keeping in mind that this is based on observation, not understanding:

Using the SUBJ: form of certificate selector:

The SUBJ: form of a certificate selector uses the Distinguished Name (DN) of the Subject of the certificate. The given selector is used to identify a certificate in the crypto API store. This is less precise than using the THUMB: form of the selector, which has the advantage that when a certificate is renewed, the --cryptoapicert "SUBJ: selector doesn't need to be updated; the client configuration file doesn't need to change unless the DN changes. The THUMB: form would always require the option value to be updated. The disadvantage is that it's a bit harder to explain...

Consider finding a certificate with this subject (as viewed in IE tools->options->content):

    E = john@…
    CN = John Smith
    OU = Group A
    OU = Department
    O = Minicorp
    L = City
    S = State
    C = US

To construct the selector, transform the DN as follows -- other tools can be used as long as they have the same effect:

  1. Display the Distinguished Name of the certificate's subject with the openssl command:
openssl x509 -in john.cer -noout -subject

which results in output of the form:

subject= /C=US/ST=State/L=City/O=Minicorp/OU=Department/OU=Group/CN=John Smith/emailAddress=john@…

Note that there may be more than one instance of a label in a Distinguished name - OU is shown here.

  1. Remove the "Subject= " label
  1. Remove all of the label specifiers (including /C= and /CN= in the example), replacing all but the first with a comma and a single space.
  1. Add the option name "SUBJ: prefix and " suffix to the result.

For the example, the resulting string will be:


cryptoapicert "SUBJ:US, State, City, Minicorp, Department, Group, John Smith, john@…"


OpenVPN uses a Microsoft function to find the certificate. This function searches the (Personal?) certificate store (Personal?) for a matching certificate. This is done as if it:

a) transforms the DN of each certificate according to the rules above, omitting the quotes, option name and SUBJ: prefix. E.g. resulting in the bolded part of the example above.

b) Determines if the transformed name contains the specified string - this is a substring match, not a string comparison for equality.

Thus, it is advisable to use the entire DN to prevent ambiguity.

c) When a 'match' is found, the matching certificate is returned and used by OpenVPN to identify the client.

d) If no matching certificate is found, OpenVPN will log an error.

Open questions from the MS doc:

If ambiguous:
In what order is the certificate store searched?

Does the search stop on the first matching certificate? Is this defined?

The MS doc refers to 'attributes' in a CERT_SIMPLE_NAME_STR and says they are delimited by plus space. Exactly what this means is unclear.

Does MS guarantee that the search order is stable? (E.g. is it alphabetic, by subject, or perhaps based on traversing a hash? If a certificate is added to or removed from the store, is the search order for the (remaining+added) certificates predictable by an end-user?)

Are expired certificates considered in the search? If so (and these are common), how can OpenVPN deal with the common case of keeping expired certificates (for decryption) in the store? Obviously, we want to offer the server (the) one with the best chance of validating.

In any case, is it always true that the IE display is inverted with respect to the CERT_SIMPLE_NAME_STR? Or is that just a coincidence in my test case?

Are any other attributes considered by the MS code?

It may be necessary to open a support ticket with Microsoft to get answers...


Given all this, you can see that this is quite hard to document. I'm actually rather surprised that this API was chosen by OpenVPN, rather than doing something that produces an exact match on DN, requires that the cert be in the validity period, requires that the cert has reasonable attributes (e.g. meets the 'purpose' test for webserver (client) validation, etc) There are other APIs documented for the certificate store, but they do require more work.

But for now, it is what it is. And we should at least explain how it works until something better comes along.

Using the THUMBprint instead has other issues - most significantly that the client config file has to be updated when a certificate is issued. For all its faults, the current SUBJ form is much more useful - especially in large deployments.

Version 1, edited 10 years ago by tlhackque (previous) (next) (diff)

comment:3 Changed 9 years ago by Samuli Seppänen

Keywords: windows added

comment:4 Changed 15 months ago by Gert Döring

Cc: Selva Nair added

So where are we with this? I've seen numerous cryptoapi improvements go into the code over the years, so this might have been addressed? Or not?

@selva, do you know?

comment:5 Changed 15 months ago by Selva Nair

I do not understand the real issue here (apart from doc improvement). Use of SUBJ: to match the cert is a convenience option that may not be appropriate for everyone. For unambiguous match, use THUMB:

We match the string provided in SUBJ: using CertFindCertificateInStore with CERT_FIND_SUBJECT_STRING_W option. How that works is documented in MSDN. Essentially, the DN is converted to a string (with each DN element separated by commas, multiple attributes separated by + etc..) and a strstr like comparison is carried out.

As the order in which entries may appear in this string is not be easy to predict, using an exact match suggested here is not very practical. Instead we expect the user to specify one of the elements in DN that is most unique for the certificate -- normally common-name or email address would be the good choice if the server admin has made a good choice for common-names.

But this may be inadequate for users who have multiple certificates with same email address or common-name. The use of THUMB: should be always preferred.

Those who use Windows PKI, there is a suggestion to add template-based selection, but patch still waiting for followup (https://patchwork.openvpn.net/project/openvpn2/patch/20210604143125.4946-1-heiko.wundram@gehrkens.it/)

Note: See TracTickets for help on using tickets.