v2-0001-Make-it-possible-to-disable-built-in-crypto.patch
application/octet-stream
Filename: v2-0001-Make-it-possible-to-disable-built-in-crypto.patch
Type: application/octet-stream
Part: 0
Patch
Format: format-patch
Series: patch v2-0001
Subject: Make it possible to disable built-in crypto
| File | + | − |
|---|---|---|
| contrib/pgcrypto/expected/crypt-des.out | 7 | 0 |
| contrib/pgcrypto/openssl.c | 29 | 0 |
| contrib/pgcrypto/pgcrypto.c | 30 | 0 |
| contrib/pgcrypto/px-crypt.c | 4 | 0 |
| contrib/pgcrypto/px.h | 10 | 0 |
| contrib/pgcrypto/sql/crypt-des.sql | 6 | 0 |
| doc/src/sgml/pgcrypto.sgml | 39 | 0 |
From 243326cc90d7824ac099b2d7b4c607d158cb76c9 Mon Sep 17 00:00:00 2001
From: Daniel Gustafsson <daniel@yesql.se>
Date: Fri, 22 Nov 2024 14:49:31 +0100
Subject: [PATCH v2] Make it possible to disable built-in crypto
---
contrib/pgcrypto/expected/crypt-des.out | 7 +++++
contrib/pgcrypto/openssl.c | 29 ++++++++++++++++++
contrib/pgcrypto/pgcrypto.c | 30 +++++++++++++++++++
contrib/pgcrypto/px-crypt.c | 4 +++
contrib/pgcrypto/px.h | 10 +++++++
contrib/pgcrypto/sql/crypt-des.sql | 6 ++++
doc/src/sgml/pgcrypto.sgml | 39 +++++++++++++++++++++++++
7 files changed, 125 insertions(+)
diff --git a/contrib/pgcrypto/expected/crypt-des.out b/contrib/pgcrypto/expected/crypt-des.out
index a462dcd580a..8993a2d1044 100644
--- a/contrib/pgcrypto/expected/crypt-des.out
+++ b/contrib/pgcrypto/expected/crypt-des.out
@@ -28,4 +28,11 @@ FROM ctest;
t
(1 row)
+-- check disabling of legacy crypto functions
+SET pgcrypto.legacy_crypto_enabled = off;
+UPDATE ctest SET salt = gen_salt('des');
+ERROR: use of built-in crypto functions is disabled
+UPDATE ctest SET res = crypt(data, salt);
+ERROR: use of built-in crypto functions is disabled
+RESET pgcrypto.legacy_crypto_enabled;
DROP TABLE ctest;
diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c
index 26454bc3e29..c29940f3d06 100644
--- a/contrib/pgcrypto/openssl.c
+++ b/contrib/pgcrypto/openssl.c
@@ -794,3 +794,32 @@ ResOwnerReleaseOSSLCipher(Datum res)
{
free_openssl_cipher((OSSLCipher *) DatumGetPointer(res));
}
+
+/*
+ * CheckLegacyCryptoMode
+ *
+ * Function for erroring out in case built-in crypto is executed when the user
+ * has disabled it. If legacy_crypto_enabled is set to LGC_OFF or LGC_FIPS and
+ * OpenSSL is operating in FIPS mode the function will error out, else the
+ * query executing built-in crypto can proceed.
+ */
+void
+CheckLegacyCryptoMode(void)
+{
+ if (legacy_crypto_enabled == LGC_ON)
+ return;
+
+ if (legacy_crypto_enabled == LGC_OFF)
+ ereport(ERROR,
+ errmsg("use of built-in crypto functions is disabled"));
+
+ Assert(legacy_crypto_enabled == LGC_FIPS);
+
+#if defined FIPS_mode
+ if (FIPS_mode())
+#else
+ if (EVP_default_properties_is_fips_enabled(OSSL_LIB_CTX_get0_global_default()))
+#endif
+ ereport(ERROR,
+ errmsg("use of non-FIPS certified crypto not allowed when OpenSSL is in FIPS mode"));
+}
diff --git a/contrib/pgcrypto/pgcrypto.c b/contrib/pgcrypto/pgcrypto.c
index ebd76eed702..fe0e2b9242a 100644
--- a/contrib/pgcrypto/pgcrypto.c
+++ b/contrib/pgcrypto/pgcrypto.c
@@ -38,16 +38,46 @@
#include "px-crypt.h"
#include "px.h"
#include "utils/builtins.h"
+#include "utils/guc.h"
#include "varatt.h"
PG_MODULE_MAGIC;
/* private stuff */
+static const struct config_enum_entry legacy_crypto_options[] = {
+ {"on", LGC_ON, false},
+ {"off", LGC_OFF, false},
+ {"fips", LGC_FIPS, false},
+ {NULL, 0, false}
+};
+
typedef int (*PFN) (const char *name, void **res);
static void *find_provider(text *name, PFN provider_lookup, const char *desc,
int silent);
+int legacy_crypto_enabled = LGC_ON;
+
+/*
+ * Entrypoint of this module.
+ */
+void
+_PG_init(void)
+{
+ DefineCustomEnumVariable("pgcrypto.legacy_crypto_enabled",
+ "Sets if builtin crypto functions are enabled.",
+ "Yes enables builtin crypto, No unconditionally disables and OpenSSL "
+ "will disable if OpenSSL is in FIPS mode",
+ &legacy_crypto_enabled,
+ LGC_ON,
+ legacy_crypto_options,
+ PGC_SUSET,
+ 0,
+ NULL,
+ NULL,
+ NULL);
+}
+
/* SQL function: hash(bytea, text) returns bytea */
PG_FUNCTION_INFO_V1(pg_digest);
diff --git a/contrib/pgcrypto/px-crypt.c b/contrib/pgcrypto/px-crypt.c
index 0913ff2c1bc..b97ea4fd36b 100644
--- a/contrib/pgcrypto/px-crypt.c
+++ b/contrib/pgcrypto/px-crypt.c
@@ -91,6 +91,8 @@ px_crypt(const char *psw, const char *salt, char *buf, unsigned len)
{
const struct px_crypt_algo *c;
+ CheckLegacyCryptoMode();
+
for (c = px_crypt_list; c->id; c++)
{
if (!c->id_len)
@@ -135,6 +137,8 @@ px_gen_salt(const char *salt_type, char *buf, int rounds)
char *p;
char rbuf[16];
+ CheckLegacyCryptoMode();
+
for (g = gen_list; g->name; g++)
if (pg_strcasecmp(g->name, salt_type) == 0)
break;
diff --git a/contrib/pgcrypto/px.h b/contrib/pgcrypto/px.h
index 471bb4ec727..8f21dad54ec 100644
--- a/contrib/pgcrypto/px.h
+++ b/contrib/pgcrypto/px.h
@@ -89,6 +89,12 @@
#define PXE_PGP_UNSUPPORTED_PUBALGO -122
#define PXE_PGP_MULTIPLE_SUBKEYS -123
+typedef enum LegacyCryptoOptions
+{
+ LGC_ON,
+ LGC_OFF,
+ LGC_FIPS,
+} LegacyCryptoOptions;
typedef struct px_digest PX_MD;
typedef struct px_alias PX_Alias;
@@ -96,6 +102,8 @@ typedef struct px_hmac PX_HMAC;
typedef struct px_cipher PX_Cipher;
typedef struct px_combo PX_Combo;
+extern int legacy_crypto_enabled;
+
struct px_digest
{
unsigned (*result_size) (PX_MD *h);
@@ -182,6 +190,8 @@ void px_set_debug_handler(void (*handler) (const char *));
void px_memset(void *ptr, int c, size_t len);
+void CheckLegacyCryptoMode(void);
+
#ifdef PX_DEBUG
void px_debug(const char *fmt,...) pg_attribute_printf(1, 2);
#else
diff --git a/contrib/pgcrypto/sql/crypt-des.sql b/contrib/pgcrypto/sql/crypt-des.sql
index a85ec1e6555..5b75dc5bb49 100644
--- a/contrib/pgcrypto/sql/crypt-des.sql
+++ b/contrib/pgcrypto/sql/crypt-des.sql
@@ -18,4 +18,10 @@ UPDATE ctest SET res = crypt(data, salt);
SELECT res = crypt(data, res) AS "worked"
FROM ctest;
+-- check disabling of legacy crypto functions
+SET pgcrypto.legacy_crypto_enabled = off;
+UPDATE ctest SET salt = gen_salt('des');
+UPDATE ctest SET res = crypt(data, salt);
+RESET pgcrypto.legacy_crypto_enabled;
+
DROP TABLE ctest;
diff --git a/doc/src/sgml/pgcrypto.sgml b/doc/src/sgml/pgcrypto.sgml
index 396c67f0cde..c54b0e8459f 100644
--- a/doc/src/sgml/pgcrypto.sgml
+++ b/doc/src/sgml/pgcrypto.sgml
@@ -1222,6 +1222,45 @@ gen_random_uuid() returns uuid
</sect3>
</sect2>
+ <sect2 id="pgcrypto-configuration-parameters">
+ <title>Configuration Parameters</title>
+
+ <para>
+ There is one configuration parameter that controls the behavior of
+ <filename>pgcrypto</filename>.
+ </para>
+
+ <variablelist>
+ <varlistentry id="pgcrypto-configuration-parameters-legacy_crypto_enabled">
+ <term>
+ <varname>pgcrypto.legacy_crypto_enabled</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>pgcrypto.legacy_crypto_enabled</varname> configuration
+ parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ <varname>pgcrypto.legacy_crypto_enabled</varname> determines if the
+ built in legacy crypto functions <literal>pg_gen_salt</literal>,
+ <literal>pg_gen_salt_rounds</literal>, and <literal>pg_crypt</literal>
+ are available for use. Setting this to <literal>off</literal>
+ disables these functions. <literal>on</literal> (the default) enables
+ these functions to work normally. <literal>fips</literal> disables these
+ functions if <application>OpenSSL</application> is detected to operate
+ in FIPS mode.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ In ordinary usage, these parameters are set
+ in <filename>postgresql.conf</filename>, although superusers can alter them
+ on-the-fly within their own sessions.
+ </para>
+ </sect2>
+
<sect2 id="pgcrypto-author">
<title>Author</title>
--
2.39.3 (Apple Git-146)