[ech] ECH split mode API

Stephen stephen at jell.ie
Wed Aug 30 15:11:28 UTC 2023


Hiya,

On 30/08/2023 15:42, Tomas Mraz wrote:
> Ah, OK. Then I think the best API would be modelled as a BIO filter or
> something similar - you write the raw data into it and read the
> decrypted/modified messages out of it to be passed to the backend
> application.

Can you think of an example on which I could model stuff?
Ideally something that takes an SSL_CTX and a buffer/BIO
and spits out another buffer/BIO I guess.

> There seems to be no point in requiring the application to extract the
> client hello and then mangle it back into new messages for the backend.

Tend to agree.

Ta,
S.

> 
> But again, I did not study the problem in depth.
> 
> Tomas Mraz, OpenSSL
> 
> On Wed, 2023-08-30 at 15:33 +0100, Stephen Farrell wrote:
>>
>> Hiya,
>>
>> On 30/08/2023 15:27, Tomas Mraz wrote:
>>> It is not clear to me why is this SSL_CTX_ech_raw_decrypt() API
>>> call
>>> needed at all? Why isn't all the processing done internally as part
>>> of
>>> the SSL_connect()/SSL_accept()? There are existing message
>>> callbacks
>>> the applications can hook into to get the messages - so these
>>> should be
>>> extended if needed.
>>
>> It's because the application isn't terminating the TLS
>> session at all in this split-mode case, the (frontend)
>> application is only doing ECH decryption and then the
>> TLS session is established between the client and the
>> backend application. For example, with haproxy as the
>> frontend in what it calls "tcp mode" we hit this case.
>>
>> When haproxy (or other servers) do terminate the TLS
>> session, then yes it all happens internally and this
>> API isn't needed. In haproxy terms, that's called
>> "http mode".
>>
>> Nginx has similar capabilities and probably other
>> servers too.
>>
>> Cheers,
>> S.
>>
>>>
>>> But I did not study the ECH RFC so there might be some obvious
>>> reasons
>>> why it is needed.
>>>
>>> Tomas Mraz, OpenSSL
>>>
>>> On Wed, 2023-08-30 at 15:17 +0100, Stephen Farrell wrote:
>>>>
>>>> Hiya,
>>>>
>>>> I'm wondering about changing the API I defined to allow
>>>> applications to support ECH split-mode, mostly due to
>>>> having now gotten that working for nginx and haproxy,
>>>> with the recent work including support for handling the
>>>> second ClientHello when one hits HRR, and properly
>>>> handling early data when that's present.
>>>>
>>>> The main off-the-wire input for the existing API is an
>>>> encoded (outer) ClientHello (including the record layer
>>>> header) as that's what's easily available when processing
>>>> the first client hello. When ECH decryption works, we
>>>> return the inner ClientHello, similarly encoded.
>>>>
>>>> But it turns out that it may be better to accept a
>>>> different input, for two reasons: the 2nd ClientHello
>>>> when one hits HRR is preceded by 6 octets of (pretend)
>>>> ChangeCipherSuite and secondly, if the first ClientHello
>>>> is accompanied by early data, then the buffer that the
>>>> application has may include that after the ClientHello.
>>>> And in the application code, when not terminating TLS,
>>>> those all tend to be present in one buffer (when the
>>>> client sent 'em) as they likely arrived in one packet.
>>>>
>>>> I had to write basically the same code in nginx and
>>>> haproxy to handle the wrangling of the above and, if
>>>> ECH decryption works, to re-constitute the right buffer
>>>> containing as appropriate the CCS, inner ClientHello and
>>>> early data.
>>>>
>>>> So, I'm thinking of changing the API to accept as input
>>>> a sequence of catenated encoded TLS messages, with the
>>>> success case behaviour being to return a buffer that's
>>>> the same but with the outer ClientHello being replaced
>>>> by the inner. That should eliminate the need to peek
>>>> into the TLS encoding so much in the application.
>>>>
>>>> The current API is below, (or at [1]) and the change
>>>> would be to go from ``outer_ch`` as an input to
>>>> ``tls_msgs_buf`` or some such, likely with a check
>>>> that the input contains an optional CCS, then a CH
>>>> and may have additional octets we don't look into
>>>> (the early_data).
>>>>
>>>> Any thoughts or ideas about potential gotchas welcome.
>>>> (I think I recall someone possibly holding their nose
>>>> about this API when we spoke before, so other comments
>>>> on this are also welcome since I'm likely to be making
>>>> these changes soonish anyway:-)
>>>>
>>>> Thanks,
>>>> S.
>>>>
>>>> [1]
>>>> https://github.com/sftcd/openssl/blob/ECH-draft-13c/include/openssl/ech.h#L117
>>>>
>>>> int SSL_CTX_ech_raw_decrypt(SSL_CTX *ctx,
>>>>           int *decrypted_ok,
>>>>           char **inner_sni, char **outer_sni,
>>>>           unsigned char *outer_ch, size_t outer_len,
>>>>           unsigned char *inner_ch, size_t *inner_len,
>>>>           unsigned char **hrrtok, size_t *toklen);
>>>
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_0xE4D8E9F997A833DD.asc
Type: application/pgp-keys
Size: 1197 bytes
Desc: OpenPGP public key
URL: <https://mta.openssl.org/pipermail/ech/attachments/20230830/e2a03dd4/attachment.asc>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 236 bytes
Desc: OpenPGP digital signature
URL: <https://mta.openssl.org/pipermail/ech/attachments/20230830/e2a03dd4/attachment.sig>


More information about the ech mailing list