diff options
author | EKR <ekr@rtfm.com> | 2015-02-24 19:45:27 -0800 |
---|---|---|
committer | EKR <ekr@rtfm.com> | 2015-02-24 19:45:27 -0800 |
commit | 0c1aae4bb1cd35c80d19648eadff7d35aa072608 (patch) | |
tree | 0710680ae947e8fad3a65120b1ffb0258e933bbd /external_tests | |
parent | 8f1a34827b177a6b50cacc498bb1e4ef3925be24 (diff) | |
download | nss-hg-0c1aae4bb1cd35c80d19648eadff7d35aa072608.tar.gz |
Bug 1122266. More session resumption tests. r=mt
Diffstat (limited to 'external_tests')
-rw-r--r-- | external_tests/ssl_gtest/gtest_utils.h | 6 | ||||
-rw-r--r-- | external_tests/ssl_gtest/ssl_gtest.cc | 6 | ||||
-rw-r--r-- | external_tests/ssl_gtest/ssl_loopback_unittest.cc | 171 | ||||
-rw-r--r-- | external_tests/ssl_gtest/test_io.cc | 4 |
4 files changed, 160 insertions, 27 deletions
diff --git a/external_tests/ssl_gtest/gtest_utils.h b/external_tests/ssl_gtest/gtest_utils.h index 191dd7acb..9ddd72484 100644 --- a/external_tests/ssl_gtest/gtest_utils.h +++ b/external_tests/ssl_gtest/gtest_utils.h @@ -7,6 +7,9 @@ #ifndef gtest_utils_h__ #define gtest_utils_h__ +#include "gtest/gtest.h" +#include "test_io.h" + namespace nss_test { // Gtest utilities @@ -16,6 +19,9 @@ class Timeout : public PollTarget { Poller::Instance()->SetTimer(timer_ms, this, &Timeout::ExpiredCallback, &handle_); } + ~Timeout() { + Cancel(); + } static void ExpiredCallback(PollTarget* target, Event event) { Timeout* timeout = static_cast<Timeout*>(target); diff --git a/external_tests/ssl_gtest/ssl_gtest.cc b/external_tests/ssl_gtest/ssl_gtest.cc index 3173890c1..ee1c40cfd 100644 --- a/external_tests/ssl_gtest/ssl_gtest.cc +++ b/external_tests/ssl_gtest/ssl_gtest.cc @@ -2,6 +2,8 @@ #include "nss.h" #include "ssl.h" +#include <cstdlib> + #include "test_io.h" #define GTEST_HAS_RTTI 0 @@ -14,6 +16,10 @@ int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); g_working_dir_path = "."; + char* workdir = getenv("NSS_GTEST_WORKDIR"); + if (workdir) + g_working_dir_path = workdir; + for (int i = 0; i < argc; i++) { if (!strcmp(argv[i], "-d")) { g_working_dir_path = argv[i + 1]; diff --git a/external_tests/ssl_gtest/ssl_loopback_unittest.cc b/external_tests/ssl_gtest/ssl_loopback_unittest.cc index 3e95e7d90..6c01887a7 100644 --- a/external_tests/ssl_gtest/ssl_loopback_unittest.cc +++ b/external_tests/ssl_gtest/ssl_loopback_unittest.cc @@ -20,6 +20,13 @@ extern std::string g_working_dir_path; namespace nss_test { +enum SessionResumptionMode { + RESUME_NONE = 0, + RESUME_SESSIONID = 1, + RESUME_TICKET = 2, + RESUME_BOTH = RESUME_SESSIONID | RESUME_TICKET +}; + #define LOG(a) std::cerr << name_ << ": " << a << std::endl; // Inspector that parses out DTLS records and passes @@ -306,22 +313,6 @@ class TlsAgent : public PollTarget { return true; } - void SetSessionTicketsEnabled(bool en) { - ASSERT_TRUE(EnsureTlsSetup()); - - SECStatus rv = SSL_OptionSet(ssl_fd_, SSL_ENABLE_SESSION_TICKETS, - en ? PR_TRUE : PR_FALSE); - ASSERT_EQ(SECSuccess, rv); - } - - void SetSessionCacheEnabled(bool en) { - ASSERT_TRUE(EnsureTlsSetup()); - - SECStatus rv = SSL_OptionSet(ssl_fd_, SSL_NO_CACHE, - en ? PR_FALSE : PR_TRUE); - ASSERT_EQ(SECSuccess, rv); - } - void SetVersionRange(uint16_t minver, uint16_t maxver) { SSLVersionRange range = {minver, maxver}; ASSERT_EQ(SECSuccess, SSL_VersionRangeSet(ssl_fd_, &range)); @@ -366,6 +357,7 @@ class TlsAgent : public PollTarget { ASSERT_EQ(version, info_.protocolVersion); } + void Handshake() { SECStatus rv = SSL_ForceHandshake(ssl_fd_); if (rv == SECSuccess) { @@ -404,6 +396,22 @@ class TlsAgent : public PollTarget { info_.sessionID + info_.sessionIDLength); } + void ConfigureSessionCache(SessionResumptionMode mode) { + ASSERT_TRUE(EnsureTlsSetup()); + + SECStatus rv = SSL_OptionSet(ssl_fd_, + SSL_NO_CACHE, + mode & RESUME_SESSIONID ? + PR_FALSE : PR_TRUE); + ASSERT_EQ(SECSuccess, rv); + + rv = SSL_OptionSet(ssl_fd_, + SSL_ENABLE_SESSION_TICKETS, + mode & RESUME_TICKET ? + PR_TRUE : PR_FALSE); + ASSERT_EQ(SECSuccess, rv); + } + private: const static char* states[]; @@ -460,6 +468,10 @@ class TlsConnectTestBase : public ::testing::Test { // Configure a fresh session cache. SSL_ConfigServerSessionIDCache(1024, 0, 0, g_working_dir_path.c_str()); + // Clear statistics. + SSL3Statistics* stats = SSL_GetStatistics(); + memset(stats, 0, sizeof(*stats)); + Init(); } @@ -467,6 +479,7 @@ class TlsConnectTestBase : public ::testing::Test { client_ = nullptr; server_ = nullptr; + SSL_ClearSessionCache(); SSL_ShutdownServerSessionIDCache(); } @@ -520,7 +533,7 @@ class TlsConnectTestBase : public ::testing::Test { std::vector<uint8_t> sid_s1 = server_->GetSessionId(); ASSERT_EQ(32, sid_s1.size()); ASSERT_EQ(sid_c1, sid_s1); - session_id_ = sid_c1; + session_ids_.push_back(sid_c1); } void EnableSomeECDHECiphers() { @@ -528,11 +541,38 @@ class TlsConnectTestBase : public ::testing::Test { server_->EnableSomeECDHECiphers(); } + void ConfigureSessionCache(SessionResumptionMode client, + SessionResumptionMode server) { + client_->ConfigureSessionCache(client); + server_->ConfigureSessionCache(server); + } + + void CheckResumption(SessionResumptionMode expected) { + ASSERT_NE(RESUME_BOTH, expected); + + int resume_ct = expected != 0; + int stateless_ct = (expected & RESUME_TICKET) ? 1 : 0; + + SSL3Statistics* stats = SSL_GetStatistics(); + ASSERT_EQ(resume_ct, stats->hch_sid_cache_hits); + ASSERT_EQ(resume_ct, stats->hsh_sid_cache_hits); + + ASSERT_EQ(stateless_ct, stats->hch_sid_stateless_resumes); + ASSERT_EQ(stateless_ct, stats->hsh_sid_stateless_resumes); + + if (resume_ct) { + // Check that the last two session ids match. + ASSERT_GE(2, session_ids_.size()); + ASSERT_EQ(session_ids_[session_ids_.size()-1], + session_ids_[session_ids_.size()-2]); + } + } + protected: Mode mode_; TlsAgent* client_; TlsAgent* server_; - std::vector<uint8_t> session_id_; + std::vector<std::vector<uint8_t>> session_ids_; }; class TlsConnectTest : public TlsConnectTestBase { @@ -568,23 +608,102 @@ TEST_P(TlsConnectGeneric, Connect) { } TEST_P(TlsConnectGeneric, ConnectResumed) { + ConfigureSessionCache(RESUME_SESSIONID, RESUME_SESSIONID); + Connect(); + + Reset(); + Connect(); + CheckResumption(RESUME_SESSIONID); +} + +TEST_P(TlsConnectGeneric, ConnectClientCacheDisabled) { + ConfigureSessionCache(RESUME_NONE, RESUME_SESSIONID); + Connect(); + Reset(); + Connect(); + CheckResumption(RESUME_NONE); +} + +TEST_P(TlsConnectGeneric, ConnectServerCacheDisabled) { + ConfigureSessionCache(RESUME_SESSIONID, RESUME_NONE); + Connect(); + Reset(); Connect(); - std::vector<uint8_t> old_sid = session_id_; + CheckResumption(RESUME_NONE); +} +TEST_P(TlsConnectGeneric, ConnectSessionCacheDisabled) { + ConfigureSessionCache(RESUME_NONE, RESUME_NONE); + Connect(); Reset(); Connect(); - ASSERT_EQ(old_sid, session_id_) << "Session was not resumed when it should have been"; + CheckResumption(RESUME_NONE); } -TEST_P(TlsConnectGeneric, ConnectNotResumed) { +TEST_P(TlsConnectGeneric, ConnectResumeSupportBoth) { + // This prefers tickets. + ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH); Connect(); - std::vector<uint8_t> old_sid = session_id_; Reset(); - client_->SetSessionCacheEnabled(false); + ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH); Connect(); + CheckResumption(RESUME_TICKET); +} - ASSERT_NE(old_sid, session_id_) << "Session was resumed when it should not have been"; +TEST_P(TlsConnectGeneric, ConnectResumeClientTicketServerBoth) { + // This causes no resumption because the client needs the + // session cache to resume even with tickets. + ConfigureSessionCache(RESUME_TICKET, RESUME_BOTH); + Connect(); + + Reset(); + ConfigureSessionCache(RESUME_TICKET, RESUME_BOTH); + Connect(); + CheckResumption(RESUME_NONE); +} + +TEST_P(TlsConnectGeneric, ConnectResumeClientBothTicketServerTicket) { + // This causes a ticket resumption. + ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); + Connect(); + + Reset(); + ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); + Connect(); + CheckResumption(RESUME_TICKET); +} + +TEST_P(TlsConnectGeneric, ConnectClientServerTicketOnly) { + // This causes no resumption because the client needs the + // session cache to resume even with tickets. + ConfigureSessionCache(RESUME_TICKET, RESUME_TICKET); + Connect(); + + Reset(); + ConfigureSessionCache(RESUME_TICKET, RESUME_TICKET); + Connect(); + CheckResumption(RESUME_NONE); +} + +TEST_P(TlsConnectGeneric, ConnectClientBothServerNone) { + ConfigureSessionCache(RESUME_BOTH, RESUME_NONE); + Connect(); + + Reset(); + ConfigureSessionCache(RESUME_BOTH, RESUME_NONE); + Connect(); + CheckResumption(RESUME_NONE); +} + +TEST_P(TlsConnectGeneric, ConnectClientNoneServerBoth) { + ConfigureSessionCache(RESUME_NONE, RESUME_BOTH); + Connect(); + + Reset(); + ConfigureSessionCache(RESUME_NONE, RESUME_BOTH); + Connect(); + CheckResumption(RESUME_NONE); } TEST_P(TlsConnectGeneric, ConnectTLS_1_1_Only) { @@ -632,7 +751,7 @@ TEST_F(TlsConnectTest, ConnectECDHETwiceReuseKey) { new TlsInspectorRecordHandshakeMessage(kTlsHandshakeServerKeyExchange); server_->SetInspector(i2); EnableSomeECDHECiphers(); - client_->SetSessionCacheEnabled(false); + ConfigureSessionCache(RESUME_NONE, RESUME_NONE); Connect(); client_->CheckKEAType(ssl_kea_ecdh); @@ -666,7 +785,7 @@ TEST_F(TlsConnectTest, ConnectECDHETwiceNewKey) { TlsInspectorRecordHandshakeMessage* i2 = new TlsInspectorRecordHandshakeMessage(kTlsHandshakeServerKeyExchange); server_->SetInspector(i2); - client_->SetSessionCacheEnabled(false); + ConfigureSessionCache(RESUME_NONE, RESUME_NONE); Connect(); client_->CheckKEAType(ssl_kea_ecdh); diff --git a/external_tests/ssl_gtest/test_io.cc b/external_tests/ssl_gtest/test_io.cc index cf3440fa9..701647831 100644 --- a/external_tests/ssl_gtest/test_io.cc +++ b/external_tests/ssl_gtest/test_io.cc @@ -438,7 +438,9 @@ bool Poller::Poll() { Timer *timer = timers_.top(); timers_.pop(); - timer->callback_(timer->target_, TIMER_EVENT); + if (timer->callback_) { + timer->callback_(timer->target_, TIMER_EVENT); + } delete timer; } |