summaryrefslogtreecommitdiff
path: root/src/test/ssl/t
diff options
context:
space:
mode:
authorDaniel Gustafsson2023-04-05 21:22:17 +0000
committerDaniel Gustafsson2023-04-05 21:22:17 +0000
commit8eda7314652703a2ae30d6c4a69c378f6813a7f2 (patch)
tree0dfd6463eabef599134238781f3c59e4b031b733 /src/test/ssl/t
parent12f3867f5534754c8bac5af35228d4079edc3a00 (diff)
Allow to use system CA pool for certificate verification
This adds a new option to libpq's sslrootcert, "system", which will load the system trusted CA roots for certificate verification. This is a more convenient way to achieve this than pointing to the system CA roots manually since the location can differ by installation and be locally adjusted by env vars in OpenSSL. When sslrootcert is set to system, sslmode is forced to be verify-full as weaker modes aren't providing much security for public CAs. Changing the location of the system roots by setting environment vars is not supported by LibreSSL so the tests will use a heuristic to determine if the system being tested is LibreSSL or OpenSSL. The workaround in .cirrus.yml is required to handle a strange interaction between homebrew and the openssl@3 formula; hopefully this can be removed in the near future. The original patch was written by Thomas Habets, which was later revived by Jacob Champion. Author: Jacob Champion <[email protected]> Author: Thomas Habets <[email protected]> Reviewed-by: Jelte Fennema <[email protected]> Reviewed-by: Andrew Dunstan <[email protected]> Reviewed-by: Magnus Hagander <[email protected]> Discussion: https://www.postgresql.org/message-id/flat/CA%2BkHd%2BcJwCUxVb-Gj_0ptr3_KZPwi3%2B67vK6HnLFBK9MzuYrLA%40mail.gmail.com
Diffstat (limited to 'src/test/ssl/t')
-rw-r--r--src/test/ssl/t/001_ssltests.pl43
1 files changed, 43 insertions, 0 deletions
diff --git a/src/test/ssl/t/001_ssltests.pl b/src/test/ssl/t/001_ssltests.pl
index dc43b8f81aa..6fdc040cfc2 100644
--- a/src/test/ssl/t/001_ssltests.pl
+++ b/src/test/ssl/t/001_ssltests.pl
@@ -33,6 +33,12 @@ sub switch_server_cert
{
$ssl_server->switch_server_cert(@_);
}
+
+# Determine whether this build uses OpenSSL or LibreSSL. As a heuristic, the
+# HAVE_SSL_CTX_SET_CERT_CB macro isn't defined for LibreSSL. (Nor for OpenSSL
+# 1.0.1, but that's old enough that accommodating it isn't worth the cost.)
+my $libressl = not check_pg_config("#define HAVE_SSL_CTX_SET_CERT_CB 1");
+
#### Some configuration
# This is the hostname used to connect to the server. This cannot be a
@@ -461,6 +467,43 @@ $node->connect_fails(
expected_stderr =>
qr/could not get server's host name from server certificate/);
+# Test system trusted roots.
+switch_server_cert($node,
+ certfile => 'server-cn-only+server_ca',
+ keyfile => 'server-cn-only',
+ cafile => 'root_ca');
+$common_connstr =
+ "$default_ssl_connstr user=ssltestuser dbname=trustdb sslrootcert=system hostaddr=$SERVERHOSTADDR";
+
+# By default our custom-CA-signed certificate should not be trusted.
+$node->connect_fails(
+ "$common_connstr sslmode=verify-full host=common-name.pg-ssltest.test",
+ "sslrootcert=system does not connect with private CA",
+ expected_stderr => qr/SSL error: certificate verify failed/);
+
+# Modes other than verify-full cannot be mixed with sslrootcert=system.
+$node->connect_fails(
+ "$common_connstr sslmode=verify-ca host=common-name.pg-ssltest.test",
+ "sslrootcert=system only accepts sslmode=verify-full",
+ expected_stderr => qr/weak sslmode "verify-ca" may not be used with sslrootcert=system/);
+
+SKIP:
+{
+ skip "SSL_CERT_FILE is not supported with LibreSSL" if $libressl;
+
+ # We can modify the definition of "system" to get it trusted again.
+ local $ENV{SSL_CERT_FILE} = $node->data_dir . "/root_ca.crt";
+ $node->connect_ok(
+ "$common_connstr sslmode=verify-full host=common-name.pg-ssltest.test",
+ "sslrootcert=system connects with overridden SSL_CERT_FILE");
+
+ # verify-full mode should be the default for system CAs.
+ $node->connect_fails(
+ "$common_connstr host=common-name.pg-ssltest.test.bad",
+ "sslrootcert=system defaults to sslmode=verify-full",
+ expected_stderr => qr/server certificate for "common-name.pg-ssltest.test" does not match host name "common-name.pg-ssltest.test.bad"/);
+}
+
# Test that the CRL works
switch_server_cert($node, certfile => 'server-revoked');