public inbox for [email protected]  
help / color / mirror / Atom feed
[PATCH 1/1] Fix overflow check and comment in GIN posting list encoding.
12+ messages / 6 participants
[nested] [flat]

* [PATCH 1/1] Fix overflow check and comment in GIN posting list encoding.
@ 2019-08-22 08:06 Heikki Linnakangas <[email protected]>
  0 siblings, 0 replies; 12+ messages in thread

From: Heikki Linnakangas @ 2019-08-22 08:06 UTC (permalink / raw)

The comment did not match what the code actually did for integers with
the 43rd bit set. You get an integer like that, if you have a posting
list with two adjacent TIDs that are more than 2^31 blocks apart.
According to the comment, we would store that in 6 bytes, with no
continuation bit on the 6th byte, but in reality, the code encodes it
using 7 bytes, with a continuation bit on the 6th byte as normal.

The decoding routine also handled these 7-byte integers correctly, except
for an overflow check that assumed that one integer needs at most 6 bytes.
Fix the overflow check, and fix the comment to match what the code
actually does.

Fitting any item pointer into max 6 bytes was an important property when
this was written, because in the old pre-9.4 format, item pointers were
stored as plain arrays, with 6 bytes for every item pointer. The maximum
of 6 bytes per integer in the new format guaranteed that we could convert
any page from the old format to the new format after upgrade, so that the
new format was never larger than the old format. But we hardly need to
worry about that anymore, and running into that problem during upgrade,
where an item pointer is expanded from 6 to 7 bytes such that the data
doesn't fit on a page anymore, is implausible in practice anyway.

Backpatch to all supported versions.

This also includes a little test module to test these large distances
between item pointers, without requiring a 16 TB table. It is not
backpatched, I'm including it more for the benefit of future development
of new posting list formats.

Discussion: XXX
---
 src/backend/access/gin/ginpostinglist.c       | 33 +++++--
 src/test/modules/Makefile                     |  1 +
 src/test/modules/test_ginpostinglist/Makefile | 21 ++++
 src/test/modules/test_ginpostinglist/README   |  2 +
 .../expected/test_ginpostinglist.out          | 19 ++++
 .../sql/test_ginpostinglist.sql               |  7 ++
 .../test_ginpostinglist--1.0.sql              |  8 ++
 .../test_ginpostinglist/test_ginpostinglist.c | 96 +++++++++++++++++++
 .../test_ginpostinglist.control               |  4 +
 9 files changed, 183 insertions(+), 8 deletions(-)
 create mode 100644 src/test/modules/test_ginpostinglist/Makefile
 create mode 100644 src/test/modules/test_ginpostinglist/README
 create mode 100644 src/test/modules/test_ginpostinglist/expected/test_ginpostinglist.out
 create mode 100644 src/test/modules/test_ginpostinglist/sql/test_ginpostinglist.sql
 create mode 100644 src/test/modules/test_ginpostinglist/test_ginpostinglist--1.0.sql
 create mode 100644 src/test/modules/test_ginpostinglist/test_ginpostinglist.c
 create mode 100644 src/test/modules/test_ginpostinglist/test_ginpostinglist.control

diff --git a/src/backend/access/gin/ginpostinglist.c b/src/backend/access/gin/ginpostinglist.c
index 48ccfafdd2..e685e0c1ff 100644
--- a/src/backend/access/gin/ginpostinglist.c
+++ b/src/backend/access/gin/ginpostinglist.c
@@ -26,22 +26,29 @@
  * lowest 32 bits are the block number. That leaves 17 bits unused, i.e.
  * only 43 low bits are used.
  *
+ * 11 bits is enough for the offset number, because MaxHeapTuplesPerPage <
+ * 2^11 on all supported block sizes. We are frugal with the bits, because
+ * smaller integers use fewer bytes in the varbyte encoding, saving disk
+ * space. (If we get a new table AM in the future that wants to use the full
+ * range of possible offset numbers, we'll need to change this.)
+ *
  * These 43-bit integers are encoded using varbyte encoding. In each byte,
  * the 7 low bits contain data, while the highest bit is a continuation bit.
  * When the continuation bit is set, the next byte is part of the same
- * integer, otherwise this is the last byte of this integer.  43 bits fit
- * conveniently in at most 6 bytes when varbyte encoded (the 6th byte does
- * not need a continuation bit, because we know the max size to be 43 bits):
+ * integer, otherwise this is the last byte of this integer. 43 bits need
+ * at most 7 bytes in this encoding:
  *
  * 0XXXXXXX
  * 1XXXXXXX 0XXXXYYY
  * 1XXXXXXX 1XXXXYYY 0YYYYYYY
  * 1XXXXXXX 1XXXXYYY 1YYYYYYY 0YYYYYYY
  * 1XXXXXXX 1XXXXYYY 1YYYYYYY 1YYYYYYY 0YYYYYYY
- * 1XXXXXXX 1XXXXYYY 1YYYYYYY 1YYYYYYY 1YYYYYYY YYYYYYYY
+ * 1XXXXXXX 1XXXXYYY 1YYYYYYY 1YYYYYYY 1YYYYYYY 0YYYYYYY
+ * 1XXXXXXX 1XXXXYYY 1YYYYYYY 1YYYYYYY 1YYYYYYY 1YYYYYYY 0uuuuuuY
  *
  * X = bits used for offset number
  * Y = bits used for block number
+ * u = unused bit
  *
  * The bytes are in stored in little-endian order.
  *
@@ -73,6 +80,9 @@
  */
 #define MaxHeapTuplesPerPageBits		11
 
+/* Max. number of bytes needed to encode the largest supported integer. */
+#define MaxBytesPerInteger				7
+
 static inline uint64
 itemptr_to_uint64(const ItemPointer iptr)
 {
@@ -126,33 +136,40 @@ decode_varbyte(unsigned char **ptr)
 	unsigned char *p = *ptr;
 	uint64		c;
 
+	/* 1st byte */
 	c = *(p++);
 	val = c & 0x7F;
 	if (c & 0x80)
 	{
+		/* 2nd byte */
 		c = *(p++);
 		val |= (c & 0x7F) << 7;
 		if (c & 0x80)
 		{
+			/* 3rd byte */
 			c = *(p++);
 			val |= (c & 0x7F) << 14;
 			if (c & 0x80)
 			{
+				/* 4th byte */
 				c = *(p++);
 				val |= (c & 0x7F) << 21;
 				if (c & 0x80)
 				{
+					/* 5th byte */
 					c = *(p++);
 					val |= (c & 0x7F) << 28;
 					if (c & 0x80)
 					{
+						/* 6th byte */
 						c = *(p++);
 						val |= (c & 0x7F) << 35;
 						if (c & 0x80)
 						{
-							/* last byte, no continuation bit */
+							/* 7th byte, should not have continuation bit */
 							c = *(p++);
 							val |= c << 42;
+							Assert(c & 0x80 == 0);
 						}
 					}
 				}
@@ -208,15 +225,15 @@ ginCompressPostingList(const ItemPointer ipd, int nipd, int maxsize,
 
 		Assert(val > prev);
 
-		if (endptr - ptr >= 6)
+		if (endptr - ptr >= MaxBytesPerInteger)
 			encode_varbyte(delta, &ptr);
 		else
 		{
 			/*
-			 * There are less than 6 bytes left. Have to check if the next
+			 * There are less than 7 bytes left. Have to check if the next
 			 * item fits in that space before writing it out.
 			 */
-			unsigned char buf[6];
+			unsigned char buf[MaxBytesPerInteger];
 			unsigned char *p = buf;
 
 			encode_varbyte(delta, &p);
diff --git a/src/test/modules/Makefile b/src/test/modules/Makefile
index 60d6d7be1b..953905d1ef 100644
--- a/src/test/modules/Makefile
+++ b/src/test/modules/Makefile
@@ -12,6 +12,7 @@ SUBDIRS = \
 		  test_bloomfilter \
 		  test_ddl_deparse \
 		  test_extensions \
+		  test_ginpostinglist \
 		  test_integerset \
 		  test_parser \
 		  test_pg_dump \
diff --git a/src/test/modules/test_ginpostinglist/Makefile b/src/test/modules/test_ginpostinglist/Makefile
new file mode 100644
index 0000000000..4d45ac999a
--- /dev/null
+++ b/src/test/modules/test_ginpostinglist/Makefile
@@ -0,0 +1,21 @@
+# src/test/modules/test_ginpostinglist/Makefile
+
+MODULE_big = test_ginpostinglist
+OBJS = test_ginpostinglist.o $(WIN32RES)
+PGFILEDESC = "test_ginpostinglist - test code for src/backend/access/gin//ginpostinglist.c"
+
+EXTENSION = test_ginpostinglist
+DATA = test_ginpostinglist--1.0.sql
+
+REGRESS = test_ginpostinglist
+
+ifdef USE_PGXS
+PG_CONFIG = pg_config
+PGXS := $(shell $(PG_CONFIG) --pgxs)
+include $(PGXS)
+else
+subdir = src/test/modules/test_ginpostinglist
+top_builddir = ../../../..
+include $(top_builddir)/src/Makefile.global
+include $(top_srcdir)/contrib/contrib-global.mk
+endif
diff --git a/src/test/modules/test_ginpostinglist/README b/src/test/modules/test_ginpostinglist/README
new file mode 100644
index 0000000000..66684dd0da
--- /dev/null
+++ b/src/test/modules/test_ginpostinglist/README
@@ -0,0 +1,2 @@
+test_ginpostinglist contains unit tests for the GIN posting list code in
+src/backend/access/gin/ginpostinglist.c.
diff --git a/src/test/modules/test_ginpostinglist/expected/test_ginpostinglist.out b/src/test/modules/test_ginpostinglist/expected/test_ginpostinglist.out
new file mode 100644
index 0000000000..4d0beaecea
--- /dev/null
+++ b/src/test/modules/test_ginpostinglist/expected/test_ginpostinglist.out
@@ -0,0 +1,19 @@
+CREATE EXTENSION test_ginpostinglist;
+--
+-- All the logic is in the test_ginpostinglist() function. It will throw
+-- a error if something fails.
+--
+SELECT test_ginpostinglist();
+NOTICE:  testing with (0, 1), (0, 2), max 14 bytes
+NOTICE:  encoded 2 item pointers to 10 bytes
+NOTICE:  testing with (0, 1), (0, 291), max 14 bytes
+NOTICE:  encoded 2 item pointers to 10 bytes
+NOTICE:  testing with (0, 1), (4294967294, 291), max 14 bytes
+NOTICE:  encoded 1 item pointers to 8 bytes
+NOTICE:  testing with (0, 1), (4294967294, 291), max 16 bytes
+NOTICE:  encoded 2 item pointers to 16 bytes
+ test_ginpostinglist 
+---------------------
+ 
+(1 row)
+
diff --git a/src/test/modules/test_ginpostinglist/sql/test_ginpostinglist.sql b/src/test/modules/test_ginpostinglist/sql/test_ginpostinglist.sql
new file mode 100644
index 0000000000..b8cab7acce
--- /dev/null
+++ b/src/test/modules/test_ginpostinglist/sql/test_ginpostinglist.sql
@@ -0,0 +1,7 @@
+CREATE EXTENSION test_ginpostinglist;
+
+--
+-- All the logic is in the test_ginpostinglist() function. It will throw
+-- a error if something fails.
+--
+SELECT test_ginpostinglist();
diff --git a/src/test/modules/test_ginpostinglist/test_ginpostinglist--1.0.sql b/src/test/modules/test_ginpostinglist/test_ginpostinglist--1.0.sql
new file mode 100644
index 0000000000..37396a4842
--- /dev/null
+++ b/src/test/modules/test_ginpostinglist/test_ginpostinglist--1.0.sql
@@ -0,0 +1,8 @@
+/* src/test/modules/test_ginpostinglist/test_ginpostinglist--1.0.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "CREATE EXTENSION test_ginpostinglist" to load this file. \quit
+
+CREATE FUNCTION test_ginpostinglist()
+RETURNS pg_catalog.void STRICT
+AS 'MODULE_PATHNAME' LANGUAGE C;
diff --git a/src/test/modules/test_ginpostinglist/test_ginpostinglist.c b/src/test/modules/test_ginpostinglist/test_ginpostinglist.c
new file mode 100644
index 0000000000..bab073bcec
--- /dev/null
+++ b/src/test/modules/test_ginpostinglist/test_ginpostinglist.c
@@ -0,0 +1,96 @@
+/*--------------------------------------------------------------------------
+ *
+ * test_ginpostinglist.c
+ *		Test varbyte-encoding in ginpostinglist.c
+ *
+ * Copyright (c) 2019, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ *		src/test/modules/test_ginpostinglist/test_ginpostinglist.c
+ *
+ * -------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include "fmgr.h"
+#include "access/ginblock.h"
+#include "access/gin_private.h"
+#include "access/htup_details.h"
+
+PG_MODULE_MAGIC;
+
+PG_FUNCTION_INFO_V1(test_ginpostinglist);
+
+/*
+ * Encodes a pair of TIDs, and decodes it back. The first TID is always
+ * (0, 1), the second one is formed from the blk/off arguments. The 'maxsize'
+ * argument is passed to ginCompressPostingList(); it can be used to test the
+ * overflow checks.
+ *
+ * The reason that we test a pair, instead of just a single TID, is that
+ * the GinPostingList stores the first TID as is, and the varbyte-encoding
+ * is only used for the deltas between TIDs. So testing a single TID would
+ * not exercise the varbyte encoding at all.
+ *
+ * This function prints NOTICEs to describe what is tested, and how large the
+ * resulting GinPostingList is. Any incorrect results, e.g. if the encode +
+ * decode round trip doesn't return the original input, are reported as
+ * ERRORs.
+ */
+static void
+test_itemptr_pair(BlockNumber blk, OffsetNumber off, int maxsize)
+{
+	ItemPointerData orig_itemptrs[2];
+	ItemPointer decoded_itemptrs;
+	GinPostingList *pl;
+	int			nwritten;
+	int			ndecoded;
+
+	elog(NOTICE, "testing with (%u, %d), (%u, %d), max %d bytes",
+		 0, 1, blk, off, maxsize);
+	ItemPointerSet(&orig_itemptrs[0], 0, 1);
+	ItemPointerSet(&orig_itemptrs[1], blk, off);
+
+	/* Encode, and decode it back */
+	pl = ginCompressPostingList(orig_itemptrs, 2, maxsize, &nwritten);
+	elog(NOTICE, "encoded %d item pointers to %zu bytes",
+		 nwritten, SizeOfGinPostingList(pl));
+
+	if (SizeOfGinPostingList(pl) > maxsize)
+		elog(ERROR, "overflow: result was %zu bytes, max %d",
+			 SizeOfGinPostingList(pl), maxsize);
+
+	decoded_itemptrs = ginPostingListDecode(pl, &ndecoded);
+	if (nwritten != ndecoded)
+		elog(NOTICE, "encoded %d itemptrs, %d came back", nwritten, ndecoded);
+
+	/* Check the result */
+	if (!ItemPointerEquals(&orig_itemptrs[0], &decoded_itemptrs[0]))
+		elog(ERROR, "mismatch on first itemptr: (%u, %d) vs (%u, %d)",
+			 0, 1,
+			 ItemPointerGetBlockNumber(&decoded_itemptrs[0]),
+			 ItemPointerGetOffsetNumber(&decoded_itemptrs[0]));
+
+	if (ndecoded == 2 &&
+		!ItemPointerEquals(&orig_itemptrs[0], &decoded_itemptrs[0]))
+	{
+		elog(ERROR, "mismatch on second itemptr: (%u, %d) vs (%u, %d)",
+			 0, 1,
+			 ItemPointerGetBlockNumber(&decoded_itemptrs[0]),
+			 ItemPointerGetOffsetNumber(&decoded_itemptrs[0]));
+	}
+}
+
+/*
+ * SQL-callable entry point to perform all tests.
+ */
+Datum
+test_ginpostinglist(PG_FUNCTION_ARGS)
+{
+	test_itemptr_pair(0, 2, 14);
+	test_itemptr_pair(0, MaxHeapTuplesPerPage, 14);
+	test_itemptr_pair(MaxBlockNumber, MaxHeapTuplesPerPage, 14);
+	test_itemptr_pair(MaxBlockNumber, MaxHeapTuplesPerPage, 16);
+
+	PG_RETURN_VOID();
+}
diff --git a/src/test/modules/test_ginpostinglist/test_ginpostinglist.control b/src/test/modules/test_ginpostinglist/test_ginpostinglist.control
new file mode 100644
index 0000000000..e4f5a7cead
--- /dev/null
+++ b/src/test/modules/test_ginpostinglist/test_ginpostinglist.control
@@ -0,0 +1,4 @@
+comment = 'Test code for ginpostinglist.c'
+default_version = '1.0'
+module_pathname = '$libdir/test_ginpostinglist'
+relocatable = true
-- 
2.20.1


--------------5480679FC0D94615B6DB6C64--





^ permalink  raw  reply  [nested|flat] 12+ messages in thread

* [PATCH v29 05/11] Add Incremental View Maintenance support to psql
@ 2019-12-20 01:21 Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 12+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:21 UTC (permalink / raw)

Add tab completion and meta-command output for IVM.
---
 src/bin/psql/describe.c     | 32 +++++++++++++++++++++++++++++++-
 src/bin/psql/tab-complete.c | 14 +++++++++-----
 2 files changed, 40 insertions(+), 6 deletions(-)

diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index bac94a338c..f6c7e7163d 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -1575,6 +1575,7 @@ describeOneTableDetails(const char *schemaname,
 		char		relpersistence;
 		char		relreplident;
 		char	   *relam;
+		bool		isivm;
 	}			tableinfo;
 	bool		show_column_details = false;
 
@@ -1587,7 +1588,26 @@ describeOneTableDetails(const char *schemaname,
 	initPQExpBuffer(&tmpbuf);
 
 	/* Get general table info */
-	if (pset.sversion >= 120000)
+	if (pset.sversion >= 170000)
+	{
+		printfPQExpBuffer(&buf,
+						  "SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
+						  "c.relhastriggers, c.relrowsecurity, c.relforcerowsecurity, "
+						  "false AS relhasoids, c.relispartition, %s, c.reltablespace, "
+						  "CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END, "
+						  "c.relpersistence, c.relreplident, am.amname, "
+						  "c.relisivm\n"
+						  "FROM pg_catalog.pg_class c\n "
+						  "LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid)\n"
+						  "LEFT JOIN pg_catalog.pg_am am ON (c.relam = am.oid)\n"
+						  "WHERE c.oid = '%s';",
+						  (verbose ?
+						   "pg_catalog.array_to_string(c.reloptions || "
+						   "array(select 'toast.' || x from pg_catalog.unnest(tc.reloptions) x), ', ')\n"
+						   : "''"),
+						  oid);
+	}
+	else if (pset.sversion >= 120000)
 	{
 		printfPQExpBuffer(&buf,
 						  "SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
@@ -1707,6 +1727,10 @@ describeOneTableDetails(const char *schemaname,
 			(char *) NULL : pg_strdup(PQgetvalue(res, 0, 14));
 	else
 		tableinfo.relam = NULL;
+	if (pset.sversion >= 170000)
+		tableinfo.isivm = strcmp(PQgetvalue(res, 0, 15), "t") == 0;
+	else
+		tableinfo.isivm = false;
 	PQclear(res);
 	res = NULL;
 
@@ -3552,6 +3576,12 @@ describeOneTableDetails(const char *schemaname,
 			printfPQExpBuffer(&buf, _("Access method: %s"), tableinfo.relam);
 			printTableAddFooter(&cont, buf.data);
 		}
+
+		/* Incremental view maintance info */
+		if (verbose && tableinfo.relkind == RELKIND_MATVIEW && tableinfo.isivm)
+		{
+			printTableAddFooter(&cont, _("Incremental view maintenance: yes"));
+		}
 	}
 
 	/* reloptions, if verbose */
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 779fdc90cb..9cc79b722f 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -1244,6 +1244,7 @@ static const pgsql_thing_t words_after_create[] = {
 	{"FOREIGN TABLE", NULL, NULL, NULL},
 	{"FUNCTION", NULL, NULL, Query_for_list_of_functions},
 	{"GROUP", Query_for_list_of_roles},
+	{"INCREMENTAL MATERIALIZED VIEW", NULL, NULL, &Query_for_list_of_matviews, NULL, THING_NO_DROP | THING_NO_ALTER},
 	{"INDEX", NULL, NULL, &Query_for_list_of_indexes},
 	{"LANGUAGE", Query_for_list_of_languages},
 	{"LARGE OBJECT", NULL, NULL, NULL, NULL, THING_NO_CREATE | THING_NO_DROP},
@@ -3217,7 +3218,7 @@ psql_completion(const char *text, int start, int end)
 		if (HeadMatches("CREATE", "SCHEMA"))
 			COMPLETE_WITH("TABLE", "SEQUENCE");
 		else
-			COMPLETE_WITH("TABLE", "SEQUENCE", "MATERIALIZED VIEW");
+			COMPLETE_WITH("TABLE", "SEQUENCE", "MATERIALIZED VIEW", "INCREMENTAL MATERIALIZED VIEW");
 	}
 	/* Complete PARTITION BY with RANGE ( or LIST ( or ... */
 	else if (TailMatches("PARTITION", "BY"))
@@ -3535,13 +3536,16 @@ psql_completion(const char *text, int start, int end)
 		COMPLETE_WITH("SELECT");
 
 /* CREATE MATERIALIZED VIEW */
-	else if (Matches("CREATE", "MATERIALIZED"))
+	else if (Matches("CREATE", "MATERIALIZED") ||
+			 Matches("CREATE", "INCREMENTAL", "MATERIALIZED"))
 		COMPLETE_WITH("VIEW");
-	/* Complete CREATE MATERIALIZED VIEW <name> with AS */
-	else if (Matches("CREATE", "MATERIALIZED", "VIEW", MatchAny))
+	/* Complete CREATE MATERIALIZED VIEW <name> with AS  */
+	else if (Matches("CREATE", "MATERIALIZED", "VIEW", MatchAny) ||
+			 Matches("CREATE", "INCREMENTAL", "MATERIALIZED", "VIEW", MatchAny))
 		COMPLETE_WITH("AS");
 	/* Complete "CREATE MATERIALIZED VIEW <sth> AS with "SELECT" */
-	else if (Matches("CREATE", "MATERIALIZED", "VIEW", MatchAny, "AS"))
+	else if (Matches("CREATE", "MATERIALIZED", "VIEW", MatchAny, "AS") ||
+			 Matches("CREATE", "INCREMENTAL", "MATERIALIZED", "VIEW", MatchAny, "AS"))
 		COMPLETE_WITH("SELECT");
 
 /* CREATE EVENT TRIGGER */
-- 
2.25.1


--Multipart=_Mon__28_Aug_2023_16_05_30_+0900_b1OvQD_3A3ZMTGvj
Content-Type: text/x-diff;
 name="v29-0006-Add-Incremental-View-Maintenance-support.patch"
Content-Disposition: attachment;
 filename="v29-0006-Add-Incremental-View-Maintenance-support.patch"
Content-Transfer-Encoding: 7bit



^ permalink  raw  reply  [nested|flat] 12+ messages in thread

* Re: Allow tests to pass in OpenSSL FIPS mode
@ 2023-11-14 23:07 Tom Lane <[email protected]>
  2023-11-15 10:06 ` Re: Allow tests to pass in OpenSSL FIPS mode Daniel Gustafsson <[email protected]>
  2023-11-15 11:44 ` Re: Allow tests to pass in OpenSSL FIPS mode Peter Eisentraut <[email protected]>
  2025-09-14 19:02 ` Re: Allow tests to pass in OpenSSL FIPS mode Tom Lane <[email protected]>
  0 siblings, 3 replies; 12+ messages in thread

From: Tom Lane @ 2023-11-14 23:07 UTC (permalink / raw)
  To: Peter Eisentraut <[email protected]>; +Cc: pgsql-hackers

Peter Eisentraut <[email protected]> writes:
> On 05.10.23 22:55, Tom Lane wrote:
>> I found another bit of fun we'll need to deal with: on my F38
>> platform, pgcrypto/3des fails as attached.  Some googling finds
>> this relevant info:
>> https://github.com/pyca/cryptography/issues/6875
>> That is, FIPS deprecation of 3DES is happening even as we speak.
>> So apparently we'll have little choice but to deal with two
>> different behaviors for that.

> I've been trying to get some VM set up with the right Red Hat 
> environment to be able to reproduce the issues you reported.  But 
> somehow switching the OS into FIPS mode messes up the boot environment 
> of the VM or something.  So I haven't been able to make progress on this.

Hm.  I was just using a native install on a microSD card for my
raspberry pi ...

> I suggest that if there are no other concerns, we proceed with the patch 
> set as is for now.

After thinking about it for awhile, I guess I'm okay with only
bothering to provide expected-files for FIPS failures under OpenSSL
3.x (which is how your patch is set up, I believe).  While there are
certainly still LTS platforms with 1.x, we don't have to consider FIPS
mode on them to be a supported case.

I'm more concerned about the 3DES situation.  Fedora might be a bit
ahead of the curve here, but according to the link above, everybody is
supposed to be in compliance by the end of 2023.  So I'd be inclined
to guess that the 3DES-is-rejected case is going to be mainstream
before v17 ships.

> The error message difference in the older OpenSSL version would probably 
> need a small bit of coding.  But we can leave that as a separate add-on 
> project.

It's the *newer* version's message that I'm unhappy about ;-).
But I agree that that's not a reason to hold up applying what's
here.  (In reality, people running FIPS mode are probably pretty
accustomed to seeing this error, so maybe it's not worth the
trouble to improve it.)

			regards, tom lane






^ permalink  raw  reply  [nested|flat] 12+ messages in thread

* Re: Allow tests to pass in OpenSSL FIPS mode
  2023-11-14 23:07 Re: Allow tests to pass in OpenSSL FIPS mode Tom Lane <[email protected]>
@ 2023-11-15 10:06 ` Daniel Gustafsson <[email protected]>
  2 siblings, 0 replies; 12+ messages in thread

From: Daniel Gustafsson @ 2023-11-15 10:06 UTC (permalink / raw)
  To: Tom Lane <[email protected]>; +Cc: Peter Eisentraut <[email protected]>; pgsql-hackers

> On 15 Nov 2023, at 00:07, Tom Lane <[email protected]> wrote:

> (In reality, people running FIPS mode are probably pretty
> accustomed to seeing this error, so maybe it's not worth the
> trouble to improve it.)

In my experience this holds a lot of truth, this is a common error pattern and
while all improvements to error messages are good, it's not a reason to hold
off this patch.

--
Daniel Gustafsson







^ permalink  raw  reply  [nested|flat] 12+ messages in thread

* Re: Allow tests to pass in OpenSSL FIPS mode
  2023-11-14 23:07 Re: Allow tests to pass in OpenSSL FIPS mode Tom Lane <[email protected]>
@ 2023-11-15 11:44 ` Peter Eisentraut <[email protected]>
  2023-11-15 14:25   ` Re: Allow tests to pass in OpenSSL FIPS mode Daniel Gustafsson <[email protected]>
  2 siblings, 1 reply; 12+ messages in thread

From: Peter Eisentraut @ 2023-11-15 11:44 UTC (permalink / raw)
  To: Tom Lane <[email protected]>; +Cc: pgsql-hackers

On 15.11.23 00:07, Tom Lane wrote:
> I'm more concerned about the 3DES situation.  Fedora might be a bit
> ahead of the curve here, but according to the link above, everybody is
> supposed to be in compliance by the end of 2023.  So I'd be inclined
> to guess that the 3DES-is-rejected case is going to be mainstream
> before v17 ships.

Right.  It is curious that I have not found any activity in the OpenSSL 
issue trackers about this.  But if you send me your results file, then I 
can include it in the patch as an alternative expected.







^ permalink  raw  reply  [nested|flat] 12+ messages in thread

* Re: Allow tests to pass in OpenSSL FIPS mode
  2023-11-14 23:07 Re: Allow tests to pass in OpenSSL FIPS mode Tom Lane <[email protected]>
  2023-11-15 11:44 ` Re: Allow tests to pass in OpenSSL FIPS mode Peter Eisentraut <[email protected]>
@ 2023-11-15 14:25   ` Daniel Gustafsson <[email protected]>
  2023-11-15 20:29     ` Re: Allow tests to pass in OpenSSL FIPS mode Tom Lane <[email protected]>
  0 siblings, 1 reply; 12+ messages in thread

From: Daniel Gustafsson @ 2023-11-15 14:25 UTC (permalink / raw)
  To: Peter Eisentraut <[email protected]>; +Cc: Tom Lane <[email protected]>; pgsql-hackers

> On 15 Nov 2023, at 12:44, Peter Eisentraut <[email protected]> wrote:
> 
> On 15.11.23 00:07, Tom Lane wrote:
>> I'm more concerned about the 3DES situation.  Fedora might be a bit
>> ahead of the curve here, but according to the link above, everybody is
>> supposed to be in compliance by the end of 2023.  So I'd be inclined
>> to guess that the 3DES-is-rejected case is going to be mainstream
>> before v17 ships.
> 
> Right.  It is curious that I have not found any activity in the OpenSSL issue trackers about this.  But if you send me your results file, then I can include it in the patch as an alternative expected.

As NIST SP800-131A allows decryption with 3DES and DES I dont think OpenSSL
will do much other than move it to the legacy module where it can be used
opt-in like DES.  SKIPJACK is already disallowed since before but is still
tested with decryption during FIPS validation.

Using an alternative resultsfile to handle platforms which explicitly removes
disallowed ciphers seem like the right choice.

Since the 3DES/DES deprecations aren't limited to FIPS, do we want to do
anything for pgcrypto where we have DES/3DES encryption?  Maybe a doc patch
which mentions the deprecation with a link to the SP could be in order?

--
Daniel Gustafsson







^ permalink  raw  reply  [nested|flat] 12+ messages in thread

* Re: Allow tests to pass in OpenSSL FIPS mode
  2023-11-14 23:07 Re: Allow tests to pass in OpenSSL FIPS mode Tom Lane <[email protected]>
  2023-11-15 11:44 ` Re: Allow tests to pass in OpenSSL FIPS mode Peter Eisentraut <[email protected]>
  2023-11-15 14:25   ` Re: Allow tests to pass in OpenSSL FIPS mode Daniel Gustafsson <[email protected]>
@ 2023-11-15 20:29     ` Tom Lane <[email protected]>
  2023-11-17 18:45       ` Re: Allow tests to pass in OpenSSL FIPS mode Peter Eisentraut <[email protected]>
  0 siblings, 1 reply; 12+ messages in thread

From: Tom Lane @ 2023-11-15 20:29 UTC (permalink / raw)
  To: Daniel Gustafsson <[email protected]>; +Cc: Peter Eisentraut <[email protected]>; pgsql-hackers

Daniel Gustafsson <[email protected]> writes:
> Since the 3DES/DES deprecations aren't limited to FIPS, do we want to do
> anything for pgcrypto where we have DES/3DES encryption?  Maybe a doc patch
> which mentions the deprecation with a link to the SP could be in order?

A docs patch that marks both MD5 and 3DES as deprecated is probably
appropriate, but it seems like a matter for a separate thread and patch.

In the meantime, I've done a pass of review of Peter's v4 patches.
v4-0001 is already committed, so that's not considered here.

v4-0002: I think it is worth splitting up contrib/pgcrypto's
pgp-encrypt test, which has only one test case whose output changes,
and a bunch of others that don't.  v5-0002, attached, does it
like that.  It's otherwise the same as v4.

(It might be worth doing something similar for uuid_ossp's test,
but I have not bothered here.  That test script is stable enough
that I'm not too worried about future maintenance.)

The attached 0003, 0004, 0005 patches are identical to Peter's.
I think that it is possibly worth modifying the password test so that
we don't fail to create the roles, so as to reduce the delta between
password.out and password_1.out (and thereby ease future maintenance
of those files).  However you might disagree, so I split my proposal
out as a separate patch v5-0007-password-test-delta.patch; you can
drop that from the set if you don't like it.

v5-0006-allow-for-disabled-3DES.patch adds the necessary expected
file to make that pass on my Fedora 38 system.

With or without 0007, as you choose, I think it's committable.

			regards, tom lane



Attachments:

  [text/x-diff] v5-0002-pgcrypto-Allow-tests-to-pass-in-OpenSSL-FIPS-mode.patch (6.8K, ../../[email protected]/2-v5-0002-pgcrypto-Allow-tests-to-pass-in-OpenSSL-FIPS-mode.patch)
  download | inline diff:
diff --git a/contrib/pgcrypto/Makefile b/contrib/pgcrypto/Makefile
index 7fb59f51b7..5efa10c334 100644
--- a/contrib/pgcrypto/Makefile
+++ b/contrib/pgcrypto/Makefile
@@ -42,7 +42,7 @@ PGFILEDESC = "pgcrypto - cryptographic functions"
 REGRESS = init md5 sha1 hmac-md5 hmac-sha1 blowfish rijndael \
 	sha2 des 3des cast5 \
 	crypt-des crypt-md5 crypt-blowfish crypt-xdes \
-	pgp-armor pgp-decrypt pgp-encrypt $(CF_PGP_TESTS) \
+	pgp-armor pgp-decrypt pgp-encrypt pgp-encrypt-md5 $(CF_PGP_TESTS) \
 	pgp-pubkey-decrypt pgp-pubkey-encrypt pgp-info
 
 EXTRA_CLEAN = gen-rtab
diff --git a/contrib/pgcrypto/expected/crypt-md5_1.out b/contrib/pgcrypto/expected/crypt-md5_1.out
new file mode 100644
index 0000000000..0ffda34ab4
--- /dev/null
+++ b/contrib/pgcrypto/expected/crypt-md5_1.out
@@ -0,0 +1,16 @@
+--
+-- crypt() and gen_salt(): md5
+--
+SELECT crypt('', '$1$Szzz0yzz');
+ERROR:  crypt(3) returned NULL
+SELECT crypt('foox', '$1$Szzz0yzz');
+ERROR:  crypt(3) returned NULL
+CREATE TABLE ctest (data text, res text, salt text);
+INSERT INTO ctest VALUES ('password', '', '');
+UPDATE ctest SET salt = gen_salt('md5');
+UPDATE ctest SET res = crypt(data, salt);
+ERROR:  crypt(3) returned NULL
+SELECT res = crypt(data, res) AS "worked"
+FROM ctest;
+ERROR:  invalid salt
+DROP TABLE ctest;
diff --git a/contrib/pgcrypto/expected/hmac-md5_1.out b/contrib/pgcrypto/expected/hmac-md5_1.out
new file mode 100644
index 0000000000..56875b0f63
--- /dev/null
+++ b/contrib/pgcrypto/expected/hmac-md5_1.out
@@ -0,0 +1,44 @@
+--
+-- HMAC-MD5
+--
+SELECT hmac(
+'Hi There',
+'\x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b'::bytea,
+'md5');
+ERROR:  Cannot use "md5": Cipher cannot be initialized
+-- 2
+SELECT hmac(
+'Jefe',
+'what do ya want for nothing?',
+'md5');
+ERROR:  Cannot use "md5": Cipher cannot be initialized
+-- 3
+SELECT hmac(
+'\xdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd'::bytea,
+'\xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'::bytea,
+'md5');
+ERROR:  Cannot use "md5": Cipher cannot be initialized
+-- 4
+SELECT hmac(
+'\xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd'::bytea,
+'\x0102030405060708090a0b0c0d0e0f10111213141516171819'::bytea,
+'md5');
+ERROR:  Cannot use "md5": Cipher cannot be initialized
+-- 5
+SELECT hmac(
+'Test With Truncation',
+'\x0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c'::bytea,
+'md5');
+ERROR:  Cannot use "md5": Cipher cannot be initialized
+-- 6
+SELECT hmac(
+'Test Using Larger Than Block-Size Key - Hash Key First',
+'\xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'::bytea,
+'md5');
+ERROR:  Cannot use "md5": Cipher cannot be initialized
+-- 7
+SELECT hmac(
+'Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data',
+'\xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'::bytea,
+'md5');
+ERROR:  Cannot use "md5": Cipher cannot be initialized
diff --git a/contrib/pgcrypto/expected/md5_1.out b/contrib/pgcrypto/expected/md5_1.out
new file mode 100644
index 0000000000..decb215c48
--- /dev/null
+++ b/contrib/pgcrypto/expected/md5_1.out
@@ -0,0 +1,17 @@
+--
+-- MD5 message digest
+--
+SELECT digest('', 'md5');
+ERROR:  Cannot use "md5": Cipher cannot be initialized
+SELECT digest('a', 'md5');
+ERROR:  Cannot use "md5": Cipher cannot be initialized
+SELECT digest('abc', 'md5');
+ERROR:  Cannot use "md5": Cipher cannot be initialized
+SELECT digest('message digest', 'md5');
+ERROR:  Cannot use "md5": Cipher cannot be initialized
+SELECT digest('abcdefghijklmnopqrstuvwxyz', 'md5');
+ERROR:  Cannot use "md5": Cipher cannot be initialized
+SELECT digest('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789', 'md5');
+ERROR:  Cannot use "md5": Cipher cannot be initialized
+SELECT digest('12345678901234567890123456789012345678901234567890123456789012345678901234567890', 'md5');
+ERROR:  Cannot use "md5": Cipher cannot be initialized
diff --git a/contrib/pgcrypto/expected/pgp-encrypt-md5.out b/contrib/pgcrypto/expected/pgp-encrypt-md5.out
new file mode 100644
index 0000000000..339e12a434
--- /dev/null
+++ b/contrib/pgcrypto/expected/pgp-encrypt-md5.out
@@ -0,0 +1,11 @@
+--
+-- PGP encrypt using MD5
+--
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret.', 'key', 's2k-digest-algo=md5'),
+	'key', 'expect-s2k-digest-algo=md5');
+ pgp_sym_decrypt 
+-----------------
+ Secret.
+(1 row)
+
diff --git a/contrib/pgcrypto/expected/pgp-encrypt-md5_1.out b/contrib/pgcrypto/expected/pgp-encrypt-md5_1.out
new file mode 100644
index 0000000000..612ca1d19c
--- /dev/null
+++ b/contrib/pgcrypto/expected/pgp-encrypt-md5_1.out
@@ -0,0 +1,7 @@
+--
+-- PGP encrypt using MD5
+--
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret.', 'key', 's2k-digest-algo=md5'),
+	'key', 'expect-s2k-digest-algo=md5');
+ERROR:  Unsupported digest algorithm
diff --git a/contrib/pgcrypto/expected/pgp-encrypt.out b/contrib/pgcrypto/expected/pgp-encrypt.out
index 77e45abe53..50cd3f6daa 100644
--- a/contrib/pgcrypto/expected/pgp-encrypt.out
+++ b/contrib/pgcrypto/expected/pgp-encrypt.out
@@ -121,14 +121,6 @@ NOTICE:  pgp_decrypt: unexpected s2k_count: expected 65000000 got 65011712
 (1 row)
 
 -- s2k digest change
-select pgp_sym_decrypt(
-	pgp_sym_encrypt('Secret.', 'key', 's2k-digest-algo=md5'),
-	'key', 'expect-s2k-digest-algo=md5');
- pgp_sym_decrypt 
------------------
- Secret.
-(1 row)
-
 select pgp_sym_decrypt(
 		pgp_sym_encrypt('Secret.', 'key', 's2k-digest-algo=sha1'),
 	'key', 'expect-s2k-digest-algo=sha1');
diff --git a/contrib/pgcrypto/meson.build b/contrib/pgcrypto/meson.build
index df7dd50dbc..4f62ea0af0 100644
--- a/contrib/pgcrypto/meson.build
+++ b/contrib/pgcrypto/meson.build
@@ -48,6 +48,7 @@ pgcrypto_regress = [
   'pgp-armor',
   'pgp-decrypt',
   'pgp-encrypt',
+  'pgp-encrypt-md5',
   'pgp-pubkey-decrypt',
   'pgp-pubkey-encrypt',
   'pgp-info',
diff --git a/contrib/pgcrypto/sql/pgp-encrypt-md5.sql b/contrib/pgcrypto/sql/pgp-encrypt-md5.sql
new file mode 100644
index 0000000000..201636c820
--- /dev/null
+++ b/contrib/pgcrypto/sql/pgp-encrypt-md5.sql
@@ -0,0 +1,7 @@
+--
+-- PGP encrypt using MD5
+--
+
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret.', 'key', 's2k-digest-algo=md5'),
+	'key', 'expect-s2k-digest-algo=md5');
diff --git a/contrib/pgcrypto/sql/pgp-encrypt.sql b/contrib/pgcrypto/sql/pgp-encrypt.sql
index ed8b17776b..f67329c2c3 100644
--- a/contrib/pgcrypto/sql/pgp-encrypt.sql
+++ b/contrib/pgcrypto/sql/pgp-encrypt.sql
@@ -63,9 +63,6 @@ select pgp_sym_decrypt(
 	'key', 'expect-s2k-count=65000000');
 
 -- s2k digest change
-select pgp_sym_decrypt(
-	pgp_sym_encrypt('Secret.', 'key', 's2k-digest-algo=md5'),
-	'key', 'expect-s2k-digest-algo=md5');
 select pgp_sym_decrypt(
 		pgp_sym_encrypt('Secret.', 'key', 's2k-digest-algo=sha1'),
 	'key', 'expect-s2k-digest-algo=sha1');


  [text/x-diff] v5-0003-Allow-tests-to-pass-in-OpenSSL-FIPS-mode-TAP-test.patch (12.9K, ../../[email protected]/3-v5-0003-Allow-tests-to-pass-in-OpenSSL-FIPS-mode-TAP-test.patch)
  download | inline diff:
From 8feace1abca7aad6b9a9a58f464d571649e2d1e2 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Thu, 5 Oct 2023 14:45:35 +0200
Subject: [PATCH v4 3/5] Allow tests to pass in OpenSSL FIPS mode (TAP tests)

Some tests using md5 authentication have to be skipped.  In other
cases, we can rewrite the tests to use a different authentication
method.
---
 src/test/authentication/t/001_password.pl | 121 ++++++++++++----------
 src/test/ssl/t/002_scram.pl               |  32 +++---
 2 files changed, 86 insertions(+), 67 deletions(-)

diff --git a/src/test/authentication/t/001_password.pl b/src/test/authentication/t/001_password.pl
index 891860886a..884f44d45d 100644
--- a/src/test/authentication/t/001_password.pl
+++ b/src/test/authentication/t/001_password.pl
@@ -66,24 +66,26 @@ sub test_conn
 $node->append_conf('postgresql.conf', "log_connections = on\n");
 $node->start;
 
+my $md5_works = ($node->psql('postgres', "select md5('')") == 0);
+
 # Create 3 roles with different password methods for each one. The same
 # password is used for all of them.
-$node->safe_psql('postgres',
+is($node->psql('postgres',
 	"SET password_encryption='scram-sha-256'; CREATE ROLE scram_role LOGIN PASSWORD 'pass';"
-);
-$node->safe_psql('postgres',
+), 0, 'created user with scram password');
+is($node->psql('postgres',
 	"SET password_encryption='md5'; CREATE ROLE md5_role LOGIN PASSWORD 'pass';"
-);
+), $md5_works ? 0 : 3, 'created user with md5 password');
 # Set up a table for tests of SYSTEM_USER.
 $node->safe_psql(
 	'postgres',
 	"CREATE TABLE sysuser_data (n) AS SELECT NULL FROM generate_series(1, 10);
-	 GRANT ALL ON sysuser_data TO md5_role;");
+	 GRANT ALL ON sysuser_data TO scram_role;");
 $ENV{"PGPASSWORD"} = 'pass';
 
 # Create a role that contains a comma to stress the parsing.
 $node->safe_psql('postgres',
-	q{SET password_encryption='md5'; CREATE ROLE "md5,role" LOGIN PASSWORD 'pass';}
+	q{SET password_encryption='scram-sha-256'; CREATE ROLE "scram,role" LOGIN PASSWORD 'pass';}
 );
 
 # Create a role with a non-default iteration count
@@ -141,8 +143,11 @@ sub test_conn
 test_conn($node, 'user=scram_role', 'trust', 0,
 	log_like =>
 	  [qr/connection authenticated: user="scram_role" method=trust/]);
-test_conn($node, 'user=md5_role', 'trust', 0,
-	log_like => [qr/connection authenticated: user="md5_role" method=trust/]);
+SKIP: {
+	skip "MD5 not supported" unless $md5_works;
+	test_conn($node, 'user=md5_role', 'trust', 0,
+		log_like => [qr/connection authenticated: user="md5_role" method=trust/]);
+}
 
 # SYSTEM_USER is null when not authenticated.
 $res = $node->safe_psql('postgres', "SELECT SYSTEM_USER IS NULL;");
@@ -157,7 +162,7 @@ sub test_conn
         SET max_parallel_workers_per_gather TO 2;
 
         SELECT bool_and(SYSTEM_USER IS NOT DISTINCT FROM n) FROM sysuser_data;),
-	connstr => "user=md5_role");
+	connstr => "user=scram_role");
 is($res, 't',
 	"users with trust authentication use SYSTEM_USER = NULL in parallel workers"
 );
@@ -275,9 +280,12 @@ sub test_conn
 test_conn($node, 'user=scram_role', 'password', 0,
 	log_like =>
 	  [qr/connection authenticated: identity="scram_role" method=password/]);
-test_conn($node, 'user=md5_role', 'password', 0,
-	log_like =>
-	  [qr/connection authenticated: identity="md5_role" method=password/]);
+SKIP: {
+	skip "MD5 not supported" unless $md5_works;
+	test_conn($node, 'user=md5_role', 'password', 0,
+		log_like =>
+		  [qr/connection authenticated: identity="md5_role" method=password/]);
+}
 
 # require_auth succeeds here with a plaintext password.
 $node->connect_ok("user=scram_role require_auth=password",
@@ -393,59 +401,62 @@ sub test_conn
 test_conn($node, 'user=scram_role', 'md5', 0,
 	log_like =>
 	  [qr/connection authenticated: identity="scram_role" method=md5/]);
-test_conn($node, 'user=md5_role', 'md5', 0,
-	log_like =>
-	  [qr/connection authenticated: identity="md5_role" method=md5/]);
+SKIP: {
+	skip "MD5 not supported" unless $md5_works;
+	test_conn($node, 'user=md5_role', 'md5', 0,
+		log_like =>
+		  [qr/connection authenticated: identity="md5_role" method=md5/]);
+}
 
-# require_auth succeeds with MD5 required.
-$node->connect_ok("user=md5_role require_auth=md5",
-	"MD5 authentication required, works with MD5 auth");
-$node->connect_ok("user=md5_role require_auth=!none",
-	"any authentication required, works with MD5 auth");
+# require_auth succeeds with SCRAM required.
+$node->connect_ok("user=scram_role require_auth=scram-sha-256",
+	"SCRAM authentication required, works with SCRAM auth");
+$node->connect_ok("user=scram_role require_auth=!none",
+	"any authentication required, works with SCRAM auth");
 $node->connect_ok(
-	"user=md5_role require_auth=md5,scram-sha-256,password",
-	"multiple authentication types required, works with MD5 auth");
+	"user=scram_role require_auth=md5,scram-sha-256,password",
+	"multiple authentication types required, works with SCRAM auth");
 
 # Authentication fails if other types are required.
 $node->connect_fails(
-	"user=md5_role require_auth=password",
-	"password authentication required, fails with MD5 auth",
+	"user=scram_role require_auth=password",
+	"password authentication required, fails with SCRAM auth",
 	expected_stderr =>
-	  qr/authentication method requirement "password" failed: server requested a hashed password/
+	  qr/authentication method requirement "password" failed: server requested SASL authentication/
 );
 $node->connect_fails(
-	"user=md5_role require_auth=scram-sha-256",
-	"SCRAM authentication required, fails with MD5 auth",
+	"user=scram_role require_auth=md5",
+	"MD5 authentication required, fails with SCRAM auth",
 	expected_stderr =>
-	  qr/authentication method requirement "scram-sha-256" failed: server requested a hashed password/
+	  qr/authentication method requirement "md5" failed: server requested SASL authentication/
 );
 $node->connect_fails(
-	"user=md5_role require_auth=none",
-	"all authentication types forbidden, fails with MD5 auth",
+	"user=scram_role require_auth=none",
+	"all authentication types forbidden, fails with SCRAM auth",
 	expected_stderr =>
-	  qr/authentication method requirement "none" failed: server requested a hashed password/
+	  qr/authentication method requirement "none" failed: server requested SASL authentication/
 );
 
-# Authentication fails if MD5 is forbidden.
+# Authentication fails if SCRAM is forbidden.
 $node->connect_fails(
-	"user=md5_role require_auth=!md5",
-	"password authentication forbidden, fails with MD5 auth",
+	"user=scram_role require_auth=!scram-sha-256",
+	"password authentication forbidden, fails with SCRAM auth",
 	expected_stderr =>
-	  qr/authentication method requirement "!md5" failed: server requested a hashed password/
+	  qr/authentication method requirement "!scram-sha-256" failed: server requested SASL authentication/
 );
 $node->connect_fails(
-	"user=md5_role require_auth=!password,!md5,!scram-sha-256",
-	"multiple authentication types forbidden, fails with MD5 auth",
+	"user=scram_role require_auth=!password,!md5,!scram-sha-256",
+	"multiple authentication types forbidden, fails with SCRAM auth",
 	expected_stderr =>
-	  qr/authentication method requirement "!password,!md5,!scram-sha-256" failed: server requested a hashed password/
+	  qr/authentication method requirement "!password,!md5,!scram-sha-256" failed: server requested SASL authentication/
 );
 
 # Test SYSTEM_USER <> NULL with parallel workers.
 $node->safe_psql(
 	'postgres',
 	"TRUNCATE sysuser_data;
-INSERT INTO sysuser_data SELECT 'md5:md5_role' FROM generate_series(1, 10);",
-	connstr => "user=md5_role");
+INSERT INTO sysuser_data SELECT 'md5:scram_role' FROM generate_series(1, 10);",
+	connstr => "user=scram_role");
 $res = $node->safe_psql(
 	'postgres', qq(
         SET min_parallel_table_scan_size TO 0;
@@ -454,7 +465,7 @@ sub test_conn
         SET max_parallel_workers_per_gather TO 2;
 
         SELECT bool_and(SYSTEM_USER IS NOT DISTINCT FROM n) FROM sysuser_data;),
-	connstr => "user=md5_role");
+	connstr => "user=scram_role");
 is($res, 't',
 	"users with md5 authentication use SYSTEM_USER = md5:role in parallel workers"
 );
@@ -490,49 +501,49 @@ sub test_conn
 
 append_to_file(
 	$pgpassfile, qq!
-*:*:*:md5_role:p\\ass
-*:*:*:md5,role:p\\ass
+*:*:*:scram_role:p\\ass
+*:*:*:scram,role:p\\ass
 !);
 
-test_conn($node, 'user=md5_role', 'password from pgpass', 0);
+test_conn($node, 'user=scram_role', 'password from pgpass', 0);
 
 # Testing with regular expression for username.  The third regexp matches.
-reset_pg_hba($node, 'all', '/^.*nomatch.*$, baduser, /^md.*$', 'password');
-test_conn($node, 'user=md5_role', 'password, matching regexp for username', 0,
+reset_pg_hba($node, 'all', '/^.*nomatch.*$, baduser, /^scr.*$', 'password');
+test_conn($node, 'user=scram_role', 'password, matching regexp for username', 0,
 	log_like =>
-	  [qr/connection authenticated: identity="md5_role" method=password/]);
+	  [qr/connection authenticated: identity="scram_role" method=password/]);
 
 # The third regex does not match anymore.
-reset_pg_hba($node, 'all', '/^.*nomatch.*$, baduser, /^m_d.*$', 'password');
-test_conn($node, 'user=md5_role',
+reset_pg_hba($node, 'all', '/^.*nomatch.*$, baduser, /^sc_r.*$', 'password');
+test_conn($node, 'user=scram_role',
 	'password, non matching regexp for username',
 	2, log_unlike => [qr/connection authenticated:/]);
 
 # Test with a comma in the regular expression.  In this case, the use of
 # double quotes is mandatory so as this is not considered as two elements
 # of the user name list when parsing pg_hba.conf.
-reset_pg_hba($node, 'all', '"/^.*5,.*e$"', 'password');
-test_conn($node, 'user=md5,role', 'password, matching regexp for username', 0,
+reset_pg_hba($node, 'all', '"/^.*m,.*e$"', 'password');
+test_conn($node, 'user=scram,role', 'password, matching regexp for username', 0,
 	log_like =>
-	  [qr/connection authenticated: identity="md5,role" method=password/]);
+	  [qr/connection authenticated: identity="scram,role" method=password/]);
 
 # Testing with regular expression for dbname. The third regex matches.
 reset_pg_hba($node, '/^.*nomatch.*$, baddb, /^regex_t.*b$', 'all',
 	'password');
 test_conn(
 	$node,
-	'user=md5_role dbname=regex_testdb',
+	'user=scram_role dbname=regex_testdb',
 	'password, matching regexp for dbname',
 	0,
 	log_like =>
-	  [qr/connection authenticated: identity="md5_role" method=password/]);
+	  [qr/connection authenticated: identity="scram_role" method=password/]);
 
 # The third regexp does not match anymore.
 reset_pg_hba($node, '/^.*nomatch.*$, baddb, /^regex_t.*ba$',
 	'all', 'password');
 test_conn(
 	$node,
-	'user=md5_role dbname=regex_testdb',
+	'user=scram_role dbname=regex_testdb',
 	'password, non matching regexp for dbname',
 	2, log_unlike => [qr/connection authenticated:/]);
 
diff --git a/src/test/ssl/t/002_scram.pl b/src/test/ssl/t/002_scram.pl
index 27abd02abf..d187f532de 100644
--- a/src/test/ssl/t/002_scram.pl
+++ b/src/test/ssl/t/002_scram.pl
@@ -64,6 +64,8 @@ sub switch_server_cert
 $ENV{PGPORT} = $node->port;
 $node->start;
 
+my $md5_works = ($node->psql('postgres', "select md5('')") == 0);
+
 # Configure server for SSL connections, with password handling.
 $ssl_server->configure_test_server_for_ssl(
 	$node, $SERVERHOSTADDR, $SERVERHOSTCIDR,
@@ -91,12 +93,15 @@ sub switch_server_cert
 	"SCRAM with SSL and channel_binding=require");
 
 # Now test when the user has an MD5-encrypted password; should fail
-$node->connect_fails(
-	"$common_connstr user=md5testuser channel_binding=require",
-	"MD5 with SSL and channel_binding=require",
-	expected_stderr =>
-	  qr/channel binding required but not supported by server's authentication request/
-);
+SKIP: {
+	skip "MD5 not supported" unless $md5_works;
+	$node->connect_fails(
+		"$common_connstr user=md5testuser channel_binding=require",
+		"MD5 with SSL and channel_binding=require",
+		expected_stderr =>
+		qr/channel binding required but not supported by server's authentication request/
+	);
+}
 
 # Now test with auth method 'cert' by connecting to 'certdb'. Should fail,
 # because channel binding is not performed.  Note that ssl/client.key may
@@ -130,12 +135,15 @@ sub switch_server_cert
 	"$common_connstr user=ssltestuser channel_binding=disable require_auth=scram-sha-256",
 	"SCRAM with SSL, channel_binding=disable, and require_auth=scram-sha-256"
 );
-$node->connect_fails(
-	"$common_connstr user=md5testuser require_auth=md5 channel_binding=require",
-	"channel_binding can fail even when require_auth succeeds",
-	expected_stderr =>
-	  qr/channel binding required but not supported by server's authentication request/
-);
+SKIP: {
+	skip "MD5 not supported" unless $md5_works;
+	$node->connect_fails(
+		"$common_connstr user=md5testuser require_auth=md5 channel_binding=require",
+		"channel_binding can fail even when require_auth succeeds",
+		expected_stderr =>
+		qr/channel binding required but not supported by server's authentication request/
+	);
+}
 $node->connect_ok(
 	"$common_connstr user=ssltestuser channel_binding=require require_auth=scram-sha-256",
 	"SCRAM with SSL, channel_binding=require, and require_auth=scram-sha-256"
-- 
2.42.0



  [text/x-diff] v5-0004-Allow-tests-to-pass-in-OpenSSL-FIPS-mode-rest.patch (16.6K, ../../[email protected]/4-v5-0004-Allow-tests-to-pass-in-OpenSSL-FIPS-mode-rest.patch)
  download | inline diff:
From d1470936ab5784b1dafc5fdc777dd8004c5f57ba Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Thu, 5 Oct 2023 14:45:35 +0200
Subject: [PATCH v4 4/5] Allow tests to pass in OpenSSL FIPS mode (rest)

This adds alternative expected files for various tests.

XXX maybe some of these could be reorgnized to make the patch smaller?
---
 .../expected/passwordcheck_1.out              |  18 +++
 contrib/uuid-ossp/expected/uuid_ossp_1.out    | 135 ++++++++++++++++
 src/test/regress/expected/md5_1.out           |  35 ++++
 src/test/regress/expected/password_1.out      | 150 ++++++++++++++++++
 4 files changed, 338 insertions(+)
 create mode 100644 contrib/passwordcheck/expected/passwordcheck_1.out
 create mode 100644 contrib/uuid-ossp/expected/uuid_ossp_1.out
 create mode 100644 src/test/regress/expected/md5_1.out
 create mode 100644 src/test/regress/expected/password_1.out

diff --git a/contrib/passwordcheck/expected/passwordcheck_1.out b/contrib/passwordcheck/expected/passwordcheck_1.out
new file mode 100644
index 0000000000..5d8d5dcc1c
--- /dev/null
+++ b/contrib/passwordcheck/expected/passwordcheck_1.out
@@ -0,0 +1,18 @@
+LOAD 'passwordcheck';
+CREATE USER regress_passwordcheck_user1;
+-- ok
+ALTER USER regress_passwordcheck_user1 PASSWORD 'a_nice_long_password';
+-- error: too short
+ALTER USER regress_passwordcheck_user1 PASSWORD 'tooshrt';
+ERROR:  password is too short
+-- error: contains user name
+ALTER USER regress_passwordcheck_user1 PASSWORD 'xyzregress_passwordcheck_user1';
+ERROR:  password must not contain user name
+-- error: contains only letters
+ALTER USER regress_passwordcheck_user1 PASSWORD 'alessnicelongpassword';
+ERROR:  password must contain both letters and nonletters
+-- encrypted ok (password is "secret")
+ALTER USER regress_passwordcheck_user1 PASSWORD 'md592350e12ac34e52dd598f90893bb3ae7';
+-- error: password is user name
+ALTER USER regress_passwordcheck_user1 PASSWORD 'md507a112732ed9f2087fa90b192d44e358';
+DROP USER regress_passwordcheck_user1;
diff --git a/contrib/uuid-ossp/expected/uuid_ossp_1.out b/contrib/uuid-ossp/expected/uuid_ossp_1.out
new file mode 100644
index 0000000000..58104dbe18
--- /dev/null
+++ b/contrib/uuid-ossp/expected/uuid_ossp_1.out
@@ -0,0 +1,135 @@
+CREATE EXTENSION "uuid-ossp";
+SELECT uuid_nil();
+               uuid_nil               
+--------------------------------------
+ 00000000-0000-0000-0000-000000000000
+(1 row)
+
+SELECT uuid_ns_dns();
+             uuid_ns_dns              
+--------------------------------------
+ 6ba7b810-9dad-11d1-80b4-00c04fd430c8
+(1 row)
+
+SELECT uuid_ns_url();
+             uuid_ns_url              
+--------------------------------------
+ 6ba7b811-9dad-11d1-80b4-00c04fd430c8
+(1 row)
+
+SELECT uuid_ns_oid();
+             uuid_ns_oid              
+--------------------------------------
+ 6ba7b812-9dad-11d1-80b4-00c04fd430c8
+(1 row)
+
+SELECT uuid_ns_x500();
+             uuid_ns_x500             
+--------------------------------------
+ 6ba7b814-9dad-11d1-80b4-00c04fd430c8
+(1 row)
+
+-- some quick and dirty field extraction functions
+-- this is actually timestamp concatenated with clock sequence, per RFC 4122
+CREATE FUNCTION uuid_timestamp_bits(uuid) RETURNS varbit AS
+$$ SELECT ('x' || substr($1::text, 15, 4) || substr($1::text, 10, 4) ||
+           substr($1::text, 1, 8) || substr($1::text, 20, 4))::bit(80)
+          & x'0FFFFFFFFFFFFFFF3FFF' $$
+LANGUAGE SQL STRICT IMMUTABLE;
+CREATE FUNCTION uuid_version_bits(uuid) RETURNS varbit AS
+$$ SELECT ('x' || substr($1::text, 15, 2))::bit(8) & '11110000' $$
+LANGUAGE SQL STRICT IMMUTABLE;
+CREATE FUNCTION uuid_reserved_bits(uuid) RETURNS varbit AS
+$$ SELECT ('x' || substr($1::text, 20, 2))::bit(8) & '11000000' $$
+LANGUAGE SQL STRICT IMMUTABLE;
+CREATE FUNCTION uuid_multicast_bit(uuid) RETURNS bool AS
+$$ SELECT (('x' || substr($1::text, 25, 2))::bit(8) & '00000001') != '00000000' $$
+LANGUAGE SQL STRICT IMMUTABLE;
+CREATE FUNCTION uuid_local_admin_bit(uuid) RETURNS bool AS
+$$ SELECT (('x' || substr($1::text, 25, 2))::bit(8) & '00000010') != '00000000' $$
+LANGUAGE SQL STRICT IMMUTABLE;
+CREATE FUNCTION uuid_node(uuid) RETURNS text AS
+$$ SELECT substr($1::text, 25) $$
+LANGUAGE SQL STRICT IMMUTABLE;
+-- Ideally, the multicast bit would never be set in V1 output, but the
+-- UUID library may fall back to MC if it can't get the system MAC address.
+-- Also, the local-admin bit might be set (if so, we're probably inside a VM).
+-- So we can't test either bit here.
+SELECT uuid_version_bits(uuid_generate_v1()),
+       uuid_reserved_bits(uuid_generate_v1());
+ uuid_version_bits | uuid_reserved_bits 
+-------------------+--------------------
+ 00010000          | 10000000
+(1 row)
+
+-- Although RFC 4122 only requires the multicast bit to be set in V1MC style
+-- UUIDs, our implementation always sets the local-admin bit as well.
+SELECT uuid_version_bits(uuid_generate_v1mc()),
+       uuid_reserved_bits(uuid_generate_v1mc()),
+       uuid_multicast_bit(uuid_generate_v1mc()),
+       uuid_local_admin_bit(uuid_generate_v1mc());
+ uuid_version_bits | uuid_reserved_bits | uuid_multicast_bit | uuid_local_admin_bit 
+-------------------+--------------------+--------------------+----------------------
+ 00010000          | 10000000           | t                  | t
+(1 row)
+
+-- timestamp+clock sequence should be monotonic increasing in v1
+SELECT uuid_timestamp_bits(uuid_generate_v1()) < uuid_timestamp_bits(uuid_generate_v1());
+ ?column? 
+----------
+ t
+(1 row)
+
+SELECT uuid_timestamp_bits(uuid_generate_v1mc()) < uuid_timestamp_bits(uuid_generate_v1mc());
+ ?column? 
+----------
+ t
+(1 row)
+
+-- Ideally, the node value is stable in V1 addresses, but OSSP UUID
+-- falls back to V1MC behavior if it can't get the system MAC address.
+SELECT CASE WHEN uuid_multicast_bit(uuid_generate_v1()) AND
+                 uuid_local_admin_bit(uuid_generate_v1()) THEN
+         true -- punt, no test
+       ELSE
+         uuid_node(uuid_generate_v1()) = uuid_node(uuid_generate_v1())
+       END;
+ case 
+------
+ t
+(1 row)
+
+-- In any case, V1MC node addresses should be random.
+SELECT uuid_node(uuid_generate_v1()) <> uuid_node(uuid_generate_v1mc());
+ ?column? 
+----------
+ t
+(1 row)
+
+SELECT uuid_node(uuid_generate_v1mc()) <> uuid_node(uuid_generate_v1mc());
+ ?column? 
+----------
+ t
+(1 row)
+
+SELECT uuid_generate_v3(uuid_ns_dns(), 'www.widgets.com');
+ERROR:  could not initialize MD5 context: unsupported
+SELECT uuid_generate_v5(uuid_ns_dns(), 'www.widgets.com');
+           uuid_generate_v5           
+--------------------------------------
+ 21f7f8de-8051-5b89-8680-0195ef798b6a
+(1 row)
+
+SELECT uuid_version_bits(uuid_generate_v4()),
+       uuid_reserved_bits(uuid_generate_v4());
+ uuid_version_bits | uuid_reserved_bits 
+-------------------+--------------------
+ 01000000          | 10000000
+(1 row)
+
+SELECT uuid_generate_v4() <> uuid_generate_v4();
+ ?column? 
+----------
+ t
+(1 row)
+
diff --git a/src/test/regress/expected/md5_1.out b/src/test/regress/expected/md5_1.out
new file mode 100644
index 0000000000..174b70bafb
--- /dev/null
+++ b/src/test/regress/expected/md5_1.out
@@ -0,0 +1,35 @@
+--
+-- MD5 test suite - from IETF RFC 1321
+-- (see: https://www.rfc-editor.org/rfc/rfc1321)
+--
+-- (The md5() function will error in OpenSSL FIPS mode.  By keeping
+-- this test in a separate file, it is easier to manage variant
+-- results.)
+select md5('') = 'd41d8cd98f00b204e9800998ecf8427e' AS "TRUE";
+ERROR:  could not compute MD5 hash: unsupported
+select md5('a') = '0cc175b9c0f1b6a831c399e269772661' AS "TRUE";
+ERROR:  could not compute MD5 hash: unsupported
+select md5('abc') = '900150983cd24fb0d6963f7d28e17f72' AS "TRUE";
+ERROR:  could not compute MD5 hash: unsupported
+select md5('message digest') = 'f96b697d7cb7938d525a2f31aaf161d0' AS "TRUE";
+ERROR:  could not compute MD5 hash: unsupported
+select md5('abcdefghijklmnopqrstuvwxyz') = 'c3fcd3d76192e4007dfb496cca67e13b' AS "TRUE";
+ERROR:  could not compute MD5 hash: unsupported
+select md5('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') = 'd174ab98d277d9f5a5611c2c9f419d9f' AS "TRUE";
+ERROR:  could not compute MD5 hash: unsupported
+select md5('12345678901234567890123456789012345678901234567890123456789012345678901234567890') = '57edf4a22be3c955ac49da2e2107b67a' AS "TRUE";
+ERROR:  could not compute MD5 hash: unsupported
+select md5(''::bytea) = 'd41d8cd98f00b204e9800998ecf8427e' AS "TRUE";
+ERROR:  could not compute MD5 hash: unsupported
+select md5('a'::bytea) = '0cc175b9c0f1b6a831c399e269772661' AS "TRUE";
+ERROR:  could not compute MD5 hash: unsupported
+select md5('abc'::bytea) = '900150983cd24fb0d6963f7d28e17f72' AS "TRUE";
+ERROR:  could not compute MD5 hash: unsupported
+select md5('message digest'::bytea) = 'f96b697d7cb7938d525a2f31aaf161d0' AS "TRUE";
+ERROR:  could not compute MD5 hash: unsupported
+select md5('abcdefghijklmnopqrstuvwxyz'::bytea) = 'c3fcd3d76192e4007dfb496cca67e13b' AS "TRUE";
+ERROR:  could not compute MD5 hash: unsupported
+select md5('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'::bytea) = 'd174ab98d277d9f5a5611c2c9f419d9f' AS "TRUE";
+ERROR:  could not compute MD5 hash: unsupported
+select md5('12345678901234567890123456789012345678901234567890123456789012345678901234567890'::bytea) = '57edf4a22be3c955ac49da2e2107b67a' AS "TRUE";
+ERROR:  could not compute MD5 hash: unsupported
diff --git a/src/test/regress/expected/password_1.out b/src/test/regress/expected/password_1.out
new file mode 100644
index 0000000000..3bb411949e
--- /dev/null
+++ b/src/test/regress/expected/password_1.out
@@ -0,0 +1,150 @@
+--
+-- Tests for password types
+--
+-- Tests for GUC password_encryption
+SET password_encryption = 'novalue'; -- error
+ERROR:  invalid value for parameter "password_encryption": "novalue"
+HINT:  Available values: md5, scram-sha-256.
+SET password_encryption = true; -- error
+ERROR:  invalid value for parameter "password_encryption": "true"
+HINT:  Available values: md5, scram-sha-256.
+SET password_encryption = 'md5'; -- ok
+SET password_encryption = 'scram-sha-256'; -- ok
+-- consistency of password entries
+SET password_encryption = 'md5';
+CREATE ROLE regress_passwd1 PASSWORD 'role_pwd1';
+ERROR:  password encryption failed: unsupported
+CREATE ROLE regress_passwd2 PASSWORD 'role_pwd2';
+ERROR:  password encryption failed: unsupported
+SET password_encryption = 'scram-sha-256';
+CREATE ROLE regress_passwd3 PASSWORD 'role_pwd3';
+CREATE ROLE regress_passwd4 PASSWORD NULL;
+-- check list of created entries
+--
+-- The scram secret will look something like:
+-- SCRAM-SHA-256$4096:E4HxLGtnRzsYwg==$6YtlR4t69SguDiwFvbVgVZtuz6gpJQQqUMZ7IQJK5yI=:ps75jrHeYU4lXCcXI4O8oIdJ3eO8o2jirjruw9phBTo=
+--
+-- Since the salt is random, the exact value stored will be different on every test
+-- run. Use a regular expression to mask the changing parts.
+SELECT rolname, regexp_replace(rolpassword, '(SCRAM-SHA-256)\$(\d+):([a-zA-Z0-9+/=]+)\$([a-zA-Z0-9+=/]+):([a-zA-Z0-9+/=]+)', '\1$\2:<salt>$<storedkey>:<serverkey>') as rolpassword_masked
+    FROM pg_authid
+    WHERE rolname LIKE 'regress_passwd%'
+    ORDER BY rolname, rolpassword;
+     rolname     |                rolpassword_masked                 
+-----------------+---------------------------------------------------
+ regress_passwd3 | SCRAM-SHA-256$4096:<salt>$<storedkey>:<serverkey>
+ regress_passwd4 | 
+(2 rows)
+
+-- Rename a role
+ALTER ROLE regress_passwd2 RENAME TO regress_passwd2_new;
+ERROR:  role "regress_passwd2" does not exist
+-- md5 entry should have been removed
+SELECT rolname, rolpassword
+    FROM pg_authid
+    WHERE rolname LIKE 'regress_passwd2_new'
+    ORDER BY rolname, rolpassword;
+ rolname | rolpassword 
+---------+-------------
+(0 rows)
+
+ALTER ROLE regress_passwd2_new RENAME TO regress_passwd2;
+ERROR:  role "regress_passwd2_new" does not exist
+-- Change passwords with ALTER USER. With plaintext or already-encrypted
+-- passwords.
+SET password_encryption = 'md5';
+-- encrypt with MD5
+ALTER ROLE regress_passwd2 PASSWORD 'foo';
+ERROR:  role "regress_passwd2" does not exist
+-- already encrypted, use as they are
+ALTER ROLE regress_passwd1 PASSWORD 'md5cd3578025fe2c3d7ed1b9a9b26238b70';
+ERROR:  role "regress_passwd1" does not exist
+ALTER ROLE regress_passwd3 PASSWORD 'SCRAM-SHA-256$4096:VLK4RMaQLCvNtQ==$6YtlR4t69SguDiwFvbVgVZtuz6gpJQQqUMZ7IQJK5yI=:ps75jrHeYU4lXCcXI4O8oIdJ3eO8o2jirjruw9phBTo=';
+SET password_encryption = 'scram-sha-256';
+-- create SCRAM secret
+ALTER ROLE  regress_passwd4 PASSWORD 'foo';
+-- already encrypted with MD5, use as it is
+CREATE ROLE regress_passwd5 PASSWORD 'md5e73a4b11df52a6068f8b39f90be36023';
+-- This looks like a valid SCRAM-SHA-256 secret, but it is not
+-- so it should be hashed with SCRAM-SHA-256.
+CREATE ROLE regress_passwd6 PASSWORD 'SCRAM-SHA-256$1234';
+-- These may look like valid MD5 secrets, but they are not, so they
+-- should be hashed with SCRAM-SHA-256.
+-- trailing garbage at the end
+CREATE ROLE regress_passwd7 PASSWORD 'md5012345678901234567890123456789zz';
+-- invalid length
+CREATE ROLE regress_passwd8 PASSWORD 'md501234567890123456789012345678901zz';
+-- Changing the SCRAM iteration count
+SET scram_iterations = 1024;
+CREATE ROLE regress_passwd9 PASSWORD 'alterediterationcount';
+SELECT rolname, regexp_replace(rolpassword, '(SCRAM-SHA-256)\$(\d+):([a-zA-Z0-9+/=]+)\$([a-zA-Z0-9+=/]+):([a-zA-Z0-9+/=]+)', '\1$\2:<salt>$<storedkey>:<serverkey>') as rolpassword_masked
+    FROM pg_authid
+    WHERE rolname LIKE 'regress_passwd%'
+    ORDER BY rolname, rolpassword;
+     rolname     |                rolpassword_masked                 
+-----------------+---------------------------------------------------
+ regress_passwd3 | SCRAM-SHA-256$4096:<salt>$<storedkey>:<serverkey>
+ regress_passwd4 | SCRAM-SHA-256$4096:<salt>$<storedkey>:<serverkey>
+ regress_passwd5 | md5e73a4b11df52a6068f8b39f90be36023
+ regress_passwd6 | SCRAM-SHA-256$4096:<salt>$<storedkey>:<serverkey>
+ regress_passwd7 | SCRAM-SHA-256$4096:<salt>$<storedkey>:<serverkey>
+ regress_passwd8 | SCRAM-SHA-256$4096:<salt>$<storedkey>:<serverkey>
+ regress_passwd9 | SCRAM-SHA-256$1024:<salt>$<storedkey>:<serverkey>
+(7 rows)
+
+-- An empty password is not allowed, in any form
+CREATE ROLE regress_passwd_empty PASSWORD '';
+NOTICE:  empty string is not a valid password, clearing password
+ALTER ROLE regress_passwd_empty PASSWORD 'md585939a5ce845f1a1b620742e3c659e0a';
+ALTER ROLE regress_passwd_empty PASSWORD 'SCRAM-SHA-256$4096:hpFyHTUsSWcR7O9P$LgZFIt6Oqdo27ZFKbZ2nV+vtnYM995pDh9ca6WSi120=:qVV5NeluNfUPkwm7Vqat25RjSPLkGeoZBQs6wVv+um4=';
+NOTICE:  empty string is not a valid password, clearing password
+SELECT rolpassword FROM pg_authid WHERE rolname='regress_passwd_empty';
+ rolpassword 
+-------------
+ 
+(1 row)
+
+-- Test with invalid stored and server keys.
+--
+-- The first is valid, to act as a control. The others have too long
+-- stored/server keys. They will be re-hashed.
+CREATE ROLE regress_passwd_sha_len0 PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941doaPOYg==$Ky+A30sewHIH3VHQLRN9vYsuzlgNyGNKCh37dy96Rqw=:COPdlNiIkrsacU5QoxydEuOH6e/KfiipeETb/bPw8ZI=';
+CREATE ROLE regress_passwd_sha_len1 PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941doaPOYg==$Ky+A30sewHIH3VHQLRN9vYsuzlgNyGNKCh37dy96RqwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=:COPdlNiIkrsacU5QoxydEuOH6e/KfiipeETb/bPw8ZI=';
+CREATE ROLE regress_passwd_sha_len2 PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941doaPOYg==$Ky+A30sewHIH3VHQLRN9vYsuzlgNyGNKCh37dy96Rqw=:COPdlNiIkrsacU5QoxydEuOH6e/KfiipeETb/bPw8ZIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=';
+-- Check that the invalid secrets were re-hashed. A re-hashed secret
+-- should not contain the original salt.
+SELECT rolname, rolpassword not like '%A6xHKoH/494E941doaPOYg==%' as is_rolpassword_rehashed
+    FROM pg_authid
+    WHERE rolname LIKE 'regress_passwd_sha_len%'
+    ORDER BY rolname;
+         rolname         | is_rolpassword_rehashed 
+-------------------------+-------------------------
+ regress_passwd_sha_len0 | f
+ regress_passwd_sha_len1 | t
+ regress_passwd_sha_len2 | t
+(3 rows)
+
+DROP ROLE regress_passwd1;
+ERROR:  role "regress_passwd1" does not exist
+DROP ROLE regress_passwd2;
+ERROR:  role "regress_passwd2" does not exist
+DROP ROLE regress_passwd3;
+DROP ROLE regress_passwd4;
+DROP ROLE regress_passwd5;
+DROP ROLE regress_passwd6;
+DROP ROLE regress_passwd7;
+DROP ROLE regress_passwd8;
+DROP ROLE regress_passwd9;
+DROP ROLE regress_passwd_empty;
+DROP ROLE regress_passwd_sha_len0;
+DROP ROLE regress_passwd_sha_len1;
+DROP ROLE regress_passwd_sha_len2;
+-- all entries should have been removed
+SELECT rolname, rolpassword
+    FROM pg_authid
+    WHERE rolname LIKE 'regress_passwd%'
+    ORDER BY rolname, rolpassword;
+ rolname | rolpassword 
+---------+-------------
+(0 rows)
+
-- 
2.42.0



  [text/x-diff] v5-0005-WIP-Use-fipshash-in-brin_multi-test.patch (5.1K, ../../[email protected]/5-v5-0005-WIP-Use-fipshash-in-brin_multi-test.patch)
  download | inline diff:
From 65b287b111fef67abed492c805519eb5c6b96efa Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Thu, 5 Oct 2023 14:45:35 +0200
Subject: [PATCH v4 5/5] WIP: Use fipshash in brin_multi test

---
 src/test/regress/expected/brin_multi.out | 24 ++++++++++++------------
 src/test/regress/sql/brin_multi.sql      |  4 ++--
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/src/test/regress/expected/brin_multi.out b/src/test/regress/expected/brin_multi.out
index 9f46934c9b..6773701c7e 100644
--- a/src/test/regress/expected/brin_multi.out
+++ b/src/test/regress/expected/brin_multi.out
@@ -740,19 +740,19 @@ RESET enable_seqscan;
 -- do some inequality tests for varlena data types
 CREATE TABLE brin_test_multi_2 (a UUID) WITH (fillfactor=10);
 INSERT INTO brin_test_multi_2
-SELECT v::uuid FROM (SELECT row_number() OVER (ORDER BY v) c, v FROM (SELECT md5((i/13)::text) AS v FROM generate_series(1,1000) s(i)) foo) bar ORDER BY c + 25 * random();
+SELECT v::uuid FROM (SELECT row_number() OVER (ORDER BY v) c, v FROM (SELECT fipshash((i/13)::text) AS v FROM generate_series(1,1000) s(i)) foo) bar ORDER BY c + 25 * random();
 CREATE INDEX brin_test_multi_2_idx ON brin_test_multi_2 USING brin (a uuid_minmax_multi_ops) WITH (pages_per_range=5);
 SET enable_seqscan=off;
 SELECT COUNT(*) FROM brin_test_multi_2 WHERE a < '33e75ff0-9dd6-01bb-e69f-351039152189';
  count 
 -------
-   195
+   156
 (1 row)
 
 SELECT COUNT(*) FROM brin_test_multi_2 WHERE a > '33e75ff0-9dd6-01bb-e69f-351039152189';
  count 
 -------
-   792
+   844
 (1 row)
 
 SELECT COUNT(*) FROM brin_test_multi_2 WHERE a <= 'f457c545-a9de-d88f-18ec-ee47145a72c0';
@@ -764,19 +764,19 @@ SELECT COUNT(*) FROM brin_test_multi_2 WHERE a <= 'f457c545-a9de-d88f-18ec-ee471
 SELECT COUNT(*) FROM brin_test_multi_2 WHERE a >= 'c51ce410-c124-a10e-0db5-e4b97fc2af39';
  count 
 -------
-   272
+   221
 (1 row)
 
 SELECT COUNT(*) FROM brin_test_multi_2 WHERE a = 'cfcd2084-95d5-65ef-66e7-dff9f98764da';
  count 
 -------
-    12
+     0
 (1 row)
 
 SELECT COUNT(*) FROM brin_test_multi_2 WHERE a = 'aab32389-22bc-c25a-6f60-6eb525ffdc56';
  count 
 -------
-    13
+     0
 (1 row)
 
 -- now do the same, but insert the rows with the indexes already created
@@ -784,17 +784,17 @@ SELECT COUNT(*) FROM brin_test_multi_2 WHERE a = 'aab32389-22bc-c25a-6f60-6eb525
 -- approach of adding rows into existing ranges
 TRUNCATE brin_test_multi_2;
 INSERT INTO brin_test_multi_2
-SELECT v::uuid FROM (SELECT row_number() OVER (ORDER BY v) c, v FROM (SELECT md5((i/13)::text) AS v FROM generate_series(1,1000) s(i)) foo) bar ORDER BY c + 25 * random();
+SELECT v::uuid FROM (SELECT row_number() OVER (ORDER BY v) c, v FROM (SELECT fipshash((i/13)::text) AS v FROM generate_series(1,1000) s(i)) foo) bar ORDER BY c + 25 * random();
 SELECT COUNT(*) FROM brin_test_multi_2 WHERE a < '33e75ff0-9dd6-01bb-e69f-351039152189';
  count 
 -------
-   195
+   156
 (1 row)
 
 SELECT COUNT(*) FROM brin_test_multi_2 WHERE a > '33e75ff0-9dd6-01bb-e69f-351039152189';
  count 
 -------
-   792
+   844
 (1 row)
 
 SELECT COUNT(*) FROM brin_test_multi_2 WHERE a <= 'f457c545-a9de-d88f-18ec-ee47145a72c0';
@@ -806,19 +806,19 @@ SELECT COUNT(*) FROM brin_test_multi_2 WHERE a <= 'f457c545-a9de-d88f-18ec-ee471
 SELECT COUNT(*) FROM brin_test_multi_2 WHERE a >= 'c51ce410-c124-a10e-0db5-e4b97fc2af39';
  count 
 -------
-   272
+   221
 (1 row)
 
 SELECT COUNT(*) FROM brin_test_multi_2 WHERE a = 'cfcd2084-95d5-65ef-66e7-dff9f98764da';
  count 
 -------
-    12
+     0
 (1 row)
 
 SELECT COUNT(*) FROM brin_test_multi_2 WHERE a = 'aab32389-22bc-c25a-6f60-6eb525ffdc56';
  count 
 -------
-    13
+     0
 (1 row)
 
 DROP TABLE brin_test_multi_2;
diff --git a/src/test/regress/sql/brin_multi.sql b/src/test/regress/sql/brin_multi.sql
index d50dbdee68..5bca4fd350 100644
--- a/src/test/regress/sql/brin_multi.sql
+++ b/src/test/regress/sql/brin_multi.sql
@@ -545,7 +545,7 @@ CREATE INDEX brin_test_multi_1_idx_2 ON brin_test_multi_1 USING brin (b int8_min
 -- do some inequality tests for varlena data types
 CREATE TABLE brin_test_multi_2 (a UUID) WITH (fillfactor=10);
 INSERT INTO brin_test_multi_2
-SELECT v::uuid FROM (SELECT row_number() OVER (ORDER BY v) c, v FROM (SELECT md5((i/13)::text) AS v FROM generate_series(1,1000) s(i)) foo) bar ORDER BY c + 25 * random();
+SELECT v::uuid FROM (SELECT row_number() OVER (ORDER BY v) c, v FROM (SELECT fipshash((i/13)::text) AS v FROM generate_series(1,1000) s(i)) foo) bar ORDER BY c + 25 * random();
 
 CREATE INDEX brin_test_multi_2_idx ON brin_test_multi_2 USING brin (a uuid_minmax_multi_ops) WITH (pages_per_range=5);
 
@@ -570,7 +570,7 @@ CREATE INDEX brin_test_multi_2_idx ON brin_test_multi_2 USING brin (a uuid_minma
 
 TRUNCATE brin_test_multi_2;
 INSERT INTO brin_test_multi_2
-SELECT v::uuid FROM (SELECT row_number() OVER (ORDER BY v) c, v FROM (SELECT md5((i/13)::text) AS v FROM generate_series(1,1000) s(i)) foo) bar ORDER BY c + 25 * random();
+SELECT v::uuid FROM (SELECT row_number() OVER (ORDER BY v) c, v FROM (SELECT fipshash((i/13)::text) AS v FROM generate_series(1,1000) s(i)) foo) bar ORDER BY c + 25 * random();
 
 SELECT COUNT(*) FROM brin_test_multi_2 WHERE a < '33e75ff0-9dd6-01bb-e69f-351039152189';
 
-- 
2.42.0



  [text/x-diff] v5-0006-allow-for-disabled-3DES.patch (1.5K, ../../[email protected]/6-v5-0006-allow-for-disabled-3DES.patch)
  download | inline diff:
diff --git a/contrib/pgcrypto/expected/3des_1.out b/contrib/pgcrypto/expected/3des_1.out
new file mode 100644
index 0000000000..fb1d1f6f0c
--- /dev/null
+++ b/contrib/pgcrypto/expected/3des_1.out
@@ -0,0 +1,29 @@
+--
+-- 3DES cipher
+--
+-- test vector from somewhere
+SELECT encrypt('\x8000000000000000',
+               '\x010101010101010101010101010101010101010101010101',
+               '3des-ecb/pad:none');
+ERROR:  encrypt error: Cipher cannot be initialized
+select encrypt('', 'foo', '3des');
+ERROR:  encrypt error: Cipher cannot be initialized
+-- 10 bytes key
+select encrypt('foo', '0123456789', '3des');
+ERROR:  encrypt error: Cipher cannot be initialized
+-- 22 bytes key
+select encrypt('foo', '0123456789012345678901', '3des');
+ERROR:  encrypt error: Cipher cannot be initialized
+-- decrypt
+select encode(decrypt(encrypt('foo', '0123456', '3des'), '0123456', '3des'), 'escape');
+ERROR:  encrypt error: Cipher cannot be initialized
+-- iv
+select encrypt_iv('foo', '0123456', 'abcd', '3des');
+ERROR:  encrypt_iv error: Cipher cannot be initialized
+select encode(decrypt_iv('\x50735067b073bb93', '0123456', 'abcd', '3des'), 'escape');
+ERROR:  decrypt_iv error: Cipher cannot be initialized
+-- long message
+select encrypt('Lets try a longer message.', '0123456789012345678901', '3des');
+ERROR:  encrypt error: Cipher cannot be initialized
+select encode(decrypt(encrypt('Lets try a longer message.', '0123456789012345678901', '3des'), '0123456789012345678901', '3des'), 'escape');
+ERROR:  encrypt error: Cipher cannot be initialized


  [text/x-diff] v5-0007-password-test-delta.patch (5.3K, ../../[email protected]/7-v5-0007-password-test-delta.patch)
  download | inline diff:
diff --git a/src/test/regress/expected/password.out b/src/test/regress/expected/password.out
index 8475231735..924d6e001d 100644
--- a/src/test/regress/expected/password.out
+++ b/src/test/regress/expected/password.out
@@ -12,8 +12,10 @@ SET password_encryption = 'md5'; -- ok
 SET password_encryption = 'scram-sha-256'; -- ok
 -- consistency of password entries
 SET password_encryption = 'md5';
-CREATE ROLE regress_passwd1 PASSWORD 'role_pwd1';
-CREATE ROLE regress_passwd2 PASSWORD 'role_pwd2';
+CREATE ROLE regress_passwd1;
+ALTER ROLE regress_passwd1 PASSWORD 'role_pwd1';
+CREATE ROLE regress_passwd2;
+ALTER ROLE regress_passwd2 PASSWORD 'role_pwd2';
 SET password_encryption = 'scram-sha-256';
 CREATE ROLE regress_passwd3 PASSWORD 'role_pwd3';
 CREATE ROLE regress_passwd4 PASSWORD NULL;
diff --git a/src/test/regress/expected/password_1.out b/src/test/regress/expected/password_1.out
index 3bb411949e..9d2cc94f37 100644
--- a/src/test/regress/expected/password_1.out
+++ b/src/test/regress/expected/password_1.out
@@ -12,9 +12,11 @@ SET password_encryption = 'md5'; -- ok
 SET password_encryption = 'scram-sha-256'; -- ok
 -- consistency of password entries
 SET password_encryption = 'md5';
-CREATE ROLE regress_passwd1 PASSWORD 'role_pwd1';
+CREATE ROLE regress_passwd1;
+ALTER ROLE regress_passwd1 PASSWORD 'role_pwd1';
 ERROR:  password encryption failed: unsupported
-CREATE ROLE regress_passwd2 PASSWORD 'role_pwd2';
+CREATE ROLE regress_passwd2;
+ALTER ROLE regress_passwd2 PASSWORD 'role_pwd2';
 ERROR:  password encryption failed: unsupported
 SET password_encryption = 'scram-sha-256';
 CREATE ROLE regress_passwd3 PASSWORD 'role_pwd3';
@@ -32,33 +34,33 @@ SELECT rolname, regexp_replace(rolpassword, '(SCRAM-SHA-256)\$(\d+):([a-zA-Z0-9+
     ORDER BY rolname, rolpassword;
      rolname     |                rolpassword_masked                 
 -----------------+---------------------------------------------------
+ regress_passwd1 | 
+ regress_passwd2 | 
  regress_passwd3 | SCRAM-SHA-256$4096:<salt>$<storedkey>:<serverkey>
  regress_passwd4 | 
-(2 rows)
+(4 rows)
 
 -- Rename a role
 ALTER ROLE regress_passwd2 RENAME TO regress_passwd2_new;
-ERROR:  role "regress_passwd2" does not exist
 -- md5 entry should have been removed
 SELECT rolname, rolpassword
     FROM pg_authid
     WHERE rolname LIKE 'regress_passwd2_new'
     ORDER BY rolname, rolpassword;
- rolname | rolpassword 
----------+-------------
-(0 rows)
+       rolname       | rolpassword 
+---------------------+-------------
+ regress_passwd2_new | 
+(1 row)
 
 ALTER ROLE regress_passwd2_new RENAME TO regress_passwd2;
-ERROR:  role "regress_passwd2_new" does not exist
 -- Change passwords with ALTER USER. With plaintext or already-encrypted
 -- passwords.
 SET password_encryption = 'md5';
 -- encrypt with MD5
 ALTER ROLE regress_passwd2 PASSWORD 'foo';
-ERROR:  role "regress_passwd2" does not exist
+ERROR:  password encryption failed: unsupported
 -- already encrypted, use as they are
 ALTER ROLE regress_passwd1 PASSWORD 'md5cd3578025fe2c3d7ed1b9a9b26238b70';
-ERROR:  role "regress_passwd1" does not exist
 ALTER ROLE regress_passwd3 PASSWORD 'SCRAM-SHA-256$4096:VLK4RMaQLCvNtQ==$6YtlR4t69SguDiwFvbVgVZtuz6gpJQQqUMZ7IQJK5yI=:ps75jrHeYU4lXCcXI4O8oIdJ3eO8o2jirjruw9phBTo=';
 SET password_encryption = 'scram-sha-256';
 -- create SCRAM secret
@@ -83,6 +85,8 @@ SELECT rolname, regexp_replace(rolpassword, '(SCRAM-SHA-256)\$(\d+):([a-zA-Z0-9+
     ORDER BY rolname, rolpassword;
      rolname     |                rolpassword_masked                 
 -----------------+---------------------------------------------------
+ regress_passwd1 | md5cd3578025fe2c3d7ed1b9a9b26238b70
+ regress_passwd2 | 
  regress_passwd3 | SCRAM-SHA-256$4096:<salt>$<storedkey>:<serverkey>
  regress_passwd4 | SCRAM-SHA-256$4096:<salt>$<storedkey>:<serverkey>
  regress_passwd5 | md5e73a4b11df52a6068f8b39f90be36023
@@ -90,7 +94,7 @@ SELECT rolname, regexp_replace(rolpassword, '(SCRAM-SHA-256)\$(\d+):([a-zA-Z0-9+
  regress_passwd7 | SCRAM-SHA-256$4096:<salt>$<storedkey>:<serverkey>
  regress_passwd8 | SCRAM-SHA-256$4096:<salt>$<storedkey>:<serverkey>
  regress_passwd9 | SCRAM-SHA-256$1024:<salt>$<storedkey>:<serverkey>
-(7 rows)
+(9 rows)
 
 -- An empty password is not allowed, in any form
 CREATE ROLE regress_passwd_empty PASSWORD '';
@@ -125,9 +129,7 @@ SELECT rolname, rolpassword not like '%A6xHKoH/494E941doaPOYg==%' as is_rolpassw
 (3 rows)
 
 DROP ROLE regress_passwd1;
-ERROR:  role "regress_passwd1" does not exist
 DROP ROLE regress_passwd2;
-ERROR:  role "regress_passwd2" does not exist
 DROP ROLE regress_passwd3;
 DROP ROLE regress_passwd4;
 DROP ROLE regress_passwd5;
diff --git a/src/test/regress/sql/password.sql b/src/test/regress/sql/password.sql
index 53e86b0b6c..bb82aa4aa2 100644
--- a/src/test/regress/sql/password.sql
+++ b/src/test/regress/sql/password.sql
@@ -10,8 +10,10 @@ SET password_encryption = 'scram-sha-256'; -- ok
 
 -- consistency of password entries
 SET password_encryption = 'md5';
-CREATE ROLE regress_passwd1 PASSWORD 'role_pwd1';
-CREATE ROLE regress_passwd2 PASSWORD 'role_pwd2';
+CREATE ROLE regress_passwd1;
+ALTER ROLE regress_passwd1 PASSWORD 'role_pwd1';
+CREATE ROLE regress_passwd2;
+ALTER ROLE regress_passwd2 PASSWORD 'role_pwd2';
 SET password_encryption = 'scram-sha-256';
 CREATE ROLE regress_passwd3 PASSWORD 'role_pwd3';
 CREATE ROLE regress_passwd4 PASSWORD NULL;


^ permalink  raw  reply  [nested|flat] 12+ messages in thread

* Re: Allow tests to pass in OpenSSL FIPS mode
  2023-11-14 23:07 Re: Allow tests to pass in OpenSSL FIPS mode Tom Lane <[email protected]>
  2023-11-15 11:44 ` Re: Allow tests to pass in OpenSSL FIPS mode Peter Eisentraut <[email protected]>
  2023-11-15 14:25   ` Re: Allow tests to pass in OpenSSL FIPS mode Daniel Gustafsson <[email protected]>
  2023-11-15 20:29     ` Re: Allow tests to pass in OpenSSL FIPS mode Tom Lane <[email protected]>
@ 2023-11-17 18:45       ` Peter Eisentraut <[email protected]>
  2024-04-19 03:50         ` Re: Allow tests to pass in OpenSSL FIPS mode Thomas Munro <[email protected]>
  0 siblings, 1 reply; 12+ messages in thread

From: Peter Eisentraut @ 2023-11-17 18:45 UTC (permalink / raw)
  To: Tom Lane <[email protected]>; Daniel Gustafsson <[email protected]>; +Cc: pgsql-hackers

On 15.11.23 21:29, Tom Lane wrote:
> Daniel Gustafsson <[email protected]> writes:
>> Since the 3DES/DES deprecations aren't limited to FIPS, do we want to do
>> anything for pgcrypto where we have DES/3DES encryption?  Maybe a doc patch
>> which mentions the deprecation with a link to the SP could be in order?
> 
> A docs patch that marks both MD5 and 3DES as deprecated is probably
> appropriate, but it seems like a matter for a separate thread and patch.
> 
> In the meantime, I've done a pass of review of Peter's v4 patches.
> v4-0001 is already committed, so that's not considered here.
> 
> v4-0002: I think it is worth splitting up contrib/pgcrypto's
> pgp-encrypt test, which has only one test case whose output changes,
> and a bunch of others that don't.  v5-0002, attached, does it
> like that.  It's otherwise the same as v4.
> 
> (It might be worth doing something similar for uuid_ossp's test,
> but I have not bothered here.  That test script is stable enough
> that I'm not too worried about future maintenance.)
> 
> The attached 0003, 0004, 0005 patches are identical to Peter's.
> I think that it is possibly worth modifying the password test so that
> we don't fail to create the roles, so as to reduce the delta between
> password.out and password_1.out (and thereby ease future maintenance
> of those files).  However you might disagree, so I split my proposal
> out as a separate patch v5-0007-password-test-delta.patch; you can
> drop that from the set if you don't like it.
> 
> v5-0006-allow-for-disabled-3DES.patch adds the necessary expected
> file to make that pass on my Fedora 38 system.
> 
> With or without 0007, as you choose, I think it's committable.

All done, thanks.







^ permalink  raw  reply  [nested|flat] 12+ messages in thread

* Re: Allow tests to pass in OpenSSL FIPS mode
  2023-11-14 23:07 Re: Allow tests to pass in OpenSSL FIPS mode Tom Lane <[email protected]>
  2023-11-15 11:44 ` Re: Allow tests to pass in OpenSSL FIPS mode Peter Eisentraut <[email protected]>
  2023-11-15 14:25   ` Re: Allow tests to pass in OpenSSL FIPS mode Daniel Gustafsson <[email protected]>
  2023-11-15 20:29     ` Re: Allow tests to pass in OpenSSL FIPS mode Tom Lane <[email protected]>
  2023-11-17 18:45       ` Re: Allow tests to pass in OpenSSL FIPS mode Peter Eisentraut <[email protected]>
@ 2024-04-19 03:50         ` Thomas Munro <[email protected]>
  2024-04-19 04:00           ` Re: Allow tests to pass in OpenSSL FIPS mode Tom Lane <[email protected]>
  0 siblings, 1 reply; 12+ messages in thread

From: Thomas Munro @ 2024-04-19 03:50 UTC (permalink / raw)
  To: Peter Eisentraut <[email protected]>; +Cc: Tom Lane <[email protected]>; Daniel Gustafsson <[email protected]>; pgsql-hackers

On Sat, Nov 18, 2023 at 7:46 AM Peter Eisentraut <[email protected]> wrote:
> All done, thanks.

Probably not this thread's fault, but following the breadcrumbs to the
last thread to touch the relevant test lines in
authentication/001_password, is it expected that we have these
warnings?

psql:<stdin>:1: WARNING:  roles created by regression test cases
should have names starting with "regress_"






^ permalink  raw  reply  [nested|flat] 12+ messages in thread

* Re: Allow tests to pass in OpenSSL FIPS mode
  2023-11-14 23:07 Re: Allow tests to pass in OpenSSL FIPS mode Tom Lane <[email protected]>
  2023-11-15 11:44 ` Re: Allow tests to pass in OpenSSL FIPS mode Peter Eisentraut <[email protected]>
  2023-11-15 14:25   ` Re: Allow tests to pass in OpenSSL FIPS mode Daniel Gustafsson <[email protected]>
  2023-11-15 20:29     ` Re: Allow tests to pass in OpenSSL FIPS mode Tom Lane <[email protected]>
  2023-11-17 18:45       ` Re: Allow tests to pass in OpenSSL FIPS mode Peter Eisentraut <[email protected]>
  2024-04-19 03:50         ` Re: Allow tests to pass in OpenSSL FIPS mode Thomas Munro <[email protected]>
@ 2024-04-19 04:00           ` Tom Lane <[email protected]>
  2024-04-19 04:12             ` Re: Allow tests to pass in OpenSSL FIPS mode Thomas Munro <[email protected]>
  0 siblings, 1 reply; 12+ messages in thread

From: Tom Lane @ 2024-04-19 04:00 UTC (permalink / raw)
  To: Thomas Munro <[email protected]>; +Cc: Peter Eisentraut <[email protected]>; Daniel Gustafsson <[email protected]>; pgsql-hackers

Thomas Munro <[email protected]> writes:
> Probably not this thread's fault, but following the breadcrumbs to the
> last thread to touch the relevant test lines in
> authentication/001_password, is it expected that we have these
> warnings?

> psql:<stdin>:1: WARNING:  roles created by regression test cases
> should have names starting with "regress_"

I think the policy is that we enforce that for cases reachable
via "make installcheck" (to avoid possibly clobbering global
objects in a live installation), but not for cases only reachable
via "make check", such as TAP tests.  So I'm not that concerned
about this, although if someone is feeling anal enough to rename
the test role I won't stand in the way.

			regards, tom lane






^ permalink  raw  reply  [nested|flat] 12+ messages in thread

* Re: Allow tests to pass in OpenSSL FIPS mode
  2023-11-14 23:07 Re: Allow tests to pass in OpenSSL FIPS mode Tom Lane <[email protected]>
  2023-11-15 11:44 ` Re: Allow tests to pass in OpenSSL FIPS mode Peter Eisentraut <[email protected]>
  2023-11-15 14:25   ` Re: Allow tests to pass in OpenSSL FIPS mode Daniel Gustafsson <[email protected]>
  2023-11-15 20:29     ` Re: Allow tests to pass in OpenSSL FIPS mode Tom Lane <[email protected]>
  2023-11-17 18:45       ` Re: Allow tests to pass in OpenSSL FIPS mode Peter Eisentraut <[email protected]>
  2024-04-19 03:50         ` Re: Allow tests to pass in OpenSSL FIPS mode Thomas Munro <[email protected]>
  2024-04-19 04:00           ` Re: Allow tests to pass in OpenSSL FIPS mode Tom Lane <[email protected]>
@ 2024-04-19 04:12             ` Thomas Munro <[email protected]>
  0 siblings, 0 replies; 12+ messages in thread

From: Thomas Munro @ 2024-04-19 04:12 UTC (permalink / raw)
  To: Tom Lane <[email protected]>; +Cc: Peter Eisentraut <[email protected]>; Daniel Gustafsson <[email protected]>; pgsql-hackers

On Fri, Apr 19, 2024 at 4:00 PM Tom Lane <[email protected]> wrote:
> Thomas Munro <[email protected]> writes:
> > Probably not this thread's fault, but following the breadcrumbs to the
> > last thread to touch the relevant test lines in
> > authentication/001_password, is it expected that we have these
> > warnings?
>
> > psql:<stdin>:1: WARNING:  roles created by regression test cases
> > should have names starting with "regress_"
>
> I think the policy is that we enforce that for cases reachable
> via "make installcheck" (to avoid possibly clobbering global
> objects in a live installation), but not for cases only reachable
> via "make check", such as TAP tests.  So I'm not that concerned
> about this, although if someone is feeling anal enough to rename
> the test role I won't stand in the way.

Got it, thanks.  Not me, just asking.






^ permalink  raw  reply  [nested|flat] 12+ messages in thread

* Re: Allow tests to pass in OpenSSL FIPS mode
  2023-11-14 23:07 Re: Allow tests to pass in OpenSSL FIPS mode Tom Lane <[email protected]>
@ 2025-09-14 19:02 ` Tom Lane <[email protected]>
  2 siblings, 0 replies; 12+ messages in thread

From: Tom Lane @ 2025-09-14 19:02 UTC (permalink / raw)
  To: Peter Eisentraut <[email protected]>; +Cc: pgsql-hackers; [email protected]

[ blast-from-the-past department ]

I wrote:
> Peter Eisentraut <[email protected]> writes:
>> I suggest that if there are no other concerns, we proceed with the patch 
>> set as is for now.

> After thinking about it for awhile, I guess I'm okay with only
> bothering to provide expected-files for FIPS failures under OpenSSL
> 3.x (which is how your patch is set up, I believe).  While there are
> certainly still LTS platforms with 1.x, we don't have to consider FIPS
> mode on them to be a supported case.

I see that Mark W. has just spun up a couple of BF animals running
FIPS mode under SLES 15 (goshawk and shoebill).  Not too surprisingly,
they are failing the MD5 test:

 select md5('') = 'd41d8cd98f00b204e9800998ecf8427e' AS "TRUE";
-ERROR:  could not compute MD5 hash: unsupported
+ERROR:  could not compute MD5 hash: disabled for FIPS
 select md5('a') = '0cc175b9c0f1b6a831c399e269772661' AS "TRUE";
-ERROR:  could not compute MD5 hash: unsupported
+ERROR:  could not compute MD5 hash: disabled for FIPS
(etc etc)

Should we revisit the decision to not support this spelling
of the error message?  SLES 15 has got another decade or so
of support according to wikipedia [1], so it's hard to call it
a dead platform.

It looks like it'd be easy enough to generate the required
alternate expected-file, just s/unsupported/disabled for FIPS/g.
Happy to take care of this if there are not objections.

			regards, tom lane

[1] https://en.wikipedia.org/wiki/SUSE_Linux_Enterprise#End-of-support_schedule





^ permalink  raw  reply  [nested|flat] 12+ messages in thread


end of thread, other threads:[~2025-09-14 19:02 UTC | newest]

Thread overview: 12+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2019-08-22 08:06 [PATCH 1/1] Fix overflow check and comment in GIN posting list encoding. Heikki Linnakangas <[email protected]>
2019-12-20 01:21 [PATCH v29 05/11] Add Incremental View Maintenance support to psql Yugo Nagata <[email protected]>
2023-11-14 23:07 Re: Allow tests to pass in OpenSSL FIPS mode Tom Lane <[email protected]>
2023-11-15 10:06 ` Re: Allow tests to pass in OpenSSL FIPS mode Daniel Gustafsson <[email protected]>
2023-11-15 11:44 ` Re: Allow tests to pass in OpenSSL FIPS mode Peter Eisentraut <[email protected]>
2023-11-15 14:25   ` Re: Allow tests to pass in OpenSSL FIPS mode Daniel Gustafsson <[email protected]>
2023-11-15 20:29     ` Re: Allow tests to pass in OpenSSL FIPS mode Tom Lane <[email protected]>
2023-11-17 18:45       ` Re: Allow tests to pass in OpenSSL FIPS mode Peter Eisentraut <[email protected]>
2024-04-19 03:50         ` Re: Allow tests to pass in OpenSSL FIPS mode Thomas Munro <[email protected]>
2024-04-19 04:00           ` Re: Allow tests to pass in OpenSSL FIPS mode Tom Lane <[email protected]>
2024-04-19 04:12             ` Re: Allow tests to pass in OpenSSL FIPS mode Thomas Munro <[email protected]>
2025-09-14 19:02 ` Re: Allow tests to pass in OpenSSL FIPS mode Tom Lane <[email protected]>

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox