bin/request
changeset 0 4f3be01b88b6
child 1 99252f548cc0
--- /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: