# $Id$ # Hack to generate a small test repository for testing Apache + OpenSSL + RPKI use strict; my %resources; my %parent; my @ordering; my %hashes; my $openssl = "../../openssl/trunk/apps/openssl"; my $subdir = "apacheca"; my $passwd = "fnord"; my $keybits = 2048; my $verbose = 0; my $debug = 1; my $revoke = 0; sub openssl { print(STDERR join(" ", qw(+ openssl), @_), "\n") if ($debug); !system($openssl, @_) or die("openssl @_ returned $?\n"); } # Ok, this is a bit complicated, but the idea is to let us specify the # resources we're giving to each leaf entity and let the program do # the work of figuring out what resources each issuers need to have, # the order in which we need to generate the certificates, which # certificates need to sign which other certificates, etcetera. # # This would be much easier to read in a sane language (eg, Scheme). { my @ctx; my $loop ; $loop= sub { my $x = shift; if (ref($x) eq "HASH") { while (my ($k, $v) = each(%$x)) { $parent{$k} = $ctx[@ctx - 1]; push(@ordering, $k); push(@ctx, $k); $loop->($v); pop(@ctx); } } else { for my $c (@ctx) { push(@{$resources{$c}}, @$x) } } }; $loop->({ RIR => { LIR1 => { ISP1 => [IPv4 => "192.0.2.1-192.0.2.33", AS => "64533"], ISP2 => [IPv4 => "192.0.2.44-192.0.2.100"], }, LIR2 => { ISP3 => [IPv6 => "2001:db8::44-2001:db8::100"], ISP4 => [IPv6 => "2001:db8::10:0:44", AS => "64544"], }, }, }); } # Put this stuff into a subdirectory mkdir($subdir) unless (-d $subdir); chdir($subdir) or die; # Generate configurations for each entity. while (my ($entity, $resources) = each(%resources)) { my %r; print($entity, ":\n") if ($verbose); for (my $i = 0; $i < @$resources; $i += 2) { printf(" %4s: %s\n", $resources->[$i], $resources->[$i+1]) if ($verbose); push(@{$r{$resources->[$i]}}, $resources->[$i+1]); } open(F, ">${entity}.cnf") or die; print(F <${entity}/index") or die; close(F); } if (!-f "${entity}/serial") { open(F, ">${entity}/serial") or die; print(F "01\n") or die; close(F); } openssl("ca", "-batch", "-verbose", "-out", "${entity}.cer", "-in", "${entity}.req", "-extensions", "req_x509_ext", "-extfile", "${entity}.cnf", ($parent{$entity} ? ("-config", "${parent{$entity}}.cnf") : ("-config", "${entity}.cnf", "-selfsign"))); } # Generate CRLs for my $entity (@ordering) { openssl("ca", "-batch", "-verbose", "-out", "${entity}.crl", "-config", "${entity}.cnf", "-gencrl"); } # Generate EE certs for my $parent (@ordering) { my $entity = "${parent}-EE"; open(F, ">${entity}.cnf") or die; print(F <${entity}/index") or die; close(F); } if (!-f "${entity}/serial") { open(F, ">${entity}/serial") or die; print(F "01\n") or die; close(F); } openssl("ca", "-batch", "-verbose", "-config", "${parent}.cnf", "-extensions", "req_x509_ext", "-extfile", "${entity}.cnf", "-out", "${entity}.cer", "-in", "${entity}.req"); } # Generate hashes for my $cert (map({("$_.cer", "$_-EE.cer")} @ordering)) { my $hash = `$openssl x509 -noout -hash -in $cert`; chomp($hash); $hash .= "."; $hash .= (0 + $hashes{$hash}++); unlink($hash) if (-l $hash); symlink($cert, $hash) or die("Couldn't link $hash to $cert: $!\n"); } for my $crl (map({"$_.crl"} @ordering)) { my $hash = `$openssl crl -noout -hash -in $crl`; chomp($hash); $hash .= ".r"; $hash .= (0 + $hashes{$hash}++); unlink($hash) if (-l $hash); symlink($crl, $hash) or die("Couldn't link $hash to $crl: $!\n"); } # Generate PKCS12 forms of EE certificates # -chain argument to pkcs12 requires certificate store, which we configure via an environment variable $ENV{SSL_CERT_DIR} = do { my $pwd = `pwd`; chomp($pwd); $pwd; }; for my $ee (map({"$_-EE"} @ordering)) { my @cmd = ("pkcs12", "-export", "-in", "$ee.cer", "-inkey", "$ee.key", "-password", "pass:$passwd"); openssl(@cmd, "-out", "$ee.p12"); openssl(@cmd, "-out", "$ee.chain.p12", "-chain"); } # Finally, generate an unrelated self-signed certificate for the server my $hostname = `hostname`; chomp($hostname); open(F, ">server.cnf") or die; print(F <