Re: [HACKERS] Trust intermediate CA for client certificates - Mailing list pgsql-general
From | Craig Ringer |
---|---|
Subject | Re: [HACKERS] Trust intermediate CA for client certificates |
Date | |
Msg-id | 5146BBBD.4020309@2ndquadrant.com Whole thread Raw |
In response to | Re: [HACKERS] Trust intermediate CA for client certificates (Craig Ringer <craig@2ndquadrant.com>) |
Responses |
Re: [HACKERS] Trust intermediate CA for client certificates
|
List | pgsql-general |
On 03/18/2013 01:07 PM, Craig Ringer wrote: > 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. It looks like we aren't reading the system-wide certs or looking them up when certs aren't resolved in the files Pg explicitly passes to OpenSSL, so a system-wide install doesn't look like it'll work. I've had a look at how Apache handles this and it took me a while to work out what's going on. Apache uses SSLCACertificateFile (concatenated certs) / SSLCACertificatePath (hashed dir) to look up trusted certificate signers. It According to the docs it doesn't appear to make any provision there for trusting intermediate certificates but not their parents as signers of client certificates, but it looks like support is there, the docs just don't explain it well. Apache has SSLCADNRequestFile / SSLCADNRequestPath which are described as controlling the acceptable certificate names sent to clients in a client cert request. The docs don't make it clear if Apache will trust only client certs with these certs in their chains or whether this only controls the list of certificate DNs presented to the client rather than what's accepted in response. The code suggests that they control trust not just the cert list presented. In Apache's modules/ssl/ssl_engine_init.c it calls SSL_CTX_load_verify_locations on the SSLCACertificateFile and SSLCACertificatePath. It then calls ssl_init_FindCAList with the SSLCADNRequestFile/SSLCADNRequestPath if they're specified in the configuration, otherwise it calls it with the SSLCACertificateFile/SSLCACertificatePath . That calls ssl_init_PushCAList on all of the certs it finds in the File and Path variants. For each cert file that calls SSL_load_client_CA_file and for each cert within each file pushes the cert onto a STACK_OF(X509_NAME) if a cert with the same DN isn't already in the stack. It passes the stack to OpenSSL's SSL_CTX_set_client_CA_list . So what Apache does appears to boil down to: SSL_CTX_load_verify_locations(ca_file,ca_path); if (ca_dn_file || ca_dn_path) { SSL_CTX_set_client_CA_list( ... STACK_OF unique certs on ca_dn_file and ca_dn_path ... ); } else { SSL_CTX_set_client_CA_list( ... STACK_OF unique certs on ca_file and ca_path ); } This appears to match Ian's description of having a validation-only cert list and a separate list of certs used to verify clients. I'd like to follow Apache's model: in postgresql.conf, if ssl_ca_file is set then pass it to SSL_CTX_load_verify_locations . If the proposed new parameter ssl_ca_valid_client_signers_file is set then pass the certs in that to SSL_CTX_set_client_CA_list ; otherwise pass the certs in ssl_ca_file to SSL_CTX_set_client_CA_list and thus retain the current behaviour. Hopefully we can avoid the ugly read-and-deduplicate stuff Apache has to do because we currently only support a certfile anyway, we don't read certdirs, so I'll look for helper functions that wrap SSL_CTX_set_client_CA_list. -- Craig Ringer http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Training & Services
pgsql-general by date: