I think it says something about the ambiguity that I'm not entirely sure which interpretation you are saying is clearly the correct one, so I'm going to discuss both. :-)
Like many extensions, RFC 8879 changes the messages that are sent over the handshake stream, both in contents (new extensions added to ClientHello and CertificateRequest) and in type (CompressedCertificate is sent instead of Certificate). While it is rare that we change the message types, it's not unheard of. For example, RFC 6066 introduced the CertificateStatus message. When that happens, such changes are reflected in the handshake transcript. The handshake transcript is all the messages that are sent or received over the handshake stream, and RFC 8879 replaces the Certificate message with the CompressedCertificate message. Thus, by the sent/received interpretation, the transcript should include CompressedCertificate and not Certificate. This matches how every TLS stack I'm aware of is structured. Indeed some handle the transcript automatically under the handshake layer and would *only* be able to implement this version. (Ours used to be like that. We've since gotten more flexible as a consequence of some work to control the timing a bit better, but I suspect other stacks of our lineage are still architectured this way.) It's also what was interoperably implemented by multiple stacks, so practically speaking, it is the interpretation we need to settle on. Yes, it happens that RFC 8879's CompressedCertificate message contains a compressed string, which uncompresses to another string formatted like a Certificate structure (without the Handshake header[*[). And it happens that other TLS handshake mechanisms interact with the result of that decompression as if they saw a vanilla Certificate message, but that's all within the handshake proper and about the handshake stream that we transcribe. Extensions change what goes on in the handshake. RFC 8879 is defined as a handshake-level mechanism, not a filter over the handshake stream. (It has to be, because it needs to add an extension to CH and CR, and correlate that to its new message.) But then the problem is the transcript in RFC 8446 is not actually defined in terms of what's actually sent/received over the handshake stream. It is defined in reference to particular messages, albeit with some "..."s in between. It also says this: For concreteness, the transcript hash is always taken from the following sequence of handshake messages, starting at the first ClientHello and including only those messages that were sent: ClientHello, HelloRetryRequest, ClientHello, ServerHello, EncryptedExtensions, server CertificateRequest, server Certificate, server CertificateVerify, server Finished, EndOfEarlyData, client Certificate, client CertificateVerify, client Finished. https://www.rfc-editor.org/rfc/rfc8446#section-4.4.1:~:text=For%20concreteness%2C%20the,CertificateVerify%2C%20client%20Finished . Taken literally, this text would suggest that, if an extension adds or modifies handshake messages, it's not reflected in the transcript, unless it says otherwise. That's not what we want, both by how real implementations work, or by the security goals of the transcript. We *want* message modifications to show up in the transcript by default, but the formal text does not say this. And thus the ambiguity. David [*] Actually, this seems to also be a point of ambiguity. The spec says you compress a Certificate, and the Certificate structure indeed does not have the four-byte header. Looking at our implementation, we indeed only compress that portion and not the header. I assume (but haven't checked) that's what other implementations do because we'd probably have heard of an interop issue by now. But in TLS we're sloppy enough about messages with and without the header that it's worth being explicit. On Wed, Feb 4, 2026 at 1:17 AM Nico Williams <[email protected]> wrote: > On Fri, Jan 30, 2026 at 12:46:40PM +0900, Kazu Yamamoto (山本和彦) wrote: > > But RFC 8879 says: > > > > After decompression, the Certificate message MUST be processed as > > if it were encoded without being compressed. > > In my opinion the quoted text is not ambiguous, and no errata is > necessary. > > First, RFC 8879 does not change how TLS 1.3 computes its transcripts. > More on this below. > > Second, the quoted sentence is superfluous and unnecessary. What > "processing" does one do with the Certificate message? One validates > the certificate. But RFC 8879 does not provide a way to validate > compressed certificates apart from decompressing them and then > validating them as usual. And what other validation method could one > design other than decompress then validate as usual? Therefore the > quoted sentence was never necessary: because it's obvious. > > Third, the next sentence in the RFC says: > > [...]. This way, the parsing and > the verification have the same security properties as they would have > in TLS normally. > > but one does use "parsed" messages to compute the TLS handshake > transcript hash. So clearly the first sentence would not be consistent > with any intent to change the way the transcript hash is computed. More > below. > > > I think the following original interpretation is possible for the > > content: > > > > Transcript-Hash(Handshake Context, Certificate) > > RFC 8879 does not change how TLS 1.3 computes its transcripts. Nor > should it. And if it did it would have to be explicit about it. > > The point of the transcript being > > Transcript-Hash(M1, M2, ... Mn) = Hash(M1 || M2 || ... || Mn) > > is that M1, M2, .., Mn are the N messages sent / received _as they are > sent or received_ without any alterations. The whole point of the > transcript hash is to _detect alterations_. Therefore no compression of > any part of the handshake should alter the Transcript-Hash() function. > > The handshake transacript is such a critical and core design point of > TLS that, had the Internet-Draft preceding RFC 8879 meant to alter the > Transcript-Hash() function then surely it would never have managed WG > consensus. > > Nico > -- > > _______________________________________________ > TLS mailing list -- [email protected] > To unsubscribe send an email to [email protected] >
_______________________________________________ TLS mailing list -- [email protected] To unsubscribe send an email to [email protected]
