Allow configuring QUIC method per-connection
This allows sharing SSL_CTX between TCP and QUIC connections, such that common settings can be configured without having to duplicate the context. Change-Id: Ie920e7f2a772dd6c6c7b63fdac243914ac5b7b26 Reviewed-on: https://boringssl-review.googlesource.com/c/33904 Reviewed-by: David Benjamin <davidben@google.com> Commit-Queue: David Benjamin <davidben@google.com>
This commit is contained in:
committed by
CQ bot account: commit-bot@chromium.org
parent
de3c1f69cc
commit
3cbb0299a2
@@ -3170,6 +3170,12 @@ OPENSSL_EXPORT int SSL_process_quic_post_handshake(SSL *ssl);
|
||||
OPENSSL_EXPORT int SSL_CTX_set_quic_method(SSL_CTX *ctx,
|
||||
const SSL_QUIC_METHOD *quic_method);
|
||||
|
||||
// SSL_set_quic_method configures the QUIC hooks. This should only be
|
||||
// configured with a minimum version of TLS 1.3. |quic_method| must remain valid
|
||||
// for the lifetime of |ssl|. It returns one on success and zero on error.
|
||||
OPENSSL_EXPORT int SSL_set_quic_method(SSL *ssl,
|
||||
const SSL_QUIC_METHOD *quic_method);
|
||||
|
||||
|
||||
// Early data.
|
||||
//
|
||||
|
||||
+1
-1
@@ -544,7 +544,7 @@ int ssl_run_handshake(SSL_HANDSHAKE *hs, bool *out_early_return) {
|
||||
case ssl_hs_read_server_hello:
|
||||
case ssl_hs_read_message:
|
||||
case ssl_hs_read_change_cipher_spec: {
|
||||
if (ssl->ctx->quic_method) {
|
||||
if (ssl->quic_method) {
|
||||
hs->wait = ssl_hs_ok;
|
||||
// The change cipher spec is omitted in QUIC.
|
||||
if (hs->wait != ssl_hs_read_change_cipher_spec) {
|
||||
|
||||
@@ -3170,6 +3170,9 @@ struct ssl_st {
|
||||
uint32_t max_cert_list = 0;
|
||||
bssl::UniquePtr<char> hostname;
|
||||
|
||||
// quic_method is the method table corresponding to the QUIC hooks.
|
||||
const SSL_QUIC_METHOD *quic_method = nullptr;
|
||||
|
||||
// renegotiate_mode controls how peer renegotiation attempts are handled.
|
||||
ssl_renegotiate_mode_t renegotiate_mode = ssl_renegotiate_never;
|
||||
|
||||
|
||||
+7
-7
@@ -192,7 +192,7 @@ bool ssl3_add_message(SSL *ssl, Array<uint8_t> msg) {
|
||||
//
|
||||
// TODO(davidben): See if we can do this uniformly.
|
||||
Span<const uint8_t> rest = msg;
|
||||
if (ssl->ctx->quic_method == nullptr &&
|
||||
if (ssl->quic_method == nullptr &&
|
||||
ssl->s3->aead_write_ctx->is_null_cipher()) {
|
||||
while (!rest.empty()) {
|
||||
Span<const uint8_t> chunk = rest.subspan(0, ssl->max_send_fragment);
|
||||
@@ -248,9 +248,9 @@ bool tls_flush_pending_hs_data(SSL *ssl) {
|
||||
auto data =
|
||||
MakeConstSpan(reinterpret_cast<const uint8_t *>(pending_hs_data->data),
|
||||
pending_hs_data->length);
|
||||
if (ssl->ctx->quic_method) {
|
||||
if (!ssl->ctx->quic_method->add_handshake_data(ssl, ssl->s3->write_level,
|
||||
data.data(), data.size())) {
|
||||
if (ssl->quic_method) {
|
||||
if (!ssl->quic_method->add_handshake_data(ssl, ssl->s3->write_level,
|
||||
data.data(), data.size())) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_QUIC_INTERNAL_ERROR);
|
||||
return false;
|
||||
}
|
||||
@@ -267,7 +267,7 @@ bool ssl3_add_change_cipher_spec(SSL *ssl) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ssl->ctx->quic_method &&
|
||||
if (!ssl->quic_method &&
|
||||
!add_record_to_flight(ssl, SSL3_RT_CHANGE_CIPHER_SPEC,
|
||||
kChangeCipherSpec)) {
|
||||
return false;
|
||||
@@ -283,13 +283,13 @@ int ssl3_flush_flight(SSL *ssl) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ssl->ctx->quic_method) {
|
||||
if (ssl->quic_method) {
|
||||
if (ssl->s3->write_shutdown != ssl_shutdown_none) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!ssl->ctx->quic_method->flush_flight(ssl)) {
|
||||
if (!ssl->quic_method->flush_flight(ssl)) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_QUIC_INTERNAL_ERROR);
|
||||
return -1;
|
||||
}
|
||||
|
||||
+3
-3
@@ -410,9 +410,9 @@ int ssl_send_alert(SSL *ssl, int level, int desc) {
|
||||
}
|
||||
|
||||
int ssl3_dispatch_alert(SSL *ssl) {
|
||||
if (ssl->ctx->quic_method) {
|
||||
if (!ssl->ctx->quic_method->send_alert(ssl, ssl->s3->write_level,
|
||||
ssl->s3->send_alert[1])) {
|
||||
if (ssl->quic_method) {
|
||||
if (!ssl->quic_method->send_alert(ssl, ssl->s3->write_level,
|
||||
ssl->s3->send_alert[1])) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_QUIC_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
+13
-4
@@ -714,6 +714,7 @@ SSL *SSL_new(SSL_CTX *ctx) {
|
||||
ssl->config->ocsp_stapling_enabled = ctx->ocsp_stapling_enabled;
|
||||
ssl->config->handoff = ctx->handoff;
|
||||
ssl->config->ignore_tls13_downgrade = ctx->ignore_tls13_downgrade;
|
||||
ssl->quic_method = ctx->quic_method;
|
||||
|
||||
if (!ssl->method->ssl_new(ssl.get()) ||
|
||||
!ssl->ctx->x509_method->ssl_new(ssl->s3->hs.get())) {
|
||||
@@ -850,7 +851,7 @@ enum ssl_encryption_level_t SSL_quic_write_level(const SSL *ssl) {
|
||||
|
||||
int SSL_provide_quic_data(SSL *ssl, enum ssl_encryption_level_t level,
|
||||
const uint8_t *data, size_t len) {
|
||||
if (ssl->ctx->quic_method == nullptr) {
|
||||
if (ssl->quic_method == nullptr) {
|
||||
OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return 0;
|
||||
}
|
||||
@@ -1077,7 +1078,7 @@ int SSL_read(SSL *ssl, void *buf, int num) {
|
||||
}
|
||||
|
||||
int SSL_peek(SSL *ssl, void *buf, int num) {
|
||||
if (ssl->ctx->quic_method != nullptr) {
|
||||
if (ssl->quic_method != nullptr) {
|
||||
OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return 0;
|
||||
}
|
||||
@@ -1098,7 +1099,7 @@ int SSL_peek(SSL *ssl, void *buf, int num) {
|
||||
int SSL_write(SSL *ssl, const void *buf, int num) {
|
||||
ssl_reset_error_state(ssl);
|
||||
|
||||
if (ssl->ctx->quic_method != nullptr) {
|
||||
if (ssl->quic_method != nullptr) {
|
||||
OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return 0;
|
||||
}
|
||||
@@ -1342,7 +1343,7 @@ int SSL_get_error(const SSL *ssl, int ret_code) {
|
||||
return SSL_ERROR_HANDBACK;
|
||||
|
||||
case SSL_READING: {
|
||||
if (ssl->ctx->quic_method) {
|
||||
if (ssl->quic_method) {
|
||||
return SSL_ERROR_WANT_READ;
|
||||
}
|
||||
BIO *bio = SSL_get_rbio(ssl);
|
||||
@@ -2459,6 +2460,14 @@ int SSL_CTX_set_quic_method(SSL_CTX *ctx, const SSL_QUIC_METHOD *quic_method) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SSL_set_quic_method(SSL *ssl, const SSL_QUIC_METHOD *quic_method) {
|
||||
if (ssl->method->is_dtls) {
|
||||
return 0;
|
||||
}
|
||||
ssl->quic_method = quic_method;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
|
||||
CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func) {
|
||||
int index;
|
||||
|
||||
+1
-1
@@ -192,7 +192,7 @@ bool ssl_get_version_range(const SSL_HANDSHAKE *hs, uint16_t *out_min_version,
|
||||
uint16_t max_version = hs->config->conf_max_version;
|
||||
|
||||
// QUIC requires TLS 1.3.
|
||||
if (hs->ssl->ctx->quic_method && min_version < TLS1_3_VERSION) {
|
||||
if (hs->ssl->quic_method && min_version < TLS1_3_VERSION) {
|
||||
min_version = TLS1_3_VERSION;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -655,7 +655,7 @@ static bool tls13_receive_key_update(SSL *ssl, const SSLMessage &msg) {
|
||||
bool tls13_post_handshake(SSL *ssl, const SSLMessage &msg) {
|
||||
if (msg.type == SSL3_MT_KEY_UPDATE) {
|
||||
ssl->s3->key_update_count++;
|
||||
if (ssl->ctx->quic_method != nullptr ||
|
||||
if (ssl->quic_method != nullptr ||
|
||||
ssl->s3->key_update_count > kMaxKeyUpdates) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MANY_KEY_UPDATES);
|
||||
ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
|
||||
|
||||
+10
-10
@@ -144,7 +144,7 @@ bool tls13_set_traffic_key(SSL *ssl, enum ssl_encryption_level_t level,
|
||||
}
|
||||
|
||||
UniquePtr<SSLAEADContext> traffic_aead;
|
||||
if (ssl->ctx->quic_method == nullptr) {
|
||||
if (ssl->quic_method == nullptr) {
|
||||
// Look up cipher suite properties.
|
||||
const EVP_AEAD *aead;
|
||||
size_t discard;
|
||||
@@ -237,16 +237,16 @@ bool tls13_derive_early_secrets(SSL_HANDSHAKE *hs) {
|
||||
}
|
||||
ssl->s3->early_exporter_secret_len = hs->hash_len;
|
||||
|
||||
if (ssl->ctx->quic_method != nullptr) {
|
||||
if (ssl->quic_method != nullptr) {
|
||||
if (ssl->server) {
|
||||
if (!ssl->ctx->quic_method->set_encryption_secrets(
|
||||
if (!ssl->quic_method->set_encryption_secrets(
|
||||
ssl, ssl_encryption_early_data, nullptr, hs->early_traffic_secret,
|
||||
hs->hash_len)) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_QUIC_INTERNAL_ERROR);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!ssl->ctx->quic_method->set_encryption_secrets(
|
||||
if (!ssl->quic_method->set_encryption_secrets(
|
||||
ssl, ssl_encryption_early_data, hs->early_traffic_secret, nullptr,
|
||||
hs->hash_len)) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_QUIC_INTERNAL_ERROR);
|
||||
@@ -273,16 +273,16 @@ bool tls13_derive_handshake_secrets(SSL_HANDSHAKE *hs) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ssl->ctx->quic_method != nullptr) {
|
||||
if (ssl->quic_method != nullptr) {
|
||||
if (ssl->server) {
|
||||
if (!ssl->ctx->quic_method->set_encryption_secrets(
|
||||
if (!ssl->quic_method->set_encryption_secrets(
|
||||
ssl, ssl_encryption_handshake, hs->client_handshake_secret,
|
||||
hs->server_handshake_secret, hs->hash_len)) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_QUIC_INTERNAL_ERROR);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!ssl->ctx->quic_method->set_encryption_secrets(
|
||||
if (!ssl->quic_method->set_encryption_secrets(
|
||||
ssl, ssl_encryption_handshake, hs->server_handshake_secret,
|
||||
hs->client_handshake_secret, hs->hash_len)) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_QUIC_INTERNAL_ERROR);
|
||||
@@ -314,16 +314,16 @@ bool tls13_derive_application_secrets(SSL_HANDSHAKE *hs) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ssl->ctx->quic_method != nullptr) {
|
||||
if (ssl->quic_method != nullptr) {
|
||||
if (ssl->server) {
|
||||
if (!ssl->ctx->quic_method->set_encryption_secrets(
|
||||
if (!ssl->quic_method->set_encryption_secrets(
|
||||
ssl, ssl_encryption_application, hs->client_traffic_secret_0,
|
||||
hs->server_traffic_secret_0, hs->hash_len)) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_QUIC_INTERNAL_ERROR);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!ssl->ctx->quic_method->set_encryption_secrets(
|
||||
if (!ssl->quic_method->set_encryption_secrets(
|
||||
ssl, ssl_encryption_application, hs->server_traffic_secret_0,
|
||||
hs->client_traffic_secret_0, hs->hash_len)) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_QUIC_INTERNAL_ERROR);
|
||||
|
||||
Reference in New Issue
Block a user