@ -30,11 +30,11 @@
# dependency is the OpenSSL commandline tool for optional text listing.
# Hacked by Guenter Knauf.
#
use File::Basename 'dirname' ;
use Getopt::Std ;
use MIME::Base64 ;
use LWP::UserAgent ;
use strict ;
use vars qw( $opt_b $opt_f $opt_ h $opt_i $opt_l $opt_n $opt_ q $opt_t $opt_u $opt_v $opt_w ) ;
use vars qw( $opt_h $opt_i $opt_l $opt_q $opt_t $opt_v $opt_w ) ;
my $ url = 'http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1' ;
# If the OpenSSL commandline is not in search path you can configure it here!
@ -42,7 +42,7 @@ my $openssl = 'openssl';
my $ version = '1.19' ;
$ opt_w = 76 ; # default base64 encoded lines length
$ opt_w = 72 ; # default base64 encoded lines length
$ 0 =~ s@.*(/|\\)@@ ;
$ Getopt:: Std:: STANDARD_HELP_VERSION = 1 ;
@ -55,21 +55,15 @@ if ($opt_i) {
print "Operating System Name : $^O\n" ;
print "Getopt::Std.pm Version : ${Getopt::Std::VERSION}\n" ;
print "MIME::Base64.pm Version : ${MIME::Base64::VERSION}\n" ;
print "LWP::UserAgent.pm Version : ${LWP::UserAgent::VERSION}\n" ;
print "LWP.pm Version : ${LWP::VERSION}\n" ;
print ( "=" x 78 . "\n" ) ;
}
sub HELP_MESSAGE () {
print "Usage:\t${0} [-b] [-f] [-i] [-l] [-n] [-q] [-t] [-u] [-v] [-w<l>] [<outputfile>]\n" ;
print "\t-b\tbackup an existing version of ca-bundle.crt\n" ;
print "\t-f\tforce rebuild even if certdata.txt is current\n" ;
print "Usage:\t${0} [-i] [-l] [-q] [-t] [-v] [-w<l>] [<outputfile>]\n" ;
print "\t-i\tprint version info about used modules\n" ;
print "\t-l\tprint license info about certdata.txt\n" ;
print "\t-n\tno download of certdata.txt (to use existing)\n" ;
print "\t-q\tbe really quiet (no progress output at all)\n" ;
print "\t-t\tinclude plain text listing of certificates\n" ;
print "\t-u\tunlink (remove) certdata.txt after processing\n" ;
print "\t-v\tbe verbose and print out processed CAs\n" ;
print "\t-w <l>\twrap base64 output lines after <l> chars (default: ${opt_w})\n" ;
exit ;
@ -81,56 +75,36 @@ sub VERSION_MESSAGE() {
HELP_MESSAGE ( ) if ( $ opt_h ) ;
my $ crt = $ ARGV [ 0 ] || 'ca-bundle.crt ';
( my $ txt = $ url ) =~ s@(.*/|\?.*)@@g ;
my $ crt = $ ARGV [ 0 ] || dirname ( __FILE__ ) . '/../src/node_root_certs.h ';
my $ txt = dirname ( __FILE__ ) . '/certdata.txt' ;
my $ stdout = $ crt eq '-' ;
my $ resp ;
my $ fetched ;
unless ( $ opt_n and - e $ txt ) {
print STDERR "Downloading '$txt' ...\n" if ( ! $ opt_q ) ;
my $ ua = new LWP:: UserAgent ( agent = > "$0/$version" ) ;
$ ua - > env_proxy ( ) ;
$ resp = $ ua - > mirror ( $ url , $ txt ) ;
if ( $ resp && $ resp - > code eq '304' ) {
print STDERR "Not modified\n" unless $ opt_q ;
exit 0 if - e $ crt && ! $ opt_f ;
} else {
$ fetched = 1 ;
}
if ( ! $ resp || $ resp - > code !~ /^(?:200|304)$/ ) {
print STDERR "Unable to download latest data: "
. ( $ resp ? $ resp - > code . ' - ' . $ resp - > message : "LWP failed" ) . "\n"
unless $ opt_q ;
exit 1 if - e $ crt || ! - r $ txt ;
}
}
my $ currentdate = scalar gmtime ( $ fetched ? $ resp - > last_modified : ( stat ( $ txt ) ) [ 9 ] ) ;
my $ format = $ opt_t ? "plain text and " : "" ;
if ( $ stdout ) {
open ( CRT , '> -' ) or die "Couldn't open STDOUT: $!\n" ;
} else {
open ( CRT , ">$crt.~ " ) or die "Couldn't open $crt.~ : $!\n" ;
open ( CRT , ">$crt" ) or die "Couldn't open $crt: $!\n" ;
}
print CRT << EOT ;
##
## $crt -- Bundle of CA Root Certificates
##
## Certificate data from Mozilla as of: ${currentdate}
##
## This is a bundle of X.509 certificates of public Certificate Authorities
## (CA). These were automatically extracted from Mozilla's root certificates
## file (certdata.txt). This file can be found in the mozilla source tree:
## ${url}
##
## It contains the certificates in ${format}PEM format and therefore
## can be directly used with curl / libcurl / php_curl, or with
## an Apache+mod_ssl webserver for SSL client authentication.
## Just configure this file as the SSLCACertificateFile.
##
/ * $ crt - - Bundle of CA Root Certificates
*
* Certificate data from Mozilla as of: $ { currentdate }
*
* This is a bundle of X .509 certificates of public Certificate Authorities
* ( CA ) . These were automatically extracted from Mozilla ' s root certificates
* file ( certdata . txt ) . This file can be found in the mozilla source tree:
* $ { url }
*
* It contains the certificates in $ { format } PEM format and therefore
* can be directly used with curl / libcurl / php_curl , or with
* an Apache + mod_ssl webserver for SSL client authentication .
* Just configure this file as the SSLCACertificateFile .
* /
EOT
@ -154,7 +128,7 @@ while (<TXT>) {
next if /^#|^\s*$/ ;
chomp ;
if ( /^CVS_ID\s+\"(.*)\"/ ) {
print CRT "# $1 \n" ;
print CRT "/* $1 */ \n" ;
}
# this is a match for the start of a certificate
@ -192,25 +166,24 @@ while (<TXT>) {
$ skipnum + + ;
} else {
my $ encoded = MIME::Base64:: encode_base64 ( $ data , '' ) ;
$ encoded =~ s/(.{1,${opt_w}})/$1\n/g ;
my $ pem = "-----BEGIN CERTIFICATE-----\n"
$ encoded =~ s/(.{1,${opt_w}})/" $1\\n" \n/g ;
my $ pem = "\" -----BEGIN CERTIFICATE-----\\n\" \n"
. $ encoded
. "-----END CERTIFICATE-----\n" ;
print CRT "\n$caname\n" ;
print CRT ( "=" x length ( $ caname ) . "\n" ) ;
. "\"-----END CERTIFICATE-----\\n\",\n" ;
print CRT "\n/* $caname */\n" ;
if ( ! $ opt_t ) {
print CRT $ pem ;
} else {
my $ pipe = "|$openssl x509 -md5 -fingerprint -text -inform PEM" ;
if ( ! $ stdout ) {
$ pipe . = " >> $crt.~ " ;
close ( CRT ) or die "Couldn't close $crt.~ : $!" ;
$ pipe . = " >> $crt" ;
close ( CRT ) or die "Couldn't close $crt: $!" ;
}
open ( TMP , $ pipe ) or die "Couldn't open openssl pipe: $!" ;
print TMP $ pem ;
close ( TMP ) or die "Couldn't close openssl pipe: $!" ;
if ( ! $ stdout ) {
open ( CRT , ">>$crt.~ " ) or die "Couldn't open $crt.~ : $!" ;
open ( CRT , ">>$crt" ) or die "Couldn't open $crt: $!" ;
}
}
print STDERR "Parsing: $caname\n" if ( $ opt_v ) ;
@ -220,20 +193,7 @@ while (<TXT>) {
}
}
close ( TXT ) or die "Couldn't close $txt: $!\n" ;
close ( CRT ) or die "Couldn't close $crt.~: $!\n" ;
unless ( $ stdout ) {
if ( $ opt_b && - e $ crt ) {
my $ bk = 1 ;
while ( - e "$crt.~${bk}~" ) {
$ bk + + ;
}
rename $ crt , "$crt.~${bk}~" or die "Failed to create backup $crt.~$bk}~: $!\n" ;
} elsif ( - e $ crt ) {
unlink ( $ crt ) or die "Failed to remove $crt: $!\n" ;
}
rename "$crt.~" , $ crt or die "Failed to rename $crt.~ to $crt: $!\n" ;
}
unlink $ txt if ( $ opt_u ) ;
close ( CRT ) or die "Couldn't close $crt: $!\n" ;
print STDERR "Done ($certnum CA certs processed, $skipnum untrusted skipped).\n" if ( ! $ opt_q ) ;
exit ;