xref: /aosp_15_r20/external/cronet/net/http/http_response_info_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2015 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/http/http_response_info.h"
6 
7 #include "base/pickle.h"
8 #include "net/cert/signed_certificate_timestamp.h"
9 #include "net/cert/signed_certificate_timestamp_and_status.h"
10 #include "net/http/http_response_headers.h"
11 #include "net/ssl/ssl_connection_status_flags.h"
12 #include "net/test/cert_test_util.h"
13 #include "net/test/ct_test_util.h"
14 #include "net/test/test_data_directory.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 
18 namespace net {
19 
20 namespace {
21 
22 class HttpResponseInfoTest : public testing::Test {
23  protected:
SetUp()24   void SetUp() override {
25     response_info_.headers = base::MakeRefCounted<HttpResponseHeaders>("");
26   }
27 
PickleAndRestore(const HttpResponseInfo & response_info,HttpResponseInfo * restored_response_info) const28   void PickleAndRestore(const HttpResponseInfo& response_info,
29                         HttpResponseInfo* restored_response_info) const {
30     base::Pickle pickle;
31     response_info.Persist(&pickle, false, false);
32     bool truncated = false;
33     EXPECT_TRUE(restored_response_info->InitFromPickle(pickle, &truncated));
34   }
35 
36   HttpResponseInfo response_info_;
37 };
38 
TEST_F(HttpResponseInfoTest,UnusedSincePrefetchDefault)39 TEST_F(HttpResponseInfoTest, UnusedSincePrefetchDefault) {
40   EXPECT_FALSE(response_info_.unused_since_prefetch);
41 }
42 
TEST_F(HttpResponseInfoTest,UnusedSincePrefetchCopy)43 TEST_F(HttpResponseInfoTest, UnusedSincePrefetchCopy) {
44   response_info_.unused_since_prefetch = true;
45   HttpResponseInfo response_info_clone(response_info_);
46   EXPECT_TRUE(response_info_clone.unused_since_prefetch);
47 }
48 
TEST_F(HttpResponseInfoTest,UnusedSincePrefetchPersistFalse)49 TEST_F(HttpResponseInfoTest, UnusedSincePrefetchPersistFalse) {
50   HttpResponseInfo restored_response_info;
51   PickleAndRestore(response_info_, &restored_response_info);
52   EXPECT_FALSE(restored_response_info.unused_since_prefetch);
53 }
54 
TEST_F(HttpResponseInfoTest,UnusedSincePrefetchPersistTrue)55 TEST_F(HttpResponseInfoTest, UnusedSincePrefetchPersistTrue) {
56   response_info_.unused_since_prefetch = true;
57   HttpResponseInfo restored_response_info;
58   PickleAndRestore(response_info_, &restored_response_info);
59   EXPECT_TRUE(restored_response_info.unused_since_prefetch);
60 }
61 
TEST_F(HttpResponseInfoTest,PKPBypassPersistTrue)62 TEST_F(HttpResponseInfoTest, PKPBypassPersistTrue) {
63   response_info_.ssl_info.pkp_bypassed = true;
64   HttpResponseInfo restored_response_info;
65   PickleAndRestore(response_info_, &restored_response_info);
66   EXPECT_TRUE(restored_response_info.ssl_info.pkp_bypassed);
67 }
68 
TEST_F(HttpResponseInfoTest,PKPBypassPersistFalse)69 TEST_F(HttpResponseInfoTest, PKPBypassPersistFalse) {
70   response_info_.ssl_info.pkp_bypassed = false;
71   HttpResponseInfo restored_response_info;
72   PickleAndRestore(response_info_, &restored_response_info);
73   EXPECT_FALSE(restored_response_info.ssl_info.pkp_bypassed);
74 }
75 
TEST_F(HttpResponseInfoTest,AsyncRevalidationRequestedDefault)76 TEST_F(HttpResponseInfoTest, AsyncRevalidationRequestedDefault) {
77   EXPECT_FALSE(response_info_.async_revalidation_requested);
78 }
79 
TEST_F(HttpResponseInfoTest,AsyncRevalidationRequestedCopy)80 TEST_F(HttpResponseInfoTest, AsyncRevalidationRequestedCopy) {
81   response_info_.async_revalidation_requested = true;
82   net::HttpResponseInfo response_info_clone(response_info_);
83   EXPECT_TRUE(response_info_clone.async_revalidation_requested);
84 }
85 
TEST_F(HttpResponseInfoTest,AsyncRevalidationRequestedAssign)86 TEST_F(HttpResponseInfoTest, AsyncRevalidationRequestedAssign) {
87   response_info_.async_revalidation_requested = true;
88   net::HttpResponseInfo response_info_clone;
89   response_info_clone = response_info_;
90   EXPECT_TRUE(response_info_clone.async_revalidation_requested);
91 }
92 
TEST_F(HttpResponseInfoTest,AsyncRevalidationRequestedNotPersisted)93 TEST_F(HttpResponseInfoTest, AsyncRevalidationRequestedNotPersisted) {
94   response_info_.async_revalidation_requested = true;
95   net::HttpResponseInfo restored_response_info;
96   PickleAndRestore(response_info_, &restored_response_info);
97   EXPECT_FALSE(restored_response_info.async_revalidation_requested);
98 }
99 
TEST_F(HttpResponseInfoTest,StaleRevalidationTimeoutDefault)100 TEST_F(HttpResponseInfoTest, StaleRevalidationTimeoutDefault) {
101   EXPECT_TRUE(response_info_.stale_revalidate_timeout.is_null());
102 }
103 
TEST_F(HttpResponseInfoTest,StaleRevalidationTimeoutCopy)104 TEST_F(HttpResponseInfoTest, StaleRevalidationTimeoutCopy) {
105   base::Time test_time = base::Time::FromSecondsSinceUnixEpoch(1000);
106   response_info_.stale_revalidate_timeout = test_time;
107   HttpResponseInfo response_info_clone(response_info_);
108   EXPECT_EQ(test_time, response_info_clone.stale_revalidate_timeout);
109 }
110 
TEST_F(HttpResponseInfoTest,StaleRevalidationTimeoutRestoreValue)111 TEST_F(HttpResponseInfoTest, StaleRevalidationTimeoutRestoreValue) {
112   base::Time test_time = base::Time::FromSecondsSinceUnixEpoch(1000);
113   response_info_.stale_revalidate_timeout = test_time;
114   HttpResponseInfo restored_response_info;
115   PickleAndRestore(response_info_, &restored_response_info);
116   EXPECT_EQ(test_time, restored_response_info.stale_revalidate_timeout);
117 }
118 
TEST_F(HttpResponseInfoTest,StaleRevalidationTimeoutRestoreNoValue)119 TEST_F(HttpResponseInfoTest, StaleRevalidationTimeoutRestoreNoValue) {
120   EXPECT_TRUE(response_info_.stale_revalidate_timeout.is_null());
121   HttpResponseInfo restored_response_info;
122   PickleAndRestore(response_info_, &restored_response_info);
123   EXPECT_TRUE(restored_response_info.stale_revalidate_timeout.is_null());
124 }
125 
126 // Test that key_exchange_group is preserved for ECDHE ciphers.
TEST_F(HttpResponseInfoTest,KeyExchangeGroupECDHE)127 TEST_F(HttpResponseInfoTest, KeyExchangeGroupECDHE) {
128   response_info_.ssl_info.cert =
129       ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
130   SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1_2,
131                                 &response_info_.ssl_info.connection_status);
132   SSLConnectionStatusSetCipherSuite(
133       0xcca8 /* TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 */,
134       &response_info_.ssl_info.connection_status);
135   response_info_.ssl_info.key_exchange_group = 23;  // X25519
136   net::HttpResponseInfo restored_response_info;
137   PickleAndRestore(response_info_, &restored_response_info);
138   EXPECT_EQ(23, restored_response_info.ssl_info.key_exchange_group);
139 }
140 
141 // Test that key_exchange_group is preserved for TLS 1.3.
TEST_F(HttpResponseInfoTest,KeyExchangeGroupTLS13)142 TEST_F(HttpResponseInfoTest, KeyExchangeGroupTLS13) {
143   response_info_.ssl_info.cert =
144       ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
145   SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1_3,
146                                 &response_info_.ssl_info.connection_status);
147   SSLConnectionStatusSetCipherSuite(0x1303 /* TLS_CHACHA20_POLY1305_SHA256 */,
148                                     &response_info_.ssl_info.connection_status);
149   response_info_.ssl_info.key_exchange_group = 23;  // X25519
150   net::HttpResponseInfo restored_response_info;
151   PickleAndRestore(response_info_, &restored_response_info);
152   EXPECT_EQ(23, restored_response_info.ssl_info.key_exchange_group);
153 }
154 
155 // Test that key_exchange_group is discarded for non-ECDHE ciphers prior to TLS
156 // 1.3, to account for the historical key_exchange_info field. See
157 // https://crbug.com/639421.
TEST_F(HttpResponseInfoTest,LegacyKeyExchangeInfoDHE)158 TEST_F(HttpResponseInfoTest, LegacyKeyExchangeInfoDHE) {
159   response_info_.ssl_info.cert =
160       ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
161   SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1_2,
162                                 &response_info_.ssl_info.connection_status);
163   SSLConnectionStatusSetCipherSuite(
164       0x0093 /* TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 */,
165       &response_info_.ssl_info.connection_status);
166   response_info_.ssl_info.key_exchange_group = 1024;
167   net::HttpResponseInfo restored_response_info;
168   PickleAndRestore(response_info_, &restored_response_info);
169   EXPECT_EQ(0, restored_response_info.ssl_info.key_exchange_group);
170 }
171 
172 // Test that key_exchange_group is discarded for unknown ciphers prior to TLS
173 // 1.3, to account for the historical key_exchange_info field. See
174 // https://crbug.com/639421.
TEST_F(HttpResponseInfoTest,LegacyKeyExchangeInfoUnknown)175 TEST_F(HttpResponseInfoTest, LegacyKeyExchangeInfoUnknown) {
176   response_info_.ssl_info.cert =
177       ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
178   SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1_2,
179                                 &response_info_.ssl_info.connection_status);
180   SSLConnectionStatusSetCipherSuite(0xffff,
181                                     &response_info_.ssl_info.connection_status);
182   response_info_.ssl_info.key_exchange_group = 1024;
183   net::HttpResponseInfo restored_response_info;
184   PickleAndRestore(response_info_, &restored_response_info);
185   EXPECT_EQ(0, restored_response_info.ssl_info.key_exchange_group);
186 }
187 
188 // Test that peer_signature_algorithm is preserved.
TEST_F(HttpResponseInfoTest,PeerSignatureAlgorithm)189 TEST_F(HttpResponseInfoTest, PeerSignatureAlgorithm) {
190   response_info_.ssl_info.cert =
191       ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
192   response_info_.ssl_info.peer_signature_algorithm =
193       0x0804;  // rsa_pss_rsae_sha256
194   net::HttpResponseInfo restored_response_info;
195   PickleAndRestore(response_info_, &restored_response_info);
196   EXPECT_EQ(0x0804, restored_response_info.ssl_info.peer_signature_algorithm);
197 }
198 
199 // Test that encrypted_client_hello is preserved.
TEST_F(HttpResponseInfoTest,EncryptedClientHello)200 TEST_F(HttpResponseInfoTest, EncryptedClientHello) {
201   response_info_.ssl_info.cert =
202       ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
203   {
204     net::HttpResponseInfo restored_response_info;
205     PickleAndRestore(response_info_, &restored_response_info);
206     EXPECT_FALSE(restored_response_info.ssl_info.encrypted_client_hello);
207   }
208 
209   response_info_.ssl_info.encrypted_client_hello = true;
210   {
211     net::HttpResponseInfo restored_response_info;
212     PickleAndRestore(response_info_, &restored_response_info);
213     EXPECT_TRUE(restored_response_info.ssl_info.encrypted_client_hello);
214   }
215 }
216 
217 // Tests that cache entries loaded over SSLv3 (no longer supported) are dropped.
TEST_F(HttpResponseInfoTest,FailsInitFromPickleWithSSLV3)218 TEST_F(HttpResponseInfoTest, FailsInitFromPickleWithSSLV3) {
219   // A valid certificate is needed for ssl_info.is_valid() to be true.
220   response_info_.ssl_info.cert =
221       ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
222 
223   // Non-SSLv3 versions should succeed.
224   SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1_2,
225                                 &response_info_.ssl_info.connection_status);
226   base::Pickle tls12_pickle;
227   response_info_.Persist(&tls12_pickle, false, false);
228   bool truncated = false;
229   net::HttpResponseInfo restored_tls12_response_info;
230   EXPECT_TRUE(
231       restored_tls12_response_info.InitFromPickle(tls12_pickle, &truncated));
232   EXPECT_EQ(SSL_CONNECTION_VERSION_TLS1_2,
233             SSLConnectionStatusToVersion(
234                 restored_tls12_response_info.ssl_info.connection_status));
235   EXPECT_FALSE(truncated);
236 
237   // SSLv3 should fail.
238   SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_SSL3,
239                                 &response_info_.ssl_info.connection_status);
240   base::Pickle ssl3_pickle;
241   response_info_.Persist(&ssl3_pickle, false, false);
242   net::HttpResponseInfo restored_ssl3_response_info;
243   EXPECT_FALSE(
244       restored_ssl3_response_info.InitFromPickle(ssl3_pickle, &truncated));
245 }
246 
247 // Test that `dns_aliases` is preserved.
TEST_F(HttpResponseInfoTest,DnsAliases)248 TEST_F(HttpResponseInfoTest, DnsAliases) {
249   response_info_.dns_aliases = {"alias1", "alias2", "alias3"};
250   net::HttpResponseInfo restored_response_info;
251   PickleAndRestore(response_info_, &restored_response_info);
252   EXPECT_THAT(restored_response_info.dns_aliases,
253               testing::ElementsAre("alias1", "alias2", "alias3"));
254 }
255 
256 // Test that an empty `dns_aliases` is preserved and doesn't throw an error.
TEST_F(HttpResponseInfoTest,EmptyDnsAliases)257 TEST_F(HttpResponseInfoTest, EmptyDnsAliases) {
258   response_info_.dns_aliases = {};
259   net::HttpResponseInfo restored_response_info;
260   PickleAndRestore(response_info_, &restored_response_info);
261   EXPECT_TRUE(restored_response_info.dns_aliases.empty());
262 }
263 
264 // Test that `browser_run_id` is preserved.
TEST_F(HttpResponseInfoTest,BrowserRunId)265 TEST_F(HttpResponseInfoTest, BrowserRunId) {
266   response_info_.browser_run_id = 1;
267   net::HttpResponseInfo restored_response_info;
268   PickleAndRestore(response_info_, &restored_response_info);
269   EXPECT_EQ(1, restored_response_info.browser_run_id);
270 }
271 
272 // Test that an empty `browser_run_id` is preserved and doesn't throw an error.
TEST_F(HttpResponseInfoTest,EmptyBrowserRunId)273 TEST_F(HttpResponseInfoTest, EmptyBrowserRunId) {
274   response_info_.browser_run_id = std::nullopt;
275   net::HttpResponseInfo restored_response_info;
276   PickleAndRestore(response_info_, &restored_response_info);
277   EXPECT_FALSE(restored_response_info.browser_run_id.has_value());
278 }
279 
280 // Test that did_use_shared_dictionary is preserved .
TEST_F(HttpResponseInfoTest,DidUseSharedDictionary)281 TEST_F(HttpResponseInfoTest, DidUseSharedDictionary) {
282   response_info_.did_use_shared_dictionary = true;
283   net::HttpResponseInfo restored_response_info;
284   PickleAndRestore(response_info_, &restored_response_info);
285   EXPECT_TRUE(restored_response_info.did_use_shared_dictionary);
286 }
287 
288 }  // namespace
289 
290 }  // namespace net
291