Go to the documentation of this file.
107 while (
CBS_len(&versions) != 0) {
130 CBS cbs = encoded_client_hello_inner;
132 &client_hello_inner)) {
158 CBB body, extensions_cbb;
168 CBS ext_list_wrapper;
173 inner_extensions.size())) {
178 const size_t offset =
CBS_data(&ext_list_wrapper) - inner_extensions.data();
179 auto inner_extensions_before =
180 inner_extensions.subspan(0,
offset - 4 );
181 auto inner_extensions_after =
182 inner_extensions.subspan(
offset +
CBS_len(&ext_list_wrapper));
183 if (!
CBB_add_bytes(&extensions_cbb, inner_extensions_before.data(),
184 inner_extensions_before.size())) {
196 CBS outer_extensions;
199 while (
CBS_len(&ext_list) != 0) {
211 if (
CBS_len(&outer_extensions) == 0) {
221 }
while (
found != want);
232 if (!
CBB_add_bytes(&extensions_cbb, inner_extensions_after.data(),
233 inner_extensions_after.size())) {
248 if (!ssl->
method->finish_message(ssl, cbb.get(), out_client_hello_inner)) {
256 bool *out_is_decrypt_error,
259 *out_is_decrypt_error =
false;
281 #if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
285 const uint8_t kBadPayload[] = {0xff};
287 *out_is_decrypt_error =
true;
304 *out_is_decrypt_error =
true;
314 if (
in.size() < 2 ||
in[0] !=
'0' || (
in[1] !=
'x' &&
in[1] !=
'X')) {
318 if (!(
'0' <=
b &&
b <=
'9') && !(
'a' <=
b &&
b <=
'f') &&
319 !(
'A' <=
b &&
b <=
'F')) {
331 if (!(
'0' <=
b &&
b <=
'9')) {
342 auto remaining = public_name;
343 if (remaining.empty()) {
347 while (!remaining.empty()) {
349 auto dot =
std::find(remaining.begin(), remaining.end(),
'.');
351 if (dot == remaining.end()) {
352 component = remaining;
356 component = remaining.
subspan(0, dot - remaining.begin());
358 remaining = remaining.
subspan(dot - remaining.begin() + 1);
359 if (remaining.empty()) {
366 if (component.
empty() || component.
size() > 63 ||
367 component.
front() ==
'-' || component.
back() ==
'-') {
371 if (!(
'a' <=
c &&
c <=
'z') && !(
'A' <=
c &&
c <=
'Z') &&
372 !(
'0' <=
c &&
c <=
'9') &&
c !=
'-') {
390 bool all_extensions_mandatory) {
401 *out_supported =
false;
407 if (!
out->raw.CopyFrom(
435 *out_supported =
false;
440 out->public_name = public_name;
445 bool has_unknown_mandatory_extension =
false;
455 if (
type & 0x8000 || all_extensions_mandatory) {
459 has_unknown_mandatory_extension =
true;
463 *out_supported = !has_unknown_mandatory_extension;
509 size_t expected_public_key_len;
511 &expected_public_key_len,
512 sizeof(expected_public_key))) {
516 MakeConstSpan(expected_public_key, expected_public_key_len) !=
534 bool cipher_ok =
false;
536 uint16_t supported_kdf_id, supported_aead_id;
541 if (kdf_id == supported_kdf_id && aead_id == supported_aead_id) {
550 static const uint8_t kInfoLabel[] =
"tls ech";
554 sizeof(kInfoLabel) ) ||
604 if (aead ==
nullptr ||
609 if (aead ==
nullptr) {
619 size_t *out_enc_len) {
649 static const uint8_t kInfoLabel[] =
"tls ech";
650 if (!
CBB_init(info.get(),
sizeof(kInfoLabel) + ech_config.
raw.
size()) ||
651 !
CBB_add_bytes(info.get(), kInfoLabel,
sizeof(kInfoLabel)) ||
677 #if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
706 "hs->grease_seed is too small");
731 CBB enc_cbb, payload_cbb;
756 ScopedCBB cbb, encoded_cbb;
758 bool needs_psk_binder;
761 !
CBB_init(encoded_cbb.get(), 256) ||
771 !ssl->
method->finish_message(ssl, cbb.get(), &hello_inner)) {
776 if (needs_psk_binder) {
783 auto encoded_binder =
787 auto hello_inner_binder =
MakeConstSpan(hello_inner).last(binder_len);
797 size_t padding_len = 0;
800 size_t hostname_len = strlen(ssl->
hostname.get());
801 if (hostname_len <= maximum_name_length) {
802 padding_len = maximum_name_length - hostname_len;
807 padding_len = 9 + maximum_name_length;
810 padding_len += 31 - ((
CBB_len(encoded_cbb.get()) + padding_len - 1) % 32);
823 CBB enc_cbb, payload_cbb;
854 assert(!needs_psk_binder);
858 #if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
860 assert(payload_span.size() == encoded.
size());
870 #endif // BORINGSSL_UNSAFE_FUZZER_MODE
877 using namespace bssl;
883 ssl->
config->ech_grease_enabled = !!enable;
887 size_t ech_config_list_len) {
892 auto span =
MakeConstSpan(ech_config_list, ech_config_list_len);
897 return ssl->
config->client_ech_config_list.CopyFrom(span);
901 size_t *out_name_len) {
910 *out_name =
reinterpret_cast<const char *
>(
920 const SSL *ssl,
const uint8_t **out_retry_configs,
921 size_t *out_retry_configs_len) {
930 static const uint8_t kPlaceholder[] = {
932 *out_retry_configs = kPlaceholder;
933 *out_retry_configs_len =
sizeof(kPlaceholder);
943 size_t max_name_len) {
945 reinterpret_cast<const uint8_t *
>(public_name), strlen(public_name));
952 if (max_name_len > 0xff) {
961 size_t public_key_len;
998 if (
keys ==
nullptr ||
1003 keys->~ssl_ech_keys_st();
1008 const uint8_t *ech_config,
size_t ech_config_len,
1010 UniquePtr<ECHServerConfig> parsed_config = MakeUnique<ECHServerConfig>();
1011 if (!parsed_config) {
1015 !!is_retry_config)) {
1027 bool seen[256] = {
false};
1047 if (
config->is_retry_config() &&
1049 config->ech_config().raw.size())) {
1058 bool has_retry_config =
false;
1060 if (
config->is_retry_config()) {
1061 has_retry_config =
true;
1065 if (!has_retry_config) {
1069 UniquePtr<SSL_ECH_KEYS> owned_keys = UpRef(
keys);
1070 MutexWriteLock lock(&
ctx->lock);
1071 ctx->ech_keys.swap(owned_keys);
1080 return ssl->
s3->hs->selected_ech_config !=
nullptr;
bool ssl_select_ech_config(SSL_HANDSHAKE *hs, Span< uint8_t > out_enc, size_t *out_enc_len)
Span subspan(size_t pos=0, size_t len=npos) const
const uint8_t * cipher_suites
#define EVP_HPKE_CTX_setup_recipient
Array< uint8_t > client_ech_config_list
#define EVP_hpke_chacha20_poly1305
void SSL_get0_ech_name_override(const SSL *ssl, const char **out_name, size_t *out_name_len)
int SSL_CTX_set1_ech_keys(SSL_CTX *ctx, SSL_ECH_KEYS *keys)
const ECHConfig & ech_config() const
bool is_retry_config() const
#define EVP_HPKE_CTX_setup_sender
static void ** find(grpc_chttp2_stream_map *map, uint32_t key)
size_t compression_methods_len
static bool is_decimal_component(Span< const uint8_t > in)
const Descriptor::ReservedRange const EnumValueDescriptor const MethodDescriptor extension
#define EVP_HPKE_DHKEM_X25519_HKDF_SHA256
#define X25519_PRIVATE_KEY_LEN
static bool setup_ech_grease(SSL_HANDSHAKE *hs)
bool ssl_is_valid_ech_config_list(Span< const uint8_t > ech_config_list)
SSLTranscript inner_transcript
#define OPENSSL_PUT_ERROR(library, reason)
#define CBB_add_u16_length_prefixed
bssl::UniquePtr< bssl::SSL_CONFIG > config
#define SSL_R_ECH_SERVER_WOULD_HAVE_NO_RETRY_CONFIGS
int 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)
#define CBS_get_u8_length_prefixed
static size_t aead_overhead(const EVP_HPKE_AEAD *aead)
bool tls13_write_psk_binder(const SSL_HANDSHAKE *hs, const SSLTranscript &transcript, Span< uint8_t > msg, size_t *out_binder_len)
void SSL_set_enable_ech_grease(SSL *ssl, int enable)
@ ssl_grease_ech_config_id
UniquePtr< ECHConfig > selected_ech_config
bool ssl_write_client_hello_without_extensions(const SSL_HANDSHAKE *hs, CBB *cbb, ssl_client_hello_type_t type, bool empty_session_id)
static const char * cipher_suites
#define SSL_AD_ILLEGAL_PARAMETER
static const EVP_HPKE_AEAD * get_ech_aead(uint16_t aead_id)
#define EVP_hpke_hkdf_sha256
static bool select_ech_cipher_suite(const EVP_HPKE_KDF **out_kdf, const EVP_HPKE_AEAD **out_aead, Span< const uint8_t > cipher_suites)
#define TLSEXT_TYPE_ech_outer_extensions
#define SSL3_MT_CLIENT_HELLO
static void * OPENSSL_memset(void *dst, int c, size_t n)
bool CopyFrom(Span< const T > in)
#define EVP_HPKE_CTX_aead
int SSL_ECH_KEYS_has_duplicate_config_id(const SSL_ECH_KEYS *keys)
#define EVP_HPKE_KEY_public_key
Array< uint8_t > ech_client_outer
ScopedEVP_HPKE_CTX ech_hpke_ctx
static const decltype(&EVP_hpke_aes_128_gcm) kSupportedAEADs[]
#define TLSEXT_TYPE_supported_versions
bool Init(Span< const uint8_t > ech_config, const EVP_HPKE_KEY *key, bool is_retry_config)
bool ssl_add_clienthello_tlsext(SSL_HANDSHAKE *hs, CBB *out, CBB *out_encoded, bool *out_needs_psk_binder, ssl_client_hello_type_t type, size_t header_len)
bool 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)
bool ech_authenticated_reject
int SSL_ech_accepted(const SSL *ssl)
int SSL_ECH_KEYS_marshal_retry_configs(const SSL_ECH_KEYS *keys, uint8_t **out, size_t *out_len)
#define SSL_R_OUTER_EXTENSION_NOT_FOUND
#define SSL_R_DECRYPTION_FAILED
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
#define CBB_add_u8_length_prefixed
#define EVP_HPKE_HKDF_SHA256
bool SetupContext(EVP_HPKE_CTX *ctx, uint16_t kdf_id, uint16_t aead_id, Span< const uint8_t > enc) const
static size_t random_size(size_t min, size_t max)
bool ssl_client_hello_get_extension(const SSL_CLIENT_HELLO *client_hello, CBS *out, uint16_t extension_type)
static void * OPENSSL_memcpy(void *dst, const void *src, size_t n)
int 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)
#define BSSL_NAMESPACE_END
#define ERR_R_INTERNAL_ERROR
static grpc_end2end_test_config configs[]
int SSL_set1_ech_config_list(SSL *ssl, const uint8_t *ech_config_list, size_t ech_config_list_len)
_W64 unsigned int uintptr_t
static constexpr BSSL_NAMESPACE_BEGIN uint16_t kECHConfigVersion
Array< uint8_t > ech_retry_configs
static bool ssl_client_hello_write_without_extensions(const SSL_CLIENT_HELLO *client_hello, CBB *out)
bssl::UniquePtr< char > hostname
bool ssl_client_hello_init(const SSL *ssl, SSL_CLIENT_HELLO *out, Span< const uint8_t > body)
const uint8_t * session_id
bool ssl_is_valid_ech_public_name(Span< const uint8_t > public_name)
bool ssl_parse_client_hello_with_trailing_data(const SSL *ssl, CBS *cbs, SSL_CLIENT_HELLO *out)
Span< const uint8_t > public_key
#define EVP_HPKE_CTX_open
#define EVP_has_aes_hardware
const uint8_t * compression_methods
#define SSL_R_INVALID_ECH_PUBLIC_NAME
OPENSSL_EXPORT bool CBBFinishArray(CBB *cbb, Array< uint8_t > *out)
static bool is_hex_component(Span< const uint8_t > in)
#define EVP_hpke_x25519_hkdf_sha256
const uint8_t * extensions
uint8_t grease_seed[ssl_grease_last_index+1]
#define EVP_HPKE_AES_128_GCM
static bool is_valid_client_hello_inner(SSL *ssl, uint8_t *out_alert, Span< const uint8_t > body)
#define SSL_R_INVALID_ECH_CONFIG_LIST
#define SSL_AD_DECODE_ERROR
void SSL_ECH_KEYS_free(SSL_ECH_KEYS *keys)
#define CBS_get_u16_length_prefixed
#define EVP_hpke_aes_128_gcm
bool Update(Span< const uint8_t > in)
#define EVP_HPKE_CHACHA20_POLY1305
#define EVP_HPKE_CTX_seal
bool ssl_client_hello_decrypt(EVP_HPKE_CTX *hpke_ctx, Array< uint8_t > *out, bool *out_is_decrypt_error, const SSL_CLIENT_HELLO *client_hello_outer, Span< const uint8_t > payload)
#define EVP_hpke_aes_256_gcm
const bssl::SSL_PROTOCOL_METHOD * method
Span< const uint8_t > cipher_suites
void SSL_get0_ech_retry_configs(const SSL *ssl, const uint8_t **out_retry_configs, size_t *out_retry_configs_len)
#define CRYPTO_refcount_inc
#define SSL_R_UNSUPPORTED_ECH_SERVER_CONFIG
bool ssl_encrypt_client_hello(SSL_HANDSHAKE *hs, Span< const uint8_t > enc)
const uint8_t * client_hello
static bool parse_ech_config(CBS *cbs, ECHConfig *out, bool *out_supported, bool all_extensions_mandatory)
#define TLSEXT_TYPE_encrypted_client_hello
#define SSL_R_DECODE_ERROR
#define EVP_HPKE_MAX_PUBLIC_KEY_LENGTH
#define SSL_in_early_data
void SSL_ECH_KEYS_up_ref(SSL_ECH_KEYS *keys)
SSL_ECH_KEYS * SSL_ECH_KEYS_new()
#define SSL_R_INVALID_CLIENT_HELLO_INNER
#define X25519_PUBLIC_VALUE_LEN
#define EVP_HPKE_KEY_copy
#define SSL_R_ECH_SERVER_CONFIG_AND_PRIVATE_KEY_MISMATCH
constexpr Span< T > MakeSpan(T *ptr, size_t size) noexcept
#define ERR_R_MALLOC_FAILURE
#define EVP_AEAD_max_overhead
#define CRYPTO_refcount_dec_and_test_zero
#define EVP_HPKE_AEAD_aead
constexpr Span< const T > MakeConstSpan(T *ptr, size_t size) noexcept
grpc
Author(s):
autogenerated on Thu Mar 13 2025 02:59:15