From 38d6f522fcb1038df979bd26364d66e82f5f6d1f Mon Sep 17 00:00:00 2001
From: Alessandro Gherardi <alessandro.gherardi@yahoo.com>
Date: Sun, 16 Sep 2018 14:11:33 -0600
Subject: [PATCH] On Windows, call FIPS_mode_set(1) if FIPS registry entry
 indicates that FIPS is enabled

---
 src/backend/libpq/be-secure-openssl.c    | 44 ++++++++++++++++++++++++++++++++
 src/interfaces/libpq/fe-secure-openssl.c | 40 +++++++++++++++++++++++++++++
 2 files changed, 84 insertions(+)

diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c
index 6a57657..f4dbef2 100644
--- a/src/backend/libpq/be-secure-openssl.c
+++ b/src/backend/libpq/be-secure-openssl.c
@@ -81,6 +81,50 @@ be_tls_init(bool isServerStart)
 	/* This stuff need be done only once. */
 	if (!SSL_initialized)
 	{
+#ifdef WIN32
+		HKEY rootKey;
+		DWORD fipsEnabled = 0;
+		DWORD fipsEnabledSize = sizeof(DWORD);
+
+		if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+			"System\\CurrentControlSet\\Control\\Lsa\\FipsAlgorithmPolicy",
+			0,
+			KEY_READ,
+			&rootKey) != ERROR_SUCCESS)
+		{
+			ereport(isServerStart ? FATAL : LOG,
+				(errmsg("could not open FIPS registry key")));
+			goto error;
+		}
+		if (RegQueryValueEx(rootKey,
+			"Enabled",
+			0,
+			0,
+			(LPBYTE)&fipsEnabled,
+			&fipsEnabledSize) != ERROR_SUCCESS)
+		{
+			RegCloseKey(rootKey);
+			ereport(isServerStart ? FATAL : LOG,
+				(errmsg("could not read FIPS registry entry")));
+			goto error;
+		}
+		RegCloseKey(rootKey);
+
+		if (fipsEnabled == 1 && FIPS_mode() == 0)
+		{
+			if (FIPS_mode_set(1) != 1)
+			{
+				ereport(isServerStart ? FATAL : LOG,
+					(errmsg("could not enable FIPS mode")));
+				goto error;
+			}
+
+			ereport(LOG,
+				(errmsg("successfully enabled OpenSSL FIPS mode")));
+		}
+
+#endif
+
 #ifdef HAVE_OPENSSL_INIT_SSL
 		OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
 #else
diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c
index bbae8ef..6c1cf6c 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -703,6 +703,46 @@ pgtls_init(PGconn *conn)
 	{
 		if (pq_init_ssl_lib)
 		{
+#ifdef WIN32
+			HKEY rootKey;
+			DWORD fipsEnabled = 0;
+			DWORD fipsEnabledSize = sizeof(DWORD);
+
+			if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+				"System\\CurrentControlSet\\Control\\Lsa\\FipsAlgorithmPolicy",
+				0,
+				KEY_READ,
+				&rootKey) != ERROR_SUCCESS)
+			{
+				printfPQExpBuffer(&conn->errorMessage,
+					libpq_gettext("could not open FIPS registry key"));
+				return -1;
+			}
+			if (RegQueryValueEx(rootKey,
+				"Enabled",
+				0,
+				0,
+				(LPBYTE) &fipsEnabled,
+				&fipsEnabledSize) != ERROR_SUCCESS)
+			{
+				RegCloseKey(rootKey);
+				printfPQExpBuffer(&conn->errorMessage,
+					libpq_gettext("could not read FIPS registry entry"));
+				return -1;
+			}
+			RegCloseKey(rootKey);
+
+			if (fipsEnabled == 1 && FIPS_mode() == 0)
+			{
+				if (FIPS_mode_set(1) != 1)
+				{
+					printfPQExpBuffer(&conn->errorMessage,
+						libpq_gettext("could not enable FIPS mode"));
+					return -1;
+				}
+			}
+#endif
+
 #ifdef HAVE_OPENSSL_INIT_SSL
 			OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
 #else
-- 
2.7.4

