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:

Previous
From: Brar Piening
Date:
Subject: Visual Studio 2013 build
Next
From: Tom Dunstan
Date:
Subject: Re: Proposed feature: Selective Foreign Keys