Remove the Channel ID callback.

The remaining remnants of Channel ID all configure the private key ahead
of time. Unwind the callback machinery, which cuts down on async points
and the cases we need to test.

This also unwinds some odd interaction between the callback and
SSL_set_tls_channel_id_enabled: If a client uses
SSL_set_tls_channel_id_enabled but doesn't set a callback, the handshake
would still pause at SSL_ERROR_WANT_CHANNEL_ID_LOOKUP. This is now
removed, so SSL_set_tls_channel_id_enabled only affects the server and
SSL_CTX_set1_tls_channel_id only affects the client.

Update-Note: SSL_CTX_set_channel_id_cb is removed.
SSL_set_tls_channel_id_enabled no longer enables Channel ID as a client,
only as a server.

Change-Id: I89ded99ca65e1c61b1bc4e009ca0bdca0b807359
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/47907
Reviewed-by: Adam Langley <agl@google.com>
chromium-5359
David Benjamin 4 years ago committed by Adam Langley
parent 8acec00e9e
commit b5879118ac
  1. 29
      include/openssl/ssl.h
  2. 4
      ssl/handshake.cc
  3. 12
      ssl/handshake_client.cc
  4. 21
      ssl/internal.h
  5. 7
      ssl/ssl_lib.cc
  6. 9
      ssl/ssl_session.cc
  7. 21
      ssl/t1_lib.cc
  8. 8
      ssl/test/handshake_util.cc
  9. 16
      ssl/test/test_config.cc
  10. 1
      ssl/test/test_state.h
  11. 9
      ssl/tls13_client.cc

@ -508,12 +508,10 @@ OPENSSL_EXPORT int SSL_get_error(const SSL *ssl, int ret_code);
// TODO(davidben): Remove this. It's used by accept BIOs which are bizarre. // TODO(davidben): Remove this. It's used by accept BIOs which are bizarre.
#define SSL_ERROR_WANT_ACCEPT 8 #define SSL_ERROR_WANT_ACCEPT 8
// SSL_ERROR_WANT_CHANNEL_ID_LOOKUP indicates the operation failed looking up // SSL_ERROR_WANT_CHANNEL_ID_LOOKUP is never used.
// the Channel ID key. The caller may retry the operation when |channel_id_cb|
// is ready to return a key or one has been configured with
// |SSL_set1_tls_channel_id|.
// //
// See also |SSL_CTX_set_channel_id_cb|. // TODO(davidben): Remove this. Some callers reference it when stringifying
// errors. They should use |SSL_error_description| instead.
#define SSL_ERROR_WANT_CHANNEL_ID_LOOKUP 9 #define SSL_ERROR_WANT_CHANNEL_ID_LOOKUP 9
// SSL_ERROR_PENDING_SESSION indicates the operation failed because the session // SSL_ERROR_PENDING_SESSION indicates the operation failed because the session
@ -2974,15 +2972,16 @@ OPENSSL_EXPORT int SSL_select_next_proto(uint8_t **out, uint8_t *out_len,
// Channel ID. // Channel ID.
// //
// See draft-balfanz-tls-channelid-01. // See draft-balfanz-tls-channelid-01. This is an old, experimental mechanism
// and should not be used in new code.
// SSL_CTX_set_tls_channel_id_enabled configures whether connections associated // SSL_CTX_set_tls_channel_id_enabled configures whether connections associated
// with |ctx| should enable Channel ID. // with |ctx| should enable Channel ID as a server.
OPENSSL_EXPORT void SSL_CTX_set_tls_channel_id_enabled(SSL_CTX *ctx, OPENSSL_EXPORT void SSL_CTX_set_tls_channel_id_enabled(SSL_CTX *ctx,
int enabled); int enabled);
// SSL_set_tls_channel_id_enabled configures whether |ssl| should enable Channel // SSL_set_tls_channel_id_enabled configures whether |ssl| should enable Channel
// ID. // ID as a server.
OPENSSL_EXPORT void SSL_set_tls_channel_id_enabled(SSL *ssl, int enabled); OPENSSL_EXPORT void SSL_set_tls_channel_id_enabled(SSL *ssl, int enabled);
// SSL_CTX_set1_tls_channel_id configures a TLS client to send a TLS Channel ID // SSL_CTX_set1_tls_channel_id configures a TLS client to send a TLS Channel ID
@ -3005,20 +3004,6 @@ OPENSSL_EXPORT int SSL_set1_tls_channel_id(SSL *ssl, EVP_PKEY *private_key);
OPENSSL_EXPORT size_t SSL_get_tls_channel_id(SSL *ssl, uint8_t *out, OPENSSL_EXPORT size_t SSL_get_tls_channel_id(SSL *ssl, uint8_t *out,
size_t max_out); size_t max_out);
// SSL_CTX_set_channel_id_cb sets a callback to be called when a TLS Channel ID
// is requested. The callback may set |*out_pkey| to a key, passing a reference
// to the caller. If none is returned, the handshake will pause and
// |SSL_get_error| will return |SSL_ERROR_WANT_CHANNEL_ID_LOOKUP|.
//
// See also |SSL_ERROR_WANT_CHANNEL_ID_LOOKUP|.
OPENSSL_EXPORT void SSL_CTX_set_channel_id_cb(
SSL_CTX *ctx, void (*channel_id_cb)(SSL *ssl, EVP_PKEY **out_pkey));
// SSL_CTX_get_channel_id_cb returns the callback set by
// |SSL_CTX_set_channel_id_cb|.
OPENSSL_EXPORT void (*SSL_CTX_get_channel_id_cb(SSL_CTX *ctx))(
SSL *ssl, EVP_PKEY **out_pkey);
// DTLS-SRTP. // DTLS-SRTP.
// //

@ -684,10 +684,6 @@ int ssl_run_handshake(SSL_HANDSHAKE *hs, bool *out_early_return) {
ssl->s3->rwstate = SSL_ERROR_WANT_X509_LOOKUP; ssl->s3->rwstate = SSL_ERROR_WANT_X509_LOOKUP;
hs->wait = ssl_hs_ok; hs->wait = ssl_hs_ok;
return -1; return -1;
case ssl_hs_channel_id_lookup:
ssl->s3->rwstate = SSL_ERROR_WANT_CHANNEL_ID_LOOKUP;
hs->wait = ssl_hs_ok;
return -1;
case ssl_hs_private_key_operation: case ssl_hs_private_key_operation:
ssl->s3->rwstate = SSL_ERROR_WANT_PRIVATE_KEY_OPERATION; ssl->s3->rwstate = SSL_ERROR_WANT_PRIVATE_KEY_OPERATION;
hs->wait = ssl_hs_ok; hs->wait = ssl_hs_ok;

@ -1480,18 +1480,6 @@ static enum ssl_hs_wait_t do_send_client_certificate_verify(SSL_HANDSHAKE *hs) {
static enum ssl_hs_wait_t do_send_client_finished(SSL_HANDSHAKE *hs) { static enum ssl_hs_wait_t do_send_client_finished(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl; SSL *const ssl = hs->ssl;
hs->can_release_private_key = true; hs->can_release_private_key = true;
// Resolve Channel ID first, before any non-idempotent operations.
if (hs->channel_id_negotiated) {
if (!ssl_do_channel_id_callback(hs)) {
return ssl_hs_error;
}
if (hs->config->channel_id_private == NULL) {
hs->state = state_send_client_finished;
return ssl_hs_channel_id_lookup;
}
}
if (!ssl->method->add_change_cipher_spec(ssl) || if (!ssl->method->add_change_cipher_spec(ssl) ||
!tls1_change_cipher_state(hs, evp_aead_seal)) { !tls1_change_cipher_state(hs, evp_aead_seal)) {
return ssl_hs_error; return ssl_hs_error;

@ -1557,7 +1557,6 @@ enum ssl_hs_wait_t {
ssl_hs_handoff, ssl_hs_handoff,
ssl_hs_handback, ssl_hs_handback,
ssl_hs_x509_lookup, ssl_hs_x509_lookup,
ssl_hs_channel_id_lookup,
ssl_hs_private_key_operation, ssl_hs_private_key_operation,
ssl_hs_pending_session, ssl_hs_pending_session,
ssl_hs_pending_ticket, ssl_hs_pending_ticket,
@ -2862,7 +2861,8 @@ struct SSL_CONFIG {
Array<uint16_t> supported_group_list; // our list Array<uint16_t> supported_group_list; // our list
// The client's Channel ID private key. // channel_id_private is the client's Channel ID private key, or null if
// Channel ID should not be offered on this connection.
UniquePtr<EVP_PKEY> channel_id_private; UniquePtr<EVP_PKEY> channel_id_private;
// For a client, this contains the list of supported protocols in wire // For a client, this contains the list of supported protocols in wire
@ -2901,9 +2901,8 @@ struct SSL_CONFIG {
// whether OCSP stapling will be requested. // whether OCSP stapling will be requested.
bool ocsp_stapling_enabled : 1; bool ocsp_stapling_enabled : 1;
// channel_id_enabled is copied from the |SSL_CTX|. For a server, means that // channel_id_enabled is copied from the |SSL_CTX|. For a server, it means
// we'll accept Channel IDs from clients. For a client, means that we'll // that we'll accept Channel IDs from clients. It is ignored on the client.
// advertise support.
bool channel_id_enabled : 1; bool channel_id_enabled : 1;
// If enforce_rsa_key_usage is true, the handshake will fail if the // If enforce_rsa_key_usage is true, the handshake will fail if the
@ -3195,12 +3194,6 @@ bool tls1_channel_id_hash(SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len);
// data. // data.
bool tls1_record_handshake_hashes_for_channel_id(SSL_HANDSHAKE *hs); bool tls1_record_handshake_hashes_for_channel_id(SSL_HANDSHAKE *hs);
// ssl_do_channel_id_callback checks runs |hs->ssl->ctx->channel_id_cb| if
// necessary. It returns true on success and false on fatal error. Note that, on
// success, |hs->ssl->channel_id_private| may be unset, in which case the
// operation should be retried later.
bool ssl_do_channel_id_callback(SSL_HANDSHAKE *hs);
// ssl_can_write returns whether |ssl| is allowed to write. // ssl_can_write returns whether |ssl| is allowed to write.
bool ssl_can_write(const SSL *ssl); bool ssl_can_write(const SSL *ssl);
@ -3324,9 +3317,6 @@ struct ssl_ctx_st {
int (*client_cert_cb)(SSL *ssl, X509 **out_x509, int (*client_cert_cb)(SSL *ssl, X509 **out_x509,
EVP_PKEY **out_pkey) = nullptr; EVP_PKEY **out_pkey) = nullptr;
// get channel id callback
void (*channel_id_cb)(SSL *ssl, EVP_PKEY **out_pkey) = nullptr;
CRYPTO_EX_DATA ex_data; CRYPTO_EX_DATA ex_data;
// Default values used when no per-SSL value is defined follow // Default values used when no per-SSL value is defined follow
@ -3454,7 +3444,8 @@ struct ssl_ctx_st {
// Supported group values inherited by SSL structure // Supported group values inherited by SSL structure
bssl::Array<uint16_t> supported_group_list; bssl::Array<uint16_t> supported_group_list;
// The client's Channel ID private key. // channel_id_private is the client's Channel ID private key, or null if
// Channel ID should not be offered on this connection.
bssl::UniquePtr<EVP_PKEY> channel_id_private; bssl::UniquePtr<EVP_PKEY> channel_id_private;
// ech_server_config_list contains the server's list of ECHConfig values and // ech_server_config_list contains the server's list of ECHConfig values and

@ -1369,7 +1369,6 @@ int SSL_get_error(const SSL *ssl, int ret_code) {
case SSL_ERROR_HANDOFF: case SSL_ERROR_HANDOFF:
case SSL_ERROR_HANDBACK: case SSL_ERROR_HANDBACK:
case SSL_ERROR_WANT_X509_LOOKUP: case SSL_ERROR_WANT_X509_LOOKUP:
case SSL_ERROR_WANT_CHANNEL_ID_LOOKUP:
case SSL_ERROR_WANT_PRIVATE_KEY_OPERATION: case SSL_ERROR_WANT_PRIVATE_KEY_OPERATION:
case SSL_ERROR_PENDING_TICKET: case SSL_ERROR_PENDING_TICKET:
case SSL_ERROR_EARLY_DATA_REJECTED: case SSL_ERROR_EARLY_DATA_REJECTED:
@ -1443,8 +1442,6 @@ const char *SSL_error_description(int err) {
return "WANT_CONNECT"; return "WANT_CONNECT";
case SSL_ERROR_WANT_ACCEPT: case SSL_ERROR_WANT_ACCEPT:
return "WANT_ACCEPT"; return "WANT_ACCEPT";
case SSL_ERROR_WANT_CHANNEL_ID_LOOKUP:
return "WANT_CHANNEL_ID_LOOKUP";
case SSL_ERROR_PENDING_SESSION: case SSL_ERROR_PENDING_SESSION:
return "PENDING_SESSION"; return "PENDING_SESSION";
case SSL_ERROR_PENDING_CERTIFICATE: case SSL_ERROR_PENDING_CERTIFICATE:
@ -2437,8 +2434,6 @@ int SSL_CTX_set1_tls_channel_id(SSL_CTX *ctx, EVP_PKEY *private_key) {
} }
ctx->channel_id_private = UpRef(private_key); ctx->channel_id_private = UpRef(private_key);
ctx->channel_id_enabled = true;
return 1; return 1;
} }
@ -2452,8 +2447,6 @@ int SSL_set1_tls_channel_id(SSL *ssl, EVP_PKEY *private_key) {
} }
ssl->config->channel_id_private = UpRef(private_key); ssl->config->channel_id_private = UpRef(private_key);
ssl->config->channel_id_enabled = true;
return 1; return 1;
} }

@ -1284,12 +1284,3 @@ void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl, int type,
int value) { int value) {
return ctx->info_callback; return ctx->info_callback;
} }
void SSL_CTX_set_channel_id_cb(SSL_CTX *ctx,
void (*cb)(SSL *ssl, EVP_PKEY **pkey)) {
ctx->channel_id_cb = cb;
}
void (*SSL_CTX_get_channel_id_cb(SSL_CTX *ctx))(SSL *ssl, EVP_PKEY **pkey) {
return ctx->channel_id_cb;
}

@ -1643,7 +1643,7 @@ static bool ext_alpn_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
static bool ext_channel_id_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { static bool ext_channel_id_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl; SSL *const ssl = hs->ssl;
if (!hs->config->channel_id_enabled || SSL_is_dtls(ssl)) { if (!hs->config->channel_id_private || SSL_is_dtls(ssl)) {
return true; return true;
} }
@ -1663,7 +1663,7 @@ static bool ext_channel_id_parse_serverhello(SSL_HANDSHAKE *hs,
} }
assert(!SSL_is_dtls(hs->ssl)); assert(!SSL_is_dtls(hs->ssl));
assert(hs->config->channel_id_enabled); assert(hs->config->channel_id_private);
if (CBS_len(contents) != 0) { if (CBS_len(contents) != 0) {
return false; return false;
@ -4189,23 +4189,6 @@ bool tls1_record_handshake_hashes_for_channel_id(SSL_HANDSHAKE *hs) {
return true; return true;
} }
bool ssl_do_channel_id_callback(SSL_HANDSHAKE *hs) {
if (hs->config->channel_id_private != NULL ||
hs->ssl->ctx->channel_id_cb == NULL) {
return true;
}
EVP_PKEY *key = NULL;
hs->ssl->ctx->channel_id_cb(hs->ssl, &key);
if (key == NULL) {
// The caller should try again later.
return true;
}
UniquePtr<EVP_PKEY> free_key(key);
return SSL_set1_tls_channel_id(hs->ssl, key);
}
bool ssl_is_sct_list_valid(const CBS *contents) { bool ssl_is_sct_list_valid(const CBS *contents) {
// Shallow parse the SCT list for sanity. By the RFC // Shallow parse the SCT list for sanity. By the RFC
// (https://tools.ietf.org/html/rfc6962#section-3.3) neither the list nor any // (https://tools.ietf.org/html/rfc6962#section-3.3) neither the list nor any

@ -86,14 +86,6 @@ bool RetryAsync(SSL *ssl, int ret) {
case SSL_ERROR_WANT_WRITE: case SSL_ERROR_WANT_WRITE:
AsyncBioAllowWrite(test_state->async_bio, 1); AsyncBioAllowWrite(test_state->async_bio, 1);
return true; return true;
case SSL_ERROR_WANT_CHANNEL_ID_LOOKUP: {
UniquePtr<EVP_PKEY> pkey = LoadPrivateKey(config->send_channel_id);
if (!pkey) {
return false;
}
test_state->channel_id = std::move(pkey);
return true;
}
case SSL_ERROR_WANT_X509_LOOKUP: case SSL_ERROR_WANT_X509_LOOKUP:
test_state->cert_ready = true; test_state->cert_ready = true;
return true; return true;

@ -695,10 +695,6 @@ static void InfoCallback(const SSL *ssl, int type, int val) {
} }
} }
static void ChannelIdCallback(SSL *ssl, EVP_PKEY **out_pkey) {
*out_pkey = GetTestState(ssl)->channel_id.release();
}
static SSL_SESSION *GetSessionCallback(SSL *ssl, const uint8_t *data, int len, static SSL_SESSION *GetSessionCallback(SSL *ssl, const uint8_t *data, int len,
int *copy) { int *copy) {
TestState *async_state = GetTestState(ssl); TestState *async_state = GetTestState(ssl);
@ -1376,8 +1372,6 @@ bssl::UniquePtr<SSL_CTX> TestConfig::SetupCtx(SSL_CTX *old_ctx) const {
SSL_CTX_set_alpn_select_cb(ssl_ctx.get(), AlpnSelectCallback, NULL); SSL_CTX_set_alpn_select_cb(ssl_ctx.get(), AlpnSelectCallback, NULL);
} }
SSL_CTX_set_channel_id_cb(ssl_ctx.get(), ChannelIdCallback);
SSL_CTX_set_current_time_cb(ssl_ctx.get(), CurrentTimeCallback); SSL_CTX_set_current_time_cb(ssl_ctx.get(), CurrentTimeCallback);
SSL_CTX_set_info_callback(ssl_ctx.get(), InfoCallback); SSL_CTX_set_info_callback(ssl_ctx.get(), InfoCallback);
@ -1727,13 +1721,9 @@ bssl::UniquePtr<SSL> TestConfig::NewSSL(
} }
} }
if (!send_channel_id.empty()) { if (!send_channel_id.empty()) {
SSL_set_tls_channel_id_enabled(ssl.get(), 1); bssl::UniquePtr<EVP_PKEY> pkey = LoadPrivateKey(send_channel_id);
if (!async) { if (!pkey || !SSL_set1_tls_channel_id(ssl.get(), pkey.get())) {
// The async case will be supplied by |ChannelIdCallback|. return nullptr;
bssl::UniquePtr<EVP_PKEY> pkey = LoadPrivateKey(send_channel_id);
if (!pkey || !SSL_set1_tls_channel_id(ssl.get(), pkey.get())) {
return nullptr;
}
} }
} }
if (!host_name.empty() && if (!host_name.empty() &&

@ -41,7 +41,6 @@ struct TestState {
// packeted_bio is the packeted BIO which simulates read timeouts. // packeted_bio is the packeted BIO which simulates read timeouts.
BIO *packeted_bio = nullptr; BIO *packeted_bio = nullptr;
std::unique_ptr<MockQuicTransport> quic_transport; std::unique_ptr<MockQuicTransport> quic_transport;
bssl::UniquePtr<EVP_PKEY> channel_id;
bool cert_ready = false; bool cert_ready = false;
bssl::UniquePtr<SSL_SESSION> session; bssl::UniquePtr<SSL_SESSION> session;
bssl::UniquePtr<SSL_SESSION> pending_session; bssl::UniquePtr<SSL_SESSION> pending_session;

@ -821,15 +821,6 @@ static enum ssl_hs_wait_t do_complete_second_flight(SSL_HANDSHAKE *hs) {
// Send a Channel ID assertion if necessary. // Send a Channel ID assertion if necessary.
if (hs->channel_id_negotiated) { if (hs->channel_id_negotiated) {
if (!ssl_do_channel_id_callback(hs)) {
hs->tls13_state = state_complete_second_flight;
return ssl_hs_error;
}
if (hs->config->channel_id_private == NULL) {
return ssl_hs_channel_id_lookup;
}
ScopedCBB cbb; ScopedCBB cbb;
CBB body; CBB body;
if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CHANNEL_ID) || if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CHANNEL_ID) ||

Loading…
Cancel
Save