diff options
author | Rob Austein <sra@hactrn.net> | 2007-12-24 06:36:18 +0000 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2007-12-24 06:36:18 +0000 |
commit | e62cfb013638b5e68218c0702e88c6c4dfeb06f9 (patch) | |
tree | 93b5b864915a92a03e805062cf3b5b6d7f8b1e27 /scripts/Old/generate-testrepo.pl | |
parent | 6923ec5709af6f4fa5ea8e6e9af9265f5b9e213f (diff) |
Cleanup
svn path=/scripts/Old/check-hashes.sh; revision=1434
Diffstat (limited to 'scripts/Old/generate-testrepo.pl')
-rw-r--r-- | scripts/Old/generate-testrepo.pl | 337 |
1 files changed, 337 insertions, 0 deletions
diff --git a/scripts/Old/generate-testrepo.pl b/scripts/Old/generate-testrepo.pl new file mode 100644 index 00000000..bacbe0de --- /dev/null +++ b/scripts/Old/generate-testrepo.pl @@ -0,0 +1,337 @@ +# $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/openssl/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 <<EOF); + + [ ca ] + default_ca = ca_default + + [ ca_default ] + + certificate = ${entity}.cer + serial = ${entity}/serial + private_key = ${entity}.key + database = ${entity}/index + new_certs_dir = ${entity} + name_opt = ca_default + cert_opt = ca_default + default_days = 365 + default_crl_days = 30 + default_md = sha1 + preserve = no + copy_extensions = copy + policy = ca_policy_anything + unique_subject = no + + [ ca_policy_anything ] + countryName = optional + stateOrProvinceName = optional + localityName = optional + organizationName = optional + organizationalUnitName = optional + commonName = supplied + emailAddress = optional + givenName = optional + surname = optional + + [ req ] + default_bits = $keybits + encrypt_key = no + distinguished_name = req_dn + x509_extensions = req_x509_ext + prompt = no + + [ req_dn ] + + CN = TEST ENTITY $entity + + [ req_x509_ext ] + + basicConstraints = critical,CA:true + subjectKeyIdentifier = hash + authorityKeyIdentifier = keyid + keyUsage = critical,keyCertSign,cRLSign + subjectInfoAccess = 1.3.6.1.5.5.7.48.5;URI:rsync://wombats-r-us.hactrn.net/ + +EOF + + print(F <<EOF) if ($parent{$entity}); + + authorityInfoAccess = caIssuers;URI:rsync://wombats-r-us.hactrn.net/$parent{$entity}.cer + +EOF + + print(F <<EOF) if ($r{AS} || $r{RDI}); + + sbgp-autonomousSysNum = critical,\@asid_ext + +EOF + + print(F <<EOF) if ($r{IPv4} || $r{IPv6}); + + sbgp-ipAddrBlock = critical,\@addr_ext + +EOF + + print(F <<EOF); + + [ asid_ext ] + +EOF + + for my $n (qw(AS RDI)) { + my $i = 0; + for my $a (@{$r{$n}}) { + print(F "\t", $n, ".", $i++, " = ", $a, "\n"); + } + } + + print(F <<EOF); + + + [ addr_ext ] + +EOF + + for my $n (qw(IPv4 IPv6)) { + my $i = 0; + for my $a (@{$r{$n}}) { + print(F "\t", $n, ".", $i++, " = ", $a, "\n"); + } + } + close(F); +} + +# Revoke old certificates, maybe. + +if ($revoke) { + for my $cert (glob("*/*.pem")) { + my $conf = (split("/", $cert))[0] . ".cnf"; + openssl("ca", "-verbose", "-config", $conf, "-revoke", $cert); + unlink($cert); + } +} + +# 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"); + + mkdir($entity) + unless (-d $entity); + if (!-f "${entity}/index") { + open(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 <<EOF); + + [ req ] + default_bits = $keybits + encrypt_key = no + distinguished_name = req_dn + x509_extensions = req_x509_ext + prompt = no + + [ req_dn ] + + CN = TEST ENDPOINT ENTITY ${entity} + + [ req_x509_ext ] + + basicConstraints = critical,CA:false + subjectKeyIdentifier = hash + authorityKeyIdentifier = keyid + subjectInfoAccess = 1.3.6.1.5.5.7.48.5;URI:rsync://wombats-r-us.hactrn.net/ + authorityInfoAccess = caIssuers;URI:rsync://wombats-r-us.hactrn.net/$parent.cer + +EOF + + close(F); + openssl("genrsa", "-out", "${entity}.key", $keybits) + unless (-f "${entity}.key"); + openssl("req", "-new", "-config", "${entity}.cnf", "-key", "${entity}.key", "-out", "${entity}.req"); + + mkdir($entity) + unless (-d $entity); + if (!-f "${entity}/index") { + open(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 <<EOF); + + [ req ] + default_bits = $keybits + encrypt_key = no + distinguished_name = req_dn + prompt = no + + [ req_dn ] + + CN = $hostname + +EOF + +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-testrepo.pl" +# End: |