-1

I want to give my users the ability to login with their own personal x.509 certificates. The user supply me (the account registration script) his/her x.509 public key. Apache should only accept the known public keys (specified in a file similar to .htpasswd) and reject others. How do I have to configure apache to make this possible?

I have tried google but found only solutions for CA signed x.509 certs. CA is meaningless for this problem. Even a self-signed x.509 should have the ability to login if its public key is known.

burnersk
  • 2,056
  • 5
  • 27
  • 39

2 Answers2

1

You can make a CA file out of all of your client certifiates, that should work.

You would, however, no longer be able to trust the certificate CN to authenticate distinct users.

If you don't want to restart Apache it should still be possible to do it by using a CA directory instead of a CA bundle, with the SSLCACertificatePath directive (You'll need to symlink or rename your certificates so that they can be accessed by hash)

b0fh
  • 3,313
  • 1
  • 21
  • 32
  • And I have to restart apache each time I (script) get a new registration? Thanks for the answer @b0fh but I can't do this. I see there is no other solution except binding the users to "my trusted CAs". It's a pity that is not possible to make a dynamic whitelist/folder of known x.509 certificates for "that vhost". – burnersk Mar 11 '12 at 17:26
  • 1
    You should still be able to make it dynamic without restarting apache, with SSLCACertificattePath. Also, this directive is supposedly valid in a vhost context. – b0fh Mar 13 '12 at 08:57
1

You can do this, there is nothing within Apache Httpd for normal authentication. You will need some code within your application to handle this (i.e. perform the authentication within the PHP/CGI/Java layer): this more or less excludes plain files (HTML, JS, ...) unfortunately.

To do so,

  • use SSLVerifyClient optional_no_ca to allow any certificate to be accepted (as far as the SSL/TLS layer of Apache Httpd is concerned);
  • point SSLCADNRequestFile to a file with just an empty line: this will make the CertificateRequest send an empty certificate_authorities list, which will indicate to the client that it can potentially send anything (not that it guarantees that the server will accept it). This behaviour is explicitly allowed by TLS 1.1 (and previous versions are silent on the subject). In practice, it works with SSLv3 and TLS 1.0 with most browsers.

This will allow any certificate to get presented and accepted during the SSL/TLS handshake. Unfortunately, this also removes any for of authentication Apache Httpd would have made, so none of the directives verifying CNs or other parts of the certificate will be of any use (since you can't trust the content of the certificate).

All you know at this stage is that the client has the private key for the public key in the certificate that was presented (otherwise the CertificateVerify TLS step would have failed). You can't even trust the subject of that cert. This certificate will be in SSL_CLIENT_CERT. You'll have to have some code to read it and extract its public key, before comparing it to your known list of public keys. (This can also work if you pass this client certificate via mod_proxy to a back-end Java server for example.) There are libraries in PHP, Perl, Python, Java (pick the language you prefer) to analyse the content of the certificate, but it will require some programming, and will of course only authenticate the requests that are handled by such an application.

Bruno
  • 4,099
  • 1
  • 21
  • 37