--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/sign Wed Jun 20 23:22:33 2012 +0200
@@ -0,0 +1,123 @@
+#! /usr/bin/perl
+
+use 5.010;
+use strict;
+use warnings;
+use Pod::Usage;
+use Getopt::Long;
+use Template;
+use File::Copy;
+
+my $opt_template = "sign.cnf";
+my $opt_type = "client";
+my $opt_init;
+
+sub genpw($);
+sub init($);
+
+MAIN: {
+ GetOptions(
+ "init" => \$opt_init,
+ "t|type=s" => \$opt_type,
+ "h|help" => sub { pod2usage(-exit => 0, -verbose => 1) },
+ "m|man" => sub { pod2usage(-exit => 0, -verbose => 2,
+ -noperldoc => system("perldoc -V >/dev/null 2>&1")) }
+ ) and @ARGV or pod2usage;
+ my $CN = shift;
+
+ if ($opt_init) {
+ init($CN);
+ exit 0;
+ }
+
+ my $csr = "requests/$CN/csr.pem";
+ if (not -f $csr) {
+ die "Can't find the request in $csr: $!\n";
+ }
+
+ $ENV{OPENSSL_CONF} = "ca/openssl.cnf";
+ system openssl => "ca",
+ -in => $csr,
+ -out => "requests/$CN/crt.pem.tmp",
+ -extensions => $opt_type;
+
+ if ($?) {
+ unlink "requests/$CN/crt.pem.tmp";
+ exit 2;
+ }
+
+ move "requests/$CN/crt.pem.tmp" => "requests/$CN/crt.pem";
+ say "Certificate saved to requests/$CN/crt.pem";
+
+}
+
+sub init($) {
+ my $cn = shift;
+
+ mkdir "ca/newcerts";
+ mkdir "ca/private";
+ open(my $x, ">>ca/index.txt");
+ close($x);
+
+ return if -f "ca/ca-crt.pem";
+
+ if (not -f "ca/ca-csr.pem") {
+ system "bin/request", "--init";
+ system "bin/request", "--check" => $cn;
+ $? and system "bin/request", "--template" => "ca-request.cnf", $cn;
+ {
+ local @ARGV = "requests/$cn/secret";
+ chomp($_ = "REMEMBER(!) THE PASSPHRASE: " . <>);
+ unlink("requests/$cn/secret") or die "@ARGV: $!";
+ $_ = join "\n", "-" x length, $_, "-" x length;
+ say;
+ }
+ copy "requests/$cn/csr.pem" => "ca/ca-csr.pem";
+ move "requests/$cn/key.pem" => "ca/private/ca-key.pem";
+ }
+
+
+ $ENV{OPENSSL_CONF} = "ca/openssl.cnf";
+ system(openssl => qw(
+ ca -selfsign
+ -create_serial -out ca/ca-crt.pem -days 3650
+ -extensions v3_ca
+ -in ca/ca-csr.pem));
+}
+
+__END__
+
+=head1 NAME
+
+ sign - sign a ssl certificate request
+
+=head1 SYNOPSIS
+
+ sign --init {CN}
+ sign [--type=client|server] {CN}
+
+=head1 DESCRIPTION
+
+B<sign> signs a SSL certificate signing request.
+The signing request is expected in F<requests/>I<CN>F</csr.pem>.
+The resulting certificate will be written to
+F<requests>/I<CN>F</crt.pem>.
+
+=head1 OPTIONS
+
+=over
+
+=item B<--type> client|server
+
+Signs the certificate as client or server certificate (default: client)
+
+=item B<--init>
+
+Using the option a new CA will get initialized. It will create a CSR if
+there is no CSR in F<requests/>I<CN>/F<csr.pem> already. For security
+reasons the KEY file found in F<requests/>I<CN>/F<key.pem> will be printed to
+stdout and B<deleted>.
+
+=cut
+
+# vim:sts=4 ts=4 sw=4 aw ai sm: