1 /* Copyright 2021 The BoringSSL Authors
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
15 #include <openssl/ssl.h>
16
17 #include <assert.h>
18 #include <string.h>
19
20 #include <algorithm>
21 #include <utility>
22
23 #include <openssl/aead.h>
24 #include <openssl/bytestring.h>
25 #include <openssl/curve25519.h>
26 #include <openssl/err.h>
27 #include <openssl/hkdf.h>
28 #include <openssl/hpke.h>
29 #include <openssl/rand.h>
30
31 #include "internal.h"
32
33
34 BSSL_NAMESPACE_BEGIN
35
36 // ECH reuses the extension code point for the version number.
37 static constexpr uint16_t kECHConfigVersion =
38 TLSEXT_TYPE_encrypted_client_hello;
39
40 static const decltype(&EVP_hpke_aes_128_gcm) kSupportedAEADs[] = {
41 &EVP_hpke_aes_128_gcm,
42 &EVP_hpke_aes_256_gcm,
43 &EVP_hpke_chacha20_poly1305,
44 };
45
get_ech_aead(uint16_t aead_id)46 static const EVP_HPKE_AEAD *get_ech_aead(uint16_t aead_id) {
47 for (const auto aead_func : kSupportedAEADs) {
48 const EVP_HPKE_AEAD *aead = aead_func();
49 if (aead_id == EVP_HPKE_AEAD_id(aead)) {
50 return aead;
51 }
52 }
53 return nullptr;
54 }
55
56 // ssl_client_hello_write_without_extensions serializes |client_hello| into
57 // |out|, omitting the length-prefixed extensions. It serializes individual
58 // fields, starting with |client_hello->version|, and ignores the
59 // |client_hello->client_hello| field. It returns true on success and false on
60 // failure.
ssl_client_hello_write_without_extensions(const SSL_CLIENT_HELLO * client_hello,CBB * out)61 static bool ssl_client_hello_write_without_extensions(
62 const SSL_CLIENT_HELLO *client_hello, CBB *out) {
63 CBB cbb;
64 if (!CBB_add_u16(out, client_hello->version) ||
65 !CBB_add_bytes(out, client_hello->random, client_hello->random_len) ||
66 !CBB_add_u8_length_prefixed(out, &cbb) ||
67 !CBB_add_bytes(&cbb, client_hello->session_id,
68 client_hello->session_id_len)) {
69 return false;
70 }
71 if (SSL_is_dtls(client_hello->ssl)) {
72 if (!CBB_add_u8_length_prefixed(out, &cbb) ||
73 !CBB_add_bytes(&cbb, client_hello->dtls_cookie,
74 client_hello->dtls_cookie_len)) {
75 return false;
76 }
77 }
78 if (!CBB_add_u16_length_prefixed(out, &cbb) ||
79 !CBB_add_bytes(&cbb, client_hello->cipher_suites,
80 client_hello->cipher_suites_len) ||
81 !CBB_add_u8_length_prefixed(out, &cbb) ||
82 !CBB_add_bytes(&cbb, client_hello->compression_methods,
83 client_hello->compression_methods_len) ||
84 !CBB_flush(out)) {
85 return false;
86 }
87 return true;
88 }
89
is_valid_client_hello_inner(SSL * ssl,uint8_t * out_alert,Span<const uint8_t> body)90 static bool is_valid_client_hello_inner(SSL *ssl, uint8_t *out_alert,
91 Span<const uint8_t> body) {
92 // See draft-ietf-tls-esni-13, section 7.1.
93 SSL_CLIENT_HELLO client_hello;
94 CBS extension;
95 if (!ssl_client_hello_init(ssl, &client_hello, body) ||
96 !ssl_client_hello_get_extension(&client_hello, &extension,
97 TLSEXT_TYPE_encrypted_client_hello) ||
98 CBS_len(&extension) != 1 || //
99 CBS_data(&extension)[0] != ECH_CLIENT_INNER ||
100 !ssl_client_hello_get_extension(&client_hello, &extension,
101 TLSEXT_TYPE_supported_versions)) {
102 *out_alert = SSL_AD_ILLEGAL_PARAMETER;
103 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_CLIENT_HELLO_INNER);
104 return false;
105 }
106 // Parse supported_versions and reject TLS versions prior to TLS 1.3. Older
107 // versions are incompatible with ECH.
108 CBS versions;
109 if (!CBS_get_u8_length_prefixed(&extension, &versions) ||
110 CBS_len(&extension) != 0 || //
111 CBS_len(&versions) == 0) {
112 *out_alert = SSL_AD_DECODE_ERROR;
113 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
114 return false;
115 }
116 while (CBS_len(&versions) != 0) {
117 uint16_t version;
118 if (!CBS_get_u16(&versions, &version)) {
119 *out_alert = SSL_AD_DECODE_ERROR;
120 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
121 return false;
122 }
123 if (version == SSL3_VERSION || version == TLS1_VERSION ||
124 version == TLS1_1_VERSION || version == TLS1_2_VERSION ||
125 version == DTLS1_VERSION || version == DTLS1_2_VERSION) {
126 *out_alert = SSL_AD_ILLEGAL_PARAMETER;
127 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_CLIENT_HELLO_INNER);
128 return false;
129 }
130 }
131 return true;
132 }
133
ssl_decode_client_hello_inner(SSL * ssl,uint8_t * out_alert,Array<uint8_t> * out_client_hello_inner,Span<const uint8_t> encoded_client_hello_inner,const SSL_CLIENT_HELLO * client_hello_outer)134 bool ssl_decode_client_hello_inner(
135 SSL *ssl, uint8_t *out_alert, Array<uint8_t> *out_client_hello_inner,
136 Span<const uint8_t> encoded_client_hello_inner,
137 const SSL_CLIENT_HELLO *client_hello_outer) {
138 SSL_CLIENT_HELLO client_hello_inner;
139 CBS cbs = encoded_client_hello_inner;
140 if (!ssl_parse_client_hello_with_trailing_data(ssl, &cbs,
141 &client_hello_inner)) {
142 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
143 return false;
144 }
145 // The remaining data is padding.
146 uint8_t padding;
147 while (CBS_get_u8(&cbs, &padding)) {
148 if (padding != 0) {
149 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
150 *out_alert = SSL_AD_ILLEGAL_PARAMETER;
151 return false;
152 }
153 }
154
155 // TLS 1.3 ClientHellos must have extensions, and EncodedClientHelloInners use
156 // ClientHelloOuter's session_id.
157 if (client_hello_inner.extensions_len == 0 ||
158 client_hello_inner.session_id_len != 0) {
159 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
160 return false;
161 }
162 client_hello_inner.session_id = client_hello_outer->session_id;
163 client_hello_inner.session_id_len = client_hello_outer->session_id_len;
164
165 // Begin serializing a message containing the ClientHelloInner in |cbb|.
166 ScopedCBB cbb;
167 CBB body, extensions_cbb;
168 if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CLIENT_HELLO) ||
169 !ssl_client_hello_write_without_extensions(&client_hello_inner, &body) ||
170 !CBB_add_u16_length_prefixed(&body, &extensions_cbb)) {
171 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
172 return false;
173 }
174
175 auto inner_extensions =
176 Span(client_hello_inner.extensions, client_hello_inner.extensions_len);
177 CBS ext_list_wrapper;
178 if (!ssl_client_hello_get_extension(&client_hello_inner, &ext_list_wrapper,
179 TLSEXT_TYPE_ech_outer_extensions)) {
180 // No ech_outer_extensions. Copy everything.
181 if (!CBB_add_bytes(&extensions_cbb, inner_extensions.data(),
182 inner_extensions.size())) {
183 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
184 return false;
185 }
186 } else {
187 const size_t offset = CBS_data(&ext_list_wrapper) - inner_extensions.data();
188 auto inner_extensions_before =
189 inner_extensions.subspan(0, offset - 4 /* extension header */);
190 auto inner_extensions_after =
191 inner_extensions.subspan(offset + CBS_len(&ext_list_wrapper));
192 if (!CBB_add_bytes(&extensions_cbb, inner_extensions_before.data(),
193 inner_extensions_before.size())) {
194 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
195 return false;
196 }
197
198 // Expand ech_outer_extensions. See draft-ietf-tls-esni-13, Appendix B.
199 CBS ext_list;
200 if (!CBS_get_u8_length_prefixed(&ext_list_wrapper, &ext_list) ||
201 CBS_len(&ext_list) == 0 || CBS_len(&ext_list_wrapper) != 0) {
202 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
203 return false;
204 }
205 CBS outer_extensions;
206 CBS_init(&outer_extensions, client_hello_outer->extensions,
207 client_hello_outer->extensions_len);
208 while (CBS_len(&ext_list) != 0) {
209 // Find the next extension to copy.
210 uint16_t want;
211 if (!CBS_get_u16(&ext_list, &want)) {
212 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
213 return false;
214 }
215 // The ECH extension itself is not in the AAD and may not be referenced.
216 if (want == TLSEXT_TYPE_encrypted_client_hello) {
217 *out_alert = SSL_AD_ILLEGAL_PARAMETER;
218 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_OUTER_EXTENSION);
219 return false;
220 }
221 // Seek to |want| in |outer_extensions|. |ext_list| is required to match
222 // ClientHelloOuter in order.
223 uint16_t found;
224 CBS ext_body;
225 do {
226 if (CBS_len(&outer_extensions) == 0) {
227 *out_alert = SSL_AD_ILLEGAL_PARAMETER;
228 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_OUTER_EXTENSION);
229 return false;
230 }
231 if (!CBS_get_u16(&outer_extensions, &found) ||
232 !CBS_get_u16_length_prefixed(&outer_extensions, &ext_body)) {
233 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
234 return false;
235 }
236 } while (found != want);
237 // Copy the extension.
238 if (!CBB_add_u16(&extensions_cbb, found) ||
239 !CBB_add_u16(&extensions_cbb, CBS_len(&ext_body)) ||
240 !CBB_add_bytes(&extensions_cbb, CBS_data(&ext_body),
241 CBS_len(&ext_body))) {
242 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
243 return false;
244 }
245 }
246
247 if (!CBB_add_bytes(&extensions_cbb, inner_extensions_after.data(),
248 inner_extensions_after.size())) {
249 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
250 return false;
251 }
252 }
253 if (!CBB_flush(&body)) {
254 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
255 return false;
256 }
257
258 if (!is_valid_client_hello_inner(ssl, out_alert,
259 Span(CBB_data(&body), CBB_len(&body)))) {
260 return false;
261 }
262
263 if (!ssl->method->finish_message(ssl, cbb.get(), out_client_hello_inner)) {
264 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
265 return false;
266 }
267 return true;
268 }
269
ssl_client_hello_decrypt(SSL_HANDSHAKE * hs,uint8_t * out_alert,bool * out_is_decrypt_error,Array<uint8_t> * out,const SSL_CLIENT_HELLO * client_hello_outer,Span<const uint8_t> payload)270 bool ssl_client_hello_decrypt(SSL_HANDSHAKE *hs, uint8_t *out_alert,
271 bool *out_is_decrypt_error, Array<uint8_t> *out,
272 const SSL_CLIENT_HELLO *client_hello_outer,
273 Span<const uint8_t> payload) {
274 *out_is_decrypt_error = false;
275
276 // The ClientHelloOuterAAD is |client_hello_outer| with |payload| (which must
277 // point within |client_hello_outer->extensions|) replaced with zeros. See
278 // draft-ietf-tls-esni-13, section 5.2.
279 Array<uint8_t> aad;
280 if (!aad.CopyFrom(Span(client_hello_outer->client_hello,
281 client_hello_outer->client_hello_len))) {
282 *out_alert = SSL_AD_INTERNAL_ERROR;
283 return false;
284 }
285
286 // We assert with |uintptr_t| because the comparison would be UB if they
287 // didn't alias.
288 assert(reinterpret_cast<uintptr_t>(client_hello_outer->extensions) <=
289 reinterpret_cast<uintptr_t>(payload.data()));
290 assert(reinterpret_cast<uintptr_t>(client_hello_outer->extensions +
291 client_hello_outer->extensions_len) >=
292 reinterpret_cast<uintptr_t>(payload.data() + payload.size()));
293 Span<uint8_t> payload_aad = Span(aad).subspan(
294 payload.data() - client_hello_outer->client_hello, payload.size());
295 OPENSSL_memset(payload_aad.data(), 0, payload_aad.size());
296
297 // Decrypt the EncodedClientHelloInner.
298 Array<uint8_t> encoded;
299 #if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
300 // In fuzzer mode, disable encryption to improve coverage. We reserve a short
301 // input to signal decryption failure, so the fuzzer can explore fallback to
302 // ClientHelloOuter.
303 const uint8_t kBadPayload[] = {0xff};
304 if (payload == kBadPayload) {
305 *out_alert = SSL_AD_DECRYPT_ERROR;
306 *out_is_decrypt_error = true;
307 OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED);
308 return false;
309 }
310 if (!encoded.CopyFrom(payload)) {
311 *out_alert = SSL_AD_INTERNAL_ERROR;
312 return false;
313 }
314 #else
315 if (!encoded.InitForOverwrite(payload.size())) {
316 *out_alert = SSL_AD_INTERNAL_ERROR;
317 return false;
318 }
319 size_t len;
320 if (!EVP_HPKE_CTX_open(hs->ech_hpke_ctx.get(), encoded.data(), &len,
321 encoded.size(), payload.data(), payload.size(),
322 aad.data(), aad.size())) {
323 *out_alert = SSL_AD_DECRYPT_ERROR;
324 *out_is_decrypt_error = true;
325 OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED);
326 return false;
327 }
328 encoded.Shrink(len);
329 #endif
330
331 if (!ssl_decode_client_hello_inner(hs->ssl, out_alert, out, encoded,
332 client_hello_outer)) {
333 return false;
334 }
335
336 ssl_do_msg_callback(hs->ssl, /*is_write=*/0, SSL3_RT_CLIENT_HELLO_INNER,
337 *out);
338 return true;
339 }
340
is_hex_component(Span<const uint8_t> in)341 static bool is_hex_component(Span<const uint8_t> in) {
342 if (in.size() < 2 || in[0] != '0' || (in[1] != 'x' && in[1] != 'X')) {
343 return false;
344 }
345 for (uint8_t b : in.subspan(2)) {
346 if (!OPENSSL_isxdigit(b)) {
347 return false;
348 }
349 }
350 return true;
351 }
352
is_decimal_component(Span<const uint8_t> in)353 static bool is_decimal_component(Span<const uint8_t> in) {
354 if (in.empty()) {
355 return false;
356 }
357 for (uint8_t b : in) {
358 if (!('0' <= b && b <= '9')) {
359 return false;
360 }
361 }
362 return true;
363 }
364
ssl_is_valid_ech_public_name(Span<const uint8_t> public_name)365 bool ssl_is_valid_ech_public_name(Span<const uint8_t> public_name) {
366 // See draft-ietf-tls-esni-13, Section 4 and RFC 5890, Section 2.3.1. The
367 // public name must be a dot-separated sequence of LDH labels and not begin or
368 // end with a dot.
369 auto remaining = public_name;
370 if (remaining.empty()) {
371 return false;
372 }
373 Span<const uint8_t> last;
374 while (!remaining.empty()) {
375 // Find the next dot-separated component.
376 auto dot = std::find(remaining.begin(), remaining.end(), '.');
377 Span<const uint8_t> component;
378 if (dot == remaining.end()) {
379 component = remaining;
380 last = component;
381 remaining = Span<const uint8_t>();
382 } else {
383 component = remaining.subspan(0, dot - remaining.begin());
384 // Skip the dot.
385 remaining = remaining.subspan(dot - remaining.begin() + 1);
386 if (remaining.empty()) {
387 // Trailing dots are not allowed.
388 return false;
389 }
390 }
391 // |component| must be a valid LDH label. Checking for empty components also
392 // rejects leading dots.
393 if (component.empty() || component.size() > 63 ||
394 component.front() == '-' || component.back() == '-') {
395 return false;
396 }
397 for (uint8_t c : component) {
398 if (!OPENSSL_isalnum(c) && c != '-') {
399 return false;
400 }
401 }
402 }
403
404 // The WHATWG URL parser additionally does not allow any DNS names that end in
405 // a numeric component. See:
406 // https://url.spec.whatwg.org/#concept-host-parser
407 // https://url.spec.whatwg.org/#ends-in-a-number-checker
408 //
409 // The WHATWG parser is formulated in terms of parsing decimal, octal, and
410 // hex, along with a separate ASCII digits check. The ASCII digits check
411 // subsumes the decimal and octal check, so we only need to check two cases.
412 return !is_hex_component(last) && !is_decimal_component(last);
413 }
414
parse_ech_config(CBS * cbs,ECHConfig * out,bool * out_supported,bool all_extensions_mandatory)415 static bool parse_ech_config(CBS *cbs, ECHConfig *out, bool *out_supported,
416 bool all_extensions_mandatory) {
417 uint16_t version;
418 CBS orig = *cbs;
419 CBS contents;
420 if (!CBS_get_u16(cbs, &version) ||
421 !CBS_get_u16_length_prefixed(cbs, &contents)) {
422 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
423 return false;
424 }
425
426 if (version != kECHConfigVersion) {
427 *out_supported = false;
428 return true;
429 }
430
431 // Make a copy of the ECHConfig and parse from it, so the results alias into
432 // the saved copy.
433 if (!out->raw.CopyFrom(
434 Span(CBS_data(&orig), CBS_len(&orig) - CBS_len(cbs)))) {
435 return false;
436 }
437
438 CBS ech_config(out->raw);
439 CBS public_name, public_key, cipher_suites, extensions;
440 if (!CBS_skip(&ech_config, 2) || // version
441 !CBS_get_u16_length_prefixed(&ech_config, &contents) ||
442 !CBS_get_u8(&contents, &out->config_id) ||
443 !CBS_get_u16(&contents, &out->kem_id) ||
444 !CBS_get_u16_length_prefixed(&contents, &public_key) ||
445 CBS_len(&public_key) == 0 ||
446 !CBS_get_u16_length_prefixed(&contents, &cipher_suites) ||
447 CBS_len(&cipher_suites) == 0 || CBS_len(&cipher_suites) % 4 != 0 ||
448 !CBS_get_u8(&contents, &out->maximum_name_length) ||
449 !CBS_get_u8_length_prefixed(&contents, &public_name) ||
450 CBS_len(&public_name) == 0 ||
451 !CBS_get_u16_length_prefixed(&contents, &extensions) ||
452 CBS_len(&contents) != 0) {
453 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
454 return false;
455 }
456
457 if (!ssl_is_valid_ech_public_name(public_name)) {
458 // TODO(https://crbug.com/boringssl/275): The draft says ECHConfigs with
459 // invalid public names should be ignored, but LDH syntax failures are
460 // unambiguously invalid.
461 *out_supported = false;
462 return true;
463 }
464
465 out->public_key = public_key;
466 out->public_name = public_name;
467 // This function does not ensure |out->kem_id| and |out->cipher_suites| use
468 // supported algorithms. The caller must do this.
469 out->cipher_suites = cipher_suites;
470
471 bool has_unknown_mandatory_extension = false;
472 while (CBS_len(&extensions) != 0) {
473 uint16_t type;
474 CBS body;
475 if (!CBS_get_u16(&extensions, &type) ||
476 !CBS_get_u16_length_prefixed(&extensions, &body)) {
477 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
478 return false;
479 }
480 // We currently do not support any extensions.
481 if (type & 0x8000 || all_extensions_mandatory) {
482 // Extension numbers with the high bit set are mandatory. Continue parsing
483 // to enforce syntax, but we will ultimately ignore this ECHConfig as a
484 // client and reject it as a server.
485 has_unknown_mandatory_extension = true;
486 }
487 }
488
489 *out_supported = !has_unknown_mandatory_extension;
490 return true;
491 }
492
Init(Span<const uint8_t> ech_config,const EVP_HPKE_KEY * key,bool is_retry_config)493 bool ECHServerConfig::Init(Span<const uint8_t> ech_config,
494 const EVP_HPKE_KEY *key, bool is_retry_config) {
495 is_retry_config_ = is_retry_config;
496
497 // Parse the ECHConfig, rejecting all unsupported parameters and extensions.
498 // Unlike most server options, ECH's server configuration is serialized and
499 // configured in both the server and DNS. If the caller configures an
500 // unsupported parameter, this is a deployment error. To catch these errors,
501 // we fail early.
502 CBS cbs = ech_config;
503 bool supported;
504 if (!parse_ech_config(&cbs, &ech_config_, &supported,
505 /*all_extensions_mandatory=*/true)) {
506 return false;
507 }
508 if (CBS_len(&cbs) != 0) {
509 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
510 return false;
511 }
512 if (!supported) {
513 OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_ECH_SERVER_CONFIG);
514 return false;
515 }
516
517 CBS cipher_suites = ech_config_.cipher_suites;
518 while (CBS_len(&cipher_suites) > 0) {
519 uint16_t kdf_id, aead_id;
520 if (!CBS_get_u16(&cipher_suites, &kdf_id) ||
521 !CBS_get_u16(&cipher_suites, &aead_id)) {
522 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
523 return false;
524 }
525 // The server promises to support every option in the ECHConfig, so reject
526 // any unsupported cipher suites.
527 if (kdf_id != EVP_HPKE_HKDF_SHA256 || get_ech_aead(aead_id) == nullptr) {
528 OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_ECH_SERVER_CONFIG);
529 return false;
530 }
531 }
532
533 // Check the public key in the ECHConfig matches |key|.
534 uint8_t expected_public_key[EVP_HPKE_MAX_PUBLIC_KEY_LENGTH];
535 size_t expected_public_key_len;
536 if (!EVP_HPKE_KEY_public_key(key, expected_public_key,
537 &expected_public_key_len,
538 sizeof(expected_public_key))) {
539 return false;
540 }
541 if (ech_config_.kem_id != EVP_HPKE_KEM_id(EVP_HPKE_KEY_kem(key)) ||
542 Span(expected_public_key, expected_public_key_len) !=
543 ech_config_.public_key) {
544 OPENSSL_PUT_ERROR(SSL, SSL_R_ECH_SERVER_CONFIG_AND_PRIVATE_KEY_MISMATCH);
545 return false;
546 }
547
548 if (!EVP_HPKE_KEY_copy(key_.get(), key)) {
549 return false;
550 }
551
552 return true;
553 }
554
SetupContext(EVP_HPKE_CTX * ctx,uint16_t kdf_id,uint16_t aead_id,Span<const uint8_t> enc) const555 bool ECHServerConfig::SetupContext(EVP_HPKE_CTX *ctx, uint16_t kdf_id,
556 uint16_t aead_id,
557 Span<const uint8_t> enc) const {
558 // Check the cipher suite is supported by this ECHServerConfig.
559 CBS cbs(ech_config_.cipher_suites);
560 bool cipher_ok = false;
561 while (CBS_len(&cbs) != 0) {
562 uint16_t supported_kdf_id, supported_aead_id;
563 if (!CBS_get_u16(&cbs, &supported_kdf_id) ||
564 !CBS_get_u16(&cbs, &supported_aead_id)) {
565 return false;
566 }
567 if (kdf_id == supported_kdf_id && aead_id == supported_aead_id) {
568 cipher_ok = true;
569 break;
570 }
571 }
572 if (!cipher_ok) {
573 return false;
574 }
575
576 static const uint8_t kInfoLabel[] = "tls ech";
577 ScopedCBB info_cbb;
578 if (!CBB_init(info_cbb.get(), sizeof(kInfoLabel) + ech_config_.raw.size()) ||
579 !CBB_add_bytes(info_cbb.get(), kInfoLabel,
580 sizeof(kInfoLabel) /* includes trailing NUL */) ||
581 !CBB_add_bytes(info_cbb.get(), ech_config_.raw.data(),
582 ech_config_.raw.size())) {
583 return false;
584 }
585
586 assert(kdf_id == EVP_HPKE_HKDF_SHA256);
587 assert(get_ech_aead(aead_id) != NULL);
588 return EVP_HPKE_CTX_setup_recipient(ctx, key_.get(), EVP_hpke_hkdf_sha256(),
589 get_ech_aead(aead_id), enc.data(),
590 enc.size(), CBB_data(info_cbb.get()),
591 CBB_len(info_cbb.get()));
592 }
593
ssl_is_valid_ech_config_list(Span<const uint8_t> ech_config_list)594 bool ssl_is_valid_ech_config_list(Span<const uint8_t> ech_config_list) {
595 CBS cbs = ech_config_list, child;
596 if (!CBS_get_u16_length_prefixed(&cbs, &child) || //
597 CBS_len(&child) == 0 || //
598 CBS_len(&cbs) > 0) {
599 return false;
600 }
601 while (CBS_len(&child) > 0) {
602 ECHConfig ech_config;
603 bool supported;
604 if (!parse_ech_config(&child, &ech_config, &supported,
605 /*all_extensions_mandatory=*/false)) {
606 return false;
607 }
608 }
609 return true;
610 }
611
select_ech_cipher_suite(const EVP_HPKE_KDF ** out_kdf,const EVP_HPKE_AEAD ** out_aead,Span<const uint8_t> cipher_suites,const bool has_aes_hardware)612 static bool select_ech_cipher_suite(const EVP_HPKE_KDF **out_kdf,
613 const EVP_HPKE_AEAD **out_aead,
614 Span<const uint8_t> cipher_suites,
615 const bool has_aes_hardware) {
616 const EVP_HPKE_AEAD *aead = nullptr;
617 CBS cbs = cipher_suites;
618 while (CBS_len(&cbs) != 0) {
619 uint16_t kdf_id, aead_id;
620 if (!CBS_get_u16(&cbs, &kdf_id) || //
621 !CBS_get_u16(&cbs, &aead_id)) {
622 return false;
623 }
624 // Pick the first common cipher suite, but prefer ChaCha20-Poly1305 if we
625 // don't have AES hardware.
626 const EVP_HPKE_AEAD *candidate = get_ech_aead(aead_id);
627 if (kdf_id != EVP_HPKE_HKDF_SHA256 || candidate == nullptr) {
628 continue;
629 }
630 if (aead == nullptr ||
631 (!has_aes_hardware && aead_id == EVP_HPKE_CHACHA20_POLY1305)) {
632 aead = candidate;
633 }
634 }
635 if (aead == nullptr) {
636 return false;
637 }
638
639 *out_kdf = EVP_hpke_hkdf_sha256();
640 *out_aead = aead;
641 return true;
642 }
643
ssl_select_ech_config(SSL_HANDSHAKE * hs,Span<uint8_t> out_enc,size_t * out_enc_len)644 bool ssl_select_ech_config(SSL_HANDSHAKE *hs, Span<uint8_t> out_enc,
645 size_t *out_enc_len) {
646 *out_enc_len = 0;
647 if (hs->max_version < TLS1_3_VERSION) {
648 // ECH requires TLS 1.3.
649 return true;
650 }
651
652 if (!hs->config->client_ech_config_list.empty()) {
653 CBS cbs = CBS(hs->config->client_ech_config_list);
654 CBS child;
655 if (!CBS_get_u16_length_prefixed(&cbs, &child) || //
656 CBS_len(&child) == 0 || //
657 CBS_len(&cbs) > 0) {
658 return false;
659 }
660 // Look for the first ECHConfig with supported parameters.
661 while (CBS_len(&child) > 0) {
662 ECHConfig ech_config;
663 bool supported;
664 if (!parse_ech_config(&child, &ech_config, &supported,
665 /*all_extensions_mandatory=*/false)) {
666 return false;
667 }
668 const EVP_HPKE_KEM *kem = EVP_hpke_x25519_hkdf_sha256();
669 const EVP_HPKE_KDF *kdf;
670 const EVP_HPKE_AEAD *aead;
671 if (supported && //
672 ech_config.kem_id == EVP_HPKE_DHKEM_X25519_HKDF_SHA256 &&
673 select_ech_cipher_suite(&kdf, &aead, ech_config.cipher_suites,
674 hs->ssl->config->aes_hw_override
675 ? hs->ssl->config->aes_hw_override_value
676 : EVP_has_aes_hardware())) {
677 ScopedCBB info;
678 static const uint8_t kInfoLabel[] = "tls ech"; // includes trailing NUL
679 if (!CBB_init(info.get(), sizeof(kInfoLabel) + ech_config.raw.size()) ||
680 !CBB_add_bytes(info.get(), kInfoLabel, sizeof(kInfoLabel)) ||
681 !CBB_add_bytes(info.get(), ech_config.raw.data(),
682 ech_config.raw.size())) {
683 return false;
684 }
685
686 if (!EVP_HPKE_CTX_setup_sender(
687 hs->ech_hpke_ctx.get(), out_enc.data(), out_enc_len,
688 out_enc.size(), kem, kdf, aead, ech_config.public_key.data(),
689 ech_config.public_key.size(), CBB_data(info.get()),
690 CBB_len(info.get())) ||
691 !hs->inner_transcript.Init()) {
692 return false;
693 }
694
695 hs->selected_ech_config = MakeUnique<ECHConfig>(std::move(ech_config));
696 return hs->selected_ech_config != nullptr;
697 }
698 }
699 }
700
701 return true;
702 }
703
aead_overhead(const EVP_HPKE_AEAD * aead)704 static size_t aead_overhead(const EVP_HPKE_AEAD *aead) {
705 #if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
706 // TODO(https://crbug.com/boringssl/275): Having to adjust the overhead
707 // everywhere is tedious. Change fuzzer mode to append a fake tag but still
708 // otherwise be cleartext, refresh corpora, and then inline this function.
709 return 0;
710 #else
711 return EVP_AEAD_max_overhead(EVP_HPKE_AEAD_aead(aead));
712 #endif
713 }
714
715 // random_size returns a random value between |min| and |max|, inclusive.
random_size(size_t min,size_t max)716 static size_t random_size(size_t min, size_t max) {
717 assert(min < max);
718 size_t value;
719 RAND_bytes(reinterpret_cast<uint8_t *>(&value), sizeof(value));
720 return value % (max - min + 1) + min;
721 }
722
setup_ech_grease(SSL_HANDSHAKE * hs)723 static bool setup_ech_grease(SSL_HANDSHAKE *hs) {
724 assert(!hs->selected_ech_config);
725 if (hs->max_version < TLS1_3_VERSION || !hs->config->ech_grease_enabled) {
726 return true;
727 }
728
729 const uint16_t kdf_id = EVP_HPKE_HKDF_SHA256;
730 const bool has_aes_hw = hs->ssl->config->aes_hw_override
731 ? hs->ssl->config->aes_hw_override_value
732 : EVP_has_aes_hardware();
733 const EVP_HPKE_AEAD *aead =
734 has_aes_hw ? EVP_hpke_aes_128_gcm() : EVP_hpke_chacha20_poly1305();
735 static_assert(ssl_grease_ech_config_id < sizeof(hs->grease_seed),
736 "hs->grease_seed is too small");
737 uint8_t config_id = hs->grease_seed[ssl_grease_ech_config_id];
738
739 uint8_t enc[X25519_PUBLIC_VALUE_LEN];
740 uint8_t private_key_unused[X25519_PRIVATE_KEY_LEN];
741 X25519_keypair(enc, private_key_unused);
742
743 // To determine a plausible length for the payload, we estimate the size of a
744 // typical EncodedClientHelloInner without resumption:
745 //
746 // 2+32+1+2 version, random, legacy_session_id, legacy_compression_methods
747 // 2+4*2 cipher_suites (three TLS 1.3 ciphers, GREASE)
748 // 2 extensions prefix
749 // 5 inner encrypted_client_hello
750 // 4+1+2*2 supported_versions (TLS 1.3, GREASE)
751 // 4+1+10*2 outer_extensions (key_share, sigalgs, sct, alpn,
752 // supported_groups, status_request, psk_key_exchange_modes,
753 // compress_certificate, GREASE x2)
754 //
755 // The server_name extension has an overhead of 9 bytes. For now, arbitrarily
756 // estimate maximum_name_length to be between 32 and 100 bytes. Then round up
757 // to a multiple of 32, to match draft-ietf-tls-esni-13, section 6.1.3.
758 const size_t payload_len =
759 32 * random_size(128 / 32, 224 / 32) + aead_overhead(aead);
760 bssl::ScopedCBB cbb;
761 CBB enc_cbb, payload_cbb;
762 uint8_t *payload;
763 if (!CBB_init(cbb.get(), 256) || !CBB_add_u16(cbb.get(), kdf_id) ||
764 !CBB_add_u16(cbb.get(), EVP_HPKE_AEAD_id(aead)) ||
765 !CBB_add_u8(cbb.get(), config_id) ||
766 !CBB_add_u16_length_prefixed(cbb.get(), &enc_cbb) ||
767 !CBB_add_bytes(&enc_cbb, enc, sizeof(enc)) ||
768 !CBB_add_u16_length_prefixed(cbb.get(), &payload_cbb) ||
769 !CBB_add_space(&payload_cbb, &payload, payload_len) ||
770 !RAND_bytes(payload, payload_len) ||
771 !CBBFinishArray(cbb.get(), &hs->ech_client_outer)) {
772 return false;
773 }
774 return true;
775 }
776
ssl_encrypt_client_hello(SSL_HANDSHAKE * hs,Span<const uint8_t> enc)777 bool ssl_encrypt_client_hello(SSL_HANDSHAKE *hs, Span<const uint8_t> enc) {
778 SSL *const ssl = hs->ssl;
779 if (!hs->selected_ech_config) {
780 return setup_ech_grease(hs);
781 }
782
783 // Construct ClientHelloInner and EncodedClientHelloInner. See
784 // draft-ietf-tls-esni-13, sections 5.1 and 6.1.
785 ScopedCBB cbb, encoded_cbb;
786 CBB body;
787 bool needs_psk_binder;
788 Array<uint8_t> hello_inner;
789 if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CLIENT_HELLO) ||
790 !CBB_init(encoded_cbb.get(), 256) ||
791 !ssl_write_client_hello_without_extensions(hs, &body,
792 ssl_client_hello_inner,
793 /*empty_session_id=*/false) ||
794 !ssl_write_client_hello_without_extensions(hs, encoded_cbb.get(),
795 ssl_client_hello_inner,
796 /*empty_session_id=*/true) ||
797 !ssl_add_clienthello_tlsext(hs, &body, encoded_cbb.get(),
798 &needs_psk_binder, ssl_client_hello_inner,
799 CBB_len(&body)) ||
800 !ssl->method->finish_message(ssl, cbb.get(), &hello_inner)) {
801 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
802 return false;
803 }
804
805 if (needs_psk_binder) {
806 size_t binder_len;
807 if (!tls13_write_psk_binder(hs, hs->inner_transcript, Span(hello_inner),
808 &binder_len)) {
809 return false;
810 }
811 // Also update the EncodedClientHelloInner.
812 auto encoded_binder =
813 Span(const_cast<uint8_t *>(CBB_data(encoded_cbb.get())),
814 CBB_len(encoded_cbb.get()))
815 .last(binder_len);
816 auto hello_inner_binder = Span(hello_inner).last(binder_len);
817 OPENSSL_memcpy(encoded_binder.data(), hello_inner_binder.data(),
818 binder_len);
819 }
820
821 ssl_do_msg_callback(ssl, /*is_write=*/1, SSL3_RT_CLIENT_HELLO_INNER,
822 hello_inner);
823 if (!hs->inner_transcript.Update(hello_inner)) {
824 return false;
825 }
826
827 // Pad the EncodedClientHelloInner. See draft-ietf-tls-esni-13, section 6.1.3.
828 size_t padding_len = 0;
829 size_t maximum_name_length = hs->selected_ech_config->maximum_name_length;
830 if (ssl->hostname) {
831 size_t hostname_len = strlen(ssl->hostname.get());
832 if (hostname_len <= maximum_name_length) {
833 padding_len = maximum_name_length - hostname_len;
834 }
835 } else {
836 // No SNI. Pad up to |maximum_name_length|, including server_name extension
837 // overhead.
838 padding_len = 9 + maximum_name_length;
839 }
840 // Pad the whole thing to a multiple of 32 bytes.
841 padding_len += 31 - ((CBB_len(encoded_cbb.get()) + padding_len - 1) % 32);
842 Array<uint8_t> encoded;
843 if (!CBB_add_zeros(encoded_cbb.get(), padding_len) ||
844 !CBBFinishArray(encoded_cbb.get(), &encoded)) {
845 return false;
846 }
847
848 // Encrypt |encoded|. See draft-ietf-tls-esni-13, section 6.1.1. First,
849 // assemble the extension with a placeholder value for ClientHelloOuterAAD.
850 // See draft-ietf-tls-esni-13, section 5.2.
851 const EVP_HPKE_KDF *kdf = EVP_HPKE_CTX_kdf(hs->ech_hpke_ctx.get());
852 const EVP_HPKE_AEAD *aead = EVP_HPKE_CTX_aead(hs->ech_hpke_ctx.get());
853 size_t payload_len = encoded.size() + aead_overhead(aead);
854 CBB enc_cbb, payload_cbb;
855 if (!CBB_init(cbb.get(), 256) ||
856 !CBB_add_u16(cbb.get(), EVP_HPKE_KDF_id(kdf)) ||
857 !CBB_add_u16(cbb.get(), EVP_HPKE_AEAD_id(aead)) ||
858 !CBB_add_u8(cbb.get(), hs->selected_ech_config->config_id) ||
859 !CBB_add_u16_length_prefixed(cbb.get(), &enc_cbb) ||
860 !CBB_add_bytes(&enc_cbb, enc.data(), enc.size()) ||
861 !CBB_add_u16_length_prefixed(cbb.get(), &payload_cbb) ||
862 !CBB_add_zeros(&payload_cbb, payload_len) ||
863 !CBBFinishArray(cbb.get(), &hs->ech_client_outer)) {
864 return false;
865 }
866
867 // Construct ClientHelloOuterAAD.
868 // TODO(https://crbug.com/boringssl/275): This ends up constructing the
869 // ClientHelloOuter twice. Instead, reuse |aad| for the ClientHello, now that
870 // draft-12 made the length prefixes match.
871 bssl::ScopedCBB aad;
872 if (!CBB_init(aad.get(), 256) ||
873 !ssl_write_client_hello_without_extensions(hs, aad.get(),
874 ssl_client_hello_outer,
875 /*empty_session_id=*/false) ||
876 !ssl_add_clienthello_tlsext(hs, aad.get(), /*out_encoded=*/nullptr,
877 &needs_psk_binder, ssl_client_hello_outer,
878 CBB_len(aad.get()))) {
879 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
880 return false;
881 }
882
883 // ClientHelloOuter may not require a PSK binder. Otherwise, we have a
884 // circular dependency.
885 assert(!needs_psk_binder);
886
887 // Replace the payload in |hs->ech_client_outer| with the encrypted value.
888 auto payload_span = Span(hs->ech_client_outer).last(payload_len);
889 #if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
890 // In fuzzer mode, the server expects a cleartext payload.
891 assert(payload_span.size() == encoded.size());
892 OPENSSL_memcpy(payload_span.data(), encoded.data(), encoded.size());
893 #else
894 if (!EVP_HPKE_CTX_seal(hs->ech_hpke_ctx.get(), payload_span.data(),
895 &payload_len, payload_span.size(), encoded.data(),
896 encoded.size(), CBB_data(aad.get()),
897 CBB_len(aad.get())) ||
898 payload_len != payload_span.size()) {
899 return false;
900 }
901 #endif // BORINGSSL_UNSAFE_FUZZER_MODE
902
903 return true;
904 }
905
906 BSSL_NAMESPACE_END
907
908 using namespace bssl;
909
SSL_set_enable_ech_grease(SSL * ssl,int enable)910 void SSL_set_enable_ech_grease(SSL *ssl, int enable) {
911 if (!ssl->config) {
912 return;
913 }
914 ssl->config->ech_grease_enabled = !!enable;
915 }
916
SSL_set1_ech_config_list(SSL * ssl,const uint8_t * ech_config_list,size_t ech_config_list_len)917 int SSL_set1_ech_config_list(SSL *ssl, const uint8_t *ech_config_list,
918 size_t ech_config_list_len) {
919 if (!ssl->config) {
920 return 0;
921 }
922
923 auto span = Span(ech_config_list, ech_config_list_len);
924 if (!ssl_is_valid_ech_config_list(span)) {
925 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_ECH_CONFIG_LIST);
926 return 0;
927 }
928 return ssl->config->client_ech_config_list.CopyFrom(span);
929 }
930
SSL_get0_ech_name_override(const SSL * ssl,const char ** out_name,size_t * out_name_len)931 void SSL_get0_ech_name_override(const SSL *ssl, const char **out_name,
932 size_t *out_name_len) {
933 // When ECH is rejected, we use the public name. Note that, if
934 // |SSL_CTX_set_reverify_on_resume| is enabled, we reverify the certificate
935 // before the 0-RTT point. If also offering ECH, we verify as if
936 // ClientHelloInner was accepted and do not override. This works because, at
937 // this point, |ech_status| will be |ssl_ech_none|. See the
938 // ECH-Client-Reject-EarlyDataReject-OverrideNameOnRetry tests in runner.go.
939 const SSL_HANDSHAKE *hs = ssl->s3->hs.get();
940 if (!ssl->server && hs && ssl->s3->ech_status == ssl_ech_rejected) {
941 *out_name = reinterpret_cast<const char *>(
942 hs->selected_ech_config->public_name.data());
943 *out_name_len = hs->selected_ech_config->public_name.size();
944 } else {
945 *out_name = nullptr;
946 *out_name_len = 0;
947 }
948 }
949
SSL_get0_ech_retry_configs(const SSL * ssl,const uint8_t ** out_retry_configs,size_t * out_retry_configs_len)950 void SSL_get0_ech_retry_configs(const SSL *ssl,
951 const uint8_t **out_retry_configs,
952 size_t *out_retry_configs_len) {
953 const SSL_HANDSHAKE *hs = ssl->s3->hs.get();
954 if (!hs || !hs->ech_authenticated_reject) {
955 // It is an error to call this function except in response to
956 // |SSL_R_ECH_REJECTED|. Returning an empty string risks the caller
957 // mistakenly believing the server has disabled ECH. Instead, return a
958 // non-empty ECHConfigList with a syntax error, so the subsequent
959 // |SSL_set1_ech_config_list| call will fail.
960 assert(0);
961 static const uint8_t kPlaceholder[] = {
962 kECHConfigVersion >> 8, kECHConfigVersion & 0xff, 0xff, 0xff, 0xff};
963 *out_retry_configs = kPlaceholder;
964 *out_retry_configs_len = sizeof(kPlaceholder);
965 return;
966 }
967
968 *out_retry_configs = hs->ech_retry_configs.data();
969 *out_retry_configs_len = hs->ech_retry_configs.size();
970 }
971
SSL_marshal_ech_config(uint8_t ** out,size_t * out_len,uint8_t config_id,const EVP_HPKE_KEY * key,const char * public_name,size_t max_name_len)972 int SSL_marshal_ech_config(uint8_t **out, size_t *out_len, uint8_t config_id,
973 const EVP_HPKE_KEY *key, const char *public_name,
974 size_t max_name_len) {
975 Span<const uint8_t> public_name_u8 = StringAsBytes(public_name);
976 if (!ssl_is_valid_ech_public_name(public_name_u8)) {
977 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_ECH_PUBLIC_NAME);
978 return 0;
979 }
980
981 // The maximum name length is encoded in one byte.
982 if (max_name_len > 0xff) {
983 OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_LENGTH);
984 return 0;
985 }
986
987 // See draft-ietf-tls-esni-13, section 4.
988 ScopedCBB cbb;
989 CBB contents, child;
990 uint8_t *public_key;
991 size_t public_key_len;
992 if (!CBB_init(cbb.get(), 128) || //
993 !CBB_add_u16(cbb.get(), kECHConfigVersion) ||
994 !CBB_add_u16_length_prefixed(cbb.get(), &contents) ||
995 !CBB_add_u8(&contents, config_id) ||
996 !CBB_add_u16(&contents, EVP_HPKE_KEM_id(EVP_HPKE_KEY_kem(key))) ||
997 !CBB_add_u16_length_prefixed(&contents, &child) ||
998 !CBB_reserve(&child, &public_key, EVP_HPKE_MAX_PUBLIC_KEY_LENGTH) ||
999 !EVP_HPKE_KEY_public_key(key, public_key, &public_key_len,
1000 EVP_HPKE_MAX_PUBLIC_KEY_LENGTH) ||
1001 !CBB_did_write(&child, public_key_len) ||
1002 !CBB_add_u16_length_prefixed(&contents, &child) ||
1003 // Write a default cipher suite configuration.
1004 !CBB_add_u16(&child, EVP_HPKE_HKDF_SHA256) ||
1005 !CBB_add_u16(&child, EVP_HPKE_AES_128_GCM) ||
1006 !CBB_add_u16(&child, EVP_HPKE_HKDF_SHA256) ||
1007 !CBB_add_u16(&child, EVP_HPKE_CHACHA20_POLY1305) ||
1008 !CBB_add_u8(&contents, max_name_len) ||
1009 !CBB_add_u8_length_prefixed(&contents, &child) ||
1010 !CBB_add_bytes(&child, public_name_u8.data(), public_name_u8.size()) ||
1011 // TODO(https://crbug.com/boringssl/275): Reserve some GREASE extensions
1012 // and include some.
1013 !CBB_add_u16(&contents, 0 /* no extensions */) ||
1014 !CBB_finish(cbb.get(), out, out_len)) {
1015 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
1016 return 0;
1017 }
1018 return 1;
1019 }
1020
SSL_ECH_KEYS_new()1021 SSL_ECH_KEYS *SSL_ECH_KEYS_new() { return New<SSL_ECH_KEYS>(); }
1022
SSL_ECH_KEYS_up_ref(SSL_ECH_KEYS * keys)1023 void SSL_ECH_KEYS_up_ref(SSL_ECH_KEYS *keys) { keys->UpRefInternal(); }
1024
SSL_ECH_KEYS_free(SSL_ECH_KEYS * keys)1025 void SSL_ECH_KEYS_free(SSL_ECH_KEYS *keys) {
1026 if (keys != nullptr) {
1027 keys->DecRefInternal();
1028 }
1029 }
1030
SSL_ECH_KEYS_add(SSL_ECH_KEYS * configs,int is_retry_config,const uint8_t * ech_config,size_t ech_config_len,const EVP_HPKE_KEY * key)1031 int SSL_ECH_KEYS_add(SSL_ECH_KEYS *configs, int is_retry_config,
1032 const uint8_t *ech_config, size_t ech_config_len,
1033 const EVP_HPKE_KEY *key) {
1034 UniquePtr<ECHServerConfig> parsed_config = MakeUnique<ECHServerConfig>();
1035 if (!parsed_config) {
1036 return 0;
1037 }
1038 if (!parsed_config->Init(Span(ech_config, ech_config_len), key,
1039 !!is_retry_config)) {
1040 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
1041 return 0;
1042 }
1043 if (!configs->configs.Push(std::move(parsed_config))) {
1044 return 0;
1045 }
1046 return 1;
1047 }
1048
SSL_ECH_KEYS_has_duplicate_config_id(const SSL_ECH_KEYS * keys)1049 int SSL_ECH_KEYS_has_duplicate_config_id(const SSL_ECH_KEYS *keys) {
1050 bool seen[256] = {false};
1051 for (const auto &config : keys->configs) {
1052 if (seen[config->ech_config().config_id]) {
1053 return 1;
1054 }
1055 seen[config->ech_config().config_id] = true;
1056 }
1057 return 0;
1058 }
1059
SSL_ECH_KEYS_marshal_retry_configs(const SSL_ECH_KEYS * keys,uint8_t ** out,size_t * out_len)1060 int SSL_ECH_KEYS_marshal_retry_configs(const SSL_ECH_KEYS *keys, uint8_t **out,
1061 size_t *out_len) {
1062 ScopedCBB cbb;
1063 CBB child;
1064 if (!CBB_init(cbb.get(), 128) ||
1065 !CBB_add_u16_length_prefixed(cbb.get(), &child)) {
1066 return false;
1067 }
1068 for (const auto &config : keys->configs) {
1069 if (config->is_retry_config() &&
1070 !CBB_add_bytes(&child, config->ech_config().raw.data(),
1071 config->ech_config().raw.size())) {
1072 return false;
1073 }
1074 }
1075 return CBB_finish(cbb.get(), out, out_len);
1076 }
1077
SSL_CTX_set1_ech_keys(SSL_CTX * ctx,SSL_ECH_KEYS * keys)1078 int SSL_CTX_set1_ech_keys(SSL_CTX *ctx, SSL_ECH_KEYS *keys) {
1079 bool has_retry_config = false;
1080 for (const auto &config : keys->configs) {
1081 if (config->is_retry_config()) {
1082 has_retry_config = true;
1083 break;
1084 }
1085 }
1086 if (!has_retry_config) {
1087 OPENSSL_PUT_ERROR(SSL, SSL_R_ECH_SERVER_WOULD_HAVE_NO_RETRY_CONFIGS);
1088 return 0;
1089 }
1090 UniquePtr<SSL_ECH_KEYS> owned_keys = UpRef(keys);
1091 MutexWriteLock lock(&ctx->lock);
1092 ctx->ech_keys.swap(owned_keys);
1093 return 1;
1094 }
1095
SSL_ech_accepted(const SSL * ssl)1096 int SSL_ech_accepted(const SSL *ssl) {
1097 if (SSL_in_early_data(ssl) && !ssl->server) {
1098 // In the client early data state, we report properties as if the server
1099 // accepted early data. The server can only accept early data with
1100 // ClientHelloInner.
1101 return ssl->s3->hs->selected_ech_config != nullptr;
1102 }
1103
1104 return ssl->s3->ech_status == ssl_ech_accepted;
1105 }
1106