Re: Trust intermediate CA for client certificates

From: Ian Pilcher <arequipeno(at)gmail(dot)com>
To: Craig Ringer <craig(at)2ndquadrant(dot)com>
Cc: pgsql-general(at)postgresql(dot)org, tgl(at)sss(dot)pgh(dot)pa(dot)us, stellr(at)vt(dot)edu, pgsql-hackers(at)postgresql(dot)org
Subject: Re: Trust intermediate CA for client certificates
Date: 2013-03-18 06:27:55
Message-ID: 5146B3EB.3080001@gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general pgsql-hackers

On 03/18/2013 12:07 AM, Craig Ringer wrote:
> So this problem is verified.

Thanks for taking the time to look into this. Good to know I'm not
crazy.

> What we need to happen instead is for root.crt to contain only the
> trusted certificates and have a *separate* file or directory for
> intermediate certificates that OpenSSL can look up to get the
> intermediates it needs to validate client certs, like
> `ssl_ca_chain_file` or `ssl_ca_chain_path` if we want to support
> OpenSSL's hashed certificate directories.

I did a fair bit of searching and asked about this subject on the
openssl-users list. The consensus seems to be that doing this with
OpenSSL will require 2 separate sets of certificates and a validation
callback.

The two sets of certificates are:

* Trusted certificates - What currently goes in the (unfortunately
named) root.crt file.

* Validation-only certificates - CA certificates that are used only to
complete the chain from a trusted certificate to a self-signed root.
I haven't been able to come up with a particularly good name for a
file containing this type of certificate(s) -- validate.crt?

All of the certificates in both sets get added to the SSL_CTX, so that
OpenSSL can do its normal validation -- all the way to a root CA. The
trusted certificates also need to be maintained as a separate set
(X509_STORE?).

Once OpenSSL has built the complete certificate chain, the validation
callback can refuse the connection if the chain does not contain at
least one of the *trusted* certificates.

This is conceptually simple, and I've been fiddling with it for the last
week or so. Unfortunately, the OpenSSL documentation has made this far
more challenging that it should be. Simple things like reading multiple
certificates from a file, checking whether an X509_STORE contains a
particular certificate, etc. are all proving to be unexpectedly
difficult. (I never thought that I'd miss the Java SSL API!)

> System wide installation of the root may allow OpenSSL to discover it
> and use it for verification back to the root without having to trust it
> to sign clients. I'll do some more checking to see if this is possible
> with how Pg uses OpenSSL but I'm inclined to doubt it.

Me too. I think that OpenSSL's behavior embodies the idea that a
certificate can only be validated if a chain can be formed to a self-
signed root CA. (And there's probably a pretty good argument to be
made for this position, particularly when CRLs are added to the mix.)

> I thought you might be able to add the common root to the server.crt
> certificate chain to let OpenSSL discover it that way, but it looks like
> OpenSSL won't use certs it's seen in server.crt when verifying client
> cert trust paths.

Nope. It's pretty obvious from be-secure.c that only the certificates
in root.crt will be used.

--
========================================================================
Ian Pilcher arequipeno(at)gmail(dot)com
Sometimes there's nothing left to do but crash and burn...or die trying.
========================================================================

In response to

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Craig Ringer 2013-03-18 07:01:17 Re: Trust intermediate CA for client certificates
Previous Message Tom Lane 2013-03-18 05:09:07 Re: Enforcing Parameterised Nested Loop Join Order for Foreign Table Joins

Browse pgsql-hackers by date

  From Date Subject
Next Message Craig Ringer 2013-03-18 07:01:17 Re: Trust intermediate CA for client certificates
Previous Message Tom Lane 2013-03-18 05:47:30 Re: Strange Windows problem, lock_timeout test request