As pointed out by Jeffrey Walton, only SSLv23_method() will negotiate
higher TLS versions than immediately requested.  All other _method()
functions will negotiate only one specific version.

Attached are two patches:

* libpq.tls11plus.diff

Use SSLv23_method() instead TLSv1_method in fe-secure.c.  Also
disable SSLv2 and SSLv3 so TLSv1 continues to be minimum
TLS version negotiated.  This means TLSv1.1 or TLSv1.2 will be
used as protocol if both sides can speak it.

* psql.conninfo.tlsver.diff

Make psql \conninfo show TLS protocol version.  It's really hard
to see what version is actually used otherwise without using
network dumps.


Random findings
---------------

- TLSv1.1 and TLSv1.2 are implemented in OpenSSL 1.0.1.

- All OpenSSL 1.0.1+ versions negotiate TLSv1.2 with SSLv23_method()
  by default.  This is default also in OpenSSL git branches (1.0.1-stable,
  1.0.2-stable, master).

- OpenSSL versions up to 0.9.7f send SSLv2 ClientHello from SSLv23_method()
  even when SSLv2 and SSLv3 are disabled.  They still manage to
  negotiate TLSv1.  Since version 0.9.7h, OpenSSL sends TLSv1 ClientHello
  in those circumstances.

- Ubuntu uses compilation flag that disables TLSv1.2 in SSLv23_method().

- Ubuntu also uses compilation flag to cut TLSv1.2 cipher list to first 25.
  This means only AES256 usable.  This also disables secure renegotation
  as that is signaled with extra ciphersuite.  And because of previous flag,
  it affects only programs using TLSv1_2_method() directly.
  I see signs of confusion here.

- Debian and Fedora OpenSSL 1.0.1+ packages do not mess with TLSv1.2,
  so I assume everything is fine there.


Because the patches are small and look safe, it might be better if they
are handled together with other SSL patches in this commitfest.  That
would give them more mileage before release, to see if any problems
pop out.  But I can add them to next commitfest if that is not OK.

-- 
marko

diff --git a/src/interfaces/libpq/fe-secure.c b/src/interfaces/libpq/fe-secure.c
index d88c752..74b9fa2 100644
--- a/src/interfaces/libpq/fe-secure.c
+++ b/src/interfaces/libpq/fe-secure.c
@@ -966,7 +966,12 @@ init_ssl_system(PGconn *conn)
 			SSL_load_error_strings();
 		}
 
-		SSL_context = SSL_CTX_new(TLSv1_method());
+		/*
+		 * SSLv23_method() is only method that negotiates
+		 * higher protocol versions.  Rest of the methods
+		 * allow only one specific TLS version.
+		 */
+		SSL_context = SSL_CTX_new(SSLv23_method());
 		if (!SSL_context)
 		{
 			char	   *err = SSLerrmessage();
@@ -981,6 +986,9 @@ init_ssl_system(PGconn *conn)
 			return -1;
 		}
 
+		/* Disable old protocol versions */
+		SSL_CTX_set_options(SSL_context, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
+
 		/*
 		 * Disable OpenSSL's moving-write-buffer sanity check, because it
 		 * causes unnecessary failures in nonblocking send cases.
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 638d8cb..0763163 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -1795,8 +1795,8 @@ printSSLInfo(void)
 		return;					/* no SSL */
 
 	SSL_get_cipher_bits(ssl, &sslbits);
-	printf(_("SSL connection (cipher: %s, bits: %d)\n"),
-		   SSL_get_cipher(ssl), sslbits);
+	printf(_("SSL connection (protocol: %s, cipher: %s, bits: %d)\n"),
+		   SSL_get_version(ssl), SSL_get_cipher(ssl), sslbits);
 #else
 
 	/*
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to