|
1 #! /usr/bin/perl |
|
2 |
|
3 use 5.010; |
|
4 use strict; |
|
5 use warnings; |
|
6 use Pod::Usage; |
|
7 use Getopt::Long; |
|
8 use Template; |
|
9 use File::Copy; |
|
10 |
|
11 my $opt_template = "sign.cnf"; |
|
12 my $opt_type = "client"; |
|
13 my $opt_init; |
|
14 |
|
15 sub genpw($); |
|
16 sub init($); |
|
17 |
|
18 MAIN: { |
|
19 GetOptions( |
|
20 "init" => \$opt_init, |
|
21 "t|type=s" => \$opt_type, |
|
22 "h|help" => sub { pod2usage(-exit => 0, -verbose => 1) }, |
|
23 "m|man" => sub { pod2usage(-exit => 0, -verbose => 2, |
|
24 -noperldoc => system("perldoc -V >/dev/null 2>&1")) } |
|
25 ) and @ARGV or pod2usage; |
|
26 my $CN = shift; |
|
27 |
|
28 if ($opt_init) { |
|
29 init($CN); |
|
30 exit 0; |
|
31 } |
|
32 |
|
33 my $csr = "requests/$CN/csr.pem"; |
|
34 if (not -f $csr) { |
|
35 die "Can't find the request in $csr: $!\n"; |
|
36 } |
|
37 |
|
38 $ENV{OPENSSL_CONF} = "ca/openssl.cnf"; |
|
39 system openssl => "ca", |
|
40 -in => $csr, |
|
41 -out => "requests/$CN/crt.pem.tmp", |
|
42 -extensions => $opt_type; |
|
43 |
|
44 if ($?) { |
|
45 unlink "requests/$CN/crt.pem.tmp"; |
|
46 exit 2; |
|
47 } |
|
48 |
|
49 move "requests/$CN/crt.pem.tmp" => "requests/$CN/crt.pem"; |
|
50 say "Certificate saved to requests/$CN/crt.pem"; |
|
51 |
|
52 } |
|
53 |
|
54 sub init($) { |
|
55 my $cn = shift; |
|
56 |
|
57 mkdir "ca/newcerts"; |
|
58 mkdir "ca/private"; |
|
59 open(my $x, ">>ca/index.txt"); |
|
60 close($x); |
|
61 |
|
62 return if -f "ca/ca-crt.pem"; |
|
63 |
|
64 if (not -f "ca/ca-csr.pem") { |
|
65 system "bin/request", "--init"; |
|
66 system "bin/request", "--check" => $cn; |
|
67 $? and system "bin/request", "--template" => "ca-request.cnf", $cn; |
|
68 { |
|
69 local @ARGV = "requests/$cn/secret"; |
|
70 chomp($_ = "REMEMBER(!) THE PASSPHRASE: " . <>); |
|
71 unlink("requests/$cn/secret") or die "@ARGV: $!"; |
|
72 $_ = join "\n", "-" x length, $_, "-" x length; |
|
73 say; |
|
74 } |
|
75 copy "requests/$cn/csr.pem" => "ca/ca-csr.pem"; |
|
76 move "requests/$cn/key.pem" => "ca/private/ca-key.pem"; |
|
77 } |
|
78 |
|
79 |
|
80 $ENV{OPENSSL_CONF} = "ca/openssl.cnf"; |
|
81 system(openssl => qw( |
|
82 ca -selfsign |
|
83 -create_serial -out ca/ca-crt.pem -days 3650 |
|
84 -extensions v3_ca |
|
85 -in ca/ca-csr.pem)); |
|
86 } |
|
87 |
|
88 __END__ |
|
89 |
|
90 =head1 NAME |
|
91 |
|
92 sign - sign a ssl certificate request |
|
93 |
|
94 =head1 SYNOPSIS |
|
95 |
|
96 sign --init {CN} |
|
97 sign [--type=client|server] {CN} |
|
98 |
|
99 =head1 DESCRIPTION |
|
100 |
|
101 B<sign> signs a SSL certificate signing request. |
|
102 The signing request is expected in F<requests/>I<CN>F</csr.pem>. |
|
103 The resulting certificate will be written to |
|
104 F<requests>/I<CN>F</crt.pem>. |
|
105 |
|
106 =head1 OPTIONS |
|
107 |
|
108 =over |
|
109 |
|
110 =item B<--type> client|server |
|
111 |
|
112 Signs the certificate as client or server certificate (default: client) |
|
113 |
|
114 =item B<--init> |
|
115 |
|
116 Using the option a new CA will get initialized. It will create a CSR if |
|
117 there is no CSR in F<requests/>I<CN>/F<csr.pem> already. For security |
|
118 reasons the KEY file found in F<requests/>I<CN>/F<key.pem> will be printed to |
|
119 stdout and B<deleted>. |
|
120 |
|
121 =cut |
|
122 |
|
123 # vim:sts=4 ts=4 sw=4 aw ai sm: |