File: tls_cert

package info (click to toggle)
qpsmtpd 0.40-3
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 1,024 kB
  • ctags: 393
  • sloc: perl: 6,462; sh: 383; makefile: 54
file content (138 lines) | stat: -rwxr-xr-x 3,703 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#!/usr/bin/perl -w
# Very basic script to create TLS certificates for qpsmtpd
use File::Temp qw/ tempfile tempdir /;
use Getopt::Long;

my %opts = ();
chomp (my $hostname = `hostname --fqdn`);
my %defaults = (
    C  => 'XY',
    ST => 'unknown',
    L  => 'unknown',
    O  => 'QSMTPD',
    OU => 'Server',
    CN => $hostname,
);

GetOptions(\%opts, 
    'C|Country:s',
    'ST|State:s',
    'L|Locality|City:s',
    'O|Organization:s',
    'OU|OrganizationalUnit|U:s',
    'CN|CommonName|N:s',
    'emailAddress|email|E:s',
    'help|H',
);

usage() if $opts{help};

# initialize defaults
foreach my $key ( keys %defaults ) {
    $opts{$key} = $defaults{$key} unless $opts{$key}
}
$opts{emailAddress} = 'postmaster@'.$opts{CN};

mkdir('ssl') unless -d 'ssl';

my $CA_key = 'ssl/qpsmtpd-ca.key';
my $CA_crt = 'ssl/qpsmtpd-ca.crt';
my $CA_serial = 'ssl/.cert.serial';

my ($CA, $CAfilename) = tempfile( $template, DIR => "ssl", UNLINK => 1);

print ${CA} return_cfg('CA');
close ${CA};

system('openssl', 'genrsa', '-out', $CA_key, 2048) == 0 
    or die "Cannot create CA key: $?";

system('openssl', 'req', '-config', $CAfilename, '-new', '-x509',
	'-days', (365*6), '-key', $CA_key,
	'-out', $CA_crt) == 0
    or die "Cannot create CA cert: $?";

my $SERVER_key = 'ssl/qpsmtpd-server.key';
my $SERVER_csr = 'ssl/qpsmtpd-server.csr';
my $SERVER_crt = 'ssl/qpsmtpd-server.crt';

my ($SERVER, $SERVERfilename) = tempfile( $template, DIR => "ssl", UNLINK => 1);
print ${SERVER} return_cfg($opts{OU});
close ${SERVER};

system('openssl', 'genrsa', '-out', $SERVER_key, 1024) == 0 
    or die "Cannot create server key: $?";

system('openssl', 'req', '-config', $SERVERfilename, '-new', 
	'-key', $SERVER_key, '-out', $SERVER_csr) == 0
    or die "Cannot create server cert: $?";

my ($SIGN, $SIGNfilename) = tempfile( $template, DIR => "ssl", UNLINK => 1);
print ${SIGN} <<"EOT";
extensions = x509v3
[ x509v3 ]
subjectAltName   = email:copy
nsComment        = tls certificate
nsCertType       = server
EOT
close ${SIGN};

open my $SERIAL, '>', $CA_serial;
print ${SERIAL} "01\n";
close ${SERIAL};

system('openssl', 'x509', '-extfile', $SIGNfilename, '-days', (365*2),
	'-CAserial', $CA_serial, '-CA', $CA_crt,
	'-CAkey', $CA_key, '-in', $SERVER_csr,
	'-req', '-out', $SERVER_crt) == 0
    or die "Cannot sign cert: $?";

exit(0);
	
sub return_cfg {
    my $OU = shift;
    my $RANDOM = int(rand(1000)).'RAN'.int(rand(1000)).'DOM';
    my $cfg = <<"EOT";
[ req ]
default_bits           = 1024
default_keyfile        = keyfile.pem
distinguished_name     = req_distinguished_name
attributes             = req_attributes
prompt                 = no
output_password        = mypass

[ req_distinguished_name ]
C                      = $opts{C}
ST                     = $opts{ST}
L                      = $opts{L}
O                      = $opts{O}
OU                     = $OU
CN                     = $opts{CN}
emailAddress           = $opts{emailAddress}

[ req_attributes ]
challengePassword      = $RANDOM challenge password
EOT
    return $cfg;
}

sub usage {
    print STDERR <<"EOT";

 $0 will generate a TLS certificate "the quick way",
 i.e. without interaction.  You can change some defaults however.
    
 These options are recognized:             Default:

  --C       Country (two letters, e.g. DE) $defaults{C}
  --ST      State (spelled out)            $defaults{ST}
  --L       City                           $defaults{L}
  --O       Organization                   $defaults{O}
  --OU      Organizational Unit            $defaults{OU}
  --CN      Common name                    $defaults{CN}
  --email   Email address of postmaster    postmaster\@CN
  --help    Show usage

EOT
    exit(1);
}