PQgetssl() and alternative SSL implementations - Mailing list pgsql-hackers

From Heikki Linnakangas
Subject PQgetssl() and alternative SSL implementations
Date
Msg-id 53F1E989.8020609@vmware.com
Whole thread Raw
Responses Re: PQgetssl() and alternative SSL implementations
Re: PQgetssl() and alternative SSL implementations
Re: PQgetssl() and alternative SSL implementations
List 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




pgsql-hackers by date:

Previous
From: Greg Stark
Date:
Subject: Re: wrapping in extended mode doesn't work well with default pager
Next
From: Michael Paquier
Date:
Subject: Re: wrapping in extended mode doesn't work well with default pager