diff options
author | Rob Austein <sra@hactrn.net> | 2006-09-05 13:48:38 +0000 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2006-09-05 13:48:38 +0000 |
commit | a23bf34b39df9703ac16129881767e7024143486 (patch) | |
tree | 7d712098deee2aed620e1b77d664ac031111f57a /scripts/generate-testrepo.pl | |
parent | f8f0ed9aca1f02a18fb5b398f4088558405873b4 (diff) |
Initial
svn path=/scripts/generate-testrepo.pl; revision=253
Diffstat (limited to 'scripts/generate-testrepo.pl')
-rw-r--r-- | scripts/generate-testrepo.pl | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/scripts/generate-testrepo.pl b/scripts/generate-testrepo.pl new file mode 100644 index 00000000..7246f332 --- /dev/null +++ b/scripts/generate-testrepo.pl @@ -0,0 +1,221 @@ +# $Id$ + +# Hack to generate a small test repository for testing Apache + OpenSSL + RPKI + +use strict; + +my %resources; +my %parent; +my @ordering; +my %hashes; + +my $subdir = "apacheca"; +my $passwd = "fnord"; +my $keybits = 2048; +my $verbose = 0; + +sub openssl { + !system("openssl", @_) + or die("openssl @_ returned $?\n"); +} + +# Ok, this is a bit complicted, 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 => "10.0.1.1-10.0.3.255", AS => "33"], + ISP2 => [IPv4 => "10.3.0.0-10.3.0.255"], + }, + LIR2 => { + ISP3 => [IPv6 => "2002::44-2002::100"], + ISP4 => [IPv6 => "2002::10:0:44", AS => "44"], + }, + }, + }); +} + +# 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)) { + if ($verbose) { + print($entity, ":\n"); + for (my $i = 0; $i < @$resources; $i += 2) { + printf(" %4s: %s\n", $resources->[$i], $resources->[$i+1]); + } + } + my %r; + for (my $i = 0; $i < @$resources; $i += 2) { + push(@{$r{$resources->[$i]}}, $resources->[$i+1]); + } + + open(F, ">${entity}.cnf") or die; + print(F + "[ req ]\n", + "default_bits = $keybits\n", + "encrypt_key = no\n", + "distinguished_name = req_dn\n", + "x509_extensions = req_x509_ext\n", + "prompt = no\n", + "\n", + "[ req_dn ]\n", + "\n", + "CN = TEST ENTITY $entity\n", + "\n", + "[ req_x509_ext ]\n", + "\n", + "basicConstraints = critical,CA:true\n", + "subjectKeyIdentifier = hash\n", + "authorityKeyIdentifier = keyid\n", + "keyUsage = critical,keyCertSign,cRLSign\n", + "subjectInfoAccess = 1.3.6.1.5.5.7.48.5;URI:rsync://wombats-r-us.hactrn.net/\n"); + print(F "authorityInfoAccess = caIssuers;URI:rsync://wombats-r-us.hactrn.net/$parent{$entity}.cer\n") + if ($parent{$entity}); + print(F "sbgp-autonomousSysNum = critical,\@asid_ext\n") + if ($r{AS} || $r{RDI}); + print(F "sbgp-ipAddrBlock = critical,\@addr_ext\n") + if ($r{IPv4} || $r{IPv6}); + print(F "\n[ asid_ext ]\n\n"); + for my $n (qw(AS RDI)) { + my $i = 0; + for my $a (@{$r{$n}}) { + print(F $n, ".", $i++, " = ", $a, "\n"); + } + } + print(F "\n[ addr_ext ]\n\n"); + for my $n (qw(IPv4 IPv6)) { + my $i = 0; + for my $a (@{$r{$n}}) { + print(F $n, ".", $i++, " = ", $a, "\n"); + } + } + close(F); +} + +# Run OpenSSL to create the keys and certificates. We generate keys +# separately to avoid wasting /dev/random bits if we need to change +# the configuration. + +for my $entity (@ordering) { + openssl("genrsa", "-out", "${entity}.key", $keybits) + unless (-f "${entity}.key"); + openssl("req", "-new", "-config", "${entity}.cnf", "-key", "${entity}.key", "-out", "${entity}.req"); + openssl("x509", "-req", "-CAcreateserial", "-in", "${entity}.req", "-out", "${entity}.cer", + "-extfile", "${entity}.cnf", "-extensions", "req_x509_ext", + ($parent{$entity} + ? ("-CA", "$parent{$entity}.cer", "-CAkey", "$parent{$entity}.key") + : ("-signkey", "${entity}.key"))); +} + +# Generate EE certs + +for my $parent (@ordering) { + my $entity = "${parent}-EE"; + open(F, ">${entity}.cnf") or die; + print(F + "[ req ]\n", + "default_bits = $keybits\n", + "encrypt_key = no\n", + "distinguished_name = req_dn\n", + "x509_extensions = req_x509_ext\n", + "prompt = no\n", + "\n", + "[ req_dn ]\n", + "\n", + "CN = TEST ENDPOINT ENTITY ${entity}\n", + "\n", + "[ req_x509_ext ]\n", + "\n", + "basicConstraints = critical,CA:false\n", + "subjectKeyIdentifier = hash\n", + "authorityKeyIdentifier = keyid\n", + "subjectInfoAccess = 1.3.6.1.5.5.7.48.5;URI:rsync://wombats-r-us.hactrn.net/\n", + "authorityInfoAccess = caIssuers;URI:rsync://wombats-r-us.hactrn.net/$parent.cer\n", + "\n"); + close(F); + openssl("genrsa", "-out", "${entity}.key", $keybits) + unless (-f "${entity}.key"); + openssl("req", "-new", "-config", "${entity}.cnf", "-key", "${entity}.key", "-out", "${entity}.req"); + openssl("x509", "-req", "-CAcreateserial", "-in", "${entity}.req", "-out", "${entity}.cer", + "-extfile", "${entity}.cnf", "-extensions", "req_x509_ext", + "-CA", "${parent}.cer", "-CAkey", "${parent}.key"); +} + +# We really ought to generate CRLs here too, but it'd be a pain, +# because that'd require us to use the ca command, which requires more +# of a database than the x509 commands above are generating. Rewrite +# later if we really need this for some reason. + +# Generate hashes + +for my $cert (map({("$_.cer", "$_-EE.cer")} @ordering)) { + my $hash = `openssl x509 -noout -hash -in $cert`; + chomp($hash); + $hash .= "." . (0 + $hashes{$hash}++); + unlink($hash) if (-l $hash); + symlink($cert, $hash) + or die("Couldn't link $hash to $cert: $!\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 + "[ req ]\n", + "default_bits = $keybits\n", + "encrypt_key = no\n", + "distinguished_name = req_dn\n", + "prompt = no\n", + "\n", + "[ req_dn ]\n", + "\n", + "CN = $hostname\n", + "\n"); +close(F); +openssl(qw(genrsa -out server.key), $keybits) + unless (-f "server.key"); +openssl(qw(req -new -config server.cnf -key server.key -out server.req)); +openssl(qw(x509 -req -CAcreateserial -in server.req -out server.cer -signkey server.key)); + +# Local Variables: +# compile-command: "perl generate.pl" +# End: |