diff options
-rw-r--r-- | contrib/pgcrypto/expected/crypt-des.out | 7 | ||||
-rw-r--r-- | contrib/pgcrypto/openssl.c | 26 | ||||
-rw-r--r-- | contrib/pgcrypto/pgcrypto.c | 31 | ||||
-rw-r--r-- | contrib/pgcrypto/px-crypt.c | 4 | ||||
-rw-r--r-- | contrib/pgcrypto/px.h | 9 | ||||
-rw-r--r-- | contrib/pgcrypto/sql/crypt-des.sql | 6 | ||||
-rw-r--r-- | doc/src/sgml/pgcrypto.sgml | 38 |
7 files changed, 121 insertions, 0 deletions
diff --git a/contrib/pgcrypto/expected/crypt-des.out b/contrib/pgcrypto/expected/crypt-des.out index a462dcd580a..70ca7b357b2 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 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; DROP TABLE ctest; diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c index e6870c72c9a..75f40a2d034 100644 --- a/contrib/pgcrypto/openssl.c +++ b/contrib/pgcrypto/openssl.c @@ -31,6 +31,7 @@ #include "postgres.h" +#include <openssl/crypto.h> #include <openssl/evp.h> #include <openssl/err.h> #include <openssl/rand.h> @@ -821,3 +822,28 @@ CheckFIPSMode(void) return (fips_enabled == 1); } + +/* + * 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) +{ + 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); + + if (CheckFIPSMode() == true) + ereport(ERROR, + errmsg("use of non-FIPS validated crypto not allowed when OpenSSL is in FIPS mode")); +} diff --git a/contrib/pgcrypto/pgcrypto.c b/contrib/pgcrypto/pgcrypto.c index ee2a010e402..b7e5383b9a6 100644 --- a/contrib/pgcrypto/pgcrypto.c +++ b/contrib/pgcrypto/pgcrypto.c @@ -38,16 +38,47 @@ #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 0913ff2c1bc..96ce9384aff 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; + CheckBuiltinCryptoMode(); + 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]; + 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 c2c2fc31245..37013cd9f82 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 BuiltinCryptoOptions +{ + BC_ON, + BC_OFF, + BC_FIPS, +} BuiltinCryptoOptions; 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 builtin_crypto_enabled; + struct px_digest { unsigned (*result_size) (PX_MD *h); @@ -183,6 +191,7 @@ void px_set_debug_handler(void (*handler) (const char *)); void px_memset(void *ptr, int c, size_t len); bool CheckFIPSMode(void); +void CheckBuiltinCryptoMode(void); #ifdef PX_DEBUG void px_debug(const char *fmt,...) pg_attribute_printf(1, 2); diff --git a/contrib/pgcrypto/sql/crypt-des.sql b/contrib/pgcrypto/sql/crypt-des.sql index a85ec1e6555..58cc9d2720a 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 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; + DROP TABLE ctest; diff --git a/doc/src/sgml/pgcrypto.sgml b/doc/src/sgml/pgcrypto.sgml index 838d7532a52..a4d035eabdd 100644 --- a/doc/src/sgml/pgcrypto.sgml +++ b/doc/src/sgml/pgcrypto.sgml @@ -1165,6 +1165,44 @@ fips_mode() returns boolean </para> </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 + <productname>OpenSSL</productname> 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-notes"> <title>Notes</title> |