aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2006-08-29 23:37:35 +0000
committerRob Austein <sra@hactrn.net>2006-08-29 23:37:35 +0000
commit26192428936c7e2c5c9daa2c68e64513bf2f7b1a (patch)
tree16efc21dbd2e9194d1933faaaaf0cc332f884e0e
parentff9c60fc05e315455cfb3a5da15606ef1bbf84f5 (diff)
Apparently we need to fetch the CRL in order to verify the cert in
which we found the CRL's URI. Ick. Have asked on list, deferring work briefly in the hope that someone will tell me that I'm wrong about this. svn path=/scripts/rcynic-prototype.pl; revision=243
-rw-r--r--scripts/rcynic-prototype.pl135
1 files changed, 85 insertions, 50 deletions
diff --git a/scripts/rcynic-prototype.pl b/scripts/rcynic-prototype.pl
index 4570e3e1..94fe4aca 100644
--- a/scripts/rcynic-prototype.pl
+++ b/scripts/rcynic-prototype.pl
@@ -21,44 +21,58 @@ my $authenticated_tree = "$root/authenticated";
my $temporary_tree = "$root/temporary";
my $cafile = "$root/CAfile.pem";
-
my @anchors;
my @preaggregated;
my %certs;
-sub mkdir_maybe {
- my $dir = shift;
- $dir =~ s=[^/]+$==;
- !system("mkdir", "-p", $dir)
- or die("Couldn't make $dir")
- unless (-d $dir);
-}
+my $verbose = 1;
-sub rsync {
- !system("rsync", "-rtiLk", @_)
- or print("rsync @_ returned failure\n");
+sub run {
+ print(join(" ", "Running", @_), "\n")
+ if ($verbose);
+ system(@_);
+ print("$_[0] returned $?\n")
+ if ($? != 0);
}
-sub openssl {
- !system($openssl, @_)
- or die("Couldn't openssl @_");
-}
-
-sub openssl_pipe {
+sub run_pipe {
+ print(join(" ", "Running", @_), "\n")
+ if ($verbose);
my $pid = open(F, "-|");
if ($pid) {
my @result = <F>;
close(F);
chomp(@result);
+ print("$_[0] returned $?\n")
+ if ($? != 0);
return @result;
} else {
open(STDERR, ">&STDOUT")
or die("Couldn't dup() STDOUT: $!");
- exec($openssl, @_)
- or die("Couldn't exec() openssl @_: $!");
+ exec(@_)
+ or die("Couldn't exec() ", join(" ", @_), ": $!");
}
}
+sub mkdir_maybe {
+ my $dir = shift;
+ $dir =~ s=[^/]+$==;
+ run("mkdir", "-p", $dir)
+ unless (-d $dir);
+}
+
+sub rsync {
+ run("rsync", "-rtiLk", @_);
+}
+
+sub openssl {
+ run($openssl, @_);
+}
+
+sub openssl_pipe {
+ run_pipe($openssl, @_);
+}
+
sub uri_to_filename {
local $_ = shift;
if ($_) {
@@ -160,59 +174,70 @@ sub verify_cert {
my @result = openssl_pipe(qw(verify -verbose -crl_check_all -policy_check -explicit_policy -policy 1.3.6.1.5.5.7.14.2 -x509_strict -CAfile), $cafile,
"$temporary_tree/$cert");
local $_;
- my $ok;
for (@result) {
- $ok = 1 if (/OK$/);
+ return 1 if (/OK$/);
}
- return $ok;
+ print("Verification failure:\n");
+ print(" Inputs:\n");
+ print(" $_\n")
+ foreach (($cert, @_));
+ print(" Result:\n");
+ print(" $_\n")
+ foreach (@result);
+ return 0;
}
sub check_cert {
- my $cert = shift; # -verified- cert we're examining (we start from trust anchors)
+ my $c = shift; # parsed verified cert we're examining
my @chain = @_; # ancestors and crls
- print("Starting check of $cert\n");
+ die("check_cert() called without a certificate to check")
+ unless ($c);
- my $u = parse_cert($cert);
- die("Couldn't parse certificate: $cert")
- unless ($u);
+ print("Starting check of $c->{uri}\n");
+
+ print("URI: $c->{uri}\n");
+ print("AIA: $c->{aia}\n") if ($c->{aia});
+ print("SIA: $c->{sia}\n") if ($c->{sai});
+ print("CDP: $c->{cdp}\n") if ($c->{cdp});
+ print("CA: ", ($c->{ca} ? "Yes" : "No"), "\n");
my $crl;
- if ($u->{cdp}) {
- $crl = uri_to_filename($u->{cdp});
- die ("Problem with CRL signature: $u->{cdp}")
- unless (check_crl($u->{cdp}, $crl, $u->{file}, @chain));
+ if ($c->{cdp}) {
+ $crl = uri_to_filename($c->{cdp});
+ die ("Problem with CRL signature: $c->{cdp}")
+ unless (check_crl($c->{cdp}, $crl, $c->{file}, @chain));
copy_crl($crl);
} else {
- print("CDP missing for cert: $cert\n");
+ print("CDP missing for cert: $c->{uri}\n");
}
- if (@chain && !$u->{aia}) {
- print("Non-trust-anchor certificate missing AIA extension: $cert\n");
- } elsif (@chain && $chain[0] ne $u->{aia}) {
- print("AIA does not match parent URI:\n\t$cert\n\t$u->{aia}\n");
+ if (@chain && !$c->{aia}) {
+ print("Non-trust-anchor certificate missing AIA extension: $c->{uri}\n");
+ } elsif (@chain && $chain[0] ne uri_to_filename($c->{aia})) {
+ print("AIA does not match parent URI:\n\trsync://$chain[0]\n\t$c->{aia}\n");
}
unshift(@chain, $crl)
if ($crl);
- unshift(@chain, $u->{file});
+ unshift(@chain, $c->{file});
- if ($u->{ca}) {
- print("CA certificate without SIA extension: $cert\n")
- unless ($u->{sia});
+ if ($c->{ca}) {
+ print("CA certificate without SIA extension: $c->{uri}\n")
+ unless ($c->{sia});
} else {
- print("EE certificate shouldn't have SIA extension: $cert\n")
- if ($u->{sia});
+ print("EE certificate shouldn't have SIA extension: $c->{uri}\n")
+ if ($c->{sia});
}
- if ($u->{sia}) {
- my $sia = uri_to_filename($u->{sia});
+ if ($c->{sia}) {
+ my $sia = uri_to_filename($c->{sia});
#
# Suppress this rsync when we've already done an ancestor?
# Almost certainly. Deal with it later.
#
mkdir_maybe("$unauthenticated_tree/$sia");
- rsync($u->{sia}, "$unauthenticated_tree/$sia");
+ rsync($c->{sia}, "$unauthenticated_tree/$sia");
for my $file (glob("$unauthenticated_tree/${sia}*.cer")) {
$file =~ s=^$unauthenticated_tree/==;
my $uri = "rsync://" . $file;
@@ -222,17 +247,27 @@ sub check_cert {
next;
}
copy_cert($file);
- if (!verify_cert($file, @chain)) {
+ my $x = parse_cert($uri, $temporary_tree);
+ if (!$x) {
+ print("Parse failure for $uri, skipping\n");
+ next;
+ }
+ #
+ # This is questionable -- CRL may not have been checked yet.
+ # One would hope that verification checks CRL signatures,
+ # but the CRL may not be in our verified repository yet.
+ #
+ if (!verify_cert($file, uri_to_filename($x->{cdp}), @chain)) {
print("Verification failure for $uri, skipping\n");
unlink("$temporary_tree/$file");
next;
}
install_cert($file);
- check_cert($uri, @chain);
+ check_cert($x, @chain);
}
}
- print("Finished check of $cert\n");
+ print("Finished check of $c->{uri}\n");
}
###
@@ -265,7 +300,7 @@ if (1) {
# Initial cleanup.
-system("rm", "-rf", $temporary_tree, "${authenticated_tree}.old");
+run("rm", "-rf", $temporary_tree, "${authenticated_tree}.old");
rename($authenticated_tree, "${authenticated_tree}.old");
# Create any missing directories.
@@ -300,7 +335,7 @@ for my $anchor (@anchors) {
# Now start walking the tree, starting with our trust anchors.
for my $anchor (@anchors) {
- check_cert($anchor);
+ check_cert(parse_cert($anchor));
}