SSL_CONFIG: new struct for sheddable handshake configuration.
|SSL_CONFIG| is a container for bits of configuration that are
unneeded after the handshake completes. By default it is retained for
the life of the |SSL|, but it may be shed at the caller's option by
calling SSL_set_shed_handshake_config(). This is incompatible with
renegotiation, and with SSL_clear().
|SSL_CONFIG| is reachable by |ssl->config| and by |hs->config|. The
latter is always non-NULL. To avoid null checks, I've changed the
signature of a number of functions from |SSL*| arguments to
|SSL_HANDSHAKE*| arguments.
When configuration has been shed, setters that touch |SSL_CONFIG|
return an error value if that is possible. Setters that return |void|
do nothing.
Getters that request |SSL_CONFIG| values will fail with an |assert| if
the configuration has been shed. When asserts are compiled out, they
will return an error value.
The aim of this commit is to simplify analysis of split-handshakes by
making it obvious that some bits of state have no effects beyond the
handshake. It also cuts down on memory usage.
Of note: |SSL_CTX| is still reachable after the configuration has been
shed, and a couple things need to be retained only for the sake of
post-handshake hooks. Perhaps these can be fixed in time.
Change-Id: Idf09642e0518945b81a1e9fcd7331cc9cf7cc2d6
Bug: 123
Reviewed-on: https://boringssl-review.googlesource.com/27644
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/ssl/tls13_server.cc b/ssl/tls13_server.cc
index fe0449d..5303f3f 100644
--- a/ssl/tls13_server.cc
+++ b/ssl/tls13_server.cc
@@ -169,7 +169,7 @@
return 0;
}
session->ticket_age_add_valid = 1;
- if (ssl->cert->enable_early_data) {
+ if (ssl->enable_early_data) {
session->ticket_max_early_data = kMaxEarlyDataAccepted;
}
@@ -186,12 +186,12 @@
!CBB_add_bytes(&nonce_cbb, nonce, sizeof(nonce)) ||
!CBB_add_u16_length_prefixed(&body, &ticket) ||
!tls13_derive_session_psk(session.get(), nonce) ||
- !ssl_encrypt_ticket(ssl, &ticket, session.get()) ||
+ !ssl_encrypt_ticket(hs, &ticket, session.get()) ||
!CBB_add_u16_length_prefixed(&body, &extensions)) {
return 0;
}
- if (ssl->cert->enable_early_data) {
+ if (ssl->enable_early_data) {
CBB early_data_info;
if (!CBB_add_u16(&extensions, TLSEXT_TYPE_early_data) ||
!CBB_add_u16_length_prefixed(&extensions, &early_data_info) ||
@@ -302,7 +302,7 @@
bool unused_renew;
UniquePtr<SSL_SESSION> session;
enum ssl_ticket_aead_result_t ret =
- ssl_process_ticket(ssl, &session, &unused_renew, CBS_data(&ticket),
+ ssl_process_ticket(hs, &session, &unused_renew, CBS_data(&ticket),
CBS_len(&ticket), NULL, 0);
switch (ret) {
case ssl_ticket_aead_success:
@@ -383,7 +383,7 @@
hs->new_session =
SSL_SESSION_dup(session.get(), SSL_SESSION_DUP_AUTH_ONLY);
- if (ssl->cert->enable_early_data &&
+ if (ssl->enable_early_data &&
// Early data must be acceptable for this ticket.
session->ticket_max_early_data != 0 &&
// The client must have offered early data.
@@ -408,8 +408,9 @@
ssl->s3->session_reused = true;
// Resumption incorporates fresh key material, so refresh the timeout.
- ssl_session_renew_timeout(ssl, hs->new_session.get(),
- ssl->session_ctx->session_psk_dhe_timeout);
+ ssl_session_renew_timeout(
+ ssl, hs->new_session.get(),
+ hs->config->session_ctx->session_psk_dhe_timeout);
break;
case ssl_ticket_aead_error:
@@ -599,9 +600,9 @@
if (!ssl->s3->session_reused) {
// Determine whether to request a client certificate.
- hs->cert_request = !!(ssl->verify_mode & SSL_VERIFY_PEER);
+ hs->cert_request = !!(hs->config->verify_mode & SSL_VERIFY_PEER);
// Only request a certificate if Channel ID isn't negotiated.
- if ((ssl->verify_mode & SSL_VERIFY_PEER_IF_NO_OBC) &&
+ if ((hs->config->verify_mode & SSL_VERIFY_PEER_IF_NO_OBC) &&
ssl->s3->tlsext_channel_id_valid) {
hs->cert_request = false;
}
@@ -635,13 +636,13 @@
}
}
- if (ssl_has_client_CAs(ssl)) {
+ if (ssl_has_client_CAs(hs->config)) {
CBB ca_contents;
if (!CBB_add_u16(&cert_request_extensions,
TLSEXT_TYPE_certificate_authorities) ||
!CBB_add_u16_length_prefixed(&cert_request_extensions,
&ca_contents) ||
- !ssl_add_client_CA_list(ssl, &ca_contents) ||
+ !ssl_add_client_CA_list(hs, &ca_contents) ||
!CBB_flush(&cert_request_extensions)) {
return ssl_hs_error;
}
@@ -654,7 +655,7 @@
// Send the server Certificate message, if necessary.
if (!ssl->s3->session_reused) {
- if (!ssl_has_certificate(ssl)) {
+ if (!ssl_has_certificate(hs->config)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
return ssl_hs_error;
}
@@ -805,7 +806,7 @@
}
const int allow_anonymous =
- (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) == 0;
+ (hs->config->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) == 0;
SSLMessage msg;
if (!ssl->method->get_message(ssl, &msg)) {
return ssl_hs_read_message;