|
|
@@ -2319,6 +2319,131 @@ static bool TestSessionTimeout(bool is_dtls, const SSL_METHOD *method, |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
static int SetSessionTimeoutCallback(SSL *ssl, void *arg) { |
|
|
|
long timeout = *(long *) arg; |
|
|
|
SSL_set_session_timeout(ssl, timeout); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
static bool TestSessionTimeoutCertCallback(bool is_dtls, |
|
|
|
const SSL_METHOD *method, |
|
|
|
uint16_t version) { |
|
|
|
static const int kStartTime = 1000; |
|
|
|
g_current_time.tv_sec = kStartTime; |
|
|
|
|
|
|
|
bssl::UniquePtr<X509> cert = GetTestCertificate(); |
|
|
|
bssl::UniquePtr<EVP_PKEY> key = GetTestKey(); |
|
|
|
if (!cert || !key) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method)); |
|
|
|
bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method)); |
|
|
|
if (!server_ctx || !client_ctx || |
|
|
|
!SSL_CTX_use_certificate(server_ctx.get(), cert.get()) || |
|
|
|
!SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) || |
|
|
|
!SSL_CTX_set_min_proto_version(client_ctx.get(), version) || |
|
|
|
!SSL_CTX_set_max_proto_version(client_ctx.get(), version) || |
|
|
|
!SSL_CTX_set_min_proto_version(server_ctx.get(), version) || |
|
|
|
!SSL_CTX_set_max_proto_version(server_ctx.get(), version)) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH); |
|
|
|
SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH); |
|
|
|
|
|
|
|
SSL_CTX_set_current_time_cb(server_ctx.get(), CurrentTimeCallback); |
|
|
|
|
|
|
|
long timeout = 25; |
|
|
|
SSL_CTX_set_cert_cb(server_ctx.get(), SetSessionTimeoutCallback, &timeout); |
|
|
|
|
|
|
|
bssl::UniquePtr<SSL_SESSION> session = |
|
|
|
CreateClientSession(client_ctx.get(), server_ctx.get()); |
|
|
|
if (!session) { |
|
|
|
fprintf(stderr, "Error getting session.\n"); |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
// Advance the clock just behind the timeout. |
|
|
|
g_current_time.tv_sec += timeout - 1; |
|
|
|
|
|
|
|
if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(), |
|
|
|
true /* expect session reused */)) { |
|
|
|
fprintf(stderr, "Error resuming session.\n"); |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
// Advance the clock one more second. |
|
|
|
g_current_time.tv_sec++; |
|
|
|
|
|
|
|
if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(), |
|
|
|
false /* expect session not reused */)) { |
|
|
|
fprintf(stderr, "Error resuming session.\n"); |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
// Set session timeout to 0 to disable resumption. |
|
|
|
timeout = 0; |
|
|
|
g_current_time.tv_sec = kStartTime; |
|
|
|
|
|
|
|
bssl::UniquePtr<SSL_SESSION> not_resumable_session = |
|
|
|
CreateClientSession(client_ctx.get(), server_ctx.get()); |
|
|
|
if (!not_resumable_session) { |
|
|
|
fprintf(stderr, "Error getting session.\n"); |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), |
|
|
|
not_resumable_session.get(), |
|
|
|
false /* expect session not reused */)) { |
|
|
|
fprintf(stderr, "Error resuming session with timeout of 0.\n"); |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
// Set both context and connection (via callback) default session timeout. |
|
|
|
// The connection one is the one that ends up being used. |
|
|
|
timeout = 25; |
|
|
|
g_current_time.tv_sec = kStartTime; |
|
|
|
|
|
|
|
SSL_CTX_set_timeout(server_ctx.get(), timeout - 10); |
|
|
|
|
|
|
|
bssl::UniquePtr<SSL_SESSION> ctx_and_cb_session = |
|
|
|
CreateClientSession(client_ctx.get(), server_ctx.get()); |
|
|
|
if (!ctx_and_cb_session) { |
|
|
|
fprintf(stderr, "Error getting session.\n"); |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), |
|
|
|
ctx_and_cb_session.get(), |
|
|
|
true /* expect session reused */)) { |
|
|
|
fprintf(stderr, "Error resuming session with timeout of 0.\n"); |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
// Advance the clock just behind the timeout. |
|
|
|
g_current_time.tv_sec += timeout - 1; |
|
|
|
|
|
|
|
if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), |
|
|
|
ctx_and_cb_session.get(), |
|
|
|
true /* expect session reused */)) { |
|
|
|
fprintf(stderr, "Error resuming session.\n"); |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
// Advance the clock one more second. |
|
|
|
g_current_time.tv_sec++; |
|
|
|
|
|
|
|
if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), |
|
|
|
ctx_and_cb_session.get(), |
|
|
|
false /* expect session not reused */)) { |
|
|
|
fprintf(stderr, "Error resuming session.\n"); |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
static int SwitchContext(SSL *ssl, int *out_alert, void *arg) { |
|
|
|
SSL_CTX *ctx = reinterpret_cast<SSL_CTX*>(arg); |
|
|
|
SSL_set_SSL_CTX(ssl, ctx); |
|
|
@@ -2664,6 +2789,7 @@ int main() { |
|
|
|
!TestClientHello() || |
|
|
|
!ForEachVersion(TestSessionIDContext) || |
|
|
|
!ForEachVersion(TestSessionTimeout) || |
|
|
|
!ForEachVersion(TestSessionTimeoutCertCallback) || |
|
|
|
!ForEachVersion(TestSNICallback) || |
|
|
|
!TestEarlyCallbackVersionSwitch() || |
|
|
|
!TestSetVersion() || |
|
|
|