Move the early_data_{offered,reason} logic out of extension callbacks.
ECH requires that we construct two ClientHellos. That means our
add_clienthello callbacks will need to be called multiple times and
should be const. (They already are called multiple times for
HelloRetryRequest, but we currently thread that through the callbacks a
bit. With ECH, I think we need to make them pure serialization.)
Bug: 275
Change-Id: I11f8195fd2ec4b8639f0a2af01a24d4974445580
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/47984
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/t1_lib.cc b/ssl/t1_lib.cc
index 7155f12..0eec28a 100644
--- a/ssl/t1_lib.cc
+++ b/ssl/t1_lib.cc
@@ -2146,21 +2146,6 @@
//
// https://tools.ietf.org/html/rfc8446#section-4.2.10
-// ssl_get_local_application_settings looks up the configured ALPS value for
-// |protocol|. If found, it sets |*out_settings| to the value and returns true.
-// Otherwise, it returns false.
-static bool ssl_get_local_application_settings(
- const SSL_HANDSHAKE *hs, Span<const uint8_t> *out_settings,
- Span<const uint8_t> protocol) {
- for (const ALPSConfig &config : hs->config->alps_configs) {
- if (protocol == config.protocol) {
- *out_settings = config.settings;
- return true;
- }
- }
- return false;
-}
-
static bool ext_early_data_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
// The second ClientHello never offers early data, and we must have already
@@ -2170,53 +2155,10 @@
return true;
}
- if (!ssl->enable_early_data) {
- ssl->s3->early_data_reason = ssl_early_data_disabled;
+ if (!hs->early_data_offered) {
return true;
}
- if (hs->max_version < TLS1_3_VERSION) {
- // We discard inapplicable sessions, so this is redundant with the session
- // checks below, but we check give a more useful reason.
- ssl->s3->early_data_reason = ssl_early_data_protocol_version;
- return true;
- }
-
- if (ssl->session == nullptr) {
- ssl->s3->early_data_reason = ssl_early_data_no_session_offered;
- return true;
- }
-
- if (ssl_session_protocol_version(ssl->session.get()) < TLS1_3_VERSION ||
- ssl->session->ticket_max_early_data == 0) {
- ssl->s3->early_data_reason = ssl_early_data_unsupported_for_session;
- return true;
- }
-
- if (!ssl->session->early_alpn.empty()) {
- if (!ssl_is_alpn_protocol_allowed(hs, ssl->session->early_alpn)) {
- // Avoid reporting a confusing value in |SSL_get0_alpn_selected|.
- ssl->s3->early_data_reason = ssl_early_data_alpn_mismatch;
- return true;
- }
-
- // If the previous connection negotiated ALPS, only offer 0-RTT when the
- // local are settings are consistent with what we'd offer for this
- // connection.
- if (ssl->session->has_application_settings) {
- Span<const uint8_t> settings;
- if (!ssl_get_local_application_settings(hs, &settings,
- ssl->session->early_alpn) ||
- settings != ssl->session->local_application_settings) {
- ssl->s3->early_data_reason = ssl_early_data_alps_mismatch;
- return true;
- }
- }
- }
-
- // |early_data_reason| will be filled in later when the server responds.
- hs->early_data_offered = true;
-
if (!CBB_add_u16(out, TLSEXT_TYPE_early_data) ||
!CBB_add_u16(out, 0) ||
!CBB_flush(out)) {
@@ -2953,6 +2895,18 @@
//
// https://tools.ietf.org/html/draft-vvv-tls-alps-01
+bool ssl_get_local_application_settings(const SSL_HANDSHAKE *hs,
+ Span<const uint8_t> *out_settings,
+ Span<const uint8_t> protocol) {
+ for (const ALPSConfig &config : hs->config->alps_configs) {
+ if (protocol == config.protocol) {
+ *out_settings = config.settings;
+ return true;
+ }
+ }
+ return false;
+}
+
static bool ext_alps_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
if (// ALPS requires TLS 1.3.