Add accumulated log entry type - #172
Conversation
|
Hmm, so purely mechanically, we can't add a field to the overall entry struct like this without updating the certificate format with the accumulated count. Otherwise the verifier cannot reconstruct things. Do you have an example of use that would need the count and two layers of extensibility? Naively I would have assumed one could just extend the top-level entry type when adding new kinds of entries, though that doesn't categorize things into accumulator and normal entries. |
The purpose of the count is to make it easy to find the n^th or the most recent accumulator log entry, through something like binary search. To kind of summarize the argument:
I don't really want the second layer of extensibility, I just don't want to define the format for this object right now / in this document.
I can add the counter to |
|
It'd be great to have a mechanism to bind important extensions such as verifiable indices. The present proposal is quite heavy handed though: the counter feels out of place on every Few scattershot remarks:
Probably just having the AP pull the landmark tree heads from multiple (mirrors of) root programs is simplest. It'd be nice though to have a distributed way to generate a log of all tree heads of all CAs (cf. CTNG broadcast protocol), so we'd have only one tree head to gossip, but it's not obvious at all how to make that work across root programs, and prevent bad behaviour if opening up completely. Perhaps the list is a better place than a PR to discuss this. |
What goes into an accumulated log entry is TBD
I'm only considering the gossip that happens when a server presents a signatureless certificate and the client accepts it. Arbitrary Verifiable Index tree heads may get put in the accumulated log entry, if that's what you mean.
I'm not proposing that either of these be done
I haven't looked into how landmarks are defined yet, but I expect it's just an arbitrary demarcation. Which goes back to "you need a trusted party to tell you what they are", which is a different (weaker) security model than what this provides. With this, there are no trusted third parties. That seems worth it for 8 bytes! |
|
The references to a better security model, etc., here, are hard for me to follow. Ultimately this PR doesn't provide a security improvement in itself, rather some secondary extension points on an already extensible system, with the aim that something not yet defined will improve security. I'm still quite unclear on this not-yet-defined thing. AIUI, the root issue is that you dismiss the cosigner-based threat model of the, currently orthogonal, vindex work that the transparency.dev community is working on? And so the claim is that this not-yet-defined will somehow provide something stronger, but we haven't written down what this not-yet-defined thing is, or what the other trade-offs will be. Without any of those details to evaluate, I don't think we can usefully use that not-yet-defined thing to reason about whether this PR makes sense. I suspect there are likely more straightforward schemes here, but there isn't enough information here, and it's probably a much larger discussion than an extension point in a PR. For example:
Looking at this purely as an extension point, it seems more-or-less redundant with the extension points that already exist. First, this introduces a second layer of extensibility, AccumulatedType, on top of an already extensible structure, MerkleTreeCertEntryType. If the goal was to make it possible to add new entry types, that wasn't needed. Now, AccumulatedTypes are special in this PR, in that they contribute to a per-entry count. I am not quite following how you want to use the binary search (see above), or your overall system, but it seems like this wouldn't work? If a log uses multiple AccumulatedTypes, the count would cover all of them, so you'd still have to potentially do a lot of work to find the one that you want, no? Then there's the problem how to do per-entry extensions. As noted, it needs to be echo'd back into the certificate. Putting it into the MTCProof would solve that mechanically, but it's redundant with a mechanism that already exists: non-critical X.509 extensions. Rather than all this, it seems you could instead just use one of those. That is entry-type-dependent, so it's a little messy and maybe there's a discussion to be had about how best to structure an individual entry, but my feeling is we should start simple. Finally keep in mind that, for all changes that involve adding to what a CA does when it constructs a log, there is already a natural extension point: the CA itself. If you change the responsibilities of a CA, you will likely need to spin up a new CA instance and do CA-level migration (e.g. trust anchor negotiation). At that point you can always key a v2 entry format, or a new set of entry types, new client behavior, etc., on that new CA. Indeed that's the very extension point that makes a MTCs, PQC, etc., viable. |
Well, yes, but that's because you wanted monitoring to be a secondary deliverable. So it's not defined here. I'm happy to talk more about the security model I described in my first comment offline if you'd like?
I'm not dismissing it, but I think it's worth considering the security model of monitoring. What you seem to have in mind is a Verifiable Index system where the cosigners are unrelated / orthogonal to CAs. I'm loath to add more trusted parties to the webPKI when it's so easy to avoid here.
It's servers that do the binary search. They would do it as part of monitoring, so it would be offline. Browsers only see the extra 8 bytes.
Yes, the assumption is already that some anonymous person is/will tail the log and check the vindex for correctness. The core issue with doing it the way you say is authenticating negative results, i.e. when there are no accumulators. Because this is going in an extension point regardless, the CA can't be assumed to support it! So if you can just tell me "there are no accumulators in this CA, fall back to the collusion-secure system" and I have to trust you or download the whole log to prove you wrong -- that would seem to defeat the point. With a counter approach, if the counter is zero, then you know there are no accumulator log entries. I think it's also worth pointing out that what you're proposing is just a lot more operationally complicated. Like I mentioned, we'd need some way to convey to servers whether a CA supports this extension or not. But also, you have to commit upfront to this parameter of "every 1024 entries" or something, and accept edge cases where that may be way too frequent or infrequent. The counter approach adjusts nicely to changes in demand.
My goal here was of course to keep it very simple. CAs can hardcode the counter to be 0 until they actually support any accumulator types. I hope this helps the PR make more sense. I think a call with either of you would actually be better than going to the mailing list but let me know :) |
|
Am somewhat swamped right now (there's a reason we said to do these kinds of addons separately :-P), but real quick...
I'm confused. Is that the only reason for this? Surely the verifier, as part of configuring all the known CAs and their keys, can simply configure whether the CA has promised to implement this extension or not. |
|
I think this is only true from a client perspective, servers just use whatever gets pushed down from ACME. So a server wouldn't necessarily trust all the CAs that it uses / have trustworthy sources of information about them. A server generally also wouldn't have a list of "all" CAs. It's not relevant to this PR but building on the above point, I see monitoring working by either having all CAs aggregated into individual vindexes, or there being some kind of verifiable discovery step for all the CAs trusted by a particular client. You wouldn't want it to be the case that the server has to have it's own view of what CAs it thinks Samsung TV accepts, where an inaccurate/out-of-date view causes monitoring misses. |
473bfa2 to
1e5968a
Compare
Going back to this idea, why doesn't this work? Landmarks are allocated on a strict cadence (one per landmark interval, Section 6.3.2). Every time it allocates a landmark, the CA could insert a landmark log entry (say, just before generating the checkpoint) that commits to vindex tree heads and anything else it likes. For a server doing monitoring, it can either fetch the landmark sequence from the CA (which requires trusting a third party, as you mention) or it can get the location of a relatively fresh landmark (and corresponding landmark log entry) by inspecting any landmark-relative certificates it holds 1. Then the server can use the gossip mechanism you described to bootstrap trust in the landmark log entries from RPs by presenting the landmark-relative certs in a TLS handshake. On the negative-results question: the landmark sequence is append-only and monotonically increasing, and any landmark-relative cert the server holds gives a lower bound on landmark freshness (the cert is unexpired, so the landmark it's relative to is within max_cert_lifetime). For vindex monitoring, that's sufficient — the server doesn't need to prove "there is no newer landmark," only that the entry it's looking at is recent enough. A CA that stopped issuing landmark entries or rolled back its landmark sequence would be detectable the same way any other log misbehavior is: by monitors observing the log structure against cosigned checkpoints. Footnotes
|
|
There are a few immediate reservations I'd have about that approach:
|
Oops, yes, I forgot to mention that point. Not sure how serious that limitation would be but good to note. (As a more heavyweight approach, you could insert a "checkpoint log entry" every time the log issues a checkpoint if you want this to work for standalone certs. I'm not advocating for this but just mentioning it as another possible tradeoff.) One correction on my original post: The server doesn't really need to trust the CA to use a CA-served landmark sequence as an index into the log. If the landmark sequence points to valid landmark log entries, great! Otherwise, the server has to do more work to find a recent landmark log entry.
Both those issuing landmark-relative certs and RPs need to agree on the landmark tree sizes. (See section 6.3.1: "Landmarks are agreed-upon tree sizes across the ecosystem for optimizing certificates.") To issue landmark-relative certificates, the CA has to get cosignatures on the landmark subtrees (via /sign-subtree, currently described in Appendix C.2). That would be a fine place to plug in the vindex validation, I think, assuming the log cosigners are the ones doing the vindex auditing.
Isn't this PR doing the same thing? The server only learns about fresh |
If by "the server has to do more work", you mean that the server has to process a linear number of certificates, that's not really ideal. The CA is an untrusted party here, it shouldn't be able to force the server to do a prohibitive amount of work to remain secure.
In 7.4 the document says "It is not necessary that the cosigners have generated signatures over the specific subtrees, only that they are consistent." So that would need to change to require 1.) cosignatures that indicate an intent to make a landmark, over the specific subtrees, and 2.) have cosigners verify existence of a landmark log entry before signing. And you'd still have the other downsides we've discussed, so this wouldn't be my preference.
No, the server is able to go to the CA (or a mirror) at any time and find a newer accumulated log entry (if one exists). The server uses its certificate to gossip the tree head with browsers, so gossip here is limited to issuance frequency. But if the server is stateful, then any fork will be detected eventually. So while the landmark log entry idea is best-case as fast as re-issuance, the accumulated log entry idea is worst-case (= your chosen CA is malicious) as fast as re-issuance and best-case as fast as your CA will allow (allowing you to detect mis-issuances by other CAs sooner). |
|
Quick note: section 7.4 refers to pushing landmark subtrees down to RPs, in
which case consistency proofs to a signed checkpoint are sufficient. See
section 6.2 for the construction of certificates which _does_
require cosignatures on the exact subtree. (This was also a point of
confusion in [1], so we should probably clarify the text.)
[1]
https://mailarchive.ietf.org/arch/msg/plants/qFo9aC8WxZBBD936aVYKMhEfqjM/
EDIT: After reading your response on the mailing list, I realize that what I wrote above is wrong. I was conflating the "landmark-anchored standalone MTCs" case from [1] (where you would need cosignatures on the landmark subtrees) with landmark-relative certificates (where you don't). Thanks for the correction!
…On Thu, Apr 23, 2026 at 4:38 PM Brendan McMillion ***@***.***> wrote:
*Bren2010* left a comment (ietf-plants-wg/merkle-tree-certs#172)
<#172?email_source=notifications&email_token=ABAARLFMOORNLRA5IIUYXRL4XJ5LRA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTIMZQG44DKMZWG432M4TFMFZW63VHMNXW23LFNZ2KKZLWMVXHJNLQOJPWG33NNVSW45C7N5YGK3S7MNWGSY3L#issuecomment-4307853677>
If the landmark sequence points to valid landmark log entries, great!
Otherwise, the server has to do more work to find a recent landmark log
entry.
If by "the server has to do more work", you mean that the server has to
process a linear number of certificates, that's not really ideal. The CA is
an untrusted party here, it shouldn't be able to force the server to do a
prohibitive amount of work to remain secure.
To issue landmark-relative certificates, the CA has to get cosignatures on
the landmark subtrees (via /sign-subtree, currently described in Appendix
C.2).
In 7.4 the document says "It is not necessary that the cosigners have
generated signatures over the specific subtrees, only that they are
consistent." So that would need to change to require 1.) cosignatures that
indicate an intent to make a landmark, over the specific subtrees, and 2.)
have cosigners verify existence of a landmark log entry before signing. And
you'd still have the other downsides we've discussed, so this wouldn't be
my preference.
Isn't this PR doing the same thing? The server only learns about fresh
accumulated_counts (and corresponding vindexes) when it gets a fresh
certificate?
No, the server is able to go to the CA (or a mirror) at any time and find
a newer accumulated log entry (if one exists). The server uses its
certificate to gossip the tree head with browsers, so gossip here is
limited to issuance frequency. But if the server is stateful, then any fork
will be detected eventually. So while the landmark log entry idea is
best-case as fast as re-issuance, the accumulated log entry idea is
worst-case (= your chosen CA is malicious) as fast as re-issuance and
best-case as fast as your CA will allow (allowing you to detect
mis-issuances by other CAs sooner).
—
Reply to this email directly, view it on GitHub
<#172?email_source=notifications&email_token=ABAARLFMOORNLRA5IIUYXRL4XJ5LRA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTIMZQG44DKMZWG432M4TFMFZW63VHMNXW23LFNZ2KKZLWMVXHJNLQOJPWG33NNVSW45C7N5YGK3S7MNWGSY3L#issuecomment-4307853677>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABAARLFVFO7CNO76T5DVAXL4XJ5LRAVCNFSM6AAAAACRLDRLCKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHM2DGMBXHA2TGNRXG4>
.
You are receiving this because you commented.Message ID:
***@***.***>
--
Luke Valenta
Systems Engineer - Research
|
|
One more question: why |
|
That assumes third-party auditors verify each log entry. The counter approach is secure without assuming third-party auditors. Yes, verifiable indexes require assuming that third-party auditors exist, but that assumption is specific to that application. You can think of other applications where being able to authenticate "most recent" is valuable and where pulling in that assumption isn't otherwise necessary. The prime example being revocation. Edit: Thinking about it some more, another cool point is secure pruning. In a pruned part of the log, I can keep only the |
Isn't there an attack where the CA writes non-monotonic counter values to the log(n) entries that would be returned to the verifier to trick them into accepting an old accumulated log entry? This would be caught with either a global auditor, like mentioned in Section 5, or might be caught if the verifier keeps state across checks or has other peers doing similar checks, but I don't think the binary search for a verifier in isolation gives security guarantees (or at least, more work is needed to demonstrate that). |
|
One other idea I wanted to explore (not fully thought out yet): put the index of the most recent 'accumulated log entry' in each checkpoint. Mirror cosigners only sign the checkpoint if that pointer is correct (so they take on additional responsibilities). The server can still learn the set of RP-trusted cosigners by serving its standalone certificate in a TLS handshake, and can then request a recent checkpoint cosigned by the same set of cosigners to get an up-to-date vindex root. This probably has different security guarantees than your proposal, but also doesn't require any per-entry state. |
Yes, the expectation is that the verifier retains state. Retaining state will generally just be necessary to detect forks, though it also helps here. The expectation is also that all users are doing the search in a way that maximizes their ability to detect conflicts with each other. The general idea for the algorithm is Section 4 here
This would be interesting to consider, but muddles the layers of abstraction between MTC (defining a log entry format) and tlog-mirror (agnostic to log entry contents). You think that muddling is worth avoiding 8 (or 4) bytes? |
|
I wanted to comment on this from the perspective of a log implementer (specifically thinking of horizontally scaled designs like Tessera). This proposal introduces a strict data dependency between individual leaf contents. Currently, log sequencers can treat leaves as opaque, immutable blobs once they are hashed. There is no ordering or data dependency between leaves; they can be considered completely independently from all other leaves in the log. With this PR, the In a batched, distributed environment:
|
|
To put it differently, log operators have 3 options:
|
Define an extensions field for the MerkleTreeCertEntry structure. Repeated extensions are disallowed, but unrecognized extensions are ignored. The extensions are duplicated in the MTCProof. This change accommodates two previously requested features for MTC: 1. ietf-plants-wg#172: The accumulated count for the accumulated log entry type 2. ietf-plants-wg#226: The log entry randomizer
Define an extensions field for the MerkleTreeCertEntry structure. Unrecognized extensions are ignored. The extensions are duplicated in the MTCProof. This change accommodates two previously requested features for MTC: 1. ietf-plants-wg#172: The accumulated count for the accumulated log entry type 2. ietf-plants-wg#226: The log entry randomizer
Define an extensions field for the MerkleTreeCertEntry structure. Unrecognized extensions are ignored. The extensions are duplicated in the MTCProof. This change accommodates two previously requested features for MTC: 1. ietf-plants-wg#172: The accumulated count for the accumulated log entry type 2. ietf-plants-wg#226: The log entry randomizer
No description provided.