1

Using Apache 2.4.

We have two valid CA certificates whose distinguished names differ only by the case of one character (say CA1 with dn: cn=MyCA,O=myOrg and CA2 with dn: cn=MyCA,O=MyOrg).

These two certificates are both in the file referred by the SSLCACertificateFile Apache directive, as we need to authenticate client certificates signed by both CAs. This does not happen: only browsers with client certificates signed by CA1 or CA2 are able to access, depending on the order of the CA certificates in the file. So, if only clients from CA1 are able to authenticate themselves, after switching the order in SSLCACertificateFile and reloading Apache, only clients from CA2 are able to authenticate.

If we perform a SSL handshake by openssl s_client -connect <server>:<port> -prexit, we notice that only one of the CA distinguished names is sent in the list of accepted CAs, and the dn that is sent depends on the order in which the CAs certificate are in the SSLCACertificateFile. This makes sense as the Openssl computed hash for the two distinguished names is the same, as distinguished names should not be case sensitive.

But it seems that the browser performs a case-sensitive match, instead, as in the Apache logs the certificate installed in the browser is not sent when the "advertised CA" is CA1 and the client certificate is signed by CA2, and vice-versa. We tried with Firefox on Windows and Linux, and Internet Explorer and Chrome on Windows.

Otherwise, the curl command line browser has not this problem, when we invoke the https URL with the client certificate and key in PEM format.

0

Without really digging I'd say you can't convince browsers to do case-insensitive search here. In case of a simple web service, you could create another VirtualHost where all the clients are distributed (say https://detect-cert.example.com).

This would mean client negotiates TLS once, then it has a redirect, then another TLS negotiation.

VirtualHost detect-cert.example.com:

  • make sure you accept optional_no_ca certificates from browsers
  • no SSLCACertificateFile
  • look at either SSL_CLIENT_I_DN or SSL_CLIENT_CERT_CHAIN_<n> environment variable
  • redirect (HTTP 302) a browser to either ca1clients.example.com or ca2clients.example.com

VirtualHost ca1clients.example.com:

  • make sure you require certificates from browsers
  • SSLCACertificateFile CA_lowercase.pem

VirtualHost ca2clients.example.com:

  • make sure you require
  • SSLCACertificateFile CA_uppercase.pem

But your web application needs to support two domain names at the same time (for example through X-Forwarded-Host header). It should never tell a browser that entered through ca2clients.example.com to reenter through ca1clients.example.com. Another difficulty would be users exchanging links between themselves (for example emailing links to some content).

  • Even with the optional_no_ca option, the browser sends the certificate only if there is no SSLCACertificateFile, right?. This may make some trouble if the user has more than one certificate in the browser. – rzabini Sep 21 '17 at 9:36
  • @rzabini True, I totally missed this scenario (multiple client certificates). I've checked the sources (mod_ssl and openssl as it relies on it) and it doesn't look like you can achieve case-sensitivity without some C programming. Maybe there is only a small number of users with multiple certs and you could have helpdesk to manually send them a target url (either ca1url or ca2url). – kubanczyk Sep 21 '17 at 10:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.