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