Skip to content

Commit a2d921d

Browse files
committed
tools: customize mk-ca-bundle.pl
Remove unneeded functionality and tweak the generated output so we can #include it in C++ source code. This commit essentially reapplies the changes from commit e159073 ("tools: customize mk-ca-bundle.pl") to the updated script. PR-URL: #1833 Reviewed-By: Shigeki Ohtsu <[email protected]>
1 parent 5be9efc commit a2d921d

File tree

1 file changed

+12
-193
lines changed

1 file changed

+12
-193
lines changed

tools/mk-ca-bundle.pl

+12-193
Original file line numberDiff line numberDiff line change
@@ -30,41 +30,20 @@
3030
# dependency is the OpenSSL commandline tool for optional text listing.
3131
# Hacked by Guenter Knauf.
3232
#
33+
use File::Basename 'dirname';
3334
use Getopt::Std;
3435
use MIME::Base64;
35-
use LWP::UserAgent;
3636
use strict;
37-
use vars qw($opt_b $opt_d $opt_f $opt_h $opt_i $opt_l $opt_n $opt_p $opt_q $opt_s $opt_t $opt_u $opt_v $opt_w);
37+
use vars qw($opt_h $opt_i $opt_l $opt_p $opt_q $opt_s $opt_t $opt_v $opt_w);
3838
use List::Util;
3939
use Text::Wrap;
40-
my $MOD_SHA = "Digest::SHA";
41-
eval "require $MOD_SHA";
42-
if ($@) {
43-
$MOD_SHA = "Digest::SHA::PurePerl";
44-
eval "require $MOD_SHA";
45-
}
46-
47-
my %urls = (
48-
'nss' =>
49-
'http://hg.mozilla.org/projects/nss/raw-file/tip/lib/ckfw/builtins/certdata.txt',
50-
'central' =>
51-
'http://hg.mozilla.org/mozilla-central/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
52-
'aurora' =>
53-
'http://hg.mozilla.org/releases/mozilla-aurora/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
54-
'beta' =>
55-
'http://hg.mozilla.org/releases/mozilla-beta/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
56-
'release' =>
57-
'http://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
58-
);
59-
60-
$opt_d = 'release';
6140

6241
# If the OpenSSL commandline is not in search path you can configure it here!
6342
my $openssl = 'openssl';
6443

6544
my $version = '1.25';
6645

67-
$opt_w = 76; # default base64 encoded lines length
46+
$opt_w = 72; # default base64 encoded lines length
6847

6948
# default cert types to include in the output (default is to include CAs which may issue SSL server certs)
7049
my $default_mozilla_trust_purposes = "SERVER_AUTH";
@@ -111,57 +90,20 @@
11190
$Getopt::Std::STANDARD_HELP_VERSION = 1;
11291
getopts('bd:fhilnp:qs:tuvw:');
11392

114-
if(!defined($opt_d)) {
115-
# to make plain "-d" use not cause warnings, and actually still work
116-
$opt_d = 'release';
117-
}
118-
119-
# Use predefined URL or else custom URL specified on command line.
120-
my $url = ( defined( $urls{$opt_d} ) ) ? $urls{$opt_d} : $opt_d;
121-
122-
my $curl = `curl -V`;
123-
12493
if ($opt_i) {
12594
print ("=" x 78 . "\n");
12695
print "Script Version : $version\n";
12796
print "Perl Version : $]\n";
12897
print "Operating System Name : $^O\n";
12998
print "Getopt::Std.pm Version : ${Getopt::Std::VERSION}\n";
13099
print "MIME::Base64.pm Version : ${MIME::Base64::VERSION}\n";
131-
print "LWP::UserAgent.pm Version : ${LWP::UserAgent::VERSION}\n";
132-
print "LWP.pm Version : ${LWP::VERSION}\n";
133-
print "Digest::SHA.pm Version : ${Digest::SHA::VERSION}\n" if ($Digest::SHA::VERSION);
134-
print "Digest::SHA::PurePerl.pm Version : ${Digest::SHA::PurePerl::VERSION}\n" if ($Digest::SHA::PurePerl::VERSION);
135100
print ("=" x 78 . "\n");
136101
}
137102

138-
sub warning_message() {
139-
if ( $opt_d =~ m/^risk$/i ) { # Long Form Warning and Exit
140-
print "Warning: Use of this script may pose some risk:\n";
141-
print "\n";
142-
print " 1) Using http is subject to man in the middle attack of certdata content\n";
143-
print " 2) Default to 'release', but more recent updates may be found in other trees\n";
144-
print " 3) certdata.txt file format may change, lag time to update this script\n";
145-
print " 4) Generally unwise to blindly trust CAs without manual review & verification\n";
146-
print " 5) Mozilla apps use additional security checks aren't represented in certdata\n";
147-
print " 6) Use of this script will make a security engineer grind his teeth and\n";
148-
print " swear at you. ;)\n";
149-
exit;
150-
} else { # Short Form Warning
151-
print "Warning: Use of this script may pose some risk, -d risk for more details.\n";
152-
}
153-
}
154-
155103
sub HELP_MESSAGE() {
156-
print "Usage:\t${0} [-b] [-d<certdata>] [-f] [-i] [-l] [-n] [-p<purposes:levels>] [-q] [-s<algorithms>] [-t] [-u] [-v] [-w<l>] [<outputfile>]\n";
157-
print "\t-b\tbackup an existing version of ca-bundle.crt\n";
158-
print "\t-d\tspecify Mozilla tree to pull certdata.txt or custom URL\n";
159-
print "\t\t Valid names are:\n";
160-
print "\t\t ", join( ", ", map { ( $_ =~ m/$opt_d/ ) ? "$_ (default)" : "$_" } sort keys %urls ), "\n";
161-
print "\t-f\tforce rebuild even if certdata.txt is current\n";
104+
print "Usage:\t${0} [-i] [-l] [-p<purposes:levels>] [-q] [-s<algorithms>] [-t] [-v] [-w<l>] [<outputfile>]\n";
162105
print "\t-i\tprint version info about used modules\n";
163106
print "\t-l\tprint license info about certdata.txt\n";
164-
print "\t-n\tno download of certdata.txt (to use existing)\n";
165107
print wrap("\t","\t\t", "-p\tlist of Mozilla trust purposes and levels for certificates to include in output. Takes the form of a comma separated list of purposes, a colon, and a comma separated list of levels. (default: $default_mozilla_trust_purposes:$default_mozilla_trust_levels)"), "\n";
166108
print "\t\t Valid purposes are:\n";
167109
print wrap("\t\t ","\t\t ", join( ", ", "ALL", @valid_mozilla_trust_purposes ) ), "\n";
@@ -172,7 +114,6 @@ ()
172114
print "\t\t Valid signature algorithms are:\n";
173115
print wrap("\t\t ","\t\t ", join( ", ", "ALL", @valid_signature_algorithms ) ), "\n";
174116
print "\t-t\tinclude plain text listing of certificates\n";
175-
print "\t-u\tunlink (remove) certdata.txt after processing\n";
176117
print "\t-v\tbe verbose and print out processed CAs\n";
177118
print "\t-w <l>\twrap base64 output lines after <l> chars (default: ${opt_w})\n";
178119
exit;
@@ -182,7 +123,6 @@ ()
182123
print "${0} version ${version} running Perl ${]} on ${^O}\n";
183124
}
184125

185-
warning_message() unless ($opt_q || $url =~ m/^(ht|f)tps:/i );
186126
HELP_MESSAGE() if ($opt_h);
187127

188128
sub report($@) {
@@ -224,35 +164,6 @@ ($$@)
224164
return @values;
225165
}
226166

227-
sub sha1 {
228-
my $result;
229-
if ($Digest::SHA::VERSION || $Digest::SHA::PurePerl::VERSION) {
230-
open(FILE, $_[0]) or die "Can't open '$_[0]': $!";
231-
binmode(FILE);
232-
$result = $MOD_SHA->new(1)->addfile(*FILE)->hexdigest;
233-
close(FILE);
234-
} else {
235-
# Use OpenSSL command if Perl Digest::SHA modules not available
236-
$result = (split(/ |\r|\n/,`$openssl dgst -sha1 $_[0]`))[1];
237-
}
238-
return $result;
239-
}
240-
241-
242-
sub oldsha1 {
243-
my $sha1 = "";
244-
open(C, "<$_[0]") || return 0;
245-
while(<C>) {
246-
chomp;
247-
if($_ =~ /^\#\# SHA1: (.*)/) {
248-
$sha1 = $1;
249-
last;
250-
}
251-
}
252-
close(C);
253-
return $sha1;
254-
}
255-
256167
if ( $opt_p !~ m/:/ ) {
257168
print "Error: Mozilla trust identifier list must include both purposes and levels\n";
258169
HELP_MESSAGE();
@@ -275,98 +186,17 @@ (%)
275186
return 0;
276187
}
277188

278-
my $crt = $ARGV[0] || 'ca-bundle.crt';
279-
(my $txt = $url) =~ s@(.*/|\?.*)@@g;
189+
my $crt = $ARGV[0] || dirname(__FILE__) . '/../src/node_root_certs.h';
190+
my $txt = dirname(__FILE__) . '/certdata.txt';
280191

281192
my $stdout = $crt eq '-';
282-
my $resp;
283-
my $fetched;
284-
285-
my $oldsha1 = oldsha1($crt);
286193

287-
report "SHA1 of old file: $oldsha1";
288-
289-
report "Downloading '$txt' ...";
290-
291-
if($curl && !$opt_n) {
292-
my $https = $url;
293-
$https =~ s/^http:/https:/;
294-
report "Get certdata over HTTPS with curl!";
295-
my $quiet = $opt_q ? "-s" : "";
296-
my @out = `curl -w %{response_code} $quiet -O $https`;
297-
if(@out && $out[0] == 200) {
298-
$fetched = 1;
299-
} else {
300-
report "Failed downloading HTTPS with curl, trying HTTP with LWP";
301-
}
302-
}
303-
304-
unless ($fetched || ($opt_n and -e $txt)) {
305-
my $ua = new LWP::UserAgent(agent => "$0/$version");
306-
$ua->env_proxy();
307-
$resp = $ua->mirror($url, $txt);
308-
if ($resp && $resp->code eq '304') {
309-
report "Not modified";
310-
exit 0 if -e $crt && !$opt_f;
311-
} else {
312-
$fetched = 1;
313-
}
314-
if( !$resp || $resp->code !~ /^(?:200|304)$/ ) {
315-
report "Unable to download latest data: "
316-
. ($resp? $resp->code . ' - ' . $resp->message : "LWP failed");
317-
exit 1 if -e $crt || ! -r $txt;
318-
}
319-
}
320-
321-
my $filedate = $resp ? $resp->last_modified : (stat($txt))[9];
322-
my $datesrc = "as of";
323-
if(!$filedate) {
324-
# mxr.mozilla.org gave us a time, hg.mozilla.org does not!
325-
$filedate = time();
326-
$datesrc="downloaded on";
327-
}
328-
329-
# get the hash from the download file
330-
my $newsha1= sha1($txt);
331-
332-
if(!$opt_f && $oldsha1 eq $newsha1) {
333-
report "Downloaded file identical to previous run\'s source file. Exiting";
334-
exit;
335-
}
336-
337-
report "SHA1 of new file: $newsha1";
338-
339-
my $currentdate = scalar gmtime($filedate);
340-
341-
my $format = $opt_t ? "plain text and " : "";
342194
if( $stdout ) {
343195
open(CRT, '> -') or die "Couldn't open STDOUT: $!\n";
344196
} else {
345197
open(CRT,">$crt.~") or die "Couldn't open $crt.~: $!\n";
346198
}
347-
print CRT <<EOT;
348-
##
349-
## Bundle of CA Root Certificates
350-
##
351-
## Certificate data from Mozilla ${datesrc}: ${currentdate}
352-
##
353-
## This is a bundle of X.509 certificates of public Certificate Authorities
354-
## (CA). These were automatically extracted from Mozilla's root certificates
355-
## file (certdata.txt). This file can be found in the mozilla source tree:
356-
## ${url}
357-
##
358-
## It contains the certificates in ${format}PEM format and therefore
359-
## can be directly used with curl / libcurl / php_curl, or with
360-
## an Apache+mod_ssl webserver for SSL client authentication.
361-
## Just configure this file as the SSLCACertificateFile.
362-
##
363-
## Conversion done with mk-ca-bundle.pl version $version.
364-
## SHA1: $newsha1
365-
##
366-
367-
EOT
368-
369-
report "Processing '$txt' ...";
199+
370200
my $caname;
371201
my $certnum = 0;
372202
my $skipnum = 0;
@@ -386,7 +216,7 @@ (%)
386216
next if /^#|^\s*$/;
387217
chomp;
388218
if (/^CVS_ID\s+\"(.*)\"/) {
389-
print CRT "# $1\n";
219+
print CRT "/* $1 */\n";
390220
}
391221

392222
# this is a match for the start of a certificate
@@ -431,11 +261,11 @@ (%)
431261
$skipnum ++;
432262
} else {
433263
my $encoded = MIME::Base64::encode_base64($data, '');
434-
$encoded =~ s/(.{1,${opt_w}})/$1\n/g;
435-
my $pem = "-----BEGIN CERTIFICATE-----\n"
264+
$encoded =~ s/(.{1,${opt_w}})/"$1\\n"\n/g;
265+
my $pem = "\"-----BEGIN CERTIFICATE-----\\n\"\n"
436266
. $encoded
437-
. "-----END CERTIFICATE-----\n";
438-
print CRT "\n$caname\n";
267+
. "\"-----END CERTIFICATE-----\\n\",\n";
268+
print CRT "\n/* $caname */\n";
439269

440270
my $maxStringLength = length($caname);
441271
if ($opt_t) {
@@ -445,7 +275,6 @@ (%)
445275
print CRT $string . "\n";
446276
}
447277
}
448-
print CRT ("=" x $maxStringLength . "\n");
449278
if (!$opt_t) {
450279
print CRT $pem;
451280
} else {
@@ -484,16 +313,6 @@ (%)
484313
close(TXT) or die "Couldn't close $txt: $!\n";
485314
close(CRT) or die "Couldn't close $crt.~: $!\n";
486315
unless( $stdout ) {
487-
if ($opt_b && -e $crt) {
488-
my $bk = 1;
489-
while (-e "$crt.~${bk}~") {
490-
$bk++;
491-
}
492-
rename $crt, "$crt.~${bk}~" or die "Failed to create backup $crt.~$bk}~: $!\n";
493-
} elsif( -e $crt ) {
494-
unlink( $crt ) or die "Failed to remove $crt: $!\n";
495-
}
496316
rename "$crt.~", $crt or die "Failed to rename $crt.~ to $crt: $!\n";
497317
}
498-
unlink $txt if ($opt_u);
499318
report "Done ($certnum CA certs processed, $skipnum skipped).";

0 commit comments

Comments
 (0)