Re: Trust intermediate CA for client certificates - Mailing list pgsql-hackers
From | Andrew Dunstan |
---|---|
Subject | Re: Trust intermediate CA for client certificates |
Date | |
Msg-id | 529D0B1A.9020309@dunslane.net Whole thread Raw |
In response to | Re: Trust intermediate CA for client certificates (Tom Lane <tgl@sss.pgh.pa.us>) |
Responses |
Re: Trust intermediate CA for client certificates
Re: Trust intermediate CA for client certificates |
List | pgsql-hackers |
On 12/02/2013 04:17 PM, Tom Lane wrote: > Bruce Momjian <bruce@momjian.us> writes: >> Sorry, I should have said: >> Tom is saying that for his openssl version, a client that passed >> an intermediate certificate had to supply a certificate _matching_ >> something in the remote root.crt, not just signed by it. >> At least I think that was the issue, rather than requiring the client to >> supply a "root" certificate, meaning the client can supply an >> intermediate or root certificicate, as long as it appears in the >> root.crt file on the remote end. > As far as the server is concerned, anything listed in its root.crt *is* a > trusted root CA. Doesn't matter if it's a child of some other CA. But it does need to be signed by a trusted signatory. At least in my test script (pretty ugly, but shown below for completeness), the Intermediate CA cert is signed with the Root cert rather than being self-signed as the Root cert is, and so if the server doesn't have that root cert as a trusted cert the validation fails. In case 1, we put the root CA cert on the server and append the intermediate CA cert to the client's cert. This succeeds. In case 2, we put the intermediate CA cert on the server without the root CA's cert, and use the bare client cert. This fails. In case 3, we put both the root and the intermediate certs in the server's root.crt, and use the bare client key, and as expected this succeeds. So the idea that you can just plonk any Intermediate CA cert in root.crt and have all keys it signs validated is not true, AFAICT. OpenSSL version 1.0.0j was used in these tests, on a Fedora 16 box. cheers andrew SUBJ='/C=US/ST=Virginia/L=Herndon/O=testca/OU=eng' ROOTPASS='rootyroot' INTERMEDIATEPASS='branchybranch' LEAFPASS='leafyleaf' CLIENTLOGIN=andrew SERVERHOST=emma INSTALL='/home/andrew/pgl/inst.93.5709' DATA="$INSTALL/testca" PGPORT=5809; export PGPORT rm -rf myCA ; rm -rf myCA mkdir myCA cd myCA # make root ca in its own directory mkdir rootCA cd rootCA DIR=`pwd` cp /etc/pki/tls/openssl.cnf . sed -i -e "s,^dir.*,dir = $DIR," -e 's/#unique_subject/unique_subject/' openssl.cnf mkdir certs private newcerts chmod 700 . echo 1000 > serial touch index.txt echo 01 > crlnumber openssl req -passout pass:"$ROOTPASS" -new -x509 -days 3650 -extensions v3_ca -config openssl.cnf -subj "$SUBJ/CN=root CA" -keyout private/cakey.pem -out cacert.pem openssl rsa -passin pass:"$ROOTPASS" -in private/cakey.pem -out private/cakey.pem # now intermediate CA cd .. cp /etc/pki/tls/openssl.cnf . DIR=`pwd` sed -i -e "s,^dir.*,dir = $DIR," -e 's/#unique_subject/unique_subject/' openssl.cnf mkdir certs private newcerts chmod 700 . echo 1000 > serial touch index.txt echo 01 > crlnumber openssl genrsa -passout pass:"$INTERMEDIATEPASS" -des3 -out private/rakey.pem 4096 openssl rsa -passin pass:"$INTERMEDIATEPASS" -in private/rakey.pem -out private/rakey.pem openssl req -passin pass:INTERMEDIATEPASS -new -subj "$SUBJ/CN=intermediate" -sha1 -key private/rakey.pem -out ra.csr -config openssl.cnf # sign using root CA openssl ca -extensions v3_ca -days 365 -out ra.crt -in ra.csr -config rootCA/openssl.cnf -batch rm ra.csr cp rootCA/cacert.pem root.crt # # postgresql client # openssl req -passout pass:$LEAFPASS -subj "$SUBJ/CN=$CLIENTLOGIN" -config openssl.cnf -new -out postgresql.req -keyout postgresql.key openssl rsa -passin pass:$LEAFPASS -in postgresql.key -out postgresql.key openssl ca -config openssl.cnf -in postgresql.req -out postgresql.crt -cert ra.crt -keyfile private/rakey.pem -batch chmod 600 postgresql.key rm postgresql.req # # postgresql server # openssl req -passout pass:$LEAFPASS -config openssl.cnf -subj "$SUBJ/CN=$SERVERHOST" -new -out server.req -keyout server.key openssl rsa -passin pass:$LEAFPASS -in server.key -out server.key openssl ca -config openssl.cnf -in server.req -out server.crt -cert ra.crt -keyfile private/rakey.pem -batch chmod 600 server.key rm server.req cat ra.crt >> server.crt cat postgresql.crt ra.crt >> client.crt # copy certs to server cp root.crt $DATA/root.crt cp server.crt $DATA cp server.key $DATA rm -f $DATA/root.crl # restart the server set -x (cd $INSTALL && $INSTALL/bin/pg_ctl -D $DATA -l $DIR/logfile.tca -w restart) # make sure certs work ok $INSTALL/bin/psql "sslmode=verify-ca host=localhost sslrootcert=root.crt sslcert=client.crt sslkey=postgresql.key" -c 'select $$key 1 OK$$, ssl_client_dn(), ssl_client_serial(), ssl_issuer_dn()' # copy intermediate cert to server's root and try again with bare client cert cp ra.crt $DATA/root.crt (cd $INSTALL && $INSTALL/bin/pg_ctl -D $DATA -l $DIR/logfile.tca -w restart) $INSTALL/bin/psql "sslmode=verify-ca host=localhost sslrootcert=root.crt sslcert=postgresql.crt sslkey=postgresql.key" -c 'select $$key 1 OK$$, ssl_client_dn(), ssl_client_serial(), ssl_issuer_dn()' # copy root cert to server's root after intermediate crt and try again with bare client cert cat root.crt >> $DATA/root.crt (cd $INSTALL && $INSTALL/bin/pg_ctl -D $DATA -l $DIR/logfile.tca -w restart) $INSTALL/bin/psql "sslmode=verify-ca host=localhost sslrootcert=root.crt sslcert=postgresql.crt sslkey=postgresql.key" -c 'select $$key 1 OK$$, ssl_client_dn(), ssl_client_serial(), ssl_issuer_dn()'
pgsql-hackers by date: