#include <openssl/ssl.h>
#include <assert.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <utility>
#include <openssl/aead.h>
#include <openssl/bytestring.h>
#include <openssl/chacha.h>
#include <openssl/curve25519.h>
#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/hpke.h>
#include <openssl/mem.h>
#include <openssl/nid.h>
#include <openssl/rand.h>
#include "../crypto/internal.h"
#include "internal.h"
BSSL_NAMESPACE_BEGIN
static bool ssl_check_clienthello_tlsext(SSL_HANDSHAKE *hs);
static bool ssl_check_serverhello_tlsext(SSL_HANDSHAKE *hs);
static int compare_uint16_t(const void *p1, const void *p2) { … }
static bool tls1_check_duplicate_extensions(const CBS *cbs) { … }
static bool is_post_quantum_group(uint16_t id) { … }
bool ssl_client_hello_init(const SSL *ssl, SSL_CLIENT_HELLO *out,
Span<const uint8_t> body) { … }
bool ssl_parse_client_hello_with_trailing_data(const SSL *ssl, CBS *cbs,
SSL_CLIENT_HELLO *out) { … }
bool ssl_client_hello_get_extension(const SSL_CLIENT_HELLO *client_hello,
CBS *out, uint16_t extension_type) { … }
static const uint16_t kDefaultGroups[] = …;
Span<const uint16_t> tls1_get_grouplist(const SSL_HANDSHAKE *hs) { … }
bool tls1_get_shared_group(SSL_HANDSHAKE *hs, uint16_t *out_group_id) { … }
bool tls1_check_group_id(const SSL_HANDSHAKE *hs, uint16_t group_id) { … }
static const uint16_t kVerifySignatureAlgorithms[] = …;
static const uint16_t kSignSignatureAlgorithms[] = …;
static Span<const uint16_t> tls12_get_verify_sigalgs(const SSL_HANDSHAKE *hs) { … }
bool tls12_add_verify_sigalgs(const SSL_HANDSHAKE *hs, CBB *out) { … }
bool tls12_check_peer_sigalg(const SSL_HANDSHAKE *hs, uint8_t *out_alert,
uint16_t sigalg, EVP_PKEY *pkey) { … }
struct tls_extension { … };
static bool forbid_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) { … }
static bool ignore_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) { … }
static bool dont_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { … }
static bool ext_sni_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
CBB *out_compressible,
ssl_client_hello_type_t type) { … }
static bool ext_sni_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) { … }
static bool ext_sni_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) { … }
static bool ext_sni_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { … }
static bool ext_ech_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
CBB *out_compressible,
ssl_client_hello_type_t type) { … }
static bool ext_ech_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) { … }
static bool ext_ech_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) { … }
static bool ext_ech_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { … }
static bool ext_ri_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
CBB *out_compressible,
ssl_client_hello_type_t type) { … }
static bool ext_ri_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) { … }
static bool ext_ri_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) { … }
static bool ext_ri_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { … }
static bool ext_ems_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
CBB *out_compressible,
ssl_client_hello_type_t type) { … }
static bool ext_ems_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) { … }
static bool ext_ems_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) { … }
static bool ext_ems_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { … }
static bool ext_ticket_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
CBB *out_compressible,
ssl_client_hello_type_t type) { … }
static bool ext_ticket_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) { … }
static bool ext_ticket_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { … }
static bool ext_sigalgs_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
CBB *out_compressible,
ssl_client_hello_type_t type) { … }
static bool ext_sigalgs_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) { … }
static bool ext_ocsp_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
CBB *out_compressible,
ssl_client_hello_type_t type) { … }
static bool ext_ocsp_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) { … }
static bool ext_ocsp_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) { … }
static bool ext_ocsp_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { … }
static bool ext_npn_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
CBB *out_compressible,
ssl_client_hello_type_t type) { … }
static bool ext_npn_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) { … }
static bool ext_npn_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) { … }
static bool ext_npn_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { … }
static bool ext_sct_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
CBB *out_compressible,
ssl_client_hello_type_t type) { … }
static bool ext_sct_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) { … }
static bool ext_sct_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) { … }
static bool ext_sct_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { … }
static bool ext_alpn_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
CBB *out_compressible,
ssl_client_hello_type_t type) { … }
static bool ext_alpn_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) { … }
bool ssl_is_valid_alpn_list(Span<const uint8_t> in) { … }
bool ssl_is_alpn_protocol_allowed(const SSL_HANDSHAKE *hs,
Span<const uint8_t> protocol) { … }
bool ssl_alpn_list_contains_protocol(Span<const uint8_t> list,
Span<const uint8_t> protocol) { … }
bool ssl_negotiate_alpn(SSL_HANDSHAKE *hs, uint8_t *out_alert,
const SSL_CLIENT_HELLO *client_hello) { … }
static bool ext_alpn_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { … }
static bool ext_channel_id_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
CBB *out_compressible,
ssl_client_hello_type_t type) { … }
static bool ext_channel_id_parse_serverhello(SSL_HANDSHAKE *hs,
uint8_t *out_alert,
CBS *contents) { … }
static bool ext_channel_id_parse_clienthello(SSL_HANDSHAKE *hs,
uint8_t *out_alert,
CBS *contents) { … }
static bool ext_channel_id_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { … }
static bool ext_srtp_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
CBB *out_compressible,
ssl_client_hello_type_t type) { … }
static bool ext_srtp_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) { … }
static bool ext_srtp_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) { … }
static bool ext_srtp_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { … }
static bool ext_ec_point_add_extension(const SSL_HANDSHAKE *hs, CBB *out) { … }
static bool ext_ec_point_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
CBB *out_compressible,
ssl_client_hello_type_t type) { … }
static bool ext_ec_point_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) { … }
static bool ext_ec_point_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) { … }
static bool ext_ec_point_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { … }
static bool should_offer_psk(const SSL_HANDSHAKE *hs,
ssl_client_hello_type_t type) { … }
static size_t ext_pre_shared_key_clienthello_length(
const SSL_HANDSHAKE *hs, ssl_client_hello_type_t type) { … }
static bool ext_pre_shared_key_add_clienthello(const SSL_HANDSHAKE *hs,
CBB *out, bool *out_needs_binder,
ssl_client_hello_type_t type) { … }
bool ssl_ext_pre_shared_key_parse_serverhello(SSL_HANDSHAKE *hs,
uint8_t *out_alert,
CBS *contents) { … }
bool ssl_ext_pre_shared_key_parse_clienthello(
SSL_HANDSHAKE *hs, CBS *out_ticket, CBS *out_binders,
uint32_t *out_obfuscated_ticket_age, uint8_t *out_alert,
const SSL_CLIENT_HELLO *client_hello, CBS *contents) { … }
bool ssl_ext_pre_shared_key_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { … }
static bool ext_psk_key_exchange_modes_add_clienthello(
const SSL_HANDSHAKE *hs, CBB *out, CBB *out_compressible,
ssl_client_hello_type_t type) { … }
static bool ext_psk_key_exchange_modes_parse_clienthello(SSL_HANDSHAKE *hs,
uint8_t *out_alert,
CBS *contents) { … }
static bool ext_early_data_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
CBB *out_compressible,
ssl_client_hello_type_t type) { … }
static bool ext_early_data_parse_serverhello(SSL_HANDSHAKE *hs,
uint8_t *out_alert,
CBS *contents) { … }
static bool ext_early_data_parse_clienthello(SSL_HANDSHAKE *hs,
uint8_t *out_alert, CBS *contents) { … }
static bool ext_early_data_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { … }
bool ssl_setup_key_shares(SSL_HANDSHAKE *hs, uint16_t override_group_id) { … }
static bool ext_key_share_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
CBB *out_compressible,
ssl_client_hello_type_t type) { … }
bool ssl_ext_key_share_parse_serverhello(SSL_HANDSHAKE *hs,
Array<uint8_t> *out_secret,
uint8_t *out_alert, CBS *contents) { … }
bool ssl_ext_key_share_parse_clienthello(SSL_HANDSHAKE *hs, bool *out_found,
Span<const uint8_t> *out_peer_key,
uint8_t *out_alert,
const SSL_CLIENT_HELLO *client_hello) { … }
bool ssl_ext_key_share_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { … }
static bool ext_supported_versions_add_clienthello(
const SSL_HANDSHAKE *hs, CBB *out, CBB *out_compressible,
ssl_client_hello_type_t type) { … }
static bool ext_cookie_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
CBB *out_compressible,
ssl_client_hello_type_t type) { … }
static bool ext_supported_groups_add_clienthello(const SSL_HANDSHAKE *hs,
CBB *out,
CBB *out_compressible,
ssl_client_hello_type_t type) { … }
static bool ext_supported_groups_parse_serverhello(SSL_HANDSHAKE *hs,
uint8_t *out_alert,
CBS *contents) { … }
static bool parse_u16_array(const CBS *cbs, Array<uint16_t> *out) { … }
static bool ext_supported_groups_parse_clienthello(SSL_HANDSHAKE *hs,
uint8_t *out_alert,
CBS *contents) { … }
static bool ext_quic_transport_params_add_clienthello_impl(
const SSL_HANDSHAKE *hs, CBB *out, bool use_legacy_codepoint) { … }
static bool ext_quic_transport_params_add_clienthello(
const SSL_HANDSHAKE *hs, CBB *out, CBB *out_compressible,
ssl_client_hello_type_t type) { … }
static bool ext_quic_transport_params_add_clienthello_legacy(
const SSL_HANDSHAKE *hs, CBB *out, CBB *out_compressible,
ssl_client_hello_type_t type) { … }
static bool ext_quic_transport_params_parse_serverhello_impl(
SSL_HANDSHAKE *hs, uint8_t *out_alert, CBS *contents,
bool used_legacy_codepoint) { … }
static bool ext_quic_transport_params_parse_serverhello(SSL_HANDSHAKE *hs,
uint8_t *out_alert,
CBS *contents) { … }
static bool ext_quic_transport_params_parse_serverhello_legacy(
SSL_HANDSHAKE *hs, uint8_t *out_alert, CBS *contents) { … }
static bool ext_quic_transport_params_parse_clienthello_impl(
SSL_HANDSHAKE *hs, uint8_t *out_alert, CBS *contents,
bool used_legacy_codepoint) { … }
static bool ext_quic_transport_params_parse_clienthello(SSL_HANDSHAKE *hs,
uint8_t *out_alert,
CBS *contents) { … }
static bool ext_quic_transport_params_parse_clienthello_legacy(
SSL_HANDSHAKE *hs, uint8_t *out_alert, CBS *contents) { … }
static bool ext_quic_transport_params_add_serverhello_impl(
SSL_HANDSHAKE *hs, CBB *out, bool use_legacy_codepoint) { … }
static bool ext_quic_transport_params_add_serverhello(SSL_HANDSHAKE *hs,
CBB *out) { … }
static bool ext_quic_transport_params_add_serverhello_legacy(SSL_HANDSHAKE *hs,
CBB *out) { … }
static bool ext_delegated_credential_add_clienthello(
const SSL_HANDSHAKE *hs, CBB *out, CBB *out_compressible,
ssl_client_hello_type_t type) { … }
static bool ext_delegated_credential_parse_clienthello(SSL_HANDSHAKE *hs,
uint8_t *out_alert,
CBS *contents) { … }
static bool cert_compression_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
CBB *out_compressible,
ssl_client_hello_type_t type) { … }
static bool cert_compression_parse_serverhello(SSL_HANDSHAKE *hs,
uint8_t *out_alert,
CBS *contents) { … }
static bool cert_compression_parse_clienthello(SSL_HANDSHAKE *hs,
uint8_t *out_alert,
CBS *contents) { … }
static bool cert_compression_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { … }
bool ssl_get_local_application_settings(const SSL_HANDSHAKE *hs,
Span<const uint8_t> *out_settings,
Span<const uint8_t> protocol) { … }
static bool ext_alps_add_clienthello_impl(const SSL_HANDSHAKE *hs, CBB *out,
CBB *out_compressible,
ssl_client_hello_type_t type,
bool use_new_codepoint) { … }
static bool ext_alps_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
CBB *out_compressible,
ssl_client_hello_type_t type) { … }
static bool ext_alps_add_clienthello_old(const SSL_HANDSHAKE *hs, CBB *out,
CBB *out_compressible,
ssl_client_hello_type_t type) { … }
static bool ext_alps_parse_serverhello_impl(SSL_HANDSHAKE *hs,
uint8_t *out_alert,
CBS *contents,
bool use_new_codepoint) { … }
static bool ext_alps_parse_serverhello(SSL_HANDSHAKE *hs,
uint8_t *out_alert,
CBS *contents) { … }
static bool ext_alps_parse_serverhello_old(SSL_HANDSHAKE *hs,
uint8_t *out_alert,
CBS *contents) { … }
static bool ext_alps_add_serverhello_impl(SSL_HANDSHAKE *hs, CBB *out,
bool use_new_codepoint) { … }
static bool ext_alps_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { … }
static bool ext_alps_add_serverhello_old(SSL_HANDSHAKE *hs, CBB *out) { … }
bool ssl_negotiate_alps(SSL_HANDSHAKE *hs, uint8_t *out_alert,
const SSL_CLIENT_HELLO *client_hello) { … }
static const struct tls_extension kExtensions[] = …;
#define kNumExtensions …
static_assert …;
static_assert …;
bool ssl_setup_extension_permutation(SSL_HANDSHAKE *hs) { … }
static const struct tls_extension *tls_extension_find(uint32_t *out_index,
uint16_t value) { … }
static bool add_padding_extension(CBB *cbb, uint16_t ext, size_t len) { … }
static bool ssl_add_clienthello_tlsext_inner(SSL_HANDSHAKE *hs, CBB *out,
CBB *out_encoded,
bool *out_needs_psk_binder) { … }
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_add_serverhello_tlsext(SSL_HANDSHAKE *hs, CBB *out) { … }
static bool ssl_scan_clienthello_tlsext(SSL_HANDSHAKE *hs,
const SSL_CLIENT_HELLO *client_hello,
int *out_alert) { … }
bool ssl_parse_clienthello_tlsext(SSL_HANDSHAKE *hs,
const SSL_CLIENT_HELLO *client_hello) { … }
static bool ssl_scan_serverhello_tlsext(SSL_HANDSHAKE *hs, const CBS *cbs,
int *out_alert) { … }
static bool ssl_check_clienthello_tlsext(SSL_HANDSHAKE *hs) { … }
static bool ssl_check_serverhello_tlsext(SSL_HANDSHAKE *hs) { … }
bool ssl_parse_serverhello_tlsext(SSL_HANDSHAKE *hs, const CBS *cbs) { … }
static enum ssl_ticket_aead_result_t decrypt_ticket_with_cipher_ctx(
Array<uint8_t> *out, EVP_CIPHER_CTX *cipher_ctx, HMAC_CTX *hmac_ctx,
Span<const uint8_t> ticket) { … }
static enum ssl_ticket_aead_result_t ssl_decrypt_ticket_with_cb(
SSL_HANDSHAKE *hs, Array<uint8_t> *out, bool *out_renew_ticket,
Span<const uint8_t> ticket) { … }
static enum ssl_ticket_aead_result_t ssl_decrypt_ticket_with_ticket_keys(
SSL_HANDSHAKE *hs, Array<uint8_t> *out, Span<const uint8_t> ticket) { … }
static enum ssl_ticket_aead_result_t ssl_decrypt_ticket_with_method(
SSL_HANDSHAKE *hs, Array<uint8_t> *out, bool *out_renew_ticket,
Span<const uint8_t> ticket) { … }
enum ssl_ticket_aead_result_t ssl_process_ticket(
SSL_HANDSHAKE *hs, UniquePtr<SSL_SESSION> *out_session,
bool *out_renew_ticket, Span<const uint8_t> ticket,
Span<const uint8_t> session_id) { … }
bool tls1_parse_peer_sigalgs(SSL_HANDSHAKE *hs, const CBS *in_sigalgs) { … }
bool tls1_get_legacy_signature_algorithm(uint16_t *out, const EVP_PKEY *pkey) { … }
bool tls1_choose_signature_algorithm(SSL_HANDSHAKE *hs,
const SSL_CREDENTIAL *cred,
uint16_t *out) { … }
bool tls1_verify_channel_id(SSL_HANDSHAKE *hs, const SSLMessage &msg) { … }
bool tls1_write_channel_id(SSL_HANDSHAKE *hs, CBB *cbb) { … }
bool tls1_channel_id_hash(SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len) { … }
bool tls1_record_handshake_hashes_for_channel_id(SSL_HANDSHAKE *hs) { … }
bool ssl_is_sct_list_valid(const CBS *contents) { … }
BSSL_NAMESPACE_END
usingnamespacebssl;
int SSL_early_callback_ctx_extension_get(const SSL_CLIENT_HELLO *client_hello,
uint16_t extension_type,
const uint8_t **out_data,
size_t *out_len) { … }