<div dir="auto">Our testing strategy is that we have a separate TLS stack for this sort of thing.<div dir="auto"><a href="https://boringssl.googlesource.com/boringssl/+/refs/heads/master/ssl/test/README.md">https://boringssl.googlesource.com/boringssl/+/refs/heads/master/ssl/test/README.md</a></div><div dir="auto"><br></div><div dir="auto">Where possible, I prefer to avoid littering the security-critical, production implementation with options that are always invalid, just needed for testing.</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Apr 18, 2023, 11:14 Stephen Farrell <<a href="mailto:stephen.farrell@cs.tcd.ie">stephen.farrell@cs.tcd.ie</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
Hi David,<br>
<br>
Thanks for all that, which makes sense (and yet again<br>
shows that I don't know about big servers;-). I'll look<br>
at mimicing that approach.<br>
<br>
One question: did you do anything that enables a server<br>
to return a borked ECHConfigList as the retry-config for<br>
test purposes? (I guess I can do up a special server for<br>
that but be nicer were it possible to do such tests as<br>
part of the openssl ``make test`` target.)<br>
<br>
Cheers,<br>
S.<br>
<br>
On 18/04/2023 16:06, David Benjamin wrote:<br>
> I don't think using the most recent config is right. We started with that<br>
> in an early prototype, but quickly realized that doesn't work. For<br>
> BoringSSL's API, when we make a config set, we just let you mark which<br>
> configs are to be sent as retry configs and which aren't. I don't think you<br>
> need a callback.<br>
> <br>
> First, consider a service backed by multiple servers, as in most large<br>
> deployments. It is impossible to atomically deploy something across all<br>
> servers concurrently, but you also need to rotate keys, so your deployment<br>
> model needs to take all this into account. You'll need to satisfy the<br>
> following:<br>
> <br>
> - New ECHConfigs, when they're generated, do not end up in DNS until all<br>
> [or almost all] your servers support it<br>
> - DNS caches should be assumed stale, so servers also need to support the<br>
> last few generations of keys<br>
> - The recovery flow makes a new connection, so it may hit a new server.<br>
> Thus retry configs should also be ones that are expected to be supported by<br>
> all servers<br>
> <br>
> Put all this together and you get something of this rough shape:<br>
> <br>
> - Servers keep a window of N configs. The most recent or so is in the<br>
> process of being rolled out and may not be available on all its peers yet.<br>
> Then there's one config that the server believes is rolled out to all its<br>
> peers. *That* one should be the retry config. Then it also retains N-2 or<br>
> so configs past that to deal with stale caches.<br>
> <br>
> - Periodically, some provisioning process generates a new ECHConfig,<br>
> prepends it to this list, retires the oldest one, and deploys the new<br>
> window to all servers. The new config is *not* put in DNS yet because not<br>
> all servers have it.<br>
> <br>
> - Once the new config is sufficiently rolled out, put the new config in<br>
> DNS, replacing the previous config. Possibly also do a round of rollout to<br>
> all the servers to tell them they can bump the retry config forward by one<br>
> generation, though the generation before that should also work fine<br>
> provided N is large enough.<br>
> <br>
> Second, there may be more than one retry config, hence why it's an<br>
> ECHConfigList. ECH's extensibility model is that the server presents<br>
> multiple ECHConfigs and the client picks one. Suppose an ECH server<br>
> supports both P-256 and X25519 KEMs. It would then provision pairs of<br>
> (P-256, X25519) configs every time it rotates. So while I said N configs<br>
> above, it's really N pairs (or more depending on what your generation size<br>
> is). The thing that goes in DNS and retry configs is one full generation of<br>
> configs. That means your API should be able to express that.<br>
> <br>
> Put another way: the retry config should be the answer to "what would I, an<br>
> individual server instance, want to put in DNS, as of the information I<br>
> have right now?" Having a simple boolean associated with each config<br>
> suffices to let the caller control this, which is what we've done. (Though<br>
> looking back, I see we didn't document the details here as well as I<br>
> thought we had. I'll see about fixing that...)<br>
> <br>
> On Sun, Apr 16, 2023 at 9:08 PM Stephen Farrell <<a href="mailto:stephen.farrell@cs.tcd.ie" target="_blank" rel="noreferrer">stephen.farrell@cs.tcd.ie</a>><br>
> wrote:<br>
> <br>
>><br>
>> Hiya,<br>
>><br>
>> I've been adding code for testing badly encoded ECH stuff<br>
>> to my branch, esp. for EncodedClientHelloInner which is the<br>
>> new thing that could cause server bugs. That's in [1] and<br>
>> seems like a reasonable start to doing that well. And that<br>
>> approach (for testing) also seems to work ok for badly<br>
>> constructed values for the ECH acceptance signal in SH.random<br>
>> or within HRRs.<br>
>><br>
>> One problem I've not solved (within the test harness) is<br>
>> how to do similarly for the retry-config values returned<br>
>> by a server when the wrong ECH public value is used by a<br>
>> client (or if a client GREASEs). Right now, a server (that<br>
>> has some ECH private values loaded) will return the ECHConfig<br>
>> corresponding to the most recently loaded ECH private value,<br>
>> which I think is reasonable.<br>
>><br>
>> However, for testing, it might be useful to enable a server<br>
>> to trigger a callback, so that it could return a borked<br>
>> retry-config value, to check that doesn't result in badness<br>
>> for a client.<br>
>><br>
>> My question is: would it be useful for real servers to be<br>
>> able to choose the retry-config value to return via a new<br>
>> callback? I guess that might be useful for servers that<br>
>> use multiple CDNs, but I'm not at all sure, since I don't<br>
>> get near such servers... hence asking:-)<br>
>><br>
>> Secondary question: if useful, then what params might such<br>
>> a callback need?<br>
>><br>
>> Opinions welcome!<br>
>> Thanks,<br>
>> S.<br>
>><br>
>> [1]<br>
>><br>
>> <a href="https://github.com/sftcd/openssl/blob/ECH-draft-13c/test/echcorrupttest.c#L41" rel="noreferrer noreferrer" target="_blank">https://github.com/sftcd/openssl/blob/ECH-draft-13c/test/echcorrupttest.c#L41</a><br>
>> --<br>
>> ech mailing list<br>
>> <a href="mailto:ech@openssl.org" target="_blank" rel="noreferrer">ech@openssl.org</a><br>
>> <a href="https://mta.openssl.org/mailman/listinfo/ech" rel="noreferrer noreferrer" target="_blank">https://mta.openssl.org/mailman/listinfo/ech</a><br>
>><br>
> <br>
</blockquote></div>