| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/loader/resource_loader.h" | 5 #include "content/browser/loader/resource_loader.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <deque> | 10 #include <deque> |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 #include "content/test/test_web_contents.h" | 35 #include "content/test/test_web_contents.h" |
| 36 #include "ipc/ipc_message.h" | 36 #include "ipc/ipc_message.h" |
| 37 #include "net/base/chunked_upload_data_stream.h" | 37 #include "net/base/chunked_upload_data_stream.h" |
| 38 #include "net/base/io_buffer.h" | 38 #include "net/base/io_buffer.h" |
| 39 #include "net/base/net_errors.h" | 39 #include "net/base/net_errors.h" |
| 40 #include "net/base/request_priority.h" | 40 #include "net/base/request_priority.h" |
| 41 #include "net/base/upload_bytes_element_reader.h" | 41 #include "net/base/upload_bytes_element_reader.h" |
| 42 #include "net/cert/x509_certificate.h" | 42 #include "net/cert/x509_certificate.h" |
| 43 #include "net/nqe/effective_connection_type.h" | 43 #include "net/nqe/effective_connection_type.h" |
| 44 #include "net/nqe/network_quality_estimator_test_util.h" | 44 #include "net/nqe/network_quality_estimator_test_util.h" |
| 45 #include "net/ssl/client_cert_identity_test_util.h" |
| 45 #include "net/ssl/client_cert_store.h" | 46 #include "net/ssl/client_cert_store.h" |
| 46 #include "net/ssl/ssl_cert_request_info.h" | 47 #include "net/ssl/ssl_cert_request_info.h" |
| 47 #include "net/ssl/ssl_private_key.h" | 48 #include "net/ssl/ssl_private_key.h" |
| 48 #include "net/test/cert_test_util.h" | 49 #include "net/test/cert_test_util.h" |
| 49 #include "net/test/embedded_test_server/embedded_test_server.h" | 50 #include "net/test/embedded_test_server/embedded_test_server.h" |
| 50 #include "net/test/test_data_directory.h" | 51 #include "net/test/test_data_directory.h" |
| 51 #include "net/test/url_request/url_request_failed_job.h" | 52 #include "net/test/url_request/url_request_failed_job.h" |
| 52 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" | 53 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" |
| 53 #include "net/url_request/url_request.h" | 54 #include "net/url_request/url_request.h" |
| 54 #include "net/url_request/url_request_filter.h" | 55 #include "net/url_request/url_request_filter.h" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 72 // in |requested_authorities| and |request_count|, respectively. The caller is | 73 // in |requested_authorities| and |request_count|, respectively. The caller is |
| 73 // responsible for ensuring those pointers outlive the ClientCertStoreStub. | 74 // responsible for ensuring those pointers outlive the ClientCertStoreStub. |
| 74 // | 75 // |
| 75 // TODO(ppi): Make the stub independent from the internal representation of | 76 // TODO(ppi): Make the stub independent from the internal representation of |
| 76 // SSLCertRequestInfo. For now it seems that we can neither save the | 77 // SSLCertRequestInfo. For now it seems that we can neither save the |
| 77 // scoped_refptr<> (since it is never passed to us) nor copy the entire | 78 // scoped_refptr<> (since it is never passed to us) nor copy the entire |
| 78 // CertificateRequestInfo (since there is no copy constructor). | 79 // CertificateRequestInfo (since there is no copy constructor). |
| 79 ClientCertStoreStub(const net::CertificateList& response, | 80 ClientCertStoreStub(const net::CertificateList& response, |
| 80 int* request_count, | 81 int* request_count, |
| 81 std::vector<std::string>* requested_authorities) | 82 std::vector<std::string>* requested_authorities) |
| 82 : response_(response), | 83 : response_(std::move(response)), |
| 83 requested_authorities_(requested_authorities), | 84 requested_authorities_(requested_authorities), |
| 84 request_count_(request_count) { | 85 request_count_(request_count) { |
| 85 requested_authorities_->clear(); | 86 requested_authorities_->clear(); |
| 86 *request_count_ = 0; | 87 *request_count_ = 0; |
| 87 } | 88 } |
| 88 | 89 |
| 89 ~ClientCertStoreStub() override {} | 90 ~ClientCertStoreStub() override {} |
| 90 | 91 |
| 91 // net::ClientCertStore: | 92 // net::ClientCertStore: |
| 92 void GetClientCerts(const net::SSLCertRequestInfo& cert_request_info, | 93 void GetClientCerts(const net::SSLCertRequestInfo& cert_request_info, |
| 93 const ClientCertListCallback& callback) override { | 94 const ClientCertListCallback& callback) override { |
| 94 *requested_authorities_ = cert_request_info.cert_authorities; | 95 *requested_authorities_ = cert_request_info.cert_authorities; |
| 95 ++(*request_count_); | 96 ++(*request_count_); |
| 96 | 97 |
| 97 callback.Run(response_); | 98 callback.Run(net::FakeClientCertIdentityListFromCertificateList(response_)); |
| 98 } | 99 } |
| 99 | 100 |
| 100 private: | 101 private: |
| 101 const net::CertificateList response_; | 102 const net::CertificateList response_; |
| 102 std::vector<std::string>* requested_authorities_; | 103 std::vector<std::string>* requested_authorities_; |
| 103 int* request_count_; | 104 int* request_count_; |
| 104 }; | 105 }; |
| 105 | 106 |
| 106 // Client certificate store which destroys its resource loader before the | 107 // Client certificate store which destroys its resource loader before the |
| 107 // asynchronous GetClientCerts callback is called. | 108 // asynchronous GetClientCerts callback is called. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 127 } | 128 } |
| 128 | 129 |
| 129 private: | 130 private: |
| 130 // This needs to be static because |loader| owns the | 131 // This needs to be static because |loader| owns the |
| 131 // LoaderDestroyingCertStore (ClientCertStores are actually handles, and not | 132 // LoaderDestroyingCertStore (ClientCertStores are actually handles, and not |
| 132 // global cert stores). | 133 // global cert stores). |
| 133 static void DoCallback(std::unique_ptr<ResourceLoader>* loader, | 134 static void DoCallback(std::unique_ptr<ResourceLoader>* loader, |
| 134 const ClientCertListCallback& cert_selected_callback, | 135 const ClientCertListCallback& cert_selected_callback, |
| 135 const base::Closure& on_loader_deleted_callback) { | 136 const base::Closure& on_loader_deleted_callback) { |
| 136 loader->reset(); | 137 loader->reset(); |
| 137 cert_selected_callback.Run(net::CertificateList()); | 138 cert_selected_callback.Run(net::ClientCertIdentityList()); |
| 138 on_loader_deleted_callback.Run(); | 139 on_loader_deleted_callback.Run(); |
| 139 } | 140 } |
| 140 | 141 |
| 141 std::unique_ptr<ResourceLoader>* loader_; | 142 std::unique_ptr<ResourceLoader>* loader_; |
| 142 base::Closure on_loader_deleted_callback_; | 143 base::Closure on_loader_deleted_callback_; |
| 143 | 144 |
| 144 DISALLOW_COPY_AND_ASSIGN(LoaderDestroyingCertStore); | 145 DISALLOW_COPY_AND_ASSIGN(LoaderDestroyingCertStore); |
| 145 }; | 146 }; |
| 146 | 147 |
| 147 // A mock URLRequestJob which simulates an SSL client auth request. | 148 // A mock URLRequestJob which simulates an SSL client auth request. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 161 scoped_refptr<net::SSLCertRequestInfo> cert_request_info( | 162 scoped_refptr<net::SSLCertRequestInfo> cert_request_info( |
| 162 new net::SSLCertRequestInfo); | 163 new net::SSLCertRequestInfo); |
| 163 cert_request_info->cert_authorities = test_authorities(); | 164 cert_request_info->cert_authorities = test_authorities(); |
| 164 base::ThreadTaskRunnerHandle::Get()->PostTask( | 165 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 165 FROM_HERE, | 166 FROM_HERE, |
| 166 base::Bind(&MockClientCertURLRequestJob::NotifyCertificateRequested, | 167 base::Bind(&MockClientCertURLRequestJob::NotifyCertificateRequested, |
| 167 weak_factory_.GetWeakPtr(), | 168 weak_factory_.GetWeakPtr(), |
| 168 base::RetainedRef(cert_request_info))); | 169 base::RetainedRef(cert_request_info))); |
| 169 } | 170 } |
| 170 | 171 |
| 171 void ContinueWithCertificate(net::X509Certificate* cert, | 172 void ContinueWithCertificate( |
| 172 net::SSLPrivateKey* private_key) override { | 173 scoped_refptr<net::X509Certificate> cert, |
| 174 scoped_refptr<net::SSLPrivateKey> private_key) override { |
| 173 net::URLRequestTestJob::Start(); | 175 net::URLRequestTestJob::Start(); |
| 174 } | 176 } |
| 175 | 177 |
| 176 private: | 178 private: |
| 177 ~MockClientCertURLRequestJob() override {} | 179 ~MockClientCertURLRequestJob() override {} |
| 178 | 180 |
| 179 base::WeakPtrFactory<MockClientCertURLRequestJob> weak_factory_; | 181 base::WeakPtrFactory<MockClientCertURLRequestJob> weak_factory_; |
| 180 | 182 |
| 181 DISALLOW_COPY_AND_ASSIGN(MockClientCertURLRequestJob); | 183 DISALLOW_COPY_AND_ASSIGN(MockClientCertURLRequestJob); |
| 182 }; | 184 }; |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 266 void WaitForSelectCertificate() { | 268 void WaitForSelectCertificate() { |
| 267 select_certificate_run_loop_.Run(); | 269 select_certificate_run_loop_.Run(); |
| 268 // Process any pending messages - just so tests can check if | 270 // Process any pending messages - just so tests can check if |
| 269 // SelectClientCertificate was called more than once. | 271 // SelectClientCertificate was called more than once. |
| 270 base::RunLoop().RunUntilIdle(); | 272 base::RunLoop().RunUntilIdle(); |
| 271 } | 273 } |
| 272 | 274 |
| 273 void SelectClientCertificate( | 275 void SelectClientCertificate( |
| 274 WebContents* web_contents, | 276 WebContents* web_contents, |
| 275 net::SSLCertRequestInfo* cert_request_info, | 277 net::SSLCertRequestInfo* cert_request_info, |
| 276 net::CertificateList client_certs, | 278 net::ClientCertIdentityList client_certs, |
| 277 std::unique_ptr<ClientCertificateDelegate> delegate) override { | 279 std::unique_ptr<ClientCertificateDelegate> delegate) override { |
| 278 EXPECT_FALSE(delegate_.get()); | 280 EXPECT_FALSE(delegate_.get()); |
| 279 | 281 |
| 280 ++call_count_; | 282 ++call_count_; |
| 281 passed_certs_ = std::move(client_certs); | 283 passed_identities_ = std::move(client_certs); |
| 282 delegate_ = std::move(delegate); | 284 delegate_ = std::move(delegate); |
| 283 select_certificate_run_loop_.Quit(); | 285 select_certificate_run_loop_.Quit(); |
| 284 } | 286 } |
| 285 | 287 |
| 286 int call_count() { return call_count_; } | 288 int call_count() { return call_count_; } |
| 287 net::CertificateList passed_certs() { return passed_certs_; } | 289 const net::ClientCertIdentityList& passed_identities() { |
| 290 return passed_identities_; |
| 291 } |
| 288 | 292 |
| 289 void ContinueWithCertificate(net::X509Certificate* cert) { | 293 void ContinueWithCertificate(scoped_refptr<net::X509Certificate> cert, |
| 290 delegate_->ContinueWithCertificate(cert); | 294 scoped_refptr<net::SSLPrivateKey> private_key) { |
| 295 delegate_->ContinueWithCertificate(std::move(cert), std::move(private_key)); |
| 291 delegate_.reset(); | 296 delegate_.reset(); |
| 292 } | 297 } |
| 293 | 298 |
| 294 void CancelCertificateSelection() { delegate_.reset(); } | 299 void CancelCertificateSelection() { delegate_.reset(); } |
| 295 | 300 |
| 296 private: | 301 private: |
| 297 net::CertificateList passed_certs_; | 302 net::ClientCertIdentityList passed_identities_; |
| 298 int call_count_; | 303 int call_count_; |
| 299 std::unique_ptr<ClientCertificateDelegate> delegate_; | 304 std::unique_ptr<ClientCertificateDelegate> delegate_; |
| 300 | 305 |
| 301 base::RunLoop select_certificate_run_loop_; | 306 base::RunLoop select_certificate_run_loop_; |
| 302 | 307 |
| 303 DISALLOW_COPY_AND_ASSIGN(SelectCertificateBrowserClient); | 308 DISALLOW_COPY_AND_ASSIGN(SelectCertificateBrowserClient); |
| 304 }; | 309 }; |
| 305 | 310 |
| 306 // Wraps a ChunkedUploadDataStream to behave as non-chunked to enable upload | 311 // Wraps a ChunkedUploadDataStream to behave as non-chunked to enable upload |
| 307 // progress reporting. | 312 // progress reporting. |
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 588 private: | 593 private: |
| 589 const GURL test_https_url_; | 594 const GURL test_https_url_; |
| 590 const GURL test_https_redirect_url_; | 595 const GURL test_https_redirect_url_; |
| 591 }; | 596 }; |
| 592 | 597 |
| 593 // Tests that client certificates are requested with ClientCertStore lookup. | 598 // Tests that client certificates are requested with ClientCertStore lookup. |
| 594 TEST_F(ClientCertResourceLoaderTest, WithStoreLookup) { | 599 TEST_F(ClientCertResourceLoaderTest, WithStoreLookup) { |
| 595 // Set up the test client cert store. | 600 // Set up the test client cert store. |
| 596 int store_request_count; | 601 int store_request_count; |
| 597 std::vector<std::string> store_requested_authorities; | 602 std::vector<std::string> store_requested_authorities; |
| 598 net::CertificateList dummy_certs( | 603 scoped_refptr<net::X509Certificate> test_cert = |
| 599 1, net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem")); | 604 net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem"); |
| 605 ASSERT_TRUE(test_cert); |
| 606 net::CertificateList dummy_certs(1, test_cert); |
| 600 std::unique_ptr<ClientCertStoreStub> test_store(new ClientCertStoreStub( | 607 std::unique_ptr<ClientCertStoreStub> test_store(new ClientCertStoreStub( |
| 601 dummy_certs, &store_request_count, &store_requested_authorities)); | 608 dummy_certs, &store_request_count, &store_requested_authorities)); |
| 602 SetClientCertStore(std::move(test_store)); | 609 SetClientCertStore(std::move(test_store)); |
| 603 | 610 |
| 604 // Plug in test content browser client. | 611 // Plug in test content browser client. |
| 605 SelectCertificateBrowserClient test_client; | 612 SelectCertificateBrowserClient test_client; |
| 606 ContentBrowserClient* old_client = SetBrowserClientForTesting(&test_client); | 613 ContentBrowserClient* old_client = SetBrowserClientForTesting(&test_client); |
| 607 | 614 |
| 608 // Start the request and wait for it to pause. | 615 // Start the request and wait for it to pause. |
| 609 loader_->StartRequest(); | 616 loader_->StartRequest(); |
| 610 test_client.WaitForSelectCertificate(); | 617 test_client.WaitForSelectCertificate(); |
| 611 | 618 |
| 612 EXPECT_EQ(0, raw_ptr_resource_handler_->on_response_completed_called()); | 619 EXPECT_EQ(0, raw_ptr_resource_handler_->on_response_completed_called()); |
| 613 | 620 |
| 614 // Check if the test store was queried against correct |cert_authorities|. | 621 // Check if the test store was queried against correct |cert_authorities|. |
| 615 EXPECT_EQ(1, store_request_count); | 622 EXPECT_EQ(1, store_request_count); |
| 616 EXPECT_EQ(MockClientCertURLRequestJob::test_authorities(), | 623 EXPECT_EQ(MockClientCertURLRequestJob::test_authorities(), |
| 617 store_requested_authorities); | 624 store_requested_authorities); |
| 618 | 625 |
| 619 // Check if the retrieved certificates were passed to the content browser | 626 // Check if the retrieved certificates were passed to the content browser |
| 620 // client. | 627 // client. |
| 621 EXPECT_EQ(1, test_client.call_count()); | 628 EXPECT_EQ(1, test_client.call_count()); |
| 622 EXPECT_EQ(dummy_certs, test_client.passed_certs()); | 629 EXPECT_EQ(1U, test_client.passed_identities().size()); |
| 630 EXPECT_EQ(test_cert.get(), test_client.passed_identities()[0]->certificate()); |
| 623 | 631 |
| 624 // Continue the request. | 632 // Continue the request. |
| 625 test_client.ContinueWithCertificate(nullptr); | 633 test_client.ContinueWithCertificate(nullptr, nullptr); |
| 626 raw_ptr_resource_handler_->WaitUntilResponseComplete(); | 634 raw_ptr_resource_handler_->WaitUntilResponseComplete(); |
| 627 EXPECT_EQ(net::OK, raw_ptr_resource_handler_->final_status().error()); | 635 EXPECT_EQ(net::OK, raw_ptr_resource_handler_->final_status().error()); |
| 628 | 636 |
| 629 // Restore the original content browser client. | 637 // Restore the original content browser client. |
| 630 SetBrowserClientForTesting(old_client); | 638 SetBrowserClientForTesting(old_client); |
| 631 } | 639 } |
| 632 | 640 |
| 633 // Tests that client certificates are requested on a platform with NULL | 641 // Tests that client certificates are requested on a platform with NULL |
| 634 // ClientCertStore. | 642 // ClientCertStore. |
| 635 TEST_F(ClientCertResourceLoaderTest, WithNullStore) { | 643 TEST_F(ClientCertResourceLoaderTest, WithNullStore) { |
| 636 // Plug in test content browser client. | 644 // Plug in test content browser client. |
| 637 SelectCertificateBrowserClient test_client; | 645 SelectCertificateBrowserClient test_client; |
| 638 ContentBrowserClient* old_client = SetBrowserClientForTesting(&test_client); | 646 ContentBrowserClient* old_client = SetBrowserClientForTesting(&test_client); |
| 639 | 647 |
| 640 // Start the request and wait for it to pause. | 648 // Start the request and wait for it to pause. |
| 641 loader_->StartRequest(); | 649 loader_->StartRequest(); |
| 642 test_client.WaitForSelectCertificate(); | 650 test_client.WaitForSelectCertificate(); |
| 643 | 651 |
| 644 // Check if the SelectClientCertificate was called on the content browser | 652 // Check if the SelectClientCertificate was called on the content browser |
| 645 // client. | 653 // client. |
| 646 EXPECT_EQ(1, test_client.call_count()); | 654 EXPECT_EQ(1, test_client.call_count()); |
| 647 EXPECT_EQ(net::CertificateList(), test_client.passed_certs()); | 655 EXPECT_EQ(net::ClientCertIdentityList(), test_client.passed_identities()); |
| 648 | 656 |
| 649 // Continue the request. | 657 // Continue the request. |
| 650 test_client.ContinueWithCertificate(nullptr); | 658 test_client.ContinueWithCertificate(nullptr, nullptr); |
| 651 raw_ptr_resource_handler_->WaitUntilResponseComplete(); | 659 raw_ptr_resource_handler_->WaitUntilResponseComplete(); |
| 652 EXPECT_EQ(net::OK, raw_ptr_resource_handler_->final_status().error()); | 660 EXPECT_EQ(net::OK, raw_ptr_resource_handler_->final_status().error()); |
| 653 | 661 |
| 654 // Restore the original content browser client. | 662 // Restore the original content browser client. |
| 655 SetBrowserClientForTesting(old_client); | 663 SetBrowserClientForTesting(old_client); |
| 656 } | 664 } |
| 657 | 665 |
| 658 // Tests that the ContentBrowserClient may cancel a certificate request. | 666 // Tests that the ContentBrowserClient may cancel a certificate request. |
| 659 TEST_F(ClientCertResourceLoaderTest, CancelSelection) { | 667 TEST_F(ClientCertResourceLoaderTest, CancelSelection) { |
| 660 // Plug in test content browser client. | 668 // Plug in test content browser client. |
| 661 SelectCertificateBrowserClient test_client; | 669 SelectCertificateBrowserClient test_client; |
| 662 ContentBrowserClient* old_client = SetBrowserClientForTesting(&test_client); | 670 ContentBrowserClient* old_client = SetBrowserClientForTesting(&test_client); |
| 663 | 671 |
| 664 // Start the request and wait for it to pause. | 672 // Start the request and wait for it to pause. |
| 665 loader_->StartRequest(); | 673 loader_->StartRequest(); |
| 666 test_client.WaitForSelectCertificate(); | 674 test_client.WaitForSelectCertificate(); |
| 667 | 675 |
| 668 // Check if the SelectClientCertificate was called on the content browser | 676 // Check if the SelectClientCertificate was called on the content browser |
| 669 // client. | 677 // client. |
| 670 EXPECT_EQ(1, test_client.call_count()); | 678 EXPECT_EQ(1, test_client.call_count()); |
| 671 EXPECT_EQ(net::CertificateList(), test_client.passed_certs()); | 679 EXPECT_EQ(net::ClientCertIdentityList(), test_client.passed_identities()); |
| 672 | 680 |
| 673 // Cancel the request. | 681 // Cancel the request. |
| 674 test_client.CancelCertificateSelection(); | 682 test_client.CancelCertificateSelection(); |
| 675 raw_ptr_resource_handler_->WaitUntilResponseComplete(); | 683 raw_ptr_resource_handler_->WaitUntilResponseComplete(); |
| 676 EXPECT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, | 684 EXPECT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, |
| 677 raw_ptr_resource_handler_->final_status().error()); | 685 raw_ptr_resource_handler_->final_status().error()); |
| 678 | 686 |
| 679 // Restore the original content browser client. | 687 // Restore the original content browser client. |
| 680 SetBrowserClientForTesting(old_client); | 688 SetBrowserClientForTesting(old_client); |
| 681 } | 689 } |
| (...skipping 872 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1554 | 1562 |
| 1555 // Tests that the effective connection type is not set on non-main frame | 1563 // Tests that the effective connection type is not set on non-main frame |
| 1556 // requests. | 1564 // requests. |
| 1557 TEST_F(EffectiveConnectionTypeResourceLoaderTest, DoesNotBelongToMainFrame) { | 1565 TEST_F(EffectiveConnectionTypeResourceLoaderTest, DoesNotBelongToMainFrame) { |
| 1558 VerifyEffectiveConnectionType(RESOURCE_TYPE_OBJECT, false, | 1566 VerifyEffectiveConnectionType(RESOURCE_TYPE_OBJECT, false, |
| 1559 net::EFFECTIVE_CONNECTION_TYPE_3G, | 1567 net::EFFECTIVE_CONNECTION_TYPE_3G, |
| 1560 net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN); | 1568 net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN); |
| 1561 } | 1569 } |
| 1562 | 1570 |
| 1563 } // namespace content | 1571 } // namespace content |
| OLD | NEW |