- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / views / ssl_client_certificate_selector_browsertest.cc
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 "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"
28
29 using ::testing::Mock;
30 using ::testing::StrictMock;
31 using content::BrowserThread;
32
33 // We don't have a way to do end-to-end SSL client auth testing, so this test
34 // creates a certificate selector_ manually with a mocked
35 // SSLClientAuthHandler.
36
37 class SSLClientCertificateSelectorTest : public InProcessBrowserTest {
38  public:
39   SSLClientCertificateSelectorTest()
40       : io_loop_finished_event_(false, false),
41         url_request_(NULL),
42         selector_(NULL) {
43   }
44
45   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
46     base::FilePath certs_dir = net::GetTestCertsDirectory();
47
48     mit_davidben_cert_ = net::ImportCertFromFile(certs_dir, "mit.davidben.der");
49     ASSERT_NE(static_cast<net::X509Certificate*>(NULL), mit_davidben_cert_);
50
51     foaf_me_chromium_test_cert_ = net::ImportCertFromFile(
52         certs_dir, "foaf.me.chromium-test-cert.der");
53     ASSERT_NE(static_cast<net::X509Certificate*>(NULL),
54               foaf_me_chromium_test_cert_);
55
56     cert_request_info_ = new net::SSLCertRequestInfo;
57     cert_request_info_->host_and_port = "foo:123";
58     cert_request_info_->client_certs.push_back(mit_davidben_cert_);
59     cert_request_info_->client_certs.push_back(foaf_me_chromium_test_cert_);
60   }
61
62   virtual void SetUpOnMainThread() OVERRIDE {
63     url_request_context_getter_ = browser()->profile()->GetRequestContext();
64
65     BrowserThread::PostTask(
66         BrowserThread::IO, FROM_HERE,
67         base::Bind(&SSLClientCertificateSelectorTest::SetUpOnIOThread, this));
68
69     io_loop_finished_event_.Wait();
70
71     content::WaitForLoadStop(
72         browser()->tab_strip_model()->GetActiveWebContents());
73     selector_ = new SSLClientCertificateSelector(
74         browser()->tab_strip_model()->GetActiveWebContents(),
75         auth_requestor_->http_network_session_,
76         auth_requestor_->cert_request_info_,
77         base::Bind(&SSLClientAuthRequestorMock::CertificateSelected,
78                    auth_requestor_));
79     selector_->Init();
80
81     EXPECT_EQ(mit_davidben_cert_.get(), selector_->GetSelectedCert());
82   }
83
84   virtual void SetUpOnIOThread() {
85     url_request_ = MakeURLRequest(url_request_context_getter_).release();
86
87     auth_requestor_ = new StrictMock<SSLClientAuthRequestorMock>(
88         url_request_,
89         cert_request_info_);
90
91     io_loop_finished_event_.Signal();
92   }
93
94   // Have to release our reference to the auth handler during the test to allow
95   // it to be destroyed while the Browser and its IO thread still exist.
96   virtual void CleanUpOnMainThread() OVERRIDE {
97     BrowserThread::PostTask(
98         BrowserThread::IO, FROM_HERE,
99         base::Bind(&SSLClientCertificateSelectorTest::CleanUpOnIOThread, this));
100
101     io_loop_finished_event_.Wait();
102
103     auth_requestor_ = NULL;
104   }
105
106   virtual void CleanUpOnIOThread() {
107     delete url_request_;
108
109     io_loop_finished_event_.Signal();
110   }
111
112  protected:
113   scoped_ptr<net::URLRequest> MakeURLRequest(
114       net::URLRequestContextGetter* context_getter) {
115     return context_getter->GetURLRequestContext()->CreateRequest(
116         GURL("https://example"), net::DEFAULT_PRIORITY, NULL);
117   }
118
119   base::WaitableEvent io_loop_finished_event_;
120
121   scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
122   net::URLRequest* url_request_;
123
124   scoped_refptr<net::X509Certificate> mit_davidben_cert_;
125   scoped_refptr<net::X509Certificate> foaf_me_chromium_test_cert_;
126   scoped_refptr<net::SSLCertRequestInfo> cert_request_info_;
127   scoped_refptr<StrictMock<SSLClientAuthRequestorMock> > auth_requestor_;
128   // The selector will be deleted when a cert is selected or the tab is closed.
129   SSLClientCertificateSelector* selector_;
130 };
131
132 class SSLClientCertificateSelectorMultiTabTest
133     : public SSLClientCertificateSelectorTest {
134  public:
135   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
136     SSLClientCertificateSelectorTest::SetUpInProcessBrowserTestFixture();
137
138     cert_request_info_1_ = new net::SSLCertRequestInfo;
139     cert_request_info_1_->host_and_port = "bar:123";
140     cert_request_info_1_->client_certs.push_back(mit_davidben_cert_);
141     cert_request_info_1_->client_certs.push_back(foaf_me_chromium_test_cert_);
142
143     cert_request_info_2_ = new net::SSLCertRequestInfo;
144     cert_request_info_2_->host_and_port = "bar:123";
145     cert_request_info_2_->client_certs.push_back(mit_davidben_cert_);
146     cert_request_info_2_->client_certs.push_back(foaf_me_chromium_test_cert_);
147   }
148
149   virtual void SetUpOnMainThread() OVERRIDE {
150     // Also calls SetUpOnIOThread.
151     SSLClientCertificateSelectorTest::SetUpOnMainThread();
152
153     AddTabAtIndex(1, GURL("about:blank"), content::PAGE_TRANSITION_LINK);
154     AddTabAtIndex(2, GURL("about:blank"), content::PAGE_TRANSITION_LINK);
155     ASSERT_TRUE(NULL != browser()->tab_strip_model()->GetWebContentsAt(0));
156     ASSERT_TRUE(NULL != browser()->tab_strip_model()->GetWebContentsAt(1));
157     ASSERT_TRUE(NULL != browser()->tab_strip_model()->GetWebContentsAt(2));
158     content::WaitForLoadStop(browser()->tab_strip_model()->GetWebContentsAt(1));
159     content::WaitForLoadStop(browser()->tab_strip_model()->GetWebContentsAt(2));
160
161     selector_1_ = new SSLClientCertificateSelector(
162         browser()->tab_strip_model()->GetWebContentsAt(1),
163         auth_requestor_1_->http_network_session_,
164         auth_requestor_1_->cert_request_info_,
165         base::Bind(&SSLClientAuthRequestorMock::CertificateSelected,
166                    auth_requestor_1_));
167     selector_1_->Init();
168     selector_2_ = new SSLClientCertificateSelector(
169         browser()->tab_strip_model()->GetWebContentsAt(2),
170         auth_requestor_2_->http_network_session_,
171         auth_requestor_2_->cert_request_info_,
172         base::Bind(&SSLClientAuthRequestorMock::CertificateSelected,
173                    auth_requestor_2_));
174     selector_2_->Init();
175
176     EXPECT_EQ(2, browser()->tab_strip_model()->active_index());
177     EXPECT_EQ(mit_davidben_cert_.get(), selector_1_->GetSelectedCert());
178     EXPECT_EQ(mit_davidben_cert_.get(), selector_2_->GetSelectedCert());
179   }
180
181   virtual void SetUpOnIOThread() OVERRIDE {
182     url_request_1_ = MakeURLRequest(url_request_context_getter_).release();
183     url_request_2_ = MakeURLRequest(url_request_context_getter_).release();
184
185     auth_requestor_1_ = new StrictMock<SSLClientAuthRequestorMock>(
186         url_request_1_,
187         cert_request_info_1_);
188     auth_requestor_2_ = new StrictMock<SSLClientAuthRequestorMock>(
189         url_request_2_,
190         cert_request_info_2_);
191
192     SSLClientCertificateSelectorTest::SetUpOnIOThread();
193   }
194
195   virtual void CleanUpOnMainThread() OVERRIDE {
196     auth_requestor_2_ = NULL;
197     auth_requestor_1_ = NULL;
198     SSLClientCertificateSelectorTest::CleanUpOnMainThread();
199   }
200
201   virtual void CleanUpOnIOThread() OVERRIDE {
202     delete url_request_1_;
203     delete url_request_2_;
204     SSLClientCertificateSelectorTest::CleanUpOnIOThread();
205   }
206
207  protected:
208   net::URLRequest* url_request_1_;
209   net::URLRequest* url_request_2_;
210   scoped_refptr<net::SSLCertRequestInfo> cert_request_info_1_;
211   scoped_refptr<net::SSLCertRequestInfo> cert_request_info_2_;
212   scoped_refptr<StrictMock<SSLClientAuthRequestorMock> > auth_requestor_1_;
213   scoped_refptr<StrictMock<SSLClientAuthRequestorMock> > auth_requestor_2_;
214   SSLClientCertificateSelector* selector_1_;
215   SSLClientCertificateSelector* selector_2_;
216 };
217
218 class SSLClientCertificateSelectorMultiProfileTest
219     : public SSLClientCertificateSelectorTest {
220  public:
221   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
222     SSLClientCertificateSelectorTest::SetUpInProcessBrowserTestFixture();
223
224     cert_request_info_1_ = new net::SSLCertRequestInfo;
225     cert_request_info_1_->host_and_port = "foo:123";
226     cert_request_info_1_->client_certs.push_back(mit_davidben_cert_);
227     cert_request_info_1_->client_certs.push_back(foaf_me_chromium_test_cert_);
228   }
229
230   virtual void SetUpOnMainThread() OVERRIDE {
231     browser_1_ = CreateIncognitoBrowser();
232     url_request_context_getter_1_ = browser_1_->profile()->GetRequestContext();
233
234     // Also calls SetUpOnIOThread.
235     SSLClientCertificateSelectorTest::SetUpOnMainThread();
236
237     selector_1_ = new SSLClientCertificateSelector(
238         browser_1_->tab_strip_model()->GetActiveWebContents(),
239         auth_requestor_1_->http_network_session_,
240         auth_requestor_1_->cert_request_info_,
241         base::Bind(&SSLClientAuthRequestorMock::CertificateSelected,
242                    auth_requestor_1_));
243     selector_1_->Init();
244
245     EXPECT_EQ(mit_davidben_cert_.get(), selector_1_->GetSelectedCert());
246   }
247
248   virtual void SetUpOnIOThread() OVERRIDE {
249     url_request_1_ = MakeURLRequest(url_request_context_getter_1_).release();
250
251     auth_requestor_1_ = new StrictMock<SSLClientAuthRequestorMock>(
252         url_request_1_,
253         cert_request_info_1_);
254
255     SSLClientCertificateSelectorTest::SetUpOnIOThread();
256   }
257
258   virtual void CleanUpOnMainThread() OVERRIDE {
259     auth_requestor_1_ = NULL;
260     SSLClientCertificateSelectorTest::CleanUpOnMainThread();
261   }
262
263   virtual void CleanUpOnIOThread() OVERRIDE {
264     delete url_request_1_;
265     SSLClientCertificateSelectorTest::CleanUpOnIOThread();
266   }
267
268  protected:
269   Browser* browser_1_;
270   scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_1_;
271   net::URLRequest* url_request_1_;
272   scoped_refptr<net::SSLCertRequestInfo> cert_request_info_1_;
273   scoped_refptr<StrictMock<SSLClientAuthRequestorMock> > auth_requestor_1_;
274   SSLClientCertificateSelector* selector_1_;
275 };
276
277 IN_PROC_BROWSER_TEST_F(SSLClientCertificateSelectorTest, SelectNone) {
278   EXPECT_CALL(*auth_requestor_, CertificateSelected(NULL));
279
280   // Let the mock get checked on destruction.
281 }
282
283 // http://crbug.com/121007
284 IN_PROC_BROWSER_TEST_F(SSLClientCertificateSelectorTest, DISABLED_Escape) {
285   EXPECT_CALL(*auth_requestor_, CertificateSelected(NULL));
286
287   EXPECT_TRUE(ui_test_utils::SendKeyPressSync(
288       browser(), ui::VKEY_ESCAPE, false, false, false, false));
289
290   Mock::VerifyAndClear(auth_requestor_.get());
291 }
292
293 // Flaky, http://crbug.com/103534 .
294 IN_PROC_BROWSER_TEST_F(SSLClientCertificateSelectorTest,
295                        DISABLED_SelectDefault) {
296   EXPECT_CALL(*auth_requestor_, CertificateSelected(mit_davidben_cert_.get()));
297
298   EXPECT_TRUE(ui_test_utils::SendKeyPressSync(
299       browser(), ui::VKEY_RETURN, false, false, false, false));
300
301   Mock::VerifyAndClear(auth_requestor_.get());
302 }
303
304 // http://crbug.com/121007
305 IN_PROC_BROWSER_TEST_F(SSLClientCertificateSelectorMultiTabTest,
306                        DISABLED_Escape) {
307   // auth_requestor_1_ should get selected automatically by the
308   // SSLClientAuthObserver when selector_2_ is accepted, since both 1 & 2 have
309   // the same host:port.
310   EXPECT_CALL(*auth_requestor_1_, CertificateSelected(NULL));
311   EXPECT_CALL(*auth_requestor_2_, CertificateSelected(NULL));
312
313   EXPECT_TRUE(ui_test_utils::SendKeyPressSync(
314       browser(), ui::VKEY_ESCAPE, false, false, false, false));
315
316   Mock::VerifyAndClear(auth_requestor_.get());
317   Mock::VerifyAndClear(auth_requestor_1_.get());
318   Mock::VerifyAndClear(auth_requestor_2_.get());
319
320   // Now let the default selection for auth_requestor_ mock get checked on
321   // destruction.
322   EXPECT_CALL(*auth_requestor_, CertificateSelected(NULL));
323 }
324
325 // http://crbug.com/121007
326 IN_PROC_BROWSER_TEST_F(SSLClientCertificateSelectorMultiTabTest,
327                        DISABLED_SelectSecond) {
328   // auth_requestor_1_ should get selected automatically by the
329   // SSLClientAuthObserver when selector_2_ is accepted, since both 1 & 2 have
330   // the same host:port.
331   EXPECT_CALL(*auth_requestor_1_,
332               CertificateSelected(foaf_me_chromium_test_cert_.get()));
333   EXPECT_CALL(*auth_requestor_2_,
334               CertificateSelected(foaf_me_chromium_test_cert_.get()));
335
336   EXPECT_TRUE(ui_test_utils::SendKeyPressSync(
337       browser(), ui::VKEY_DOWN, false, false, false, false));
338
339   EXPECT_EQ(mit_davidben_cert_.get(), selector_->GetSelectedCert());
340   EXPECT_EQ(mit_davidben_cert_.get(), selector_1_->GetSelectedCert());
341   EXPECT_EQ(foaf_me_chromium_test_cert_.get(), selector_2_->GetSelectedCert());
342
343   EXPECT_TRUE(ui_test_utils::SendKeyPressSync(
344       browser(), ui::VKEY_RETURN, false, false, false, false));
345
346   Mock::VerifyAndClear(auth_requestor_.get());
347   Mock::VerifyAndClear(auth_requestor_1_.get());
348   Mock::VerifyAndClear(auth_requestor_2_.get());
349
350   // Now let the default selection for auth_requestor_ mock get checked on
351   // destruction.
352   EXPECT_CALL(*auth_requestor_, CertificateSelected(NULL));
353 }
354
355 // http://crbug.com/103529
356 IN_PROC_BROWSER_TEST_F(SSLClientCertificateSelectorMultiProfileTest,
357                        DISABLED_Escape) {
358   EXPECT_CALL(*auth_requestor_1_, CertificateSelected(NULL));
359
360   EXPECT_TRUE(ui_test_utils::SendKeyPressSync(
361       browser_1_, ui::VKEY_ESCAPE, false, false, false, false));
362
363   Mock::VerifyAndClear(auth_requestor_.get());
364   Mock::VerifyAndClear(auth_requestor_1_.get());
365
366   // Now let the default selection for auth_requestor_ mock get checked on
367   // destruction.
368   EXPECT_CALL(*auth_requestor_, CertificateSelected(NULL));
369 }
370
371 // http://crbug.com/103534
372 IN_PROC_BROWSER_TEST_F(SSLClientCertificateSelectorMultiProfileTest,
373                        DISABLED_SelectDefault) {
374   EXPECT_CALL(*auth_requestor_1_,
375               CertificateSelected(mit_davidben_cert_.get()));
376
377   EXPECT_TRUE(ui_test_utils::SendKeyPressSync(
378       browser_1_, ui::VKEY_RETURN, false, false, false, false));
379
380   Mock::VerifyAndClear(auth_requestor_.get());
381   Mock::VerifyAndClear(auth_requestor_1_.get());
382
383   // Now let the default selection for auth_requestor_ mock get checked on
384   // destruction.
385   EXPECT_CALL(*auth_requestor_, CertificateSelected(NULL));
386 }