diff -r f44419b55cf0 -r 72112c207284 bin/ca --- a/bin/ca Tue Jan 26 23:43:31 2010 +0100 +++ b/bin/ca Wed Jan 27 00:30:39 2010 +0100 @@ -8,14 +8,15 @@ use File::Basename; use Getopt::Long qw(GetOptionsFromArray); use Pod::Usage; +use feature qw(switch); my $CA_CRT = "CA/ca-crt.pem"; my $CA_KEY = "CA/private/ca-key.pem"; my $CA_DIR = "./var"; my %TEMPLATE = ( - ca => "templates/ca", - req => "templates/req", + ca => "lib/templates/ca", + req => "lib/templates/req", ); my $TMP = tempdir("/tmp/$ENV{USER}.ca.XXXXXX", CLEANUP => 1); @@ -37,8 +38,8 @@ "t|type=s" => \$opt_type, "p|policy=s" => \$opt_policy, "o|outfile=s" => \$opt_outfile, - "force" => \$opt_force, - "init" => sub { init_ca(); exit 0; }, + "f|force" => \$opt_force, + "i|init" => sub { eval { init_ca() }; if ($@) { warn $@; exit 1 }; exit 0 }, "h|help" => sub { pod2usage(-verbose => 1, -exit => 0) }, "m|man" => sub { pod2usage(-verbose => 2, -exit => 0) }, ) or pod2usage; @@ -46,13 +47,10 @@ pod2usage if @ARGV > 1; $csrfile = $ARGV[0]; # don't shift, we'll need it later! - my $csr = new IO::File "$TMP/csr" => "w+" - or die "Can't open +>$TMP/csr: $!\n"; - my $cnf = new IO::File "$TMP/cnf" => "w" - or die "Can't open >$TMP/cnf: $!\n"; - my $crt = new IO::File "$TMP/crt" => "w+" - or die "Can't open +>$TMP/crt: $!\n"; - my $tt2 = new Template or die $Template::ERROR; + my $cnf = new IO::File ">$TMP/cnf" or die "Can't open >$TMP/cnf: $!\n"; + my $csr = new IO::File "+>$TMP/csr" or die "Can't open +>$TMP/csr: $!\n"; + my $crt = new IO::File "+>$TMP/crt" or die "Can't open +>$TMP/crt: $!\n"; + my $tt2 = new Template or die $Template::ERROR; # get a private copy of the request print { IO::File->new("|openssl req -out $TMP/csr") } <>; @@ -86,21 +84,35 @@ } # to be sure not to have an invalid/dangerous file name - fork() or do { - open(STDOUT, ">$outfile") - if defined $outfile + if (fork() == 0) { + if (defined $outfile) { + open(STDOUT, ">$outfile") or die "Can't open >$outfile: $!\n"; + } exec "openssl x509 -in $TMP/crt"; die "Can't exec openssl x509: $!\n"; - }; - wait; + } + else { wait } + + # and now, since it's finally done, we'll copy the request + # away (for later use (thing about re-issuing a certificate)) + my $subject = `openssl x509 -in $TMP/crt -noout -subject`; + if (my ($cn) = $subject =~ /CN=(\S+?)[,\/\s\$]/) { + if (fork() == 0) { + open(STDOUT, ">$CA_DIR/requests/$cn-csr.pem") + or die "Can't open >$CA_DIR/requests/$cn-csr.pem: $!\n"; + exec "openssl req -in $TMP/csr"; + die "Can't exec openssl req: $!\n"; + } + else { wait } + } + else { + die "Can't determine the CN from $subject, not saving the request\n"; + } + exit; } -sub verbose($) { - warn $_[0], " \n "; -} - sub ask_pass($) { my $prompt = shift; my @keys = ("x", "y"); @@ -127,7 +139,7 @@ # initialize the CA directory structure. This should # correspond to the values found in templates/ca die "$CA_DIR already exists" if -d $CA_DIR and not $opt_force; - mkpath(map { "$CA_DIR/$_" } qw(newcerts)); + mkpath(map { "$CA_DIR/$_" } qw(newcerts requests)); mkpath(map { dirname $_ } $CA_CRT, $CA_KEY); (new IO::File ">$CA_DIR/index"); (new IO::File ">$CA_DIR/serial")->print("01\n"); @@ -154,6 +166,8 @@ ) and exit; umask($_); + return 0; + } __END__