NaCl docs: add sanitizers to GSoC ideas
[chromium-blink-merge.git] / chrome / browser / ui / views / ssl_client_certificate_selector_browsertest.cc
blob63ee691a18b56b7a5379b6bcf26aa732c6fd178f
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.
5 #include "base/bind.h"
6 #include "base/files/file_path.h"
7 #include "base/synchronization/waitable_event.h"
8 #include "chrome/browser/profiles/profile.h"
9 #include "chrome/browser/ssl/ssl_client_auth_requestor_mock.h"
10 #include "chrome/browser/ui/browser.h"
11 #include "chrome/browser/ui/tabs/tab_strip_model.h"
12 #include "chrome/browser/ui/views/ssl_client_certificate_selector.h"
13 #include "chrome/test/base/in_process_browser_test.h"
14 #include "chrome/test/base/interactive_test_utils.h"
15 #include "chrome/test/base/ui_test_utils.h"
16 #include "content/public/browser/web_contents.h"
17 #include "content/public/test/browser_test_utils.h"
18 #include "net/base/request_priority.h"
19 #include "net/base/test_data_directory.h"
20 #include "net/cert/x509_certificate.h"
21 #include "net/http/http_transaction_factory.h"
22 #include "net/ssl/ssl_cert_request_info.h"
23 #include "net/test/cert_test_util.h"
24 #include "net/url_request/url_request.h"
25 #include "net/url_request/url_request_context.h"
26 #include "net/url_request/url_request_context_getter.h"
27 #include "testing/gtest/include/gtest/gtest.h"
29 #if defined(USE_NSS)
30 #include "crypto/scoped_test_nss_db.h"
31 #endif
33 using ::testing::Mock;
34 using ::testing::StrictMock;
35 using content::BrowserThread;
37 // We don't have a way to do end-to-end SSL client auth testing, so this test
38 // creates a certificate selector_ manually with a mocked
39 // SSLClientAuthHandler.
41 class SSLClientCertificateSelectorTest : public InProcessBrowserTest {
42 public:
43 SSLClientCertificateSelectorTest()
44 : io_loop_finished_event_(false, false),
45 url_request_(NULL),
46 selector_(NULL) {
49 void SetUpInProcessBrowserTestFixture() override {
50 base::FilePath certs_dir = net::GetTestCertsDirectory();
52 #if defined(USE_NSS)
53 // If USE_NSS, the selector tries to unlock the slot where the private key
54 // of each certificate is stored. If no private key is found, the slot would
55 // be null and the unlock will crash.
56 ASSERT_TRUE(test_nssdb_.is_open());
57 client_cert_1_ = net::ImportClientCertAndKeyFromFile(
58 certs_dir, "client_1.pem", "client_1.pk8", test_nssdb_.slot());
59 client_cert_2_ = net::ImportClientCertAndKeyFromFile(
60 certs_dir, "client_2.pem", "client_2.pk8", test_nssdb_.slot());
61 #else
62 // No unlock is attempted if !USE_NSS. Thus, there is no need to import a
63 // private key.
64 client_cert_1_ = net::ImportCertFromFile(certs_dir, "client_1.pem");
65 client_cert_2_ = net::ImportCertFromFile(certs_dir, "client_2.pem");
66 #endif
67 ASSERT_NE(nullptr, client_cert_1_.get());
68 ASSERT_NE(nullptr, client_cert_2_.get());
70 cert_request_info_ = new net::SSLCertRequestInfo;
71 cert_request_info_->host_and_port = net::HostPortPair("foo", 123);
72 cert_request_info_->client_certs.push_back(client_cert_1_);
73 cert_request_info_->client_certs.push_back(client_cert_2_);
76 void SetUpOnMainThread() override {
77 url_request_context_getter_ = browser()->profile()->GetRequestContext();
79 BrowserThread::PostTask(
80 BrowserThread::IO, FROM_HERE,
81 base::Bind(&SSLClientCertificateSelectorTest::SetUpOnIOThread, this));
83 io_loop_finished_event_.Wait();
85 content::WaitForLoadStop(
86 browser()->tab_strip_model()->GetActiveWebContents());
87 selector_ = new SSLClientCertificateSelector(
88 browser()->tab_strip_model()->GetActiveWebContents(),
89 auth_requestor_->cert_request_info_,
90 base::Bind(&SSLClientAuthRequestorMock::CertificateSelected,
91 auth_requestor_));
92 selector_->Init();
93 selector_->Show();
95 EXPECT_EQ(client_cert_1_.get(), selector_->GetSelectedCert());
98 virtual void SetUpOnIOThread() {
99 url_request_ = MakeURLRequest(url_request_context_getter_.get()).release();
101 auth_requestor_ = new StrictMock<SSLClientAuthRequestorMock>(
102 url_request_,
103 cert_request_info_);
105 io_loop_finished_event_.Signal();
108 // Have to release our reference to the auth handler during the test to allow
109 // it to be destroyed while the Browser and its IO thread still exist.
110 void TearDownOnMainThread() override {
111 BrowserThread::PostTask(
112 BrowserThread::IO, FROM_HERE,
113 base::Bind(&SSLClientCertificateSelectorTest::CleanUpOnIOThread, this));
115 io_loop_finished_event_.Wait();
117 auth_requestor_ = NULL;
120 virtual void CleanUpOnIOThread() {
121 delete url_request_;
123 io_loop_finished_event_.Signal();
126 protected:
127 scoped_ptr<net::URLRequest> MakeURLRequest(
128 net::URLRequestContextGetter* context_getter) {
129 return context_getter->GetURLRequestContext()->CreateRequest(
130 GURL("https://example"), net::DEFAULT_PRIORITY, NULL, NULL);
133 base::WaitableEvent io_loop_finished_event_;
135 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
136 net::URLRequest* url_request_;
138 scoped_refptr<net::X509Certificate> client_cert_1_;
139 scoped_refptr<net::X509Certificate> client_cert_2_;
140 scoped_refptr<net::SSLCertRequestInfo> cert_request_info_;
141 scoped_refptr<StrictMock<SSLClientAuthRequestorMock> > auth_requestor_;
142 // The selector will be deleted when a cert is selected or the tab is closed.
143 SSLClientCertificateSelector* selector_;
144 #if defined(USE_NSS)
145 crypto::ScopedTestNSSDB test_nssdb_;
146 #endif
149 class SSLClientCertificateSelectorMultiTabTest
150 : public SSLClientCertificateSelectorTest {
151 public:
152 void SetUpInProcessBrowserTestFixture() override {
153 SSLClientCertificateSelectorTest::SetUpInProcessBrowserTestFixture();
155 cert_request_info_1_ = new net::SSLCertRequestInfo;
156 cert_request_info_1_->host_and_port = net::HostPortPair("bar", 123);
157 cert_request_info_1_->client_certs.push_back(client_cert_1_);
158 cert_request_info_1_->client_certs.push_back(client_cert_2_);
160 cert_request_info_2_ = new net::SSLCertRequestInfo;
161 cert_request_info_2_->host_and_port = net::HostPortPair("bar", 123);
162 cert_request_info_2_->client_certs.push_back(client_cert_1_);
163 cert_request_info_2_->client_certs.push_back(client_cert_2_);
166 void SetUpOnMainThread() override {
167 // Also calls SetUpOnIOThread.
168 SSLClientCertificateSelectorTest::SetUpOnMainThread();
170 AddTabAtIndex(1, GURL("about:blank"), ui::PAGE_TRANSITION_LINK);
171 AddTabAtIndex(2, GURL("about:blank"), ui::PAGE_TRANSITION_LINK);
172 ASSERT_TRUE(NULL != browser()->tab_strip_model()->GetWebContentsAt(0));
173 ASSERT_TRUE(NULL != browser()->tab_strip_model()->GetWebContentsAt(1));
174 ASSERT_TRUE(NULL != browser()->tab_strip_model()->GetWebContentsAt(2));
175 content::WaitForLoadStop(browser()->tab_strip_model()->GetWebContentsAt(1));
176 content::WaitForLoadStop(browser()->tab_strip_model()->GetWebContentsAt(2));
178 selector_1_ = new SSLClientCertificateSelector(
179 browser()->tab_strip_model()->GetWebContentsAt(1),
180 auth_requestor_1_->cert_request_info_,
181 base::Bind(&SSLClientAuthRequestorMock::CertificateSelected,
182 auth_requestor_1_));
183 selector_1_->Init();
184 selector_1_->Show();
185 selector_2_ = new SSLClientCertificateSelector(
186 browser()->tab_strip_model()->GetWebContentsAt(2),
187 auth_requestor_2_->cert_request_info_,
188 base::Bind(&SSLClientAuthRequestorMock::CertificateSelected,
189 auth_requestor_2_));
190 selector_2_->Init();
191 selector_2_->Show();
193 EXPECT_EQ(2, browser()->tab_strip_model()->active_index());
194 EXPECT_EQ(client_cert_1_.get(), selector_1_->GetSelectedCert());
195 EXPECT_EQ(client_cert_1_.get(), selector_2_->GetSelectedCert());
198 void SetUpOnIOThread() override {
199 url_request_1_ =
200 MakeURLRequest(url_request_context_getter_.get()).release();
201 url_request_2_ =
202 MakeURLRequest(url_request_context_getter_.get()).release();
204 auth_requestor_1_ = new StrictMock<SSLClientAuthRequestorMock>(
205 url_request_1_,
206 cert_request_info_1_);
207 auth_requestor_2_ = new StrictMock<SSLClientAuthRequestorMock>(
208 url_request_2_,
209 cert_request_info_2_);
211 SSLClientCertificateSelectorTest::SetUpOnIOThread();
214 void TearDownOnMainThread() override {
215 auth_requestor_2_ = NULL;
216 auth_requestor_1_ = NULL;
217 SSLClientCertificateSelectorTest::TearDownOnMainThread();
220 void CleanUpOnIOThread() override {
221 delete url_request_1_;
222 delete url_request_2_;
223 SSLClientCertificateSelectorTest::CleanUpOnIOThread();
226 protected:
227 net::URLRequest* url_request_1_;
228 net::URLRequest* url_request_2_;
229 scoped_refptr<net::SSLCertRequestInfo> cert_request_info_1_;
230 scoped_refptr<net::SSLCertRequestInfo> cert_request_info_2_;
231 scoped_refptr<StrictMock<SSLClientAuthRequestorMock> > auth_requestor_1_;
232 scoped_refptr<StrictMock<SSLClientAuthRequestorMock> > auth_requestor_2_;
233 SSLClientCertificateSelector* selector_1_;
234 SSLClientCertificateSelector* selector_2_;
237 class SSLClientCertificateSelectorMultiProfileTest
238 : public SSLClientCertificateSelectorTest {
239 public:
240 void SetUpInProcessBrowserTestFixture() override {
241 SSLClientCertificateSelectorTest::SetUpInProcessBrowserTestFixture();
243 cert_request_info_1_ = new net::SSLCertRequestInfo;
244 cert_request_info_1_->host_and_port = net::HostPortPair("foo", 123);
245 cert_request_info_1_->client_certs.push_back(client_cert_1_);
246 cert_request_info_1_->client_certs.push_back(client_cert_2_);
249 void SetUpOnMainThread() override {
250 browser_1_ = CreateIncognitoBrowser();
251 url_request_context_getter_1_ = browser_1_->profile()->GetRequestContext();
253 // Also calls SetUpOnIOThread.
254 SSLClientCertificateSelectorTest::SetUpOnMainThread();
256 selector_1_ = new SSLClientCertificateSelector(
257 browser_1_->tab_strip_model()->GetActiveWebContents(),
258 auth_requestor_1_->cert_request_info_,
259 base::Bind(&SSLClientAuthRequestorMock::CertificateSelected,
260 auth_requestor_1_));
261 selector_1_->Init();
262 selector_1_->Show();
264 EXPECT_EQ(client_cert_1_.get(), selector_1_->GetSelectedCert());
267 void SetUpOnIOThread() override {
268 url_request_1_ =
269 MakeURLRequest(url_request_context_getter_1_.get()).release();
271 auth_requestor_1_ = new StrictMock<SSLClientAuthRequestorMock>(
272 url_request_1_,
273 cert_request_info_1_);
275 SSLClientCertificateSelectorTest::SetUpOnIOThread();
278 void TearDownOnMainThread() override {
279 auth_requestor_1_ = NULL;
280 SSLClientCertificateSelectorTest::TearDownOnMainThread();
283 void CleanUpOnIOThread() override {
284 delete url_request_1_;
285 SSLClientCertificateSelectorTest::CleanUpOnIOThread();
288 protected:
289 Browser* browser_1_;
290 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_1_;
291 net::URLRequest* url_request_1_;
292 scoped_refptr<net::SSLCertRequestInfo> cert_request_info_1_;
293 scoped_refptr<StrictMock<SSLClientAuthRequestorMock> > auth_requestor_1_;
294 SSLClientCertificateSelector* selector_1_;
297 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA)
298 // TODO(erg): linux_aura bringup: http://crbug.com/163931
299 #define MAYBE_SelectNone DISABLED_SelectNone
300 #else
301 #define MAYBE_SelectNone SelectNone
302 #endif
305 IN_PROC_BROWSER_TEST_F(SSLClientCertificateSelectorTest, MAYBE_SelectNone) {
306 EXPECT_CALL(*auth_requestor_.get(), CertificateSelected(NULL));
308 // Let the mock get checked on destruction.
311 IN_PROC_BROWSER_TEST_F(SSLClientCertificateSelectorTest, Escape) {
312 EXPECT_CALL(*auth_requestor_.get(), CertificateSelected(NULL));
314 EXPECT_TRUE(ui_test_utils::SendKeyPressSync(
315 browser(), ui::VKEY_ESCAPE, false, false, false, false));
317 Mock::VerifyAndClear(auth_requestor_.get());
320 IN_PROC_BROWSER_TEST_F(SSLClientCertificateSelectorTest, SelectDefault) {
321 EXPECT_CALL(*auth_requestor_.get(),
322 CertificateSelected(client_cert_1_.get()));
324 EXPECT_TRUE(ui_test_utils::SendKeyPressSync(
325 browser(), ui::VKEY_RETURN, false, false, false, false));
327 Mock::VerifyAndClear(auth_requestor_.get());
330 IN_PROC_BROWSER_TEST_F(SSLClientCertificateSelectorMultiTabTest, Escape) {
331 // auth_requestor_1_ should get selected automatically by the
332 // SSLClientAuthObserver when selector_2_ is accepted, since both 1 & 2 have
333 // the same host:port.
334 EXPECT_CALL(*auth_requestor_1_.get(), CertificateSelected(NULL));
335 EXPECT_CALL(*auth_requestor_2_.get(), CertificateSelected(NULL));
337 EXPECT_TRUE(ui_test_utils::SendKeyPressSync(
338 browser(), ui::VKEY_ESCAPE, false, false, false, false));
340 Mock::VerifyAndClear(auth_requestor_.get());
341 Mock::VerifyAndClear(auth_requestor_1_.get());
342 Mock::VerifyAndClear(auth_requestor_2_.get());
344 // Now let the default selection for auth_requestor_ mock get checked on
345 // destruction.
346 EXPECT_CALL(*auth_requestor_.get(), CertificateSelected(NULL));
349 IN_PROC_BROWSER_TEST_F(SSLClientCertificateSelectorMultiTabTest, SelectSecond) {
350 // auth_requestor_1_ should get selected automatically by the
351 // SSLClientAuthObserver when selector_2_ is accepted, since both 1 & 2 have
352 // the same host:port.
353 EXPECT_CALL(*auth_requestor_1_.get(),
354 CertificateSelected(client_cert_2_.get()));
355 EXPECT_CALL(*auth_requestor_2_.get(),
356 CertificateSelected(client_cert_2_.get()));
358 EXPECT_TRUE(ui_test_utils::SendKeyPressSync(
359 browser(), ui::VKEY_DOWN, false, false, false, false));
361 EXPECT_EQ(client_cert_1_.get(), selector_->GetSelectedCert());
362 EXPECT_EQ(client_cert_1_.get(), selector_1_->GetSelectedCert());
363 EXPECT_EQ(client_cert_2_.get(), selector_2_->GetSelectedCert());
365 EXPECT_TRUE(ui_test_utils::SendKeyPressSync(
366 browser(), ui::VKEY_RETURN, false, false, false, false));
368 Mock::VerifyAndClear(auth_requestor_.get());
369 Mock::VerifyAndClear(auth_requestor_1_.get());
370 Mock::VerifyAndClear(auth_requestor_2_.get());
372 // Now let the default selection for auth_requestor_ mock get checked on
373 // destruction.
374 EXPECT_CALL(*auth_requestor_.get(), CertificateSelected(NULL));
377 IN_PROC_BROWSER_TEST_F(SSLClientCertificateSelectorMultiProfileTest, Escape) {
378 EXPECT_CALL(*auth_requestor_1_.get(), CertificateSelected(NULL));
380 EXPECT_TRUE(ui_test_utils::SendKeyPressSync(
381 browser_1_, ui::VKEY_ESCAPE, false, false, false, false));
383 Mock::VerifyAndClear(auth_requestor_.get());
384 Mock::VerifyAndClear(auth_requestor_1_.get());
386 // Now let the default selection for auth_requestor_ mock get checked on
387 // destruction.
388 EXPECT_CALL(*auth_requestor_.get(), CertificateSelected(NULL));
391 IN_PROC_BROWSER_TEST_F(SSLClientCertificateSelectorMultiProfileTest,
392 SelectDefault) {
393 EXPECT_CALL(*auth_requestor_1_.get(),
394 CertificateSelected(client_cert_1_.get()));
396 EXPECT_TRUE(ui_test_utils::SendKeyPressSync(
397 browser_1_, ui::VKEY_RETURN, false, false, false, false));
399 Mock::VerifyAndClear(auth_requestor_.get());
400 Mock::VerifyAndClear(auth_requestor_1_.get());
402 // Now let the default selection for auth_requestor_ mock get checked on
403 // destruction.
404 EXPECT_CALL(*auth_requestor_.get(), CertificateSelected(NULL));