From nobody Thu Apr 30 15:04:15 2026 X-Original-To: dev-commits-src-all@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 4g5yB760RLz6c4RN for ; Thu, 30 Apr 2026 15:04:15 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (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 "mxrelay.nyi.freebsd.org", Issuer "R13" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4g5yB73qm4z41FR for ; Thu, 30 Apr 2026 15:04:15 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1777561455; 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; bh=9o8dqPFE//t2B4o+BUsZ5x/ct/8WiF8y/fd3IJu2B50=; b=nIXmPkcWl5eNr1xP18MMkfAaCYRYRA3j8bESlvDJw7Ngj22bENdJ/7yJdwv+B3vRybzVOC oqG4oLVJM3RMUj91K8URzO/IUvvytWUDV0uCpaFNE3QOmBZjqOfrJ3dNP1n+KMEgcmc26q mLkYnZhszjM2bRNrjvS8m64l/0dZhCEI+l3fXvkaltf8ROWv3hUKMfRm6mp7QUgUjKY21s c7Q+IkPiXDJxv3wmQij3zfF3xK7vQ2uaTL6WZF0gSi9BnpeZ1iRwlUii7juMMOfXiTPT/n kk5U8T7nkSAjt6HThDrxCiKbYTl9vI7YuslqPR4DRBpL+7da/jVSE94wocPeyQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1777561455; a=rsa-sha256; cv=none; b=f9M+jlstv8NgBsuflQs9EmEqZ35pgWth8p3v5tz6xdql4u2gTcO0nKRt51nw4IPrqqcUBH bu2W/YMzYuWGC0iB5tQoEbziP1WRpoLMdIKIkcMzgJrXz80JpwhIOdU/nPAdJ0C1EjuQU6 s0NBaXWkURUdFFv28IGdmBmcrwFsKGYgVW39qR+ZA/i2nP1s/bXe8C+kthXnuY3kOcrEqY 9QmWqztPf8NCPRnV/EYsVkDFZHjwM/PHiKucMcRJ93D+LYSxfFjyTLovlJtuMOGYxNTAlL E9PQhVIqkwA7niXp+6bVsHxI8YZUEgA3zumqFjXwaQ78TSLehcOgj6N1gRvcKA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1777561455; 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; bh=9o8dqPFE//t2B4o+BUsZ5x/ct/8WiF8y/fd3IJu2B50=; b=mx0M71OcEKUuE9rUZCJ8KXwQnuTBb6OyiuvpO49hoo3Oxkfo+PLJdDEDwVfLbhaHVz0rMj VuftzhpBfHJS9yNCSwhfZQZBMDJKmP0Ie2c0eyJC28ThUcoKp3IuOcFD74p5ExN6mWXdoE meuS5GfMt3jK9AL6cCIZY+DZishuW3TaW1OqX5EVIVozzXBiI7tf29Sis5NrqIGwYgBDiS 1F5K46hjLjNCd6sAfulA95gdBdNeWmK6+ZDnmlFFNLp2/IEQNNcy01wxnhELcQrlw04d5a TjZ7/VTRCQj62b1oA7VIKMFClL3pa1FMOGGhZrkBm+AkTaimVZLvF64BqSr9JA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4g5yB73Rqqz1VD for ; Thu, 30 Apr 2026 15:04:15 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 18647 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Thu, 30 Apr 2026 15:04:15 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Dag-Erling=?utf-8?Q? Sm=C3=B8rg?=rav Subject: git: ca80ae39e8c6 - stable/14 - caroot: Generate both trusted and untrusted List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: des X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: ca80ae39e8c64a10a7f42a9b127d7472418c60b3 Auto-Submitted: auto-generated Date: Thu, 30 Apr 2026 15:04:15 +0000 Message-Id: <69f36f6f.18647.42633dd7@gitrepo.freebsd.org> The branch stable/14 has been updated by des: URL: https://cgit.FreeBSD.org/src/commit/?id=ca80ae39e8c64a10a7f42a9b127d7472418c60b3 commit ca80ae39e8c64a10a7f42a9b127d7472418c60b3 Author: Dag-Erling Smørgrav AuthorDate: 2025-08-25 21:41:36 +0000 Commit: Dag-Erling Smørgrav CommitDate: 2026-04-30 15:03:09 +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 (cherry picked from commit b88b0bb784c7fdcfb8174806e822c1f8983c223f) --- 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 <) { 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 5e2bb85fc5d2..a50624c10306 100644 --- a/secure/caroot/Makefile +++ b/secure/caroot/Makefile @@ -14,4 +14,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 20d0ccfcbe23..71aca4dcc116 100644 --- a/secure/caroot/trusted/Makefile +++ b/secure/caroot/trusted/Makefile @@ -1,11 +1,11 @@ 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 e5341c978008..0577f3c26994 100644 --- a/secure/caroot/untrusted/Makefile +++ b/secure/caroot/untrusted/Makefile @@ -1,8 +1,11 @@ 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