--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/request Wed Jun 20 23:22:33 2012 +0200
@@ -0,0 +1,96 @@
+#! /usr/bin/perl
+
+use 5.010;
+use strict;
+use warnings;
+use Pod::Usage;
+use Getopt::Long;
+use Template;
+#use autodie;
+
+my $DIR = "requests";
+
+my $opt_template = "request.cnf";
+my $opt_check;
+my $opt_init;
+
+sub genpw($);
+
+MAIN: {
+ GetOptions(
+ "template=s" => \$opt_template,
+ "init" => \$opt_init,
+ "check" => \$opt_check,
+ "h|help" => sub { pod2usage(-exit => 0, -verbose => 1) },
+ "m|man" => sub { pod2usage(-exit => 0, -verbose => 2,
+ -noperldoc => system("perldoc -V >/dev/null 2>&1")) }
+ ) or pod2usage;
+
+ my $CN = shift;
+ mkdir($DIR), exit if $opt_init;
+
+ pod2usage if not defined $CN;
+
+ exit(-f "$DIR/$CN/csr.pem" ? 0 : 1)
+ if $opt_check;
+
+ rmdir($_ = "$DIR/$CN"); # succeeds if empty
+ mkdir($_ = "$DIR/$CN") or die "directory $_: $!\n";
+
+ # create the config template
+ my $tt = Template->new(
+ INCLUDE_PATH => "ca/templates",
+ ) or die "$Template::ERROR\n";
+ $tt->process($opt_template, { CN => $CN }, "$DIR/$CN/openssl.cnf")
+ or die $tt->error, "\n";
+ $ENV{OPENSSL_CONF} = "$DIR/$CN/openssl.cnf";
+
+ # create the password file
+ open(my $pw, ">", $_ = "$DIR/$CN/secret") or die "$_: $!\n";
+ say $pw genpw(10);
+ close($pw);
+
+ system(openssl => "req",
+ qw(-new),
+ -keyout => "$DIR/$CN/key.pem",
+ -out => "$DIR/$CN/csr.pem",
+ -passout => "file:$DIR/$CN/secret");
+}
+
+sub genpw($) {
+ my $n = shift;
+ my @chars = (qw(_ . - /), "a".."z", "A".."Z", 0..9);
+ join "" => map { @chars[rand @chars + 1] } (1..$n);
+}
+
+
+__END__
+
+=head1 NAME
+
+ request - generate a ssl certificate request
+
+=head1 SYNOPSIS
+
+ request [--init]
+ request [--template={file}] {CN}
+
+=head1 DESCRIPTION
+
+B<request> generates a new SSL certificate signing request. The files
+(CSR and KEY) are placed in F<requests>. The generated key is protected
+by a passphrase. The passphrase is written to stdout and has to be saved
+by the caller!
+
+=head1 OPTIONS
+
+=over
+
+=item B<--template> I<file>
+
+The template file to be used for creating the request. The templates will be searched
+unter F<ca/templates>. The only substituted item is [%CN%]. (default: request.cnf)
+
+=cut
+
+# vim:sts=4 ts=4 sw=4 aw ai sm: