Re: [HACKERS] SSL regression test suite

2014-12-05 Thread Noah Misch
On Thu, Dec 04, 2014 at 02:42:41PM +0200, Heikki Linnakangas wrote:
 On 10/06/2014 04:21 PM, Heikki Linnakangas wrote:
 This probably needs some further cleanup before it's ready for
 committing. One issues is that it creates a temporary cluster that
 listens for TCP connections on localhost, which isn't safe on a
 multi-user system.
 
 This issue remains. There isn't much we can do about it; SSL doesn't work
 over Unix domain sockets. We could make it work, but that's a whole
 different feature.

A large subset of the test suite could be made secure.  Omit or lock down
trustdb, and skip affected tests.  (Perhaps have an --unsafe-tests option to
reactivate them.)  Instead of distributing frozen keys, generate all keys
on-demand.  Ensure that key files have secure file modes from the start.
Having said that, ...

 How do people feel about including this test suite in the source tree? It's
 probably not suitable for running as part of make check-world, but it's
 extremely handy if you're working on a patch related to SSL. I'd like to
 commit this, even if it has some rough edges. That way we can improve it
 later, rather than have it fall into oblivion. Any objections?

... +1 for having this suite in the tree, even if check-world ignores it.
Echoing Tom's comment, the README should mention its security weakness.

Thanks,
nm


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] SSL regression test suite

2014-12-04 Thread Heikki Linnakangas

On 10/06/2014 04:21 PM, Heikki Linnakangas wrote:

Here's a new version of the SSL regression suite I wrote earlier. It now
specifies both host and hostaddr in the connection string as Andres
suggested, so it no longer requires changes to network configuration. I
added a bunch of tests for the SAN feature that Alexey Klyukin wrote and
was committed earlier. Plus a lot of miscellaneous cleanup.


And here's another version. It now includes tests for CRLs, and uses a 
root CA that's used to sign the server and client CA's certificates, to 
test that using intermediary CAs work.



This probably needs some further cleanup before it's ready for
committing. One issues is that it creates a temporary cluster that
listens for TCP connections on localhost, which isn't safe on a
multi-user system.


This issue remains. There isn't much we can do about it; SSL doesn't 
work over Unix domain sockets. We could make it work, but that's a whole 
different feature.


How do people feel about including this test suite in the source tree? 
It's probably not suitable for running as part of make check-world, 
but it's extremely handy if you're working on a patch related to SSL. 
I'd like to commit this, even if it has some rough edges. That way we 
can improve it later, rather than have it fall into oblivion. Any 
objections?


- Heikki
diff --git a/src/test/Makefile b/src/test/Makefile
index 9238860..1d6f789 100644
--- a/src/test/Makefile
+++ b/src/test/Makefile
@@ -12,7 +12,7 @@ subdir = src/test
 top_builddir = ../..
 include $(top_builddir)/src/Makefile.global
 
-SUBDIRS = regress isolation modules
+SUBDIRS = regress isolation modules ssl
 
 # We want to recurse to all subdirs for all standard targets, except that
 # installcheck and install should not recurse into the subdirectory modules.
diff --git a/src/test/ssl/Makefile b/src/test/ssl/Makefile
new file mode 100644
index 000..194267b
--- /dev/null
+++ b/src/test/ssl/Makefile
@@ -0,0 +1,126 @@
+#-
+#
+# 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_ca server-cn-and-alt-names \
+	server-cn-only server-single-alt-name server-multiple-alt-names \
+	server-no-names server-revoked server-ss \
+	client_ca client client-revoked \
+	root_ca
+
+SSLFILES := $(CERTIFICATES:%=ssl/%.key) $(CERTIFICATES:%=ssl/%.crt) \
+	ssl/client.crl ssl/server.crl ssl/root.crl \
+	ssl/both-cas-1.crt ssl/both-cas-2.crt \
+	ssl/root+server_ca.crt ssl/root+server.crl \
+	ssl/root+client_ca.crt ssl/root+client.crl
+
+sslfiles: $(SSLFILES)
+
+ssl/new_certs_dir:
+	mkdir ssl/new_certs_dir
+
+# Rule for creating private/public key pairs
+ssl/%.key:
+	openssl genrsa -out $@ 1024
+	chmod 0600 $@
+
+# Rules for creating root CA certificates
+ssl/root_ca.crt: ssl/root_ca.key cas.config
+	touch ssl/root_ca-certindex
+	openssl req -new -out ssl/root_ca.crt -x509 -config cas.config -config root_ca.config -key ssl/root_ca.key
+	echo 01  ssl/root_ca.srl
+
+# for client and server CAs
+ssl/%_ca.crt: ssl/%_ca.key %_ca.config ssl/root_ca.crt ssl/new_certs_dir
+	touch ssl/$*_ca-certindex
+	openssl req -new -out ssl/temp_ca.crt -config cas.config -config $*_ca.config -key ssl/$*_ca.key
+# Sign the certificate with the root CA
+	openssl ca -name root_ca -batch -config cas.config -in ssl/temp_ca.crt -out ssl/temp_ca_signed.crt
+	openssl x509 -in ssl/temp_ca_signed.crt -out ssl/$*_ca.crt # to keep just the PEM cert
+	rm ssl/temp_ca.crt ssl/temp_ca_signed.crt
+	echo 01  ssl/$*_ca.srl
+
+# 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
+	openssl ca -name server_ca -batch -config cas.config -in ssl/server-$*.csr -out ssl/temp.crt  -extensions v3_req -extfile server-$*.config
+	openssl x509 -in ssl/temp.crt -out ssl/server-$*.crt # to keep just the PEM cert
+	rm ssl/server-$*.csr
+
+# Self-signed version of server-cn-only.crt
+ssl/server-ss.crt: ssl/server-cn-only.key ssl/server-cn-only.crt server-cn-only.config
+	openssl req -new -key ssl/server-cn-only.key -out ssl/server-ss.csr -config server-cn-only.config
+	openssl x509 -req -days 1 -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
+
+# Client certificate, signed by the client CA:
+ssl/client.crt: ssl/client.key ssl/client_ca.crt
+	openssl req -new -key ssl/client.key -out ssl/client.csr -config client.config
+	openssl ca -name client_ca -batch -out ssl/temp.crt -config cas.config -infiles 

Re: [HACKERS] SSL regression test suite

2014-12-04 Thread David Fetter
On Thu, Dec 04, 2014 at 02:42:41PM +0200, Heikki Linnakangas wrote:
 On 10/06/2014 04:21 PM, Heikki Linnakangas wrote:
 This probably needs some further cleanup before it's ready for
 committing. One issues is that it creates a temporary cluster that
 listens for TCP connections on localhost, which isn't safe on a
 multi-user system.
 
 This issue remains. There isn't much we can do about it; SSL doesn't work
 over Unix domain sockets. We could make it work, but that's a whole
 different feature.
 
 How do people feel about including this test suite in the source tree? It's
 probably not suitable for running as part of make check-world,

What makes it unsuitable?

 but it's extremely handy if you're working on a patch related to
 SSL.  I'd like to commit this, even if it has some rough edges. That
 way we can improve it later, rather than have it fall into oblivion.
 Any objections?

Not from me :)

Cheers,
David.
-- 
David Fetter da...@fetter.org http://fetter.org/
Phone: +1 415 235 3778  AIM: dfetter666  Yahoo!: dfetter
Skype: davidfetter  XMPP: david.fet...@gmail.com

Remember to vote!
Consider donating to Postgres: http://www.postgresql.org/about/donate


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] SSL regression test suite

2014-12-04 Thread Tom Lane
Heikki Linnakangas hlinnakan...@vmware.com writes:
 On 10/06/2014 04:21 PM, Heikki Linnakangas wrote:
 This probably needs some further cleanup before it's ready for
 committing. One issues is that it creates a temporary cluster that
 listens for TCP connections on localhost, which isn't safe on a
 multi-user system.

 This issue remains. There isn't much we can do about it; SSL doesn't 
 work over Unix domain sockets. We could make it work, but that's a whole 
 different feature.

 How do people feel about including this test suite in the source tree? 
 It's probably not suitable for running as part of make check-world, 
 but it's extremely handy if you're working on a patch related to SSL. 
 I'd like to commit this, even if it has some rough edges. That way we 
 can improve it later, rather than have it fall into oblivion. Any 
 objections?

As long as it's not run by any standard target, and there's some
documentation explaining why not, I see no reason it can't be in the
tree.

regards, tom lane


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] SSL regression test suite

2014-12-04 Thread Alvaro Herrera
Heikki Linnakangas wrote:

 How do people feel about including this test suite in the source tree?

+1

 It's probably not suitable for running as part of make check-world,
 but it's extremely handy if you're working on a patch related to SSL.
 I'd like to commit this, even if it has some rough edges. That way we
 can improve it later, rather than have it fall into oblivion. Any
 objections?

To prevent it from breaking, one idea is to have one or more buildfarm
animals that run this test as a separate module.

-- 
Álvaro Herrerahttp://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training  Services


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] SSL regression test suite

2014-10-06 Thread Heikki Linnakangas

On 08/12/2014 03:53 PM, Heikki Linnakangas wrote:

On 08/12/2014 02:28 PM, Andres Freund wrote:

On 2014-08-12 14:01:18 +0300, Heikki Linnakangas wrote:

Also, to test sslmode=verify-full, where the client checks that the server
certificate's hostname matches the hostname that it connected to, you need
to have two aliases for the same server, one that matches the certificate
and one that doesn't. But I think I found a way around that part; if the
certificate is set up for localhost, and connect to 127.0.0.1, you get a
mismatch.


Alternatively, and to e.g. test wildcard certs and such, I think you can
specify both host and hostaddr to connect to connect without actually
doing a dns lookup.


Oh, I didn't know that's possible! Yeah, that's a good solution.


Here's a new version of the SSL regression suite I wrote earlier. It now 
specifies both host and hostaddr in the connection string as Andres 
suggested, so it no longer requires changes to network configuration. I 
added a bunch of tests for the SAN feature that Alexey Klyukin wrote and 
was committed earlier. Plus a lot of miscellaneous cleanup.


This probably needs some further cleanup before it's ready for 
committing. One issues is that it creates a temporary cluster that 
listens for TCP connections on localhost, which isn't safe on a 
multi-user system.


- Heikki

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 000..8e0db47
--- /dev/null
+++ b/src/test/ssl/Makefile
@@ -0,0 +1,59 @@
+#-
+#
+# 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 := serverroot server-cn-and-alt-names \
+	server-cn-only server-single-alt-name server-multiple-alt-names \
+	server-no-names \
+	clientroot client
+
+SSLFILES := $(CERTIFICATES:%=ssl/%.key) $(CERTIFICATES:%=ssl/%.crt)
+
+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 %root.config
+	openssl req -new -key ssl/$*root.key -days 36500 -out ssl/$*root.crt -x509 -config $*root.config
+	echo 00  ssl/$*root.srl
+
+# Server certificates, signed by server root CA:
+ssl/server-%.crt: ssl/server-%.key ssl/serverroot.crt
+# Generate a Certificate Sign Request (CSR)
+	openssl req -new -key ssl/server-$*.key -out ssl/server-$*.csr -config server-$*.config
+# Sign the certificate with the right CA
+	openssl x509 -req -in ssl/server-$*.csr -CA ssl/serverroot.crt -CAkey ssl/serverroot.key -CAserial ssl/serverroot.srl -out ssl/server-$*.crt -extfile server-$*.config -extensions v3_req
+	rm ssl/server-$*.csr
+
+# Client certificate, signed by the client root CA:
+ssl/client.crt: ssl/client.key ssl/clientroot.crt
+# Generate a Certificate Sign Request (CSR)
+	openssl req -new -key ssl/client.key -out ssl/client.csr -config client.config
+# Sign the certificate with the right CA
+	openssl x509 -req -in ssl/client.csr -CA ssl/clientroot.crt -CAkey ssl/clientroot.key -CAserial ssl/clientroot.srl -out ssl/client.crt
+	rm ssl/client.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 000..dfd2d79
--- /dev/null
+++ b/src/test/ssl/README
@@ -0,0 +1,43 @@
+src/test/ssl/README
+
+SSL regression tests
+
+
+This directory contains a test suite for SSL support.
+
+Running the tests
+=
+
+make check
+
+Certificates
+
+
+The test suite needs a set of public/private key pairs and certificates to
+run:
+
+serverroot.crt: CA used to sign server certificates
+clientroot.crt: CA used to sign client certificates
+server-*.crt: server certificate, with small variations in the hostnames
+  present in the certificate.
+client.crt: a client certificate, for user ssltestuser
+
+For convenience, these keypairs and certificates are included in the ssl/
+subdirectory, but the Makefile also contains a rule, make sslfiles, to
+recreate them if you want to make changes.
+
+
+TODO
+
+
+* Allow the client-side of the tests to be run on different host easily.
+  Currently, 

Re: [HACKERS] SSL regression test suite

2014-08-12 Thread Heikki Linnakangas

On 08/05/2014 10:46 PM, Robert Haas wrote:

On Mon, Aug 4, 2014 at 10:38 AM, Heikki Linnakangas
hlinnakan...@vmware.com wrote:

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.


That seems so onerous that I think few people will do it, and not
regularly, resulting in the tests breaking and nobody noticing.
Reconfiguring the loopback interface like that requires root
privilege, and won't survive a reboot, and doing it in the system
configuration will require hackery specific to the particular flavor
of Linux you're running, and probably other hackery on non-Linux
systems (never mind Windows).


Yeah, you're probably right.


Why can't you make it work over 127.0.0.1?


I wanted it to be easy to run the client and the server on different 
hosts. As soon as we have more than one SSL implementation, it would be 
really nice to do interoperability testing between a client and a server 
using different implementations.


Also, to test sslmode=verify-full, where the client checks that the 
server certificate's hostname matches the hostname that it connected to, 
you need to have two aliases for the same server, one that matches the 
certificate and one that doesn't. But I think I found a way around that 
part; if the certificate is set up for localhost, and connect to 
127.0.0.1, you get a mismatch.


So, I got rid of the DNS setup, it only depends localhost/127.0.0.1 now. 
Patch attached. That means that it's not easy to run the client and the 
server on different hosts, but we can improve that later.


- Heikki
commit 140c590ca86a0ba4a6b422e4b618cd459b84175f
Author: Heikki Linnakangas heikki.linnakan...@iki.fi
Date:   Wed Aug 6 18:43:39 2014 +0300

Refactor cert file stuff in client

diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c
index f950fc3..cee7b2e 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -780,57 +780,21 @@ destroy_ssl_system(void)
 static int
 initialize_SSL(PGconn *conn)
 {
-	struct stat buf;
-	char		homedir[MAXPGPATH];
-	char		fnbuf[MAXPGPATH];
-	char		sebuf[256];
-	bool		have_homedir;
-	bool		have_cert;
 	EVP_PKEY   *pkey = NULL;
-
-	/*
-	 * We'll need the home directory if any of the relevant parameters are
-	 * defaulted.  If pqGetHomeDirectory fails, act as though none of the
-	 * files could be found.
-	 */
-	if (!(conn-sslcert  strlen(conn-sslcert)  0) ||
-		!(conn-sslkey  strlen(conn-sslkey)  0) ||
-		!(conn-sslrootcert  strlen(conn-sslrootcert)  0) ||
-		!(conn-sslcrl  strlen(conn-sslcrl)  0))
-		have_homedir = pqGetHomeDirectory(homedir, sizeof(homedir));
-	else	/* won't need it */
-		have_homedir = false;
-
-	/* Read the client certificate file */
-	if (conn-sslcert  strlen(conn-sslcert)  0)
-		strncpy(fnbuf, conn-sslcert, sizeof(fnbuf));
-	else if (have_homedir)
-		snprintf(fnbuf, sizeof(fnbuf), %s/%s, homedir, USER_CERT_FILE);
-	else
-		fnbuf[0] = '\0';
-
-	if (fnbuf[0] == '\0')
-	{
-		/* no home directory, proceed without a client cert */
-		have_cert = false;
-	}
-	else if (stat(fnbuf, buf) != 0)
-	{
-		/*
-		 * If file is not present, just go on without a client cert; server
-		 * might or might not accept the connection.  Any other error,
-		 * however, is grounds for complaint.
-		 */
-		if (errno != ENOENT  errno != ENOTDIR)
-		{
-			printfPQExpBuffer(conn-errorMessage,
-			   libpq_gettext(could not open certificate file \%s\: %s\n),
-			  fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
-			return -1;
-		}
-		have_cert = false;
-	}
-	else
+	char	   *sslcertfile = NULL;
+	char	   *engine = NULL;
+	char	   *keyname = NULL;
+	char	   *sslkeyfile = NULL;
+	char	   *sslrootcert = NULL;
+	char	   *sslcrl = NULL;
+	int			ret = -1;
+
+	if (!pqsecure_get_ssl_files(conn,
+sslcertfile, sslkeyfile, engine, keyname,
+sslrootcert, sslcrl))
+		return PGRES_POLLING_READING;
+
+	if (sslcertfile)
 	{
 		/*
 		 * Cert file exists, so load it.  Since OpenSSL doesn't provide the
@@ -855,216 +819,146 @@ initialize_SSL(PGconn *conn)
 		{
 			printfPQExpBuffer(conn-errorMessage,
 			   libpq_gettext(could not acquire mutex: %s\n), strerror(rc));
-			return -1;
+			goto fail;
 		}
 #endif
-		if (SSL_CTX_use_certificate_chain_file(SSL_context, fnbuf) != 1)
+		if (SSL_CTX_use_certificate_chain_file(SSL_context, sslcertfile) != 1)
 		{
 			char	   *err = SSLerrmessage();
 
 			printfPQExpBuffer(conn-errorMessage,
 			   libpq_gettext(could not read certificate file \%s\: %s\n),
-			  fnbuf, err);
+			  sslcertfile, err);
 			SSLerrfree(err);
 
 #ifdef 

Re: [HACKERS] SSL regression test suite

2014-08-12 Thread Andres Freund
On 2014-08-12 14:01:18 +0300, Heikki Linnakangas wrote:
 On 08/05/2014 10:46 PM, Robert Haas wrote:
 Why can't you make it work over 127.0.0.1?
 
 I wanted it to be easy to run the client and the server on different hosts.
 As soon as we have more than one SSL implementation, it would be really nice
 to do interoperability testing between a client and a server using different
 implementations.
 
 Also, to test sslmode=verify-full, where the client checks that the server
 certificate's hostname matches the hostname that it connected to, you need
 to have two aliases for the same server, one that matches the certificate
 and one that doesn't. But I think I found a way around that part; if the
 certificate is set up for localhost, and connect to 127.0.0.1, you get a
 mismatch.

Alternatively, and to e.g. test wildcard certs and such, I think you can
specify both host and hostaddr to connect to connect without actually
doing a dns lookup.

Greetings,

Andres Freund

-- 
 Andres Freund http://www.2ndQuadrant.com/
 PostgreSQL Development, 24x7 Support, Training  Services


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] SSL regression test suite

2014-08-12 Thread Heikki Linnakangas

On 08/12/2014 02:28 PM, Andres Freund wrote:

On 2014-08-12 14:01:18 +0300, Heikki Linnakangas wrote:

Also, to test sslmode=verify-full, where the client checks that the server
certificate's hostname matches the hostname that it connected to, you need
to have two aliases for the same server, one that matches the certificate
and one that doesn't. But I think I found a way around that part; if the
certificate is set up for localhost, and connect to 127.0.0.1, you get a
mismatch.


Alternatively, and to e.g. test wildcard certs and such, I think you can
specify both host and hostaddr to connect to connect without actually
doing a dns lookup.


Oh, I didn't know that's possible! Yeah, that's a good solution.

- Heikki


--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] SSL regression test suite

2014-08-05 Thread Robert Haas
On Mon, Aug 4, 2014 at 10:38 AM, Heikki Linnakangas
hlinnakan...@vmware.com wrote:
 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.

That seems so onerous that I think few people will do it, and not
regularly, resulting in the tests breaking and nobody noticing.
Reconfiguring the loopback interface like that requires root
privilege, and won't survive a reboot, and doing it in the system
configuration will require hackery specific to the particular flavor
of Linux you're running, and probably other hackery on non-Linux
systems (never mind Windows).  Why can't you make it work over
127.0.0.1?

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


[HACKERS] SSL regression test suite

2014-08-04 Thread Heikki Linnakangas
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 000..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 000..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 000..c7fd5f8
--- /dev/null
+++ b/src/test/ssl/ssl/client-root.config
@@ -0,0 +1,6 @@
+[ req ]