Set SSL_in_init to false before new_session_cb.

This fixes a regression in Conscrypt added by
https://boringssl-review.googlesource.com/19144. SSL_get_session
otherwise attempts to return hs->new_session, but that has been released
at this point.

Change-Id: I55b41cbefb65b3ae3cfbfad72f6338bd66db3341
Reviewed-on: https://boringssl-review.googlesource.com/19904
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
This commit is contained in:
Steven Valdez 2017-08-31 10:15:48 -04:00 committed by CQ bot account: commit-bot@chromium.org
parent 1ab133a9da
commit d816874c52
6 changed files with 26 additions and 1 deletions

View File

@ -126,6 +126,7 @@ SSL_HANDSHAKE::SSL_HANDSHAKE(SSL *ssl_arg)
needs_psk_binder(0), needs_psk_binder(0),
received_hello_retry_request(0), received_hello_retry_request(0),
received_custom_extension(0), received_custom_extension(0),
handshake_finalized(0),
accept_psk_mode(0), accept_psk_mode(0),
cert_request(0), cert_request(0),
certificate_status_expected(0), certificate_status_expected(0),

View File

@ -1709,6 +1709,7 @@ static enum ssl_hs_wait_t do_finish_client_handshake(SSL_HANDSHAKE *hs) {
hs->new_session.reset(); hs->new_session.reset();
} }
hs->handshake_finalized = 1;
ssl->s3->initial_handshake_complete = 1; ssl->s3->initial_handshake_complete = 1;
ssl_update_cache(hs, SSL_SESS_CACHE_CLIENT); ssl_update_cache(hs, SSL_SESS_CACHE_CLIENT);

View File

@ -1568,6 +1568,7 @@ static enum ssl_hs_wait_t do_finish_server_handshake(SSL_HANDSHAKE *hs) {
ssl->s3->established_session->not_resumable = 0; ssl->s3->established_session->not_resumable = 0;
} }
hs->handshake_finalized = 1;
ssl->s3->initial_handshake_complete = 1; ssl->s3->initial_handshake_complete = 1;
ssl_update_cache(hs, SSL_SESS_CACHE_SERVER); ssl_update_cache(hs, SSL_SESS_CACHE_SERVER);

View File

@ -1243,6 +1243,10 @@ struct SSL_HANDSHAKE {
unsigned received_custom_extension:1; unsigned received_custom_extension:1;
// handshake_finalized is true once the handshake has completed, at which
// point accessors should use the established state.
unsigned handshake_finalized:1;
// accept_psk_mode stores whether the client's PSK mode is compatible with our // accept_psk_mode stores whether the client's PSK mode is compatible with our
// preferences. // preferences.
unsigned accept_psk_mode:1; unsigned accept_psk_mode:1;

View File

@ -2336,7 +2336,11 @@ int SSL_is_init_finished(const SSL *ssl) {
} }
int SSL_in_init(const SSL *ssl) { int SSL_in_init(const SSL *ssl) {
return ssl->s3->hs != NULL; // This returns false once all the handshake state has been finalized, to
// allow callbacks and getters based on SSL_in_init to return the correct
// values.
SSL_HANDSHAKE *hs = ssl->s3->hs;
return hs != nullptr && !hs->handshake_finalized;
} }
int SSL_in_false_start(const SSL *ssl) { int SSL_in_false_start(const SSL *ssl) {

View File

@ -887,6 +887,12 @@ static void InfoCallback(const SSL *ssl, int type, int val) {
// test fails. // test fails.
abort(); abort();
} }
// This callback is called when the handshake completes. |SSL_get_session|
// must continue to work and |SSL_in_init| must return false.
if (SSL_in_init(ssl) || SSL_get_session(ssl) == nullptr) {
fprintf(stderr, "Invalid state for SSL_CB_HANDSHAKE_DONE.\n");
abort();
}
GetTestState(ssl)->handshake_done = true; GetTestState(ssl)->handshake_done = true;
// Callbacks may be called again on a new handshake. // Callbacks may be called again on a new handshake.
@ -896,6 +902,14 @@ static void InfoCallback(const SSL *ssl, int type, int val) {
} }
static int NewSessionCallback(SSL *ssl, SSL_SESSION *session) { static int NewSessionCallback(SSL *ssl, SSL_SESSION *session) {
// This callback is called as the handshake completes. |SSL_get_session|
// must continue to work and, historically, |SSL_in_init| returned false at
// this point.
if (SSL_in_init(ssl) || SSL_get_session(ssl) == nullptr) {
fprintf(stderr, "Invalid state for NewSessionCallback.\n");
abort();
}
GetTestState(ssl)->got_new_session = true; GetTestState(ssl)->got_new_session = true;
GetTestState(ssl)->new_session.reset(session); GetTestState(ssl)->new_session.reset(session);
return 1; return 1;