|
1 #!/usr/bin/perl |
|
2 # Usage: |
|
3 # PATH=$NSS_PREFIX/bin:$NSS_PREFIX/lib:$PATH ./generate.pl |
|
4 |
|
5 use Cwd; |
|
6 use File::Temp qw/ tempfile tempdir /; |
|
7 |
|
8 use strict; |
|
9 |
|
10 my $srcdir=getcwd(); |
|
11 my $db = tempdir( CLEANUP => 1 ); |
|
12 my $noisefile=$db."/noise"; |
|
13 my $passwordfile=$db."/passwordfile"; |
|
14 my $ca_responses=$srcdir."/ca_responses"; |
|
15 my $ee_responses=$srcdir."/ee_responses"; |
|
16 |
|
17 #my $db=$tmpdir; |
|
18 |
|
19 my @base_usages=("", |
|
20 "certSigning,crlSigning", |
|
21 "digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement,certSigning,crlSigning", |
|
22 "digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement,crlSigning"); |
|
23 |
|
24 my @ee_usages=("", |
|
25 "digitalSignature,keyEncipherment,dataEncipherment", |
|
26 "digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement", |
|
27 "certSigning"); |
|
28 my @eku_usages=("serverAuth,clientAuth,codeSigning,emailProtection,timeStamp,ocspResponder,stepUp,msTrustListSign", |
|
29 "serverAuth,clientAuth", |
|
30 "codeSigning,emailProtection", |
|
31 "timeStamp,ocspResponder,stepUp,msTrustListSign" |
|
32 ); |
|
33 |
|
34 sub dsystem{ |
|
35 my @args = @_; |
|
36 system(@args) == 0 |
|
37 or die "system @args failed: $?"; |
|
38 } |
|
39 |
|
40 sub generate_certs(){ |
|
41 for (my $i = 1; $i < scalar(@base_usages) + 1; $i++) { |
|
42 my $ca_name = "ca-$i"; |
|
43 my $ca_key_usage = $base_usages[$i - 1]; |
|
44 if (length($ca_key_usage) > 1) { |
|
45 $ca_key_usage = " --keyUsage $ca_key_usage,critical"; |
|
46 } |
|
47 my $ca_email = "$ca_name\@example.com"; |
|
48 my $ca_subject = "CN=$ca_name, E=$ca_email"; |
|
49 print "key_usage=$ca_key_usage\n"; |
|
50 dsystem("certutil -S -s '$ca_name' -s '$ca_subject' -t 'C,,' -x -m $i -v 120 -n '$ca_name' $ca_key_usage -Z SHA256 -2 -d $db -f $passwordfile -z $noisefile < $ca_responses"); |
|
51 |
|
52 #and now export |
|
53 dsystem("certutil -d $db -f $passwordfile -L -n $ca_name -r -o $srcdir/$ca_name.der"); |
|
54 |
|
55 for (my $j = 1; $j < scalar(@ee_usages) + 1; $j++) { |
|
56 ##do ee certs |
|
57 my $ee_name = "ee-$j-ca-$i"; |
|
58 my $ee_key_usage = $ee_usages[$j - 1]; |
|
59 if (length($ee_key_usage) > 1) { |
|
60 $ee_key_usage=" --keyUsage $ee_key_usage,critical"; |
|
61 } |
|
62 my $serial = (scalar(@base_usages) + 1) * $j + $i; |
|
63 dsystem("certutil -S -n '$ee_name' -s 'CN=$ee_name' -c '$ca_name' $ee_key_usage -t 'P,,' -k rsa -g 1024 -Z SHA256 -m $serial -v 120 -d $db -f $passwordfile -z $noisefile < $ee_responses"); |
|
64 #and export |
|
65 dsystem("certutil -d $db -f $passwordfile -L -n $ee_name -r -o $srcdir/$ee_name.der"); |
|
66 } |
|
67 for (my $j = 1; $j < scalar(@eku_usages) + 1; $j++){ |
|
68 my $ee_name = "ee-" . ($j + scalar(@ee_usages)) . "-ca-$i"; |
|
69 my $eku_key_usage = $eku_usages[$j - 1]; |
|
70 $eku_key_usage = " --extKeyUsage $eku_key_usage,critical"; |
|
71 my $serial = 10000 + (scalar(@base_usages) + 1) * $j + $i; |
|
72 dsystem("certutil -S -n '$ee_name' -s 'CN=$ee_name' -c '$ca_name' $eku_key_usage -t 'P,,' -k rsa -g 1024 -Z SHA256 -m $serial -v 120 -d $db -f $passwordfile -z $noisefile < $ee_responses"); |
|
73 #and export |
|
74 dsystem("certutil -d $db -f $passwordfile -L -n $ee_name -r -o $srcdir/$ee_name.der"); |
|
75 |
|
76 } |
|
77 } |
|
78 } |
|
79 |
|
80 |
|
81 sub main(){ |
|
82 |
|
83 ##setup |
|
84 dsystem("echo password1 > $passwordfile"); |
|
85 dsystem("head --bytes 32 /dev/urandom > $noisefile"); |
|
86 |
|
87 ##why no include this in the source dir? |
|
88 # XXX: certutil cannot generate basic constraints without interactive prompts, |
|
89 # so we need to build response files to answer its questions |
|
90 # XXX: certutil cannot generate AKI/SKI without interactive prompts so we just |
|
91 # skip them. |
|
92 dsystem("echo y > $ca_responses"); # Is this a CA? |
|
93 dsystem("echo >> $ca_responses");# Accept default path length constraint (no constraint) |
|
94 dsystem("echo y >> $ca_responses"); # Is this a critical constraint? |
|
95 dsystem("echo n > $ee_responses"); # Is this a CA? |
|
96 dsystem("echo >> $ee_responses"); # Accept default path length constraint (no constraint) |
|
97 dsystem("echo y >> $ee_responses"); # Is this a critical constraint? |
|
98 |
|
99 dsystem("certutil -d $db -N -f $passwordfile"); |
|
100 |
|
101 generate_certs(); |
|
102 |
|
103 print "Done\n"; |
|
104 |
|
105 } |
|
106 |
|
107 |
|
108 main(); |