Add regression tests for syslogd TLS client certificates.
authorbluhm <bluhm@openbsd.org>
Tue, 12 Jul 2016 09:57:20 +0000 (09:57 +0000)
committerbluhm <bluhm@openbsd.org>
Tue, 12 Jul 2016 09:57:20 +0000 (09:57 +0000)
regress/usr.sbin/syslogd/Makefile
regress/usr.sbin/syslogd/Server.pm
regress/usr.sbin/syslogd/args-server-tls-client-cert.pl [new file with mode: 0644]
regress/usr.sbin/syslogd/args-server-tls-client-fake.pl [new file with mode: 0644]

index c676343..e7bd195 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: Makefile,v 1.14 2015/11/04 20:02:26 bluhm Exp $
+#      $OpenBSD: Makefile,v 1.15 2016/07/12 09:57:20 bluhm Exp $
 
 # The following ports must be installed for the regression tests:
 # p5-IO-Socket-INET6   object interface for AF_INET and AF_INET6 domain sockets
@@ -84,10 +84,10 @@ run-regress-$a: $a
 ca.crt fake-ca.crt:
        openssl req -batch -new -subj /L=OpenBSD/O=syslogd-regress/OU=ca/CN=root/ -nodes -newkey rsa -keyout ${@:R}.key -x509 -out $@
 
-server.req:
-       openssl req -batch -new -subj /L=OpenBSD/O=syslogd-regress/OU=server/CN=localhost/ -nodes -newkey rsa -keyout ${@:R}.key -out $@
+client.req server.req:
+       openssl req -batch -new -subj /L=OpenBSD/O=syslogd-regress/OU=${@:R}/CN=localhost/ -nodes -newkey rsa -keyout ${@:R}.key -out $@
 
-server.crt: ca.crt server.req
+client.crt server.crt: ca.crt ${@:R}.req
        openssl x509 -CAcreateserial -CAkey ca.key -CA ca.crt -req -in ${@:R}.req -out $@
 
 empty:
@@ -96,7 +96,7 @@ empty:
 toobig:
        dd if=/dev/zero of=$@ bs=1 count=1 seek=50M
 
-${REGRESS_TARGETS:M*tls*}: server.crt 127.0.0.1.crt
+${REGRESS_TARGETS:M*tls*}: client.crt server.crt 127.0.0.1.crt
 ${REGRESS_TARGETS:M*empty*}: empty
 ${REGRESS_TARGETS:M*toobig*}: toobig
 ${REGRESS_TARGETS:M*fake*}: fake-ca.crt
index d81ecf8..48d69b6 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: Server.pm,v 1.7 2015/12/04 13:49:42 bluhm Exp $
+#      $OpenBSD: Server.pm,v 1.8 2016/07/12 09:57:20 bluhm Exp $
 
 # Copyright (c) 2010-2015 Alexander Bluhm <bluhm@openbsd.org>
 #
@@ -50,13 +50,15 @@ sub listen {
            Proto               => $proto,
            ReuseAddr           => 1,
            Domain              => $self->{listendomain},
-           $self->{listenaddr} ? (LocalAddr => $self->{listenaddr}) : (),
-           $self->{listenport} ? (LocalPort => $self->{listenport}) : (),
+           $self->{listenaddr} ? (LocalAddr => $self->{listenaddr}) : (),
+           $self->{listenport} ? (LocalPort => $self->{listenport}) : (),
            SSL_key_file        => "server.key",
            SSL_cert_file       => "server.crt",
-           SSL_verify_mode     => SSL_VERIFY_NONE,
-           $self->{sslversion} ? (SSL_version => $self->{sslversion}) : (),
-           $self->{sslciphers} ? (SSL_cipher_list => $self->{sslciphers}) : (),
+           SSL_ca_file         => ($self->{cacrt} || "ca.crt"),
+           $self->{sslverify}  ? (SSL_verify_mode => SSL_VERIFY_PEER) : (),
+           $self->{sslverify}  ? (SSL_verifycn_scheme => "none") : (),
+           $self->{sslversion} ? (SSL_version => $self->{sslversion}) : (),
+           $self->{sslciphers} ? (SSL_cipher_list => $self->{sslciphers}) : (),
        ) or die ref($self), " $iosocket socket failed: $!,$SSL_ERROR";
        if ($self->{listenproto} ne "udp") {
                listen($ls, 1)
@@ -101,6 +103,8 @@ sub child {
        if ($self->{listenproto} eq "tls") {
                print STDERR "ssl version: ",$as->get_sslversion(),"\n";
                print STDERR "ssl cipher: ",$as->get_cipher(),"\n";
+               print STDERR "ssl subject: ", $as->peer_certificate("subject")
+                   ,"\n" if $self->{sslverify};
        }
 
        *STDIN = *STDOUT = $self->{as} = $as;
diff --git a/regress/usr.sbin/syslogd/args-server-tls-client-cert.pl b/regress/usr.sbin/syslogd/args-server-tls-client-cert.pl
new file mode 100644 (file)
index 0000000..d27fe25
--- /dev/null
@@ -0,0 +1,34 @@
+# The client writes a message to Sys::Syslog native method.
+# The syslogd writes it into a file and through a pipe.
+# The syslogd passes it via TLS with client certificate to the loghost.
+# The server verifies the connection to its TLS socket and gets the message.
+# Find the message in client, file, pipe, syslogd, server log.
+# Check that syslogd has client cert and key in log.
+# Check that server has client certificate subject in log.
+
+use strict;
+use warnings;
+use Socket;
+
+our %args = (
+    syslogd => {
+       options => [qw(-c client.crt -k client.key)],
+       loghost => '@tls://localhost:$connectport',
+       loggrep => {
+           qr/ClientCertfile client.crt/ => 1,
+           qr/ClientKeyfile client.key/ => 1,
+           get_testgrep() => 1,
+       },
+    },
+    server => {
+       listen => { domain => AF_UNSPEC, proto => "tls", addr => "localhost" },
+       sslverify => 1,
+       loggrep => {
+           qr/ssl subject: /.
+               qr{/L=OpenBSD/O=syslogd-regress/OU=client/CN=localhost} => 1,
+           get_testgrep() => 1,
+       },
+    },
+);
+
+1;
diff --git a/regress/usr.sbin/syslogd/args-server-tls-client-fake.pl b/regress/usr.sbin/syslogd/args-server-tls-client-fake.pl
new file mode 100644 (file)
index 0000000..ae3cf8c
--- /dev/null
@@ -0,0 +1,40 @@
+# The client writes a message to Sys::Syslog native method.
+# The syslogd writes it into a file and through a pipe.
+# The syslogd passes it via TLS with client certificate to the loghost.
+# The server tries to verify the connection to its TLS socket with wrong ca.
+# Find the message in client, file, pipe, syslogd log.
+# Check that syslogd and server have error message in log.
+
+use strict;
+use warnings;
+use Socket;
+
+our %args = (
+    syslogd => {
+       options => [qw(-c client.crt -k client.key)],
+       loghost => '@tls://localhost:$connectport',
+       loggrep => {
+           qr/ClientCertfile client.crt/ => 1,
+           qr/ClientKeyfile client.key/ => 1,
+           qr/syslogd: loghost .* connection error: /.
+               qr/handshake failed: error:.*/.
+               qr/SSL3_READ_BYTES:tlsv1 alert decrypt error/ => 2,
+           get_testgrep() => 1,
+       },
+    },
+    server => {
+       listen => { domain => AF_UNSPEC, proto => "tls", addr => "localhost" },
+       sslverify => 1,
+       cacrt => "fake-ca.crt",
+       up => qr/IO::Socket::SSL socket accept failed/,
+       down => qr/SSL accept attempt failed error/,
+       exit => 255,
+       loggrep => {
+           qr/Server IO::Socket::SSL socket accept failed: /.
+               qr/,SSL accept attempt failed error:.*/.
+               qr/SSL3_GET_CLIENT_CERTIFICATE:no certificate returned/ => 1.
+       },
+    },
+);
+
+1;