Summary

  • RFC 9921 defines two different COSE/RFC 3161 constructions: CTT timestamps the COSE signature field, while TTC timestamps the payload before a later COSE signature covers both payload and token.
  • A verifier may not use a TTC token as evidence that a signature existed before certificate revocation. The mode, exact hashed bytes, TSA trust and time policy must survive into the final relying-party decision.

The incident review had a green cryptography column, a green timestamp column and a red revocation notice. The signer’s certificate had been revoked on Tuesday. The document carried an RFC 3161 token dated Monday. An automated checker accepted the document as a long-term signature: the token sat in the protected COSE header, the token’s CMS signature verified, and the later COSE signature covered both the token and the payload.

The conclusion was still wrong.

The token showed that the payload existed when the TSA created its token. It did not show that the COSE signature already existed then. The signer could have asked a TSA to timestamp a payload on Monday, waited until after the certificate was revoked, and then created a COSE signature that protected both the old token and the same payload. Every byte in the review could be genuine. The inference about signature time would nevertheless be invented.

That is not a fussy distinction imposed by an auditor. It is the central security warning in RFC 9921, the IETF’s February 2026 Standard for putting RFC 3161 TimeStampTokens into COSE_Sign and COSE_Sign1. The standard defines two constructions precisely because a timestamp has a scope. A token is not a magic date attached to an entire business story.

Two orders create two different facts

The first construction is COSE, Then Timestamp, abbreviated CTT. The producer signs the COSE object first. It then hashes the CBOR-encoded signature field in a COSE_Sign1 object, or the CBOR-encoded signatures field in COSE_Sign, and sends that hash to a Time Stamping Authority. The returned token is placed in the 3161-ctt unprotected header parameter.

The important fact is the input to the TSA. CTT timestamps the actual signature field, including the encoding scope RFC 9921 specifies. The token is therefore akin to a TSA countersignature: if the relying party verifies the COSE signature and the associated timestamp token under the relevant trust conditions, it has evidence that the signature existed by the TSA time. That is the construction RFC 9921 uses for long-term signatures—particularly where a signer may later deny the act or where the signing certificate has a short life.

The second construction reverses the sequence. In Timestamp, Then COSE, or TTC, the producer first takes a hash of the COSE payload bytes and asks the TSA to timestamp that hash. The payload bytes—not the CBOR byte-string wrapping, not a later signature field—are the RFC 3161 MessageImprint. The producer puts the returned token in the 3161-ttc protected header and then creates the COSE signature over the protected headers and payload.

TTC produces a valuable, different package. It binds an earlier payload timestamp into a subsequently signed COSE object. This makes it suitable for RFC 9921’s transparency/notarisation scenario: an issuer can preserve a timestamp token inside the signed statement before registering the signed material with an append-only transparency service. But “payload existed” and “signature existed” are not interchangeable past-tense claims. The first can be true before the signer acts. The second requires the signature bytes themselves to be within the TSA’s covered material.

RFC 9921 says validators must make this distinction explicitly. A protected-header payload timestamp is not proof of signature-creation time; treating it as one can wrongly admit a signature created after key revocation. The mode names are not helpful comments. They select different verification algorithms and authorize different conclusions.

The header location is a control, not decoration

It can feel counterintuitive that the long-term-signature token is in an unprotected header while the payload-first token is protected. The locations follow the construction order.

In CTT, a signature cannot cover a timestamp that did not yet exist. The token is obtained after the COSE signature and attached afterward, so it cannot be inside that earlier signature’s protected headers. RFC 9921 consequently warns that an attacker can remove or replace the 3161-ctt header. The standard’s answer is not to pretend the header was signed; it is to require an adjacent transport-and-storage integrity control for the complete COSE Signed Message.

That creates an operating obligation. A CTT verifier needs a record not only of the signature and token validation, but of the carrier that preserved their association. Systems should be able to identify the artifact hash, storage or transport protection, mode, TSA certificate and policy, the exact signature-field bytes used for the imprint, and the decision that consumed the result. A dashboard that displays “timestamp valid” after silently dropping an unprotected CTT header has lost the evidence it claims to summarize.

In TTC, the token appears before the COSE signature and is therefore protected by it. That stops a later party from changing the token without invalidating the COSE signature. It does not reverse time. Protected placement tells a verifier that the signer covered the token; it does not tell the verifier that the signer had signed before the TSA issued it.

The difference matters most where the organization makes expensive historical claims. “This payload existed by this time” may be exactly what a provenance, disclosure or transparency workflow needs. “This signature existed while this certificate was valid” is a different claim, with a different construction and a different revocation test. Neither one establishes that an issuer had authority to sign, that a log actually included the statement, that a recipient received it, or that an operational action took place.

A timestamp needs a decision chain

RFC 3161 is already clear that a TSA timestamps a hash representation rather than inspecting and endorsing the meaning of the datum. A client must check the response status, TSA identity and certificate, requested data imprint, hash algorithm, timeliness evidence, certificate status and policy acceptability. The TSA’s genTime is when it made its token; accuracy, precision, latency and the selected TSA policy constrain how that time should be read.

RFC 9921 adds the COSE-specific step: the receiver must recompute the embedded token’s MessageImprint over exactly the payload, signature or signatures field specified by the selected mode. “We found a valid token nearby” is not a verification result. The decisive question is: what exact byte sequence did the TSA token cover, and what conclusion is this relying party licensed to draw from that coverage?

For CTT, the chain is: identify 3161-ctt; validate the COSE signature; validate the TSA token and policy; hash the prescribed encoded signature field; compare it to the token’s imprint; protect the assembled object during carriage and retention; then apply a documented historical-certificate policy. The conclusion can be that the signature was already present by the TSA time, subject to those validations and time assumptions.

For TTC, the chain is different: identify 3161-ttc; validate the token; hash the payload bytes exactly; validate the later COSE signature over the protected header and payload; then record that the payload had the timestamped prior existence. If a transparency service is involved, validate log inclusion and consistency separately, establish whose statement was registered, test revocation chronology, and apply the relying party’s own policy. A time token cannot smuggle those independent facts into existence.

Heng Lu’s running-code principle is useful because a policy document can name all of these checks while the deployed validator only verifies CMS. The real control surface is the executable path that chooses CTT or TTC, recomputes the right bytes, fetches the right status evidence, applies a versioned time policy and records the decision. His reality-layer distinction keeps four statements separate: a COSE object parsed; a token verified; a policy accepted a bounded time claim; an accountable system acted. None is a decorative synonym for another.

Sources