1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-30 11:03:19 +03:00

Remove support for tls-unique channel binding.

There are some problems with the tls-unique channel binding type. It's not
supported by all SSL libraries, and strictly speaking it's not defined for
TLS 1.3 at all, even though at least in OpenSSL, the functions used for it
still seem to work with TLS 1.3 connections. And since we had no
mechanism to negotiate what channel binding type to use, there would be
awkward interoperability issues if a server only supported some channel
binding types. tls-server-end-point seems feasible to support with any SSL
library, so let's just stick to that.

This removes the scram_channel_binding libpq option altogether, since there
is now only one supported channel binding type.

This also removes all the channel binding tests from the SSL test suite.
They were really just testing the scram_channel_binding option, which
is now gone. Channel binding is used if both client and server support it,
so it is used in the existing tests. It would be good to have some tests
specifically for channel binding, to make sure it really is used, and the
different combinations of a client and a server that support or doesn't
support it. The current set of settings we have make it hard to write such
tests, but I did test those things manually, by disabling
HAVE_BE_TLS_GET_CERTIFICATE_HASH and/or
HAVE_PGTLS_GET_PEER_CERTIFICATE_HASH.

I also removed the SCRAM_CHANNEL_BINDING_TLS_END_POINT constant. This is a
matter of taste, but IMO it's more readable to just use the
"tls-server-end-point" string.

Refactor the checks on whether the SSL library supports the functions
needed for tls-server-end-point channel binding. Now the server won't
advertise, and the client won't choose, the SCRAM-SHA-256-PLUS variant, if
compiled with an OpenSSL version too old to support it.

In the passing, add some sanity checks to check that the chosen SASL
mechanism, SCRAM-SHA-256 or SCRAM-SHA-256-PLUS, matches whether the SCRAM
exchange used channel binding or not. For example, if the client selects
the non-channel-binding variant SCRAM-SHA-256, but in the SCRAM message
uses channel binding anyway. It's harmless from a security point of view,
I believe, and I'm not sure if there are some other conditions that would
cause the connection to fail, but it seems better to be strict about these
things and check explicitly.

Discussion: https://www.postgresql.org/message-id/ec787074-2305-c6f4-86aa-6902f98485a4%40iki.fi
This commit is contained in:
Heikki Linnakangas
2018-08-05 13:44:21 +03:00
parent 87790fd1ea
commit 1b7378b3d6
15 changed files with 245 additions and 335 deletions

View File

@ -1245,34 +1245,6 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
</listitem>
</varlistentry>
<varlistentry id="libpq-scram-channel-binding" xreflabel="scram_channel_binding">
<term><literal>scram_channel_binding</literal></term>
<listitem>
<para>
Specifies the channel binding type to use with SCRAM
authentication. While <acronym>SCRAM</acronym> alone prevents
the replay of transmitted hashed passwords, channel binding also
prevents man-in-the-middle attacks.
</para>
<para>
The list of channel binding types supported by the server are
listed in <xref linkend="sasl-authentication"/>. An empty value
specifies that the client will not use channel binding. If this
parameter is not specified, <literal>tls-unique</literal> is used,
if supported by both server and client.
Channel binding is only supported on SSL connections. If the
connection is not using SSL, then this setting is ignored.
</para>
<para>
This parameter is mainly intended for protocol testing. In normal
use, there should not be a need to choose a channel binding type other
than the default one.
</para>
</listitem>
</varlistentry>
<varlistentry id="libpq-connect-replication" xreflabel="replication">
<term><literal>replication</literal></term>
<listitem>

View File

@ -1576,12 +1576,8 @@ the password is in.
<para>
<firstterm>Channel binding</firstterm> is supported in PostgreSQL builds with
SSL support. The SASL mechanism name for SCRAM with channel binding is
<literal>SCRAM-SHA-256-PLUS</literal>. Two channel binding types are
supported: <literal>tls-unique</literal> and
<literal>tls-server-end-point</literal>, both defined in RFC 5929. Clients
should use <literal>tls-unique</literal> if they can support it.
<literal>tls-server-end-point</literal> is intended for third-party clients
that cannot support <literal>tls-unique</literal> for some reason.
<literal>SCRAM-SHA-256-PLUS</literal>. The channel binding type used by
PostgreSQL is <literal>tls-server-end-point</literal>.
</para>
<para>
@ -1596,19 +1592,11 @@ that cannot support <literal>tls-unique</literal> for some reason.
<para>
<acronym>SCRAM</acronym> with channel binding prevents such
man-in-the-middle attacks by mixing a value into the transmitted
password hash that cannot be retransmitted by a fake server.
In <acronym>SCRAM</acronym> with <literal>tls-unique</literal>
channel binding, the shared secret negotiated during the SSL session
is mixed into the user-supplied password hash. The shared secret
is partly chosen by the server, but not directly transmitted, making
it impossible for a fake server to create an SSL connection with the
client that has the same shared secret it has with the real server.
<acronym>SCRAM</acronym> with <literal>tls-server-end-point</literal>
mixes a hash of the server's certificate into the user-supplied password
hash. While a fake server can retransmit the real server's certificate,
it doesn't have access to the private key matching that certificate, and
therefore cannot prove it is the owner, causing SSL connection failure.
man-in-the-middle attacks by mixing the signature of the server's
certificate into the transmitted password hash. While a fake server can
retransmit the real server's certificate, it doesn't have access to the
private key matching that certificate, and therefore cannot prove it is
the owner, causing SSL connection failure.
</para>
<procedure>

View File

@ -2693,10 +2693,7 @@ same commits as above
the feature currently does not prevent man-in-the-middle
attacks when using libpq and interfaces built using it. It is
expected that future versions of libpq and interfaces not built
using libpq, e.g. JDBC, will allow this capability. The libpq
options to control the optional channel binding type are <link
linkend="libpq-scram-channel-binding"><option>scram_channel_binding=tls-unique</option></link>
and <option>scram_channel_binding=tls-server-end-point</option>.
using libpq, e.g. JDBC, will allow this capability.
</para>
</listitem>