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