LibreSSL and OpenSSL separation in libpq to support 1.1.1 deprecation

Started by Daniel Gustafsson2 months ago9 messageshackers
Beta feature

Hackorum builds and tests every patch posted to the lists, not only commitfest submissions. This is Hackorum's own CI rather than the PostgreSQL project's, and it is still under testing - please report anything that looks wrong.

appliesbuild failedCI history

Every patchset is also pushed to a branch of our PostgreSQL fork, so you can check out the same tree CI built. Without a PostgreSQL checkout:

git clone --branch t253036_1 https://github.com/hackorum-dev/postgres.git

In a checkout you already have, add the fork once:

git remote add hackorum https://github.com/hackorum-dev/postgres.git

then, for this patchset and every later one:

git fetch hackorum t253036_1 && git checkout t253036_1

Patchset v1 (message #1) is on t253036_1

Jump to latest
#1Daniel Gustafsson
daniel@yesql.se

Since the discussion on the minimum supported version of OpenSSL for v20 has
kicked off, I wanted to share what I believe is an important step on the path
to OpenSSL modernization; namely how to deal with LibreSSL.

Our LibreSSL support is currently based on the OpenSSL code and the OpenSSL
compatibility in LibreSSL, so much so that for quite some time we didn't even
document that it was supported even though it was buildfarm tested. Over time
we've accumulated more ifdefs for differences in API support. If we want to
modernize our OpenSSL support in libpq with v3+ API's once we've deprecated
1.1.1, the code will soon become unreadable and IMHO, a CVE hazard.

LibreSSL supports the 1.1.1 API, and they dont have the manpower to keep up
with the rapid pace of OpenSSL development so are likely to stay there for the
foreseeable future. The libraries have already started diverging quite a lot
and it will continue (LibreSSL have also developed their own API which if I
were them is what I'd focus on).

As I can see it we have two choices wrt LibreSSL if we want to move past 1.1.1;
either deprecate support or separate it out such that OpenSSL and LibreSSL can
move at their own pace. I don't like the idea of deprecating LibreSSL so I
favor the latter alternative.

The attached implements LibreSSL as a separate TLS library implementation (*)
in libpq with fe-secure-libressl.c and be-secure-libressl.c along with build
and test infrastructure. This is a PoC rather than a polished for-inclusion
patch as of now, since I wanted to get the discussion going. Some of the known
TODO items include:

- Autoconf support is a POC and not tested at all yet, only the
Meson side has been tested as of now
- include/common/openssl.h needs to either be renamed, copied
or at least have its comments extended
- test/ssl/t/SSL/Backend/OpenSSL.pm has been hackily extended
for now, the exact level of changes required here are not
clear, and a future move to pytest may influence how much we
want to invest here
- the discovery in meson.build is likely rubbish and could be
cleaned up by our Meson experts
- there are likely lots of comments still that mention OpenSSL
which could be expanded to say something about LibreSSL
- documentation of the build option is missing
- we can simplify a few uses of USE_OPENSSL || USE_LIBRESSL to
just USE_SSL

There are no new features introduced (and none removed) or API usage changes,
the only changes are to cut away the ifdefs and only keep the code we actually
need per file. This way the differences are quite easy to check by diffing
{fe|be}-secure-{openssl|libressl}.c.

While this duplicate a lot of code, it doesn't really add a maintenance burden
we don't already carry since we do support LibreSSL already, but it does alter
the burden for sure (not least when it comes to backpatching). That being
said, staying on a long-since deprecated API level (we are at 1.0.1 with
warnings silenced) also doesn't sound great.

One option is to not do this until we have a case where we want to use a v3+
API and only do it then as a prerequisite step; keeping the patch rebased in
the back-pocket till that day comes. Personally I have serverside SNI support
for LibreSSL on my radar for v20, which will need such a split in order to keep
the files readable as it will be implemented quite differently from its OpenSSL
counterpart.

All of the above is of course moot if we don't move the needle past 1.1.1 in
v20..

--
Daniel Gustafsson

(*) Yes. The irony of me proposing to add a new TLS library implementation to
postgres is *not* lost on me.

Attachments:

t253036_1
vPoC-0001-ssl-Split-OpenSSL-and-LibreSSL-into-separate-mo.patchapplication/octet-stream; name=vPoC-0001-ssl-Split-OpenSSL-and-LibreSSL-into-separate-mo.patch; x-unix-mode=0644Download+4105-202
#2Peter Eisentraut
peter_e@gmx.net
In reply to: Daniel Gustafsson (#1)
Re: LibreSSL and OpenSSL separation in libpq to support 1.1.1 deprecation

On 09.07.26 23:14, Daniel Gustafsson wrote:

The attached implements LibreSSL as a separate TLS library implementation (*)
in libpq with fe-secure-libressl.c and be-secure-libressl.c along with build
and test infrastructure.

I'm skeptical about this approach. What has been presented so far
doesn't convince me that the differences between the openssl and the
libressl variants will be larger than their commonalities.

As an example, my recent patch [0]/messages/by-id/953bceb7-340d-4717-9682-0ebe65c4b57e@eisentraut.org works just the same on both (AFAICT).
I didn't have to worry about the differences at all.

Under the proposed system, I would have to make the same code changes
twice, test everything twice (including obtaining libressl in the first
place and set up a separate build for it). Doesn't sound appealing.

Another possible future of the proposed system is that changes and
improvements for the libressl variant are forgotten or just skipped,
which would lead to it degrading over time, while now at least it is
sort of dragged along by force.

[0]: /messages/by-id/953bceb7-340d-4717-9682-0ebe65c4b57e@eisentraut.org
/messages/by-id/953bceb7-340d-4717-9682-0ebe65c4b57e@eisentraut.org

#3Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Peter Eisentraut (#2)
Re: LibreSSL and OpenSSL separation in libpq to support 1.1.1 deprecation

On 2026-Aug-12, Peter Eisentraut wrote:

On 09.07.26 23:14, Daniel Gustafsson wrote:

The attached implements LibreSSL as a separate TLS library implementation (*)
in libpq with fe-secure-libressl.c and be-secure-libressl.c along with build
and test infrastructure.

I'm skeptical about this approach. What has been presented so far doesn't
convince me that the differences between the openssl and the libressl
variants will be larger than their commonalities.

I think it should be possible to have one file where the common routines
that are identical for both libraries live (say be-secure-lossl.c for
"libre/open" or whatever), and the corresponding be-secure-libressl.c
and be-secure-openssl.c files only have the routines that differ between
the two implementations. So the common code appears once and has to be
patched just once, and we would only have differences where we must.
Probably it's easiest to do this by having one .c file that's included
by the other two, to avoid having to export the static variables and
such.

(Looking at the patch Peter mentions and the diff between the two
be-secure files after Daniel's patch, the code involved there would be
wholly in the common file, so there would be no need for double
patching.)

The diff between the two files has 552 "-" lines (mostly, libressl
removing the SNI code), 89 "+" lines, and 1889 common lines. So this is
not a completely absurd approach. In the src/interfaces/libpq code, the
fraction of code that is common is even more pronounced. (In fact
looking at that diff I wonder if fe-secure-libressl.c just didn't keep
track of recent changes e.g. 7d45a6dc1974.)

--
Álvaro Herrera Breisgau, Deutschland — https://www.EnterpriseDB.com/
"We have labored long to build a heaven, only (Prof. Milton Glass)
to find it populated with horrors" (Watchmen, Alan Moore)

#4Daniel Gustafsson
daniel@yesql.se
In reply to: Peter Eisentraut (#2)
Re: LibreSSL and OpenSSL separation in libpq to support 1.1.1 deprecation

On 12 Aug 2026, at 11:51, Peter Eisentraut <peter@eisentraut.org> wrote:

On 09.07.26 23:14, Daniel Gustafsson wrote:

The attached implements LibreSSL as a separate TLS library implementation (*)
in libpq with fe-secure-libressl.c and be-secure-libressl.c along with build
and test infrastructure.

I'm skeptical about this approach. What has been presented so far doesn't convince me that the differences between the openssl and the libressl variants will be larger than their commonalities.

That assumes that future changes are done within the 1.1.1 API, which is
already not the case since 1f3b9bb109b8b1a7b (granted, it's in src/common but
similar patches against be-secure-openssl.c are already on the list).

Personally I'd be much more interested in deprecating 1.1.1 and moving us onto
supported APIs. Until we do there is of course no point in a patch like this
(which I tried to say upthread).

As an example, my recent patch [0] works just the same on both (AFAICT). I didn't have to worry about the differences at all.

While not introduced in this patch, merely moved, it also use a since 3.0
deprecated API which is not available in LibreSSL. Reading the implementation
they seem quite similar apart from ibreSSL not supporting increased keysize
when using SSL_CTX_set_security_level. While we don't use the security level
API, it's an example of difference behind the API which *I* constantly worry
about when poking at this code.

Under the proposed system, I would have to make the same code changes twice, test everything twice (including obtaining libressl in the first place and set up a separate build for it). Doesn't sound appealing.

Testing everything twice isn't new, we already need to test all libpq TLS
related changes on both OpenSSL and LibreSSL since they are supported.
Trusting that one works because the other one does is a brittle assumption and
I've had to revert commits because of precisely that reason. Applying code
twice is a real pain though, but navigating an increased level of ifdefs won't
be pleasant either (assuming it happens of course).

Again, all of this is moot if we don't deprecate 1.1.1 support, but I don't
think we are doing our users a service by allowing them to use an TLS library
which when v20 goes EOL has been out of security updates for 8+ years.

--
Daniel Gustafsson

#5Jacob Champion
jacob.champion@enterprisedb.com
In reply to: Daniel Gustafsson (#4)
Re: LibreSSL and OpenSSL separation in libpq to support 1.1.1 deprecation

On Wed, Aug 12, 2026 at 8:14 AM Daniel Gustafsson <daniel@yesql.se> wrote:

Under the proposed system, I would have to make the same code changes twice, test everything twice (including obtaining libressl in the first place and set up a separate build for it). Doesn't sound appealing.

Testing everything twice isn't new, we already need to test all libpq TLS
related changes on both OpenSSL and LibreSSL since they are supported.
Trusting that one works because the other one does is a brittle assumption and
I've had to revert commits because of precisely that reason. Applying code
twice is a real pain though, but navigating an increased level of ifdefs won't
be pleasant either (assuming it happens of course).

+1 -- this is where I kind of raised an eyebrow at your argument,
Peter. We're already doing that, and we *must* do it, whether it's
obvious or not that said work is being done. I'm very much in favor of
splitting that apart and making the invisible pain visible (at least
conceptually -- I haven't had a chance yet to sit down and look at
this particular patch, and I'm very sorry for that; maybe a hybrid
such as Alvaro's suggestion would work too).

In my opinion, keeping the two same-in-name-but-not-in-practice
implementations together is keeping things more brittle, not less,
most recently when I look at the SNI work. If we split the two, then
in addition to not risking 1.1.1-based destabilization as we move to
4.0 APIs, we can investigate porting LibreSSL code on top of their
libtls API instead.

Again, all of this is moot if we don't deprecate 1.1.1 support, but I don't
think we are doing our users a service by allowing them to use an TLS library
which when v20 goes EOL has been out of security updates for 8+ years.

We should do that for PG20. I'm continuing to push for that in other
threads [1]/messages/by-id/CAOYmi+=VJJ=1a-wHwWd2mTgQ3bkHzAUHCFssosF7h1y8TEN+iw@mail.gmail.com. No one has said "no" yet, I think, so IMNSHO we should
just do it.

Thanks,
--Jacob

[1]: /messages/by-id/CAOYmi+=VJJ=1a-wHwWd2mTgQ3bkHzAUHCFssosF7h1y8TEN+iw@mail.gmail.com

#6Daniel Gustafsson
daniel@yesql.se
In reply to: Alvaro Herrera (#3)
Re: LibreSSL and OpenSSL separation in libpq to support 1.1.1 deprecation

On 12 Aug 2026, at 13:24, Álvaro Herrera <alvherre@kurilemu.de> wrote:

I think it should be possible to have one file where the common routines
that are identical for both libraries live (say be-secure-lossl.c for
"libre/open" or whatever), and the corresponding be-secure-libressl.c
and be-secure-openssl.c files only have the routines that differ between
the two implementations. So the common code appears once and has to be
patched just once, and we would only have differences where we must.

A scheme like that is certainly an option as well. There might also be parts
which could be extracted into be-secure-common.c on the grounds of not being
OpenSSL specific at all.

Probably it's easiest to do this by having one .c file that's included
by the other two, to avoid having to export the static variables and
such.

I'm not a fan of #including a C file, and the move towards threading requires
us to clean up and remove such things anyways no?

--
Daniel Gustafsson

#7Michael Paquier
michael@paquier.xyz
In reply to: Jacob Champion (#5)
Re: LibreSSL and OpenSSL separation in libpq to support 1.1.1 deprecation

On Wed, Aug 12, 2026 at 08:34:14AM -0700, Jacob Champion wrote:

In my opinion, keeping the two same-in-name-but-not-in-practice
implementations together is keeping things more brittle, not less,
most recently when I look at the SNI work. If we split the two, then
in addition to not risking 1.1.1-based destabilization as we move to
4.0 APIs, we can investigate porting LibreSSL code on top of their
libtls API instead.

OpenSSL 3.0 has from an architectural point of view forked hard from
LibreSSL. I agree that dropping 1.1.1 and doing this split is a
sensible thing long-term: it would make easier the modernization of
both LibreSSL and OpenSSL code paths.

On top of 1f3b9bb109b8 and b91f79cd08ab, there was a third patch for
channel binding that I was planning to take care of by the end of this
week to be completely done with the EVP switch and the removal of the
legacy SHA APIs for the backend code and libpq. If that's annoying in
terms of what this thread is dealing with, please let me know. I
don't think so, but well, as a wise man said N PostgreSQL hackers can
have up to (N+1) opinions.

We should do that for PG20. I'm continuing to push for that in other
threads [1]. No one has said "no" yet, I think, so IMNSHO we should
just do it.

I say yes to this split in v20, as much as yes to a drop of 1.1.1 in
v20.

My question would be a bit different, though: in which order should
things be worked out? First a file-based split and then a drop of
OpenSSL 1.1.1 or the opposite? I'm finding a drop of OpenSSL 1.1.1
done first a bit unattractive because we still need to support the
LibreSSL path with what OpenSSL has already marked as deprecated.

Please note that I did not look at the internals of LibreSSL to see if
they still recommend the use of the EVP_sha*() routines or not..
--
Michael

#8Daniel Gustafsson
daniel@yesql.se
In reply to: Michael Paquier (#7)
Re: LibreSSL and OpenSSL separation in libpq to support 1.1.1 deprecation

On 13 Aug 2026, at 00:56, Michael Paquier <michael@paquier.xyz> wrote:

If that's annoying in terms of what this thread is dealing with, please let me
know.

No problems at all, please go ahead.

--
Daniel Gustafsson

#9Michael Paquier
michael@paquier.xyz
In reply to: Daniel Gustafsson (#8)
Re: LibreSSL and OpenSSL separation in libpq to support 1.1.1 deprecation

On Thu, Aug 13, 2026 at 09:33:41AM +0200, Daniel Gustafsson wrote:

No problems at all, please go ahead.

OK, thanks! I think that I am done with all the changes planned.
That should ease this thread a bit, hopefully..
--
Michael