Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(43)

Side by Side Diff: content/browser/loader/resource_loader_unittest.cc

Issue 12035105: Move client certificates retrieval logic out of the SSL sockets. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address Ryan's remarks Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
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 "content/browser/loader/resource_loader.h"
6
7 #include "base/message_loop.h"
8 #include "content/browser/browser_thread_impl.h"
9 #include "content/browser/loader/resource_loader_delegate.h"
10 #include "content/public/browser/resource_request_info.h"
11 #include "content/public/test/mock_resource_context.h"
12 #include "content/test/test_content_browser_client.h"
13 #include "net/base/client_cert_store.h"
14 #include "net/base/ssl_cert_request_info.h"
15 #include "net/base/x509_certificate.h"
16 #include "net/url_request/url_request.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 namespace content {
20 namespace {
21
22 // Stub client certificate store that returns a preset list of certificates for
23 // each query and allows inspection of the requests which the store accepted.
24 class ClientCertStoreStub : public net::ClientCertStore {
25 public:
26 ClientCertStoreStub() : request_count_(0) {}
27
28 virtual ~ClientCertStoreStub() {}
29
30 // Sets the certificates that will be returned for subsequent calls to
31 // GetClientCerts().
32 void set_response(const net::CertificateList& certs) {
33 response_ = certs;
34 }
35
36 // Returns |cert_authorities| field of the certificate request passed in the
37 // most recent call to GetClientCerts().
38 // TODO(ppi): Make the stub independent from the internal representation of
39 // SSLCertRequestInfo. For now it seems that we cannot neither save the
40 // scoped_refptr<> (since it is never passed to us) nor copy the entire
41 // CertificateRequestInfo (since there is no copy constructor).
42 std::vector<std::string> requested_authorities() {
43 return requested_authorities_;
44 }
45
46 // Returns the number of calls to GetClientCerts().
47 int request_count() {
48 return request_count_;
49 }
50
51 // ClientCertStore:
52 virtual bool GetClientCerts(const net::SSLCertRequestInfo& cert_request_info,
53 net::CertificateList* selected_certs) OVERRIDE {
54 ++request_count_;
55 requested_authorities_ = cert_request_info.cert_authorities;
56 *selected_certs = response_;
57 return true;
58 }
59
60 private:
61 net::CertificateList response_;
62 std::vector<std::string> requested_authorities_;
63 int request_count_;
64 };
65
66 // Dummy implementation of ResourceHandler, instance of which is needed to
67 // initialize ResourceLoader.
68 class ResourceHandlerStub : public ResourceHandler {
69 public:
70 virtual bool OnUploadProgress(int request_id,
71 uint64 position,
72 uint64 size) OVERRIDE {
73 return true;
74 }
75
76 virtual bool OnRequestRedirected(int request_id,
77 const GURL& url,
78 ResourceResponse* response,
79 bool* defer) OVERRIDE {
80 return true;
81 }
82
83 virtual bool OnResponseStarted(int request_id,
84 ResourceResponse* response,
85 bool* defer) OVERRIDE { return true; }
86
87 virtual bool OnWillStart(int request_id,
88 const GURL& url,
89 bool* defer) OVERRIDE {
90 return true;
91 }
92
93 virtual bool OnWillRead(int request_id,
94 net::IOBuffer** buf,
95 int* buf_size,
96 int min_size) OVERRIDE {
97 return true;
98 }
99
100 virtual bool OnReadCompleted(int request_id,
101 int bytes_read,
102 bool* defer) OVERRIDE {
103 return true;
104 }
105
106 virtual bool OnResponseCompleted(int request_id,
107 const net::URLRequestStatus& status,
108 const std::string& security_info) OVERRIDE {
109 return true;
110 }
111
112 virtual void OnDataDownloaded(int request_id,
113 int bytes_downloaded) OVERRIDE {}
114 };
115
116 // Test browser client that captures calls to SelectClientCertificates and
117 // allows inspection of the call arguments.
118 class SelectCertificateBrowserClient : public TestContentBrowserClient {
119 public:
120 SelectCertificateBrowserClient() : call_count_(0) {}
121
122 virtual void SelectClientCertificate(
123 int render_process_id,
124 int render_view_id,
125 const net::HttpNetworkSession* network_session,
126 net::SSLCertRequestInfo* cert_request_info,
127 const base::Callback<void(net::X509Certificate*)>& callback) OVERRIDE {
128 ++call_count_;
129 passed_certs_ = cert_request_info->client_certs;
130 }
131
132 int call_count() {
133 return call_count_;
134 }
135
136 net::CertificateList passed_certs() {
137 return passed_certs_;
138 }
139
140 private:
141 net::CertificateList passed_certs_;
142 int call_count_;
143 };
144
145 } // namespace
146
147 class ResourceLoaderTest : public testing::Test,
148 public ResourceLoaderDelegate {
149 protected:
150 // testing::Test:
151 virtual void SetUp() OVERRIDE {
152 message_loop_.reset(new MessageLoop(MessageLoop::TYPE_IO));
153 ui_thread_.reset(new BrowserThreadImpl(BrowserThread::UI,
154 message_loop_.get()));
155 io_thread_.reset(new BrowserThreadImpl(BrowserThread::IO,
156 message_loop_.get()));
157 }
158
159 // ResourceLoaderDelegate:
160 virtual ResourceDispatcherHostLoginDelegate* CreateLoginDelegate(
161 ResourceLoader* loader,
162 net::AuthChallengeInfo* auth_info) OVERRIDE {
163 return NULL;
164 }
165 virtual bool AcceptAuthRequest(
166 ResourceLoader* loader,
167 net::AuthChallengeInfo* auth_info) OVERRIDE {
168 return false;
169 };
170 virtual bool AcceptSSLClientCertificateRequest(
171 ResourceLoader* loader,
172 net::SSLCertRequestInfo* cert_info) OVERRIDE {
173 return true;
174 }
175 virtual bool HandleExternalProtocol(ResourceLoader* loader,
176 const GURL& url) OVERRIDE {
177 return false;
178 }
179 virtual void DidStartRequest(ResourceLoader* loader) OVERRIDE {}
180 virtual void DidReceiveRedirect(ResourceLoader* loader,
181 const GURL& new_url) OVERRIDE {}
182 virtual void DidReceiveResponse(ResourceLoader* loader) OVERRIDE {}
183 virtual void DidFinishLoading(ResourceLoader* loader) OVERRIDE {}
184
185 scoped_ptr<MessageLoop> message_loop_;
186 scoped_ptr<BrowserThreadImpl> ui_thread_;
187 scoped_ptr<BrowserThreadImpl> io_thread_;
188
189 content::MockResourceContext resource_context_;
190 };
191
192 // When OpenSSL is used, client cert store is not being queried in
193 // ResourceLoader.
194 #if !defined(USE_OPENSSL)
195 // Verifies if a call to net::UrlRequest::Delegate::OnCertificateRequested()
196 // causes client cert store to be queried for certificates and if the returned
197 // certificates are correctly passed to the content browser client for
198 // selection.
199 TEST_F(ResourceLoaderTest, ClientCertStoreLookup) {
200 const int kRenderProcessId = 1;
201 const int kRenderViewId = 2;
202
203 scoped_ptr<net::URLRequest> request(new net::URLRequest(
204 GURL("dummy"), NULL,
205 resource_context_.GetRequestContext()));
206
207 ResourceRequestInfo::AllocateForTesting(request.get(),
208 ResourceType::MAIN_FRAME,
209 &resource_context_,
210 kRenderProcessId,
211 kRenderViewId);
212
213 // Ownership of |request| is about to be passed to ResourceLoader. We need a
214 // copy of the pointer to issue a fake call to OnCertificateRequested() later.
215 net::URLRequest* weak_ptr_to_request = request.get();
216 scoped_ptr<ResourceHandler> resource_handler(new ResourceHandlerStub());
217 ResourceLoader loader(request.Pass(), resource_handler.Pass(), this);
218
219 // Set up the test client cert store.
220 scoped_ptr<ClientCertStoreStub> concrete_test_store(
221 new ClientCertStoreStub());
222 net::CertificateList dummy_certs(1, scoped_refptr<net::X509Certificate>(
223 new net::X509Certificate("test", "test", base::Time(), base::Time())));
224 concrete_test_store->set_response(dummy_certs);
225 EXPECT_EQ(0, concrete_test_store->request_count());
226
227 // Prepare a dummy certificate request.
228 scoped_refptr<net::SSLCertRequestInfo> cert_request_info(
229 new net::SSLCertRequestInfo());
230 std::vector<std::string> dummy_authority(1, "dummy");
231 cert_request_info->cert_authorities = dummy_authority;
232
233 // Plug in the test client cert store to the resource loader.
234 scoped_ptr<net::ClientCertStore> test_store(concrete_test_store.Pass());
235 loader.swap_client_cert_store_for_testing(test_store);
236
237 // Plug in test content browser client.
238 ContentBrowserClient* old_client = GetContentClient()->browser();
239 SelectCertificateBrowserClient test_client;
240 GetContentClient()->set_browser_for_testing(&test_client);
241
242 // Everything is set up. Trigger the resource loader certificate request event
243 // and run the message loop.
244 loader.OnCertificateRequested(weak_ptr_to_request, cert_request_info.get());
245 message_loop_->RunUntilIdle();
246
247 // Restore the original content browser client.
248 GetContentClient()->set_browser_for_testing(old_client);
Ryan Sleevi 2013/02/01 22:48:37 I don't understand why this is necessary.
ppi 2013/02/04 19:35:54 This is being done consistently in existing conten
249
250 // Regain the pointer and ownership of the test store.
251 loader.swap_client_cert_store_for_testing(test_store);
252 concrete_test_store = scoped_ptr<ClientCertStoreStub>(
253 static_cast<ClientCertStoreStub*>(test_store.release()));
254
255 // Check if the test store was queried against correct |cert_authorities|.
256 EXPECT_EQ(1, concrete_test_store->request_count());
257 EXPECT_EQ(dummy_authority, concrete_test_store->requested_authorities());
258
259 // Check if the retrieved certificates were passed to the content browser
260 // client.
261 EXPECT_EQ(1, test_client.call_count());
262 EXPECT_EQ(dummy_certs, test_client.passed_certs());
263 }
264 #endif // !defined(OPENSSL)
265
266 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698