From 8237b229c676b75f3a3afba84871c4aef5001933 Mon Sep 17 00:00:00 2001 From: Renegade334 Date: Sun, 8 Nov 2026 21:03:53 +0100 Subject: [PATCH] tools: update mk-ca-bundle to 1.35 Adds the facility to ignore root certificates by fingerprint using mk-ca-bundle's -x parameter. Signed-off-by: Renegade334 --- tools/dep_updaters/update-root-certs.mjs | 19 ++++++++-- tools/mk-ca-bundle.pl | 48 ++++++++++++++++++------ 2 files changed, 52 insertions(+), 15 deletions(-) diff --git a/tools/dep_updaters/update-root-certs.mjs b/tools/dep_updaters/update-root-certs.mjs index 80b6fb33f74c..a4cdc1be9863 100644 --- a/tools/dep_updaters/update-root-certs.mjs +++ b/tools/dep_updaters/update-root-certs.mjs @@ -8,6 +8,14 @@ import { pipeline } from 'node:stream/promises'; import { fileURLToPath } from 'node:url'; import { parseArgs } from 'node:util'; +// SHA-256 fingerprints of root certificates to exclude from node-root-certs.h +// Fingerprints can be found in the certificate report at +// https://ccadb.my.salesforce-sites.com/mozilla/IncludedRootCertificateReport +const ignoreRoots = [ + // /* Example Root CA */ + // '0000000000000000000000000000000000000000000000000000000000000000', +]; + const __filename = fileURLToPath(import.meta.url); const getCertdataURL = (version) => { @@ -145,9 +153,14 @@ if (values.verbose) { } const opts = { encoding: 'utf8' }; const mkCABundleTool = join(checkoutDir, 'tools', 'mk-ca-bundle.pl'); -const mkCABundleOut = execFileSync(mkCABundleTool, - values.verbose ? [ '-v' ] : [], - opts); +const mkCABundleArgs = []; +if (values.verbose) { + mkCABundleArgs.push('-v'); +} +if (ignoreRoots.length) { + mkCABundleArgs.push('-x', ignoreRoots.join(',')); +} +const mkCABundleOut = execFileSync(mkCABundleTool, mkCABundleArgs, opts); if (values.verbose) { console.log(mkCABundleOut); } diff --git a/tools/mk-ca-bundle.pl b/tools/mk-ca-bundle.pl index 6763ac52bf20..4911e84d52b3 100755 --- a/tools/mk-ca-bundle.pl +++ b/tools/mk-ca-bundle.pl @@ -37,14 +37,14 @@ use MIME::Base64; use strict; use warnings; -use vars qw($opt_h $opt_i $opt_l $opt_m $opt_p $opt_q $opt_s $opt_t $opt_v $opt_w); +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); use List::Util; use Text::Wrap; # If the OpenSSL commandline is not in search path you can configure it here! my $openssl = 'openssl'; -my $version = '1.33'; +my $version = '1.35'; $opt_w = 72; # default base64 encoded lines length @@ -94,7 +94,7 @@ $0 =~ s@.*(/|\\)@@; $Getopt::Std::STANDARD_HELP_VERSION = 1; -getopts('hilmp:qs:tvw:'); +getopts('hilmp:qs:tvw:x:'); if($opt_i) { print ("=" x 78 . "\n"); @@ -107,7 +107,7 @@ } sub HELP_MESSAGE() { - print "Usage:\t${0} [-i] [-l] [-m] [-p] [-q] [-s] [-t] [-v] [-w] []\n"; + print "Usage:\t${0} [-i] [-l] [-m] [-p] [-q] [-s] [-t] [-v] [-w] [-x] []\n"; print "\t-i\tprint version info about used modules\n"; print "\t-l\tprint license info about certdata.txt\n"; print "\t-m\tinclude meta data in output\n"; @@ -125,6 +125,7 @@ () print "\t-t\tinclude plain text listing of certificates\n"; print "\t-v\tbe verbose and print out processed CAs\n"; print "\t-w \twrap base64 output lines after chars (default: ${opt_w})\n"; + print "\t-x\texclude list of SHA-256 fingerprints. Comma separated, case-insensitive, whitespace and ':' byte delimiters are ignored.\n"; exit; } @@ -202,9 +203,17 @@ (%) my $stdout = $crt eq '-'; +my @opt_x_list; +if($opt_x) { + $opt_x = uc $opt_x; + $opt_x =~ s/[\s:]//g; + @opt_x_list = split(/,/, $opt_x); +} + if($stdout) { open(CRT, '> -') or die "Could not open STDOUT: $!\n"; -} else { +} +else { open(CRT, ">", "$crt.~") or die "Could not open $crt.~: $!\n"; } @@ -356,9 +365,11 @@ (%) if(/^CKA_TRUST_([A-Z_]+)\s+CK_TRUST\s+CKT_NSS_([A-Z_]+)\s*$/) { if(!is_in_list($1, @valid_mozilla_trust_purposes)) { report "Warning: Unrecognized trust purpose for cert: $caname. Trust purpose: $1. Trust Level: $2"; - } elsif(!is_in_list($2, @valid_mozilla_trust_levels)) { + } + elsif(!is_in_list($2, @valid_mozilla_trust_levels)) { report "Warning: Unrecognized trust level for cert: $caname. Trust purpose: $1. Trust Level: $2"; - } else { + } + else { push @{$trust_purposes_by_level{$2}}, $1; } } @@ -380,11 +391,23 @@ (%) } if(!should_output_cert(%trust_purposes_by_level)) { - $skipnum ++; + $skipnum++; report "Skipping: $caname lacks acceptable trust level" if($opt_v); - } elsif($caname =~ /TrustCor/) { - $skipnum ++; - } else { + } + else { + # Skip if explicitly excluded + if($opt_x) { + my ($fingerprint_sha256) = grep { m{^// Fingerprint .*SHA.*256}i } @precert; + $fingerprint_sha256 =~ s/://g; + $fingerprint_sha256 = uc $fingerprint_sha256; + ($fingerprint_sha256) = $fingerprint_sha256 =~ /([A-F0-9]{64})/; + if(grep { $_ eq $fingerprint_sha256 } @opt_x_list) { + report "Skipping: '$main_block_name' fingerprint explicitly excluded: $fingerprint_sha256"; + $skipnum++; + next; + } + } + my $encoded = MIME::Base64::encode_base64($cka_value, ''); $encoded =~ s/(.{1,${opt_w}})/"$1\\n"\n/g; my $pem = "\"-----BEGIN CERTIFICATE-----\\n\"\n" @@ -402,7 +425,8 @@ (%) } if(!$opt_t) { print CRT $pem; - } else { + } + else { my $pipe = ""; foreach my $hash (@included_signature_algorithms) { $pipe = "|$openssl x509 -" . $hash . " -fingerprint -noout -inform PEM";