Skip to content

Commit

Permalink
Allow configuring QUIC method per-connection
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
ghedo authored and CQ bot account: commit-bot@chromium.org committed Jan 14, 2019
1 parent de3c1f6 commit 3cbb029
Show file tree
Hide file tree
Showing 9 changed files with 45 additions and 27 deletions.
6 changes: 6 additions & 0 deletions include/openssl/ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
//
Expand Down
2 changes: 1 addition & 1 deletion ssl/handshake.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
3 changes: 3 additions & 0 deletions ssl/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
14 changes: 7 additions & 7 deletions ssl/s3_both.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
Expand All @@ -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;
}
Expand Down
6 changes: 3 additions & 3 deletions ssl/s3_pkt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
17 changes: 13 additions & 4 deletions ssl/ssl_lib.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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())) {
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion ssl/ssl_versions.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
2 changes: 1 addition & 1 deletion ssl/tls13_both.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
20 changes: 10 additions & 10 deletions ssl/tls13_enc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 3cbb029

Please sign in to comment.