bin/sign
changeset 0 4f3be01b88b6
--- /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: