--- 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__