OpenSSL 3.0.0 compatibility
Since OpenSSL is now releasing 3.0.0-alpha versions, I took a look at using it
with postgres to see what awaits us. As it is now shipping in releases (with
GA planned for Q4), users will probably soon start to test against it so I
wanted to be prepared.
Regarding the deprecations, we can either set preprocessor directives or use
compiler flags to silence the warning and do nothing (for now), or we could
update to the new API. We probably want to different things for master vs
back-branches, but as an illustration of what the latter could look like I've
implemented this in 0001.
SSL_CTX_load_verify_locations and X509_STORE_load_locations are deprecated and
replaced by individual calls to load files and directories. These are quite
straightforward, and are implemented like how we handle the TLS protocol API.
DH_check has been discouraged to use for quite some time, and is now marked
deprecated without a 1:1 replacement. The OpenSSL docs recommends using the
EVP API, which is also done in 0001. For now I just stuck it in with version
gated ifdefs, something cleaner than that can clearly be done. 0001 is clearly
not proposed for review/commit yet, it's included in case someone else is
interested as well.
OpenSSL also deprecates DES keys in 3.0.0, which cause our password callback
tests to fail with the cryptic error "fetch failed", as the test suite keys are
encrypted with DES. 0002 fixes this by changing to AES256 (randomly chosen
among the ciphers supported in 1.0.1+ and likely to be around), and could be
applied already today as there is nothing 3.0.0 specific about it.
On top of DES keys there are also a lot of deprecations or low-level functions
which breaks pgcrypto in quite a few ways. I haven't tackled these yet, but it
looks like we have to do the EVP rewrite there.
cheers ./daniel
Attachments:
0002-OpenSSL-3.0.0-compatibility-in-tests.patchapplication/octet-stream; name=0002-OpenSSL-3.0.0-compatibility-in-tests.patch; x-unix-mode=0644Download
From f6f3f2e84fd4947f422e5d1a0eb503f25cc76f8b Mon Sep 17 00:00:00 2001
From: Daniel Gustafsson <daniel@yesql.se>
Date: Tue, 26 May 2020 20:32:06 +0200
Subject: [PATCH 2/2] OpenSSL 3.0.0 compatibility in tests
DES has been deprecated in OpenSSL 3.0.0 which makes loading keys
encrypted with DES fail with "fetch failed". Solve by changing the
cipher used to aes256 which has been supported since 1.0.1 (and is
more realistic to use anyways).
---
src/test/ssl/Makefile | 2 +-
src/test/ssl/ssl/server-password.key | 52 ++++++++++++++--------------
2 files changed, 27 insertions(+), 27 deletions(-)
diff --git a/src/test/ssl/Makefile b/src/test/ssl/Makefile
index 06e37d5269..777ee39413 100644
--- a/src/test/ssl/Makefile
+++ b/src/test/ssl/Makefile
@@ -79,7 +79,7 @@ ssl/server-ss.crt: ssl/server-cn-only.key ssl/server-cn-only.crt server-cn-only.
# Password-protected version of server-cn-only.key
ssl/server-password.key: ssl/server-cn-only.key
- openssl rsa -des -in $< -out $@ -passout 'pass:secret1'
+ openssl rsa -aes256 -in $< -out $@ -passout 'pass:secret1'
# Client certificate, signed by the client CA:
ssl/client.crt: ssl/client.key ssl/client_ca.crt
diff --git a/src/test/ssl/ssl/server-password.key b/src/test/ssl/ssl/server-password.key
index 337054fe4f..a8e383a949 100644
--- a/src/test/ssl/ssl/server-password.key
+++ b/src/test/ssl/ssl/server-password.key
@@ -1,30 +1,30 @@
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
-DEK-Info: DES-CBC,6FCB918813C446D2
+DEK-Info: AES-256-CBC,B335CBE53A05F4FC5805FC038BA80BA0
-rNHoFsQpQh1UGbh2QSgtWj/pkoe29Q+uZgEwbCTIfE/ONMoiZLC6f2g+PDPg2qYn
-BC4VY2NbxkOLw7kK3k6cHwRD5YWfzm+HxmXQYsfPCeGV+C/Pse8srswh7GERSQ77
-zEn7BzkXnevL8ytYAoqezYjXaDSh+76KSN64R21zaGvgToQRGICCevbnjnNRI+HJ
-sPGGFTRIWLNNnxULHYpFbMXoJSnOrCbpzEqshUFkdGTpLvLW9se3/LVMWy/Wssje
-GwQbh9mDavUlFUl+vTn+ER4C0pzV10DjtQzkDhx88OIhdTsPQ8ClIvVFpBI6fjME
-je1n4YkLWGfJrXpifg8hAedmQ9tiw/E+h8IjZJfUgL+C2QybCQ8Yx1/v8HUYzwkA
-O7WMM90qI2sxzKWJZVvRVIY7zaTzFcvhpZrceX+d7iLV3h9UF4ru0CcUqK13t3ax
-4oOvQnj8DP0fThQOloQX4zY1oUqgLNFdoqgwMIssHzCdsyZ5VdFz8iWA1n+syzKC
-DGPJHo4DQ/YNpy0gGmBUcHaiyeKsaDYBQBwE7xm3UnrtYCr1WKkcYfncuNXCZdDJ
-X8qiB1w6diDKor9NC15uBBVjv3ERCx1rgG98+KvenQob9dtd6iguLjWtUsQoGI8D
-mgcwIuw4NRMIxZa5+1ITOkjnUfvXGTVHwvjHzz2BK6gFQu2NgwgZyrgqSMOZAn3T
-JcDDEhE8lgAsEPHVsPiLuc7DbH/ehkv8VocqJE7K9vmdR2UVG2wOO7p/1Ewm0RfJ
-9wsry4Ae0uqH+ay/TfMUBOC6tEqcPzicCMc9mYEOdnAjPwoDFFXLNdbjV8WG1KTr
-zzn9cucFvbyDOKecWbrduTbEFU5LbTddlOwWBaYVlS8xDX8wYTTyK0HnpLtP5KRJ
-69D+CYOnYAQyiPqRnZglIo4hSbNsiWThhWUlbGBWwynhR6fX4MA8PcoFnR88q3g3
-Wjmq0A0jIETwBxYrLFwvgi/PtQJ2p+yjhHCsl3idBgnGYtUiRxpCkuoCIBV1B23j
-CJB3NVoOOVEoGi9WYonLOt6vciYQhkjTkM4u3JP6rB/9kDIRpW4HeXYzrhmo0JA2
-PtRbvEwJyMHNoyNc/Pf1ydb+lqv1TBUbPQLsNbzHLKklfAMhQGd3OJWn8NcGB4i7
-uXAHSA/zY5AuE4Vf6mdjCznKbqCGurT+CUctFBajLcV2gwaFT/DikzlzR+TdFJ8E
-Qcg+5XUzg7E7tTrLGjM/DFES7ECkpr1cYGheCgoZLj0lT3bLURUUHG4e6BnyGS6M
-AdeKh4mZL3HAcbI8rSyoTx0cszQu3BR4QeAMJcnsq69uuLZ3A/r5zYDTIerz53ZO
-JYGhWWEsRszToO5eGGKpONIPTIYRLtj5NBfoQ7PZGRfRBlX44Vv3JytsBjrpABJI
-iqge5jifhTKcWVB0/OAu3A3uKXOU7AozXa79sdTVRs2KoVAgRTDK7zy3FsYRsT03
-sBdZgR1pr90PhDjlJ6N3Ebk9MXbB9bcwx0C6C/aZPFTsXT6sEoPqlrd6gCLc/YU/
-uTaXmARj45I89uRcZtroq5dZy5HE5nBpds7Vydiz1MwBnIMyBRjjAg==
+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
-----END RSA PRIVATE KEY-----
--
2.21.1 (Apple Git-122.3)
0001-Compatibility-with-OpenSSL-3.0.0.patchapplication/octet-stream; name=0001-Compatibility-with-OpenSSL-3.0.0.patch; x-unix-mode=0644Download
From 28ed04b053247ecbcb1f14045cd16f98864f2488 Mon Sep 17 00:00:00 2001
From: Daniel Gustafsson <daniel@yesql.se>
Date: Tue, 26 May 2020 20:21:30 +0200
Subject: [PATCH 1/2] Compatibility with OpenSSL 3.0.0
OpenSSL 3.0.0 deprecates a set of functions used in libpq:
SSL_CTX_load_verify_locations and X509_STORE_load_locations were
replaced with individual calls for file and directory, so replace
with the appropriate call since we only have configuration options
for files.
Usage of DH_check has been discouraged for a long time, and it was
finally deprecated with no direct replacement. Instead implement a
version using the EVP api which is the recommended alternative.
u
---
src/backend/libpq/be-secure-openssl.c | 81 +++++++++++++++++-------
src/common/Makefile | 3 +-
src/common/cert_openssl.c | 42 ++++++++++++
src/include/common/openssl.h | 6 ++
src/interfaces/libpq/fe-secure-openssl.c | 4 +-
5 files changed, 110 insertions(+), 26 deletions(-)
create mode 100644 src/common/cert_openssl.c
diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c
index 78a865d23b..32bdca30a1 100644
--- a/src/backend/libpq/be-secure-openssl.c
+++ b/src/backend/libpq/be-secure-openssl.c
@@ -266,7 +266,7 @@ be_tls_init(bool isServerStart)
*/
if (ssl_ca_file[0])
{
- if (SSL_CTX_load_verify_locations(context, ssl_ca_file, NULL) != 1 ||
+ if (SSL_CTX_load_verify_file(context, ssl_ca_file) != 1 ||
(root_cert_list = SSL_load_client_CA_file(ssl_ca_file)) == NULL)
{
ereport(isServerStart ? FATAL : LOG,
@@ -289,7 +289,7 @@ be_tls_init(bool isServerStart)
if (cvstore)
{
/* Set the flags to check against the complete CRL chain */
- if (X509_STORE_load_locations(cvstore, ssl_crl_file, NULL) == 1)
+ if (X509_STORE_load_file(cvstore, ssl_crl_file) == 1)
{
X509_STORE_set_flags(cvstore,
X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
@@ -817,7 +817,6 @@ load_dh_file(char *filename, bool isServerStart)
{
FILE *fp;
DH *dh = NULL;
- int codes;
/* attempt to open file. It's not an error if it doesn't exist. */
if ((fp = AllocateFile(filename, "r")) == NULL)
@@ -841,30 +840,66 @@ load_dh_file(char *filename, bool isServerStart)
return NULL;
}
- /* make sure the DH parameters are usable */
- if (DH_check(dh, &codes) == 0)
+#if OPENSSL_VERSION_MAJOR < 3
{
- ereport(isServerStart ? FATAL : LOG,
- (errcode(ERRCODE_CONFIG_FILE_ERROR),
- errmsg("invalid DH parameters: %s",
- SSLerrmessage(ERR_get_error()))));
- return NULL;
- }
- if (codes & DH_CHECK_P_NOT_PRIME)
- {
- ereport(isServerStart ? FATAL : LOG,
- (errcode(ERRCODE_CONFIG_FILE_ERROR),
- errmsg("invalid DH parameters: p is not prime")));
- return NULL;
+ int codes;
+
+ /* make sure the DH parameters are usable */
+ if (DH_check(dh, &codes) == 0)
+ {
+ ereport(isServerStart ? FATAL : LOG,
+ (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ errmsg("invalid DH parameters: %s",
+ SSLerrmessage(ERR_get_error()))));
+ return NULL;
+ }
+ if (codes & DH_CHECK_P_NOT_PRIME)
+ {
+ ereport(isServerStart ? FATAL : LOG,
+ (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ errmsg("invalid DH parameters: p is not prime")));
+ return NULL;
+ }
+ if ((codes & DH_NOT_SUITABLE_GENERATOR) &&
+ (codes & DH_CHECK_P_NOT_SAFE_PRIME))
+ {
+ ereport(isServerStart ? FATAL : LOG,
+ (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ errmsg("invalid DH parameters: neither suitable generator or safe prime")));
+ return NULL;
+ }
}
- if ((codes & DH_NOT_SUITABLE_GENERATOR) &&
- (codes & DH_CHECK_P_NOT_SAFE_PRIME))
+#else
{
- ereport(isServerStart ? FATAL : LOG,
- (errcode(ERRCODE_CONFIG_FILE_ERROR),
- errmsg("invalid DH parameters: neither suitable generator or safe prime")));
- return NULL;
+ EVP_PKEY *pkey;
+ EVP_PKEY_CTX *pkey_ctx = NULL;
+ unsigned long err = 0;
+
+ pkey = EVP_PKEY_new();
+
+ if (!EVP_PKEY_set1_DH(pkey, dh))
+ err = ERR_get_error();
+ else
+ {
+ pkey_ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
+
+ if (!EVP_PKEY_param_check(pkey_ctx))
+ err = ERR_get_error();
+ }
+
+ EVP_PKEY_CTX_free(pkey_ctx);
+ EVP_PKEY_free(pkey);
+
+ if (err)
+ {
+ ereport(isServerStart ? FATAL : LOG,
+ (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ errmsg("invalid DH parameters: %s",
+ SSLerrmessage(err))));
+ return NULL;
+ }
}
+#endif
return dh;
}
diff --git a/src/common/Makefile b/src/common/Makefile
index d0be882cca..482561f63e 100644
--- a/src/common/Makefile
+++ b/src/common/Makefile
@@ -80,7 +80,8 @@ OBJS_COMMON = \
ifeq ($(with_openssl),yes)
OBJS_COMMON += \
protocol_openssl.o \
- sha2_openssl.o
+ sha2_openssl.o \
+ cert_openssl.o
else
OBJS_COMMON += sha2.o
endif
diff --git a/src/common/cert_openssl.c b/src/common/cert_openssl.c
new file mode 100644
index 0000000000..2149e7eb36
--- /dev/null
+++ b/src/common/cert_openssl.c
@@ -0,0 +1,42 @@
+/*-------------------------------------------------------------------------
+ *
+ * protocol_openssl.c
+ * OpenSSL certificate functionality shared between frontend and backend
+ *
+ * This should only be used if code is compiled with OpenSSL support.
+ *
+ * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * IDENTIFICATION
+ * src/common/cert_openssl.c
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef FRONTEND
+#include "postgres.h"
+#else
+#include "postgres_fe.h"
+#endif
+
+#include "common/openssl.h"
+
+/*
+ * SSL_CTX_load_verify_locations and X509_STORE_load_locations were deprecated
+ * in OpenSSL 3.0.0 and replaced by their new _file counterparts. Provide
+ * implementations of the replacement for OpenSSL versions 1.0.1 through 1.1.1
+ * where they are missing.
+ */
+#if OPENSSL_VERSION_MAJOR < 3
+int
+SSL_CTX_load_verify_file(SSL_CTX *ctx, const char *CAfile)
+{
+ return SSL_CTX_load_verify_locations(ctx, CAfile, NULL);
+}
+int
+X509_STORE_load_file(X509_STORE *ctx, const char *file)
+{
+ return X509_STORE_load_locations(ctx, file, NULL);
+}
+#endif
diff --git a/src/include/common/openssl.h b/src/include/common/openssl.h
index 47fa129994..d5dc2910bf 100644
--- a/src/include/common/openssl.h
+++ b/src/include/common/openssl.h
@@ -23,6 +23,12 @@ extern int SSL_CTX_set_min_proto_version(SSL_CTX *ctx, int version);
extern int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, int version);
#endif
+/* src/common/cert_openssl.c */
+#if OPENSSL_VERSION_MAJOR < 3
+extern int SSL_CTX_load_verify_file(SSL_CTX *ctx, const char *CAfile);
+int X509_STORE_load_file(X509_STORE *ctx, const char *file);
+#endif
+
#endif
#endif /* COMMON_OPENSSL_H */
diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c
index 2d813ef5f9..a1ad181976 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -922,7 +922,7 @@ initialize_SSL(PGconn *conn)
{
X509_STORE *cvstore;
- if (SSL_CTX_load_verify_locations(SSL_context, fnbuf, NULL) != 1)
+ if (SSL_CTX_load_verify_file(SSL_context, fnbuf) != 1)
{
char *err = SSLerrmessage(ERR_get_error());
@@ -945,7 +945,7 @@ initialize_SSL(PGconn *conn)
/* Set the flags to check against the complete CRL chain */
if (fnbuf[0] != '\0' &&
- X509_STORE_load_locations(cvstore, fnbuf, NULL) == 1)
+ X509_STORE_load_file(cvstore, fnbuf) == 1)
{
X509_STORE_set_flags(cvstore,
X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
--
2.21.1 (Apple Git-122.3)
On Fri, 2020-05-29 at 00:16 +0200, Daniel Gustafsson wrote:
Since OpenSSL is now releasing 3.0.0-alpha versions, I took a look at using it
with postgres to see what awaits us. As it is now shipping in releases (with
GA planned for Q4), users will probably soon start to test against it so I
wanted to be prepared.Regarding the deprecations, we can either set preprocessor directives or use
compiler flags to silence the warning and do nothing (for now), or we could
update to the new API. We probably want to different things for master vs
back-branches, but as an illustration of what the latter could look like I've
implemented this in 0001.
An important question will be: if we convert to functions that are not deprecated,
what is the earliest OpenSSL version we can support?
Yours,
Laurenz Albe
On 29 May 2020, at 08:06, Laurenz Albe <laurenz.albe@cybertec.at> wrote:
Regarding the deprecations, we can either set preprocessor directives or use
compiler flags to silence the warning and do nothing (for now), or we could
update to the new API. We probably want to different things for master vs
back-branches, but as an illustration of what the latter could look like I've
implemented this in 0001.An important question will be: if we convert to functions that are not deprecated,
what is the earliest OpenSSL version we can support?
The replacement functions for _locations calls are introduced together with the
deprecation in 3.0.0, so there is no overlap.
For pgcrypto, that remains to be seen once it attempted, but ideally all the
way down to 1.0.1.
cheers ./daniel
On 2020-05-29 00:16, Daniel Gustafsson wrote:
Regarding the deprecations, we can either set preprocessor directives or use
compiler flags to silence the warning and do nothing (for now), or we could
update to the new API. We probably want to different things for master vs
back-branches, but as an illustration of what the latter could look like I've
implemented this in 0001.
I think we should set OPENSSL_API_COMPAT=10001, and move that along with
whatever our oldest supported release is going forward. That declares
our intention, it will silence the deprecation warnings, and IIUC, if
the deprecated stuff actually gets removed, you get a clean compiler
error that your API level is too low.
OpenSSL also deprecates DES keys in 3.0.0, which cause our password callback
tests to fail with the cryptic error "fetch failed", as the test suite keys are
encrypted with DES. 0002 fixes this by changing to AES256 (randomly chosen
among the ciphers supported in 1.0.1+ and likely to be around), and could be
applied already today as there is nothing 3.0.0 specific about it.
It appears you can load a "legacy provider" to support these keys. What
if someone made a key using 0.9.* with an older PostgreSQL version and
keeps using the same key? I'm wondering about the implications in
practice here. Obviously moving off legacy crypto is good in general.
There is also the question of what to do with the test suites in the
back branches.
Maybe we will want some user-exposed option about which providers to
load, since that also affects whether the FIPS provider gets loaded.
What's the plan there?
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
On 29 May 2020, at 13:34, Peter Eisentraut <peter.eisentraut@2ndquadrant.com> wrote:
On 2020-05-29 00:16, Daniel Gustafsson wrote:
Regarding the deprecations, we can either set preprocessor directives or use
compiler flags to silence the warning and do nothing (for now), or we could
update to the new API. We probably want to different things for master vs
back-branches, but as an illustration of what the latter could look like I've
implemented this in 0001.I think we should set OPENSSL_API_COMPAT=10001, and move that along with whatever our oldest supported release is going forward. That declares our intention, it will silence the deprecation warnings, and IIUC, if the deprecated stuff actually gets removed, you get a clean compiler error that your API level is too low.
I think I know what you mean but just to clarify: I master, back-branches or
all of the above?
Considering how little effort it is to not use the deprecated API's I'm not
entirely convinced, but I don't have too strong opinions there.
OpenSSL also deprecates DES keys in 3.0.0, which cause our password callback
tests to fail with the cryptic error "fetch failed", as the test suite keys are
encrypted with DES. 0002 fixes this by changing to AES256 (randomly chosen
among the ciphers supported in 1.0.1+ and likely to be around), and could be
applied already today as there is nothing 3.0.0 specific about it.It appears you can load a "legacy provider" to support these keys. What if someone made a key using 0.9.* with an older PostgreSQL version and keeps using the same key? I'm wondering about the implications in practice here. Obviously moving off legacy crypto is good in general.
If they do, then that key will stop working with any OpenSSL 3 enabled software
unless the legacy provider has been loaded. My understanding is that users can
load these in openssl.conf, so maybe it's mostly a documentation patch for us?
Iff key loading fails with an errormessage that indicates that the algorithm
couldn't be fetched (ie fetch failed), we could add an errhint on algorithm
use. Currently it's easy to believe that it's the key file that couldn't be
fetched, as the error message from OpenSSL is quite cryptic and expects the
user to understand OpenSSL terminology. This could happen already in pre-3
versions, so maybe it's worthwhile to do?
There is also the question of what to do with the test suites in the back branches.
If we don't want to change the testdata in the backbranches, we could add a
SKIP section for the password key tests iff OpenSSL is 3.0.0+?
Maybe we will want some user-exposed option about which providers to load, since that also affects whether the FIPS provider gets loaded. What's the plan there?
This again boils down to if we want to load providers, or if we want to punt
that to openssl.conf completely. Since we will support olders versions for a
long time still, maybe punting will render the cleanest code?
AFAICT, if care is taken with openssl.conf one could already load providers
such that postgres will operate in FIPS mode due to nothing non-FIPS being
available. For libpq I'm not sure if there is anything to do, as we don't
mandate any cipher use (SSL_CTX_set_cipher_list will simply fail IIUC). For
pgcrypto however it's another story, but there we'd need to rewrite it to not
use low-level APIs first since the use of those aren't FIPS compliant. Once
done, we could have an option for FIPS mode and pass the "fips=yes" property
when loading ciphers to make sure the right version is loaded if multiple ones
are available.
cheers ./daniel
On 2020-05-29 14:45, Daniel Gustafsson wrote:
I think we should set OPENSSL_API_COMPAT=10001, and move that along with whatever our oldest supported release is going forward. That declares our intention, it will silence the deprecation warnings, and IIUC, if the deprecated stuff actually gets removed, you get a clean compiler error that your API level is too low.
I think I know what you mean but just to clarify: I master, back-branches or
all of the above?
I'm not sure. I don't have a good sense of what OpenSSL versions we
claim to support in branches older than PG13. We made a conscious
decision for 1.0.1 in PG13, but I seem to recall that that discussion
also revealed that the version assumptions before that were quite
inconsistent. Code in PG12 and before makes references to OpenSSL as
old as 0.9.6. But OpenSSL 3.0.0 will reject a compat level older than
0.9.8.
My proposal would be to introduce OPENSSL_API_COMPAT=10001 into master
after the 13/14 branching, along with any other changes to make it
compile cleanly against OpenSSL 3.0.0. Once that has survived some
scrutiny from the buildfarm and also from folks building against
LibreSSL etc., it should probably be backpatched into PG13. In the
immediate future, I wouldn't bother about the older branches (<=PG12) at
all. As long as they still compile, users can just disable deprecation
warnings, and we may add some patches to that effect at some point, but
it's not like OpenSSL 3.0.0 will be adopted into production builds any
time soon.
Considering how little effort it is to not use the deprecated API's I'm not
entirely convinced, but I don't have too strong opinions there.
Well, in the case like X509_STORE_load_locations(), the solution is in
either case to write a wrapper. It doesn't matter if we write the
wrapper or OpenSSL writes the wrapper. Only OpenSSL has already written
the wrapper and has created a well-defined way to declare that you want
to use the wrapper, so I'd just take that.
In any case, using OPENSSL_API_COMPAT is also good just for our own
documentation, so we can keep track of what version we claim to support
in different branches.
If they do, then that key will stop working with any OpenSSL 3 enabled software
unless the legacy provider has been loaded. My understanding is that users can
load these in openssl.conf, so maybe it's mostly a documentation patch for us?
Yes, it looks like that should work, so no additional work required from us.
There is also the question of what to do with the test suites in the back branches.
If we don't want to change the testdata in the backbranches, we could add a
SKIP section for the password key tests iff OpenSSL is 3.0.0+?
I suggest to update the test data in PG13+, since we require OpenSSL
1.0.1 there. For the older branches, I would look into changing the
test driver setup so that it loads a custom openssl.cnf that loads the
legacy providers.
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
On 5/28/20 6:16 PM, Daniel Gustafsson wrote:
OpenSSL also deprecates DES keys in 3.0.0, which cause our password callback
tests to fail with the cryptic error "fetch failed", as the test suite keys are
encrypted with DES. 0002 fixes this by changing to AES256 (randomly chosen
among the ciphers supported in 1.0.1+ and likely to be around), and could be
applied already today as there is nothing 3.0.0 specific about it.
+1 for applying this forthwith. The key in my recent commit 896fcdb230
is encrypted with AES256.
cheers
andrew
--
Andrew Dunstan https://www.2ndQuadrant.com
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
On Sat, May 30, 2020 at 11:29:11AM +0200, Peter Eisentraut wrote:
I'm not sure. I don't have a good sense of what OpenSSL versions we claim
to support in branches older than PG13. We made a conscious decision for
1.0.1 in PG13, but I seem to recall that that discussion also revealed that
the version assumptions before that were quite inconsistent. Code in PG12
and before makes references to OpenSSL as old as 0.9.6. But OpenSSL 3.0.0
will reject a compat level older than 0.9.8.
593d4e4 claims that we only support OpenSSL >= 0.9.8, meaning that
down to PG 10 we have this requirement, and that PG 9.6 and 9.5 should
be able to work with OpenSSL 0.9.7 and 0.9.6, but little effort has
been put in testing these.
My proposal would be to introduce OPENSSL_API_COMPAT=10001 into master after
the 13/14 branching, along with any other changes to make it compile cleanly
against OpenSSL 3.0.0. Once that has survived some scrutiny from the
buildfarm and also from folks building against LibreSSL etc., it should
probably be backpatched into PG13. In the immediate future, I wouldn't
bother about the older branches (<=PG12) at all. As long as they still
compile, users can just disable deprecation warnings, and we may add some
patches to that effect at some point, but it's not like OpenSSL 3.0.0 will
be adopted into production builds any time soon.
Please note that I actually may have to bother about 12 and OpenSSL
3.0.0 as 1.0.2 deprecation is visibly accelerating a move to newer
versions at least in my close neighborhood. We are not there yet of
course, so doing this work with 14 and 13 sounds fine to me for now.
--
Michael
On 2020-05-30 14:34, Andrew Dunstan wrote:
On 5/28/20 6:16 PM, Daniel Gustafsson wrote:
OpenSSL also deprecates DES keys in 3.0.0, which cause our password callback
tests to fail with the cryptic error "fetch failed", as the test suite keys are
encrypted with DES. 0002 fixes this by changing to AES256 (randomly chosen
among the ciphers supported in 1.0.1+ and likely to be around), and could be
applied already today as there is nothing 3.0.0 specific about it.+1 for applying this forthwith. The key in my recent commit 896fcdb230
is encrypted with AES256.
I don't see anything in that commit about how to regenerate those files,
such as a makefile rule. Is that missing?
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
On 2020-05-31 04:52, Michael Paquier wrote:
593d4e4 claims that we only support OpenSSL >= 0.9.8, meaning that
down to PG 10 we have this requirement, and that PG 9.6 and 9.5 should
be able to work with OpenSSL 0.9.7 and 0.9.6, but little effort has
been put in testing these.
Then we can stick a OPENSSL_API_COMPAT=908 into at least PG10, 11, and
12, and probably also into PG9.5 and 9.6 without harm.
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
On 30 May 2020, at 11:29, Peter Eisentraut <peter.eisentraut@2ndquadrant.com> wrote:
On 2020-05-29 14:45, Daniel Gustafsson wrote:
I think we should set OPENSSL_API_COMPAT=10001, and move that along with whatever our oldest supported release is going forward. That declares our intention, it will silence the deprecation warnings, and IIUC, if the deprecated stuff actually gets removed, you get a clean compiler error that your API level is too low.
I think I know what you mean but just to clarify: I master, back-branches or
all of the above?I'm not sure. I don't have a good sense of what OpenSSL versions we claim to support in branches older than PG13. We made a conscious decision for 1.0.1 in PG13, but I seem to recall that that discussion also revealed that the version assumptions before that were quite inconsistent. Code in PG12 and before makes references to OpenSSL as old as 0.9.6. But OpenSSL 3.0.0 will reject a compat level older than 0.9.8.
My proposal would be to introduce OPENSSL_API_COMPAT=10001 into master after the 13/14 branching, along with any other changes to make it compile cleanly against OpenSSL 3.0.0. Once that has survived some scrutiny from the buildfarm and also from folks building against LibreSSL etc., it should probably be backpatched into PG13. In the immediate future, I wouldn't bother about the older branches (<=PG12) at all. As long as they still compile, users can just disable deprecation warnings, and we may add some patches to that effect at some point, but it's not like OpenSSL 3.0.0 will be adopted into production builds any time soon.
Considering how little effort it is to not use the deprecated API's I'm not
entirely convinced, but I don't have too strong opinions there.Well, in the case like X509_STORE_load_locations(), the solution is in either case to write a wrapper. It doesn't matter if we write the wrapper or OpenSSL writes the wrapper. Only OpenSSL has already written the wrapper and has created a well-defined way to declare that you want to use the wrapper, so I'd just take that.
I'll buy that argument.
In any case, using OPENSSL_API_COMPAT is also good just for our own documentation, so we can keep track of what version we claim to support in different branches.
Good point.
There is also the question of what to do with the test suites in the back branches.
If we don't want to change the testdata in the backbranches, we could add a
SKIP section for the password key tests iff OpenSSL is 3.0.0+?I suggest to update the test data in PG13+, since we require OpenSSL 1.0.1 there. For the older branches, I would look into changing the test driver setup so that it loads a custom openssl.cnf that loads the legacy providers.
Ok, I'll roll a patch along these lines for master for ~ the 13/14 branch time
and then we'll see how we deal with PG13 once the dust has settled not only on
our side but for OpenSSL.
cheers ./daniel
On 6/1/20 4:33 AM, Peter Eisentraut wrote:
On 2020-05-30 14:34, Andrew Dunstan wrote:
On 5/28/20 6:16 PM, Daniel Gustafsson wrote:
OpenSSL also deprecates DES keys in 3.0.0, which cause our password
callback
tests to fail with the cryptic error "fetch failed", as the test
suite keys are
encrypted with DES.� 0002 fixes this by changing to AES256 (randomly
chosen
among the ciphers supported in 1.0.1+ and likely to be around), and
could be
applied already today as there is nothing 3.0.0 specific about it.+1 for applying this forthwith. The key in my recent commit 896fcdb230
is encrypted with AES256.I don't see anything in that commit about how to regenerate those
files, such as a makefile rule.� Is that missing?
You missed these comments in the test file:
# self-signed cert was generated like this:
# system('openssl req -new -x509 -days 10000 -nodes -out server.crt
-keyout server.ckey -subj "/CN=localhost"');
# add the cleartext passphrase to the key, remove the unprotected key
# system("openssl rsa -aes256 -in server.ckey -out server.key -passout
pass:$clearpass");
# unlink "server.ckey";
If you want I can add a rule for it to the Makefile, although who knows
what commands will actually apply when the certificate runs out?
cheers
andrew
--
Andrew Dunstan https://www.2ndQuadrant.com
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
On 1 Jun 2020, at 13:58, Andrew Dunstan <andrew.dunstan@2ndquadrant.com> wrote:
If you want I can add a rule for it to the Makefile, although who knows
what commands will actually apply when the certificate runs out?
Being able to easily regenerate the testdata, regardless of expiration status,
has proven very helpful for me when implementing support for new TLS backends.
+1 for adding it to the Makefile.
cheers ./daniel
On 6/1/20 8:03 AM, Daniel Gustafsson wrote:
On 1 Jun 2020, at 13:58, Andrew Dunstan <andrew.dunstan@2ndquadrant.com> wrote:
If you want I can add a rule for it to the Makefile, although who knows
what commands will actually apply when the certificate runs out?Being able to easily regenerate the testdata, regardless of expiration status,
has proven very helpful for me when implementing support for new TLS backends.
+1 for adding it to the Makefile.
OK, here's a patch.
cheers
andrew
--
Andrew Dunstan https://www.2ndQuadrant.com
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
Attachments:
ssl-passphase-callback-certs.patchtext/x-patch; charset=UTF-8; name=ssl-passphase-callback-certs.patchDownload
diff --git a/src/test/modules/ssl_passphrase_callback/Makefile b/src/test/modules/ssl_passphrase_callback/Makefile
index a3b518b50d..f81265c296 100644
--- a/src/test/modules/ssl_passphrase_callback/Makefile
+++ b/src/test/modules/ssl_passphrase_callback/Makefile
@@ -20,3 +20,21 @@ include $(top_srcdir)/contrib/contrib-global.mk
endif
SHLIB_LINK += $(filter -lssl -lcrypto -lssleay32 -leay32, $(LIBS))
+
+# Targets to generate or remove the ssl certificate and key
+# Normally not needed. Don't run these targets in a vpath build, the results
+# won't be in the right place if you do.
+
+# needs to agree with what's in the test script
+PASS = FooBaR1
+
+.PHONY: ssl-files ssl-files-clean
+
+ssl-files:
+ openssl req -new -x509 -days 10000 -nodes -out server.crt \
+ -keyout server.ckey -subj "/CN=localhost"
+ openssl rsa -aes256 -in server.ckey -out server.key -passout pass:$(PASS)
+ rm server.ckey
+
+ssl-files-clean:
+ rm -f server.crt server.key
Andrew Dunstan <andrew.dunstan@2ndquadrant.com> writes:
On 6/1/20 8:03 AM, Daniel Gustafsson wrote:
+1 for adding it to the Makefile.
OK, here's a patch.
Likewise +1 for having it in the makefile. But now you have two copies,
the other being in comments in the test script. The latter should go
away, as we surely won't remember to maintain it. (You could replace it
with a pointer to the makefile rules if you want.)
regards, tom lane
On 2020-06-01 15:23, Andrew Dunstan wrote:
On 6/1/20 8:03 AM, Daniel Gustafsson wrote:
On 1 Jun 2020, at 13:58, Andrew Dunstan <andrew.dunstan@2ndquadrant.com> wrote:
If you want I can add a rule for it to the Makefile, although who knows
what commands will actually apply when the certificate runs out?Being able to easily regenerate the testdata, regardless of expiration status,
has proven very helpful for me when implementing support for new TLS backends.
+1 for adding it to the Makefile.OK, here's a patch.
In src/test/ssl/ we have targets sslfiles and sslfiles-clean, and here
we have ssl-files and ssl-files-clean. Let's keep that consistent.
Or, why not actually use the generated files from src/test/ssl/ instead
of making another set?
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
On 6/2/20 4:57 AM, Peter Eisentraut wrote:
On 2020-06-01 15:23, Andrew Dunstan wrote:
On 6/1/20 8:03 AM, Daniel Gustafsson wrote:
On 1 Jun 2020, at 13:58, Andrew Dunstan
<andrew.dunstan@2ndquadrant.com> wrote:
If you want I can add a rule for it to the Makefile, although who
knows
what commands will actually apply when the certificate runs out?Being able to easily regenerate the testdata, regardless of
expiration status,
has proven very helpful for me when implementing support for new TLS
backends.
+1 for adding it to the Makefile.OK, here's a patch.
In src/test/ssl/ we have targets sslfiles and sslfiles-clean, and here
we have ssl-files and ssl-files-clean. Let's keep that consistent.Or, why not actually use the generated files from src/test/ssl/
instead of making another set?
Honestly, I think we've spent plenty of time on this already. I don't
see a problem with each module having its own certificate(s) - that
makes them more self-contained - nor any great need to have the targets
named the same.
cheers
andrew
--
Andrew Dunstan https://www.2ndQuadrant.com
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
On Tue, Jun 02, 2020 at 02:45:11PM -0400, Andrew Dunstan wrote:
Honestly, I think we've spent plenty of time on this already. I don't
see a problem with each module having its own certificate(s) - that
makes them more self-contained - nor any great need to have the targets
named the same.
Yeah, I don't see much point in combining both of them as those
modules have different assumptions behind the files built. Now I
agree with Peter's point to use the same Makefile rule names in both
files so as it gets easier to grep for all instances.
So, src/test/ssl/ being the oldest one, ssl_passphrase_callback should
just do s/ssl-files/sslfiles/.
--
Michael
On Mon, Jun 01, 2020 at 10:44:17AM +0200, Peter Eisentraut wrote:
Then we can stick a OPENSSL_API_COMPAT=908 into at least PG10, 11, and 12,
and probably also into PG9.5 and 9.6 without harm.
FWIW, I am fine that for PG >= 10, and I don't think that it is worth
bothering with PG <= 9.6.
--
Michael
On 2020-05-30 11:29, Peter Eisentraut wrote:
I suggest to update the test data in PG13+, since we require OpenSSL
1.0.1 there. For the older branches, I would look into changing the
test driver setup so that it loads a custom openssl.cnf that loads the
legacy providers.
I have pushed your 0002 patch (the one that updates the test data) to
master.
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
On 2020-05-30 11:29, Peter Eisentraut wrote:
My proposal would be to introduce OPENSSL_API_COMPAT=10001 into master
after the 13/14 branching, along with any other changes to make it
compile cleanly against OpenSSL 3.0.0. Once that has survived some
scrutiny from the buildfarm and also from folks building against
LibreSSL etc., it should probably be backpatched into PG13. In the
immediate future, I wouldn't bother about the older branches (<=PG12) at
all. As long as they still compile, users can just disable deprecation
warnings, and we may add some patches to that effect at some point, but
it's not like OpenSSL 3.0.0 will be adopted into production builds any
time soon.
Trying to move this along, where would be a good place to define
OPENSSL_API_COMPAT? The only place that's shared between frontend and
backend code is c.h. The attached patch does it that way.
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
Attachments:
0001-Define-OPENSSL_API_COMPAT.patchtext/plain; charset=UTF-8; name=0001-Define-OPENSSL_API_COMPAT.patch; x-mac-creator=0; x-mac-type=0Download
From 0c5c83c6051688a643194388000ea356a8d055d5 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Tue, 7 Jul 2020 19:43:22 +0200
Subject: [PATCH] Define OPENSSL_API_COMPAT
This avoids deprecation warnings from newer OpenSSL versions (3.0.0 in
particular).
Discussion: https://www.postgresql.org/message-id/flat/FEF81714-D479-4512-839B-C769D2605F8A%40yesql.se
---
src/include/c.h | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/src/include/c.h b/src/include/c.h
index a904b49a37..03e87ae3a8 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -1080,6 +1080,14 @@ extern void ExceptionalCondition(const char *conditionName,
#define HAVE_UNIX_SOCKETS 1
#endif
+/*
+ * OpenSSL API compatibility level
+ *
+ * Set this to the minimum supported version. This avoids deprecation
+ * warnings when building with newer OpenSSL versions.
+ */
+#define OPENSSL_API_COMPAT 10001
+
/*
* Invert the sign of a qsort-style comparison result, ie, exchange negative
* and positive integer values, being careful not to get the wrong answer
--
2.27.0
Peter Eisentraut <peter.eisentraut@2ndquadrant.com> writes:
Trying to move this along, where would be a good place to define
OPENSSL_API_COMPAT? The only place that's shared between frontend and
backend code is c.h. The attached patch does it that way.
pg_config_manual.h, perhaps?
regards, tom lane
On 7 Jul 2020, at 19:53, Tom Lane <tgl@sss.pgh.pa.us> wrote:
Peter Eisentraut <peter.eisentraut@2ndquadrant.com> writes:
Trying to move this along,
Thanks, this has stalled a bit on my TODO.
where would be a good place to define
OPENSSL_API_COMPAT? The only place that's shared between frontend and
backend code is c.h. The attached patch does it that way.pg_config_manual.h, perhaps?
I don't have a strong preference. When starting hacking on this I went for the
quick and simple option of adding it to CFLAGS in configure.in for the time
being since I wasn't sure where to put it.
A slightly more complicated problem arise when trying to run the pgcrypto
regress tests, and make it run the tests for the now deprecated ciphers, as
they require the legacy provider to be loaded via the openssl configuration
file. As was mentioned upthread, this requires us to inject our own
openssl.cnf in OPENSSL_CONF, load the legacy provider there and then from that
file include the system openssl.cnf (or override the system one completely
during testing which doesn't seem like a good idea).
Hacking this up in a crude PoC I added a REGRESS_ENV option in pgxs.mk which
then pgcrypto/Makefile could use to set an OPENSSL_CONF, which in turn ends
with a .include=<path> for my system config. This enables pgcrypto to load
the now deprecated ciphers, but even as PoC's goes this is awfully brittle and
a significant amount of bricks shy.
Actually running the tests with the legacy provider loaded yields a fair number
of errors like these, and somewhere around there I ran out of time for now as
the CF started.
- decrypt
-----------------------------
- Lets try a longer message.
+ decrypt
+----------------------------------------------------------
+ Lets try a longer messag\177\177\177\177\177\177\177\177
Memorizing the "cannot load cipher" errors in an alternative output and
documenting how to use old ciphers in pgcrypto together with OpenSSL 3.0.0+
might be the least bad option? Anyone else have any good ideas on how to get
this into the testrunner?
cheers ./daniel
On Tue, Jul 7, 2020 at 1:46 PM Peter Eisentraut
<peter.eisentraut@2ndquadrant.com> wrote:
Trying to move this along, where would be a good place to define
OPENSSL_API_COMPAT? The only place that's shared between frontend and
backend code is c.h. The attached patch does it that way.
So, if we go this way, does that mean that we're not going to pursue
removing dependencies on the deprecated interfaces? I wonder if we
really ought to be doing that too, with preprocessor conditionals.
Otherwise, aren't we putting ourselves in an uncomfortable situation
when the deprecated stuff eventually goes away upstream?
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
On 2020-07-08 16:51, Robert Haas wrote:
On Tue, Jul 7, 2020 at 1:46 PM Peter Eisentraut
<peter.eisentraut@2ndquadrant.com> wrote:Trying to move this along, where would be a good place to define
OPENSSL_API_COMPAT? The only place that's shared between frontend and
backend code is c.h. The attached patch does it that way.So, if we go this way, does that mean that we're not going to pursue
removing dependencies on the deprecated interfaces? I wonder if we
really ought to be doing that too, with preprocessor conditionals.
Otherwise, aren't we putting ourselves in an uncomfortable situation
when the deprecated stuff eventually goes away upstream?
I don't think there is a rush. The 3.0.0 alphas still support
interfaces deprecated in 0.9.8 (released 2005). AFAICT, nothing tagged
under this API compatibility scheme has ever been removed. If they
started doing so, they would presumably do it step by step at the tail
end, which would still give us several steps before it catches up with us.
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
On 2020-07-07 22:52, Daniel Gustafsson wrote:
Actually running the tests with the legacy provider loaded yields a fair number
of errors like these, and somewhere around there I ran out of time for now as
the CF started.- decrypt ----------------------------- - Lets try a longer message. + decrypt +---------------------------------------------------------- + Lets try a longer messag\177\177\177\177\177\177\177\177Memorizing the "cannot load cipher" errors in an alternative output and
documenting how to use old ciphers in pgcrypto together with OpenSSL 3.0.0+
might be the least bad option? Anyone else have any good ideas on how to get
this into the testrunner?
I think an alternative test output file would be a legitimate solution
in the short and mid term.
However, as you mention, and looking at the test output, this might also
require a bit of work making the handling of these new various error
conditions more robust.
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
On 2020-07-07 22:52, Daniel Gustafsson wrote:
where would be a good place to define
OPENSSL_API_COMPAT? The only place that's shared between frontend and
backend code is c.h. The attached patch does it that way.pg_config_manual.h, perhaps?
I don't have a strong preference. When starting hacking on this I went for the
quick and simple option of adding it to CFLAGS in configure.in for the time
being since I wasn't sure where to put it.
Actually, it would be most formally correct to set it using AC_DEFINE in
configure.in, so that configure tests see it. It doesn't look like we
currently have any configure tests that would really be affected, but it
seems sensible to do it there anyway.
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
Peter Eisentraut <peter.eisentraut@2ndquadrant.com> writes:
where would be a good place to define
OPENSSL_API_COMPAT?
Actually, it would be most formally correct to set it using AC_DEFINE in
configure.in, so that configure tests see it.
Yeah, very good point.
regards, tom lane
On 2020-07-13 15:38, Tom Lane wrote:
Peter Eisentraut <peter.eisentraut@2ndquadrant.com> writes:
where would be a good place to define
OPENSSL_API_COMPAT?Actually, it would be most formally correct to set it using AC_DEFINE in
configure.in, so that configure tests see it.Yeah, very good point.
New patch done that way.
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
Attachments:
v2-0001-Define-OPENSSL_API_COMPAT.patchtext/plain; charset=UTF-8; name=v2-0001-Define-OPENSSL_API_COMPAT.patch; x-mac-creator=0; x-mac-type=0Download
From 612e42bb6073707924187c044ffd71ecff2607bd Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Thu, 16 Jul 2020 10:55:55 +0200
Subject: [PATCH v2] Define OPENSSL_API_COMPAT
This avoids deprecation warnings from newer OpenSSL versions (3.0.0 in
particular).
Discussion: https://www.postgresql.org/message-id/flat/FEF81714-D479-4512-839B-C769D2605F8A%40yesql.se
---
configure | 5 ++++-
configure.in | 2 ++
src/include/pg_config.h.in | 4 ++++
src/tools/msvc/Solution.pm | 10 +++++++++-
4 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/configure b/configure
index 2feff37fe3..00f863fd2d 100755
--- a/configure
+++ b/configure
@@ -12083,7 +12083,10 @@ fi
fi
if test "$with_openssl" = yes ; then
- if test "$PORTNAME" != "win32"; then
+
+$as_echo "#define OPENSSL_API_COMPAT 10001" >>confdefs.h
+
+ if test "$PORTNAME" != "win32"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for CRYPTO_new_ex_data in -lcrypto" >&5
$as_echo_n "checking for CRYPTO_new_ex_data in -lcrypto... " >&6; }
if ${ac_cv_lib_crypto_CRYPTO_new_ex_data+:} false; then :
diff --git a/configure.in b/configure.in
index 0188c6ff07..c06fec4726 100644
--- a/configure.in
+++ b/configure.in
@@ -1204,6 +1204,8 @@ fi
if test "$with_openssl" = yes ; then
dnl Order matters!
+ AC_DEFINE(OPENSSL_API_COMPAT, [10001],
+ [Define to the OpenSSL API version in use. This avoids deprecation warnings from newer OpenSSL versions.])
if test "$PORTNAME" != "win32"; then
AC_CHECK_LIB(crypto, CRYPTO_new_ex_data, [], [AC_MSG_ERROR([library 'crypto' is required for OpenSSL])])
AC_CHECK_LIB(ssl, SSL_new, [], [AC_MSG_ERROR([library 'ssl' is required for OpenSSL])])
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index c199cd46d2..73aa618166 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -749,6 +749,10 @@
/* Define bytes to use libc memset(). */
#undef MEMSET_LOOP_LIMIT
+/* Define to the OpenSSL API version in use. This avoids deprecation warnings
+ from newer OpenSSL versions. */
+#undef OPENSSL_API_COMPAT
+
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index a13ca6e02e..ba61544911 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -152,6 +152,8 @@ sub GenerateFiles
my $package_bugreport;
my $package_url;
my ($majorver, $minorver);
+ my $ac_define_openssl_api_compat_found = 0;
+ my $openssl_api_compat;
# Parse configure.in to get version numbers
open(my $c, '<', "configure.in")
@@ -176,10 +178,15 @@ sub GenerateFiles
$majorver = sprintf("%d", $1);
$minorver = sprintf("%d", $2 ? $2 : 0);
}
+ elsif (/\bAC_DEFINE\(OPENSSL_API_COMPAT, \[(\d+)\]/)
+ {
+ $ac_define_openssl_api_compat_found = 1;
+ $openssl_api_compat = $1;
+ }
}
close($c);
confess "Unable to parse configure.in for all variables!"
- unless $ac_init_found;
+ unless $ac_init_found && $ac_define_openssl_api_compat_found;
if (IsNewer("src/include/pg_config_os.h", "src/include/port/win32.h"))
{
@@ -433,6 +440,7 @@ sub GenerateFiles
LOCALE_T_IN_XLOCALE => undef,
MAXIMUM_ALIGNOF => 8,
MEMSET_LOOP_LIMIT => 1024,
+ OPENSSL_API_COMPAT => $openssl_api_compat,
PACKAGE_BUGREPORT => qq{"$package_bugreport"},
PACKAGE_NAME => qq{"$package_name"},
PACKAGE_STRING => qq{"$package_name $package_version"},
--
2.27.0
On Thu, Jul 16, 2020 at 10:58:58AM +0200, Peter Eisentraut wrote:
if test "$with_openssl" = yes ; then dnl Order matters! + AC_DEFINE(OPENSSL_API_COMPAT, [10001], + [Define to the OpenSSL API version in use. This avoids deprecation warnings from newer OpenSSL versions.]) if test "$PORTNAME" != "win32"; then
I think that you should additionally mention the version number
directly in the description, so as when support for 1.0.1 gets removed
it is possible to grep for it, and then adjust the number and the
description.
--
Michael
On 2020-07-16 13:45, Michael Paquier wrote:
On Thu, Jul 16, 2020 at 10:58:58AM +0200, Peter Eisentraut wrote:
if test "$with_openssl" = yes ; then dnl Order matters! + AC_DEFINE(OPENSSL_API_COMPAT, [10001], + [Define to the OpenSSL API version in use. This avoids deprecation warnings from newer OpenSSL versions.]) if test "$PORTNAME" != "win32"; thenI think that you should additionally mention the version number
directly in the description, so as when support for 1.0.1 gets removed
it is possible to grep for it, and then adjust the number and the
description.
Good point. I have committed it with that adjustment. Also, I had the
format of the version number wrong, so I changed that, too.
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
On Sun, Jul 19, 2020 at 04:29:54PM +0200, Peter Eisentraut wrote:
Good point. I have committed it with that adjustment. Also, I had the
format of the version number wrong, so I changed that, too.
Thanks. I was not paying much attention to the format, but what you
have committed is in line with the upstream docs:
https://www.openssl.org/docs/manmaster/man7/OPENSSL_API_COMPAT.html
So we are all good.
--
Michael
On Fri, May 29, 2020 at 12:16:47AM +0200, Daniel Gustafsson wrote:
SSL_CTX_load_verify_locations and X509_STORE_load_locations are deprecated and
replaced by individual calls to load files and directories. These are quite
straightforward, and are implemented like how we handle the TLS protocol API.
DH_check has been discouraged to use for quite some time, and is now marked
deprecated without a 1:1 replacement. The OpenSSL docs recommends using the
EVP API, which is also done in 0001. For now I just stuck it in with version
gated ifdefs, something cleaner than that can clearly be done. 0001 is clearly
not proposed for review/commit yet, it's included in case someone else is
interested as well.
Leaving the problems with pgcrypto aside for now, we have also two
parts involving DH_check() deprecation and the load-file APIs for the
backend.
From what I can see, the new APIs to load files are new as of 3.0.0,
but these are not marked as deprecated yet, so I am not sure that it
is worth having now one extra API compatibility layer just for that
now as proposed in cert_openssl.c. Most of the the EVP counterparts,
though, are much older than 1.0.1, except for EVP_PKEY_param_check()
introduced in 1.1.1 :(
By the way, in the previous patch, EVP_PKEY_CTX_new_from_pkey() was
getting used but it is new as of 3.0. We could just use
EVP_PKEY_CTX_new() which does the same work (see
crypto/evp/pmeth_lib.c as we have no library context of engine to pass
down), and is much older, but it does not reduce the diffs. Then the
actual problem is EVP_PKEY_param_check(), new as of 1.1.1, which looks
to be the expected replacement for DH_check().
It seems to me that it would not be a bad thing to switch to the EVP
APIs on HEAD to be prepared for the future, but I would switch to
EVP_PKEY_CTX_new() instead of EVP_PKEY_CTX_new_from_pkey() and add a
configure check to see if EVP_PKEY_param_check() is defined or not.
OPENSSL_VERSION_NUMBER cannot be used because of LibreSSL overriding
it, and I guess that OPENSSL_VERSION_MAJOR, as used in the original
patch, would not work with LibreSSL either.
Any thoughts?
--
Michael
On 17 Aug 2020, at 06:12, Michael Paquier <michael@paquier.xyz> wrote:
Leaving the problems with pgcrypto aside for now
Returning to this subject, I decided to take a stab at fixing pgcrypto since it
wasn't working.
Since we support ciphers that are now deprecated, we have no other choice than
to load the legacy provider. The other problem was that the cipher context
padding must be explicitly set, whereas in previous versions relying on the
default worked fine. EVP_CIPHER_CTX_set_padding always returns 1 so thats why
it isn't checking the returnvalue as the other nearby initialization calls.
To avoid problems with the by LibreSSL overloaded OPENSSL_VERSION_NUMBER macro
(which too is deprecated in 3.0.0), I used the new macro which is only set in
3.0.0. Not sure if that's considered acceptable or if we should invent our own
version macro in autoconf.
For the main SSL tests, the incorrect password test has a new errormessage
which is added in 0002.
With these two all SSL tests pass for me in 1.0.1 through 3.0.0-alpha6 (tested
on a mix of Debian and macOS).
Thoughts on these?
cheers ./daniel
Attachments:
0002-Fix-ssl-tests-to-support-OpenSSL-3.0.0.patchapplication/octet-stream; name=0002-Fix-ssl-tests-to-support-OpenSSL-3.0.0.patch; x-unix-mode=0644Download
From 2cb803f39ace02adf98dcfd80952ddff8e4d9c60 Mon Sep 17 00:00:00 2001
From: Daniel Gustafsson <daniel@yesql.se>
Date: Fri, 18 Sep 2020 15:53:37 +0200
Subject: [PATCH 2/2] Fix ssl tests to support OpenSSL 3.0.0
Decrypting a key with an incorrect password is now reported as a
nested asn1 error. Handle both in the regex.
---
src/test/ssl/t/001_ssltests.pl | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/test/ssl/t/001_ssltests.pl b/src/test/ssl/t/001_ssltests.pl
index fd2727b568..347113b076 100644
--- a/src/test/ssl/t/001_ssltests.pl
+++ b/src/test/ssl/t/001_ssltests.pl
@@ -428,10 +428,11 @@ test_connect_ok(
);
# correct client cert in encrypted PEM with wrong password
+# In OpenSSL 3.0.0, the returned error was changed to "nested asn1 error"
test_connect_fails(
$common_connstr,
"user=ssltestuser sslcert=ssl/client.crt sslkey=ssl/client-encrypted-pem_tmp.key sslpassword='wrong'",
- qr!\Qprivate key file "ssl/client-encrypted-pem_tmp.key": bad decrypt\E!,
+ qr!\Qprivate key file "ssl/client-encrypted-pem_tmp.key":\E (bad decrypt|nested asn1 error)!,
"certificate authorization fails with correct client cert and wrong password in encrypted PEM format"
);
--
2.21.1 (Apple Git-122.3)
0001-Fix-pgcrypto-to-support-OpenSSL-3.0.0.patchapplication/octet-stream; name=0001-Fix-pgcrypto-to-support-OpenSSL-3.0.0.patch; x-unix-mode=0644Download
From f1081116eeb5b7cdbc5d89772058a2a25bd1a834 Mon Sep 17 00:00:00 2001
From: Daniel Gustafsson <daniel@yesql.se>
Date: Fri, 18 Sep 2020 15:51:15 +0200
Subject: [PATCH 1/2] Fix pgcrypto to support OpenSSL 3.0.0
Many of the ciphers supported in pgcrypto are deprecated in 3.0.0
and require the legacy provider in order to work. Also explicitly
set up the padding which is now required.
---
contrib/pgcrypto/openssl.c | 35 ++++++++++++++++++++++++++++++++++-
doc/src/sgml/pgcrypto.sgml | 6 ++++++
2 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c
index 3057afb339..c9e97d5279 100644
--- a/contrib/pgcrypto/openssl.c
+++ b/contrib/pgcrypto/openssl.c
@@ -34,6 +34,14 @@
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/rand.h>
+/*
+ * OPENSSL_VERSION_MAJOR isn't defined at all until OpenSSL 3.0.0, but since
+ * OPENSSL_VERSION_NUMBER is used by both OpenSSL and LibreSSL it's safer to
+ * check for the new macro rather than the overloaded old one.
+ */
+#if OPENSSL_VERSION_MAJOR >= 3
+#include <openssl/provider.h>
+#endif
#include "px.h"
#include "utils/memutils.h"
@@ -64,6 +72,10 @@ typedef struct OSSLDigest
struct OSSLDigest *prev;
} OSSLDigest;
+#if OPENSSL_VERSION_MAJOR >= 3
+static OSSL_PROVIDER *legacy_provider = NULL;
+static OSSL_PROVIDER *default_provider = NULL;
+#endif
static OSSLDigest *open_digests = NULL;
static bool digest_resowner_callback_registered = false;
@@ -173,8 +185,20 @@ px_find_digest(const char *name, PX_MD **res)
if (!px_openssl_initialized)
{
- px_openssl_initialized = 1;
+#if OPENSSL_VERSION_MAJOR >= 3
+ if (legacy_provider == NULL)
+ legacy_provider = OSSL_PROVIDER_load(NULL, "legacy");
+ if (default_provider == NULL)
+ default_provider = OSSL_PROVIDER_load(NULL, "default");
+#endif
+
+ /*
+ * OpenSSL_add_all_algorithms is deprecated in OpenSSL 1.1.0 and no
+ * longer required in 1.1.0 and later versions as initialization is
+ * performed automatically.
+ */
OpenSSL_add_all_algorithms();
+ px_openssl_initialized = 1;
}
if (!digest_resowner_callback_registered)
@@ -367,6 +391,7 @@ gen_ossl_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
{
if (!EVP_DecryptInit_ex(od->evp_ctx, od->evp_ciph, NULL, NULL, NULL))
return PXE_CIPHER_INIT;
+ EVP_CIPHER_CTX_set_padding(od->evp_ctx, 0);
if (!EVP_CIPHER_CTX_set_key_length(od->evp_ctx, od->klen))
return PXE_CIPHER_INIT;
if (!EVP_DecryptInit_ex(od->evp_ctx, NULL, NULL, od->key, od->iv))
@@ -391,6 +416,7 @@ gen_ossl_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
{
if (!EVP_EncryptInit_ex(od->evp_ctx, od->evp_ciph, NULL, NULL, NULL))
return PXE_CIPHER_INIT;
+ EVP_CIPHER_CTX_set_padding(od->evp_ctx, 0);
if (!EVP_CIPHER_CTX_set_key_length(od->evp_ctx, od->klen))
return PXE_CIPHER_INIT;
if (!EVP_EncryptInit_ex(od->evp_ctx, NULL, NULL, od->key, od->iv))
@@ -751,6 +777,13 @@ px_find_cipher(const char *name, PX_Cipher **res)
EVP_CIPHER_CTX *ctx;
OSSLCipher *od;
+#if OPENSSL_VERSION_MAJOR >= 3
+ if (legacy_provider == NULL)
+ legacy_provider = OSSL_PROVIDER_load(NULL, "legacy");
+ if (default_provider == NULL)
+ default_provider = OSSL_PROVIDER_load(NULL, "default");
+#endif
+
name = px_resolve_alias(ossl_aliases, name);
for (i = ossl_cipher_types; i->name; i++)
if (strcmp(i->name, name) == 0)
diff --git a/doc/src/sgml/pgcrypto.sgml b/doc/src/sgml/pgcrypto.sgml
index 8748c64e2d..5c6d54042e 100644
--- a/doc/src/sgml/pgcrypto.sgml
+++ b/doc/src/sgml/pgcrypto.sgml
@@ -1233,6 +1233,12 @@ gen_random_uuid() returns uuid
</tgroup>
</table>
+ <para>
+ When compiled against <productname>OpenSSL</productname> 3.0.0, the legacy
+ provider will be automatically loaded in order to support the ciphers in
+ the above table.
+ </para>
+
<para>
Notes:
</para>
--
2.21.1 (Apple Git-122.3)
On Fri, Sep 18, 2020 at 04:11:13PM +0200, Daniel Gustafsson wrote:
Since we support ciphers that are now deprecated, we have no other choice than
to load the legacy provider.
Ah, thanks. I actually tried something similar to that when I had my
mind on it by loading the legacy providers, but missed the padding
part. Nice find.
The other problem was that the cipher context
padding must be explicitly set, whereas in previous versions relying on the
default worked fine. EVP_CIPHER_CTX_set_padding always returns 1 so thats why
it isn't checking the returnvalue as the other nearby initialization calls.
It seems to me that it would be a good idea to still check for the
return value of EVP_CIPHER_CTX_set_padding() and just return with
a PXE_CIPHER_INIT. By looking at the upstream code, it is true that
it always returns true for <= 1.1.1, but that's not the case for
3.0.0. Some code paths of upstream also check after it.
Also, what's the impact with disabling the padding for <= 1.1.1? This
part of the upstream code is still a bit obscure to me..
To avoid problems with the by LibreSSL overloaded OPENSSL_VERSION_NUMBER macro
(which too is deprecated in 3.0.0), I used the new macro which is only set in
3.0.0. Not sure if that's considered acceptable or if we should invent our own
version macro in autoconf.
OSSL_PROVIDER_load() is new as of 3.0.0, so using a configure switch
similarly as what we do for the other functions should be more
consistent and enough, no?
For the main SSL tests, the incorrect password test has a new errormessage
which is added in 0002.
Hmm. I am linking to a build of alpha6 here, but I still see the
error being reported as a bad decrypt for this test. Interesting.
--
Michael
On 19 Sep 2020, at 04:11, Michael Paquier <michael@paquier.xyz> wrote:
On Fri, Sep 18, 2020 at 04:11:13PM +0200, Daniel Gustafsson wrote:
The other problem was that the cipher context
padding must be explicitly set, whereas in previous versions relying on the
default worked fine. EVP_CIPHER_CTX_set_padding always returns 1 so thats why
it isn't checking the returnvalue as the other nearby initialization calls.It seems to me that it would be a good idea to still check for the
return value of EVP_CIPHER_CTX_set_padding() and just return with
a PXE_CIPHER_INIT. By looking at the upstream code, it is true that
it always returns true for <= 1.1.1, but that's not the case for
3.0.0. Some code paths of upstream also check after it.
Thats a good point, it's now provider dependent and can thus fail in case the
provider isn't supplying the functionality. We've already loaded a provider
where we know the call is supported, but it's of course better to check. Fixed
in the attached v2.
I was only reading the docs and not the code, and they haven't been updated to
reflect this. I'll open a PR to the OpenSSL devs to fix that.
Also, what's the impact with disabling the padding for <= 1.1.1? This
part of the upstream code is still a bit obscure to me..
I'm far from fluent in OpenSSL, but AFAICT it has to do with the new provider
API. The default value for padding is unchanged, but it needs to be propaged
into the provider to be set in the context where the old code picked it up
automatically. The relevant OpenSSL commit (83f68df32f0067ee7b0) which changes
the docs to say the function should be called doesn't contain enough
information to explain why.
To avoid problems with the by LibreSSL overloaded OPENSSL_VERSION_NUMBER macro
(which too is deprecated in 3.0.0), I used the new macro which is only set in
3.0.0. Not sure if that's considered acceptable or if we should invent our own
version macro in autoconf.OSSL_PROVIDER_load() is new as of 3.0.0, so using a configure switch
similarly as what we do for the other functions should be more
consistent and enough, no?
Good point, fixed in the attached.
For the main SSL tests, the incorrect password test has a new errormessage
which is added in 0002.Hmm. I am linking to a build of alpha6 here, but I still see the
error being reported as a bad decrypt for this test. Interesting.
Turns out it was coming from when I tested against OpenSSL git HEAD, so it may
come in alpha7 (or whatever the next version will be). Let's disregard this
for now until dust settles, I've dropped the patch from the series.
cheers ./daniel
Attachments:
0001-Fix-OpenSSL-3-support-in-pgcrypto-v2.patchapplication/octet-stream; name=0001-Fix-OpenSSL-3-support-in-pgcrypto-v2.patch; x-unix-mode=0644Download
From 57fe7e80df5189fc0cfe0a1ef13bd473ebadcea3 Mon Sep 17 00:00:00 2001
From: Daniel Gustafsson <daniel@yesql.se>
Date: Mon, 21 Sep 2020 15:21:18 +0200
Subject: [PATCH] Fix OpenSSL 3 support in pgcrypto v2
---
configure | 13 +++++++++++++
configure.ac | 3 +++
contrib/pgcrypto/openssl.c | 32 +++++++++++++++++++++++++++++++-
doc/src/sgml/pgcrypto.sgml | 6 ++++++
src/include/pg_config.h.in | 3 +++
5 files changed, 56 insertions(+), 1 deletion(-)
diff --git a/configure b/configure
index 19a3cd09a0..1a409e45fe 100755
--- a/configure
+++ b/configure
@@ -12437,6 +12437,19 @@ if test "x$ac_cv_func_CRYPTO_lock" = xyes; then :
#define HAVE_CRYPTO_LOCK 1
_ACEOF
+fi
+done
+
+ # OpenSSL 3.0.0 introduce the concept of providers, which pgcrypto need to
+ # use to support since deprecated ciphers.
+ for ac_func in OSSL_PROVIDER_load
+do :
+ ac_fn_c_check_func "$LINENO" "OSSL_PROVIDER_load" "ac_cv_func_OSSL_PROVIDER_load"
+if test "x$ac_cv_func_OSSL_PROVIDER_load" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_OSSL_PROVIDER_LOAD 1
+_ACEOF
+
fi
done
diff --git a/configure.ac b/configure.ac
index 6b9d0487a8..dd5b95d7e1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1233,6 +1233,9 @@ if test "$with_openssl" = yes ; then
# thread-safety. In 1.1.0, it's no longer required, and CRYPTO_lock()
# function was removed.
AC_CHECK_FUNCS([CRYPTO_lock])
+ # OpenSSL 3.0.0 introduce the concept of providers, which pgcrypto need to
+ # use to support since deprecated ciphers.
+ AC_CHECK_FUNCS([OSSL_PROVIDER_load])
fi
if test "$with_pam" = yes ; then
diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c
index 3057afb339..7e843394d1 100644
--- a/contrib/pgcrypto/openssl.c
+++ b/contrib/pgcrypto/openssl.c
@@ -34,6 +34,9 @@
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/rand.h>
+#ifdef HAVE_OSSL_PROVIDER_LOAD
+#include <openssl/provider.h>
+#endif
#include "px.h"
#include "utils/memutils.h"
@@ -64,6 +67,10 @@ typedef struct OSSLDigest
struct OSSLDigest *prev;
} OSSLDigest;
+#ifdef HAVE_OSSL_PROVIDER_LOAD
+static OSSL_PROVIDER *legacy_provider = NULL;
+static OSSL_PROVIDER *default_provider = NULL;
+#endif
static OSSLDigest *open_digests = NULL;
static bool digest_resowner_callback_registered = false;
@@ -173,8 +180,20 @@ px_find_digest(const char *name, PX_MD **res)
if (!px_openssl_initialized)
{
- px_openssl_initialized = 1;
+#ifdef HAVE_OSSL_PROVIDER_LOAD
+ if (legacy_provider == NULL)
+ legacy_provider = OSSL_PROVIDER_load(NULL, "legacy");
+ if (default_provider == NULL)
+ default_provider = OSSL_PROVIDER_load(NULL, "default");
+#endif
+
+ /*
+ * OpenSSL_add_all_algorithms is deprecated in OpenSSL 1.1.0 and no
+ * longer required in 1.1.0 and later versions as initialization is
+ * performed automatically.
+ */
OpenSSL_add_all_algorithms();
+ px_openssl_initialized = 1;
}
if (!digest_resowner_callback_registered)
@@ -367,6 +386,8 @@ gen_ossl_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
{
if (!EVP_DecryptInit_ex(od->evp_ctx, od->evp_ciph, NULL, NULL, NULL))
return PXE_CIPHER_INIT;
+ if (!EVP_CIPHER_CTX_set_padding(od->evp_ctx, 0))
+ return PXE_CIPHER_INIT;
if (!EVP_CIPHER_CTX_set_key_length(od->evp_ctx, od->klen))
return PXE_CIPHER_INIT;
if (!EVP_DecryptInit_ex(od->evp_ctx, NULL, NULL, od->key, od->iv))
@@ -391,6 +412,8 @@ gen_ossl_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
{
if (!EVP_EncryptInit_ex(od->evp_ctx, od->evp_ciph, NULL, NULL, NULL))
return PXE_CIPHER_INIT;
+ if (!EVP_CIPHER_CTX_set_padding(od->evp_ctx, 0))
+ return PXE_CIPHER_INIT;
if (!EVP_CIPHER_CTX_set_key_length(od->evp_ctx, od->klen))
return PXE_CIPHER_INIT;
if (!EVP_EncryptInit_ex(od->evp_ctx, NULL, NULL, od->key, od->iv))
@@ -751,6 +774,13 @@ px_find_cipher(const char *name, PX_Cipher **res)
EVP_CIPHER_CTX *ctx;
OSSLCipher *od;
+#ifdef HAVE_OSSL_PROVIDER_LOAD
+ if (legacy_provider == NULL)
+ legacy_provider = OSSL_PROVIDER_load(NULL, "legacy");
+ if (default_provider == NULL)
+ default_provider = OSSL_PROVIDER_load(NULL, "default");
+#endif
+
name = px_resolve_alias(ossl_aliases, name);
for (i = ossl_cipher_types; i->name; i++)
if (strcmp(i->name, name) == 0)
diff --git a/doc/src/sgml/pgcrypto.sgml b/doc/src/sgml/pgcrypto.sgml
index 8748c64e2d..5c6d54042e 100644
--- a/doc/src/sgml/pgcrypto.sgml
+++ b/doc/src/sgml/pgcrypto.sgml
@@ -1233,6 +1233,12 @@ gen_random_uuid() returns uuid
</tgroup>
</table>
+ <para>
+ When compiled against <productname>OpenSSL</productname> 3.0.0, the legacy
+ provider will be automatically loaded in order to support the ciphers in
+ the above table.
+ </para>
+
<para>
Notes:
</para>
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index fb270df678..e4844f67c1 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -385,6 +385,9 @@
/* Define to 1 if you have the `OPENSSL_init_ssl' function. */
#undef HAVE_OPENSSL_INIT_SSL
+/* Define to 1 if you have the `OSSL_PROVIDER_load' function */
+#undef HAVE_OSSL_PROVIDER_LOAD
+
/* Define to 1 if you have the <ossp/uuid.h> header file. */
#undef HAVE_OSSP_UUID_H
--
2.21.1 (Apple Git-122.3)
On 2020-09-18 16:11, Daniel Gustafsson wrote:
Since we support ciphers that are now deprecated, we have no other choice than
to load the legacy provider.
Well, we could just have deprecated ciphers fail, unless the user loads
the legacy provider in the OS configuration. There might be an argument
that that is more proper.
As a more extreme analogy, what if OpenSSL remove a cipher from the
legacy provider? Are we then obliged to reimplement it manually for the
purpose of pgcrypto? Probably not.
The code you wrote to load the necessary providers is small enough that
I think it's fine, but it's worth pondering this question briefly.
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
On 22 Sep 2020, at 11:37, Peter Eisentraut <peter.eisentraut@2ndquadrant.com> wrote:
On 2020-09-18 16:11, Daniel Gustafsson wrote:
Since we support ciphers that are now deprecated, we have no other choice than
to load the legacy provider.Well, we could just have deprecated ciphers fail, unless the user loads the legacy provider in the OS configuration. There might be an argument that that is more proper.
Thats a fair point. The issue I have with that is that we'd impose a system
wide loading of the legacy provider, impacting other consumers of libssl as
well.
As a more extreme analogy, what if OpenSSL remove a cipher from the legacy provider? Are we then obliged to reimplement it manually for the purpose of pgcrypto? Probably not.
I don't think we have made any such guarantees of support, especially since
it's in contrib/. That doesn't mean that some users wont expect it though.
Another option would be to follow OpenSSL's deprecations and mark these ciphers
as deprecated such that we can remove them in case they indeed get removed from
libcypto. That would give users a heads-up that they should have a migration
plan for if that time comes.
The code you wrote to load the necessary providers is small enough that I think it's fine, but it's worth pondering this question briefly.
Absolutely.
cheers ./daniel
On Mon, Sep 21, 2020 at 08:18:42PM +0200, Daniel Gustafsson wrote:
I'm far from fluent in OpenSSL, but AFAICT it has to do with the new provider
API. The default value for padding is unchanged, but it needs to be propaged
into the provider to be set in the context where the old code picked it up
automatically. The relevant OpenSSL commit (83f68df32f0067ee7b0) which changes
the docs to say the function should be called doesn't contain enough
information to explain why.
Hmm. Perhaps we should consider making this part conditional on
3.0.0? But I don't see an actual reason why we cannot do it
unconditionally either. This needs careful testing for sure.
Turns out it was coming from when I tested against OpenSSL git HEAD, so it may
come in alpha7 (or whatever the next version will be). Let's disregard this
for now until dust settles, I've dropped the patch from the series.
Yeah. I have just tried that on the latest HEAD at e771249 and I
could reproduce what you saw. It smells to me like a regression
introduced by upstream, as per 9a30f40c and c2150f7. I'd rather wait
for 3.0.0 to be GA before concluding here. If it proves to be
reproducible with their golden version as a bug (or even not as a
bug), we will need to have a workaround in any case.
--
Michael
On Tue, Sep 22, 2020 at 02:01:18PM +0200, Daniel Gustafsson wrote:
Another option would be to follow OpenSSL's deprecations and mark these ciphers
as deprecated such that we can remove them in case they indeed get removed from
libcypto. That would give users a heads-up that they should have a migration
plan for if that time comes.
Does that mean a deprecation note in the docs as well as a WARNING
when attempting to use those ciphers in pgcryto with the version of
OpenSSL marking such ciphers as deprecated? I would assume that we
should do both, rather than only one of them to bring more visibility
to the user.
--
Michael
On 23 Sep 2020, at 10:19, Michael Paquier <michael@paquier.xyz> wrote:
On Tue, Sep 22, 2020 at 02:01:18PM +0200, Daniel Gustafsson wrote:
Another option would be to follow OpenSSL's deprecations and mark these ciphers
as deprecated such that we can remove them in case they indeed get removed from
libcypto. That would give users a heads-up that they should have a migration
plan for if that time comes.Does that mean a deprecation note in the docs as well as a WARNING
when attempting to use those ciphers in pgcryto with the version of
OpenSSL marking such ciphers as deprecated? I would assume that we
should do both, rather than only one of them to bring more visibility
to the user.
We generally don't issue WARNINGs for deprecated functionality do we? The only
one I can see is for GLOBAL TEMPORARY in temp table creation. The relevant
errcode ERRCODE_WARNING_DEPRECATED_FEATURE is also not used anywhere.
I'd expect it to just be a note in the documentation, with a prominent
placement in the release notes, if we decide to do something like this.
cheers ./daniel
On 22 Sep 2020, at 14:01, Daniel Gustafsson <daniel@yesql.se> wrote:
On 22 Sep 2020, at 11:37, Peter Eisentraut <peter.eisentraut@2ndquadrant.com> wrote:
On 2020-09-18 16:11, Daniel Gustafsson wrote:
Since we support ciphers that are now deprecated, we have no other choice than
to load the legacy provider.Well, we could just have deprecated ciphers fail, unless the user loads the legacy provider in the OS configuration. There might be an argument that that is more proper.
Thats a fair point. The issue I have with that is that we'd impose a system
wide loading of the legacy provider, impacting other consumers of libssl as
well.
After another round of thinking on this, somewhat spurred on by findings in the
the nearby FIPS thread, I'm coming around to this idea.
Looking at SCRAM+FIPS made me realize that we can't enforce FIPS mode in
pgcrypto via the OpenSSL configuration file, since pgcrypto doesn't load the
config. The automatic initialization in 1.1.0+ will however load the config
file, so not doing it for older versions makes pgcrypto inconsistent. Thus, I
think we should make sure that pgcrypto loads the configuratio for all OpenSSL
versions, and defer the provider decision in 3.0.0 to the users. This makes
the patch minimally intrusive while making pgcrypto behave consistently (and
giving 3.0.0 users the option to not run legacy).
The attached adds config loading to pgcrypto for < 1.1.0 and a doc notice for
enabling the legacy provider in 3.0.0. This will require an alternative output
file for non-legacy configs, but that should wait until 3.0.0 is GA since the
returned error messages have changed over course of development and may not be
set in stone just yet.
cheers ./daniel
Attachments:
0001-Fix-OpenSSL-3-support-in-pgcrypto-v3.patchapplication/octet-stream; name=0001-Fix-OpenSSL-3-support-in-pgcrypto-v3.patch; x-unix-mode=0644Download
From 7c03c8e5ce2a895850e75857eb4aa44dcc5f787c Mon Sep 17 00:00:00 2001
From: Daniel Gustafsson <daniel@yesql.se>
Date: Mon, 21 Sep 2020 15:21:18 +0200
Subject: [PATCH] Fix OpenSSL 3 support in pgcrypto v3
---
contrib/pgcrypto/openssl.c | 19 ++++++++++++++++++-
doc/src/sgml/pgcrypto.sgml | 6 ++++++
2 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c
index 90951a8ae7..7ae843bd7d 100644
--- a/contrib/pgcrypto/openssl.c
+++ b/contrib/pgcrypto/openssl.c
@@ -31,6 +31,9 @@
#include "postgres.h"
+#ifndef HAVE_OPENSSL_INIT_SSL
+#include <openssl/conf.h>
+#endif
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/rand.h>
@@ -173,8 +176,18 @@ px_find_digest(const char *name, PX_MD **res)
if (!px_openssl_initialized)
{
- px_openssl_initialized = 1;
+ /*
+ * OpenSSL_add_all_algorithms is deprecated in OpenSSL 1.1.0 and no
+ * longer required in 1.1.0 and later versions, as initialization is
+ * performed automatically. We don't have macros for OpenSSL versions
+ * since they collide with LibreSSL, OPENSSL_init_ssl was introduced
+ * in 1.1.0 so we can use the corresponding HAVE_ macro.
+ */
+#ifndef HAVE_OPENSSL_INIT_SSL
+ OPENSSL_config(NULL);
OpenSSL_add_all_algorithms();
+#endif
+ px_openssl_initialized = 1;
}
if (!digest_resowner_callback_registered)
@@ -367,6 +380,8 @@ gen_ossl_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
{
if (!EVP_DecryptInit_ex(od->evp_ctx, od->evp_ciph, NULL, NULL, NULL))
return PXE_CIPHER_INIT;
+ if (!EVP_CIPHER_CTX_set_padding(od->evp_ctx, 0))
+ return PXE_CIPHER_INIT;
if (!EVP_CIPHER_CTX_set_key_length(od->evp_ctx, od->klen))
return PXE_CIPHER_INIT;
if (!EVP_DecryptInit_ex(od->evp_ctx, NULL, NULL, od->key, od->iv))
@@ -391,6 +406,8 @@ gen_ossl_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
{
if (!EVP_EncryptInit_ex(od->evp_ctx, od->evp_ciph, NULL, NULL, NULL))
return PXE_CIPHER_INIT;
+ if (!EVP_CIPHER_CTX_set_padding(od->evp_ctx, 0))
+ return PXE_CIPHER_INIT;
if (!EVP_CIPHER_CTX_set_key_length(od->evp_ctx, od->klen))
return PXE_CIPHER_INIT;
if (!EVP_EncryptInit_ex(od->evp_ctx, NULL, NULL, od->key, od->iv))
diff --git a/doc/src/sgml/pgcrypto.sgml b/doc/src/sgml/pgcrypto.sgml
index 8748c64e2d..3c1e16e0f9 100644
--- a/doc/src/sgml/pgcrypto.sgml
+++ b/doc/src/sgml/pgcrypto.sgml
@@ -1233,6 +1233,12 @@ gen_random_uuid() returns uuid
</tgroup>
</table>
+ <para>
+ When compiled against <productname>OpenSSL</productname> 3.0.0, the legacy
+ provider must be activated in the <filename>openssl.cnf</filename> file
+ in order to use older ciphers like MD5.
+ </para>
+
<para>
Notes:
</para>
--
2.21.1 (Apple Git-122.3)
On Tue, Sep 29, 2020 at 12:25:05PM +0200, Daniel Gustafsson wrote:
The attached adds config loading to pgcrypto for < 1.1.0 and a doc notice for
enabling the legacy provider in 3.0.0. This will require an alternative output
file for non-legacy configs, but that should wait until 3.0.0 is GA since the
returned error messages have changed over course of development and may not be
set in stone just yet.
FWIW, testing with 3.0.0-alpha9 dev (2d84089), I can see that the
error we have in our SSL tests when using a wrong password in the
private PEM key leads now to "PEM lib" instead of "bad decrypt".
Upthread, we had "nested asn1 error":
/messages/by-id/9CE70AF4-E1A0-4D24-86FA-4C3067077897@yesql.se
It looks like not everything is sorted out there yet.
pgcrypto is also throwing new errors. Daniel, what if we let this
patch aside until upstream has sorted out their stuff?
--
Michael
On 26 Nov 2020, at 09:08, Michael Paquier <michael@paquier.xyz> wrote:
On Tue, Sep 29, 2020 at 12:25:05PM +0200, Daniel Gustafsson wrote:
The attached adds config loading to pgcrypto for < 1.1.0 and a doc notice for
enabling the legacy provider in 3.0.0. This will require an alternative output
file for non-legacy configs, but that should wait until 3.0.0 is GA since the
returned error messages have changed over course of development and may not be
set in stone just yet.FWIW, testing with 3.0.0-alpha9 dev (2d84089), I can see that the
error we have in our SSL tests when using a wrong password in the
private PEM key leads now to "PEM lib" instead of "bad decrypt".Upthread, we had "nested asn1 error":
/messages/by-id/9CE70AF4-E1A0-4D24-86FA-4C3067077897@yesql.se
It looks like not everything is sorted out there yet.pgcrypto is also throwing new errors. Daniel, what if we let this
patch aside until upstream has sorted out their stuff?
Well, the patch as it stands isn't changing any expected output at all, and
only adds a docs notice for OpenSSL 3.0.0 conformance. The gist of the patch
is to ensure that all supported versions of OpenSSL are initialized equally as
currently < 1.1.0 are bypassing the local openssl config, where 1.1.0+ isn't.
So I still think this patch is worth considering.
Regarding test output: it's clear that we'll need to revisit this as the dust
settles on OpenSSL 3.0.0, but as you say there is no use in doing anything
until it has. According to their tracker they are, at this time of writing,
64% complete on the milestone to reach beta readiness [0]https://github.com/openssl/openssl/milestone/17 (which I believe
started counting on alpha7).
cheers ./daniel
This thread is still in the commit fest, but I don't see any actual
proposed patch still pending. Most of the activity has moved into other
threads.
Could you update the status of this CF entry, and perhaps also on the
status of OpenSSL compatibility in general?
On Wed, Mar 03, 2021 at 02:55:41PM +0100, Peter Eisentraut wrote:
This thread is still in the commit fest, but I don't see any actual proposed
patch still pending. Most of the activity has moved into other threads.Could you update the status of this CF entry, and perhaps also on the status
of OpenSSL compatibility in general?
3.0.0 has released an alpha 12 on the 18th of February, so their stuff
is not quite close to GA yet.
I have not looked closely, but my guess is that it would take a couple
of extra months at least to see a release. What if we just waited and
revisited this stuff during the next dev cycle, once there is at least
a beta, meaning mostly stable APIs?
Daniel, what do you think?
--
Michael
On 3 Mar 2021, at 14:55, Peter Eisentraut <peter.eisentraut@2ndquadrant.com> wrote:
This thread is still in the commit fest, but I don't see any actual proposed patch still pending. Most of the activity has moved into other threads.
The doc changes in the patch proposed on 29/9 still stands, although I see that
it had an off by one in mentioning MD5 when it should be MD4 et.al; so
something more like the below.
diff --git a/doc/src/sgml/pgcrypto.sgml b/doc/src/sgml/pgcrypto.sgml
index b6bb23de0f..d45464c7ea 100644
--- a/doc/src/sgml/pgcrypto.sgml
+++ b/doc/src/sgml/pgcrypto.sgml
@@ -1234,6 +1234,12 @@ gen_random_uuid() returns uuid
</tgroup>
</table>
+ <para>
+ When compiled against <productname>OpenSSL</productname> 3.0.0, the legacy
+ provider must be activated in the system <filename>openssl.cnf</filename>
+ configuration file in order to use older ciphers like DES and Blowfish.
+ </para>
+
<para>
Could you update the status of this CF entry, and perhaps also on the status of OpenSSL compatibility in general?
Let's just wait for 3.0.0 to ship before we do anything.
--
Daniel Gustafsson https://vmware.com/
On 10.03.21 09:23, Daniel Gustafsson wrote:
On 3 Mar 2021, at 14:55, Peter Eisentraut <peter.eisentraut@2ndquadrant.com> wrote:
This thread is still in the commit fest, but I don't see any actual proposed patch still pending. Most of the activity has moved into other threads.
The doc changes in the patch proposed on 29/9 still stands, although I see that
it had an off by one in mentioning MD5 when it should be MD4 et.al; so
something more like the below.diff --git a/doc/src/sgml/pgcrypto.sgml b/doc/src/sgml/pgcrypto.sgml index b6bb23de0f..d45464c7ea 100644 --- a/doc/src/sgml/pgcrypto.sgml +++ b/doc/src/sgml/pgcrypto.sgml @@ -1234,6 +1234,12 @@ gen_random_uuid() returns uuid </tgroup> </table>+ <para> + When compiled against <productname>OpenSSL</productname> 3.0.0, the legacy + provider must be activated in the system <filename>openssl.cnf</filename> + configuration file in order to use older ciphers like DES and Blowfish. + </para> + <para>
I tested the current master with openssl-3.0.0-alpha12.
Everything builds cleanly.
The ssl tests fail with a small error message difference that must have
been introduced recently, because I think this was never reported before:
--- a/src/test/ssl/t/001_ssltests.pl
+++ b/src/test/ssl/t/001_ssltests.pl
@@ -449,7 +449,7 @@
test_connect_fails(
$common_connstr,
"user=ssltestuser sslcert=ssl/client.crt
sslkey=ssl/client-encrypted-pem_tmp.key sslpassword='wrong'",
- qr!\Qprivate key file "ssl/client-encrypted-pem_tmp.key": bad
decrypt\E!,
+ qr!\Qprivate key file "ssl/client-encrypted-pem_tmp.key":\E (bad
decrypt|PEM lib)!,
"certificate authorization fails with correct client cert and wrong
password in encrypted PEM format"
);
The pgcrypto tests fail all over the place. Some of these failures are
quite likely because of the disabled legacy provider, but some appear to
be due to bad error handling.
Then I tried enabling the legacy provider in openssl.cnf. This caused
pg_strong_random() to fail, which causes initdb to fail, like this:
PANIC: could not generate secret authorization token
I tried patching around in pg_strong_random.c to use the /dev/urandom
variant as a workaround, but apparently that doesn't work. You get all
kinds of scary make check failures from md5 and sha256 calls.
So, we knew pgcrypto was in trouble with openssl 3.0.0, but can someone
else get its tests to pass with some kind of openssl.cnf configuration?
On 11 Mar 2021, at 11:03, Peter Eisentraut <peter.eisentraut@enterprisedb.com> wrote:
The ssl tests fail with a small error message difference that must have been introduced recently, because I think this was never reported before:
This was mentioned by Michael on 26/11, it was earlier in the 3.0.0 cycle
reported as "nested asn.1 error". Waiting for 3.0.0 to go beta or GA before
changing saves us from having to change again should they update, but tests
will fail for anyone testing out new OpenSSL versions.
The pgcrypto tests fail all over the place. Some of these failures are quite likely because of the disabled legacy provider, but some appear to be due to bad error handling.
The below ones are likely due to the provider not being loaded, but as you say
they are probably cases of poor error handling as they fail in various places
while probably being due to the same root cause:
+ERROR: encrypt error: Key was too big
+ERROR: encrypt error: Cipher cannot be initialized ?
+ERROR: Wrong key or corrupt data
Then there are a few where we get padding back where we really should have
ended up with the "Cipher cannot be initialized" error since DES is in the
legacy provider:
select decrypt_iv(decode('50735067b073bb93', 'hex'), '0123456', 'abcd', 'des');
- decrypt_iv
-------------
- foo
+ decrypt_iv
+----------------------------------
+ \177\177\177\177\177\177\177\177
(1 row)
Then I tried enabling the legacy provider in openssl.cnf. This caused pg_strong_random() to fail, which causes initdb to fail, like this:
Huh? Enabling the legacy provider shouldn't affect the CRNG. I see no such
failure, and haven't in any alpha version tested. How did you change the
openssl config? If one can break pg_strong_random with a config change then we
need defensive coding to cope with that.
So, we knew pgcrypto was in trouble with openssl 3.0.0, but can someone else get its tests to pass with some kind of openssl.cnf configuration?
If I enable the legacy provider in openssl.cnf like this:
[openssl_init]
providers = provider_sect
[provider_sect]
default = default_sect
legacy = legacy_sect
[default_sect]
activate = 1
[legacy_sect]
activate = 1
.. and apply the padding changes as proposed in a patch upthread like this (these
work for all OpenSSL versions I've tested, and I'm rather more puzzled as to
why we got away with not having them in the past):
diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c
index ed8e74a2b9..e236b0d79c 100644
--- a/contrib/pgcrypto/openssl.c
+++ b/contrib/pgcrypto/openssl.c
@@ -379,6 +379,8 @@ gen_ossl_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
{
if (!EVP_DecryptInit_ex(od->evp_ctx, od->evp_ciph, NULL, NULL, NULL))
return PXE_CIPHER_INIT;
+ if (!EVP_CIPHER_CTX_set_padding(od->evp_ctx, 0))
+ return PXE_CIPHER_INIT;
if (!EVP_CIPHER_CTX_set_key_length(od->evp_ctx, od->klen))
return PXE_CIPHER_INIT;
if (!EVP_DecryptInit_ex(od->evp_ctx, NULL, NULL, od->key, od->iv))
@@ -403,6 +405,8 @@ gen_ossl_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
{
if (!EVP_EncryptInit_ex(od->evp_ctx, od->evp_ciph, NULL, NULL, NULL))
return PXE_CIPHER_INIT;
+ if (!EVP_CIPHER_CTX_set_padding(od->evp_ctx, 0))
+ return PXE_CIPHER_INIT;
if (!EVP_CIPHER_CTX_set_key_length(od->evp_ctx, od->klen))
return PXE_CIPHER_INIT;
if (!EVP_EncryptInit_ex(od->evp_ctx, NULL, NULL, od->key, od->iv))
.. then all the pgcrypto tests pass for me as well as "make check", with a single
SSL test failing on the above mentioned PEM lib error message.
Did you build OpenSSL with anything non-standard?
--
Daniel Gustafsson https://vmware.com/
On Thu, Mar 11, 2021 at 11:41:22AM +0100, Daniel Gustafsson wrote:
.. and apply the padding changes as proposed in a patch upthread
like this (these work for all OpenSSL versions I've tested, and I'm
rather more puzzled as to why we got away with not having them in
the past):
No objections from here to disable the padding and tighten a bit the
error checks on the amount of data encrypted or decrypted based on
the block size. This indeed works correctly down to OpenSSL 1.0.1 as
far as I have tested, so let's extract this part first, and figure the
rest after there is a beta.
--
Michael
On 11.03.21 11:41, Daniel Gustafsson wrote:
Then there are a few where we get padding back where we really should have
ended up with the "Cipher cannot be initialized" error since DES is in the
legacy provider:select decrypt_iv(decode('50735067b073bb93', 'hex'), '0123456', 'abcd', 'des'); - decrypt_iv ------------- - foo + decrypt_iv +---------------------------------- + \177\177\177\177\177\177\177\177 (1 row)
The attached patch appears to address these cases.
Attachments:
0001-Check-for-error-return-of-px_cipher_decrypt.patchtext/plain; charset=UTF-8; name=0001-Check-for-error-return-of-px_cipher_decrypt.patch; x-mac-creator=0; x-mac-type=0Download
From 1b9cf580e9e441806def681eea71ce6fd2228206 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Thu, 11 Mar 2021 23:58:29 +0100
Subject: [PATCH] Check for error return of px_cipher_decrypt()
---
contrib/pgcrypto/px.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/contrib/pgcrypto/px.c b/contrib/pgcrypto/px.c
index a243f575d3..4205e9c3ef 100644
--- a/contrib/pgcrypto/px.c
+++ b/contrib/pgcrypto/px.c
@@ -292,6 +292,7 @@ static int
combo_decrypt(PX_Combo *cx, const uint8 *data, unsigned dlen,
uint8 *res, unsigned *rlen)
{
+ int err = 0;
unsigned bs,
i,
pad;
@@ -317,7 +318,9 @@ combo_decrypt(PX_Combo *cx, const uint8 *data, unsigned dlen,
/* decrypt */
*rlen = dlen;
- px_cipher_decrypt(c, data, dlen, res);
+ err = px_cipher_decrypt(c, data, dlen, res);
+ if (err)
+ return err;
/* unpad */
if (bs > 1 && cx->padding)
--
2.30.1
On 12 Mar 2021, at 00:04, Peter Eisentraut <peter.eisentraut@enterprisedb.com> wrote:
On 11.03.21 11:41, Daniel Gustafsson wrote:
Then there are a few where we get padding back where we really should have ended up with the "Cipher cannot be initialized" error since DES is in the legacy provider: select decrypt_iv(decode('50735067b073bb93', 'hex'), '0123456', 'abcd', 'des'); - decrypt_iv ------------- - foo + decrypt_iv +---------------------------------- + \177\177\177\177\177\177\177\177 (1 row)The attached patch appears to address these cases.
+1, males a lot of sense. This removes said errors when running without the
legacy provider enabled, and all tests still pass with it enabled.
--
Daniel Gustafsson https://vmware.com/
On 11.03.21 11:41, Daniel Gustafsson wrote:
.. and apply the padding changes as proposed in a patch upthread like this (these
work for all OpenSSL versions I've tested, and I'm rather more puzzled as to
why we got away with not having them in the past):
Yes, before proceeding with this, we should probably understand why
these changes are effective and why they haven't been required in the past.
On 12.03.21 00:22, Daniel Gustafsson wrote:
On 12 Mar 2021, at 00:04, Peter Eisentraut <peter.eisentraut@enterprisedb.com> wrote:
On 11.03.21 11:41, Daniel Gustafsson wrote:
Then there are a few where we get padding back where we really should have ended up with the "Cipher cannot be initialized" error since DES is in the legacy provider: select decrypt_iv(decode('50735067b073bb93', 'hex'), '0123456', 'abcd', 'des'); - decrypt_iv ------------- - foo + decrypt_iv +---------------------------------- + \177\177\177\177\177\177\177\177 (1 row)The attached patch appears to address these cases.
+1, males a lot of sense. This removes said errors when running without the
legacy provider enabled, and all tests still pass with it enabled.
I have committed this to master. I see that the commit fest entry has
been withdrawn in the meantime. I suppose we'll come back to this,
including possible backpatching, when OpenSSL 3.0.0 is in beta.
On 12.03.21 08:51, Peter Eisentraut wrote:
On 11.03.21 11:41, Daniel Gustafsson wrote:
.. and apply the padding changes as proposed in a patch upthread like
this (these
work for all OpenSSL versions I've tested, and I'm rather more puzzled
as to
why we got away with not having them in the past):Yes, before proceeding with this, we should probably understand why
these changes are effective and why they haven't been required in the past.
I took another look at this with openssl-3.0.0-beta1. The issue with
the garbled padding output is still there. What I found is that
pgcrypto has been using the encryption and decryption API slightly
incorrectly. You are supposed to call EVP_DecryptUpdate() followed by
EVP_DecryptFinal_ex() (and similarly for encryption), but pgcrypto
doesn't do the second one. (To be fair, this API was added to OpenSSL
after pgcrypto first appeared.) The "final" functions take care of the
padding. We have been getting away with it like this because we do the
padding manually elsewhere. But apparently, something has changed in
OpenSSL 3.0.0 in that if padding is enabled in OpenSSL,
EVP_DecryptUpdate() doesn't flush the last normal block until the
"final" function is called.
Your proposed fix was to explicitly disable padding, and then this
problem goes away. You can still call the "final" functions, but they
won't do anything, except check that there is no more data left, but we
already check that elsewhere.
Another option is to throw out our own padding code and let OpenSSL
handle it. See attached demo patch. But that breaks the non-OpenSSL
code in internal.c, so we'd have to re-add the padding code there. So
this isn't quite as straightforward an option. (At least, with the
patch we can confirm that the OpenSSL padding works consistently with
our own implementation.)
So I think your proposed patch is sound and a good short-term and
low-risk solution.
Attachments:
0001-Use-EVP_EncryptFinal_ex-and-EVP_DecryptFinal_ex.patchtext/plain; charset=UTF-8; name=0001-Use-EVP_EncryptFinal_ex-and-EVP_DecryptFinal_ex.patch; x-mac-creator=0; x-mac-type=0Download
From be5882c7e7b80a6d213eee88a8960f6c9773f958 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Sat, 3 Jul 2021 15:39:30 +0200
Subject: [PATCH] Use EVP_EncryptFinal_ex() and EVP_DecryptFinal_ex()
---
contrib/pgcrypto/openssl.c | 22 +++++--
contrib/pgcrypto/pgp-cfb.c | 4 +-
contrib/pgcrypto/px.c | 119 +------------------------------------
contrib/pgcrypto/px.h | 12 ++--
4 files changed, 27 insertions(+), 130 deletions(-)
diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c
index ed8e74a2b9..68fd61b716 100644
--- a/contrib/pgcrypto/openssl.c
+++ b/contrib/pgcrypto/openssl.c
@@ -369,16 +369,18 @@ gen_ossl_free(PX_Cipher *c)
}
static int
-gen_ossl_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
- uint8 *res)
+gen_ossl_decrypt(PX_Cipher *c, int padding, const uint8 *data, unsigned dlen,
+ uint8 *res, unsigned *rlen)
{
OSSLCipher *od = c->ptr;
- int outlen;
+ int outlen, outlen2;
if (!od->init)
{
if (!EVP_DecryptInit_ex(od->evp_ctx, od->evp_ciph, NULL, NULL, NULL))
return PXE_CIPHER_INIT;
+ if (!EVP_CIPHER_CTX_set_padding(od->evp_ctx, padding))
+ return PXE_CIPHER_INIT;
if (!EVP_CIPHER_CTX_set_key_length(od->evp_ctx, od->klen))
return PXE_CIPHER_INIT;
if (!EVP_DecryptInit_ex(od->evp_ctx, NULL, NULL, od->key, od->iv))
@@ -388,21 +390,26 @@ gen_ossl_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
if (!EVP_DecryptUpdate(od->evp_ctx, res, &outlen, data, dlen))
return PXE_DECRYPT_FAILED;
+ if (!EVP_DecryptFinal_ex(od->evp_ctx, res + outlen, &outlen2))
+ return PXE_DECRYPT_FAILED;
+ *rlen = outlen + outlen2;
return 0;
}
static int
-gen_ossl_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
- uint8 *res)
+gen_ossl_encrypt(PX_Cipher *c, int padding, const uint8 *data, unsigned dlen,
+ uint8 *res, unsigned *rlen)
{
OSSLCipher *od = c->ptr;
- int outlen;
+ int outlen, outlen2;
if (!od->init)
{
if (!EVP_EncryptInit_ex(od->evp_ctx, od->evp_ciph, NULL, NULL, NULL))
return PXE_CIPHER_INIT;
+ if (!EVP_CIPHER_CTX_set_padding(od->evp_ctx, padding))
+ return PXE_CIPHER_INIT;
if (!EVP_CIPHER_CTX_set_key_length(od->evp_ctx, od->klen))
return PXE_CIPHER_INIT;
if (!EVP_EncryptInit_ex(od->evp_ctx, NULL, NULL, od->key, od->iv))
@@ -412,6 +419,9 @@ gen_ossl_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
if (!EVP_EncryptUpdate(od->evp_ctx, res, &outlen, data, dlen))
return PXE_ENCRYPT_FAILED;
+ if (!EVP_EncryptFinal_ex(od->evp_ctx, res + outlen, &outlen2))
+ return PXE_ENCRYPT_FAILED;
+ *rlen = outlen + outlen2;
return 0;
}
diff --git a/contrib/pgcrypto/pgp-cfb.c b/contrib/pgcrypto/pgp-cfb.c
index dafa562daa..de41e825b0 100644
--- a/contrib/pgcrypto/pgp-cfb.c
+++ b/contrib/pgcrypto/pgp-cfb.c
@@ -220,7 +220,9 @@ cfb_process(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst,
while (len > 0)
{
- px_cipher_encrypt(ctx->ciph, ctx->fr, ctx->block_size, ctx->fre);
+ unsigned rlen;
+
+ px_cipher_encrypt(ctx->ciph, 0, ctx->fr, ctx->block_size, ctx->fre, &rlen);
if (ctx->block_no < 5)
ctx->block_no++;
diff --git a/contrib/pgcrypto/px.c b/contrib/pgcrypto/px.c
index 4205e9c3ef..5ccab44122 100644
--- a/contrib/pgcrypto/px.c
+++ b/contrib/pgcrypto/px.c
@@ -223,129 +223,14 @@ static int
combo_encrypt(PX_Combo *cx, const uint8 *data, unsigned dlen,
uint8 *res, unsigned *rlen)
{
- int err = 0;
- uint8 *bbuf;
- unsigned bs,
- bpos,
- i,
- pad;
-
- PX_Cipher *c = cx->cipher;
-
- bbuf = NULL;
- bs = px_cipher_block_size(c);
-
- /* encrypt */
- if (bs > 1)
- {
- bbuf = palloc(bs * 4);
- bpos = dlen % bs;
- *rlen = dlen - bpos;
- memcpy(bbuf, data + *rlen, bpos);
-
- /* encrypt full-block data */
- if (*rlen)
- {
- err = px_cipher_encrypt(c, data, *rlen, res);
- if (err)
- goto out;
- }
-
- /* bbuf has now bpos bytes of stuff */
- if (cx->padding)
- {
- pad = bs - (bpos % bs);
- for (i = 0; i < pad; i++)
- bbuf[bpos++] = pad;
- }
- else if (bpos % bs)
- {
- /* ERROR? */
- pad = bs - (bpos % bs);
- for (i = 0; i < pad; i++)
- bbuf[bpos++] = 0;
- }
-
- /* encrypt the rest - pad */
- if (bpos)
- {
- err = px_cipher_encrypt(c, bbuf, bpos, res + *rlen);
- *rlen += bpos;
- }
- }
- else
- {
- /* stream cipher/mode - no pad needed */
- err = px_cipher_encrypt(c, data, dlen, res);
- if (err)
- goto out;
- *rlen = dlen;
- }
-out:
- if (bbuf)
- pfree(bbuf);
-
- return err;
+ return px_cipher_encrypt(cx->cipher, cx->padding, data, dlen, res, rlen);
}
static int
combo_decrypt(PX_Combo *cx, const uint8 *data, unsigned dlen,
uint8 *res, unsigned *rlen)
{
- int err = 0;
- unsigned bs,
- i,
- pad;
- unsigned pad_ok;
-
- PX_Cipher *c = cx->cipher;
-
- /* decide whether zero-length input is allowed */
- if (dlen == 0)
- {
- /* with padding, empty ciphertext is not allowed */
- if (cx->padding)
- return PXE_DECRYPT_FAILED;
-
- /* without padding, report empty result */
- *rlen = 0;
- return 0;
- }
-
- bs = px_cipher_block_size(c);
- if (bs > 1 && (dlen % bs) != 0)
- goto block_error;
-
- /* decrypt */
- *rlen = dlen;
- err = px_cipher_decrypt(c, data, dlen, res);
- if (err)
- return err;
-
- /* unpad */
- if (bs > 1 && cx->padding)
- {
- pad = res[*rlen - 1];
- pad_ok = 0;
- if (pad > 0 && pad <= bs && pad <= *rlen)
- {
- pad_ok = 1;
- for (i = *rlen - pad; i < *rlen; i++)
- if (res[i] != pad)
- {
- pad_ok = 0;
- break;
- }
- }
-
- if (pad_ok)
- *rlen -= pad;
- }
-
- return 0;
-
-block_error:
- return PXE_NOTBLOCKSIZE;
+ return px_cipher_decrypt(cx->cipher, cx->padding, data, dlen, res, rlen);
}
static void
diff --git a/contrib/pgcrypto/px.h b/contrib/pgcrypto/px.h
index 17d6f22498..9348d6c997 100644
--- a/contrib/pgcrypto/px.h
+++ b/contrib/pgcrypto/px.h
@@ -143,8 +143,8 @@ struct px_cipher
unsigned (*iv_size) (PX_Cipher *c);
int (*init) (PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv);
- int (*encrypt) (PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res);
- int (*decrypt) (PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res);
+ int (*encrypt) (PX_Cipher *c, int padding, const uint8 *data, unsigned dlen, uint8 *res, unsigned *rlen);
+ int (*decrypt) (PX_Cipher *c, int padding, const uint8 *data, unsigned dlen, uint8 *res, unsigned *rlen);
void (*free) (PX_Cipher *c);
/* private */
void *ptr;
@@ -207,10 +207,10 @@ void px_debug(const char *fmt,...) pg_attribute_printf(1, 2);
#define px_cipher_block_size(c) (c)->block_size(c)
#define px_cipher_iv_size(c) (c)->iv_size(c)
#define px_cipher_init(c, k, klen, iv) (c)->init(c, k, klen, iv)
-#define px_cipher_encrypt(c, data, dlen, res) \
- (c)->encrypt(c, data, dlen, res)
-#define px_cipher_decrypt(c, data, dlen, res) \
- (c)->decrypt(c, data, dlen, res)
+#define px_cipher_encrypt(c, padding, data, dlen, res, rlen) \
+ (c)->encrypt(c, padding, data, dlen, res, rlen)
+#define px_cipher_decrypt(c, padding, data, dlen, res, rlen) \
+ (c)->decrypt(c, padding, data, dlen, res, rlen)
#define px_cipher_free(c) (c)->free(c)
--
2.32.0
On 3 Jul 2021, at 17:00, Peter Eisentraut <peter.eisentraut@enterprisedb.com> wrote:
On 12.03.21 08:51, Peter Eisentraut wrote:
On 11.03.21 11:41, Daniel Gustafsson wrote:
.. and apply the padding changes as proposed in a patch upthread like this (these
work for all OpenSSL versions I've tested, and I'm rather more puzzled as to
why we got away with not having them in the past):Yes, before proceeding with this, we should probably understand why these changes are effective and why they haven't been required in the past.
I took another look at this with openssl-3.0.0-beta1. The issue with the garbled padding output is still there. What I found is that pgcrypto has been using the encryption and decryption API slightly incorrectly. You are supposed to call EVP_DecryptUpdate() followed by EVP_DecryptFinal_ex() (and similarly for encryption), but pgcrypto doesn't do the second one. (To be fair, this API was added to OpenSSL after pgcrypto first appeared.) The "final" functions take care of the padding. We have been getting away with it like this because we do the padding manually elsewhere.
That does make a lot of sense, following the code and API docs I concur with
your findings.
..apparently, something has changed in OpenSSL 3.0.0 in that if padding is enabled in OpenSSL, EVP_DecryptUpdate() doesn't flush the last normal block until the "final" function is called.
Skimming the code I wasn't able to find something off the cuff, but there has
been work done to postpone/move padding for constant time operations so maybe
it's related to that.
Your proposed fix was to explicitly disable padding, and then this problem goes away. You can still call the "final" functions, but they won't do anything, except check that there is no more data left, but we already check that elsewhere.
In earlier versions, _Final also closed the context to ensure nothing can leak
from there, but I'm not sure if 1.0.1 constitutes as earlier. Still calling it
from the finish function seems like a good idea though.
Another option is to throw out our own padding code and let OpenSSL handle it. See attached demo patch. But that breaks the non-OpenSSL code in internal.c, so we'd have to re-add the padding code there. So this isn't quite as straightforward an option.
While the PX cleanup is nice, since we can't get rid of all the padding we
simply shift the complexity to another place where I'd be wary of introducing
bugs into quite stable code.
(At least, with the patch we can confirm that the OpenSSL padding works consistently with our own implementation.)
+1
So I think your proposed patch is sound and a good short-term and low-risk solution
The attached 0001 disables the padding. I've tested this with OpenSSL 1.0.1,
1.0.2, 1.1.1 and Git HEAD at e278127cbfa2709d.
Another aspect of OpenSSL 3 compatibility is that of legacy cipher support, and
as we concluded upthread it's best to leave that to the user to define in
openssl.cnf. The attached 0002 adds alternative output files for 3.0.0
installations without the legacy provider loaded, as well as adds a note in the
pgcrypto docs to enable it in case DES is needed. It does annoy me a bit that
we don't load the openssl.cnf file for 1.0.1 if we start mentioning it in the
docs for other versions, but it's probably not worth the effort to fix it given
the lack of complaints so far (it needs a call to OPENSSL_config(NULL); guarded
to HAVE_ macros for 1.0.1).
--
Daniel Gustafsson https://vmware.com/
Attachments:
0002-Add-alternative-output-for-OpenSSL-3-without-legacy-.patchapplication/octet-stream; name=0002-Add-alternative-output-for-OpenSSL-3-without-legacy-.patch; x-unix-mode=0644Download
From 1ffb6306eae812ad89fb25a4af388be6090f17a0 Mon Sep 17 00:00:00 2001
From: Daniel Gustafsson <daniel@yesql.se>
Date: Mon, 19 Jul 2021 02:22:30 +0200
Subject: [PATCH 2/2] Add alternative output for OpenSSL 3 without legacy
loaded
OpenSSL 3 introduced the concept of providers to support modularization,
and moved the outdated ciphers to the new legacy provider. In case it's
not loaded in the users openssl.cnf file there will be a lot of regress
test failures, so add alternative outputs covering those.
Also document the need to load the legacy provider in order to use older
ciphers with OpenSSL-enabled pgcrypto.
---
contrib/pgcrypto/expected/blowfish_1.out | 95 +++
contrib/pgcrypto/expected/cast5_1.out | 48 ++
contrib/pgcrypto/expected/des_1.out | 31 +
contrib/pgcrypto/expected/pgp-decrypt_1.out | 421 +++++++++++
.../expected/pgp-pubkey-decrypt_1.out | 652 ++++++++++++++++++
doc/src/sgml/pgcrypto.sgml | 7 +
6 files changed, 1254 insertions(+)
create mode 100644 contrib/pgcrypto/expected/blowfish_1.out
create mode 100644 contrib/pgcrypto/expected/cast5_1.out
create mode 100644 contrib/pgcrypto/expected/des_1.out
create mode 100644 contrib/pgcrypto/expected/pgp-decrypt_1.out
create mode 100644 contrib/pgcrypto/expected/pgp-pubkey-decrypt_1.out
diff --git a/contrib/pgcrypto/expected/blowfish_1.out b/contrib/pgcrypto/expected/blowfish_1.out
new file mode 100644
index 0000000000..565a0853cb
--- /dev/null
+++ b/contrib/pgcrypto/expected/blowfish_1.out
@@ -0,0 +1,95 @@
+--
+-- Blowfish cipher
+--
+-- ensure consistent test output regardless of the default bytea format
+SET bytea_output TO escape;
+-- some standard Blowfish testvalues
+SELECT encode(encrypt(
+decode('0000000000000000', 'hex'),
+decode('0000000000000000', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+ERROR: encrypt error: Cipher cannot be initialized ?
+SELECT encode(encrypt(
+decode('ffffffffffffffff', 'hex'),
+decode('ffffffffffffffff', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+ERROR: encrypt error: Cipher cannot be initialized ?
+SELECT encode(encrypt(
+decode('1000000000000001', 'hex'),
+decode('3000000000000000', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+ERROR: encrypt error: Cipher cannot be initialized ?
+SELECT encode(encrypt(
+decode('1111111111111111', 'hex'),
+decode('1111111111111111', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+ERROR: encrypt error: Cipher cannot be initialized ?
+SELECT encode(encrypt(
+decode('0123456789abcdef', 'hex'),
+decode('fedcba9876543210', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+ERROR: encrypt error: Cipher cannot be initialized ?
+SELECT encode(encrypt(
+decode('01a1d6d039776742', 'hex'),
+decode('fedcba9876543210', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+ERROR: encrypt error: Cipher cannot be initialized ?
+SELECT encode(encrypt(
+decode('ffffffffffffffff', 'hex'),
+decode('0000000000000000', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+ERROR: encrypt error: Cipher cannot be initialized ?
+-- setkey
+SELECT encode(encrypt(
+decode('fedcba9876543210', 'hex'),
+decode('f0e1d2c3b4a5968778695a4b3c2d1e0f', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+ERROR: encrypt error: Cipher cannot be initialized ?
+-- with padding
+SELECT encode(encrypt(
+decode('01234567890123456789', 'hex'),
+decode('33443344334433443344334433443344', 'hex'),
+'bf-ecb'), 'hex');
+ERROR: encrypt error: Cipher cannot be initialized ?
+-- cbc
+-- 28 bytes key
+SELECT encode(encrypt(
+decode('6b77b4d63006dee605b156e27403979358deb9e7154616d959f1652bd5', 'hex'),
+decode('37363534333231204e6f77206973207468652074696d6520666f7220', 'hex'),
+'bf-cbc'), 'hex');
+ERROR: encrypt error: Key was too big
+-- 29 bytes key
+SELECT encode(encrypt(
+decode('6b77b4d63006dee605b156e27403979358deb9e7154616d959f1652bd5ff92cc', 'hex'),
+decode('37363534333231204e6f77206973207468652074696d6520666f722000', 'hex'),
+'bf-cbc'), 'hex');
+ERROR: encrypt error: Key was too big
+-- blowfish-448
+SELECT encode(encrypt(
+decode('fedcba9876543210', 'hex'),
+decode('f0e1d2c3b4a5968778695a4b3c2d1e0f001122334455667704689104c2fd3b2f584023641aba61761f1f1f1f0e0e0e0effffffffffffffff', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+ERROR: encrypt error: Key was too big
+-- result: c04504012e4e1f53
+-- empty data
+select encode(encrypt('', 'foo', 'bf'), 'hex');
+ERROR: encrypt error: Cipher cannot be initialized ?
+-- 10 bytes key
+select encode(encrypt('foo', '0123456789', 'bf'), 'hex');
+ERROR: encrypt error: Cipher cannot be initialized ?
+-- 22 bytes key
+select encode(encrypt('foo', '0123456789012345678901', 'bf'), 'hex');
+ERROR: encrypt error: Key was too big
+-- decrypt
+select decrypt(encrypt('foo', '0123456', 'bf'), '0123456', 'bf');
+ERROR: encrypt error: Cipher cannot be initialized ?
+-- iv
+select encode(encrypt_iv('foo', '0123456', 'abcd', 'bf'), 'hex');
+ERROR: encrypt_iv error: Cipher cannot be initialized ?
+select decrypt_iv(decode('95c7e89322525d59', 'hex'), '0123456', 'abcd', 'bf');
+ERROR: decrypt_iv error: Cipher cannot be initialized ?
+-- long message
+select encode(encrypt('Lets try a longer message.', '0123456789', 'bf'), 'hex');
+ERROR: encrypt error: Cipher cannot be initialized ?
+select decrypt(encrypt('Lets try a longer message.', '0123456789', 'bf'), '0123456789', 'bf');
+ERROR: encrypt error: Cipher cannot be initialized ?
diff --git a/contrib/pgcrypto/expected/cast5_1.out b/contrib/pgcrypto/expected/cast5_1.out
new file mode 100644
index 0000000000..e3b38dbce2
--- /dev/null
+++ b/contrib/pgcrypto/expected/cast5_1.out
@@ -0,0 +1,48 @@
+--
+-- Cast5 cipher
+--
+-- ensure consistent test output regardless of the default bytea format
+SET bytea_output TO escape;
+-- test vectors from RFC2144
+-- 128 bit key
+SELECT encode(encrypt(
+decode('01 23 45 67 89 AB CD EF', 'hex'),
+decode('01 23 45 67 12 34 56 78 23 45 67 89 34 56 78 9A', 'hex'),
+'cast5-ecb/pad:none'), 'hex');
+ERROR: encrypt error: Cipher cannot be initialized ?
+-- result: 23 8B 4F E5 84 7E 44 B2
+-- 80 bit key
+SELECT encode(encrypt(
+decode('01 23 45 67 89 AB CD EF', 'hex'),
+decode('01 23 45 67 12 34 56 78 23 45', 'hex'),
+'cast5-ecb/pad:none'), 'hex');
+ERROR: encrypt error: Cipher cannot be initialized ?
+-- result: EB 6A 71 1A 2C 02 27 1B
+-- 40 bit key
+SELECT encode(encrypt(
+decode('01 23 45 67 89 AB CD EF', 'hex'),
+decode('01 23 45 67 12', 'hex'),
+'cast5-ecb/pad:none'), 'hex');
+ERROR: encrypt error: Cipher cannot be initialized ?
+-- result: 7A C8 16 D1 6E 9B 30 2E
+-- cbc
+-- empty data
+select encode( encrypt('', 'foo', 'cast5'), 'hex');
+ERROR: encrypt error: Cipher cannot be initialized ?
+-- 10 bytes key
+select encode( encrypt('foo', '0123456789', 'cast5'), 'hex');
+ERROR: encrypt error: Cipher cannot be initialized ?
+-- decrypt
+select decrypt(encrypt('foo', '0123456', 'cast5'), '0123456', 'cast5');
+ERROR: encrypt error: Cipher cannot be initialized ?
+-- iv
+select encode(encrypt_iv('foo', '0123456', 'abcd', 'cast5'), 'hex');
+ERROR: encrypt_iv error: Cipher cannot be initialized ?
+select decrypt_iv(decode('384a970695ce016a', 'hex'),
+ '0123456', 'abcd', 'cast5');
+ERROR: decrypt_iv error: Cipher cannot be initialized ?
+-- long message
+select encode(encrypt('Lets try a longer message.', '0123456789', 'cast5'), 'hex');
+ERROR: encrypt error: Cipher cannot be initialized ?
+select decrypt(encrypt('Lets try a longer message.', '0123456789', 'cast5'), '0123456789', 'cast5');
+ERROR: encrypt error: Cipher cannot be initialized ?
diff --git a/contrib/pgcrypto/expected/des_1.out b/contrib/pgcrypto/expected/des_1.out
new file mode 100644
index 0000000000..e8cca0505f
--- /dev/null
+++ b/contrib/pgcrypto/expected/des_1.out
@@ -0,0 +1,31 @@
+--
+-- DES cipher
+--
+-- ensure consistent test output regardless of the default bytea format
+SET bytea_output TO escape;
+-- no official test vectors atm
+-- from blowfish.sql
+SELECT encode(encrypt(
+decode('0123456789abcdef', 'hex'),
+decode('fedcba9876543210', 'hex'),
+'des-ecb/pad:none'), 'hex');
+ERROR: encrypt error: Cipher cannot be initialized ?
+-- empty data
+select encode( encrypt('', 'foo', 'des'), 'hex');
+ERROR: encrypt error: Cipher cannot be initialized ?
+-- 8 bytes key
+select encode( encrypt('foo', '01234589', 'des'), 'hex');
+ERROR: encrypt error: Cipher cannot be initialized ?
+-- decrypt
+select decrypt(encrypt('foo', '0123456', 'des'), '0123456', 'des');
+ERROR: encrypt error: Cipher cannot be initialized ?
+-- iv
+select encode(encrypt_iv('foo', '0123456', 'abcd', 'des'), 'hex');
+ERROR: encrypt_iv error: Cipher cannot be initialized ?
+select decrypt_iv(decode('50735067b073bb93', 'hex'), '0123456', 'abcd', 'des');
+ERROR: decrypt_iv error: Cipher cannot be initialized ?
+-- long message
+select encode(encrypt('Lets try a longer message.', '01234567', 'des'), 'hex');
+ERROR: encrypt error: Cipher cannot be initialized ?
+select decrypt(encrypt('Lets try a longer message.', '01234567', 'des'), '01234567', 'des');
+ERROR: encrypt error: Cipher cannot be initialized ?
diff --git a/contrib/pgcrypto/expected/pgp-decrypt_1.out b/contrib/pgcrypto/expected/pgp-decrypt_1.out
new file mode 100644
index 0000000000..63d5ab9865
--- /dev/null
+++ b/contrib/pgcrypto/expected/pgp-decrypt_1.out
@@ -0,0 +1,421 @@
+--
+-- pgp decrypt tests
+--
+-- Checking ciphers
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.blowfish.sha1.mdc.s2k3.z0
+
+jA0EBAMCfFNwxnvodX9g0jwB4n4s26/g5VmKzVab1bX1SmwY7gvgvlWdF3jKisvS
+yA6Ce1QTMK3KdL2MPfamsTUSAML8huCJMwYQFfE=
+=JcP+
+-----END PGP MESSAGE-----
+'), 'foobar');
+ERROR: Wrong key or corrupt data
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.sha1.mdc.s2k3.z0
+
+jA0EBwMCci97v0Q6Z0Zg0kQBsVf5Oe3iC+FBzUmuMV9KxmAyOMyjCc/5i8f1Eest
+UTAsG35A1vYs02VARKzGz6xI2UHwFUirP+brPBg3Ee7muOx8pA==
+=XtrP
+-----END PGP MESSAGE-----
+'), 'foobar');
+ pgp_sym_decrypt
+-----------------
+ Secret message.
+(1 row)
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes192.sha1.mdc.s2k3.z0
+
+jA0ECAMCI7YQpWqp3D1g0kQBCjB7GlX7+SQeXNleXeXQ78ZAPNliquGDq9u378zI
+5FPTqAhIB2/2fjY8QEIs1ai00qphjX2NitxV/3Wn+6dufB4Q4g==
+=rCZt
+-----END PGP MESSAGE-----
+'), 'foobar');
+ pgp_sym_decrypt
+-----------------
+ Secret message.
+(1 row)
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes256.sha1.mdc.s2k3.z0
+
+jA0ECQMC4f/5djqCC1Rg0kQBTHEPsD+Sw7biBsM2er3vKyGPAQkuTBGKC5ie7hT/
+lceMfQdbAg6oTFyJpk/wH18GzRDphCofg0X8uLgkAKMrpcmgog==
+=fB6S
+-----END PGP MESSAGE-----
+'), 'foobar');
+ pgp_sym_decrypt
+-----------------
+ Secret message.
+(1 row)
+
+-- Checking MDC modes
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.sha1.nomdc.s2k3.z0
+
+jA0EBwMCnv07rlXqWctgyS2Dm2JfOKCRL4sLSLJUC8RS2cH7cIhKSuLitOtyquB+
+u9YkgfJfsuRJmgQ9tmo=
+=60ui
+-----END PGP MESSAGE-----
+'), 'foobar');
+ pgp_sym_decrypt
+-----------------
+ Secret message.
+(1 row)
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.sha1.mdc.s2k3.z0
+
+jA0EBwMCEeP3idNjQ1Bg0kQBf4G0wX+2QNzLh2YNwYkQgQkfYhn/hLXjV4nK9nsE
+8Ex1Dsdt5UPvOz8W8VKQRS6loOfOe+yyXil8W3IYFwUpdDUi+Q==
+=moGf
+-----END PGP MESSAGE-----
+'), 'foobar');
+ pgp_sym_decrypt
+-----------------
+ Secret message.
+(1 row)
+
+-- Checking hashes
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.md5.mdc.s2k3.z0
+
+jA0EBwMClrXXtOXetohg0kQBn0Kl1ymevQZRHkdoYRHgzCwSQEiss7zYff2UNzgO
+KyRrHf7zEBuZiZ2AG34jNVMOLToj1jJUg5zTSdecUzQVCykWTA==
+=NyLk
+-----END PGP MESSAGE-----
+'), 'foobar');
+ pgp_sym_decrypt
+-----------------
+ Secret message.
+(1 row)
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.sha1.mdc.s2k3.z0
+
+jA0EBwMCApbdlrURoWJg0kQBzHM/E0o7djY82bNuspjxjAcPFrrtp0uvDdMQ4z2m
+/PM8jhgI5vxFYfNQjLl8y3fHYIomk9YflN9K/Q13iq8A8sjeTw==
+=FxbQ
+-----END PGP MESSAGE-----
+'), 'foobar');
+ pgp_sym_decrypt
+-----------------
+ Secret message.
+(1 row)
+
+-- Checking S2K modes
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.sha1.mdc.s2k0.z0
+
+jAQEBwAC0kQBKTaLAKE3xzps+QIZowqRNb2eAdzBw2LxEW2YD5PgNlbhJdGg+dvw
+Ah9GXjGS1TVALzTImJbz1uHUZRfhJlFbc5yGQw==
+=YvkV
+-----END PGP MESSAGE-----
+'), 'foobar');
+ pgp_sym_decrypt
+-----------------
+ Secret message.
+(1 row)
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.sha1.mdc.s2k1.z0
+
+jAwEBwEC/QTByBLI3b/SRAHPxKzI6SZBo5lAEOD+EsvKQWO4adL9tDY+++Iqy1xK
+4IaWXVKEj9R2Lr2xntWWMGZtcKtjD2lFFRXXd9dZp1ZThNDz
+=dbXm
+-----END PGP MESSAGE-----
+'), 'foobar');
+ pgp_sym_decrypt
+-----------------
+ Secret message.
+(1 row)
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.sha1.mdc.s2k3.z0
+
+jA0EBwMCEq4Su3ZqNEJg0kQB4QG5jBTKF0i04xtH+avzmLhstBNRxvV3nsmB3cwl
+z+9ZaA/XdSx5ZiFnMym8P6r8uY9rLjjNptvvRHlxIReF+p9MNg==
+=VJKg
+-----END PGP MESSAGE-----
+'), 'foobar');
+ pgp_sym_decrypt
+-----------------
+ Secret message.
+(1 row)
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes192.sha1.mdc.s2k0.z0
+
+jAQECAAC0kQBBDnQWkgsx9YFaqDfWmpsiyAJ6y2xG/sBvap1dySYEMuZ+wJTXQ9E
+Cr3i2M7TgVZ0M4jp4QL0adG1lpN5iK7aQeOwMw==
+=cg+i
+-----END PGP MESSAGE-----
+'), 'foobar');
+ pgp_sym_decrypt
+-----------------
+ Secret message.
+(1 row)
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes192.sha1.mdc.s2k1.z0
+
+jAwECAECruOfyNDFiTnSRAEVoGXm4A9UZKkWljdzjEO/iaE7mIraltIpQMkiqCh9
+7h8uZ2u9uRBOv222fZodGvc6bvq/4R4hAa/6qSHtm8mdmvGt
+=aHmC
+-----END PGP MESSAGE-----
+'), 'foobar');
+ pgp_sym_decrypt
+-----------------
+ Secret message.
+(1 row)
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes192.sha1.mdc.s2k3.z0
+
+jA0ECAMCjFn6SRi3SONg0kQBqtSHPaD0m7rXfDAhCWU/ypAsI93GuHGRyM99cvMv
+q6eF6859ZVnli3BFSDSk3a4e/pXhglxmDYCfjAXkozKNYLo6yw==
+=K0LS
+-----END PGP MESSAGE-----
+'), 'foobar');
+ pgp_sym_decrypt
+-----------------
+ Secret message.
+(1 row)
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes256.sha1.mdc.s2k0.z0
+
+jAQECQAC0kQB4L1eMbani07XF2ZYiXNK9LW3v8w41oUPl7dStmrJPQFwsdxmrDHu
+rQr3WbdKdY9ufjOE5+mXI+EFkSPrF9rL9NCq6w==
+=RGts
+-----END PGP MESSAGE-----
+'), 'foobar');
+ pgp_sym_decrypt
+-----------------
+ Secret message.
+(1 row)
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes256.sha1.mdc.s2k1.z0
+
+jAwECQECKHhrou7ZOIXSRAHWIVP+xjVQcjAVBTt+qh9SNzYe248xFTwozkwev3mO
++KVJW0qhk0An+Y2KF99/bYFl9cL5D3Tl43fC8fXGl3x3m7pR
+=SUrU
+-----END PGP MESSAGE-----
+'), 'foobar');
+ pgp_sym_decrypt
+-----------------
+ Secret message.
+(1 row)
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes256.sha1.mdc.s2k3.z0
+
+jA0ECQMCjc8lwZu8Fz1g0kQBkEzjImi21liep5jj+3dAJ2aZFfUkohi8b3n9z+7+
+4+NRzL7cMW2RLAFnJbiqXDlRHMwleeuLN1up2WIxsxtYYuaBjA==
+=XZrG
+-----END PGP MESSAGE-----
+'), 'foobar');
+ pgp_sym_decrypt
+-----------------
+ Secret message.
+(1 row)
+
+-- Checking longer passwords
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.sha1.mdc.s2k3.z0
+
+jA0EBwMCx6dBiuqrYNRg0kQBEo63AvA1SCslxP7ayanLf1H0/hlk2nONVhTwVEWi
+tTGup1mMz6Cfh1uDRErUuXpx9A0gdMu7zX0o5XjrL7WGDAZdSw==
+=XKKG
+-----END PGP MESSAGE-----
+'), '0123456789abcdefghij');
+ pgp_sym_decrypt
+-----------------
+ Secret message.
+(1 row)
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.sha1.mdc.s2k3.z0
+
+jA0EBwMCBDvYuS990iFg0kQBW31UK5OiCjWf5x6KJ8qNNT2HZWQCjCBZMU0XsOC6
+CMxFKadf144H/vpoV9GA0f22keQgCl0EsTE4V4lweVOPTKCMJg==
+=gWDh
+-----END PGP MESSAGE-----
+'), '0123456789abcdefghij2jk4h5g2j54khg23h54g2kh54g2khj54g23hj54');
+ pgp_sym_decrypt
+-----------------
+ Secret message.
+(1 row)
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.sha1.mdc.s2k3.z0
+
+jA0EBwMCqXbFafC+ofVg0kQBejyiPqH0QMERVGfmPOjtAxvyG5KDIJPYojTgVSDt
+FwsDabdQUz5O7bgNSnxfmyw1OifGF+W2bIn/8W+0rDf8u3+O+Q==
+=OxOF
+-----END PGP MESSAGE-----
+'), 'x');
+ pgp_sym_decrypt
+-----------------
+ Secret message.
+(1 row)
+
+-- Checking various data
+select encode(digest(pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.sha1.mdc.s2k3.z0
+
+jA0EBwMCGJ+SpuOysINg0kQBJfSjzsW0x4OVcAyr17O7FBvMTwIGeGcJd99oTQU8
+Xtx3kDqnhUq9Z1fS3qPbi5iNP2A9NxOBxPWz2JzxhydANlgbxg==
+=W/ik
+-----END PGP MESSAGE-----
+'), '0123456789abcdefghij'), 'sha1'), 'hex');
+ encode
+------------------------------------------
+ 0225e3ede6f2587b076d021a189ff60aad67e066
+(1 row)
+
+-- expected: 0225e3ede6f2587b076d021a189ff60aad67e066
+select encode(digest(pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat2.aes.sha1.mdc.s2k3.z0
+
+jA0EBwMCvdpDvidNzMxg0jUBvj8eS2+1t/9/zgemxvhtc0fvdKGGbjH7dleaTJRB
+SaV9L04ky1qECNDx3XjnoKLC+H7IOQ==
+=Fxen
+-----END PGP MESSAGE-----
+'), '0123456789abcdefghij'), 'sha1'), 'hex');
+ encode
+------------------------------------------
+ da39a3ee5e6b4b0d3255bfef95601890afd80709
+(1 row)
+
+-- expected: da39a3ee5e6b4b0d3255bfef95601890afd80709
+select encode(digest(pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat3.aes.sha1.mdc.s2k3.z0
+
+jA0EBwMCxQvxJZ3G/HRg0lgBeYmTa7/uDAjPyFwSX4CYBgpZWVn/JS8JzILrcWF8
+gFnkUKIE0PSaYFp+Yi1VlRfUtRQ/X/LYNGa7tWZS+4VQajz2Xtz4vUeAEiYFYPXk
+73Hb8m1yRhQK
+=ivrD
+-----END PGP MESSAGE-----
+'), '0123456789abcdefghij'), 'sha1'), 'hex');
+ encode
+------------------------------------------
+ 5e5c135efc0dd00633efc6dfd6e731ea408a5b4c
+(1 row)
+
+-- expected: 5e5c135efc0dd00633efc6dfd6e731ea408a5b4c
+-- Checking CRLF
+select encode(digest(pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: crlf mess
+
+ww0ECQMCt7VAtby6l4Bi0lgB5KMIZiiF/b3CfMfUyY0eDncsGXtkbu1X+l9brjpMP8eJnY79Amms
+a3nsOzKTXUfS9VyaXo8IrncM6n7fdaXpwba/3tNsAhJG4lDv1k4g9v8Ix2dfv6Rs
+=mBP9
+-----END PGP MESSAGE-----
+'), 'key', 'convert-crlf=0'), 'sha1'), 'hex');
+ encode
+------------------------------------------
+ 9353062be7720f1446d30b9e75573a4833886784
+(1 row)
+
+-- expected: 9353062be7720f1446d30b9e75573a4833886784
+select encode(digest(pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: crlf mess
+
+ww0ECQMCt7VAtby6l4Bi0lgB5KMIZiiF/b3CfMfUyY0eDncsGXtkbu1X+l9brjpMP8eJnY79Amms
+a3nsOzKTXUfS9VyaXo8IrncM6n7fdaXpwba/3tNsAhJG4lDv1k4g9v8Ix2dfv6Rs
+=mBP9
+-----END PGP MESSAGE-----
+'), 'key', 'convert-crlf=1'), 'sha1'), 'hex');
+ encode
+------------------------------------------
+ 7efefcab38467f7484d6fa43dc86cf5281bd78e2
+(1 row)
+
+-- expected: 7efefcab38467f7484d6fa43dc86cf5281bd78e2
+-- check BUG #11905, problem with messages 6 less than a power of 2.
+select pgp_sym_decrypt(pgp_sym_encrypt(repeat('x',65530),'1'),'1') = repeat('x',65530);
+ ?column?
+----------
+ t
+(1 row)
+
+-- expected: true
+-- Negative tests
+-- Decryption with a certain incorrect key yields an apparent Literal Data
+-- packet reporting its content to be binary data. Ciphertext source:
+-- iterative pgp_sym_encrypt('secret', 'key') until the random prefix gave
+-- rise to that property.
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+
+ww0EBwMCxf8PTrQBmJdl0jcB6y2joE7GSLKRv7trbNsF5Z8ou5NISLUg31llVH/S0B2wl4bvzZjV
+VsxxqLSPzNLAeIspJk5G
+=mSd/
+-----END PGP MESSAGE-----
+'), 'wrong-key', 'debug=1');
+NOTICE: dbg: prefix_init: corrupt prefix
+NOTICE: dbg: parse_literal_data: data type=b
+NOTICE: dbg: mdcbuf_finish: bad MDC pkt hdr
+ERROR: Wrong key or corrupt data
+-- Routine text/binary mismatch.
+select pgp_sym_decrypt(pgp_sym_encrypt_bytea('P', 'key'), 'key', 'debug=1');
+NOTICE: dbg: parse_literal_data: data type=b
+ERROR: Not text data
+-- Decryption with a certain incorrect key yields an apparent BZip2-compressed
+-- plaintext. Ciphertext source: iterative pgp_sym_encrypt('secret', 'key')
+-- until the random prefix gave rise to that property.
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+
+ww0EBwMC9rK/dMkF5Zlt0jcBlzAQ1mQY2qYbKYbw8h3EZ5Jk0K2IiY92R82TRhWzBIF/8cmXDPtP
+GXsd65oYJZp3Khz0qfyn
+=Nmpq
+-----END PGP MESSAGE-----
+'), 'wrong-key', 'debug=1');
+NOTICE: dbg: prefix_init: corrupt prefix
+NOTICE: dbg: parse_compressed_data: bzip2 unsupported
+NOTICE: dbg: mdcbuf_finish: bad MDC pkt hdr
+ERROR: Wrong key or corrupt data
+-- Routine use of BZip2 compression. Ciphertext source:
+-- echo x | gpg --homedir /nonexistent --personal-compress-preferences bzip2 \
+-- --personal-cipher-preferences aes --no-emit-version --batch \
+-- --symmetric --passphrase key --armor
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+
+jA0EBwMCRhFrAKNcLVJg0mMBLJG1cCASNk/x/3dt1zJ+2eo7jHfjgg3N6wpB3XIe
+QCwkWJwlBG5pzbO5gu7xuPQN+TbPJ7aQ2sLx3bAHhtYb0i3vV9RO10Gw++yUyd4R
+UCAAw2JRIISttRHMfDpDuZJpvYo=
+=AZ9M
+-----END PGP MESSAGE-----
+'), 'key', 'debug=1');
+NOTICE: dbg: parse_compressed_data: bzip2 unsupported
+ERROR: Unsupported compression algorithm
diff --git a/contrib/pgcrypto/expected/pgp-pubkey-decrypt_1.out b/contrib/pgcrypto/expected/pgp-pubkey-decrypt_1.out
new file mode 100644
index 0000000000..f41c6c9893
--- /dev/null
+++ b/contrib/pgcrypto/expected/pgp-pubkey-decrypt_1.out
@@ -0,0 +1,652 @@
+--
+-- PGP Public Key Encryption
+--
+-- As most of the low-level stuff is tested in symmetric key
+-- tests, here's only public-key specific tests
+create table keytbl (
+ id int4,
+ name text,
+ pubkey text,
+ seckey text
+);
+create table encdata (
+ id int4,
+ data text
+);
+insert into keytbl (id, name, pubkey, seckey)
+values (1, 'elg1024', '
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+mQGiBELIIUgRBACp401L6jXrLB28c3YA4sM3OJKnxM1GT9YTkWyE3Vyte65H8WU9
+tGPBX7OMuaX5eGZ84LFUGvaP0k7anfmXcDkCO3P9GgL+ro/dS2Ps/vChQPZqHaxE
+xpKDUt47B7DGdRJrC8DRnIR4wbSyQA6ma3S1yFqC5pJhSs+mqf9eExOjiwCgntth
+klRxIYw352ZX9Ov9oht/p/ED/1Xi4PS+tkXVvyIw5aZfa61bT6XvDkoPI0Aj3GE5
+YmCHJlKA/IhEr8QJOLV++5VEv4l6KQ1/DFoJzoNdr1AGJukgTc6X/WcQRzfQtUic
+PHQme5oAWoHa6bVQZOwvbJh3mOXDq/Tk/KF22go8maM44vMn4bvv+SBbslviYLiL
+jZJ1A/9JXF1esNq+X9HehJyqHHU7LEEf/ck6zC7o2erM3/LZlZuLNPD2cv3oL3Nv
+saEgcTSZl+8XmO8pLmzjKIb+hi70qVx3t2IhMqbb4B/dMY1Ck62gPBKa81/Wwi7v
+IsEBQLEtyBmGmI64YpzoRNFeaaF9JY+sAKqROqe6dLjJ7vebQLQfRWxnYW1hbCAx
+MDI0IDx0ZXN0QGV4YW1wbGUub3JnPoheBBMRAgAeBQJCyCFIAhsDBgsJCAcDAgMV
+AgMDFgIBAh4BAheAAAoJEBwpvA0YF3NkOtsAniI9W2bC3CxARTpYrev7ihreDzFc
+AJ9WYLQxDQAi5Ec9AQoodPkIagzZ4LkBDQRCyCFKEAQAh5SNbbJMAsJ+sQbcWEzd
+ku8AdYB5zY7Qyf9EOvn0g39bzANhxmmb6gbRlQN0ioymlDwraTKUAfuCZgNcg/0P
+sxFGb9nDcvjIV8qdVpnq1PuzMFuBbmGI6weg7Pj01dlPiO0wt1lLX+SubktqbYxI
++h31c3RDZqxj+KAgxR8YNGMAAwYD+wQs2He1Z5+p4OSgMERiNzF0acZUYmc0e+/9
+6gfL0ft3IP+SSFo6hEBrkKVhZKoPSSRr5KpNaEobhdxsnKjUaw/qyoaFcNMzb4sF
+k8wq5UlCkR+h72u6hv8FuleCV8SJUT1U2JjtlXJR2Pey9ifh8rZfu57UbdwdHa0v
+iWc4DilhiEkEGBECAAkFAkLIIUoCGwwACgkQHCm8DRgXc2TtrwCfdPom+HlNVE9F
+ig3hGY1Rb4NEk1gAn1u9IuQB+BgDP40YHHz6bKWS/x80
+=RWci
+-----END PGP PUBLIC KEY BLOCK-----
+', '
+-----BEGIN PGP PRIVATE KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+lQG7BELIIUgRBACp401L6jXrLB28c3YA4sM3OJKnxM1GT9YTkWyE3Vyte65H8WU9
+tGPBX7OMuaX5eGZ84LFUGvaP0k7anfmXcDkCO3P9GgL+ro/dS2Ps/vChQPZqHaxE
+xpKDUt47B7DGdRJrC8DRnIR4wbSyQA6ma3S1yFqC5pJhSs+mqf9eExOjiwCgntth
+klRxIYw352ZX9Ov9oht/p/ED/1Xi4PS+tkXVvyIw5aZfa61bT6XvDkoPI0Aj3GE5
+YmCHJlKA/IhEr8QJOLV++5VEv4l6KQ1/DFoJzoNdr1AGJukgTc6X/WcQRzfQtUic
+PHQme5oAWoHa6bVQZOwvbJh3mOXDq/Tk/KF22go8maM44vMn4bvv+SBbslviYLiL
+jZJ1A/9JXF1esNq+X9HehJyqHHU7LEEf/ck6zC7o2erM3/LZlZuLNPD2cv3oL3Nv
+saEgcTSZl+8XmO8pLmzjKIb+hi70qVx3t2IhMqbb4B/dMY1Ck62gPBKa81/Wwi7v
+IsEBQLEtyBmGmI64YpzoRNFeaaF9JY+sAKqROqe6dLjJ7vebQAAAnj4i4st+s+C6
+WKTIDcL1Iy0Saq8lCp60H0VsZ2FtYWwgMTAyNCA8dGVzdEBleGFtcGxlLm9yZz6I
+XgQTEQIAHgUCQsghSAIbAwYLCQgHAwIDFQIDAxYCAQIeAQIXgAAKCRAcKbwNGBdz
+ZDrbAJ9cp6AsjOhiLxwznsMJheGf4xkH8wCfUPjMCLm4tAEnyYn2hDNt7CB8B6Kd
+ATEEQsghShAEAIeUjW2yTALCfrEG3FhM3ZLvAHWAec2O0Mn/RDr59IN/W8wDYcZp
+m+oG0ZUDdIqMppQ8K2kylAH7gmYDXIP9D7MRRm/Zw3L4yFfKnVaZ6tT7szBbgW5h
+iOsHoOz49NXZT4jtMLdZS1/krm5Lam2MSPod9XN0Q2asY/igIMUfGDRjAAMGA/sE
+LNh3tWefqeDkoDBEYjcxdGnGVGJnNHvv/eoHy9H7dyD/kkhaOoRAa5ClYWSqD0kk
+a+SqTWhKG4XcbJyo1GsP6sqGhXDTM2+LBZPMKuVJQpEfoe9ruob/BbpXglfEiVE9
+VNiY7ZVyUdj3svYn4fK2X7ue1G3cHR2tL4lnOA4pYQAA9030E4u2ZKOfJBpUM+EM
+m9VmsGjaQZV4teB0R/q3W8sRIYhJBBgRAgAJBQJCyCFKAhsMAAoJEBwpvA0YF3Nk
+7a8AniFFotw1x2X+oryu3Q3nNtmxoKHpAJ9HU7jw7ydg33dI9J8gVkrmsSZ2/w==
+=nvqq
+-----END PGP PRIVATE KEY BLOCK-----
+');
+insert into keytbl (id, name, pubkey, seckey)
+values (2, 'elg2048', '
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+mQGiBELIIgoRBAC1onBpxKYgDvrgCaUWPY34947X3ogxGOfCN0p6Eqrx+2PUhm4n
+vFvmczpMT4iDc0mUO+iwnwsEkXQI1eC99g8c0jnZAvzJZ5miAHL8hukMAMfDkYke
+5aVvcPPc8uPDlItpszGmH0rM0V9TIt/i9QEXetpyNWhk4jj5qnohYhLeZwCgkOdO
+RFAdNi4vfFPivvtAp2ffjU8D/R3x/UJCvkzi7i9rQHGo313xxmQu5BuqIjANBUij
+8IE7LRPI/Qhg2hYy3sTJwImDi7VkS+fuvNVk0d6MTWplAXYU96bn12JaD21R9sKl
+Fzcc+0iZI1wYA1PczisUkoTISE+dQFUsoGHfpDLhoBuesXQrhBavI8t8VPd+nkdt
+J+oKA/9iRQ87FzxdYTkh2drrv69FZHc3Frsjw9nPcBq/voAvXH0MRilqyCg7HpW/
+T9naeOERksa+Rj4R57IF1l4e5oiiGJo9QmaKZcsCsXrREJCycrlEtMqXfSPy+bi5
+0yDZE/Qm1dwu13+OXOsRvkoNYjO8Mzo9K8wU12hMqN0a2bu6a7QjRWxnYW1hbCAy
+MDQ4IDx0ZXN0MjA0OEBleGFtcGxlLm9yZz6IXgQTEQIAHgUCQsgiCgIbAwYLCQgH
+AwIDFQIDAxYCAQIeAQIXgAAKCRBI6c1W/qZo29PDAKCG724enIxRog1j+aeCp/uq
+or6mbwCePuKy2/1kD1FvnhkZ/R5fpm+pdm25Ag0EQsgiIhAIAJI3Gb2Ehtz1taQ9
+AhPY4Avad2BsqD3S5X/R11Cm0KBE/04D29dxn3f8QfxDsexYvNIZjoJPBqqZ7iMX
+MhoWyw8ZF5Zs1mLIjFGVorePrm94N3MNPWM7x9M36bHUjx0vCZKFIhcGY1g+htE/
+QweaJzNVeA5z4qZmik41FbQyQSyHa3bOkTZu++/U6ghP+iDp5UDBjMTkVyqITUVN
+gC+MR+da/I60irBVhue7younh4ovF+CrVDQJC06HZl6CAJJyA81SmRfi+dmKbbjZ
+LF6rhz0norPjISJvkIqvdtM4VPBKI5wpgwCzpEqjuiKrAVujRT68zvBvJ4aVqb11
+k5QdJscAAwUH/jVJh0HbWAoiFTe+NvohfrA8vPcD0rtU3Y+siiqrabotnxJd2NuC
+bxghJYGfNtnx0KDjFbCRKJVeTFok4UnuVYhXdH/c6i0/rCTNdeW2D6pmR4GfBozR
+Pw/ARf+jONawGLyUj7uq13iquwMSE7VyNuF3ycL2OxXjgOWMjkH8c+zfHHpjaZ0R
+QsetMq/iNBWraayKZnWUd+eQqNzE+NUo7w1jAu7oDpy+8a1eipxzK+O0HfU5LTiF
+Z1Oe4Um0P2l3Xtx8nEgj4vSeoEkl2qunfGW00ZMMTCWabg0ZgxPzMfMeIcm6525A
+Yn2qL+X/qBJTInAl7/hgPz2D1Yd7d5/RdWaISQQYEQIACQUCQsgiIgIbDAAKCRBI
+6c1W/qZo25ZSAJ98WTrtl2HiX8ZqZq95v1+9cHtZPQCfZDoWQPybkNescLmXC7q5
+1kNTmEU=
+=8QM5
+-----END PGP PUBLIC KEY BLOCK-----
+', '
+-----BEGIN PGP PRIVATE KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+lQG7BELIIgoRBAC1onBpxKYgDvrgCaUWPY34947X3ogxGOfCN0p6Eqrx+2PUhm4n
+vFvmczpMT4iDc0mUO+iwnwsEkXQI1eC99g8c0jnZAvzJZ5miAHL8hukMAMfDkYke
+5aVvcPPc8uPDlItpszGmH0rM0V9TIt/i9QEXetpyNWhk4jj5qnohYhLeZwCgkOdO
+RFAdNi4vfFPivvtAp2ffjU8D/R3x/UJCvkzi7i9rQHGo313xxmQu5BuqIjANBUij
+8IE7LRPI/Qhg2hYy3sTJwImDi7VkS+fuvNVk0d6MTWplAXYU96bn12JaD21R9sKl
+Fzcc+0iZI1wYA1PczisUkoTISE+dQFUsoGHfpDLhoBuesXQrhBavI8t8VPd+nkdt
+J+oKA/9iRQ87FzxdYTkh2drrv69FZHc3Frsjw9nPcBq/voAvXH0MRilqyCg7HpW/
+T9naeOERksa+Rj4R57IF1l4e5oiiGJo9QmaKZcsCsXrREJCycrlEtMqXfSPy+bi5
+0yDZE/Qm1dwu13+OXOsRvkoNYjO8Mzo9K8wU12hMqN0a2bu6awAAn2F+iNBElfJS
+8azqO/kEiIfpqu6/DQG0I0VsZ2FtYWwgMjA0OCA8dGVzdDIwNDhAZXhhbXBsZS5v
+cmc+iF0EExECAB4FAkLIIgoCGwMGCwkIBwMCAxUCAwMWAgECHgECF4AACgkQSOnN
+Vv6maNvTwwCYkpcJmpl3aHCQdGomz7dFohDgjgCgiThZt2xTEi6GhBB1vuhk+f55
+n3+dAj0EQsgiIhAIAJI3Gb2Ehtz1taQ9AhPY4Avad2BsqD3S5X/R11Cm0KBE/04D
+29dxn3f8QfxDsexYvNIZjoJPBqqZ7iMXMhoWyw8ZF5Zs1mLIjFGVorePrm94N3MN
+PWM7x9M36bHUjx0vCZKFIhcGY1g+htE/QweaJzNVeA5z4qZmik41FbQyQSyHa3bO
+kTZu++/U6ghP+iDp5UDBjMTkVyqITUVNgC+MR+da/I60irBVhue7younh4ovF+Cr
+VDQJC06HZl6CAJJyA81SmRfi+dmKbbjZLF6rhz0norPjISJvkIqvdtM4VPBKI5wp
+gwCzpEqjuiKrAVujRT68zvBvJ4aVqb11k5QdJscAAwUH/jVJh0HbWAoiFTe+Nvoh
+frA8vPcD0rtU3Y+siiqrabotnxJd2NuCbxghJYGfNtnx0KDjFbCRKJVeTFok4Unu
+VYhXdH/c6i0/rCTNdeW2D6pmR4GfBozRPw/ARf+jONawGLyUj7uq13iquwMSE7Vy
+NuF3ycL2OxXjgOWMjkH8c+zfHHpjaZ0RQsetMq/iNBWraayKZnWUd+eQqNzE+NUo
+7w1jAu7oDpy+8a1eipxzK+O0HfU5LTiFZ1Oe4Um0P2l3Xtx8nEgj4vSeoEkl2qun
+fGW00ZMMTCWabg0ZgxPzMfMeIcm6525AYn2qL+X/qBJTInAl7/hgPz2D1Yd7d5/R
+dWYAAVQKFPXbRaxbdArwRVXMzSD3qj/+VwwhwEDt8zmBGnlBfwVdkjQQrDUMmV1S
+EwyISQQYEQIACQUCQsgiIgIbDAAKCRBI6c1W/qZo25ZSAJ4sgUfHTVsG/x3p3fcM
+3b5R86qKEACggYKSwPWCs0YVRHOWqZY0pnHtLH8=
+=3Dgk
+-----END PGP PRIVATE KEY BLOCK-----
+');
+insert into keytbl (id, name, pubkey, seckey)
+values (3, 'elg4096', '
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+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
+=kRxT
+-----END PGP PUBLIC KEY BLOCK-----
+', '
+-----BEGIN PGP PRIVATE KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+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
+=Gjq6
+-----END PGP PRIVATE KEY BLOCK-----
+');
+insert into keytbl (id, name, pubkey, seckey)
+values (4, 'rsa2048', '
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+mQELBELIJbEBCADAIdtcoLAmQfl8pb73pPRuEYx8qW9klLfCGG5A4OUOi00JHNwP
+ZaABe1PGzjoeXrgM1MTQZhoZu1Vdg+KDI6XAtiy9P6bLg7ntsXksD4wBoIKtQKc2
+55pdukxTiu+xeJJG2q8ZZPOp97CV9fbQ9vPCwgnuSsDCoQlibZikDVPAyVTvp7Jx
+5rz8yXsl4sxvaeMZPqqFPtA/ENeQ3cpsyR1BQXSvoZpH1Fq0b8GcZTEdWWD/w6/K
+MCRC8TmgEd+z3e8kIsCwFQ+TSHbCcxRWdgZE7gE31sJHHVkrZlXtLU8MPXWqslVz
+R0cX+yC8j6bXI6/BqZ2SvRndJwuunRAr4um7AAYptB5SU0EgMjA0OCA8cnNhMjA0
+OEBleGFtcGxlLm9yZz6JATQEEwECAB4FAkLIJbECGwMGCwkIBwMCAxUCAwMWAgEC
+HgECF4AACgkQnc+OnJvTHyQqHwf8DtzuAGmObfe3ggtn14x2wnU1Nigebe1K5liR
+nrLuVlLBpdO6CWmMUzfKRvyZlx54GlA9uUQSjW+RlgejdOTQqesDrcTEukYd4yzw
+bLZyM5Gb3lsE/FEmE7Dxw/0Utf59uACqzG8LACQn9J6sEgZWKxAupuYTHXd12lDP
+D3dnU4uzKPhMcjnSN00pzjusP7C9NZd3OLkAx2vw/dmb4Q+/QxeZhVYYsAUuR2hv
+9bgGWopumlOkt8Zu5YG6+CtTbJXprPI7pJ1jHbeE+q/29hWJQtS8Abx82AcOkzhv
+S3NZKoJ/1DrGgoDAu1mGkM4KvLAxfDs/qQ9dZhtEmDbKPLTVEA==
+=lR4n
+-----END PGP PUBLIC KEY BLOCK-----
+', '
+-----BEGIN PGP PRIVATE KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+lQOWBELIJbEBCADAIdtcoLAmQfl8pb73pPRuEYx8qW9klLfCGG5A4OUOi00JHNwP
+ZaABe1PGzjoeXrgM1MTQZhoZu1Vdg+KDI6XAtiy9P6bLg7ntsXksD4wBoIKtQKc2
+55pdukxTiu+xeJJG2q8ZZPOp97CV9fbQ9vPCwgnuSsDCoQlibZikDVPAyVTvp7Jx
+5rz8yXsl4sxvaeMZPqqFPtA/ENeQ3cpsyR1BQXSvoZpH1Fq0b8GcZTEdWWD/w6/K
+MCRC8TmgEd+z3e8kIsCwFQ+TSHbCcxRWdgZE7gE31sJHHVkrZlXtLU8MPXWqslVz
+R0cX+yC8j6bXI6/BqZ2SvRndJwuunRAr4um7AAYpAAf/QZsrrz0c7dgWwGqMIpw6
+fP+/lLa74+fa2CFRWtYowEiKsfDg/wN7Ua07036dNhPa8aZPsU6SRzm5PybKOURe
+D9pNt0FxJkX0j5pCWfjSJgTbc1rCdqZ/oyBk/U6pQtf//zfw3PbDl7I8TC6GOt2w
+5NgcXdsWHP7LAmPctOVUyzFsenevR0MFTHkMbmKI1HpFm8XN/e1Fl+qIAD+OagTF
+5B32VvpoJtkh5nxnIuToNJsa9Iy7F9MM2CeFOyTMihMcjXKBBUaAYoF115irBvqu
+7N/qWmzqLg8yxBZ56mh6meCF3+67VA2y7fL8rhw2QuqgLg1JFlKAVL+9crCSrn//
+GQQA1kT7FytW6BNOffblFYZkrJer3icoRDqa/ljgH/yVaWoVT1igy0E9XzYO7MwP
+2usj/resLy0NC1qCthk51cZ/wthooMl88e5Wb4l5FYwBEac7muSBTo4W8cAH1hFj
+TWL6XAGvEzGX3Mt9pn8uYGlQLZAhJoNCAU2EOCbN1PchDvsEAOWNKYesuUVk8+sQ
+St0NDNhd9BWtTWTHkCZb1dKC3JTfr9PqkTBLrWFbYjkOtvdPAW7FDaXXXZfdH1jH
+WfwP3Q+I6sqgSaWpCS4dBAns3/RVtO7czVgyIwma04iIvJqderYrfvkUq95KfwP2
+V8wXkhrPPPxyrg5y3wQlpY2jb5RBBAC17SK1ms+DBtck4vpdjp3SJ32SbyC/DU30
+89Q12j74S7Zdu1qZlKnvy3kWPYX/hMuSzGZ+mLVJNFEqH2X01aFzppYz0hdI9PGB
+9tTFEqZWQL9ZkXfjc79Cgnt12pNukRbtw0N/kyutOdIFHVT79wVAd+powqziXJsC
+Kc+4xjwSCkZitB5SU0EgMjA0OCA8cnNhMjA0OEBleGFtcGxlLm9yZz6JATQEEwEC
+AB4FAkLIJbECGwMGCwkIBwMCAxUCAwMWAgECHgECF4AACgkQnc+OnJvTHyQqHwf8
+DtzuAGmObfe3ggtn14x2wnU1Nigebe1K5liRnrLuVlLBpdO6CWmMUzfKRvyZlx54
+GlA9uUQSjW+RlgejdOTQqesDrcTEukYd4yzwbLZyM5Gb3lsE/FEmE7Dxw/0Utf59
+uACqzG8LACQn9J6sEgZWKxAupuYTHXd12lDPD3dnU4uzKPhMcjnSN00pzjusP7C9
+NZd3OLkAx2vw/dmb4Q+/QxeZhVYYsAUuR2hv9bgGWopumlOkt8Zu5YG6+CtTbJXp
+rPI7pJ1jHbeE+q/29hWJQtS8Abx82AcOkzhvS3NZKoJ/1DrGgoDAu1mGkM4KvLAx
+fDs/qQ9dZhtEmDbKPLTVEA==
+=WKAv
+-----END PGP PRIVATE KEY BLOCK-----
+');
+insert into keytbl (id, name, pubkey, seckey)
+values (5, 'psw-elg1024', '
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+mQGiBELIIUgRBACp401L6jXrLB28c3YA4sM3OJKnxM1GT9YTkWyE3Vyte65H8WU9
+tGPBX7OMuaX5eGZ84LFUGvaP0k7anfmXcDkCO3P9GgL+ro/dS2Ps/vChQPZqHaxE
+xpKDUt47B7DGdRJrC8DRnIR4wbSyQA6ma3S1yFqC5pJhSs+mqf9eExOjiwCgntth
+klRxIYw352ZX9Ov9oht/p/ED/1Xi4PS+tkXVvyIw5aZfa61bT6XvDkoPI0Aj3GE5
+YmCHJlKA/IhEr8QJOLV++5VEv4l6KQ1/DFoJzoNdr1AGJukgTc6X/WcQRzfQtUic
+PHQme5oAWoHa6bVQZOwvbJh3mOXDq/Tk/KF22go8maM44vMn4bvv+SBbslviYLiL
+jZJ1A/9JXF1esNq+X9HehJyqHHU7LEEf/ck6zC7o2erM3/LZlZuLNPD2cv3oL3Nv
+saEgcTSZl+8XmO8pLmzjKIb+hi70qVx3t2IhMqbb4B/dMY1Ck62gPBKa81/Wwi7v
+IsEBQLEtyBmGmI64YpzoRNFeaaF9JY+sAKqROqe6dLjJ7vebQLQfRWxnYW1hbCAx
+MDI0IDx0ZXN0QGV4YW1wbGUub3JnPoheBBMRAgAeBQJCyCFIAhsDBgsJCAcDAgMV
+AgMDFgIBAh4BAheAAAoJEBwpvA0YF3NkOtsAniI9W2bC3CxARTpYrev7ihreDzFc
+AJ9WYLQxDQAi5Ec9AQoodPkIagzZ4LkBDQRCyCFKEAQAh5SNbbJMAsJ+sQbcWEzd
+ku8AdYB5zY7Qyf9EOvn0g39bzANhxmmb6gbRlQN0ioymlDwraTKUAfuCZgNcg/0P
+sxFGb9nDcvjIV8qdVpnq1PuzMFuBbmGI6weg7Pj01dlPiO0wt1lLX+SubktqbYxI
++h31c3RDZqxj+KAgxR8YNGMAAwYD+wQs2He1Z5+p4OSgMERiNzF0acZUYmc0e+/9
+6gfL0ft3IP+SSFo6hEBrkKVhZKoPSSRr5KpNaEobhdxsnKjUaw/qyoaFcNMzb4sF
+k8wq5UlCkR+h72u6hv8FuleCV8SJUT1U2JjtlXJR2Pey9ifh8rZfu57UbdwdHa0v
+iWc4DilhiEkEGBECAAkFAkLIIUoCGwwACgkQHCm8DRgXc2TtrwCfdPom+HlNVE9F
+ig3hGY1Rb4NEk1gAn1u9IuQB+BgDP40YHHz6bKWS/x80
+=RWci
+-----END PGP PUBLIC KEY BLOCK-----
+', '
+-----BEGIN PGP PRIVATE KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+lQHpBELIIUgRBACp401L6jXrLB28c3YA4sM3OJKnxM1GT9YTkWyE3Vyte65H8WU9
+tGPBX7OMuaX5eGZ84LFUGvaP0k7anfmXcDkCO3P9GgL+ro/dS2Ps/vChQPZqHaxE
+xpKDUt47B7DGdRJrC8DRnIR4wbSyQA6ma3S1yFqC5pJhSs+mqf9eExOjiwCgntth
+klRxIYw352ZX9Ov9oht/p/ED/1Xi4PS+tkXVvyIw5aZfa61bT6XvDkoPI0Aj3GE5
+YmCHJlKA/IhEr8QJOLV++5VEv4l6KQ1/DFoJzoNdr1AGJukgTc6X/WcQRzfQtUic
+PHQme5oAWoHa6bVQZOwvbJh3mOXDq/Tk/KF22go8maM44vMn4bvv+SBbslviYLiL
+jZJ1A/9JXF1esNq+X9HehJyqHHU7LEEf/ck6zC7o2erM3/LZlZuLNPD2cv3oL3Nv
+saEgcTSZl+8XmO8pLmzjKIb+hi70qVx3t2IhMqbb4B/dMY1Ck62gPBKa81/Wwi7v
+IsEBQLEtyBmGmI64YpzoRNFeaaF9JY+sAKqROqe6dLjJ7vebQP4HAwImKZ5q2QwT
+D2DDAY/IQBjes7WgqZeacfLPDoB8ecD/KLoSCH6Z3etvbPHSOKiazxoJ962Ix74H
+ZAE6ZbMTtl5dZW1ptB9FbGdhbWFsIDEwMjQgPHRlc3RAZXhhbXBsZS5vcmc+iF4E
+ExECAB4FAkLIIUgCGwMGCwkIBwMCAxUCAwMWAgECHgECF4AACgkQHCm8DRgXc2Q6
+2wCfXKegLIzoYi8cM57DCYXhn+MZB/MAn1D4zAi5uLQBJ8mJ9oQzbewgfAeinQFf
+BELIIUoQBACHlI1tskwCwn6xBtxYTN2S7wB1gHnNjtDJ/0Q6+fSDf1vMA2HGaZvq
+BtGVA3SKjKaUPCtpMpQB+4JmA1yD/Q+zEUZv2cNy+MhXyp1WmerU+7MwW4FuYYjr
+B6Ds+PTV2U+I7TC3WUtf5K5uS2ptjEj6HfVzdENmrGP4oCDFHxg0YwADBgP7BCzY
+d7Vnn6ng5KAwRGI3MXRpxlRiZzR77/3qB8vR+3cg/5JIWjqEQGuQpWFkqg9JJGvk
+qk1oShuF3GycqNRrD+rKhoVw0zNviwWTzCrlSUKRH6Hva7qG/wW6V4JXxIlRPVTY
+mO2VclHY97L2J+Hytl+7ntRt3B0drS+JZzgOKWH+BwMCJimeatkMEw9gRkFjt4Xa
+9rX8awMBE5+vVcGKv/DNiCvJnlYvSdCj8VfuHsYFliiJo6u17NJon+K43e3yvDNk
+f631VOVanGEz7TyqOkWQiEkEGBECAAkFAkLIIUoCGwwACgkQHCm8DRgXc2TtrwCe
+IUWi3DXHZf6ivK7dDec22bGgoekAn0dTuPDvJ2Dfd0j0nyBWSuaxJnb/
+=SNvr
+-----END PGP PRIVATE KEY BLOCK-----
+');
+insert into keytbl (id, name, pubkey, seckey)
+values (6, 'rsaenc2048', '
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+mQELBELr2m0BCADOrnknlnXI0EzRExf/TgoHvK7Xx/E0keWqV3KrOyC3/tY2KOrj
+UVxaAX5pkFX9wdQObGPIJm06u6D16CH6CildX/vxG7YgvvKzK8JGAbwrXAfk7OIW
+czO2zRaZGDynoK3mAxHRBReyTKtNv8rDQhuZs6AOozJNARdbyUO/yqUnqNNygWuT
+4htFDEuLPIJwAbMSD0BvFW6YQaPdxzaAZm3EWVNbwDzjgbBUdBiUUwRdZIFUhsjJ
+dirFdy5+uuZru6y6CNC1OERkJ7P8EyoFiZckAIE5gshVZzNuyLOZjc5DhWBvLbX4
+NZElAnfiv+4nA6y8wQLSIbmHA3nqJaBklj85AAYptCVSU0EgMjA0OCBFbmMgPHJz
+YTIwNDhlbmNAZXhhbXBsZS5vcmc+iQE0BBMBAgAeBQJC69ptAhsDBgsJCAcDAgMV
+AgMDFgIBAh4BAheAAAoJEMiZ6pNEGVVZHMkIAJtGHHZ9iM8Yq1rr0zl1L6SvlQP8
+JCaxHa31wH3PKqGtq2M+cpb2rXf7gAY/doHJPXggfVzkyFrysmQ1gPbDGYLyOutw
++IkhihEb5bWxQBNj+3zAFs1YX6v2HXWbSUSmyY1V9/+NTtKk03olDc/swd3lXzku
+UOhcgfpBgIt3Q+MpT6M2+OIF7lVfSb1rWdpwTfGhZzW9szQOeoS4gPvxCCRyuabQ
+RJ6DWH61F8fFIDJg1z+A/Obx4fqX6GOA69RzgZ3oukFBIXxNwV9PZNnAmHtZVYO8
+0g/oVYBbuvOYedffDBeQarhERZ5W2TnIE+nqY61YOLBqosliygdZTXULzNi5AQsE
+QuvaugEIAOuCJZdkzORA6e1lr81Lnr4JzMsVBFA+X/yIkBbV6qX/A4nVSLAZKNPX
+z1YIrMTu+1rMIiy10IWbA6zgMTpzPhJRfgePONgdnCYyK5Ksh5/C5ntzKwwGwxfK
+lAXIxJurCHXTbEa+YvPdn76vJ3HsXOXVEL+fLb4U3l3Ng87YM202Lh1Ha2MeS2zE
+FZcAoKbFqAAjDLEai64SoOFh0W3CsD1DL4zmfp+YZrUPHTtZadsi53i4KKW/ws9U
+rHlolqYNhYze/uRLyfnUx9PN4r/GhEzauyDMV0smo91uB3aewPft+eCpmeWnu0PF
+JVK4xyRmhIq2rVCw16a1pBJirvGM+y0ABimJAR8EGAECAAkFAkLr2roCGwwACgkQ
+yJnqk0QZVVku1wgAg1bLSjPkhw+ldG5HzumpqR84+JKyozdJaJzefu2+1iqYE0B0
+WLz2PJVIiK41xiEkKhBvTOQYuXmtWqAWXptD91P5SoXoNJWLQO3TNwarANhHxkWg
+w/TOUxQqoctlRUej5NDD+4eW5G9lcS1FEGuKDWtX096u80vO+TbyJjvx2eVM1k+X
+dmeYsGOiNgDimCreJGYc14G7eY9jt24gw10n1sMAKI1qm6lcoHqZ9OOyla+wJdro
+PYZGO7R8+1O9R22WrK6BYDT5j/1JwMZqbOESjNvDEVT0yOHClCHRN4CChbt6LhKh
+CLUNdz/udIt0JAC6c/HdPLSW3HnmM3+iNj+Kug==
+=pwU2
+-----END PGP PUBLIC KEY BLOCK-----
+', '
+-----BEGIN PGP PRIVATE KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+lQOWBELr2m0BCADOrnknlnXI0EzRExf/TgoHvK7Xx/E0keWqV3KrOyC3/tY2KOrj
+UVxaAX5pkFX9wdQObGPIJm06u6D16CH6CildX/vxG7YgvvKzK8JGAbwrXAfk7OIW
+czO2zRaZGDynoK3mAxHRBReyTKtNv8rDQhuZs6AOozJNARdbyUO/yqUnqNNygWuT
+4htFDEuLPIJwAbMSD0BvFW6YQaPdxzaAZm3EWVNbwDzjgbBUdBiUUwRdZIFUhsjJ
+dirFdy5+uuZru6y6CNC1OERkJ7P8EyoFiZckAIE5gshVZzNuyLOZjc5DhWBvLbX4
+NZElAnfiv+4nA6y8wQLSIbmHA3nqJaBklj85AAYpAAf9GuKpxrXp267eSPw9ZeSw
+Ik6ob1I0MHbhhHeaXQnF0SuOViJ1+Bs74hUB3/F5fqrnjVLIS/ysYzegYpbpXOIa
+MZwYcp2e+dpmVb7tkGQgzXH0igGtBQBqoSUVq9mG2XKPVh2JmiYgOH6GrHSGmnCq
+GCgEK4ezSomB/3OtPFSjAxOlSw6dXSkapSxW3pEGvCdaWd9p8yl4rSpGsZEErPPL
+uSbZZrHtWfgq5UXdPeE1UnMlBcvSruvpN4qgWMgSMs4d2lXvzXJLcht/nryP+atT
+H1gwnRmlDCVv5BeJepKo3ORJDvcPlXkJPhqS9If3BhTqt6QgQEFI4aIYYZOZpZoi
+2QQA2Zckzktmsc1MS04zS9gm1CbxM9d2KK8EOlh7fycRQhYYqqavhTBH2MgEp+Dd
+ZtuEN5saNDe9x/fwi2ok1Bq6luGMWPZU/nZe7fxadzwfliy/qPzStWFW3vY9mMLu
+6uEqgjin/lf4YrAswXDZaEc5e4GuNgGfwr27hpjxE1jg3PsEAPMqXEOMT2yh+yRu
+DlLRbFhYOI4aUHY2CGoQQONnwv2O5gFvmOcPlg3J5lvnwlOYCx0c3bDxAtHyjPJq
+FAZqcJBaB9RDhKHwlWDrbx/6FPH2SuKE+u4msIhPFin4V3FAP+yTem/TKrdnaWy6
+EUrhCWTXVRTijBaCudfjFd/ipHZbA/0dv7UAcoWK6kiVLzyE+jOvtN+ZxTzxq7CW
+mlFPgAC966hgJmz9IXqadtMgPAoL3PK9q1DbPM3JhsQcJrNzTJqZrdN1/kPU0HHa
++aof1BVy3wSvp2mXgaRUULStyhUIyBRM6hAYp3/MoWEYn/bwr+zQkIU8Zsk6OsZ6
+q1xE3cowrUWFtCVSU0EgMjA0OCBFbmMgPHJzYTIwNDhlbmNAZXhhbXBsZS5vcmc+
+iQE0BBMBAgAeBQJC69ptAhsDBgsJCAcDAgMVAgMDFgIBAh4BAheAAAoJEMiZ6pNE
+GVVZHMkIAJtGHHZ9iM8Yq1rr0zl1L6SvlQP8JCaxHa31wH3PKqGtq2M+cpb2rXf7
+gAY/doHJPXggfVzkyFrysmQ1gPbDGYLyOutw+IkhihEb5bWxQBNj+3zAFs1YX6v2
+HXWbSUSmyY1V9/+NTtKk03olDc/swd3lXzkuUOhcgfpBgIt3Q+MpT6M2+OIF7lVf
+Sb1rWdpwTfGhZzW9szQOeoS4gPvxCCRyuabQRJ6DWH61F8fFIDJg1z+A/Obx4fqX
+6GOA69RzgZ3oukFBIXxNwV9PZNnAmHtZVYO80g/oVYBbuvOYedffDBeQarhERZ5W
+2TnIE+nqY61YOLBqosliygdZTXULzNidA5YEQuvaugEIAOuCJZdkzORA6e1lr81L
+nr4JzMsVBFA+X/yIkBbV6qX/A4nVSLAZKNPXz1YIrMTu+1rMIiy10IWbA6zgMTpz
+PhJRfgePONgdnCYyK5Ksh5/C5ntzKwwGwxfKlAXIxJurCHXTbEa+YvPdn76vJ3Hs
+XOXVEL+fLb4U3l3Ng87YM202Lh1Ha2MeS2zEFZcAoKbFqAAjDLEai64SoOFh0W3C
+sD1DL4zmfp+YZrUPHTtZadsi53i4KKW/ws9UrHlolqYNhYze/uRLyfnUx9PN4r/G
+hEzauyDMV0smo91uB3aewPft+eCpmeWnu0PFJVK4xyRmhIq2rVCw16a1pBJirvGM
++y0ABikAB/oC3z7lv6sVg+ngjbpWy9lZu2/ECZ9FqViVz7bUkjfvSuowgpncryLW
+4EpVV4U6mMSgU6kAi5VGT/BvYGSAtnqDWGiPs7Kk+h4Adz74bEAXzU280pNBtSfX
+tGvzlS4a376KzYFSCJDRBdMebEhJMbY0wQmR8lTZu5JSUI4YYEuN0c7ckdsw8w42
+QWTLonG8HC6h8UPKS0EAcaCo7tFubMIesU6cWuTYucsHE+wjbADjuSNX968qczNe
+NoL2BUznXOQoPu6HQO4/8cr7ib+VQkB2bHQcMoZazPUStIID1e4CL4XcxfuAmT8o
+3XDvMLgVqNp5W2f8Mzmk3/DbtsLXLOv5BADsCzQpseC8ikSYJC72hcon1wlUmGeH
+3qgGiiHhYXFa18xgI5juoO8DaWno0rPPlgr36Y8mSB5qjYHMXwjKnKyUmt11H+hU
++6uk4hq3Rjd8l+vfuOSr1xoTrtBUg9Rwfw6JVo0DC+8CWg4oBWsLXVM6KQXPFdJs
+8kyFQplR/iP1XQQA/2tbDANjAYGNNDjJO9/0kEnSAUyYMasFJDrA2q17J5CroVQw
+QpMmWwdDkRANUVPKnWHS5sS65BRc7UytKe2f3A3ZInGXJIK2Hl+TzapWYcYxql+4
+ol5mEDDMDbhEE8Wmj9KyB6iifdLI0K+yxNb9T4Jpj3J18+St+G8+9AcFcBEEAM1b
+M9C+/05cnV8gjcByqH9M9ypo8fzPvMKVXWwCLQXpaL50QIkzLURkiMoEWrCdELaA
+sVPotRzePTIQ1ooLeDxd1gRnDqjZiIR0kwmv6vq8tfzY96O2ZbGWFI5eth89aWEJ
+WB8AR3zYcXpwJLwPuhXW2/NlZF0bclJ3jNzAfTIeQmeJAR8EGAECAAkFAkLr2roC
+GwwACgkQyJnqk0QZVVku1wgAg1bLSjPkhw+ldG5HzumpqR84+JKyozdJaJzefu2+
+1iqYE0B0WLz2PJVIiK41xiEkKhBvTOQYuXmtWqAWXptD91P5SoXoNJWLQO3TNwar
+ANhHxkWgw/TOUxQqoctlRUej5NDD+4eW5G9lcS1FEGuKDWtX096u80vO+TbyJjvx
+2eVM1k+XdmeYsGOiNgDimCreJGYc14G7eY9jt24gw10n1sMAKI1qm6lcoHqZ9OOy
+la+wJdroPYZGO7R8+1O9R22WrK6BYDT5j/1JwMZqbOESjNvDEVT0yOHClCHRN4CC
+hbt6LhKhCLUNdz/udIt0JAC6c/HdPLSW3HnmM3+iNj+Kug==
+=UKh3
+-----END PGP PRIVATE KEY BLOCK-----
+');
+insert into keytbl (id, name, pubkey, seckey)
+values (7, 'rsaenc2048-psw', '
+same key with password
+', '
+-----BEGIN PGP PRIVATE KEY BLOCK-----
+Version: GnuPG v1.4.11 (GNU/Linux)
+
+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
+=QFm5
+-----END PGP PRIVATE KEY BLOCK-----
+');
+-- elg1024 / aes128
+insert into encdata (id, data) values (1, '
+-----BEGIN PGP MESSAGE-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+hQEOA9k2z2S7c/RmEAQAgVWW0DeLrZ+1thWJGBPp2WRFL9HeNqqWHbKJCXJbz1Uy
+faUY7yxVvG5Eutmo+JMiY3mg23/DgVVXHQZsTWpGvGM6djgUNGKUjZDbW6Nog7Mr
+e78IywattCOmgUP9vIwwg3OVjuDCN/nVirGQFnXpJBc8DzWqDMWRWDy1M0ZsK7AD
+/2JTosSFxUdpON0DKtIY3GLzmh6Nk3iV0g8VgJKUBT1rhCXuMDj3snm//EMm7hTY
+PlnObq4mIhgz8NqprmhooxnU0Kapofb3P3wCHPpU14zxhXY8iKO/3JhBq2uFcx4X
+uBMwkW4AdNxY/mzJZELteTL8Tr0s7PISk+owb4URpG3n0jsBc0CVULxrjh5Ejkdw
+wCM195J6+KbQxOOFQ0b3uOVvv4dEgd/hRERCOq5EPaFhlHegyYJ7YO842vnSDA==
+=PABx
+-----END PGP MESSAGE-----
+');
+-- elg2048 / blowfish
+insert into encdata (id, data) values (2, '
+-----BEGIN PGP MESSAGE-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+hQIOAywibh/+XMfUEAf+OINhBngEsw4a/IJIeJvUgv1gTQzBwOdQEuc/runr4Oa8
+Skw/Bj0X/zgABVZLem1a35NHaNwaQaCFwMQ41YyWCu+jTdsiyX/Nw0w8LKKz0rNC
+vVpG6YuV7Turtsf8a5lXy1K0SHkLlgxQ6c76GS4gtSl5+bsL2+5R1gSRJ9NXqCQP
+OHRipEiYwBPqr5R21ZG0FXXNKGOGkj6jt/M/wh3WVtAhYuBI+HPKRfAEjd/Pu/eD
+e1zYtkH1dKKFmp44+nF0tTI274xpuso7ShfKYrOK3saFWrl0DWiWteUinjSA1YBY
+m7dG7NZ8PW+g1SZWhEoPjEEEHz3kWMvlKheMRDudnQf/dDyX6kZVIAQF/5B012hq
+QyVewgTGysowFIDn01uIewoEA9cASw699jw9IoJp+k5WZXnU+INllBLzQxniQCSu
+iEcr0x3fYqNtj9QBfbIqyRcY6HTWcmzyOUeGaSyX76j+tRAvtVtXpraFFFnaHB70
+YpXTjLkp8EBafzMghFaKDeXlr2TG/T7rbwcwWrFIwPqEAUKWN5m97Q3eyo8/ioMd
+YoFD64J9ovSsgbuU5IpIGAsjxK+NKzg/2STH7zZFEVCtgcIXsTHTZfiwS98/+1H9
+p1DIDaXIcUFV2ztmcKxh9gt2sXRz1W+x6D8O0k3nanU5yGG4miLKaq18fbcA0BD1
++NIzAfelq6nvvxYKcGcamBMgLo5JkZOBHvyr6RsAKIT5QYc0QTjysTk9l0Am3gYc
+G2pAE+3k
+=TBHV
+-----END PGP MESSAGE-----
+');
+-- elg4096 / aes256
+insert into encdata (id, data) values (3, '
+-----BEGIN PGP MESSAGE-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+hQQOA7aFBP0Sjh/5EA/+JCgncc8IZmmRjPStWnGf9tVJhgHTn+smIclibGzs0deS
+SPSCitzpblwbUDvu964+/5e5Q1l7rRuNN+AgETlEd4eppv7Swn2ChdgOXxRwukcT
+Nh3G+PTFvD4ayi7w1db3qvXIt0MwN4Alt436wJmK1oz2Ka9IcyO+wHWrDy1nSGSx
+z5x7YEj+EZPgWc/YAvudqE8Jpzd/OT5zSHN09UFkIAk6NxisKaIstbEGFgpqtoDZ
+1SJM84XAdL2IcaJ3YY7k/yzwlawhsakKd4GSd5vWmAwvyzzbSiBMfKsDE16ePLNU
+ZBF7CzmlCBPZ7YrFAHLpXBXXkCQvzD2BEYOjse50ZEfJ036T7950Ozcdy1EQbGon
+nyQ4Gh0PBpnMcBuiXOceWuYzhlzFOzDtlVKdNTxFRDcbEyW2jo9xQYvCCLnYy8EH
+2M7S8jCtVYJBbn63a82ELv+3+kWYcsvBJv2ZVBh4ncrBu9o0P+OYS7ApoOU+j6p2
++t0RXHksqXS1YiUwYF5KSw09EbYMgNZ9G04Px/PxLU6fSC9iDrGX7Xt3kOUP0mku
+C518fPckT0zzRXqfFruJNRzDytW50KxkOQZzU1/Az1YlYN9QzWeU4EtLPb2fftZo
+D0qH/ln+f9Op5t6sD2fcxZVECU1b/bFtZsxvwH406YL+UQ7hU/XnZrzVVzODal8P
+/j1hg7v7BdJqu1DTp9nFWUuwMFcYAczuXn29IG183NZ7Ts4whDeYEhS8eNoLPX4j
+txY12ILD/w/3Q4LoW/hPa6OdfEzsn0U5GLf1WiGmJE1H6ft2U/xUnerc/u0kt+FU
+WAisArd4MuKtf7B5Vu/VF3kUdrR0hTniUKUivmC4o1jSId31Dufxj4aadVyldXAr
+6TNBcdyragZjxEZ6hsBCYzA0Rd1a8atd6OaQoIEEfAzCu5Ks29pydHErStYGjWJ1
+KA5KPLVvjbHpDmRhlCcm8vgpYQsBYEB5gE9fx5yCTlsVhCB6y23h7hfdMqerDqkO
+ZOPsO5h+tiHCdIrQ36sMjuINy1/K2rYcXd+Crh2iHcfidpU9fvDz2ihTRNQlhjuT
+0cQZM5JhctEx4VXF4LDctRhit7Hn0iqsk604woQfJVvP8O673xSXT/kBY0A/v9C0
+3C4YoFNeSaKwbfZQ/4u1ZFPJxK2IIJa8UGpyAUewLMlzGVVagljybv/f4Z9ERAhy
+huq5sMmw8UPsrJF2TUGHz5WSIwoh0J/qovoQI09I9sdEnFczDvRavMO2Mldy3E5i
+exz9oewtel6GOmsZQSYWT/vJzbYMmvHNmNpVwwoKrLV6oI3kyQ80GHBwI1WlwHoK
+2iRB0w8q4VVvJeYAz8ZIp380cqC3pfO0uZsrOx4g3k4X0jsB5y7rF5xXcZfnVbvG
+DYKcOy60/OHMWVvpw6trAoA+iP+cVWPtrbRvLglTVTfYmi1ToZDDipkALBhndQ==
+=L/M/
+-----END PGP MESSAGE-----
+');
+-- rsaenc2048 / aes128
+insert into encdata (id, data) values (4, '
+-----BEGIN PGP MESSAGE-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+hQEMA/0CBsQJt0h1AQf+JyYnCiortj26P11zk28MKOGfWpWyAhuIgwbJXsdQ+e6r
+pEyyqs9GC6gI7SNF6+J8B/gsMwvkAL4FHAQCvA4ZZ6eeXR1Of4YG22JQGmpWVWZg
+DTyfhA2vkczuqfAD2tgUpMT6sdyGkQ/fnQ0lknlfHgC5GRx7aavOoAKtMqiZW5PR
+yae/qR48mjX7Mb+mLvbagv9mHEgQSmHwFpaq2k456BbcZ23bvCmBnCvqV/90Ggfb
+VP6gkSoFVsJ19RHsOhW1dk9ehbl51WB3zUOO5FZWwUTY9DJvKblRK/frF0+CXjE4
+HfcZXHSpSjx4haGGTsMvEJ85qFjZpr0eTGOdY5cFhNJAAVP8MZfji7OhPRAoOOIK
+eRGOCkao12pvPyFTFnPd5vqmyBbdNpK4Q0hS82ljugMJvM0p3vJZVzW402Kz6iBL
+GQ==
+=XHkF
+-----END PGP MESSAGE-----
+');
+-- rsaenc2048 / aes128 (not from gnupg)
+insert into encdata (id, data) values (5, '
+-----BEGIN PGP MESSAGE-----
+
+wcBMA/0CBsQJt0h1AQgAzxZ8j+OTeZ8IlLxfZ/mVd28/gUsCY+xigWBk/anZlK3T
+p2tNU2idHzKdAttH2Hu/PWbZp4kwjl9spezYxMqCeBZqtfGED88Y+rqK0n/ul30A
+7jjFHaw0XUOqFNlST1v6H2i7UXndnp+kcLfHPhnO5BIYWxB2CYBehItqtrn75eqr
+C7trGzU/cr74efcWagbCDSNjiAV7GlEptlzmgVMmNikyI6w0ojEUx8lCLc/OsFz9
+pJUAX8xuwjxDVv+W7xk6c96grQiQlm+FLDYGiGNXoAzx3Wi/howu3uV40dXfY+jx
+3WBrhEew5Pkpt1SsWoFnJWOfJ8GLd0ec8vfRCqAIVdLgAeS7NyawQYtd6wuVrEAj
+5SMg4Thb4d+g45RksuGLHUUr4qO9tiXglODa4InhmJfgNuLk+RGz4LXjq8wepEmW
+vRbgFOG54+Cf4C/gC+HkreDm5JKSKjvvw4B/jC6CDxq+JoziEe2Z1uEjCuEcr+Es
+/eGzeOi36BejXPMHeKxXejj5qBBHKV0pHVhZSgffR0TtlXdB967Yl/5agV0R89hI
+7Gw52emfnH4Z0Y4V0au2H0k1dR/2IxXdJEWSTG7Be1JHT59p9ei2gSEOrdBMIOjP
+tbYYUlmmbvD49bHfThkDiC+oc9947LgQsk3kOOLbNHcjkbrjH8R5kjII4m/SEZA1
+g09T+338SzevBcVXh/cFrQ6/Et+lyyO2LJRUMs69g/HyzJOVWT2Iu8E0eS9MWevY
+Qtrkrhrpkl3Y02qEp/j6M03Yu2t6ZF7dp51aJ5VhO2mmmtHaTnCyCc8Fcf72LmD8
+blH2nKZC9d6fi4YzSYMepZpMOFR65M80MCMiDUGnZBB8sEADu2/iVtqDUeG8mAA=
+=PHJ1
+-----END PGP MESSAGE-----
+');
+-- successful decrypt
+select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
+from keytbl, encdata where keytbl.id=1 and encdata.id=1;
+ pgp_pub_decrypt
+-----------------
+ Secret msg
+(1 row)
+
+select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
+from keytbl, encdata where keytbl.id=2 and encdata.id=2;
+ERROR: Wrong key or corrupt data
+select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
+from keytbl, encdata where keytbl.id=3 and encdata.id=3;
+ pgp_pub_decrypt
+-----------------
+ Secret msg
+(1 row)
+
+select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
+from keytbl, encdata where keytbl.id=6 and encdata.id=4;
+ pgp_pub_decrypt
+-----------------
+ Secret message.
+(1 row)
+
+-- wrong key
+select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
+from keytbl, encdata where keytbl.id=2 and encdata.id=1;
+ERROR: Wrong key
+-- sign-only key
+select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
+from keytbl, encdata where keytbl.id=4 and encdata.id=1;
+ERROR: No encryption key found
+-- rsa: password-protected secret key, wrong password
+select pgp_pub_decrypt(dearmor(data), dearmor(seckey), '123')
+from keytbl, encdata where keytbl.id=7 and encdata.id=4;
+ERROR: Wrong key or corrupt data
+-- rsa: password-protected secret key, right password
+select pgp_pub_decrypt(dearmor(data), dearmor(seckey), 'parool')
+from keytbl, encdata where keytbl.id=7 and encdata.id=4;
+ pgp_pub_decrypt
+-----------------
+ Secret message.
+(1 row)
+
+-- password-protected secret key, no password
+select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
+from keytbl, encdata where keytbl.id=5 and encdata.id=1;
+ERROR: Need password for secret key
+-- password-protected secret key, wrong password
+select pgp_pub_decrypt(dearmor(data), dearmor(seckey), 'foo')
+from keytbl, encdata where keytbl.id=5 and encdata.id=1;
+ERROR: Wrong key or corrupt data
+-- password-protected secret key, right password
+select pgp_pub_decrypt(dearmor(data), dearmor(seckey), 'parool')
+from keytbl, encdata where keytbl.id=5 and encdata.id=1;
+ pgp_pub_decrypt
+-----------------
+ Secret msg
+(1 row)
+
+-- test for a short read from prefix_init
+select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
+from keytbl, encdata where keytbl.id=6 and encdata.id=5;
+ERROR: Wrong key or corrupt data
diff --git a/doc/src/sgml/pgcrypto.sgml b/doc/src/sgml/pgcrypto.sgml
index c4dce94001..bbaa2691fe 100644
--- a/doc/src/sgml/pgcrypto.sgml
+++ b/doc/src/sgml/pgcrypto.sgml
@@ -1234,6 +1234,13 @@ gen_random_uuid() returns uuid
</tgroup>
</table>
+ <para>
+ When compiled against <productname>OpenSSL</productname> 3.0.0 and later
+ versions, the legacy provider must be activated in the
+ <filename>openssl.cnf</filename> configuration file in order to use older
+ ciphers like DES or Blowfish.
+ </para>
+
<para>
Notes:
</para>
--
2.30.1 (Apple Git-130)
0001-Disable-OpenSSL-EVP-digest-padding-in-pgcrypto.patchapplication/octet-stream; name=0001-Disable-OpenSSL-EVP-digest-padding-in-pgcrypto.patch; x-unix-mode=0644Download
From 3e21135eca4c5413ad15ad888212164de3c40337 Mon Sep 17 00:00:00 2001
From: Daniel Gustafsson <daniel@yesql.se>
Date: Mon, 19 Jul 2021 01:58:16 +0200
Subject: [PATCH 1/2] Disable OpenSSL EVP digest padding in pgcrypto
The PX layer in pgcrypto is handling digest padding on its own uniformly
for all backend implementations. Starting with OpenSSL 3.0.0, DecryptUpdate
doesn't flush the last block in case padding is enabled so explicitly
disable it as we don't use it.
Discussion: https://postgr.es/m/FEF81714-D479-4512-839B-C769D2605F8A@yesql.se
---
contrib/pgcrypto/openssl.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c
index ed8e74a2b9..e236b0d79c 100644
--- a/contrib/pgcrypto/openssl.c
+++ b/contrib/pgcrypto/openssl.c
@@ -379,6 +379,8 @@ gen_ossl_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
{
if (!EVP_DecryptInit_ex(od->evp_ctx, od->evp_ciph, NULL, NULL, NULL))
return PXE_CIPHER_INIT;
+ if (!EVP_CIPHER_CTX_set_padding(od->evp_ctx, 0))
+ return PXE_CIPHER_INIT;
if (!EVP_CIPHER_CTX_set_key_length(od->evp_ctx, od->klen))
return PXE_CIPHER_INIT;
if (!EVP_DecryptInit_ex(od->evp_ctx, NULL, NULL, od->key, od->iv))
@@ -403,6 +405,8 @@ gen_ossl_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
{
if (!EVP_EncryptInit_ex(od->evp_ctx, od->evp_ciph, NULL, NULL, NULL))
return PXE_CIPHER_INIT;
+ if (!EVP_CIPHER_CTX_set_padding(od->evp_ctx, 0))
+ return PXE_CIPHER_INIT;
if (!EVP_CIPHER_CTX_set_key_length(od->evp_ctx, od->klen))
return PXE_CIPHER_INIT;
if (!EVP_EncryptInit_ex(od->evp_ctx, NULL, NULL, od->key, od->iv))
--
2.30.1 (Apple Git-130)
On Tue, Jul 20, 2021 at 01:23:42AM +0200, Daniel Gustafsson wrote:
Another aspect of OpenSSL 3 compatibility is that of legacy cipher support, and
as we concluded upthread it's best to leave that to the user to define in
openssl.cnf. The attached 0002 adds alternative output files for 3.0.0
installations without the legacy provider loaded, as well as adds a note in the
pgcrypto docs to enable it in case DES is needed. It does annoy me a bit that
we don't load the openssl.cnf file for 1.0.1 if we start mentioning it in the
docs for other versions, but it's probably not worth the effort to fix it given
the lack of complaints so far (it needs a call to OPENSSL_config(NULL); guarded
to HAVE_ macros for 1.0.1).
Sounds sensible as a whole. Another thing I can notice is that
OpenSSL 3.0.0beta1 has taken care of the issue causing diffs in the
tests of src/test/ssl/. So once pgcrypto is addressed, it looks like
there is nothing left for this thread.
--
Michael
On 20 Jul 2021, at 09:54, Michael Paquier <michael@paquier.xyz> wrote:
On Tue, Jul 20, 2021 at 01:23:42AM +0200, Daniel Gustafsson wrote:
Another aspect of OpenSSL 3 compatibility is that of legacy cipher support, and
as we concluded upthread it's best to leave that to the user to define in
openssl.cnf. The attached 0002 adds alternative output files for 3.0.0
installations without the legacy provider loaded, as well as adds a note in the
pgcrypto docs to enable it in case DES is needed. It does annoy me a bit that
we don't load the openssl.cnf file for 1.0.1 if we start mentioning it in the
docs for other versions, but it's probably not worth the effort to fix it given
the lack of complaints so far (it needs a call to OPENSSL_config(NULL); guarded
to HAVE_ macros for 1.0.1).Sounds sensible as a whole.
Thanks for reviewing!
Another thing I can notice is that
OpenSSL 3.0.0beta1 has taken care of the issue causing diffs in the
tests of src/test/ssl/. So once pgcrypto is addressed, it looks like
there is nothing left for this thread.
That's a good point, I forgot to bring that up.
--
Daniel Gustafsson https://vmware.com/
On 20.07.21 01:23, Daniel Gustafsson wrote:
So I think your proposed patch is sound and a good short-term and low-risk solution
The attached 0001 disables the padding. I've tested this with OpenSSL 1.0.1,
1.0.2, 1.1.1 and Git HEAD at e278127cbfa2709d.Another aspect of OpenSSL 3 compatibility is that of legacy cipher support, and
as we concluded upthread it's best to leave that to the user to define in
openssl.cnf. The attached 0002 adds alternative output files for 3.0.0
installations without the legacy provider loaded, as well as adds a note in the
pgcrypto docs to enable it in case DES is needed. It does annoy me a bit that
we don't load the openssl.cnf file for 1.0.1 if we start mentioning it in the
docs for other versions, but it's probably not worth the effort to fix it given
the lack of complaints so far (it needs a call to OPENSSL_config(NULL); guarded
to HAVE_ macros for 1.0.1).
Are you going to commit these?
Peter Eisentraut <peter.eisentraut@enterprisedb.com> writes:
Are you going to commit these?
Note that with release wraps scheduled for Monday, we are probably
already past the time when it'd be wise to push anything that has
a significant chance of introducing portability issues. There's
just not much time to deal with it if the buildfarm shows problems.
So unless you intend this as HEAD-only, I'd counsel waiting for the
release window to pass.
regards, tom lane
On 6 Aug 2021, at 21:01, Tom Lane <tgl@sss.pgh.pa.us> wrote:
Peter Eisentraut <peter.eisentraut@enterprisedb.com> writes:
Are you going to commit these?
Absolutely, a combination of unplanned home renovations and vacations changed
my plans a bit recently.
Note that with release wraps scheduled for Monday, we are probably
already past the time when it'd be wise to push anything that has
a significant chance of introducing portability issues. There's
just not much time to deal with it if the buildfarm shows problems.
So unless you intend this as HEAD-only, I'd counsel waiting for the
release window to pass.
Until there is an animal running OpenSSL 3.0.0 in the buildfarm I think this
should be HEAD only. Further down the line we need to support OpenSSL 3 in all
backbranches IMO since they are all equally likely to be compiled against it,
but not until we can regularly test against it in the farm.
--
Daniel Gustafsson https://vmware.com/
Daniel Gustafsson <daniel@yesql.se> writes:
Until there is an animal running OpenSSL 3.0.0 in the buildfarm I think this
should be HEAD only. Further down the line we need to support OpenSSL 3 in all
backbranches IMO since they are all equally likely to be compiled against it,
but not until we can regularly test against it in the farm.
Works for me.
regards, tom lane
On 6 Aug 2021, at 21:17, Tom Lane <tgl@sss.pgh.pa.us> wrote:
Daniel Gustafsson <daniel@yesql.se> writes:
Until there is an animal running OpenSSL 3.0.0 in the buildfarm I think this
should be HEAD only. Further down the line we need to support OpenSSL 3 in all
backbranches IMO since they are all equally likely to be compiled against it,
but not until we can regularly test against it in the farm.Works for me.
These have now been committed, when OpenSSL 3.0.0 ships and there is coverage
in the buildfarm I’ll revisit this for the backbranches.
--
Daniel Gustafsson https://vmware.com/
On 10 Aug 2021, at 15:27, Daniel Gustafsson <daniel@yesql.se> wrote:
These have now been committed, when OpenSSL 3.0.0 ships and there is coverage
in the buildfarm I’ll revisit this for the backbranches.
As an update to this, I’ve tested the tree frozen for the upcoming 3.0.0
release (scheduled for today AFAIK) and postgres still builds and tests clean
with the patches that were applied.
--
Daniel Gustafsson https://vmware.com/
On Tue, Sep 07, 2021 at 02:04:23PM +0200, Daniel Gustafsson wrote:
On 10 Aug 2021, at 15:27, Daniel Gustafsson <daniel@yesql.se> wrote:
These have now been committed, when OpenSSL 3.0.0 ships and there is coverage
in the buildfarm I’ll revisit this for the backbranches.As an update to this, I’ve tested the tree frozen for the upcoming 3.0.0
release (scheduled for today AFAIK) and postgres still builds and tests clean
with the patches that were applied.
I think that the time to do a backpatch of 318df8 has come. caiman,
that runs Fedora 35, has just failed:
https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=caiman&dt=2021-09-22%2006%3A28%3A00
Here is a diff:
@@ -8,168 +8,88 @@
decode('0000000000000000', 'hex'),
decode('0000000000000000', 'hex'),
'bf-ecb/pad:none'), 'hex');
- encode
-------------------
- 4ef997456198dd78
-(1 row)
-
+ERROR: encrypt error: Cipher cannot be initialized ?
And if I look at the list of packages at the top of Fedora, I see an
update to OpenSSL 3.0.0:
https://fedora.pkgs.org/rawhide/fedora-aarch64/openssl-libs-3.0.0-1.fc36.aarch64.rpm.html
So the coverage is here. HEAD passes, not the stabele branches. At
least for 14 it would be nice to do that before the release of next
week.
--
Michael
On 22 Sep 2021, at 09:49, Michael Paquier <michael@paquier.xyz> wrote:
On Tue, Sep 07, 2021 at 02:04:23PM +0200, Daniel Gustafsson wrote:
On 10 Aug 2021, at 15:27, Daniel Gustafsson <daniel@yesql.se> wrote:
These have now been committed, when OpenSSL 3.0.0 ships and there is coverage
in the buildfarm I’ll revisit this for the backbranches.As an update to this, I’ve tested the tree frozen for the upcoming 3.0.0
release (scheduled for today AFAIK) and postgres still builds and tests clean
with the patches that were applied.I think that the time to do a backpatch of 318df8 has come. caiman,
that runs Fedora 35, has just failed:
https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=caiman&dt=2021-09-22%2006%3A28%3A00Here is a diff: @@ -8,168 +8,88 @@ decode('0000000000000000', 'hex'), decode('0000000000000000', 'hex'), 'bf-ecb/pad:none'), 'hex'); - encode ------------------- - 4ef997456198dd78 -(1 row) - +ERROR: encrypt error: Cipher cannot be initialized ?
That particular error stems from the legacy provider not being enabled in
openssl.cnf, so for this we need to backpatch 72bbff4cd as well.
So the coverage is here. HEAD passes, not the stabele branches. At
least for 14 it would be nice to do that before the release of next
week.
Agreed, I will go ahead and prep backpatches for 318df8 and 72bbff4cd.
--
Daniel Gustafsson https://vmware.com/
On 22 Sep 2021, at 10:06, Daniel Gustafsson <daniel@yesql.se> wrote:
Agreed, I will go ahead and prep backpatches for 318df8 and 72bbff4cd.
These commits are enough to keep 14 happy, and I intend to apply them tomorrow
after another round of testing and caffeine.
For the 13- backbranches we also need to backport 22e1943f1 ("pgcrypto: Check
for error return of px_cipher_decrypt()" by Peter E) in order to avoid
incorrect results for decrypt tests on disallowed ciphers. Does anyone have
any concerns about applying this to backbranches?
13 and older will, when compiled against OpenSSL 3.0.0, produce a fair amount
of compiler warnings on usage of depreceted functionality but there is really
anything we can do as suppressing that is beyond the scope of a backpatchable
fix IMHO.
--
Daniel Gustafsson https://vmware.com/
On Thu, Sep 23, 2021 at 2:51 PM Daniel Gustafsson <daniel@yesql.se> wrote:
For the 13- backbranches we also need to backport 22e1943f1 ("pgcrypto: Check
for error return of px_cipher_decrypt()" by Peter E) in order to avoid
incorrect results for decrypt tests on disallowed ciphers. Does anyone have
any concerns about applying this to backbranches?
To me it looks like it would be more concerning if we did not apply it
to back-branches.
--
Robert Haas
EDB: http://www.enterprisedb.com
On 23.09.21 20:51, Daniel Gustafsson wrote:
For the 13- backbranches we also need to backport 22e1943f1 ("pgcrypto: Check
for error return of px_cipher_decrypt()" by Peter E) in order to avoid
incorrect results for decrypt tests on disallowed ciphers. Does anyone have
any concerns about applying this to backbranches?
This should be backpatched as a bug fix.
13 and older will, when compiled against OpenSSL 3.0.0, produce a fair amount
of compiler warnings on usage of depreceted functionality but there is really
anything we can do as suppressing that is beyond the scope of a backpatchable
fix IMHO.
Right, that's just a matter of adjusting the compiler warnings.
Earlier in this thread, I had suggested backpatching the
OPENSSL_API_COMPAT definition to PG13, but now I'm thinking I wouldn't
bother, since that still wouldn't help with anything older.
On 23 Sep 2021, at 23:26, Peter Eisentraut <peter.eisentraut@enterprisedb.com> wrote:
On 23.09.21 20:51, Daniel Gustafsson wrote:
For the 13- backbranches we also need to backport 22e1943f1 ("pgcrypto: Check
for error return of px_cipher_decrypt()" by Peter E) in order to avoid
incorrect results for decrypt tests on disallowed ciphers. Does anyone have
any concerns about applying this to backbranches?This should be backpatched as a bug fix.
Thanks for confirming, I will go ahead and do that.
--
Daniel Gustafsson https://vmware.com/
On 23 Sep 2021, at 23:41, Daniel Gustafsson <daniel@yesql.se> wrote:
Thanks for confirming, I will go ahead and do that.
These have now been pushed to 14 through to 10 ahead of next week releases, I
will keep an eye on caiman as it builds these branches. The OpenSSL support in
9.6 pgcrypto isn't using the EVP API (committed in 5ff4a67f63) so it's a bit
trickier to get green, but I'll take a stab at that when my fever goes down a
bit.
--
Daniel Gustafsson https://vmware.com/
On Sat, Sep 25, 2021 at 11:55:03AM +0200, Daniel Gustafsson wrote:
These have now been pushed to 14 through to 10 ahead of next week releases, I
will keep an eye on caiman as it builds these branches. The OpenSSL support in
9.6 pgcrypto isn't using the EVP API (committed in 5ff4a67f63) so it's a bit
trickier to get green,
Thanks! As 9.6 will be EOL'd in a couple of weeks, is that really
worth the effort though? It sounds risky to me to introduce an
invasive change as that would increase the risk of bugs for existing
users. So my vote would be to just let this one go.
but I'll take a stab at that when my fever goes down a bit.
Ouch. Take care!
--
Michael
On 25 Sep 2021, at 12:03, Michael Paquier <michael@paquier.xyz> wrote:
As 9.6 will be EOL'd in a couple of weeks, is that really
worth the effort though? It sounds risky to me to introduce an
invasive change as that would increase the risk of bugs for existing
users. So my vote would be to just let this one go.
Agreed, if it's not a simple fix it's unlikely to be worth it.
--
Daniel Gustafsson https://vmware.com/
Daniel Gustafsson <daniel@yesql.se> writes:
On 25 Sep 2021, at 12:03, Michael Paquier <michael@paquier.xyz> wrote:
As 9.6 will be EOL'd in a couple of weeks, is that really
worth the effort though? It sounds risky to me to introduce an
invasive change as that would increase the risk of bugs for existing
users. So my vote would be to just let this one go.
Agreed, if it's not a simple fix it's unlikely to be worth it.
Yeah, there will be no second chance to get 9.6.last right,
so I'd vote against touching it for this.
regards, tom lane
On 25 Sep 2021, at 15:45, Tom Lane <tgl@sss.pgh.pa.us> wrote:
Daniel Gustafsson <daniel@yesql.se> writes:
On 25 Sep 2021, at 12:03, Michael Paquier <michael@paquier.xyz> wrote:
As 9.6 will be EOL'd in a couple of weeks, is that really
worth the effort though? It sounds risky to me to introduce an
invasive change as that would increase the risk of bugs for existing
users. So my vote would be to just let this one go.Agreed, if it's not a simple fix it's unlikely to be worth it.
Yeah, there will be no second chance to get 9.6.last right,
so I'd vote against touching it for this.
Fair point. Should we perhaps instead include a note in the pgcrypto docs for
9.6 that 3.0.0 isn't supported and leave it at that?
--
Daniel Gustafsson https://vmware.com/
On Wed, 29 Jun 2022 at 10:55, Daniel Gustafsson <daniel@yesql.se> wrote:
These have now been pushed to 14 through to 10 ahead of next week releases
I upgraded my OS to Ubuntu 22.04 and it seems that "Define
OPENSSL_API_COMPAT" commit was never backported
(4d3db13621be64fbac2faf7c01c4879d20885c1b). I now get various
deprecation warnings when compiling PG13 on Ubuntu 22.04, because of
OpenSSL 3.0. Was this simply forgotten, or is there a reason why it
wasn't backported?
On 29 Jun 2022, at 11:02, Jelte Fennema <postgres@jeltef.nl> wrote:
On Wed, 29 Jun 2022 at 10:55, Daniel Gustafsson <daniel@yesql.se> wrote:
These have now been pushed to 14 through to 10 ahead of next week releases
I upgraded my OS to Ubuntu 22.04 and it seems that "Define
OPENSSL_API_COMPAT" commit was never backported
(4d3db13621be64fbac2faf7c01c4879d20885c1b). I now get various
deprecation warnings when compiling PG13 on Ubuntu 22.04, because of
OpenSSL 3.0. Was this simply forgotten, or is there a reason why it
wasn't backported?
See upthread in ef5c7896-20cb-843f-e91e-0ee5f7fd932e@enterprisedb.com, below is
the relevant portion:
13 and older will, when compiled against OpenSSL 3.0.0, produce a fair amount
of compiler warnings on usage of depreceted functionality but there is really
anything we can do as suppressing that is beyond the scope of a backpatchable
fix IMHO.Right, that's just a matter of adjusting the compiler warnings.
Earlier in this thread, I had suggested backpatching the OPENSSL_API_COMPAT definition to PG13, but now I'm thinking I wouldn't bother, since that still wouldn't help with anything older.
--
Daniel Gustafsson https://vmware.com/
See upthread in ef5c7896-20cb-843f-e91e-0ee5f7fd932e@enterprisedb.com
I saw that section, but I thought that only applied before you
backpatched the actual fixes to PG13 and below. I mean there's no
reason anymore not to compile those older versions with OpenSSL 3.0,
right? If so, it seems confusing for the build to spit out warnings
that indicate the contrary.
On 29 Jun 2022, at 11:44, Jelte Fennema <postgres@jeltef.nl> wrote:
See upthread in ef5c7896-20cb-843f-e91e-0ee5f7fd932e@enterprisedb.com
I saw that section, but I thought that only applied before you
backpatched the actual fixes to PG13 and below. I mean there's no
reason anymore not to compile those older versions with OpenSSL 3.0,
right? If so, it seems confusing for the build to spit out warnings
that indicate the contrary.
The project isn't automatically fixing compiler warnings or library deprecation
warnings in back-branches. I guess one could make the argument for this case
given how widespread OpenSSL 3.0, but it comes with a significant testing
effort to ensure that all back-branches behave correctly with all version of
OpenSSL so it's not for free (it should be, but with OpenSSL I would personally
not trust that). Also, PG12 and below had 0.9.8 as minimum version.
--
Daniel Gustafsson https://vmware.com/