Re: Trust intermediate CA for client certificates

From: Andrew Dunstan <andrew(at)dunslane(dot)net>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Bruce Momjian <bruce(at)momjian(dot)us>, Stephen Frost <sfrost(at)snowman(dot)net>, Craig Ringer <craig(at)2ndquadrant(dot)com>, Ian Pilcher <arequipeno(at)gmail(dot)com>, stellr(at)vt(dot)edu, PostgreSQL Hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Trust intermediate CA for client certificates
Date: 2013-12-02 22:35:06
Message-ID: 529D0B1A.9020309@dunslane.net
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general pgsql-hackers


On 12/02/2013 04:17 PM, Tom Lane wrote:
> Bruce Momjian <bruce(at)momjian(dot)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()'

In response to

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Stephen Frost 2013-12-02 22:43:48 Re: Trust intermediate CA for client certificates
Previous Message AK 2013-12-02 22:20:29 Re: NpgsqlCopySerializer blows up if no rows are saved

Browse pgsql-hackers by date

  From Date Subject
Next Message Tom Dunstan 2013-12-02 22:37:11 Re: Proposed feature: Selective Foreign Keys
Previous Message Brar Piening 2013-12-02 22:12:28 Visual Studio 2013 build