Add notes and helper-script for OCSP
authorJeremy Harris <jgh146exb@wizmail.org>
Sun, 30 Jun 2013 14:50:35 +0000 (15:50 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Sun, 30 Jun 2013 14:50:35 +0000 (15:50 +0100)
doc/doc-txt/experimental-spec.txt
src/util/ocsp_fetch.pl [new file with mode: 0755]

index d58f396..7fd2bd8 100644 (file)
@@ -92,10 +92,25 @@ is requested and required for the connection to proceed.  The host(s)
 should also be in "hosts_require_tls", and "tls_verify_certificates"
 configured for the transport.
 
+For the client to be able to verify the stapled OCSP the server must
+also supply, in its stapled information, any intermediate
+certificates for the chain leading to the OCSP proof from the signer
+of the server certificate.  There may be zero or one such. These
+intermediate certificates should be added to the server OCSP stapling
+file (named by tls_ocsp_file).
+
 At this point in time, we're gathering feedback on use, to determine if
 it's worth adding complexity to the Exim daemon to periodically re-fetch
 OCSP files and somehow handling multiple files.
 
+  A helper script "ocsp_fetch.pl" for fetching a proof from a CA
+  OCSP server is supplied.  The server URL may be included in the
+  server certificate, if the CA is helpful.
+
+  One fail mode seen was the OCSP Signer cert expiring before the end
+  of vailidity of the OCSP proof. The checking done by Exim/OpenSSL
+  noted this as invalid overall, but the re-fetch script did not.
+
 
 
 
diff --git a/src/util/ocsp_fetch.pl b/src/util/ocsp_fetch.pl
new file mode 100755 (executable)
index 0000000..0d214d6
--- /dev/null
@@ -0,0 +1,83 @@
+#!/usr/bin/perl
+# Copyright (C) 2012 Wizards Internet Ltd
+# License GPLv2: GNU GPL version 2 <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
+use strict;
+use Getopt::Std;
+$Getopt::Std::STANDARD_HELP_VERSION=1;
+use IO::Handle;
+use Date::Parse;
+my ($o,$i,$s,$f,$t,$u,$VERSION);
+$VERSION='1.0';
+$o={'m'=>10};
+getopts("c:i:u:a:o:m:fv",$o);
+usage('No issuer specified') if ! $o->{'i'} && ! -f $o->{'i'};
+usage('No certificate specified') if ! $o->{'c'} && ! -f $o->{'c'};
+usage('No CA chain specified') if ! $o->{'a'} && ! -f $o->{'a'};
+usage('No OCSP file specified') if ! $o->{'o'};
+usage('No URL specified') if ! $o->{'u'};
+$o->{'t'}=$o->{'o'}.'.tmp';
+
+# check if we need to
+if (     $o->{'f'}
+    || ! -f $o->{'o'}
+    || ( -M $o->{'o'} > 0 )
+   )
+{
+    $i = new IO::Handle;
+    open( $i, "openssl ocsp -issuer $o->{'i'} -cert $o->{'c'} -url $o->{'u'} -CAfile $o->{'a'} -respout $o->{'t'} 2>/dev/null |" ) || die 'Unable to execute ocsp command';
+    $s = <$i> || die 'Unable to read status';
+    $f = <$i> || die 'Unable to read update time';
+    $t = <$i> || die 'Unable to read next update time';
+    close $i;
+    # Status ok ?
+    chomp($s);
+    chomp($f);
+    chomp($t);
+    $s =~ s/[^:]*: //;
+    $f =~ s/[^:]*: //;
+    $t =~ s/[^:]*: //;
+    $t = str2time($t);
+    die "OCSP status is $s" if $s ne 'good';
+    warn "Next Update $t" if $o->{'v'};
+    # response is good, adjust mod time and move into place.
+    $u = $t - $o->{'m'} * (($t - time)/100);
+    utime $u,$u,$o->{'t'};
+    rename $o->{'t'},$o->{'o'};
+}
+exit;
+
+sub
+usage
+{
+    my $m = shift;
+    print STDERR "$m\n" if $m;
+    HELP_MESSAGE(\*STDERR);
+    die;
+}
+sub
+HELP_MESSAGE
+{
+    my $h = shift;
+    print $h <<EOF
+Usage: $0 -i issuer -c certificate -u ocsp_url -a ca_certs -o response [-v] [-f]
+
+For a certificate    "www.example.com.pem"
+  signed by          "signing.example.net.pem"
+  signed by root CA  "ca.example.net.pem"
+  with OCSP server   http://ocsp.example.net/
+
+Ensure there is a file with the signing chain
+
+  cat ca.example.net.pem signing.example.net.pem >chain.pem
+
+The update procedure would be
+
+    ocsp_fetch -i signing.example.net.pem \
+        -c www.example.com.pem \
+    -u http://ocsp.example.net/ \
+    -a chain.pem \
+    -o www.example.com.ocsp.der
+EOF
+}
+# vi: aw ai sw=4
+# End of File