From 9caa50893fc3b8d3447ce14d4b93876aa7ffe91a Mon Sep 17 00:00:00 2001
From: Jacob Champion <pchampion@vmware.com>
Date: Mon, 19 Jul 2021 12:14:00 -0700
Subject: [PATCH 3/4] nss: fix spurious "unable to verify certificate" message

That message gets written to conn->errorMessage even if sslmode isn't
verifying the certificate contents, which can lead to a confusing UX if
the connection later fails for some other reason.
---
 src/interfaces/libpq/fe-secure-nss.c | 25 ++++++++++++-------------
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/src/interfaces/libpq/fe-secure-nss.c b/src/interfaces/libpq/fe-secure-nss.c
index cc66f5bb8c..4490fb03e4 100644
--- a/src/interfaces/libpq/fe-secure-nss.c
+++ b/src/interfaces/libpq/fe-secure-nss.c
@@ -858,12 +858,6 @@ pg_cert_auth_handler(void *arg, PRFileDesc *fd, PRBool checksig, PRBool isServer
 		if (!pq_verify_peer_name_matches_certificate(conn))
 			status = SECFailure;
 	}
-	else
-	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("unable to verify certificate: %s"),
-						  pg_SSLerrmessage(PR_GetError()));
-	}
 
 	CERT_DestroyCertificate(server_cert);
 	return status;
@@ -923,6 +917,8 @@ pg_bad_cert_handler(void *arg, PRFileDesc *fd)
 	if (!arg)
 		return SECFailure;
 
+	err = PORT_GetError();
+
 	/*
 	 * For sslmodes other than verify-full and verify-ca we don't perform peer
 	 * validation, so return immediately.  sslmode require with a database
@@ -934,13 +930,11 @@ pg_bad_cert_handler(void *arg, PRFileDesc *fd)
 		if (conn->ssldatabase &&
 			strlen(conn->ssldatabase) > 0 &&
 			certificate_database_has_CA(conn))
-			return SECFailure;
+			goto failure;
 	}
 	else if (strcmp(conn->sslmode, "verify-full") == 0 ||
 			 strcmp(conn->sslmode, "verify-ca") == 0)
-		return SECFailure;
-
-	err = PORT_GetError();
+		goto failure;
 
 	/*
 	 * TODO: these are relevant error codes that can occur in certificate
@@ -963,15 +957,20 @@ pg_bad_cert_handler(void *arg, PRFileDesc *fd)
 		case SEC_ERROR_CA_CERT_INVALID:
 		case SEC_ERROR_CERT_USAGES_INVALID:
 		case SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION:
-			return SECSuccess;
 			break;
 		default:
-			return SECFailure;
+			goto failure;
 			break;
 	}
 
-	/* Unreachable */
 	return SECSuccess;
+
+failure:
+	printfPQExpBuffer(&conn->errorMessage,
+					  libpq_gettext("unable to verify certificate: %s"),
+					  pg_SSLerrmessage(err));
+
+	return SECFailure;
 }
 
 /* ------------------------------------------------------------ */
-- 
2.25.1

