From nobody Mon Aug 25 22:30:39 2025 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4c9lqj0YWLz65lQC; Mon, 25 Aug 2025 22:30:41 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from smtp.freebsd.org (smtp.freebsd.org [96.47.72.83]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "smtp.freebsd.org", Issuer "R13" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4c9lqh623gz3Wkn; Mon, 25 Aug 2025 22:30:40 +0000 (UTC) (envelope-from kevans@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1756161040; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=oLt8c5wGHNs1B8x0McG/tY9BVmsUjFtBzE9YgCBGcBs=; b=Z3rZMjFUawuFtw4Sz2UaLmQaKCF+PRP8n7eLjfaNIobctNS4fZWACRrGgMy1B9VDJQJXbu nFJcD9W2bQ9k0XtUJI1LmRp8JE2LjYybYH1Qf/lupEkWm9gPpyIsH8egi/toNdHYz8mSPa MBN4Zm+BMlFYeuGG2ZAa++FQjuTTy3YO33xTdeAjEADI93eyrtO/qhc8sZGW6/YjIiPLt7 /vpWdVo4cfleoONH1yfb0LUhzlqCt9+DGn6znSHVHQetjEKmPt8G5TGps8smYndoirjjV2 vXjYwGkv26+4mCT/nSm+kjVVj5/oBnTwysx+wjtHbNAdKRPnIhpU0y2sokuGDA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1756161040; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=oLt8c5wGHNs1B8x0McG/tY9BVmsUjFtBzE9YgCBGcBs=; b=Jj5JdREsb9yh+gpIOY7hm+3ILeyYYmVeQhVF8QFEztJzjNYFyyg2N5CdIgr7ufk6qWCOdW CbBjdu6kuN4zxZBGWG/3NDWmn7X0KgpueYFqOIlGrIrWDiNGEUoNlWJTTvJ41kto3aPLYf vEmLDgkQDOuccUhh8uH1KTrBt32YUwNvnWixjcavrldwDbIjEO6MYwDgbK74cdY3hqlMDq Z3lBxCa7SPwo+Up5FK3BgcY6rC1wsxCV5xTpeqa9X+NTOCWh9qZRfIstc6k3UcHt2yTpmi zcwaYSwhkMkZPzVZmRtPvTkDwhD0JbPSlKbQCM5gB4SZCJjXPhdCTeM2wEXw2Q== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1756161040; a=rsa-sha256; cv=none; b=II45Vx0STabEhkrQNt/nJQQxmNeRCMk03PBms0+Ps20O8LO4F3/g80jkS9ujNU1+dyf5bJ 1wy1ZwRfHybnXmnC11S8OaMyu6IT0hti/fSdRIDqRJjYn0ITPp3gtfaU7sFkmlGDLVcfsX ZhkrrQuwb4nBF0d6yX1m+znwBO4QupXf4BG3E67WevOQf+pgXOrVq930jsj/TtjmvQgYaH +IVhzRP6IuFM8+unx9mwZwhg7UdvtywUIsdAznaRX2wmCmJJevx2e2CAGJNXP4687KZljy rIQ6tCi4uAKHM4IF9AAW3b4aeFjHDpnHVvURBy8at6BY3ujPH/HJ8LRhSMst+A== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from [10.9.4.95] (unknown [209.182.120.176]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) (Authenticated sender: kevans/mail) by smtp.freebsd.org (Postfix) with ESMTPSA id 4c9lqh2wmNzBQf; Mon, 25 Aug 2025 22:30:40 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Message-ID: Date: Mon, 25 Aug 2025 17:30:39 -0500 List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: git: b88b0bb784c7 - main - caroot: Generate both trusted and untrusted To: =?UTF-8?Q?Dag-Erling_Sm=C3=B8rgrav?= , src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org References: <202508252142.57PLgh5i068682@gitrepo.freebsd.org> Content-Language: en-US From: Kyle Evans In-Reply-To: <202508252142.57PLgh5i068682@gitrepo.freebsd.org> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit On 8/25/25 16:42, Dag-Erling Smørgrav wrote: > The branch main has been updated by des: > > URL: https://cgit.FreeBSD.org/src/commit/?id=b88b0bb784c7fdcfb8174806e822c1f8983c223f > > commit b88b0bb784c7fdcfb8174806e822c1f8983c223f > Author: Dag-Erling Smørgrav > AuthorDate: 2025-08-25 21:41:36 +0000 > Commit: Dag-Erling Smørgrav > CommitDate: 2025-08-25 21:41:36 +0000 > > caroot: Generate both trusted and untrusted > > Until now, the untrusted directory has been maintained manually. Modify > the script used to maintain the trusted directory so it can handle both. > While here, clean it up a bit. > > MFC after: 1 week > Reviewed by: mandree, markj > Differential Revision: https://reviews.freebsd.org/D51774 > --- That's great, thanks! I do notice one case if I run this today: deleted: trusted/Baltimore_CyberTrust_Root.pem This would traditionally get moved (by me) into untrusted/ so that `certctl rehash` would do the right thing, but... I started typing this out and realized that we would have removed the contents of /etc/ssl/certs before rehashing so that stale entries don't stick around, and the source certs in /usr/share/certs/trusted should be in ObsoleteFiles.inc and removed by `make delete-old`. We should probably call bankruptcy on the untrusted/ dir entirely and regenerate it completely from today's world with our next update, and update README in secure/caroot to avoid recommending silly practices. > secure/caroot/MAca-bundle.pl | 136 ++++++++++++--------------------------- > secure/caroot/Makefile | 3 +- > secure/caroot/trusted/Makefile | 6 +- > secure/caroot/untrusted/Makefile | 5 +- > 4 files changed, 51 insertions(+), 99 deletions(-) > > diff --git a/secure/caroot/MAca-bundle.pl b/secure/caroot/MAca-bundle.pl > index 58cfe1cbf6fa..411d00b9bb61 100755 > --- a/secure/caroot/MAca-bundle.pl > +++ b/secure/caroot/MAca-bundle.pl > @@ -8,6 +8,7 @@ > ## Copyright (c) 2011, 2013 Matthias Andree > ## All rights reserved. > ## Copyright (c) 2018, Allan Jude > +## Copyright (c) 2025 Dag-Erling Smørgrav > ## > ## Redistribution and use in source and binary forms, with or without > ## modification, are permitted provided that the following conditions are > @@ -34,6 +35,7 @@ > ## POSSIBILITY OF SUCH DAMAGE. > > use strict; > +use warnings; > use Carp; > use MIME::Base64; > use Getopt::Long; > @@ -44,10 +46,12 @@ my $generated = '@' . 'generated'; > my $inputfh = *STDIN; > my $debug = 0; > my $infile; > -my $outputdir; > +my $trustdir = "trusted"; > +my $untrustdir = "untrusted"; > my %labels; > my %certs; > my %trusts; > +my %expires; > > $debug++ > if defined $ENV{'WITH_DEBUG'} > @@ -56,8 +60,9 @@ $debug++ > GetOptions ( > "debug+" => \$debug, > "infile:s" => \$infile, > - "outputdir:s" => \$outputdir) > - or die("Error in command line arguments\n$0 [-d] [-i input-file] [-o output-dir]\n"); > + "trustdir:s" => \$trustdir, > + "untrustdir:s" => \$untrustdir) > + or die("Error in command line arguments\n$0 [-d] [-i input-file] [-t trust-dir] [-u untrust-dir]\n"); > > if ($infile) { > open($inputfh, "<", $infile) or die "Failed to open $infile"; > @@ -68,8 +73,7 @@ sub print_header($$) > my $dstfile = shift; > my $label = shift; > > - if ($outputdir) { > - print $dstfile < + print $dstfile < ## > ## $label > ## > @@ -77,38 +81,17 @@ sub print_header($$) > ## Authority (CA). It was automatically extracted from Mozilla's > ## root CA list (the file `certdata.txt' in security/nss). > ## > -## It contains a certificate trusted for server authentication. > -## > -## Extracted from nss > -## > ## $generated > ## > EOFH > - } else { > - print $dstfile < -## > -## ca-root-nss.crt -- Bundle of CA Root Certificates > -## > -## This is a bundle of X.509 certificates of public Certificate > -## Authorities (CA). These were automatically extracted from Mozilla's > -## root CA list (the file `certdata.txt'). > -## > -## It contains certificates trusted for server authentication. > -## > -## Extracted from nss > -## > -## $generated > -## > -EOH > - } > } > > sub printcert($$$) > { > my ($fh, $label, $certdata) = @_; > return unless $certdata; > - open(OUT, "|openssl x509 -text -inform DER -fingerprint") > - or die "could not pipe to openssl x509"; > + open(OUT, "|-", qw(openssl x509 -text -inform DER -fingerprint)) > + or die "could not pipe to openssl x509"; > print OUT $certdata; > close(OUT) or die "openssl x509 failed with exit code $?"; > } > @@ -118,13 +101,11 @@ sub printcert($$$) > sub graboct($) > { > my $ifh = shift; > - my $data; > + my $data = ""; > > while (<$ifh>) { > last if /^END/; > - my (undef,@oct) = split /\\/; > - my @bin = map(chr(oct), @oct); > - $data .= join('', @bin); > + $data .= join('', map { chr(oct($_)) } m/\\([0-7]{3})/g); > } > > return $data; > @@ -158,18 +139,8 @@ sub grabcert($) > { > my $distrust_after = graboct($ifh); > my ($year, $mon, $mday, $hour, $min, $sec) = unpack "A2A2A2A2A2A2", $distrust_after; > - $distrust_after = timegm_posix( $sec, $min, $hour, $mday, $mon - 1, $year + 100); > - my $time_now = time; > - # When a CA is distrusted before its NotAfter date, issued certificates > - # are valid for a maximum of 398 days after that date. > - if ($time_now >= $distrust_after + 398 * 24 * 60 * 60) { $distrust = 1; } > - if ($debug) { > - printf STDERR "line $.: $cka_label ser #%d: distrust 398 days after %s, now: %s -> distrust $distrust\n", $serial, > - strftime("%FT%TZ", gmtime($distrust_after)), strftime("%FT%TZ", gmtime($time_now)); > - } > - if ($distrust) { > - return undef; > - } > + $distrust_after = timegm_posix($sec, $min, $hour, $mday, $mon - 1, $year + 100); > + $expires{$cka_label."\0".$serial} = $distrust_after; > } > } > return ($serial, $cka_label, $certdata); > @@ -194,8 +165,7 @@ sub grabtrust($) { > $serial = graboct($ifh); > } > > - if (/^CKA_TRUST_SERVER_AUTH CK_TRUST (\S+)$/) > - { > + if (/^CKA_TRUST_SERVER_AUTH CK_TRUST (\S+)$/) { > if ($1 eq 'CKT_NSS_NOT_TRUSTED') { > $distrust = 1; > } elsif ($1 eq 'CKT_NSS_TRUSTED_DELEGATOR') { > @@ -216,12 +186,6 @@ sub grabtrust($) { > return ($serial, $cka_label, $trust); > } > > -if (!$outputdir) { > - print_header(*STDOUT, ""); > -} > - > -my $untrusted = 0; > - > while (<$inputfh>) { > if (/^CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE/) { > my ($serial, $label, $certdata) = grabcert($inputfh); > @@ -229,12 +193,10 @@ while (<$inputfh>) { > warn "Certificate $label duplicated!\n"; > } > if (defined $certdata) { > - $certs{$label."\0".$serial} = $certdata; > - # We store the label in a separate hash because truncating the key > - # with \0 was causing garbage data after the end of the text. > - $labels{$label."\0".$serial} = $label; > - } else { # $certdata undefined? distrust_after in effect > - $untrusted ++; > + $certs{$label."\0".$serial} = $certdata; > + # We store the label in a separate hash because truncating the key > + # with \0 was causing garbage data after the end of the text. > + $labels{$label."\0".$serial} = $label; > } > } elsif (/^CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST/) { > my ($serial, $label, $trust) = grabtrust($inputfh); > @@ -254,52 +216,38 @@ sub label_to_filename(@) { > return wantarray ? @res : $res[0]; > } > > -# weed out untrusted certificates > -foreach my $it (keys %trusts) { > - if (!$trusts{$it}) { > - if (!exists($certs{$it})) { > - warn "Found trust for nonexistent certificate $labels{$it}\n" if $debug; > - } else { > - delete $certs{$it}; > - warn "Skipping untrusted $labels{$it}\n" if $debug; > - $untrusted++; > - } > - } > -} > - > -if (!$outputdir) { > - print "## Untrusted certificates omitted from this bundle: $untrusted\n\n"; > -} > -print STDERR "## Untrusted certificates omitted from this bundle: $untrusted\n"; > +my $untrusted = 0; > +my $trusted = 0; > +my $now = time; > > -my $certcount = 0; > foreach my $it (sort {uc($a) cmp uc($b)} keys %certs) { > my $fh = *STDOUT; > + my $outputdir; > my $filename; > - if (!exists($trusts{$it})) { > - die "Found certificate without trust block,\naborting"; > - } > - if ($outputdir) { > - $filename = label_to_filename($labels{$it}); > - open($fh, ">", "$outputdir/$filename") or die "Failed to open certificate $filename"; > - print_header($fh, $labels{$it}); > + if (exists($expires{$it}) && > + $now >= $expires{$it} + 398 * 24 * 60 * 60) { > + print(STDERR "## Expired: $labels{$it}\n"); > + $outputdir = $untrustdir; > + $untrusted++; > + } elsif (!$trusts{$it}) { > + print(STDERR "## Untrusted: $labels{$it}\n"); > + $outputdir = $untrustdir; > + $untrusted++; > + } else { > + print(STDERR "## Trusted: $labels{$it}\n"); > + $outputdir = $trustdir; > + $trusted++; > } > + $filename = label_to_filename($labels{$it}); > + open($fh, ">", "$outputdir/$filename") or die "Failed to open certificate $outputdir/$filename"; > + print_header($fh, $labels{$it}); > printcert($fh, $labels{$it}, $certs{$it}); > if ($outputdir) { > close($fh) or die "Unable to close: $filename"; > } else { > print $fh "\n\n\n"; > } > - $certcount++; > - print STDERR "Trusting $certcount: $labels{$it}\n" if $debug; > } > > -if ($certcount < 25) { > - die "Certificate count of $certcount is implausibly low.\nAbort"; > -} > - > -if (!$outputdir) { > - print "## Number of certificates: $certcount\n"; > - print "## End of file.\n"; > -} > -print STDERR "## Number of certificates: $certcount\n"; > +printf STDERR "## Trusted certificates: %4d\n", $trusted; > +printf STDERR "## Untrusted certificates: %4d\n", $untrusted; > diff --git a/secure/caroot/Makefile b/secure/caroot/Makefile > index ace802a906a3..d48285437f10 100644 > --- a/secure/caroot/Makefile > +++ b/secure/caroot/Makefile > @@ -13,4 +13,5 @@ cleancerts: .PHONY > @${MAKE} -C ${.CURDIR}/trusted ${.TARGET} > > updatecerts: .PHONY cleancerts fetchcerts > - perl ${.CURDIR}/MAca-bundle.pl -i certdata.txt -o ${.CURDIR}/trusted > + perl ${.CURDIR}/MAca-bundle.pl -i certdata.txt \ > + -t ${.CURDIR}/trusted -u ${.CURDIR}/untrusted > diff --git a/secure/caroot/trusted/Makefile b/secure/caroot/trusted/Makefile > index b2fe43fcb802..a47e781262b8 100644 > --- a/secure/caroot/trusted/Makefile > +++ b/secure/caroot/trusted/Makefile > @@ -1,10 +1,10 @@ > BINDIR= /usr/share/certs/trusted > > -TRUSTED_CERTS!= echo ${.CURDIR}/*.pem 2> /dev/null || true > +TRUSTED_CERTS!= (cd ${.CURDIR} && echo *.pem) > > FILES+= ${TRUSTED_CERTS} > > -cleancerts: > - @[ -z "${TRUSTED_CERTS}" ] || rm ${TRUSTED_CERTS} > +cleancerts: .PHONY > + @(cd ${.CURDIR} && rm -f ${TRUSTED_CERTS}) > > .include > diff --git a/secure/caroot/untrusted/Makefile b/secure/caroot/untrusted/Makefile > index 19d7359ddcb9..45df0a55ebd9 100644 > --- a/secure/caroot/untrusted/Makefile > +++ b/secure/caroot/untrusted/Makefile > @@ -1,7 +1,10 @@ > BINDIR= /usr/share/certs/untrusted > > -UNTRUSTED_CERTS!= echo ${.CURDIR}/*.pem 2> /dev/null || true > +UNTRUSTED_CERTS!= (cd ${.CURDIR} && echo *.pem) > > FILES+= ${UNTRUSTED_CERTS} > > +cleancerts: .PHONY > + @(cd ${.CURDIR} && rm -f ${UNTRUSTED_CERTS}) > + > .include