Hi Ilari,

Thank you for the quick review. I've been integrating all of the editorial feedback in the draft (separate mail to follow to the group). Regarding your feedback:

On 06/09/2023 17:46, Ilari Liusvaara wrote:
Doing quick review:

Section 3.1.2:

- It is not clear what exactly is replaced if cert_data is known.
   Obviously overriding the length field would be more compact, but it
   also can be interpreted as replacing the value, wasting 3 bytes.

   (Reminds me of RFC 8879, which is not clear about similar things.)

- CertificateEntry and Certificate length fields are just waste of
   space, since both can be recovered in other ways when decoding.

- RFC 8879 does not allow ignoring unrecognized three-byte identifiers.
   Instead, the connection MUST be terminated with bad_certificate alert.

   This has consequence that any client that can ever add a custom trust
   anchor via any means must have the complete certificate list (whereas
   partial list would be enough if no custom trust anchors can ever be
   added).

   And I find the last comment about transcript validation failing very
   scary.

I've improved the language in the draft to clarify exactly how this pass works. A TLS1.3 Certificate Message carrying X509 is structured as follows:

      struct {
          opaque cert_data<1..2^24-1>;
          Extension extensions<0..2^16-1>;
      } CertificateEntry;

      struct {
          opaque certificate_request_context<0..2^8-1>;
          CertificateEntry certificate_list<0..2^24-1>;
      } Certificate;

When compressing during this first pass, we're going to be swapping the opaque cert_data fields for short three byte identifiers and correcting the lengths. The extension and certificate_request_context fields are not going to be adjusted. Pass 2 is then going to compress the result with ZStd with a provided dictionary.

When we're decompressing, after the ZStd pass, we're going to use the length fields to parse the message and replace any recognized three byte identifiers with the corresponding certificate, again leaving the extensions and the certificate_request_context untouched.

I hope that clarifies why transmitting the lengths is necessary. Regarding the decompression errors, I've updated the draft to say that decompression must fail and the correct alert sent if the length fields are incorrect as you suggested. I've filed an issue to discuss the case of unrecognized identifiers specifically [1].

Regarding the general security considerations, I want to clarify the situation. At the point we receive a Certificate (or a CompressedCertificate) message in TLS1.3, we don't know who we're talking to, the point of the message is to provide that information. Obviously, a peer can send any payload it likes in a Certificate message already, it's the job of the receiver to parse the Certificate message and establish whether it trusts the presented certificate (chain).

Using Certificate Compression with any scheme (including this draft) doesn't change the fundamentals. The result of decompressing the message is handled exactly like a Certificate message. So with the exception of memory safety bugs during decompression, there is no additional attack surface. An attacker can already send arbitrary content in a Certificate message and so implementations receiving a Certificate message already have to be able to robustly validate it. Any attack which somehow leveraged the decompression aspect is also possible by the attacker just sending the output of the decompression directly as a Certificate message. Nothing in this draft changes the situation from existing uses of Certificate Compression.


Section 3.2.:

- Using alternate scheme could result drastically reduced implementation
   complexity.

   Furthermore, one can't even use standard zstd decoder with this due to
   security reasons. One needs special one (but seems like reference zstd
   library ships that as alternative API).

Can you clarify what you mean by this? The standard zstd decoder works fine.

Section 3.2.1.:

- I suspect that having CA-specific dictionaries would make it much
   easier to be equitable and improve compression.

   Then I don't think the dictionary construction method is good:
* Using just one certificate is very dubious.
   * It is more optimal to consider byte substrings with no structure.

This is tracked in [2] and [3]. Depending on the experimental data we get when evaluating [3], we might omit pass 2 entirely.


Section 3.2.1.1.:

- Caching monolithic compression from startup does not work because of
   extension fields.

   For caching to work, one would have to compress the certificate
   entries independently and leave the extension fields in between
   uncompressed.
The draft currently preserves the extension fields. Existing TLS Certificate Compression APIs perform the caching at the level of the entire message and so the cache is only used if the entire message, including extensions, is bytewise identical. Can you think of an extension in a Certificate message which changes frequently?

Section 5.1.:

- I think the argument about adding roots taking time is flawed. Roots
   are usually not even included in the chain, but intermediates are,
   and can change much faster.

   I remember seeing one CA that judging from naming of the intermediate
   rotated it every 6 months.

This draft definitely doesn't want to be a factor slowing rotation. I've filed [4] to keep track of this. As discussed in Appendix B and in the IETF 117 presentation, it might be that dynamic versioning is more suitable in the long run.

Section 5.4:

- I think the current complexity as I understand the draft is just
   scary.

   I consider not being able to adjust extension fields in the fly to
   be a hard blocker (that is already a hard blocker for implementing
   RFC 8879 sending side).

As discussed above, I think this is a misunderstanding of the draft and how existing TLS Certificate Compression schemes work.

Regarding the complexity, a lot of the draft is dedicated to how the wider WebPKI works and how the draft interacts with it in a principled way, as well as highlighting possible options. The actual implementation of this draft is extremely succinct:

1) Some code for parsing the lengths in a Certificate Compression message.
2) A key-value substitution for the recognized certificates
3) A call to the existing ZStd interface.

Best,
Dennis

[1] https://github.com/tlswg/draft-ietf-tls-cert-abridge/issues/22

[2] https://github.com/tlswg/draft-ietf-tls-cert-abridge/issues/7

[3] https://github.com/tlswg/draft-ietf-tls-cert-abridge/issues/12

[4] https://github.com/tlswg/draft-ietf-tls-cert-abridge/issues/16
_______________________________________________
TLS mailing list
TLS@ietf.org
https://www.ietf.org/mailman/listinfo/tls

Reply via email to