jiebi/CodeConvo huggingface dataset:
Code change:
server in the same session. Set the "config_digest" field to a randomly-generated string of <del> hash_length bytes, where hash_length is the length of the hash function associated with the chosen HpkeCipherSuite. </del> <ins> "Nh" bytes, where "Nh" is the output length of the "Extract" function of the KDF associated with the chosen cipher suite.  (The KDF API is specified in I-D.irtf-cfrg-hpke.) </ins> Set the "enc" field to a randomly-generated valid encapsulated public key output by the HPKE KEM.

Related discussion:
text: Per NAME suggestion, this replaces computations involving the "hash underlying the KDF" with evaluation of the KDF itself. This respects the API defined in the HPKE draft. This supersedes .
Hey NAME and NAME I rolled up your changes! Please have another look before merging.
Rebased and rolled up.
Thanks -- let's let this stew until Friday, at which point we can merge.
Rebased.
Field is computed as "digest of the complete ClientHelloInner" (including presumably, the "outer_extensions" extension). I don't understand the analytical value of this hash. Can anyone explain its reasoning?
The hash is intended to prevent the attacker from influencing the reconstructed CHInner by manipulating CHOuter. Consider the contrived example of an extension which is separately protected but only works for SNI-A and not SNI-B. E.g., it's constructed by doing E(K_sni, SNI). If that extension were included in CHOuter and then imported into CHInner via this mechanism, then an attacker could substitute it and use a reaction attack to determine whether the CH referred to A or B. However, with the hash (which may be not well-specified), this attack gets caught by the client-facing server and the handshake is rejected without leaking information.
My initial understanding of this mechanism was incorrect. What happens is that the hash is computed over the ClientHelloInner that is consumed by the backend server. This is intended to ensure that if ECH accepts, then the backend server consumes the CH intended by the client. (PR URL makes this more clear, I think.) I wonder if this mechanism is redundant. Agreement on the CH between the client and backend server is provided by the binding of the transcript hash to the handshake traffic secret, so any attempt to manipulate the ClientHelloInner by fiddling with the ClientHelloOuter should be detected. On the other hand, the binding of the outer extensions to ClientHelloInner ensures agreement on the CH prior to the backend server consuming it. This is a strictly stronger property, which may or may not be useful. I agree that the attack works, but the example seems really contrived :) I'd be interested if there are more natural extensions for which this extra layer of security would be useful.
From the interim meeting, the consensus seems to be that we should err on the conservative side.
Code change:
server in the same session. Set the "config_digest" field to a randomly-generated string of <del> hash_length bytes, where hash_length is the length of the hash function associated with the chosen HpkeCipherSuite. </del> <ins> "Nh" bytes, where "Nh" is the output length of the "Extract" function of the KDF associated with the chosen cipher suite.  (The KDF API is specified in I-D.irtf-cfrg-hpke.) </ins> Set the "enc" field to a randomly-generated valid encapsulated public key output by the HPKE KEM.

Related discussion:
text: Let's close this issue and leave the mechanism as is.
Hrm, before closing I think it might be worth noting, in the spec, the stronger security property this provides.
I think we should also consider binding the CHInner to a hash of the whole CHOuter (minus the ClientEncryptedCH extension). That would have the same size overhead, but would give us a stronger property: modifying anything in CHOuter (not just one of the copied extensions) invalidates the whole thing.
The point of hashing outer extensions is to provide integrity of the ClientHelloInner. What would be the point in hashing more of the ClientHelloOuter? (Not a rhetorical question :) It seems conceptually different, and I'm curious what the security benefit might be.)
If we authenticate the ClientHelloOuter, we'd be authenticating all the inputs that go into the ClientHelloInner, so I think that would also provide integrity. I expect Ben is suggesting this in the context of URL, where GREASE can additionally be made a little stronger if we did that. Getting that to interact well with any PSK binders in ClientHelloOuter is tricky though, unless we decide to ban resumption attempts in outer ClientHellos. (Probably best to keep the GREASE-related conversation in one place. Though I see I didn't help on that front because some discussion is also in . Ah, GitHub.)
Yep, I'm just echoing NAME observation. See also URL
Today, the only thing that gets copied into ClientHelloInner is extensions, so I don't see how it's an improvement in terms of our primary security goal. (Not sure about the "don't stick out" benefit.)
I don't understand how hashing all of CHOuter is going to work. In split mode, the server never sees any of CHOuter.
Yes, the hash would be checked when reconstructing the inner ClientHello (as here), and would not be present in the reconstructed ClientHello.
There's not much discussion here. Unless there's objection, shall we leave the mechanism as-is and close out this issue? cc/ NAME
Works for me.
From Section 6.1: This assumes that the KDF specifies some underlying hash function.
Code change:
server in the same session. Set the "config_digest" field to a randomly-generated string of <del> hash_length bytes, where hash_length is the length of the hash function associated with the chosen HpkeCipherSuite. </del> <ins> "Nh" bytes, where "Nh" is the output length of the "Extract" function of the KDF associated with the chosen cipher suite.  (The KDF API is specified in I-D.irtf-cfrg-hpke.) </ins> Set the "enc" field to a randomly-generated valid encapsulated public key output by the HPKE KEM.

Related discussion:
text: From the HPKE spec, it seems like all that's required of the KDF is that it's an "extract-then-expand" KDF: URL In fact, the currently assigned code points are all for HKDF: URL But there's no requirement that the KDF always have some underlying hash function. As an alternative to HKDF, one can imagine a dedicated primitive that satisfies the extract-then-expand API but is not constructed from a hash function.
Impacted fields: ClientEncryptedCH.record_digest URL
We can probably replace with and be done with it.
Putting on my theorist hat, I'd say that the extract function is a "randomness extractor" and not a collision resistant hash function. We want the latter in this context. From a practical stand point, using the extract function is more hashing than we need. I'd suggest doing away with (see ) and figuring something else out for . Could we simply require HKDF be used with HPKE?
Sure, but in practice randomness extractors use a collision resistant hash or PRF (CBC) under the hood. I don't think we can require HKDF for HPKE. That seems too restrictive. We might just say that ECH requires HKDF-based HPKE ciphersuites, as HKDF is already paramount for TLS 1.3, and then just reference HKDF's hash function.
addresses this issue.
As I mentioned on the list, we can use the KDF in place of a hash.
I tend to agree. I'll create a new PR.
Have a look at , NAME
Resolved in . Closing.
Code change:
certainly as examining decrypted traffic. Because HTTPS has historically layered HTTP on top of TLS, which is <del> in turn layered on top of TCP, intermediaries do have access to unencrypted TCP-level transport information, such as retransmissions, and some carriers exploited this information in attempts to improve transport-layer performance RFC3135.  The most recent standardized version of HTTPS, HTTP/3 I-D.ietf-quic-http, uses the QUIC protocol RFC9000 as its transport layer.  QUIC relies on the TLS 1.3 initial handshake RFC8446 only for key exchange RFC9001, and encrypts almost all transport parameters itself except for a few invariant header fields.  In the QUIC short header, the only transport-level parameter which is sent "in the clear" is the Destination Connection ID RFC8999, and even in the QUIC long header, the only transport-level parameters sent "in the clear" are the Version, Destination </del> <ins> in turn layered on top of TCP, intermediaries have historically had access to unencrypted TCP-level transport information, such as retransmissions, and some carriers exploited this information in attempts to improve transport-layer performance RFC3135.  The most recent standardized version of HTTPS, HTTP/3 RFC9114, uses the QUIC protocol RFC9000 as its transport layer.  QUIC relies on the TLS 1.3 initial handshake RFC8446 only for key exchange RFC9001, and encrypts almost all transport parameters itself except for a few invariant header fields.  In the QUIC short header, the only transport-level parameter which is sent "in the clear" is the Destination Connection ID RFC8999, and even in the QUIC long header, the only transport- level parameters sent "in the clear" are the Version, Destination </ins> Connection ID, and Source Connection ID.  For these reasons, HTTP/3 is significantly more "opaque" than HTTPS with HTTP/1 or HTTP/2.

Related discussion:
text: Section 6.3. QUIC and Its Behavior As already noted, the discussion about head-of-line-blocking would really benefit from backing by a reference. Section 7. Streaming Encrypted Media As far as I know, streaming users sometimes use encrypted tunnels such as OpenVPN or WireGuard (or IPsec) to access video content. I may miss something, but it is unclear to me how that fits into the categories presented in Section
Code change:
The length of the Certificate message once it is uncompressed.  If after decompression the specified length does not match the actual length, the party receiving the invalid message MUST abort the <del> connection with the "bad_certificate" alert. </del> <ins> connection with the "bad_certificate" alert.  The presence of this field allows the receiver to pre-allocate the buffer for the uncompressed Certificate message and to enforce limits on the message size before performing decompression. </ins> The compressed body of the Certificate message, in the same format as it would normally be expressed in.  The compression algorithm

Related discussion:
text: State explicitly that we do not define any compression dictionaries. Explain the rationale behind the uncompressed_length field. Addresses comments from John Mattsson on the list.
Actually, I have a small nit.
Code change:
If not populating the "path" field: Set the "path" field in the Commit to the null optional.  Define "commit_secret" as the all- <del> zero vector of the same length as a "path_secret" value would be. In this case, the new ratchet tree is the same as the provisional ratchet tree. </del> <ins> zero vector of length "KDF.Nh" (the same length as a "path_secret" value would be).  In this case, the new ratchet tree is the same as the provisional ratchet tree. </ins> Derive the "psk_secret" as specified in pre-shared-keys, where the order of PSKs in the derivation corresponds to the order of

Related discussion:
text: Right now, the vector is described in a couple of ways. This PR standardizes on "of length ".
Code change:
2.4. New QUIC connections are established using a handshake, which is <del> distinguishable on the wire and contains some information that can be passively observed. </del> <ins> distinguishable on the wire (see sec-identifying for details), and contains some information that can be passively observed. </ins> To illustrate the information visible in the QUIC wire image during the handshake, we first show the general communication pattern

Related discussion:
text: Could the first 1200-byte QUIC packet be used to suspect a QUIC connection establishment ? [MK] Yes, I think if you look at the first packet as a whole you can be reasonably sure that you look at a quic packet. I guess this is an assumption throughout the whole document, as section 2.4 says: "New QUIC connections are established using a handshake, which is distinguishable on the wire and contains some information that can be passively observed." [MK] Do we need to say more? EV> hummm I guess not even if the text in 2.4 is rather generic while the point in 3.1 is really specific. Perhaps adding which handshake properties are 'distinguishable' already in section 2.4 ?
proposes to fix this with a forward reference.
Code change:
empty redemption contexts must be stored and shared across all requests until token-key expiration or rotation. <ins> Origins that share redemption contexts, i.e., by using the same redemption context, choosing the same issuer, and providing the same origin_info field in the TokenChallenge, must necessarily share state required to enforce double spend prevention.  Origins should consider the operational complexity of this shared state before choosing to share redemption contexts.  Failure to successfully synchronize this state and use it for double spend prevention can allow Clients to redeem tokens to one Origin that were issued after an interaction with another Origin that shares the context. </ins> 2.1.2. Clients can generate multiple tokens from a single TokenChallenge,

Related discussion:
text: The section references seem to be breaking the build, so I'll fix that later before we land this.
Origins currently choose whether their challenges are per-origin or cross-origin. For cross-origin, double-spend prevention is only as good as the coordination between origins and the Issuer. Per-origin allows double-spend prevention to be isolated to a single origin; also prevents the cache of tokens being take up by some other origin.
Write this as "any origins that share a redemption context must also share double spend state for that context."
Code change:
5. A DNS client that already knows the name of an Encrypted Resolver can <del> use DEER to discover details about all supported encrypted DNS </del> <ins> use DDR to discover details about all supported encrypted DNS </ins> protocols.  This situation can arise if a client has been configured to use a given Encrypted Resolver, or if a network provisioning protocol (such as DHCP or IPv6 Router Advertisements) provides a name

Related discussion:
text: Changed 2 instances of DEER to DDR
I was so focused on finding "equivalent" that I missed a couple deer apparently. Thank you!
Code change:
server has selected for the negotiated key exchange.  Servers MUST NOT send a KeyShareEntry for any group not indicated in the "supported_groups" extension and MUST NOT send a KeyShareEntry when <del> using the "psk_ke" PskKeyExchangeMode.  If a HelloRetryRequest was received by the client, the client MUST verify that the selected NamedGroup in the ServerHello is the same as that in the </del> <ins> using the "psk_ke" PskKeyExchangeMode.  If using (EC)DHE key establishment, and a HelloRetryRequest containing a "key_share" extension was received by the client, the client MUST verify that the selected NamedGroup in the ServerHello is the same as that in the </ins> HelloRetryRequest.  If this check fails, the client MUST abort the handshake with an "illegal_parameter" alert.

Related discussion:
text: This clarifies two items relevant to stateless HelloRetryRequests: 1) If a HelloRetryRequest does not contain a keyshare extension, the negotiated group does not have to match the non-existent selected group in the HRR. 2) If a HelloRetryRequest does select a group, the server can still choose to use pskke key exchange. When sending a stateless HelloRetryRequest, the server may not know if it will accept a PSK yet. This allows the server to still select a group in the HelloRetryRequest which it would need for a full handshake, but later decide to accept the PSK with psk_ke mode.
Seems reasonable to me.
Code change:
message MUST be compressed with the ZLIB compression algorithm, as defined in RFC1950.  If the specified compression algorithm is brotli, the Certificate message MUST be compressed with the Brotli <del> compression algorithm as defined in RFC7932. </del> <ins> compression algorithm as defined in RFC7932.  If the specified compression algorithm is zstd, the Certificate message MUST be compressed with the Zstandard compression algorithm as defined in RFC8478. </ins> It is possible to define a certificate compression algorithm that uses a pre-shared dictionary to achieve higher compression ratio.

Related discussion:
text: Parking this here; if we have a consensus on the list to add it, we should merge this.
Code change:
to match the protocol version that is negotiated by the client and server. <del> The credential's public key, a DER-encoded SubjectPublicKeyInfo as defined in RFC5280. </del> <ins> The credential's public key, a DER-encoded X690 SubjectPublicKeyInfo as defined in RFC5280. </ins> The delegated credential has the following structure:

Related discussion:
text: Just some nits.
The public key name and type have been changed in , as NAME suggested on the mailing list.
NAME beat me to it!
oh looks like the travis build is failing for some reason
NAME I have no idea why pushing that worked ...
awesomesauce. it's probably some temporary failure while trying to fetch the new references or something
Code change:
including the signature algorithm identifier in the data to be signed. <ins> 9.2. The RSASSA-PSS signature algorithm is defined in RFC3447. The RSASSA-PSS signature algorithm is parametized with a hash function, a mask generation function and a salt length (sLen).  For this specification, the mask generation function is fixed to be MGF1 as defined in RFC3447.  It has been recommended that the same hash function be used for hashing the data as well as in the mask generation function, for this specification we following this recommendation.  The salt length is the same length as the hash function output. Three algorithms are defined in this document.  These algorithms are: This uses the hash algorithm SHA-256 for signature processing. The value used for this algorithm is -10.  The key type used for this algorithm is 'RSA'. This uses the hash algorithm SHA-384 for signature processing. The value used for this algorithm is "PS384".  The key type used for this algorithm is 'RSA'. This uses the hash algorithm SHA-512 for signature processing. The value used for this algorithm is -11.  The key type used for this algorithm is 'RSA'. There are no algorithm parameters defined for these signature algorithms.  A summary of the algorithm definitions can be found in table-rsa-algs. 9.2.1. Key size.  is there a MUST for 2048? or do we need to specify a minimum here? </ins> 10. Message Authentication Codes (MACs) provide data authentication and

Related discussion:
text: MTI Algorithm requirements Expand RSASSA-PSS section Correct one coordinate EC for endian Hint to get binary versions of examples Correct kid to binary in the examples (except for static public key one).
Code change:
needs to initialize a GroupContext object that can be updated to the current state using the Add message.  This information is encrypted for the new member using HPKE.  The recipient key pair for the HPKE <del> encryption is the one included in the indicated ClientInitKey, corresponding to the indicated ciphersuite.  The "add_key_nonce" field contains the key and nonce used to encrypt the corresponding Add message; if it is not encrypted, then this field MUST be set to the null optional value. </del> <ins> encryption is the one included in the indicated ClientInitKey.  The "add_key_nonce" field contains the key and nonce used to encrypt the corresponding Add message; if it is not encrypted, then this field MUST be set to the null optional value. </ins> In the description of the tree as a list of nodes, the "credential" field for a node MUST be populated if and only if that node is a leaf

Related discussion:
text: Here's the Weekly Digest for : - - Last week 3 issues were created. Of these, 1 issues have been closed and 2 issues are still open. :greenheart: , by :greenheart: , by :heart: , by :speaker: , by It received 1 comments. - - Last week, 6 pull requests were created, updated or merged. Last week, 1 pull request was opened. :greenheart: , by Last week, 1 pull request was updated. :yellowheart: , by Last week, 4 pull requests were merged. :purpleheart: , by :purpleheart: , by :purpleheart: , by :purpleheart: , by - - Last week there were 6 commits. :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by - - Last week there was 1 contributor. :bustinsilhouette: - - Last week there was 1 stargazer. :star: You are the star! :star2: - - Last week there were no releases. - - That's all for last week, please :eyes: Watch and :star: Star the repository to receive next weekly updates. :smiley: You can also .
Here's the Weekly Digest for : - - Last week, no issues were created. - - Last week, 3 pull requests were created, updated or merged. Last week, 2 pull requests were updated. :yellowheart: , by :yellowheart: , by Last week, 1 pull request was merged. :purpleheart: , by - - Last week there was 1 commit. :hammerandwrench: by - - Last week there was 1 contributor. :bustin_silhouette: - - Last week there was 1 stargazer. :star: You are the star! :star2: - - Last week there were no releases. - - That's all for last week, please :eyes: Watch and :star: Star the repository to receive next weekly updates. :smiley: You can also .
Here's the Weekly Digest for : - - Last week 2 issues were created.
Code change:
needs to initialize a GroupContext object that can be updated to the current state using the Add message.  This information is encrypted for the new member using HPKE.  The recipient key pair for the HPKE <del> encryption is the one included in the indicated ClientInitKey, corresponding to the indicated ciphersuite.  The "add_key_nonce" field contains the key and nonce used to encrypt the corresponding Add message; if it is not encrypted, then this field MUST be set to the null optional value. </del> <ins> encryption is the one included in the indicated ClientInitKey.  The "add_key_nonce" field contains the key and nonce used to encrypt the corresponding Add message; if it is not encrypted, then this field MUST be set to the null optional value. </ins> In the description of the tree as a list of nodes, the "credential" field for a node MUST be populated if and only if that node is a leaf

Related discussion:
text: Of these, 0 issues have been closed and 2 issues are still open. :greenheart: , by :greenheart: , by - - Last week, 2 pull requests were created, updated or merged. Last week, 2 pull requests were opened. :greenheart: , by :greenheart: , by - - Last week there were no commits. - - Last week there were no contributors. - - Last week there were 2 stagazers. :star: :star: You all are the stars! :star2: - - Last week there were no releases. - - That's all for last week, please :eyes: Watch and :star: Star the repository to receive next weekly updates. :smiley: You can also .
Code change:
Certain characters are escaped in Normalized Paths, in one and only one way; all other characters are unescaped. <del> Note: Normalized Paths are Singular Queries, but not all Singular Queries are Normalized Paths.  For example, "$[-3]" is a singular </del> <ins> Note: Normalized Paths are singular queries, but not all singular queries are Normalized Paths.  For example, "$[-3]" is a singular </ins> query, but is not a Normalized Path.  The Normalized Path equivalent to "$[-3]" would have an index equal to the array length minus "3". (The array length must be at least "3" if "$[-3]" is to identify a

Related discussion:
text: Sometimes the spec uses "Singular Query" and sometimes "singular query". We should be consistent. (If we decide to use lower case, it's probably best to address this issue after PR has been merged, since that PR adds some usages of "Singular Query".) Also, there is one instance of "Logical context", which I think would be better uncapitalised ("logical context").
After merging in my changes from main, it appears some Singular Queries still need fixing.