3737use MIME::Base64;
3838use strict;
3939use warnings;
40- use vars qw( $opt_h $opt_i $opt_l $opt_m $opt_p $opt_q $opt_s $opt_t $opt_v $opt_w) ;
40+ use vars qw( $opt_h $opt_i $opt_l $opt_m $opt_p $opt_q $opt_s $opt_t $opt_v $opt_w $opt_x ) ;
4141use List::Util;
4242use Text::Wrap;
4343
4444# If the OpenSSL commandline is not in search path you can configure it here!
4545my $openssl = ' openssl' ;
4646
47- my $version = ' 1.33 ' ;
47+ my $version = ' 1.35 ' ;
4848
4949$opt_w = 72; # default base64 encoded lines length
5050
9494
9595$0 =~ s @ .*(/|\\ )@@ ;
9696$Getopt::Std::STANDARD_HELP_VERSION = 1;
97- getopts(' hilmp:qs:tvw:' );
97+ getopts(' hilmp:qs:tvw:x: ' );
9898
9999if ($opt_i ) {
100100 print (" =" x 78 . " \n " );
107107}
108108
109109sub HELP_MESSAGE () {
110- print " Usage:\t ${0} [-i] [-l] [-m] [-p<purposes:levels>] [-q] [-s<algorithms>] [-t] [-v] [-w<l>] [<outputfile>]\n " ;
110+ print " Usage:\t ${0} [-i] [-l] [-m] [-p<purposes:levels>] [-q] [-s<algorithms>] [-t] [-v] [-w<l>] [-x<sha256>] [ <outputfile>]\n " ;
111111 print " \t -i\t print version info about used modules\n " ;
112112 print " \t -l\t print license info about certdata.txt\n " ;
113113 print " \t -m\t include meta data in output\n " ;
125125 print " \t -t\t include plain text listing of certificates\n " ;
126126 print " \t -v\t be verbose and print out processed CAs\n " ;
127127 print " \t -w <l>\t wrap base64 output lines after <l> chars (default: ${opt_w} )\n " ;
128+ print " \t -x\t exclude list of SHA-256 fingerprints. Comma separated, case-insensitive, whitespace and ':' byte delimiters are ignored.\n " ;
128129 exit ;
129130}
130131
202203
203204my $stdout = $crt eq ' -' ;
204205
206+ my @opt_x_list ;
207+ if ($opt_x ) {
208+ $opt_x = uc $opt_x ;
209+ $opt_x =~ s / [\s :]// g ;
210+ @opt_x_list = split (/ ,/ , $opt_x );
211+ }
212+
205213if ($stdout ) {
206214 open (CRT, ' > -' ) or die " Could not open STDOUT: $! \n " ;
207- } else {
215+ }
216+ else {
208217 open (CRT, " >" , " $crt .~" ) or die " Could not open $crt .~: $! \n " ;
209218}
210219
280289 # The commented lines in a main block are plaintext metadata that describes
281290 # the certificate. Issuer, Subject, Fingerprint, etc.
282291 if ($main_block ) {
283- push @precert , s { ^#} { //} r if not /^# $/;
292+ push @precert , s { ^#} { //} r unless / ^#$ / ;
284293 if (/ ^# Not Valid After : (.*)/ ) {
285294 my $stamp = $1 ;
286295 use Time::Piece;
356365 if (/ ^CKA_TRUST_([A-Z_]+)\s +CK_TRUST\s +CKT_NSS_([A-Z_]+)\s *$ / ) {
357366 if (!is_in_list($1 , @valid_mozilla_trust_purposes )) {
358367 report " Warning: Unrecognized trust purpose for cert: $caname . Trust purpose: $1 . Trust Level: $2 " ;
359- } elsif (!is_in_list($2 , @valid_mozilla_trust_levels )) {
368+ }
369+ elsif (!is_in_list($2 , @valid_mozilla_trust_levels )) {
360370 report " Warning: Unrecognized trust level for cert: $caname . Trust purpose: $1 . Trust Level: $2 " ;
361- } else {
371+ }
372+ else {
362373 push @{$trust_purposes_by_level {$2 }}, $1 ;
363374 }
364375 }
@@ -380,11 +391,23 @@ (%)
380391 }
381392
382393 if (!should_output_cert(%trust_purposes_by_level )) {
383- $skipnum ++;
394+ $skipnum ++;
384395 report " Skipping: $caname lacks acceptable trust level" if ($opt_v );
385- } elsif ($caname =~ / TrustCor/ ) {
386- $skipnum ++;
387- } else {
396+ }
397+ else {
398+ # Skip if explicitly excluded
399+ if ($opt_x ) {
400+ my ($fingerprint_sha256 ) = grep { m { ^// Fingerprint .*SHA.*256} i } @precert ;
401+ $fingerprint_sha256 =~ s / :// g ;
402+ $fingerprint_sha256 = uc $fingerprint_sha256 ;
403+ ($fingerprint_sha256 ) = $fingerprint_sha256 =~ / ([A-F0-9]{64})/ ;
404+ if (grep { $_ eq $fingerprint_sha256 } @opt_x_list ) {
405+ report " Skipping: '$main_block_name ' fingerprint explicitly excluded: $fingerprint_sha256 " ;
406+ $skipnum ++;
407+ next ;
408+ }
409+ }
410+
388411 my $encoded = MIME::Base64::encode_base64($cka_value , ' ' );
389412 $encoded =~ s / (.{1,${opt_w}})/ "$1 \\ n"\n / g ;
390413 my $pem = " \" -----BEGIN CERTIFICATE-----\\ n\"\n "
402425 }
403426 if (!$opt_t ) {
404427 print CRT $pem ;
405- } else {
428+ }
429+ else {
406430 my $pipe = " " ;
407431 foreach my $hash (@included_signature_algorithms ) {
408432 $pipe = " |$openssl x509 -" . $hash . " -fingerprint -noout -inform PEM" ;
0 commit comments