While working on the SSL refactoring patch, it struck me that we don't have any regression tests for SSL support. A suite to test all the different sslmodes etc. is essential before we can start implementing alternatives to OpenSSL.

Now that we use TAP for testing client tools, I think we can use that to test various SSL options too. I came up with the attached. Comments?

It currently assumes that the client's and the server's hostnames are "postgres-client.test" and "postgres-server.test", respectively. That makes it a bit tricky to run on a single systme. The README includes instructions; basically you need to set up an additional loopback device, and add entries to /etc/hosts for that.

It would make sense to separate the client and server portions of the test so that you could run the server on one host and the client on another. That's a TODO; I'm not sure how to do that.

- Heikki
commit 3657a5684fcf5ac840d819641b484a3d535a7331
Author: Heikki Linnakangas <heikki.linnakan...@iki.fi>
Date:   Mon Aug 4 17:07:31 2014 +0300

    Add SSL regression test suite.

diff --git a/src/test/Makefile b/src/test/Makefile
index 0fd7eab..e6a7154 100644
--- a/src/test/Makefile
+++ b/src/test/Makefile
@@ -12,6 +12,6 @@ subdir = src/test
 top_builddir = ../..
 include $(top_builddir)/src/Makefile.global
 
-SUBDIRS = regress isolation
+SUBDIRS = regress isolation ssl
 
 $(recurse)
diff --git a/src/test/ssl/Makefile b/src/test/ssl/Makefile
new file mode 100644
index 0000000..33a026a
--- /dev/null
+++ b/src/test/ssl/Makefile
@@ -0,0 +1,48 @@
+#-------------------------------------------------------------------------
+#
+# Makefile for src/test/ssl
+#
+# Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
+# Portions Copyright (c) 1994, Regents of the University of California
+#
+# src/test/ssl/Makefile
+#
+#-------------------------------------------------------------------------
+
+subdir = src/test/ssl
+top_builddir = ../../..
+include $(top_builddir)/src/Makefile.global
+
+CERTIFICATES := server-root client-root server client
+
+SSLFILES := $(CERTIFICATES:%=ssl/%.key) $(CERTIFICATES:%=ssl/%.crt)
+
+.PHONY: sslfiles
+sslfiles: $(SSLFILES)
+
+# Rule for creating private/public key pairs
+ssl/%.key:
+	openssl genrsa -out $@ 1024
+	chmod 0600 $@
+
+# Rule for creating CA certificates (client and server)
+ssl/%-root.crt: ssl/%-root.key ssl/%.config
+	openssl req -new -key ssl/$*-root.key -days 36500 -out ssl/$*-root.crt -x509 -config ssl/$*-root.config
+	echo "00" > ssl/$*-root.srl
+
+# Server & client certificates, signed by CA:
+ssl/%.crt: ssl/%.key ssl/%-root.crt
+	openssl req -new -key ssl/$*.key -out ssl/$*.csr -config ssl/$*.config
+# Sign the certificate with the right CA
+	openssl x509 -req -in ssl/$*.csr -CA ssl/$*-root.crt -CAkey ssl/$*-root.key -CAserial ssl/$*-root.srl -out ssl/$*.crt
+	rm ssl/$*.csr
+
+sslfiles-clean:
+	rm -f $(SSLFILES) ssl/client-root.srl ssl/server-root.srl
+
+check:
+	$(prove_check)
+
+installcheck:
+	rm -rf tmp_check
+	$(prove_installcheck)
diff --git a/src/test/ssl/README b/src/test/ssl/README
new file mode 100644
index 0000000..a2b3e37
--- /dev/null
+++ b/src/test/ssl/README
@@ -0,0 +1,53 @@
+src/test/ssl/README
+
+SSL regression tests
+====================
+
+This directory contains a test suite for SSL support.
+
+Setup
+=====
+
+The tests require some additional setup:
+
+1. The suite assumes that the server's fully-qualified hostname is
+   postgres-server.test. The server's listen_addresses is set to
+   postgres-server.test, and the client uses that hostname to connect.
+
+2. The client needs another hostname, alias-for-postgres-server.test, to be
+   set up, pointing to the same IP address as postgres-server.test.
+
+3. The server expects the client's IP address to resolve to postgres-client.test
+
+The easiest way to set up all three hostnames is to use the loopback network
+device. Configure it with the following command (tested on Linux):
+
+    ifconfig lo:10 127.0.10.1 netmask 255.255.255.0 up
+
+And then append the following to /etc/hosts:
+
+    127.0.10.1 postgres-client.test
+    127.0.10.2 postgres-server.test
+    127.0.10.2 alias-for-postgres-server.test
+
+
+Running the tests
+=================
+
+    make installcheck
+
+
+
+Certificates
+============
+
+The test suite needs four public/private key pairs and certificates to run:
+
+server-root: CA used to sign the server certificate
+client-root: CA used to sign client certificates
+server: the server's certificate, for hostname "postgres-server.test"
+client: the client's certificate, for user "ssltestuser"
+
+These keypairs and certificates are included in the ssl/ subdirectory, but
+the Makefile also contains a rule, "make certificates", to recreate them if
+you want to make changes.
diff --git a/src/test/ssl/ssl/client-root.config b/src/test/ssl/ssl/client-root.config
new file mode 100644
index 0000000..c7fd5f8
--- /dev/null
+++ b/src/test/ssl/ssl/client-root.config
@@ -0,0 +1,6 @@
+[ req ]
+distinguished_name     = req_distinguished_name
+prompt                 = no
+
+[ req_distinguished_name ]
+CN                     = Test CA for PostgreSQL SSL regression test client certs
diff --git a/src/test/ssl/ssl/client-root.crt b/src/test/ssl/ssl/client-root.crt
new file mode 100644
index 0000000..2295403
--- /dev/null
+++ b/src/test/ssl/ssl/client-root.crt
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIIB/TCCAWYCCQDm71vKU5vw/zANBgkqhkiG9w0BAQsFADBCMUAwPgYDVQQDDDdU
+ZXN0IENBIGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3QgY2xpZW50
+IGNlcnRzMCAXDTE0MDgwNDE0MDYzMFoYDzIxMTQwNzExMTQwNjMwWjBCMUAwPgYD
+VQQDDDdUZXN0IENBIGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qg
+Y2xpZW50IGNlcnRzMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzsE98l5D6
+PWBKO4a5xXsFzS52Vqbn+a/wj7i4HDsKFFkYp/z6VCPltbA07PPLfN9FpX1C9tRI
+j6Puw+CFSwBqRQiyhbKxmDuIEPK8zeh3709Gekqd80598mHoYN6OuTNTcifsFgv8
+GgFHqgB/q+aHxJtozaVoAibjuNvTgOYlgwIDAQABMA0GCSqGSIb3DQEBCwUAA4GB
+AK1u67db7/dtkRbvV4Zexbstb6lQaFwGQw9tcQXbQyZOAR0tkZ40Jka1Y7nXdAKm
+jIegxGMaO7jz1n3JyIZ6QLFuyT+HcVaYR9nqmgPdqmRjek+VDJLiWC28nIWvrNgj
+1sb2AHMmsgm7U1oTXfRHguWs7PRIQHhVEhq5MlcXeIcw
+-----END CERTIFICATE-----
diff --git a/src/test/ssl/ssl/client-root.key b/src/test/ssl/ssl/client-root.key
new file mode 100644
index 0000000..5ad3e83
--- /dev/null
+++ b/src/test/ssl/ssl/client-root.key
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXgIBAAKBgQCzsE98l5D6PWBKO4a5xXsFzS52Vqbn+a/wj7i4HDsKFFkYp/z6
+VCPltbA07PPLfN9FpX1C9tRIj6Puw+CFSwBqRQiyhbKxmDuIEPK8zeh3709Gekqd
+80598mHoYN6OuTNTcifsFgv8GgFHqgB/q+aHxJtozaVoAibjuNvTgOYlgwIDAQAB
+AoGBALGBmXQmMiTSHt4WIchAyn/3qk9i2GzO3rxQ7hSKZtRVN5LA2IreNbwFmPUf
+otLBH7soeS5+sUShCTukKpbieZvZdjEAMrwScshRwx4n74PQBm+mGSKZv2F7+Noi
+QSafpVrvr6xKBSvM4RCy1rVTfA8qpsrlKUEnmK4OGlFAYLYZAkEA3Rq0+o3GPlJi
+4JSeRXvr1wOGbLDYDmEY5bZRY/pnsFxA1jcvfPIzS/TD53eV0ELR/zG8PUmGHmIa
+yyXFK2a+FQJBANAMSSmWOPCtfiwonHJkdTm8WQwvmHb27WvQuTMG/FRs0hB090GR
+fr3/zrhrFxPf9jrgfwP0tzFSy0g8z3SI0zcCQQDJ3uR2DpN9u0LDwW1wC2Ccg39s
+JVpeZpCQyxEssyeQgepAq0oUTh4/r05eO3TxHNEWqpYvbr2hZ/kGmYmXwsqxAkEA
+l6pdK5P3rnzLniV852eUjaJgyCFqZE9ehVqDqE9PY7xw5s5d8c6/NoNlj8uB51s9
+hW5jKd8cLTjOOLscATg9wQJADZM8TboSwoM5A63VGt89ERAAFEkLcGW7JT8CrPFS
+R33an5L6L8rTqBQ2GYOAAyOXNiE/SA2cCEQ/6O1KgDH31g==
+-----END RSA PRIVATE KEY-----
diff --git a/src/test/ssl/ssl/client-root.srl b/src/test/ssl/ssl/client-root.srl
new file mode 100644
index 0000000..8a0f05e
--- /dev/null
+++ b/src/test/ssl/ssl/client-root.srl
@@ -0,0 +1 @@
+01
diff --git a/src/test/ssl/ssl/client.config b/src/test/ssl/ssl/client.config
new file mode 100644
index 0000000..56c8f4f
--- /dev/null
+++ b/src/test/ssl/ssl/client.config
@@ -0,0 +1,6 @@
+[ req ]
+distinguished_name     = req_distinguished_name
+prompt                 = no
+
+[ req_distinguished_name ]
+CN                     = ssltestuser
diff --git a/src/test/ssl/ssl/client.crt b/src/test/ssl/ssl/client.crt
new file mode 100644
index 0000000..4dd2e89
--- /dev/null
+++ b/src/test/ssl/ssl/client.crt
@@ -0,0 +1,12 @@
+-----BEGIN CERTIFICATE-----
+MIIBxzCCATACAQEwDQYJKoZIhvcNAQELBQAwQjFAMD4GA1UEAww3VGVzdCBDQSBm
+b3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0ZXN0IGNsaWVudCBjZXJ0czAe
+Fw0xNDA4MDQxNDA2MzBaFw0xNDA5MDMxNDA2MzBaMBYxFDASBgNVBAMMC3NzbHRl
+c3R1c2VyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCkm/TdFLy3Pb3UqZwb
+NSP2VwyAzlcmAT2faElMfrjg/Bv8Fv44IsFmCR0+qlJthkBnEK+eIp9YlBuGBIlX
+DZzPb4cC9O8sZf2oy/9oHeZP0k81iKjkLgdK9Cr7MaG9HvmOfwVTFWT5HnWw6dNI
+TfUFbeMhl3/5Hr9k5MLjCYPVawIDAQABMA0GCSqGSIb3DQEBCwUAA4GBAFB2LsqT
+Lsgc0VNidlbnc30/xwGVZUXD68YW+0MgYRvLsko8+ujx094JxCIDWW+yZnXt3hV5
+bHx/ol9FpTXE2wmdxmTnwy7GuD+EtqUXp/+N7mc9eMTstuRRCoog1V3vjnPXVjTe
+8mMMV/g9AeW0uHHkt2dSFKkIdf/LrTAZLTWp
+-----END CERTIFICATE-----
diff --git a/src/test/ssl/ssl/client.key b/src/test/ssl/ssl/client.key
new file mode 100644
index 0000000..1398db4
--- /dev/null
+++ b/src/test/ssl/ssl/client.key
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQCkm/TdFLy3Pb3UqZwbNSP2VwyAzlcmAT2faElMfrjg/Bv8Fv44
+IsFmCR0+qlJthkBnEK+eIp9YlBuGBIlXDZzPb4cC9O8sZf2oy/9oHeZP0k81iKjk
+LgdK9Cr7MaG9HvmOfwVTFWT5HnWw6dNITfUFbeMhl3/5Hr9k5MLjCYPVawIDAQAB
+AoGAQMTozVDKjKNrnVD7jq0TMGvCDLCkE90rHR0QsluubUBl1oRJlVb/mCF/81db
+RaMsliE3qNZgsp7cUZhZXfqKN2dSWrPc8xRqcW2D6vE21qP/aFg7TCwFFX5g/UOW
+B9gN6bJIjZcAJCObwlZ0i6MB5UYTQHJsdRQJ14HqHx9DkrECQQDPCof5mC6HAhLm
+iew0alYb6nBqUBabmiL4A73pnHixa3ElA/eGgjjrZFSHUuhap8WbHf7jRA5dMh8R
+qxYl73BJAkEAy4jCrQkIH1t3epsiahtfXxxYecrgLs+9rUjY8s9gbDADt4UMBgm+
+moh2H+YuI4OmLQudkd21zEY57Ifmr8qAEwJAd0/DUkOvtF+ukqoys3YAD3BHvgxP
+KvZlZnWJkMF6EAwxlLo3f401zfjweVd+zRdX2e8sPr2uZWiH3P+x8MSN+QJBAKuS
+9/kB2hUE9+0lBZfIx1bYAEV7HgyYFt8Sv7+/zRqmRxvXTlFwuXpvepRdZ5uMiPME
+Dao+6dfvgzi/P1oFLH0CQQCANUPm4B5B+O91A+EKVI5NwF6+FXLFPTkA7XjkLsNz
+uJqF/C4eGvCfBxXbcUOyu7gTMakM6yIvJGmL5N5550VT
+-----END RSA PRIVATE KEY-----
diff --git a/src/test/ssl/ssl/server-root.config b/src/test/ssl/ssl/server-root.config
new file mode 100644
index 0000000..16ef29d
--- /dev/null
+++ b/src/test/ssl/ssl/server-root.config
@@ -0,0 +1,6 @@
+[ req ]
+distinguished_name     = req_distinguished_name
+prompt                 = no
+
+[ req_distinguished_name ]
+CN                     = Test CA for PostgreSQL SSL regression test server certs
diff --git a/src/test/ssl/ssl/server-root.crt b/src/test/ssl/ssl/server-root.crt
new file mode 100644
index 0000000..3b6e552
--- /dev/null
+++ b/src/test/ssl/ssl/server-root.crt
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIIB/TCCAWYCCQCCMEPUwcYHhDANBgkqhkiG9w0BAQsFADBCMUAwPgYDVQQDDDdU
+ZXN0IENBIGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qgc2VydmVy
+IGNlcnRzMCAXDTE0MDgwNDE0MDYzMFoYDzIxMTQwNzExMTQwNjMwWjBCMUAwPgYD
+VQQDDDdUZXN0IENBIGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qg
+c2VydmVyIGNlcnRzMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDjtQ1ZkmCw
+i0wVfCrWhR60kKoSHbZRIL1EbPwbuhOcOo7GKKdyEAqpNXCiQY2zqK6resimPukv
+IIxY2mYmhSlYd9qyFZoxFxx8NwWZL2re7IJVk3NXd+FpQ0KDNCt4sBoNcxv8uJ+k
+YAJcniYZsQLclw4IT12tMcpCiO5r2iuuJQIDAQABMA0GCSqGSIb3DQEBCwUAA4GB
+AGhruBhhd1RV7monhEyTqR+zH7yD4l/+7ynPI/QkA2PdCQ2wkpJPVqaIG4kN1XkU
+53Wwuh7EzchEl7mMWRgqbRgucc0YL++B6l2Y5jRdWnAi5Ju59fOzg58AuoQQYLhH
+f3a47gyprNUPAkfix+vU+2rMaPR0fXXX7NuEPXGrHlz8
+-----END CERTIFICATE-----
diff --git a/src/test/ssl/ssl/server-root.key b/src/test/ssl/ssl/server-root.key
new file mode 100644
index 0000000..a3e23bb
--- /dev/null
+++ b/src/test/ssl/ssl/server-root.key
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQDjtQ1ZkmCwi0wVfCrWhR60kKoSHbZRIL1EbPwbuhOcOo7GKKdy
+EAqpNXCiQY2zqK6resimPukvIIxY2mYmhSlYd9qyFZoxFxx8NwWZL2re7IJVk3NX
+d+FpQ0KDNCt4sBoNcxv8uJ+kYAJcniYZsQLclw4IT12tMcpCiO5r2iuuJQIDAQAB
+AoGBAJsx295vqJzK49lE3oGFC09vxapBO/CBSt4nFZDkOtdhBcxDCxTvoASBmrnL
+ygNn9VyEe9rqx81J9r3cZIDegzUylOKJDe82dl662AextBRKxOVVEyfIwvKq+rRP
+lvxMgQih6peodItBWwdR3FYawH0f0ydTFXWl6swxi+UboufhAkEA9l1fzBIeArZU
+1Yebn/wFZ43CEnpoquiv/ntk2v08By7yHQOFjV66vXhqjRdVCaVS1DPQqYb+jqpm
+LsHSPe9ZDQJBAOyc4JcM6EgjTA9XUASd0VX/bMn9+iekbN7vqnQ8g6aRD8Duc6fI
+OAXB61gt6wHTKBYmSEdXl5Vw+C/sLS1BM3kCQGmMy7Q0tuLWlzX8qXI7mV0qYNFl
+3F4M3woad7VS9VrmhBhmH9vXkA4I/y1/p5FAYWJE6MsY6Qraenjh1V9voikCQFLj
+9m4UUH+NFgU90kN7wi09aTAuMGeY26cSEQXdeUVuBjXRk2TQ6Idj0v22QGEIRz/T
+M3kCv5DT3a50L7Nt5wkCQEMG+YJawAPKW8gMebXqMd5/VPaIe2eybB9YTraIXUVU
+s9DAGeaVv+iGXIqoBsa0Mez0TJ9mzFWa3h421AEsRBQ=
+-----END RSA PRIVATE KEY-----
diff --git a/src/test/ssl/ssl/server-root.srl b/src/test/ssl/ssl/server-root.srl
new file mode 100644
index 0000000..8a0f05e
--- /dev/null
+++ b/src/test/ssl/ssl/server-root.srl
@@ -0,0 +1 @@
+01
diff --git a/src/test/ssl/ssl/server.config b/src/test/ssl/ssl/server.config
new file mode 100644
index 0000000..c3d7201
--- /dev/null
+++ b/src/test/ssl/ssl/server.config
@@ -0,0 +1,6 @@
+[ req ]
+distinguished_name     = req_distinguished_name
+prompt                 = no
+
+[ req_distinguished_name ]
+CN                     = postgres-server.test
diff --git a/src/test/ssl/ssl/server.crt b/src/test/ssl/ssl/server.crt
new file mode 100644
index 0000000..8b525f7
--- /dev/null
+++ b/src/test/ssl/ssl/server.crt
@@ -0,0 +1,12 @@
+-----BEGIN CERTIFICATE-----
+MIIB0DCCATkCAQEwDQYJKoZIhvcNAQELBQAwQjFAMD4GA1UEAww3VGVzdCBDQSBm
+b3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0ZXN0IHNlcnZlciBjZXJ0czAe
+Fw0xNDA4MDQxNDA2MzBaFw0xNDA5MDMxNDA2MzBaMB8xHTAbBgNVBAMMFHBvc3Rn
+cmVzLXNlcnZlci50ZXN0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDL0E5X
+54Dw1VTXHYvYUIuE2j7wwGutyX3gT8SpdxPtTWD/cfJsqj5p02WWdL+AdnSqXBnV
+ZkIJ4J7nBsqO9QnTlSpmQGoeXMlX0Ic4xmMgM+ayiQThHJ7/n7qchTdE5noZVRrd
+6XckF6W6JWsojZaY3EBQsKhB2TCaoNdzHQ0zgQIDAQABMA0GCSqGSIb3DQEBCwUA
+A4GBAKoR4p+vtf1mnOdEpwjpCuoYvRs6QcC1gVAkyDaO7T9V+U1Tkmdq05KMf+iF
+miA+A8LeFvEnc2lNeE8nqySmJx6RG2UclhizgsRhLTZl79Pu4LdBbXAx5Tc1MrHB
+n4H8hc8ekpBCuOg7rz6n22aLx3UJSDzTDGZoNbXlUPARRqIm
+-----END CERTIFICATE-----
diff --git a/src/test/ssl/ssl/server.key b/src/test/ssl/ssl/server.key
new file mode 100644
index 0000000..91db421
--- /dev/null
+++ b/src/test/ssl/ssl/server.key
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQDL0E5X54Dw1VTXHYvYUIuE2j7wwGutyX3gT8SpdxPtTWD/cfJs
+qj5p02WWdL+AdnSqXBnVZkIJ4J7nBsqO9QnTlSpmQGoeXMlX0Ic4xmMgM+ayiQTh
+HJ7/n7qchTdE5noZVRrd6XckF6W6JWsojZaY3EBQsKhB2TCaoNdzHQ0zgQIDAQAB
+AoGAZAVMDTOdQZNP2Wm0kWmlroL0VG356gVx8rzyxD+d1d0ddv7Se6Voj8Kgnh+Z
+Q0/enSQpwWI3kmVbVgEtMs7qDL0VEYnvUdcVlM44VTxEKeOlIeWNJzA+iwFefJ13
+xICD/ikqAujy1+M5ctQSBG/Diwnyd18sDYTaXxqnTGhmzIkCQQDycQif5RZ7lQqj
+QjGrHO22eKHXxJD8+8tM+/IHmLDOpH8dh1BCItvbh4BMT00ozqJRYpGW28Dv0tuU
+Mnv2qMXfAkEA1zY/oHshdX+Jl7KfDXHtNdD54+4lo7UCHTY8nYTWSKOse73uIi5n
+OrjyPxTxppeT3LImDfGGz3trn6AFn4NynwJADfM5FtI8v/GsggZeC0WH3BcG4P57
+hUMLyKs6mvtLOSi388AEezm8Qt6CIGHzw6RYLKyqSe7tJB+S6O0auu+tKwJAII8h
+gyr9veQEsgGhFIym4ZxzIeu2oBTTdA3vj7k4Hhc9Eh+C9oLktTqj061cfeKyyRHe
+tf9TcPJwLt8r2p0tawJBANak2VFGrNCvE5kF7WSyCtX6PndPyCpstOGK7oy4brJ2
+8psqKePnamaL7W0WjJuTmbN1GotPf0dlZsP4pTpuUWI=
+-----END RSA PRIVATE KEY-----
diff --git a/src/test/ssl/t/001_ssltests.pl b/src/test/ssl/t/001_ssltests.pl
new file mode 100644
index 0000000..a5734dc
--- /dev/null
+++ b/src/test/ssl/t/001_ssltests.pl
@@ -0,0 +1,141 @@
+use strict;
+use warnings;
+use TestLib;
+use Test::More tests => 16;
+
+
+#### Part 1. Set up the server.
+
+#my $tempdir = TestLib::tempdir;
+my $tempdir = 'tmp_check';
+
+start_test_server($tempdir);
+
+# Create a test user and two databases
+psql 'postgres', "CREATE USER ssltestuser";
+psql 'postgres', "CREATE USER anotheruser";
+psql 'postgres', "CREATE DATABASE trustdb";
+psql 'postgres', "CREATE DATABASE certdb";
+
+# enable SSL and set up server key
+open CONF, ">>$tempdir/pgdata/postgresql.conf";
+print CONF "fsync=off\n";
+print CONF "ssl=on\n";
+print CONF "ssl_ca_file='client-root.crt'\n";
+print CONF "listen_addresses='postgres-server.test'\n";
+print CONF "log_connections=on\n";
+print CONF "log_hostname=on\n";
+print CONF "log_statement=all\n";
+close CONF;
+
+# Copy server certificate and key, and client root certificate, to the data dir
+system_or_bail "cp ssl/server.crt '$tempdir'/pgdata";
+system_or_bail "cp ssl/server.key '$tempdir'/pgdata";
+system_or_bail "chmod 0600 '$tempdir'/pgdata/server.key";
+system_or_bail "cp ssl/client-root.crt '$tempdir'/pgdata";
+
+# Only accept SSL connections, from host "postgres-client.test".
+# When connecting to certdb, also check the client certificate.
+open HBA, ">>$tempdir/pgdata/pg_hba.conf";
+# TYPE  DATABASE        USER            ADDRESS                 METHOD
+print HBA "hostssl	trustdb all postgres-client.test trust\n";
+print HBA "hostssl	certdb all postgres-client.test cert\n";
+close HBA;
+
+# Stop and restart server to reload the new config. We cannot use
+# restart_test_server() because that overrides listen_addresses to only allow
+# Unix domain socket connections.
+
+system_or_bail 'pg_ctl', 'stop', '-D', "$tempdir/pgdata", '-w';
+system_or_bail 'pg_ctl', 'start', '-D', "$tempdir/pgdata", '-w', '-l',
+	"$tempdir/logfile";
+
+my $common_connstr;
+
+# Define a couple of helper functions to test connecting to the server.
+#
+# The first argument is a (part of a) connection string, and it's also printed
+# out as the test case name. It is appended to $common_connstr global variable,
+# which also contains a libpq connection string.
+#
+# The second argument is a hostname to connect to.
+sub test_connect_ok {
+	my $connstr = $_[0];
+	my $hostname = $_[1];
+
+	command_ok([ 'psql',
+				 '-c', "SELECT 'Connection test with $connstr'",
+				 '-d', "$common_connstr host=$hostname $connstr"],
+			   "$connstr");
+}
+
+sub test_connect_fails {
+	my $connstr = $_[0];
+	my $hostname = $_[1];
+
+	command_fails([ 'psql',
+					'-c', "SELECT 'Connection test with $connstr'",
+					'-d', "$common_connstr host=$hostname $connstr"],
+				  "$connstr (should fail)");
+}
+
+
+### Part 2. Run client-side tests.
+###
+### Test that the client accepts/rejects the connection correctly, depending
+### on sslmode and whether the server's certificate looks correct. No
+### client certificate is used in these tests.
+
+$common_connstr="user=ssltestuser dbname=trustdb sslcert=invalid";
+my $host="postgres-server.test";
+
+# The server should not accept non-SSL connections
+test_connect_fails("sslmode=disable", $host);
+
+# Try without a root cert. In sslmode=require, this should work. In verify-ca
+# or verify-full mode it should fail
+test_connect_ok   ("sslrootcert=invalid sslmode=require", $host);
+test_connect_fails("sslrootcert=invalid sslmode=verify-ca", $host);
+test_connect_fails("sslrootcert=invalid sslmode=verify-full", $host);
+
+# 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("sslrootcert=ssl/client-root.crt sslmode=require", $host);
+test_connect_fails("sslrootcert=ssl/client-root.crt sslmode=verify-ca", $host);
+test_connect_fails("sslrootcert=ssl/client-root.crt sslmode=verify-full", $host);
+
+# And finally, with the correct root cert.
+test_connect_ok   ("sslrootcert=ssl/server-root.crt sslmode=require", $host);
+test_connect_ok   ("sslrootcert=ssl/server-root.crt sslmode=verify-ca", $host);
+test_connect_ok   ("sslrootcert=ssl/server-root.crt sslmode=verify-full", $host);
+
+# Check that connecting with verify-full fails, when the hostname doesn't
+# match the hostname in the server's certificate.
+$host="alias-for-postgres-server.test";
+test_connect_ok   ("sslrootcert=ssl/server-root.crt sslmode=require", $host);
+test_connect_ok   ("sslrootcert=ssl/server-root.crt sslmode=verify-ca", $host);
+test_connect_fails("sslrootcert=ssl/server-root.crt sslmode=verify-full", $host);
+
+
+
+### Part 2. Server-side tests.
+###
+### Test certificate authorization. 
+
+$common_connstr="sslrootcert=ssl/server-root.crt sslmode=require dbname=certdb";
+$host="postgres-server.test";
+
+# no client cert
+test_connect_fails("user=ssltestuser sslcert=invalid", $host);
+
+# correct client cert
+test_connect_ok   ("user=ssltestuser sslcert=ssl/client.crt sslkey=ssl/client.key", $host);
+
+# client cert belonging to another user
+test_connect_fails("user=anotheruser sslcert=ssl/client.crt sslkey=ssl/client.key", $host);
+
+
+### Part 3. Test Certificate Revocation Lists
+###
+### TODO
+
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to