PQgetssl() and alternative SSL implementations

From: Heikki Linnakangas <hlinnakangas(at)vmware(dot)com>
To: PostgreSQL-development <pgsql-hackers(at)postgreSQL(dot)org>
Subject: PQgetssl() and alternative SSL implementations
Date: 2014-08-18 11:54:49
Message-ID: 53F1E989.8020609@vmware.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

In order to support alternatives to OpenSSL, we need to wean off
applications from using PQgetssl(). To do that, we have to provide an
alternative API to get the same information. PQgetSSL() returns a
pointer directly to the OpenSSL private struct, and you can do anything
with that. We cannot have a generic interface that exposes everything,
so we need to identify the information that people actually want, and
expose that.

In the ancient patch that Martijn posted for this back in 2006 (*), he
added a new libpq function called PQgettlsinfo, which returned all
attributes the SSL implementation exposes as a result set with two
columns, key and value. I think that was a bit awkward - a caller that's
interested in a specific attribute would need to iterate through the
result set to find the one its looking for. And some of the values might
be somewhat expensive to calculate - e.g. extracting some attribute of
the server certificate - so it would be better to only calculate the
attributes that are actually needed.

I propose two functions like this:

-------

const char *
PQsslAttribute(const PGconn *conn, const char *attributeName)

Look up an attribute with the given name. Returns NULL if no attribute
with that name is found.

The following common attributes are available:

library: name of the SSL implementation used. Currently always
"OpenSSL", or NULL if not compiled with SSL support.

active: Is the current connection using SSL? "yes" or "no" (note that
"yes" does not necessarily mean that the connection is secure, e.g. if
the null-cipher is used)

server_cert_valid: Did the server present a valid certificate? "yes"
or "no"

server_cert_matches_host: Does the Common Name of the certificate
match the host connected to? "yes" or "no"

compression: Is SSL compression is in use, returns the name of the
compression algorithm, or "yes" if compression is used but the algorithm
is not known. If compression is not enabled, returns "no".

The following standard attributes are available to get more information
on the ciphersuite. Note that an SSL implementation may not provide all
the attributes:

protocol: SSL/TLS version in use. Common values are "SSLv2", "SSLv3",
"TLSv1", "TLSv1.1" and "TLSv1.2", but an implementation may return other
strings if some other protocol is used.

cipher: a short name of the ciphersuite used, e.g.
"DHE-RSA-DES-CBC3-SHA". The names are specific to each SSL implementation.

key_bits: number of key bits used by the encryption algorithm.

An implementation may provide any number of additional,
implementation-specific attributes.

Although the returned pointer is declared const, it in fact points to
mutable storage associated with the PGconn structure. It is unwise to
assume the pointer will remain valid across queries.

const char **
PQsslListAttributes(const PGconn *conn)

Return an array of SSL attribute names available. The array is
terminated by a NULL pointer. Use PQsslAttribute to get the value of an
attribute.

-------

Exposing the SSL information as generic key/value pairs allows adding
more attributes in the future, without breaking the ABI, and it also
allows exposing implementation-specific information in a generic way.
The attributes listed above cover the needs of psql. What else do we need?

I think it would also be nice to get more information from the server's
certificate, like the hostname and the organization its issued to, and
expiration date, so that an interactive client like pgAdmin or even psql
could display that information like a web browser does. Would it be best
to add those as extra attributes in the above list, perhaps with a
"server_cert_*" prefix, or add a new function for extracting server
cert's attributes?

The other question is: What do we do with PQgetssl()? We should document
it as deprecated, but we'll have to keep it around for the foreseeable
future for backwards-compatibility. We obviously cannot return a valid
OpenSSL struct when using any other implementation, so I think it'll
have to just return NULL when not using OpenSSL. Probably the most
common use of PQgetssl() is to just check if it returns NULL or not, to
determine if SSL is enabled, so a client that does that would
incorrectly think that SSL is not used, even when it is. I think we can
live with that.

(*) http://www.postgresql.org/message-id/20060504134807.GK4752@svana.org

- Heikki

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Michael Paquier 2014-08-18 11:55:42 Re: wrapping in extended mode doesn't work well with default pager
Previous Message Greg Stark 2014-08-18 11:30:40 Re: wrapping in extended mode doesn't work well with default pager