v26-0004-nss-Add-NSS-specific-tests.patch
application/octet-stream
Filename: v26-0004-nss-Add-NSS-specific-tests.patch
Type: application/octet-stream
Part: 6
Patch
Format: format-patch
Series: patch v26-0004
Subject: nss: Add NSS specific tests
| File | + | − |
|---|---|---|
| src/test/ssl/Makefile | 225 | 0 |
| src/test/ssl/t/001_ssltests.pl | 204 | 92 |
| src/test/ssl/t/002_scram.pl | 21 | 8 |
| src/test/ssl/t/SSL/Backend/NSS.pm | 73 | 0 |
From a595749b283822921dd08e8eceeed33bcb6d9dcc Mon Sep 17 00:00:00 2001
From: Daniel Gustafsson <daniel@yesql.se>
Date: Mon, 8 Feb 2021 23:52:37 +0100
Subject: [PATCH v26 04/10] nss: Add NSS specific tests
This adds the SSL/Backend/NSS which implements the setup and teardown
required as well as adds the NSS configuration to the existing tests.
The OpenSSL testfiles are reused by repackaging them into NSS databases
in order for the tests to be cross-library. Additional testfiles are
generated by using only the NSS toolchain as well as rudimentary tests
using these.
---
src/test/ssl/Makefile | 225 +++++++++++++++++++++++
src/test/ssl/t/001_ssltests.pl | 296 ++++++++++++++++++++----------
src/test/ssl/t/002_scram.pl | 29 ++-
src/test/ssl/t/SSL/Backend/NSS.pm | 73 ++++++++
4 files changed, 523 insertions(+), 100 deletions(-)
create mode 100644 src/test/ssl/t/SSL/Backend/NSS.pm
diff --git a/src/test/ssl/Makefile b/src/test/ssl/Makefile
index d545382eea..6966dc23d2 100644
--- a/src/test/ssl/Makefile
+++ b/src/test/ssl/Makefile
@@ -30,6 +30,35 @@ SSLFILES := $(CERTIFICATES:%=ssl/%.key) $(CERTIFICATES:%=ssl/%.crt) \
ssl/client+client_ca.crt ssl/client-der.key \
ssl/client-encrypted-pem.key ssl/client-encrypted-der.key
+# Even though we in practice could get away with far fewer NSS databases, they
+# are generated to mimic the setup for the OpenSSL tests in order to ensure
+# we isolate the same behavior between the backends. The database name should
+# contain the files included for easier test suite code reading.
+NSSFILES := ssl/nss/client_ca.crt.db \
+ ssl/nss/server_ca.crt.db \
+ ssl/nss/root+server_ca.crt.db \
+ ssl/nss/root+client_ca.crt.db \
+ ssl/nss/client.crt__client.key.db \
+ ssl/nss/client-revoked.crt__client-revoked.key.db \
+ ssl/nss/server-cn-only.crt__server-password.key.db \
+ ssl/nss/server-cn-only.crt__server-cn-only.key.db \
+ ssl/nss/root.crl \
+ ssl/nss/server.crl \
+ ssl/nss/client.crl \
+ ssl/nss/server-multiple-alt-names.crt__server-multiple-alt-names.key.db \
+ ssl/nss/server-single-alt-name.crt__server-single-alt-name.key.db \
+ ssl/nss/server-cn-and-alt-names.crt__server-cn-and-alt-names.key.db \
+ ssl/nss/server-no-names.crt__server-no-names.key.db \
+ ssl/nss/server-revoked.crt__server-revoked.key.db \
+ ssl/nss/root+client.crl \
+ ssl/nss/client+client_ca.crt__client.key.db \
+ ssl/nss/client.crt__client-encrypted-pem.key.db \
+ ssl/nss/root+server_ca.crt__server.crl.db \
+ ssl/nss/root+server_ca.crt__root+server.crl.db \
+ ssl/nss/native_ca-root.db \
+ ssl/nss/native_server-root.db \
+ ssl/nss/native_client-root.db
+
# This target re-generates all the key and certificate files. Usually we just
# use the ones that are committed to the tree without rebuilding them.
#
@@ -37,6 +66,10 @@ SSLFILES := $(CERTIFICATES:%=ssl/%.key) $(CERTIFICATES:%=ssl/%.crt) \
#
sslfiles: $(SSLFILES)
+# Generate NSS certificate databases corresponding to the OpenSSL certificates.
+# This target will fail unless preceded by nssfiles-clean.
+nssfiles: $(NSSFILES)
+
# OpenSSL requires a directory to put all generated certificates in. We don't
# use this for anything, but we need a location.
ssl/new_certs_dir:
@@ -64,6 +97,24 @@ ssl/%_ca.crt: ssl/%_ca.key %_ca.config ssl/root_ca.crt ssl/new_certs_dir
rm ssl/temp_ca.crt ssl/temp_ca_signed.crt
echo "01" > ssl/$*_ca.srl
+ssl/nss/%_ca.crt.db: ssl/%_ca.crt
+ $(MKDIR_P) $@
+ certutil -d "sql:$@" -N --empty-password
+ certutil -d "sql:$@" -A -n $*_ca.crt -i ssl/$*_ca.crt -t "CT,C,C"
+
+ssl/nss/root+server_ca.crt__server.crl.db: ssl/root+server_ca.crt ssl/nss/server.crl
+ $(MKDIR_P) $@
+ certutil -d "sql:$@" -N --empty-password
+ certutil -d "sql:$@" -A -n ssl/root+server_ca.crt -i ssl/root+server_ca.crt -t "CT,C,C"
+ crlutil -I -i ssl/nss/server.crl -d $@ -B
+
+ssl/nss/root+server_ca.crt__root+server.crl.db: ssl/root+server_ca.crt ssl/nss/root.crl ssl/nss/server.crl
+ $(MKDIR_P) $@
+ certutil -d "sql:$@" -N --empty-password
+ certutil -d "sql:$@" -A -n ssl/root+server_ca.crt -i ssl/root+server_ca.crt -t "CT,C,C"
+ crlutil -I -i ssl/nss/root.crl -d $@ -B
+ crlutil -I -i ssl/nss/server.crl -d $@ -B
+
# Server certificates, signed by server CA:
ssl/server-%.crt: ssl/server-%.key ssl/server_ca.crt server-%.config
openssl req -new -key ssl/server-$*.key -out ssl/server-$*.csr -config server-$*.config
@@ -77,6 +128,79 @@ ssl/server-ss.crt: ssl/server-cn-only.key ssl/server-cn-only.crt server-cn-only.
openssl x509 -req -days 10000 -in ssl/server-ss.csr -signkey ssl/server-cn-only.key -out ssl/server-ss.crt -extensions v3_req -extfile server-cn-only.config
rm ssl/server-ss.csr
+# pk12util won't preserve the password when importing the password protected
+# key, the password must be set on the database *before* importing it as the
+# password in the pkcs12 envelope will be dropped.
+ssl/nss/server-cn-only.crt__server-password.key.db: ssl/server-cn-only.crt
+ $(MKDIR_P) $@
+ echo "secret1" > password.txt
+ certutil -d "sql:$@" -N -f password.txt
+ certutil -d "sql:$@" -A -n ssl/server-cn-only.crt -i ssl/server-cn-only.crt -t "CT,C,C" -f password.txt
+ certutil -d "sql:$@" -A -n server_ca.crt -i ssl/server_ca.crt -t "CT,C,C" -f password.txt
+ certutil -d "sql:$@" -A -n root_ca.crt -i ssl/root_ca.crt -t "CT,C,C" -f password.txt
+ certutil -d "sql:$@" -A -n client_ca.crt -i ssl/client_ca.crt -t "CT,C,C" -f password.txt
+ openssl pkcs12 -export -out ssl/nss/server-password.pfx -inkey ssl/server-password.key -in ssl/server-cn-only.crt -certfile ssl/server_ca.crt -passin 'pass:secret1' -passout 'pass:secret1'
+ pk12util -i ssl/nss/server-password.pfx -d "sql:$@" -W 'secret1' -K 'secret1'
+
+ssl/nss/server-cn-only.crt__server-cn-only.key.db: ssl/server-cn-only.crt ssl/server-cn-only.key
+ $(MKDIR_P) $@
+ certutil -d "sql:$@" -N --empty-password
+ certutil -d "sql:$@" -A -n ssl/server-cn-only.crt -i ssl/server-cn-only.crt -t "CT,C,C"
+ certutil -d "sql:$@" -A -n server_ca.crt -i ssl/server_ca.crt -t "CT,C,C"
+ certutil -d "sql:$@" -A -n root_ca.crt -i ssl/root_ca.crt -t "CT,C,C"
+ openssl pkcs12 -export -out ssl/nss/server-cn-only.pfx -inkey ssl/server-cn-only.key -in ssl/server-cn-only.crt -certfile ssl/server_ca.crt -passout pass:
+ pk12util -i ssl/nss/server-cn-only.pfx -d "sql:$@" -W ''
+
+ssl/nss/server-multiple-alt-names.crt__server-multiple-alt-names.key.db: ssl/server-multiple-alt-names.crt
+ $(MKDIR_P) $@
+ certutil -d "sql:$@" -N --empty-password
+ certutil -d "sql:$@" -A -n ssl/server-multiple-alt-names.crt -i ssl/server-multiple-alt-names.crt -t "CT,C,C"
+ certutil -d "sql:$@" -A -n server_ca.crt -i ssl/server_ca.crt -t "CT,C,C"
+ certutil -d "sql:$@" -A -n root_ca.crt -i ssl/root_ca.crt -t "CT,C,C"
+ certutil -d "sql:$@" -A -n client_ca.crt -i ssl/client_ca.crt -t "CT,C,C"
+ openssl pkcs12 -export -out ssl/nss/server-multiple-alt-names.pfx -inkey ssl/server-multiple-alt-names.key -in ssl/server-multiple-alt-names.crt -certfile ssl/server-multiple-alt-names.crt -passout pass:
+ pk12util -i ssl/nss/server-multiple-alt-names.pfx -d "sql:$@" -W ''
+
+ssl/nss/server-single-alt-name.crt__server-single-alt-name.key.db: ssl/server-single-alt-name.crt
+ $(MKDIR_P) $@
+ certutil -d "sql:$@" -N --empty-password
+ certutil -d "sql:$@" -A -n ssl/server-single-alt-name.crt -i ssl/server-single-alt-name.crt -t "CT,C,C"
+ certutil -d "sql:$@" -A -n server_ca.crt -i ssl/server_ca.crt -t "CT,C,C"
+ certutil -d "sql:$@" -A -n root_ca.crt -i ssl/root_ca.crt -t "CT,C,C"
+ certutil -d "sql:$@" -A -n client_ca.crt -i ssl/client_ca.crt -t "CT,C,C"
+ openssl pkcs12 -export -out ssl/nss/server-single-alt-name.pfx -inkey ssl/server-single-alt-name.key -in ssl/server-single-alt-name.crt -certfile ssl/server-single-alt-name.crt -passout pass:
+ pk12util -i ssl/nss/server-single-alt-name.pfx -d "sql:$@" -W ''
+
+ssl/nss/server-cn-and-alt-names.crt__server-cn-and-alt-names.key.db: ssl/server-cn-and-alt-names.crt
+ $(MKDIR_P) $@
+ certutil -d "sql:$@" -N --empty-password
+ certutil -d "sql:$@" -A -n ssl/server-cn-and-alt-names.crt -i ssl/server-cn-and-alt-names.crt -t "CT,C,C"
+ certutil -d "sql:$@" -A -n server_ca.crt -i ssl/server_ca.crt -t "CT,C,C"
+ certutil -d "sql:$@" -A -n root_ca.crt -i ssl/root_ca.crt -t "CT,C,C"
+ certutil -d "sql:$@" -A -n client_ca.crt -i ssl/client_ca.crt -t "CT,C,C"
+ openssl pkcs12 -export -out ssl/nss/server-cn-and-alt-names.pfx -inkey ssl/server-cn-and-alt-names.key -in ssl/server-cn-and-alt-names.crt -certfile ssl/server-cn-and-alt-names.crt -passout pass:
+ pk12util -i ssl/nss/server-cn-and-alt-names.pfx -d $@ -W ''
+
+ssl/nss/server-no-names.crt__server-no-names.key.db: ssl/server-no-names.crt
+ $(MKDIR_P) $@
+ certutil -d "sql:$@" -N --empty-password
+ certutil -d "sql:$@" -A -n ssl/server-no-names.crt -i ssl/server-no-names.crt -t "CT,C,C"
+ certutil -d "sql:$@" -A -n server_ca.crt -i ssl/server_ca.crt -t "CT,C,C"
+ certutil -d "sql:$@" -A -n root_ca.crt -i ssl/root_ca.crt -t "CT,C,C"
+ certutil -d "sql:$@" -A -n client_ca.crt -i ssl/client_ca.crt -t "CT,C,C"
+ openssl pkcs12 -export -out ssl/nss/server-no-names.pfx -inkey ssl/server-no-names.key -in ssl/server-no-names.crt -certfile ssl/server-no-names.crt -passout pass:
+ pk12util -i ssl/nss/server-no-names.pfx -d "sql:$@" -W ''
+
+ssl/nss/server-revoked.crt__server-revoked.key.db: ssl/server-revoked.crt
+ $(MKDIR_P) $@
+ certutil -d "sql:$@" -N --empty-password
+ certutil -d "sql:$@" -A -n ssl/server-revoked.crt -i ssl/server-revoked.crt -t "CT,C,C"
+ certutil -d "sql:$@" -A -n server_ca.crt -i ssl/server_ca.crt -t "CT,C,C"
+ certutil -d "sql:$@" -A -n root_ca.crt -i ssl/root_ca.crt -t "CT,C,C"
+ certutil -d "sql:$@" -A -n client_ca.crt -i ssl/client_ca.crt -t "CT,C,C"
+ openssl pkcs12 -export -out ssl/nss/server-revoked.pfx -inkey ssl/server-revoked.key -in ssl/server-revoked.crt -certfile ssl/server-revoked.crt -passout pass:
+ pk12util -i ssl/nss/server-revoked.pfx -d "sql:$@" -W ''
+
# Password-protected version of server-cn-only.key
ssl/server-password.key: ssl/server-cn-only.key
openssl rsa -aes256 -in $< -out $@ -passout 'pass:secret1'
@@ -88,6 +212,27 @@ ssl/client.crt: ssl/client.key ssl/client_ca.crt
openssl x509 -in ssl/temp.crt -out ssl/client.crt # to keep just the PEM cert
rm ssl/client.csr ssl/temp.crt
+# Client certificate, signed by client CA
+ssl/nss/client.crt__client.key.db: ssl/client.crt
+ $(MKDIR_P) $@
+ certutil -d "sql:$@" -N --empty-password
+ certutil -d "sql:$@" -A -n ssl/client.crt -i ssl/client.crt -t "CT,C,C"
+ certutil -d "sql:$@" -A -n client_ca.crt -i ssl/client_ca.crt -t "CT,C,C"
+ certutil -d "sql:$@" -A -n root+client_ca.crt -i ssl/root+client_ca.crt -t "CT,C,C"
+ openssl pkcs12 -export -out ssl/nss/client.pfx -inkey ssl/client.key -in ssl/client.crt -certfile ssl/client_ca.crt -passout pass:
+ pk12util -i ssl/nss/client.pfx -d "sql:$@" -W ''
+
+# Client certificate with encrypted key, signed by client CA
+ssl/nss/client.crt__client-encrypted-pem.key.db: ssl/client.crt
+ $(MKDIR_P) $@
+ echo 'dUmmyP^#+' > $@.pass
+ certutil -d "sql:$@" -N -f $@.pass
+ certutil -d "sql:$@" -A -f $@.pass -n ssl/client.crt -i ssl/client.crt -t "CT,C,C"
+ certutil -d "sql:$@" -A -f $@.pass -n client_ca.crt -i ssl/client_ca.crt -t "CT,C,C"
+ certutil -d "sql:$@" -A -f $@.pass -n root+server_ca.crt -i ssl/root+server_ca.crt -t "CT,C,C"
+ openssl pkcs12 -export -out ssl/nss/client-encrypted-pem.pfx -inkey ssl/client-encrypted-pem.key -in ssl/client.crt -certfile ssl/client_ca.crt -passin pass:'dUmmyP^#+' -passout pass:'dUmmyP^#+'
+ pk12util -i ssl/nss/client-encrypted-pem.pfx -d "sql:$@" -W 'dUmmyP^#+' -k $@.pass
+
# Another client certificate, signed by the client CA. This one is revoked.
ssl/client-revoked.crt: ssl/client-revoked.key ssl/client_ca.crt client.config
openssl req -new -key ssl/client-revoked.key -out ssl/client-revoked.csr -config client.config
@@ -95,6 +240,14 @@ ssl/client-revoked.crt: ssl/client-revoked.key ssl/client_ca.crt client.config
openssl x509 -in ssl/temp.crt -out ssl/client-revoked.crt # to keep just the PEM cert
rm ssl/client-revoked.csr ssl/temp.crt
+ssl/nss/client-revoked.crt__client-revoked.key.db: ssl/client-revoked.crt
+ $(MKDIR_P) $@
+ certutil -d "sql:$@" -N --empty-password
+ certutil -d "sql:$@" -A -n ssl/client-revoked.crt -i ssl/client-revoked.crt -t "CT,C,C"
+ certutil -d "sql:$@" -A -n client_ca.crt -i ssl/client_ca.crt -t "CT,C,C"
+ openssl pkcs12 -export -out ssl/nss/client-revoked.pfx -inkey ssl/client-revoked.key -in ssl/client-revoked.crt -certfile ssl/client_ca.crt -passout pass:
+ pk12util -i ssl/nss/client-revoked.pfx -d "sql:$@" -W ''
+
# Convert the key to DER, to test our behaviour there too
ssl/client-der.key: ssl/client.key
openssl rsa -in ssl/client.key -outform DER -out ssl/client-der.key
@@ -127,19 +280,40 @@ ssl/root+client_ca.crt: ssl/root_ca.crt ssl/client_ca.crt
ssl/client+client_ca.crt: ssl/client.crt ssl/client_ca.crt
cat $^ > $@
+# Client certificate, signed by client CA
+ssl/nss/client+client_ca.crt__client.key.db: ssl/client+client_ca.crt
+ $(MKDIR_P) $@
+ certutil -d "sql:$@" -N --empty-password
+ certutil -d "sql:$@" -A -n ssl/client+client_ca.crt -i ssl/client+client_ca.crt -t "CT,C,C"
+ certutil -d "sql:$@" -A -n ssl/root+server_ca.crt -i ssl/root+server_ca.crt -t "CT,C,C"
+ openssl pkcs12 -export -out ssl/nss/client.pfx -inkey ssl/client.key -in ssl/client.crt -certfile ssl/client_ca.crt -passout pass:
+ pk12util -i ssl/nss/client.pfx -d "sql:$@" -W ''
+
#### CRLs
ssl/client.crl: ssl/client-revoked.crt
openssl ca -config cas.config -name client_ca -revoke ssl/client-revoked.crt
openssl ca -config cas.config -name client_ca -gencrl -out ssl/client.crl
+ssl/nss/client.crl: ssl/client.crl
+ openssl crl -in $^ -outform der -out $@
+
ssl/server.crl: ssl/server-revoked.crt
openssl ca -config cas.config -name server_ca -revoke ssl/server-revoked.crt
openssl ca -config cas.config -name server_ca -gencrl -out ssl/server.crl
+ssl/nss/server.crl: ssl/server.crl
+ openssl crl -in $^ -outform der -out $@
+
ssl/root.crl: ssl/root_ca.crt
openssl ca -config cas.config -name root_ca -gencrl -out ssl/root.crl
+ssl/nss/root.crl: ssl/root.crl
+ openssl crl -in $^ -outform der -out $@
+
+ssl/nss/root+client.crl: ssl/root+client.crl
+ openssl crl -in $^ -outform der -out $@
+
# If a CRL is used, OpenSSL requires a CRL file for *all* the CAs in the
# chain, even if some of them are empty.
ssl/root+server.crl: ssl/root.crl ssl/server.crl
@@ -147,13 +321,64 @@ ssl/root+server.crl: ssl/root.crl ssl/server.crl
ssl/root+client.crl: ssl/root.crl ssl/client.crl
cat $^ > $@
+#### NSS specific certificates and keys
+
+ssl/nss/native_ca-%.db:
+ $(MKDIR_P) ssl/nss/native_ca-$*.db
+ certutil -N -d "sql:ssl/nss/native_ca-$*.db/" --empty-password
+ echo y > nss_ca_params.txt
+ echo 10 >> nss_ca_params.txt
+ echo y >> nss_ca_params.txt
+ cat nss_ca_params.txt | certutil -S -d "sql:ssl/nss/native_ca-$*.db/" -n ca-$* \
+ -s "CN=Test CA for PostgreSQL SSL regression tests,OU=PostgreSQL test suite" \
+ -x -k rsa -g 2048 -m 5432 -t CTu,CTu,CTu \
+ --keyUsage certSigning -2 --nsCertType sslCA,smimeCA,objectSigningCA \
+ -z Makefile -Z SHA256
+ rm nss_ca_params.txt
+
+ssl/nss/native_ca-%.pem: ssl/nss/native_ca-%.db
+ certutil -L -d "sql:ssl/nss/native_ca-$*.db/" -n ca-$* -a > ssl/nss/native_ca-$*.pem
+
+# Create and sign a server certificate
+ssl/nss/native_server-%.db: ssl/nss/native_ca-%.pem
+ $(MKDIR_P) ssl/nss/native_server-$*.db
+ certutil -N -d "sql:ssl/nss/native_server-$*.db/" --empty-password
+ certutil -R -d "sql:ssl/nss/native_server-$*.db/" \
+ -s "CN=common-name.pg-ssltest.test,OU=PostgreSQL test suite" \
+ -o ssl/nss/native_server-$*.csr -g 2048 -Z SHA256 -z Makefile
+ echo 1 > nss_server_params.txt
+ echo 9 >> nss_server_params.txt
+ cat nss_server_params.txt | certutil -C -d "sql:ssl/nss/native_ca-$*.db/" -c ca-root -i ssl/nss/native_server-$*.csr \
+ -o ssl/nss/native_server_$*.der -m 5433 --keyUsage dataEncipherment,digitalSignature,keyEncipherment \
+ --nsCertType sslServer --certVersion 1 -Z SHA256
+ certutil -A -d "sql:ssl/nss/native_server-$*.db/" -n ca-$* -t CTu,CTu,CTu -a -i ssl/nss/native_ca-$*.pem
+ certutil -A -d "sql:ssl/nss/native_server-$*.db/" -n ssl/native_server-$*.crt -t CTu,CTu,CTu -i ssl/nss/native_server_$*.der
+ rm nss_server_params.txt
+
+# Create and sign a client certificate
+ssl/nss/native_client-%.db: ssl/nss/native_ca-%.pem
+ $(MKDIR_P) ssl/nss/native_client-$*.db
+ certutil -N -d "sql:ssl/nss/native_client-$*.db/" --empty-password
+ certutil -R -d "sql:ssl/nss/native_client-$*.db/" -s "CN=ssltestuser,OU=PostgreSQL test suite" \
+ -o ssl/nss/native_client-$*.csr -g 2048 -Z SHA256 -z Makefile
+ certutil -C -d "sql:ssl/nss/native_ca-$*.db/" -c ca-$* -i ssl/nss/native_client-$*.csr -o ssl/nss/native_client-$*.der \
+ -m 5434 --keyUsage keyEncipherment,dataEncipherment,digitalSignature --nsCertType sslClient \
+ --certVersion 1 -Z SHA256
+ certutil -A -d "sql:ssl/nss/native_client-$*.db" -n ca-$* -t CTu,CTu,CTu -a -i ssl/nss/native_ca-$*.pem
+ certutil -A -d "sql:ssl/nss/native_client-$*.db" -n native_client-$* -t CTu,CTu,CTu -i ssl/nss/native_client-$*.der
+
.PHONY: sslfiles-clean
sslfiles-clean:
rm -f $(SSLFILES) ssl/client_ca.srl ssl/server_ca.srl ssl/client_ca-certindex* ssl/server_ca-certindex* ssl/root_ca-certindex* ssl/root_ca.srl ssl/temp_ca.crt ssl/temp_ca_signed.crt
+.PHONY: nssfiles-clean
+nssfiles-clean:
+ rm -rf ssl/nss
+
clean distclean maintainer-clean:
rm -rf tmp_check
rm -rf ssl/*.old ssl/new_certs_dir ssl/client*_tmp.key
+ rm -rf ssl/nss
# Doesn't depend on $(SSLFILES) because we don't rebuild them by default
check:
diff --git a/src/test/ssl/t/001_ssltests.pl b/src/test/ssl/t/001_ssltests.pl
index a6d79e2bfc..394505dd8b 100644
--- a/src/test/ssl/t/001_ssltests.pl
+++ b/src/test/ssl/t/001_ssltests.pl
@@ -9,7 +9,20 @@ use lib $FindBin::RealBin;
use SSL::Server;
-if ($ENV{with_ssl} ne 'openssl')
+my $openssl;
+my $nss;
+
+if ($ENV{with_ssl} eq 'openssl')
+{
+ $openssl = 1;
+ plan tests => 93;
+}
+elsif ($ENV{with_ssl} eq 'nss')
+{
+ $nss = 1;
+ plan tests => 99;
+}
+else
{
plan skip_all => 'SSL not supported by this build';
}
@@ -47,19 +60,58 @@ configure_test_server_for_ssl($node, $SERVERHOSTADDR, $SERVERHOSTCIDR,
note "testing password-protected keys";
-set_server_cert($node, 'server-cn-only', 'root+client_ca',
- 'server-password', 'echo wrongpassword');
-command_fails(
- [ 'pg_ctl', '-D', $node->data_dir, '-l', $node->logfile, 'restart' ],
- 'restart fails with password-protected key file with wrong password');
-$node->_update_pid(0);
+# Since the passphrase callbacks operate at different stages in OpenSSL and
+# NSS we have two separate blocks for them
+SKIP:
+{
+ skip "Certificate passphrases aren't checked on server restart in NSS", 2
+ if ($nss);
+
+ set_server_cert($node, 'server-cn-only', 'root+client_ca',
+ 'server-password', 'echo wrongpassword');
+ command_fails(
+ [ 'pg_ctl', '-D', $node->data_dir, '-l', $node->logfile, 'restart' ],
+ 'restart fails with password-protected key file with wrong password');
+ $node->_update_pid(0);
+
+ set_server_cert($node, 'server-cn-only', 'root+client_ca',
+ 'server-password', 'echo secret1');
+ command_ok(
+ [ 'pg_ctl', '-D', $node->data_dir, '-l', $node->logfile, 'restart' ],
+ 'restart succeeds with password-protected key file');
+ $node->_update_pid(1);
+}
-set_server_cert($node, 'server-cn-only', 'root+client_ca',
- 'server-password', 'echo secret1');
-command_ok(
- [ 'pg_ctl', '-D', $node->data_dir, '-l', $node->logfile, 'restart' ],
- 'restart succeeds with password-protected key file');
-$node->_update_pid(1);
+SKIP:
+{
+ skip "Certificate passphrases are checked on connection in NSS", 5
+ if ($openssl);
+
+ set_server_cert($node, 'server-cn-only', 'root+client_ca',
+ 'server-password', 'echo wrongpassword');
+ command_ok(
+ [ 'pg_ctl', '-D', $node->data_dir, '-l', $node->logfile, 'restart' ],
+ 'restart fails with password-protected key file with wrong password');
+ $node->_update_pid(1);
+
+ test_connect_fails(
+ "user=ssltestuser dbname=trustdb sslcert=invalid hostaddr=$SERVERHOSTADDR host=common-name.pg-ssltest.test",
+ "sslrootcert=invalid sslmode=require",
+ qr/\QSSL error\E/,
+ "connect to server with incorrect key password configured");
+
+ set_server_cert($node, 'server-cn-only', 'root+client_ca',
+ 'server-password', 'echo secret1');
+ command_ok(
+ [ 'pg_ctl', '-D', $node->data_dir, '-l', $node->logfile, 'restart' ],
+ 'restart fails with password-protected key file with wrong password');
+ $node->_update_pid(1);
+
+ test_connect_ok(
+ "user=ssltestuser dbname=trustdb sslcert=invalid hostaddr=$SERVERHOSTADDR host=common-name.pg-ssltest.test",
+ "sslrootcert=invalid sslmode=require",
+ "connect to server with correct key password configured");
+}
# Test compatibility of SSL protocols.
# TLSv1.1 is lower than TLSv1.2, so it won't work.
@@ -107,82 +159,105 @@ test_connect_ok(
test_connect_fails(
$common_connstr,
"sslrootcert=invalid sslmode=verify-ca",
- qr/root certificate file "invalid" does not exist/,
+ qr/root certificate file "invalid" does not exist|Peer's certificate issuer has been marked as not trusted by the user/,
"connect without server root cert sslmode=verify-ca");
test_connect_fails(
$common_connstr,
"sslrootcert=invalid sslmode=verify-full",
- qr/root certificate file "invalid" does not exist/,
+ qr/root certificate file "invalid" does not exist|Peer's certificate issuer has been marked as not trusted by the user/,
"connect without server root cert sslmode=verify-full");
# Try with wrong root cert, should fail. (We're using the client CA as the
# root, but the server's key is signed by the server CA.)
-test_connect_fails($common_connstr,
- "sslrootcert=ssl/client_ca.crt sslmode=require",
- qr/SSL error/, "connect with wrong server root cert sslmode=require");
-test_connect_fails($common_connstr,
- "sslrootcert=ssl/client_ca.crt sslmode=verify-ca",
- qr/SSL error/, "connect with wrong server root cert sslmode=verify-ca");
-test_connect_fails($common_connstr,
- "sslrootcert=ssl/client_ca.crt sslmode=verify-full",
- qr/SSL error/, "connect with wrong server root cert sslmode=verify-full");
-
-# Try with just the server CA's cert. This fails because the root file
-# must contain the whole chain up to the root CA.
-test_connect_fails($common_connstr,
- "sslrootcert=ssl/server_ca.crt sslmode=verify-ca",
- qr/SSL error/, "connect with server CA cert, without root CA");
+test_connect_fails(
+ $common_connstr,
+ "sslrootcert=ssl/client_ca.crt sslmode=require cert_database=ssl/nss/client_ca.crt.db",
+ qr/SSL error/,
+ "connect with wrong server root cert sslmode=require");
+test_connect_fails(
+ $common_connstr,
+ "sslrootcert=ssl/client_ca.crt sslmode=verify-ca cert_database=ssl/nss/client_ca.crt.db",
+ qr/SSL error/,
+ "connect with wrong server root cert sslmode=verify-ca");
+test_connect_fails(
+ $common_connstr,
+ "sslrootcert=ssl/client_ca.crt sslmode=verify-full cert_database=ssl/nss/client_ca.crt.db",
+ qr/SSL error/,
+ "connect with wrong server root cert sslmode=verify-full");
+
+SKIP:
+{
+ # NSS supports partial chain validation, so this test doesn't work there.
+ # This is similar to the OpenSSL option X509_V_FLAG_PARTIAL_CHAIN which
+ # we don't allow.
+ skip "NSS support partial chain validation", 2 if ($nss);
+ # Try with just the server CA's cert. This fails because the root file
+ # must contain the whole chain up to the root CA.
+ test_connect_fails($common_connstr,
+ "sslrootcert=ssl/server_ca.crt sslmode=verify-ca",
+ qr/SSL error/, "connect with server CA cert, without root CA");
+}
# And finally, with the correct root cert.
test_connect_ok(
$common_connstr,
- "sslrootcert=ssl/root+server_ca.crt sslmode=require",
+ "sslrootcert=ssl/root+server_ca.crt sslmode=require cert_database=ssl/nss/root+server_ca.crt.db",
"connect with correct server CA cert file sslmode=require");
test_connect_ok(
$common_connstr,
- "sslrootcert=ssl/root+server_ca.crt sslmode=verify-ca",
+ "sslrootcert=ssl/root+server_ca.crt sslmode=verify-ca cert_database=ssl/nss/root+server_ca.crt.db",
"connect with correct server CA cert file sslmode=verify-ca");
test_connect_ok(
$common_connstr,
- "sslrootcert=ssl/root+server_ca.crt sslmode=verify-full",
+ "sslrootcert=ssl/root+server_ca.crt sslmode=verify-full cert_database=ssl/nss/root+server_ca.crt.db",
"connect with correct server CA cert file sslmode=verify-full");
-# Test with cert root file that contains two certificates. The client should
-# be able to pick the right one, regardless of the order in the file.
-test_connect_ok(
- $common_connstr,
- "sslrootcert=ssl/both-cas-1.crt sslmode=verify-ca",
- "cert root file that contains two certificates, order 1");
-test_connect_ok(
- $common_connstr,
- "sslrootcert=ssl/both-cas-2.crt sslmode=verify-ca",
- "cert root file that contains two certificates, order 2");
+SKIP:
+{
+ skip "CA ordering is irrelevant in NSS databases", 2 if ($nss);
+ # Test with cert root file that contains two certificates. The client should
+ # be able to pick the right one, regardless of the order in the file.
+ test_connect_ok(
+ $common_connstr,
+ "sslrootcert=ssl/both-cas-1.crt sslmode=verify-ca",
+ "cert root file that contains two certificates, order 1");
+
+ # How about import the both-file into a database?
+ test_connect_ok(
+ $common_connstr,
+ "sslrootcert=ssl/both-cas-2.crt sslmode=verify-ca",
+ "cert root file that contains two certificates, order 2");
+}
# CRL tests
# Invalid CRL filename is the same as no CRL, succeeds
test_connect_ok(
$common_connstr,
- "sslrootcert=ssl/root+server_ca.crt sslmode=verify-ca sslcrl=invalid",
+ "sslrootcert=ssl/root+server_ca.crt sslmode=verify-ca sslcrl=invalid cert_database=ssl/nss/root+server_ca.crt.db",
"sslcrl option with invalid file name");
-# A CRL belonging to a different CA is not accepted, fails
-test_connect_fails(
- $common_connstr,
- "sslrootcert=ssl/root+server_ca.crt sslmode=verify-ca sslcrl=ssl/client.crl",
- qr/SSL error/,
- "CRL belonging to a different CA");
+SKIP:
+{
+ skip "CRL's are verified when adding to NSS database", 2 if ($nss);
+ # A CRL belonging to a different CA is not accepted, fails
+ test_connect_fails(
+ $common_connstr,
+ "sslrootcert=ssl/root+server_ca.crt sslmode=verify-ca sslcrl=ssl/client.crl",
+ qr/SSL error/,
+ "CRL belonging to a different CA");
+}
# With the correct CRL, succeeds (this cert is not revoked)
test_connect_ok(
$common_connstr,
- "sslrootcert=ssl/root+server_ca.crt sslmode=verify-ca sslcrl=ssl/root+server.crl",
+ "sslrootcert=ssl/root+server_ca.crt sslmode=verify-ca sslcrl=ssl/root+server.crl cert_database=ssl/nss/root+server_ca.crt__root+server.crl.db",
"CRL with a non-revoked cert");
# Check that connecting with verify-full fails, when the hostname doesn't
# match the hostname in the server's certificate.
$common_connstr =
- "user=ssltestuser dbname=trustdb sslcert=invalid sslrootcert=ssl/root+server_ca.crt hostaddr=$SERVERHOSTADDR";
+ "user=ssltestuser dbname=trustdb sslcert=invalid sslrootcert=ssl/root+server_ca.crt hostaddr=$SERVERHOSTADDR cert_database=ssl/nss/root+server_ca.crt.db";
test_connect_ok(
$common_connstr,
@@ -195,14 +270,14 @@ test_connect_ok(
test_connect_fails(
$common_connstr,
"sslmode=verify-full host=wronghost.test",
- qr/\Qserver certificate for "common-name.pg-ssltest.test" does not match host name "wronghost.test"\E/,
+ qr/\Qserver certificate for "common-name.pg-ssltest.test" does not match host name "wronghost.test"\E|requested domain name does not match the server's certificate/,
"mismatch between host name and server certificate sslmode=verify-full");
# Test Subject Alternative Names.
switch_server_cert($node, 'server-multiple-alt-names');
$common_connstr =
- "user=ssltestuser dbname=trustdb sslcert=invalid sslrootcert=ssl/root+server_ca.crt hostaddr=$SERVERHOSTADDR sslmode=verify-full";
+ "user=ssltestuser dbname=trustdb sslcert=invalid sslrootcert=ssl/root+server_ca.crt hostaddr=$SERVERHOSTADDR sslmode=verify-full cert_database=ssl/nss/root+server_ca.crt.db";
test_connect_ok(
$common_connstr,
@@ -220,12 +295,12 @@ test_connect_ok(
test_connect_fails(
$common_connstr,
"host=wronghost.alt-name.pg-ssltest.test",
- qr/\Qserver certificate for "dns1.alt-name.pg-ssltest.test" (and 2 other names) does not match host name "wronghost.alt-name.pg-ssltest.test"\E/,
+ qr/\Qserver certificate for "dns1.alt-name.pg-ssltest.test" (and 2 other names) does not match host name "wronghost.alt-name.pg-ssltest.test"\E|requested domain name does not match the server's certificate/,
"host name not matching with X.509 Subject Alternative Names");
test_connect_fails(
$common_connstr,
"host=deep.subdomain.wildcard.pg-ssltest.test",
- qr/\Qserver certificate for "dns1.alt-name.pg-ssltest.test" (and 2 other names) does not match host name "deep.subdomain.wildcard.pg-ssltest.test"\E/,
+ qr/\Qserver certificate for "dns1.alt-name.pg-ssltest.test" (and 2 other names) does not match host name "deep.subdomain.wildcard.pg-ssltest.test"\E|requested domain name does not match the server's certificate/,
"host name not matching with X.509 Subject Alternative Names wildcard");
# Test certificate with a single Subject Alternative Name. (this gives a
@@ -233,7 +308,7 @@ test_connect_fails(
switch_server_cert($node, 'server-single-alt-name');
$common_connstr =
- "user=ssltestuser dbname=trustdb sslcert=invalid sslrootcert=ssl/root+server_ca.crt hostaddr=$SERVERHOSTADDR sslmode=verify-full";
+ "user=ssltestuser dbname=trustdb sslcert=invalid sslrootcert=ssl/root+server_ca.crt hostaddr=$SERVERHOSTADDR sslmode=verify-full cert_database=ssl/nss/root+server_ca.crt.db";
test_connect_ok(
$common_connstr,
@@ -243,12 +318,12 @@ test_connect_ok(
test_connect_fails(
$common_connstr,
"host=wronghost.alt-name.pg-ssltest.test",
- qr/\Qserver certificate for "single.alt-name.pg-ssltest.test" does not match host name "wronghost.alt-name.pg-ssltest.test"\E/,
+ qr/\Qserver certificate for "single.alt-name.pg-ssltest.test" does not match host name "wronghost.alt-name.pg-ssltest.test"\E|requested domain name does not match the server's certificate/,
"host name not matching with a single X.509 Subject Alternative Name");
test_connect_fails(
$common_connstr,
"host=deep.subdomain.wildcard.pg-ssltest.test",
- qr/\Qserver certificate for "single.alt-name.pg-ssltest.test" does not match host name "deep.subdomain.wildcard.pg-ssltest.test"\E/,
+ qr/\Qserver certificate for "single.alt-name.pg-ssltest.test" does not match host name "deep.subdomain.wildcard.pg-ssltest.test"\E|requested domain name does not match the server's certificate/,
"host name not matching with a single X.509 Subject Alternative Name wildcard"
);
@@ -257,7 +332,7 @@ test_connect_fails(
switch_server_cert($node, 'server-cn-and-alt-names');
$common_connstr =
- "user=ssltestuser dbname=trustdb sslcert=invalid sslrootcert=ssl/root+server_ca.crt hostaddr=$SERVERHOSTADDR sslmode=verify-full";
+ "user=ssltestuser dbname=trustdb sslcert=invalid sslrootcert=ssl/root+server_ca.crt hostaddr=$SERVERHOSTADDR sslmode=verify-full cert_database=ssl/nss/root+server_ca.crt.db";
test_connect_ok(
$common_connstr,
@@ -270,14 +345,14 @@ test_connect_ok(
test_connect_fails(
$common_connstr,
"host=common-name.pg-ssltest.test",
- qr/\Qserver certificate for "dns1.alt-name.pg-ssltest.test" (and 1 other name) does not match host name "common-name.pg-ssltest.test"\E/,
+ qr/\Qserver certificate for "dns1.alt-name.pg-ssltest.test" (and 1 other name) does not match host name "common-name.pg-ssltest.test"\E|requested domain name does not match the server's certificate/,
"certificate with both a CN and SANs ignores CN");
# Finally, test a server certificate that has no CN or SANs. Of course, that's
# not a very sensible certificate, but libpq should handle it gracefully.
switch_server_cert($node, 'server-no-names');
$common_connstr =
- "user=ssltestuser dbname=trustdb sslcert=invalid sslrootcert=ssl/root+server_ca.crt hostaddr=$SERVERHOSTADDR";
+ "user=ssltestuser dbname=trustdb sslcert=invalid sslrootcert=ssl/root+server_ca.crt hostaddr=$SERVERHOSTADDR cert_database=ssl/nss/root+server_ca.crt.db";
test_connect_ok(
$common_connstr,
@@ -286,7 +361,7 @@ test_connect_ok(
test_connect_fails(
$common_connstr,
"sslmode=verify-full host=common-name.pg-ssltest.test",
- qr/could not get server's host name from server certificate/,
+ qr/could not get server's host name from server certificate|requested domain name does not match the server's certificate./,
"server certificate without CN or SANs sslmode=verify-full");
# Test that the CRL works
@@ -298,11 +373,11 @@ $common_connstr =
# Without the CRL, succeeds. With it, fails.
test_connect_ok(
$common_connstr,
- "sslrootcert=ssl/root+server_ca.crt sslmode=verify-ca",
+ "sslrootcert=ssl/root+server_ca.crt sslmode=verify-ca cert_database=ssl/nss/root+server_ca.crt.db",
"connects without client-side CRL");
test_connect_fails(
$common_connstr,
- "sslrootcert=ssl/root+server_ca.crt sslmode=verify-ca sslcrl=ssl/root+server.crl",
+ "sslrootcert=ssl/root+server_ca.crt sslmode=verify-ca sslcrl=ssl/server.crl cert_database=ssl/nss/root+server_ca.crt__server.crl.db",
qr/SSL error/,
"does not connect with client-side CRL");
@@ -323,32 +398,50 @@ command_like(
# Test min/max SSL protocol versions.
test_connect_ok(
$common_connstr,
- "sslrootcert=ssl/root+server_ca.crt sslmode=require ssl_min_protocol_version=TLSv1.2 ssl_max_protocol_version=TLSv1.2",
+ "sslrootcert=ssl/root+server_ca.crt sslmode=require ssl_min_protocol_version=TLSv1.2 ssl_max_protocol_version=TLSv1.2 cert_database=ssl/nss/root+server_ca.crt.db",
"connection success with correct range of TLS protocol versions");
test_connect_fails(
$common_connstr,
- "sslrootcert=ssl/root+server_ca.crt sslmode=require ssl_min_protocol_version=TLSv1.2 ssl_max_protocol_version=TLSv1.1",
+ "sslrootcert=ssl/root+server_ca.crt sslmode=require ssl_min_protocol_version=TLSv1.2 ssl_max_protocol_version=TLSv1.1 cert_database=ssl/nss/root+server_ca.crt.db",
qr/invalid SSL protocol version range/,
"connection failure with incorrect range of TLS protocol versions");
test_connect_fails(
$common_connstr,
- "sslrootcert=ssl/root+server_ca.crt sslmode=require ssl_min_protocol_version=incorrect_tls",
+ "sslrootcert=ssl/root+server_ca.crt sslmode=require ssl_min_protocol_version=incorrect_tls cert_database=ssl/nss/root+server_ca.crt.db",
qr/invalid ssl_min_protocol_version value/,
"connection failure with an incorrect SSL protocol minimum bound");
test_connect_fails(
$common_connstr,
- "sslrootcert=ssl/root+server_ca.crt sslmode=require ssl_max_protocol_version=incorrect_tls",
+ "sslrootcert=ssl/root+server_ca.crt sslmode=require ssl_max_protocol_version=incorrect_tls cert_database=ssl/nss/root+server_ca.crt.db",
qr/invalid ssl_max_protocol_version value/,
"connection failure with an incorrect SSL protocol maximum bound");
+# tests of NSS generated certificates/keys
+SKIP:
+{
+ skip "NSS specific tests", 1 if ($openssl);
+
+ switch_server_cert($node, 'native_server-root', 'native_ca-root');
+ $common_connstr =
+ "user=ssltestuser dbname=trustdb hostaddr=$SERVERHOSTADDR host=common-name.pg-ssltest.test";
+
+ test_connect_ok(
+ $common_connstr,
+ "sslmode=require user=ssltestuser",
+ "NSS generated certificates"
+ );
+}
+
### Server-side tests.
###
### Test certificate authorization.
+switch_server_cert($node, 'server-revoked');
+
note "running server tests";
$common_connstr =
- "sslrootcert=ssl/root+server_ca.crt sslmode=require dbname=certdb hostaddr=$SERVERHOSTADDR";
+ "sslrootcert=ssl/root+server_ca.crt sslmode=require dbname=certdb hostaddr=$SERVERHOSTADDR cert_database=ssl/nss/client.crt__client.key.db";
# no client cert
test_connect_fails(
@@ -364,32 +457,43 @@ test_connect_ok(
"certificate authorization succeeds with correct client cert in PEM format"
);
-# correct client cert in unencrypted DER
-test_connect_ok(
- $common_connstr,
- "user=ssltestuser sslcert=ssl/client.crt sslkey=ssl/client-der_tmp.key",
- "certificate authorization succeeds with correct client cert in DER format"
-);
+$common_connstr =
+ "sslrootcert=ssl/root+server_ca.crt sslmode=require dbname=certdb hostaddr=$SERVERHOSTADDR";
+
+SKIP:
+{
+ skip "NSS database not implemented in the Makefile", 1 if ($nss);
+ # correct client cert in unencrypted DER
+ test_connect_ok(
+ $common_connstr,
+ "user=ssltestuser sslcert=ssl/client.crt sslkey=ssl/client-der_tmp.key",
+ "certificate authorization succeeds with correct client cert in DER format"
+ );
+}
# correct client cert in encrypted PEM
test_connect_ok(
$common_connstr,
- "user=ssltestuser sslcert=ssl/client.crt sslkey=ssl/client-encrypted-pem_tmp.key sslpassword='dUmmyP^#+'",
+ "user=ssltestuser sslcert=ssl/client.crt sslkey=ssl/client-encrypted-pem_tmp.key sslpassword='dUmmyP^#+' cert_database=ssl/nss/client.crt__client-encrypted-pem.key.db",
"certificate authorization succeeds with correct client cert in encrypted PEM format"
);
-# correct client cert in encrypted DER
-test_connect_ok(
- $common_connstr,
- "user=ssltestuser sslcert=ssl/client.crt sslkey=ssl/client-encrypted-der_tmp.key sslpassword='dUmmyP^#+'",
- "certificate authorization succeeds with correct client cert in encrypted DER format"
-);
+SKIP:
+{
+ skip "NSS database not implemented in the Makefile", 1 if ($nss);
+ # correct client cert in encrypted DER
+ test_connect_ok(
+ $common_connstr,
+ "user=ssltestuser sslcert=ssl/client.crt sslkey=ssl/client-encrypted-der_tmp.key sslpassword='dUmmyP^#+'",
+ "certificate authorization succeeds with correct client cert in encrypted DER format"
+ );
+}
# correct client cert in encrypted PEM with wrong password
test_connect_fails(
$common_connstr,
- "user=ssltestuser sslcert=ssl/client.crt sslkey=ssl/client-encrypted-pem_tmp.key sslpassword='wrong'",
- qr!\Qprivate key file "ssl/client-encrypted-pem_tmp.key": bad decrypt\E!,
+ "user=ssltestuser sslcert=ssl/client.crt sslkey=ssl/client-encrypted-pem_tmp.key sslpassword='wrong' cert_database=ssl/nss/client.crt__client-encrypted-pem.key.db",
+ qr!connection requires a valid client certificate|\Qprivate key file "ssl/client-encrypted-pem_tmp.key": bad decrypt\E!,
"certificate authorization fails with correct client cert and wrong password in encrypted PEM format"
);
@@ -429,18 +533,19 @@ command_like(
'-P',
'null=_null_',
'-d',
- "$common_connstr user=ssltestuser sslcert=ssl/client.crt sslkey=ssl/client_tmp.key",
+ "$common_connstr user=ssltestuser sslcert=ssl/client.crt sslkey=ssl/client_tmp.key cert_database=ssl/nss/client.crt__client.key.db",
'-c',
"SELECT * FROM pg_stat_ssl WHERE pid = pg_backend_pid()"
],
qr{^pid,ssl,version,cipher,bits,compression,client_dn,client_serial,issuer_dn\r?\n
- ^\d+,t,TLSv[\d.]+,[\w-]+,\d+,f,/CN=ssltestuser,1,\Q/CN=Test CA for PostgreSQL SSL regression test client certs\E\r?$}mx,
+ ^\d+,t,TLSv[\d.]+,[\w-]+,\d+,f,/?CN=ssltestuser,1,/?\QCN=Test CA for PostgreSQL SSL regression test client certs\E\r?$}mx,
'pg_stat_ssl with client certificate');
# client key with wrong permissions
SKIP:
{
skip "Permissions check not enforced on Windows", 2 if ($windows_os);
+ skip "Key not on filesystem with NSS", 2 if ($nss);
test_connect_fails(
$common_connstr,
@@ -453,10 +558,13 @@ SKIP:
test_connect_fails(
$common_connstr,
"user=anotheruser sslcert=ssl/client.crt sslkey=ssl/client_tmp.key",
- qr/certificate authentication failed for user "anotheruser"/,
+ qr/unable to verify certificate|certificate authentication failed for user "anotheruser"/,
"certificate authorization fails with client cert belonging to another user"
);
+$common_connstr =
+ "sslrootcert=ssl/root+server_ca.crt sslmode=require dbname=certdb hostaddr=$SERVERHOSTADDR cert_database=ssl/nss/client-revoked.crt__client-revoked.key.db";
+
# revoked client cert
test_connect_fails(
$common_connstr,
@@ -468,7 +576,7 @@ test_connect_fails(
# works, iff username matches Common Name
# fails, iff username doesn't match Common Name.
$common_connstr =
- "sslrootcert=ssl/root+server_ca.crt sslmode=require dbname=verifydb hostaddr=$SERVERHOSTADDR";
+ "sslrootcert=ssl/root+server_ca.crt sslmode=require dbname=verifydb hostaddr=$SERVERHOSTADDR cert_database=ssl/nss/client.crt__client.key.db";
test_connect_ok(
$common_connstr,
@@ -494,14 +602,18 @@ test_connect_ok(
# intermediate client_ca.crt is provided by client, and isn't in server's ssl_ca_file
switch_server_cert($node, 'server-cn-only', 'root_ca');
$common_connstr =
- "user=ssltestuser dbname=certdb sslkey=ssl/client_tmp.key sslrootcert=ssl/root+server_ca.crt hostaddr=$SERVERHOSTADDR";
+ "user=ssltestuser dbname=certdb sslkey=ssl/client_tmp.key sslrootcert=ssl/root+server_ca.crt hostaddr=$SERVERHOSTADDR cert_database=ssl/nss/client+client_ca.crt__client.key.db";
test_connect_ok(
$common_connstr,
"sslmode=require sslcert=ssl/client+client_ca.crt",
"intermediate client certificate is provided by client");
-test_connect_fails($common_connstr, "sslmode=require sslcert=ssl/client.crt",
- qr/SSL error/, "intermediate client certificate is missing");
+
+test_connect_fails(
+ $common_connstr,
+ "sslmode=require sslcert=ssl/client.crt",
+ qr/connection requires a valid client certificate|SSL error/,
+ "intermediate client certificate is missing");
# clean up
diff --git a/src/test/ssl/t/002_scram.pl b/src/test/ssl/t/002_scram.pl
index 3383b3e531..55fe3922e1 100644
--- a/src/test/ssl/t/002_scram.pl
+++ b/src/test/ssl/t/002_scram.pl
@@ -13,7 +13,26 @@ use lib $FindBin::RealBin;
use SSL::Server;
-if ($ENV{with_ssl} ne 'openssl')
+my $openssl;
+my $nss;
+
+my $supports_tls_server_end_point;
+
+if ($ENV{with_ssl} eq 'openssl')
+{
+ $openssl = 1;
+ # Determine whether build supports tls-server-end-point.
+ $supports_tls_server_end_point =
+ check_pg_config("#define HAVE_X509_GET_SIGNATURE_NID 1");
+ plan tests => $supports_tls_server_end_point ? 9 : 10;
+}
+elsif ($ENV{with_ssl} eq 'nss')
+{
+ $nss = 1;
+ $supports_tls_server_end_point = 1;
+ plan tests => 9;
+}
+else
{
plan skip_all => 'SSL not supported by this build';
}
@@ -23,12 +42,6 @@ my $SERVERHOSTADDR = '127.0.0.1';
# This is the pattern to use in pg_hba.conf to match incoming connections.
my $SERVERHOSTCIDR = '127.0.0.1/32';
-# Determine whether build supports tls-server-end-point.
-my $supports_tls_server_end_point =
- check_pg_config("#define HAVE_X509_GET_SIGNATURE_NID 1");
-
-my $number_of_tests = $supports_tls_server_end_point ? 9 : 10;
-
# Allocation of base connection string shared among multiple tests.
my $common_connstr;
@@ -97,7 +110,7 @@ my $client_tmp_key = "ssl/client_scram_tmp.key";
copy("ssl/client.key", $client_tmp_key);
chmod 0600, $client_tmp_key;
test_connect_fails(
- "sslcert=ssl/client.crt sslkey=$client_tmp_key sslrootcert=invalid hostaddr=$SERVERHOSTADDR",
+ "sslcert=ssl/client.crt sslkey=$client_tmp_key sslrootcert=invalid hostaddr=$SERVERHOSTADDR cert_database=ssl/nss/client.crt__client.key.db",
"dbname=certdb user=ssltestuser channel_binding=require",
qr/channel binding required, but server authenticated client without channel binding/,
"Cert authentication and channel_binding=require");
diff --git a/src/test/ssl/t/SSL/Backend/NSS.pm b/src/test/ssl/t/SSL/Backend/NSS.pm
new file mode 100644
index 0000000000..c5b31e584a
--- /dev/null
+++ b/src/test/ssl/t/SSL/Backend/NSS.pm
@@ -0,0 +1,73 @@
+package SSL::Backend::NSS;
+
+use strict;
+use warnings;
+use Exporter;
+
+our @ISA = qw(Exporter);
+our @EXPORT_OK = qw(get_new_nss_backend);
+
+sub new
+{
+ my ($class) = @_;
+
+ my $self = { _library => 'NSS' };
+
+ bless $self, $class;
+
+ return $self;
+}
+
+sub get_new_nss_backend
+{
+ my $class = 'SSL::Backend::NSS';
+
+ return $class->new();
+}
+
+sub init
+{
+ # Make sure the certificate databases are in place?
+}
+
+sub get_library
+{
+ my ($self) = @_;
+
+ return $self->{_library};
+}
+
+sub set_server_cert
+{
+ my $self = $_[0];
+ my $certfile = $_[1];
+ my $cafile = $_[2];
+ my $keyfile = $_[3];
+
+ my $cert_nickname;
+
+ if ($certfile =~ /native/)
+ {
+ $cert_nickname = $certfile;
+ }
+ else
+ {
+ $cert_nickname = $certfile . '.crt__' . $keyfile . '.key';
+ }
+ my $cert_database = $cert_nickname . '.db';
+
+ my $sslconf =
+ "ssl_ca_file='$cafile.crt'\n"
+ . "ssl_cert_file='ssl/$certfile.crt'\n"
+ . "ssl_crl_file=''\n"
+ . "ssl_database='nss/$cert_database'\n";
+
+ return $sslconf;
+}
+
+sub cleanup
+{
+ # Something?
+}
+
+1;
--
2.21.1 (Apple Git-122.3)