[TLS] Re: PLANTS and extending TLS Trust Anchor IDs
David Benjamin <davidben@chromium.org> Tue, 07 April 2026 23:20 UTC
Return-Path: <davidben@google.com>
X-Original-To: tls@mail2.ietf.org
Delivered-To: tls@mail2.ietf.org
Received: from localhost (localhost [127.0.0.1]) by mail2.ietf.org (Postfix) with ESMTP id 03114D7C7F29 for <tls@mail2.ietf.org>; Tue, 7 Apr 2026 16:20:01 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ietf.org; s=ietf1; t=1775604001; bh=/y9d4Py3TEgi7hOs/ppnNLnqJ/gSoZ6JqniFIe7fsHo=; h=References:In-Reply-To:From:Date:Subject:To:Cc; b=FqjuHsU6sFGAdQONOnma/K/P7b8zDZQqIN1ji3L84KHuoN+lgtRSwZJme76K+nYbd SvmkgPgAJ958gR3qwhHfatAo0WdqQ+vUxX49MTu21Z6QSiZqvXSu4cuyZc29iAg/Pu /JG0jL7LJJ/XSpVgCTTj23S+11l66mXNqWw4W21I=
X-Virus-Scanned: amavisd-new at ietf.org
X-Spam-Flag: NO
X-Spam-Score: -9.499
X-Spam-Level:
X-Spam-Status: No, score=-9.499 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, USER_IN_DEF_SPF_WL=-7.5] autolearn=ham autolearn_force=no
Authentication-Results: mail2.ietf.org (amavisd-new); dkim=pass (1024-bit key) header.d=chromium.org
Received: from mail2.ietf.org ([166.84.6.31]) by localhost (mail2.ietf.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id d3s0clcOh4qu for <tls@mail2.ietf.org>; Tue, 7 Apr 2026 16:19:59 -0700 (PDT)
Received: from mail-ej1-x632.google.com (mail-ej1-x632.google.com [IPv6:2a00:1450:4864:20::632]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature ECDSA (P-256) server-digest SHA256) (No client certificate requested) by mail2.ietf.org (Postfix) with ESMTPS id A034AD7C7EFE for <tls@ietf.org>; Tue, 7 Apr 2026 16:19:59 -0700 (PDT)
Received: by mail-ej1-x632.google.com with SMTP id a640c23a62f3a-b9910707d82so742868766b.1 for <tls@ietf.org>; Tue, 07 Apr 2026 16:19:59 -0700 (PDT)
ARC-Seal: i=1; a=rsa-sha256; t=1775603998; cv=none; d=google.com; s=arc-20240605; b=edJrQR19gP8CDvwFlbHfH+WIBtOShVhw1Xz5DVO7zqLXpHfLFiYGEbZLpDD2m64Zoz L6n783Wijj4EBj+peqNp+Ij+u2WzpJFuNgto/Fh1krMeVoX5YIx8NmiHVdjgoc+DQFQt iEucjnZAeoeoZm4sFyGvg2iXjL0dmCca/ZkY63uO13uX2aSPKFwb0EAMUqVKp+aXjtme /Fpm3vcBEqmVWRKlRUVU28JTKLlL7uDNV4DJKSOWNNxXIKcQuFAOkpw58bIfXSrMoiOX U5z2P3S2FAmJ2DuoheCWKJtmCWhcNvB31QXPerazRAsus1XACPuy/Ww/qyyXAY7TQ8nS t0/Q==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:dkim-signature; bh=/y9d4Py3TEgi7hOs/ppnNLnqJ/gSoZ6JqniFIe7fsHo=; fh=esLjNc+Q9MNEverTF7oKbS+QMWsl/hBlOHBVOHKSvd8=; b=U3Gf2cM/z7DL/68ra2dYNLouK4ewj2/OpwSRmEnOkFowaPoQK4zf4BoTvcelD8lJl0 zSwxtWPXJDWHYsGGHPirT6qBtySoX4mpBprH/giNKXxBj/PE3S1LAJH8Vahi3gPgt79S v8ZghZcbxcaSAtbGmAcq6YVC5NSOerxWzAEy9zeFs7V378QdYY+hgIbI+udP+IYeWRWK 7dicsiFg0Yxud7ZMIunu5q9oLhW+QP+M/bfFei2hIFxQx1RMgnmOk2xgr4ww3b2j1jEq znJv6SUOw2/3Wh9Z5xKSLuCNSFBNb9ZxfYLCEs06t+x6zHuTSL/TlfVWIhhapt2p+U4U 6lQQ==; darn=ietf.org
ARC-Authentication-Results: i=1; mx.google.com; arc=none
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1775603998; x=1776208798; darn=ietf.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=/y9d4Py3TEgi7hOs/ppnNLnqJ/gSoZ6JqniFIe7fsHo=; b=TU5gM51c5v349D5gTds1qsF1vvQkNAMa5hcYE7y8MEhbeMDiyEOIbTTfZpsCva+1ut UtKgUoEdwycT5KqpAUd0UD+fDonE0sSUlDyX/7ySTOyN9pcJ67/Y2LGnQ1CkSRv0XI80 GJRmIslqAG/aPHto0RvwnilQSAQOmNiLaASfg=
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775603998; x=1776208798; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=/y9d4Py3TEgi7hOs/ppnNLnqJ/gSoZ6JqniFIe7fsHo=; b=ToUZABJPAg7pcZ/SDjyL5muAC5o65b6f+aDjXEd05PbHgJRRZPjVatd/VW8h0s9bau b62wBPN+VOHIVcW17YSqTKAHDs/4MznprWOeBW1oR9LCiOrZWWXMu02CdnvtBtUZKaaB M9nM+wXbgV7A1hjj96g8c4NEpzz1WtDJuILrT6f5vykYodJleluBUK+nXWRNqBzEiXx9 hIpSVtloXHb6mRy9HL+yU1u/5clWx7iW60mul53tBOokVWg/NPdir1K6U+S7NLaUicSX 5sBoNA7BaIB/aGtgIY3QLj4UmeceINg/r6CQZKuX3clWg97wuYSt/TIISRtQwdEQKROo vfug==
X-Gm-Message-State: AOJu0Yy02lQXDa4SvLXJCWweFFtiolfae1ZntUxNfIZCEC/l1CMGc/W4 9Jg6yIvLhB5aof+6/KBXI39ISPEbbksTsY+lTv6M/7tO+Eoj2QifaTYN1fDKmWoyhJkED/pVR+c XvGVMy2pG/zlSjGPb8A8nxirjGjU+x0I6pi4dnjTVKuQLEjoHg8T7vSLeLQ==
X-Gm-Gg: AeBDievYA/W+MuTXy6jFuBw3CRfHiW06iz/bFqFQ3AsmVyUwCvYkd3AOKA31AuWHudv U105k3j+PIfj+cNZAv0FsPsx5n1KCqVNbZ4WEW9/6m6SSWlXowlp3ypCAa6ENLRVt+vPkhxhWfD wapdpQDCWR/DNPd6AaCKMYUtNwBh62MuPv+v5LuDqIEPIlcz3o93hr4qVWhNEHbfctAP3KT0/7H Yj9wdpTOXUo0mdNDwtqddJkLHVEegaR1N8z1pHqmHJ3l57WpIjJ3cK/enOP17f1EPiLaGn6RRek YEzSDouNg9qm7jl65N9uM/vNYzC+O7bhyB0KNl7Is3fhb4OqkhMI3Wsa6P4gb/OlJe/9
X-Received: by 2002:a17:907:3f90:b0:b98:443:6f33 with SMTP id a640c23a62f3a-b9c679f7d01mr739502266b.51.1775603997231; Tue, 07 Apr 2026 16:19:57 -0700 (PDT)
MIME-Version: 1.0
References: <CAF8qwaCeWjVFMxDzZX0aa2QLRjtvfey77xDR7pt_FOy5i=MDOg@mail.gmail.com> <aafbgeYCGMTrs5zo@LK-Perkele-VII2.locald> <CAF8qwaCKiuykw3BokzLqmGJ6id+SgeJS16q1hNdZiK2VzjXTEA@mail.gmail.com> <aah0DqUpsgT35jpf@LK-Perkele-VII2.locald> <CAF8qwaC2UTmkWfD+-3LAfObb6CTYeYcBO_ixnZEZzJVEyvg67w@mail.gmail.com> <aasFxyc0YzQZm6Bc@LK-Perkele-VII2.locald>
In-Reply-To: <aasFxyc0YzQZm6Bc@LK-Perkele-VII2.locald>
From: David Benjamin <davidben@chromium.org>
Date: Tue, 07 Apr 2026 19:19:40 -0400
X-Gm-Features: AQROBzBbQG8qdzbcWq865BGoxU1MRyJacn9mcU9kqIoGfl05F0TGmeTsXlWq1U8
Message-ID: <CAF8qwaBkZiQpHdv9DjE1r1-Ps56YvB3Ai4BO45Z=-omeLq3+Qg@mail.gmail.com>
To: Ilari Liusvaara <ilariliusvaara@welho.com>
Content-Type: multipart/alternative; boundary="000000000000853066064ee70535"
Message-ID-Hash: EIGIQDA3WVKFDWY7KQD3X77ELMA2A7I5
X-Message-ID-Hash: EIGIQDA3WVKFDWY7KQD3X77ELMA2A7I5
X-MailFrom: davidben@google.com
X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-tls.ietf.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header
CC: "<tls@ietf.org>" <tls@ietf.org>
X-Mailman-Version: 3.3.9rc6
Precedence: list
Subject: [TLS] Re: PLANTS and extending TLS Trust Anchor IDs
List-Id: "This is the mailing list for the Transport Layer Security working group of the IETF." <tls.ietf.org>
Archived-At: <https://mailarchive.ietf.org/arch/msg/tls/W_Vu1LjslRO_G03DBW-H4dRB74o>
List-Archive: <https://mailarchive.ietf.org/arch/browse/tls>
List-Help: <mailto:tls-request@ietf.org?subject=help>
List-Owner: <mailto:tls-owner@ietf.org>
List-Post: <mailto:tls@ietf.org>
List-Subscribe: <mailto:tls-join@ietf.org>
List-Unsubscribe: <mailto:tls-leave@ietf.org>
(Sorry about the late reply. I was traveling all of March, and then caught
a cold, so this got buried in my inbox.)
On Fri, Mar 6, 2026, 11:51 Ilari Liusvaara <ilariliusvaara@welho.com> wrote:
> On Fri, Mar 06, 2026 at 07:18:21AM -0500, David Benjamin wrote:
> > On Wed, Mar 4, 2026, 13:04 Ilari Liusvaara <ilariliusvaara@welho.com>
> wrote:
> >
> > > On Wed, Mar 04, 2026 at 10:44:43AM -0500, David Benjamin wrote:
> > > >
> > > > In MTC, landmarks are not global. They're CA-specific and allocated
> per
> > > CA.
> > > > Thus, if your CA is 32473.1, then your landmarks for that CA
> > > > are 32473.1.1, 32473.2, 32473.1.3, etc. A landmark ID specifies
> *both*
> > > the
> > > > landmark *and* the issuer and identifies the thing the relying party
> must
> > > > trust to accept this certificate. That works with TAI as-is without
> any
> > > > fuss.
> > > >
> > > > The invariant this is encoding is simply that, in a CA with 100 live
> > > > landmarks, every client which supports 32473.1.200 can also be
> assumed to
> > > > know about 32473.1.{101-199}. Thus, in a certificate issued by
> > > 32473.1.101,
> > > > the CA can be defined (in the MTC spec) to set trust_anchor =
> 32473.1.101
> > > > and additional_trust_anchor_ranges = 32473.1.{102-200}. Then the
> relying
> > > > party only needs to send 32473.1.{latest-for-this-CA} to capture the
> > > whole
> > > > range.
> > >
> > > 1) If client trusts some landmarks, it probably trusts the parent log
> > > as well (cases where it does not are expected to be exceptional), so
> > > needing to duplicate the parent identifier wastes space.
> > >
> >
> > Indeed. The standalone certificate can probably mark the full range of
> > landmark IDs as aliases and then the client can just send one ID for the
> > whole CA. No duplicate parent identifier.
>
> What does client that trusts some log but has no landmarks for it send?
> X.0?
>
Just X. That's the name for the CA overall.
And there are some discussion about log "generations" in PLANTS (to
> handle the inevitable incidents that bork logs). How would that be
> accommodated?
>
In the model where we try to advertise CAs individual, with log generations
(which still needs to be spec'd), the CA is named X, a single log is X.Y,
and landmark within that log is X.Y.Z. A landmark-relative certificate at
landmark Z of generation Y would configure something like trust_anchor =
X.Y.Z and trust_anchor_aliases = X.Y.(Z+1....). Then any landmark
advertisement of Z or higher would match. Since CAs are only expected to
have one active landmark at a time, I think we don't need to worry about
inter-log-generation advertisements. A relying party only needs to have the
active generation's worth of landmarks configured.
Though it's true that the PR as written is not currently able to express
that a standalone certificate issued by X has an alias of X.*.* because we
only get one wildcard, so that would probably require X on its own to also
be listed. Or we could extend that a bit. Or the certificates can just be
configured with a small window of generation's worth of aliases; after the
certificate expires, you don't care anymore. (How many incidents are you
going to have in 45 days??) So just listing a handful should be plenty.
This also assumes we do an individual-CA-advertisement model. That's very
straightforward when the number of anchors is few enough that we can just
list them all. While TAI does have the (horrible) DNS mechanism, it's never
been a requirement. It's really only there when you aren't able to just
list them all. I think "just list them all" is a much, much better
direction when you can manage it.
*If* you can't manage it, while there is the DNS mechanism, this extension
does actually allow deployments to design bulk trust anchor encoding
schemes in general. As long as you can express the inverse mapping on the
CA -> authenticating party configuration side, that one piece of server
logic can apply. The retry also gives a little tolerance for signalling
inaccuracies as things shift over time. (The trust expressions design had
this complex excluded_labels thing to work around some version skew edge
cases. Those edge cases can instead be handled by a retry. Though those
edge cases are also much fewer with SCTNotAfter-based distrust anyway.
Indeed this idea, trust anchor IDs, and trust expressions all share some
DNA.)
> Data scoping constraints make it difficult for trusted log identifier
> > > sets to not be server-global for initial advertisment, so there can be
> > > more than a few of those.
> >
> >
> > Not sure I follow what you mean by this. (Sorry, I'm probably confused.)
> > The ranges business on the server allows the client to describe its state
> > for each CA with one ID. The client's landmark state in MTC for a given
> CA
> > is independent of which server it's talking to.
>
> Basically, due to how DNS works, the CA info in DNS has to be
> conservative. And this means there can be fair bit of CAs. So the client
> advertisment for each CA should be as compact as possible.
>
> If one counts conservatively, just Let's Encrypt is currently 16(!) CAs.
>
> Then some servers use multiple ACME servers for backup, which multiplies
> the CA count. And since there is no way to tell apart alias sources, if
> there are any oddball CAs used by some domain, those must be included
> too.
>
I'm guessing you're assuming a server deployment that has to fold all
co-hosted target names onto a single DNS configuration, because they've all
been aliased together via CNAMEs and whatnot? I don't think that's a
universal limitation—Cloudflare seems to encourage CNAMEing a hostname-specific
destination
<https://developers.cloudflare.com/dns/zone-setups/partial-setup/>—but yeah
if you're unioning a bunch of disparate origins together, something using
DNS records would requires you to union them together. This isn't really
specific to TAI, rather a general fact about the HTTPS/SVCB design that the
IETF standardized. The more server properties you put into a DNS record,
the less you're able to just alias a bunch of disparate configurations
together. (E.g. if you want names to differ in QUIC support, or ECH
support. or any future SvcParam, you had better be able to differentiate
them at the DNS level.)
Back to the matter at hand, this PR doesn't currently propose to change the
DNS or retry parts, except in that it gives us tools to reduce the need for
the DNS part. The PR still keeps the authenticating party's "I have these
trust anchors available" parts of the design (EE or DNS) as the true IDs of
the trust anchors, since there was less of a need to do anything there. I
think you raise a good point that DNS has a harder time listing the IDs of
the actual trust anchors, so perhaps we should do even more? I think we can
probably explore that separately though. Here I'm just trying to address
the relying party's "I trust these anchors" half. I think it makes sense to
separate them because the better we get at the RP half, the less we have to
care about the DNS scheme at all. It seems to me that only improves the
situation here. (Maybe it's enough of an improvement to not care about DNS
at all? That sure would be nice.)
I'm not sure counting intermediates from CA operator's today is directly
analogous because today's PKIs basically assume there is no cost to
proliferating intermediates. Today, they're not too big, and not pushed to
RPs. But things will look very different for a PQ PKI. Each distinct CA
instance key is a separate, large key that either needs to be pushed to
relying parties, or needs to be sent during the TLS handshake. With Merkle
Tree Certificates, each CA instance in active use is another set of
landmarks that needs to be maintained and provisioned. So I think we can
reasonably expect things to settle at not so many intermediates per
operator in a PQ PKI.
Still, many intermediates doesn't necessarily have to be a problem for this
particular part. Spitballing, if a given CA operator has a whole suite of
intermediates, you could imagine just giving them a versioned identifier
(version is last OID component) that increments when you add new ones. Each
intermediate then is aliased to
(oldest_version_including_that_intermediate, ...) and now the RP can utter
that CA's whole intermediate set with one ID. That can be expressed by this
PR just as easily as the MTC landmarks thing.
> > 2) The client could send 32473.{1-3}. If the server implements ranges
> > > as lexicographic compares, this goes badly wrong, as it will match any
> > > landmark issued by 32473.1 or 32473.2, even ones too new for the
> > > client.
> >
> >
> > 3) And even if client only uses ranges for landmarks, the lexicographic
> > > compares go wrong in some edge cases (crossing to 2^14, 2^21, 2^28,
> > > ...). If log issues landmarks once per hour, it takes about 22 months
> to
> > > reach 2^14.
> > >
> >
> > Hmm. I think there might still be a misunderstanding here? Or maybe I'm
> > confused (pretty often true!). The proposal is not that the client sends
> > ranges. A client sends one ID and the server has information on each cert
> > (from the CA ideally) for whether that ID matches the cert.
> >
> > Basically the CA tells the server "these are the conditions that can
> > activate this cert". (In BoringSSL, we've modeled cert selection as an
> > ordered preference list of "credentials". The TLS stack iterates over the
> > credentials and picks the first usable one. "Usable" includes things like
> > sigalg negotiation, etc. And then if you set the must_match_issuer flag
> on
> > the credential, we will require *some* signal of matching trust anchor,
> be
> > it TAI or certificate_authorities or whatever else we end up doing. Under
> > that model, trust anchor negotiation boils down to knowing when to say
> yes
> > to this question.)
>
> Well, this needs new extension for signaling anyway.
> Certificate_authorities
> does not support recovering from DNS signaling failure (and is more
> verbose than needed, which is an issue due to number of CAs).
>
> Then trying to extend the X.509 negotiation in TLS servers to MTC can be
> a major mess. E.g., it would be a non-starter in TLS library I have
> written (it would need to be fourth(!) certificate negotiation).
>
Hmm, I'm not sure I follow what you're saying.
Not sure I see the connection to certificate_authorities's lack of
signaling recovery. This PR is about trust anchor IDs.
BoringSSL's must_match_issuer flag indeed checks both.
Since certificate_authorities doesn't tolerate signaling failure, the
authenticating party can reasonably assume that, if the RP was willing to
send certificate_authorities, it indeed trusts the listed CAs. Of
course, certificate_authorities has the limitations you describe, but
that's why we're here. :-) BoringSSL just keys it on the same credential
flag because, the only meaningful application-level semantics is to
distinguish between "this candidate credential is a fallback option" and
"this candidate credential is a issuer-gated option".
What is the "this" that would need a new extension? Negotiating based on
Trust anchor IDs indeed needs a trust anchor IDs extension. Or are you
saying this particular modification to trust anchor IDs needs a new
extension? Why would it? Mechanically, the proposal is to merge it into the
trust anchor IDs draft anyway, which we're still working on. But it's also
compatible in that the relying party message doesn't change. We're just
widening the authenticating party's matching function. (Relying parties do
not send ranges in this PR. They still send singular IDs. Just now some of
those IDs can represent multiple trust anchors, and then we provision the
authenticating party with the inverse mapping: the authenticating party
knows which multi-anchor IDs matches each candidate certificate.)
> And then there are some edge cases, like all MTC certificates ignoring
> signature_algorithms_cert.
>
Adding an MTC sigalgs_cert codepoint is easy enough and, yeah, I expect
we'll need one of those. Though in my experience, sigalgs_cert negotiation
is not very widely used or depended on. In a world with trust anchor
negotiation, it's basically redundant—if I know you trust *this* ML-DSA CA,
I implicitly know you support ML-DSA. In a world without trust anchor
negotiation, sigalgs_cert has never been enough—knowing you support ML-DSA
doesn't tell me you support *this* ML-DSA CA.
> OIDs are a varint encoding, but it's not terribly complicated. (It's just
> > base 128 with the high bit telling you if you're at the end.) I made sure
> > to spell out the exact routine to help people out here, so they can just
> > transcribe that.
>
> How to perform range compare against what client sent? There is simple-
> looking way to do that, but it does not actually work correctly.
>
> How I would implement it is doing prefix strip followed by decoding the
> remainder as integer and then doing range contains. Which is at least
> correct, but very different from what the document seems to specify.
>
Oh? It certainly was meant to be exactly that. I took another look and that
seems to be correct. Where are you seeing the discrepancy? (Steps 1-2 are
the prefix strip. Step 3 decodes the remainder as an integer. Step 4 is the
range contains.)
David
- [TLS] PLANTS and extending TLS Trust Anchor IDs David Benjamin
- [TLS] Re: PLANTS and extending TLS Trust Anchor I… Ilari Liusvaara
- [TLS] Re: PLANTS and extending TLS Trust Anchor I… David Benjamin
- [TLS] Re: PLANTS and extending TLS Trust Anchor I… Ilari Liusvaara
- [TLS] Re: PLANTS and extending TLS Trust Anchor I… David Benjamin
- [TLS] Re: PLANTS and extending TLS Trust Anchor I… Ilari Liusvaara
- [TLS] Re: PLANTS and extending TLS Trust Anchor I… David Benjamin
- [TLS] Re: PLANTS and extending TLS Trust Anchor I… Ilari Liusvaara
- [TLS] Re: PLANTS and extending TLS Trust Anchor I… David Benjamin