TestSSLTokensCache.cpp (5998B)
1 #include <numeric> 2 3 #include "CertVerifier.h" 4 #include "CommonSocketControl.h" 5 #include "SSLTokensCache.h" 6 #include "TransportSecurityInfo.h" 7 #include "gtest/gtest.h" 8 #include "mozilla/Preferences.h" 9 #include "nsITransportSecurityInfo.h" 10 #include "nsIWebProgressListener.h" 11 #include "nsIX509Cert.h" 12 #include "nsIX509CertDB.h" 13 #include "nsServiceManagerUtils.h" 14 #include "sslproto.h" 15 16 static already_AddRefed<CommonSocketControl> createDummySocketControl() { 17 nsCOMPtr<nsIX509CertDB> certDB(do_GetService(NS_X509CERTDB_CONTRACTID)); 18 EXPECT_TRUE(certDB); 19 nsLiteralCString base64( 20 "MIIBbjCCARWgAwIBAgIUOyCxVVqw03yUxKSfSojsMF8K/" 21 "ikwCgYIKoZIzj0EAwIwHTEbMBkGA1UEAwwScm9vdF9zZWNwMjU2azFfMjU2MCIYDzIwMjAxM" 22 "TI3MDAwMDAwWhgPMjAyMzAyMDUwMDAwMDBaMC8xLTArBgNVBAMMJGludF9zZWNwMjU2cjFfM" 23 "jU2LXJvb3Rfc2VjcDI1NmsxXzI1NjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABE+/" 24 "u7th4Pj5saYKWayHBOLsBQtCPjz3LpI/" 25 "LE95S0VcKmnSM0VsNsQRnQcG4A7tyNGTkNeZG3stB6ME6qBKpsCjHTAbMAwGA1UdEwQFMAMB" 26 "Af8wCwYDVR0PBAQDAgEGMAoGCCqGSM49BAMCA0cAMEQCIFuwodUwyOUnIR4KN5ZCSrU7y4iz" 27 "4/1EWRdHm5kWKi8dAiB6Ixn9sw3uBVbyxnQKYqGnOwM+qLOkJK0W8XkIE3n5sg=="); 28 nsCOMPtr<nsIX509Cert> cert; 29 EXPECT_TRUE(NS_SUCCEEDED( 30 certDB->ConstructX509FromBase64(base64, getter_AddRefs(cert)))); 31 EXPECT_TRUE(cert); 32 nsTArray<nsTArray<uint8_t>> succeededCertChain; 33 for (size_t i = 0; i < 3; i++) { 34 nsTArray<uint8_t> certDER; 35 EXPECT_TRUE(NS_SUCCEEDED(cert->GetRawDER(certDER))); 36 succeededCertChain.AppendElement(std::move(certDER)); 37 } 38 RefPtr<CommonSocketControl> socketControl( 39 new CommonSocketControl(nsLiteralCString("example.com"), 433, 0)); 40 socketControl->SetServerCert(cert, mozilla::psm::EVStatus::NotEV); 41 socketControl->SetSucceededCertChain(std::move(succeededCertChain)); 42 return socketControl.forget(); 43 } 44 45 static auto MakeTestData(const size_t aDataSize) { 46 auto data = nsTArray<uint8_t>(); 47 data.SetLength(aDataSize); 48 std::iota(data.begin(), data.end(), 0); 49 return data; 50 } 51 52 static void putToken(const nsACString& aKey, uint32_t aSize) { 53 RefPtr<CommonSocketControl> socketControl = createDummySocketControl(); 54 nsTArray<uint8_t> token = MakeTestData(aSize); 55 nsresult rv = mozilla::net::SSLTokensCache::Put(aKey, token.Elements(), aSize, 56 socketControl, aSize); 57 ASSERT_EQ(rv, NS_OK); 58 } 59 60 static void getAndCheckResult(const nsACString& aKey, uint32_t aExpectedSize) { 61 nsTArray<uint8_t> result; 62 mozilla::net::SessionCacheInfo unused; 63 nsresult rv = mozilla::net::SSLTokensCache::Get(aKey, result, unused); 64 ASSERT_EQ(rv, NS_OK); 65 ASSERT_EQ(result.Length(), (size_t)aExpectedSize); 66 } 67 68 TEST(TestTokensCache, SinglePut) 69 { 70 mozilla::net::SSLTokensCache::Clear(); 71 mozilla::Preferences::SetInt("network.ssl_tokens_cache_records_per_entry", 1); 72 mozilla::Preferences::SetBool("network.ssl_tokens_cache_use_only_once", true); 73 74 putToken("anon:www.example.com:443"_ns, 100); 75 nsTArray<uint8_t> result; 76 mozilla::net::SessionCacheInfo unused; 77 nsresult rv = mozilla::net::SSLTokensCache::Get("anon:www.example.com:443"_ns, 78 result, unused); 79 ASSERT_EQ(rv, NS_OK); 80 rv = mozilla::net::SSLTokensCache::Get("anon:www.example.com:443"_ns, result, 81 unused); 82 ASSERT_EQ(rv, NS_ERROR_NOT_AVAILABLE); 83 } 84 85 TEST(TestTokensCache, MultiplePut) 86 { 87 mozilla::net::SSLTokensCache::Clear(); 88 mozilla::Preferences::SetInt("network.ssl_tokens_cache_records_per_entry", 3); 89 90 putToken("anon:www.example1.com:443"_ns, 300); 91 // This record will be removed because 92 // "network.ssl_tokens_cache_records_per_entry" is 3. 93 putToken("anon:www.example1.com:443"_ns, 100); 94 putToken("anon:www.example1.com:443"_ns, 200); 95 putToken("anon:www.example1.com:443"_ns, 400); 96 97 // Test if records are ordered by the expiration time 98 getAndCheckResult("anon:www.example1.com:443"_ns, 200); 99 getAndCheckResult("anon:www.example1.com:443"_ns, 300); 100 getAndCheckResult("anon:www.example1.com:443"_ns, 400); 101 } 102 103 TEST(TestTokensCache, RemoveAll) 104 { 105 mozilla::net::SSLTokensCache::Clear(); 106 mozilla::Preferences::SetInt("network.ssl_tokens_cache_records_per_entry", 3); 107 108 putToken("anon:www.example1.com:443"_ns, 100); 109 putToken("anon:www.example1.com:443"_ns, 200); 110 putToken("anon:www.example1.com:443"_ns, 300); 111 112 putToken("anon:www.example2.com:443"_ns, 100); 113 putToken("anon:www.example2.com:443"_ns, 200); 114 putToken("anon:www.example2.com:443"_ns, 300); 115 116 nsTArray<uint8_t> result; 117 mozilla::net::SessionCacheInfo unused; 118 nsresult rv = mozilla::net::SSLTokensCache::Get( 119 "anon:www.example1.com:443"_ns, result, unused); 120 ASSERT_EQ(rv, NS_OK); 121 ASSERT_EQ(result.Length(), (size_t)100); 122 123 rv = mozilla::net::SSLTokensCache::RemoveAll("anon:www.example1.com:443"_ns); 124 ASSERT_EQ(rv, NS_OK); 125 126 rv = mozilla::net::SSLTokensCache::Get("anon:www.example1.com:443"_ns, result, 127 unused); 128 ASSERT_EQ(rv, NS_ERROR_NOT_AVAILABLE); 129 130 rv = mozilla::net::SSLTokensCache::Get("anon:www.example2.com:443"_ns, result, 131 unused); 132 ASSERT_EQ(rv, NS_OK); 133 ASSERT_EQ(result.Length(), (size_t)100); 134 } 135 136 TEST(TestTokensCache, Eviction) 137 { 138 mozilla::net::SSLTokensCache::Clear(); 139 140 mozilla::Preferences::SetInt("network.ssl_tokens_cache_records_per_entry", 3); 141 mozilla::Preferences::SetInt("network.ssl_tokens_cache_capacity", 8); 142 143 putToken("anon:www.example2.com:443"_ns, 300); 144 putToken("anon:www.example2.com:443"_ns, 400); 145 putToken("anon:www.example2.com:443"_ns, 500); 146 // The one has expiration time "300" will be removed because we only allow 3 147 // records per entry. 148 putToken("anon:www.example2.com:443"_ns, 600); 149 150 putToken("anon:www.example3.com:443"_ns, 600); 151 putToken("anon:www.example3.com:443"_ns, 500); 152 // The one has expiration time "400" was evicted, so we get "500". 153 getAndCheckResult("anon:www.example2.com:443"_ns, 500); 154 }