v9-0001-pgcrypto-Make-it-possible-to-disable-built-in-cry.patch
text/x-patch
Filename: v9-0001-pgcrypto-Make-it-possible-to-disable-built-in-cry.patch
Type: text/x-patch
Part: 0
Patch
Format: unified
Series: patch v9-0001
| File | + | − |
|---|---|---|
| contrib/pgcrypto/expected/crypt-des.out | 0 | 0 |
| contrib/pgcrypto/openssl.c | 0 | 0 |
| contrib/pgcrypto/pgcrypto.c | 0 | 0 |
| contrib/pgcrypto/px-crypt.c | 0 | 0 |
| contrib/pgcrypto/px.h | 0 | 0 |
| contrib/pgcrypto/sql/crypt-des.sql | 0 | 0 |
| doc/src/sgml/pgcrypto.sgml | 0 | 0 |
diff --git a/contrib/pgcrypto/expected/crypt-des.out b/contrib/pgcrypto/expected/crypt-des.out
index a462dcd..edc559d 100644
*** a/contrib/pgcrypto/expected/crypt-des.out
--- b/contrib/pgcrypto/expected/crypt-des.out
*************** FROM ctest;
*** 28,31 ****
--- 28,42 ----
t
(1 row)
+ -- check disabling of built in crypto functions
+ SET pgcrypto.builtin_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.builtin_crypto_enabled;
+ SET pgcrypto.builtin_crypto_enabled = fips;
+ UPDATE ctest SET salt = gen_salt('des');
+ UPDATE ctest SET res = crypt(data, salt);
+ RESET pgcrypto.builtin_crypto_enabled;
DROP TABLE ctest;
diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c
index 448db33..fc930e4 100644
*** a/contrib/pgcrypto/openssl.c
--- b/contrib/pgcrypto/openssl.c
*************** ResOwnerReleaseOSSLCipher(Datum res)
*** 794,796 ****
--- 794,837 ----
{
free_openssl_cipher((OSSLCipher *) DatumGetPointer(res));
}
+
+ /*
+ * CheckBuiltinCryptoMode
+ *
+ * Function for erroring out in case built-in crypto is executed when the user
+ * has disabled it. If builtin_crypto_enabled is set to BC_OFF or BC_FIPS and
+ * OpenSSL is operating in FIPS mode the function will error out, else the
+ * query executing built-in crypto can proceed.
+ */
+ void
+ CheckBuiltinCryptoMode(void)
+ {
+ int fips_enabled;
+
+ if (builtin_crypto_enabled == BC_ON)
+ return;
+
+ if (builtin_crypto_enabled == BC_OFF)
+ ereport(ERROR,
+ errmsg("use of built-in crypto functions is disabled"));
+
+ Assert(builtin_crypto_enabled == BC_FIPS);
+
+ /*
+ * EVP_default_properties_is_fips_enabled was added in OpenSSL 3.0, before
+ * that FIPS_mode() was used to test for FIPS being enabled. The last
+ * upstream OpenSSL version before 3.0 which supported FIPS was 1.0.2, but
+ * there are forks of 1.1.1 which are FIPS certified so we still need to
+ * test with FIPS_mode() even though we don't support 1.0.2.
+ */
+ fips_enabled =
+ #if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ EVP_default_properties_is_fips_enabled(NULL);
+ #else
+ FIPS_mode();
+ #endif
+
+ if (fips_enabled)
+ 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 ebd76ee..d02a621 100644
*** a/contrib/pgcrypto/pgcrypto.c
--- b/contrib/pgcrypto/pgcrypto.c
***************
*** 38,53 ****
--- 38,84 ----
#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 builtin_crypto_options[] = {
+ {"on", BC_ON, false},
+ {"off", BC_OFF, false},
+ {"fips", BC_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 builtin_crypto_enabled = BC_ON;
+
+ /*
+ * Entrypoint of this module.
+ */
+ void
+ _PG_init(void)
+ {
+ DefineCustomEnumVariable("pgcrypto.builtin_crypto_enabled",
+ "Sets if builtin crypto functions are enabled.",
+ "\"on\" enables builtin crypto, \"off\" unconditionally disables and \"fips\" "
+ "will disable builtin crypto if OpenSSL is in FIPS mode",
+ &builtin_crypto_enabled,
+ BC_ON,
+ builtin_crypto_options,
+ PGC_SUSET,
+ 0,
+ NULL,
+ NULL,
+ NULL);
+ MarkGUCPrefixReserved("pgcrypto");
+ }
+
/* 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 0913ff2..96ce938 100644
*** a/contrib/pgcrypto/px-crypt.c
--- b/contrib/pgcrypto/px-crypt.c
*************** px_crypt(const char *psw, const char *sa
*** 91,96 ****
--- 91,98 ----
{
const struct px_crypt_algo *c;
+ CheckBuiltinCryptoMode();
+
for (c = px_crypt_list; c->id; c++)
{
if (!c->id_len)
*************** px_gen_salt(const char *salt_type, char
*** 135,140 ****
--- 137,144 ----
char *p;
char rbuf[16];
+ CheckBuiltinCryptoMode();
+
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 471bb4e..c574f72 100644
*** a/contrib/pgcrypto/px.h
--- b/contrib/pgcrypto/px.h
***************
*** 89,94 ****
--- 89,100 ----
#define PXE_PGP_UNSUPPORTED_PUBALGO -122
#define PXE_PGP_MULTIPLE_SUBKEYS -123
+ typedef enum BuiltinCryptoOptions
+ {
+ BC_ON,
+ BC_OFF,
+ BC_FIPS,
+ } BuiltinCryptoOptions;
typedef struct px_digest PX_MD;
typedef struct px_alias PX_Alias;
*************** typedef struct px_hmac PX_HMAC;
*** 96,101 ****
--- 102,109 ----
typedef struct px_cipher PX_Cipher;
typedef struct px_combo PX_Combo;
+ extern int builtin_crypto_enabled;
+
struct px_digest
{
unsigned (*result_size) (PX_MD *h);
*************** void px_set_debug_handler(void (*handle
*** 182,187 ****
--- 190,197 ----
void px_memset(void *ptr, int c, size_t len);
+ void CheckBuiltinCryptoMode(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 a85ec1e..bd61938 100644
*** a/contrib/pgcrypto/sql/crypt-des.sql
--- b/contrib/pgcrypto/sql/crypt-des.sql
*************** UPDATE ctest SET res = crypt(data, salt)
*** 18,21 ****
--- 18,32 ----
SELECT res = crypt(data, res) AS "worked"
FROM ctest;
+ -- check disabling of built in crypto functions
+ SET pgcrypto.builtin_crypto_enabled = off;
+ UPDATE ctest SET salt = gen_salt('des');
+ UPDATE ctest SET res = crypt(data, salt);
+ RESET pgcrypto.builtin_crypto_enabled;
+
+ SET pgcrypto.builtin_crypto_enabled = fips;
+ UPDATE ctest SET salt = gen_salt('des');
+ UPDATE ctest SET res = crypt(data, salt);
+ RESET pgcrypto.builtin_crypto_enabled;
+
DROP TABLE ctest;
diff --git a/doc/src/sgml/pgcrypto.sgml b/doc/src/sgml/pgcrypto.sgml
index 396c67f..d1034ef 100644
*** a/doc/src/sgml/pgcrypto.sgml
--- b/doc/src/sgml/pgcrypto.sgml
*************** gen_random_uuid() returns uuid
*** 1222,1227 ****
--- 1222,1265 ----
</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-builtin_crypto_enabled">
+ <term>
+ <varname>pgcrypto.builtin_crypto_enabled</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>pgcrypto.builtin_crypto_enabled</varname> configuration
+ parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ <varname>pgcrypto.builtin_crypto_enabled</varname> determines if the
+ built in crypto functions <function>gen_salt()</function>, and
+ <function>crypt()</function> 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, this parameter is set
+ in <filename>postgresql.conf</filename>, although superusers can alter it
+ on-the-fly within their own sessions.
+ </para>
+ </sect2>
+
<sect2 id="pgcrypto-author">
<title>Author</title>