Test asynchronous session lookup.

Change-Id: I62c255590ba8e7352e3d6171615cfb369327a646
Reviewed-on: https://boringssl-review.googlesource.com/3347
Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
David Benjamin 2015-02-09 04:28:16 -05:00 committed by Adam Langley
parent 2fff5bf4a8
commit 1b8b691458

View File

@ -45,6 +45,8 @@ struct AsyncState {
ScopedEVP_PKEY channel_id; ScopedEVP_PKEY channel_id;
bool cert_ready; bool cert_ready;
ScopedSSL_SESSION session;
ScopedSSL_SESSION pending_session;
}; };
static void AsyncExFree(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int index, static void AsyncExFree(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int index,
@ -290,6 +292,19 @@ static int cert_callback(SSL *ssl, void *arg) {
return 1; return 1;
} }
static SSL_SESSION *get_session_callback(SSL *ssl, uint8_t *data, int len,
int *copy) {
AsyncState *async_state = GetAsyncState(ssl);
if (async_state->session) {
*copy = 0;
return async_state->session.release();
} else if (async_state->pending_session) {
return SSL_magic_pending_session_ptr();
} else {
return NULL;
}
}
static ScopedSSL_CTX setup_ctx(const TestConfig *config) { static ScopedSSL_CTX setup_ctx(const TestConfig *config) {
ScopedSSL_CTX ssl_ctx(SSL_CTX_new( ScopedSSL_CTX ssl_ctx(SSL_CTX_new(
config->is_dtls ? DTLS_method() : TLS_method())); config->is_dtls ? DTLS_method() : TLS_method()));
@ -318,7 +333,15 @@ static ScopedSSL_CTX setup_ctx(const TestConfig *config) {
return nullptr; return nullptr;
} }
SSL_CTX_set_session_cache_mode(ssl_ctx.get(), SSL_SESS_CACHE_BOTH); if (config->async && config->is_server) {
// Disable the internal session cache. To test asynchronous session lookup,
// we use an external session cache.
SSL_CTX_set_session_cache_mode(
ssl_ctx.get(), SSL_SESS_CACHE_BOTH | SSL_SESS_CACHE_NO_INTERNAL);
SSL_CTX_sess_set_get_cb(ssl_ctx.get(), get_session_callback);
} else {
SSL_CTX_set_session_cache_mode(ssl_ctx.get(), SSL_SESS_CACHE_BOTH);
}
ssl_ctx->select_certificate_cb = select_certificate_callback; ssl_ctx->select_certificate_cb = select_certificate_callback;
@ -383,6 +406,10 @@ static int retry_async(SSL *ssl, int ret, BIO *async,
case SSL_ERROR_WANT_X509_LOOKUP: case SSL_ERROR_WANT_X509_LOOKUP:
GetAsyncState(ssl)->cert_ready = true; GetAsyncState(ssl)->cert_ready = true;
return 1; return 1;
case SSL_ERROR_PENDING_SESSION:
GetAsyncState(ssl)->session =
std::move(GetAsyncState(ssl)->pending_session);
return 1;
default: default:
return 0; return 0;
} }
@ -537,9 +564,16 @@ static int do_exchange(ScopedSSL_SESSION *out_session,
bio.release(); // SSL_set_bio takes ownership. bio.release(); // SSL_set_bio takes ownership.
if (session != NULL) { if (session != NULL) {
if (SSL_set_session(ssl.get(), session) != 1) { if (!config->is_server) {
fprintf(stderr, "failed to set session\n"); if (SSL_set_session(ssl.get(), session) != 1) {
return 2; fprintf(stderr, "failed to set session\n");
return 2;
}
} else if (config->async) {
// The internal session cache is disabled, so install the session
// manually.
GetAsyncState(ssl.get())->pending_session.reset(
SSL_SESSION_up_ref(session));
} }
} }
@ -814,20 +848,15 @@ int main(int argc, char **argv) {
} }
ScopedSSL_SESSION session; ScopedSSL_SESSION session;
int ret = do_exchange(&session, int ret = do_exchange(&session, ssl_ctx.get(), &config, false /* is_resume */,
ssl_ctx.get(), &config,
false /* is_resume */,
3 /* fd */, NULL /* session */); 3 /* fd */, NULL /* session */);
if (ret != 0) { if (ret != 0) {
return ret; return ret;
} }
if (config.resume) { if (config.resume) {
ret = do_exchange(NULL, ret = do_exchange(NULL, ssl_ctx.get(), &config, true /* is_resume */,
ssl_ctx.get(), &config, 4 /* fd */, session.get());
true /* is_resume */,
4 /* fd */,
config.is_server ? NULL : session.get());
if (ret != 0) { if (ret != 0) {
return ret; return ret;
} }