BUG #14329: libpq doesn't send complete client certificate chain on first SSL connection

From: kzuk(at)akamai(dot)com
To: pgsql-bugs(at)postgresql(dot)org
Subject: BUG #14329: libpq doesn't send complete client certificate chain on first SSL connection
Date: 2016-09-20 10:10:51
Message-ID: 20160920101051.1355.79453@wrigleys.postgresql.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

The following bug has been logged on the website:

Bug reference: 14329
Logged by: Kacper Zuk
Email address: kzuk(at)akamai(dot)com
PostgreSQL version: 9.5.4
Operating system: GNU/Linux 4.1.20
Description:

I have PostgreSQL 9.5.4 compiled with OpenSSL 1.0.2h. Server is configured
to require SSL certificate for client. Server's root.crt only contains
top-level CA certificate and pg_hba.conf contains:

hostssl dbname dbuser 127.0.0.1/32 cert map=usermap

I'm trying to connect using psql:

psql "dbname=dbname user=dbuser host=127.0.0.1 sslmode=verify-ca
sslkey=certs/client.key sslrootcert=certs/root.crt
sslcert=certs/client-int-chain.crt"

client-int-chain.crt contains client certificate signed by intermediate
certificate and intermediate certificate signed by our top-level CA
certificate (the same as in server's root.crt).

Server rejects this connection. psql reports error "SSL error: tlsv1 alert
unknown ca". Server reports "could not accept SSL connection: certificate
verify failed" in logs.

tcpdump of traffic confirms that psql only presents client certificate,
without intermediate.

When using psycopg2 in Python (psycopg2 uses libpq and I'm testing with the
same settings and certificates as with psql), the first connection fails
with the same error, but it succeeds if it's retried. tcpdump of traffic
confirms, that on the second try both client and intermediate certificates
are sent.

It works correctly (psql connects successfully and psycopg2 connects on
first try) when PostgreSQL is compiled with OpenSSL 1.0.1. It also works
correctly if server is compiled with OpenSSL 1.0.2, but client with OpenSSL
1.0.1.

My educated guess is that in fe-secure-openssl.c in initialize_SSL function
whole certificate chain is loaded into SSL_context, but only client
certificate is loaded to SSL object. SSL object is created before loading
certificate chain into SSL_context, so it doesn't see this update. Only the
next connection, with new SSL object, picks up the certificate chain from
SSL_context. It doesn't explain why it works with OpenSSL 1.0.1 though, so
that may be a false trail.

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Keiko Oda 2016-09-20 22:30:31 Segmentation fault with pg_restore
Previous Message Michael Paquier 2016-09-20 08:14:41 Re: BUG #14325: backup restore inherited constraint