Supporting tls-server-end-point as SCRAM channel binding for OpenSSL 1.0.0 and 1.0.1

From: Michael Paquier <michael(at)paquier(dot)xyz>
To: Postgres hackers <pgsql-hackers(at)postgresql(dot)org>
Cc: sfackler(at)gmail(dot)com
Subject: Supporting tls-server-end-point as SCRAM channel binding for OpenSSL 1.0.0 and 1.0.1
Date: 2018-05-29 21:02:12
Message-ID: 20180529210212.GE6632@paquier.xyz
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi all,

Currently, the SCRAM channel binding tls-server-end-point is supported
only with OpenSSL 1.0.2 and newer versions as we rely on
X509_get_signature_nid to get the certificate signature ID, which is the
official way of upstream to get this information as all the contents of
X509 are shadowed since this version.

I think that this matters for users of JDBC with environments shipping
and maintaining longer than upstream versions of OpenSSL like 1.0.1 and
1.0.0 (Redhat is one of them).

Stephen Fackler, who is in CC, has reported to me off-list that it is
possible to get easily this information by looking at
X509->sig_alg->algorithm, which to easily get tls-server-end-point
support for OpenSSL 1.0.0 and 1.0.1.

The official way to get the hashing algorithm is then to apply
OBJ_find_sigid_algs, which is only available since 1.0.0. Stephen has
also pointed me out that we could use EVP_get_digestbynid, but it is
surprising to see that working correctly if you particularly look at
upstream commit ee1d9ec which introduced a sort of hack to fix links
between the digest and signature algorithms in OpenSSL 1.0.0 and above.
Anyway, it seems to me that it would not be a good bet to rely on an
upstream hack as we may get trapped later on if the handlings for
EVP_get_digestbynid get reworked by upstream again. So I propose to
rely on OBJ_find_sigid_algs which is the official interface to get the
signature algorithm as far as I understand.

While hacking on that, I also noticed that OBJ_find_sigid_algs can crash
when using OpenSSL 1.0.0 if a NULL input is used with its 2nd and 3rd
arguments, which is an issue fixed by upstream in commit 177f27d,
present since 1.0.1 but bit 1.0.0, so we need an idle field to get that
to work properly with OpenSSL 1.0.0.

Attached is the result of this investigation, which I have tested using
OpenSSL from 0.9.8 to 1.0.2 compiled manually. 0.9.8 fails any
connection attempt with tls-server-end-point, while 1.0.0, 1.0.1 and
1.0.2 succeed properly.

An open item is added as well.

One of the versions I discussed with Stephen is here by the way, and I
am attaching it to this thread as well for transparency (see
end-point-support-stephen.patch):
https://github.com/sfackler/postgres/commit/93383be85358a1ee03f34f34de45058e238964d1

Thanks,
--
Michael

Attachment Content-Type Size
end-point-support-stephen.patch text/x-diff 7.2 KB
0001-Allow-tls-server-end-point-with-OpenSSL-1.0.0-and-1..patch text/x-diff 7.1 KB

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Michael Paquier 2018-05-29 21:15:59 pg_config.h.win32 missing a set of flags from pg_config.h.in added in v11 development
Previous Message Tom Lane 2018-05-29 20:38:36 Re: "column i.indnkeyatts does not exist" in pg_upgrade from 11dev to 11b1