Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / policy / policy_cert_verifier_browsertest.cc
1 // Copyright 2014 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 "chrome/browser/chromeos/policy/policy_cert_verifier.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/callback.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/run_loop.h"
13 #include "chrome/browser/chromeos/net/cert_verify_proc_chromeos.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "content/public/test/test_browser_thread_bundle.h"
16 #include "crypto/nss_util_internal.h"
17 #include "crypto/scoped_test_nss_chromeos_user.h"
18 #include "net/base/net_log.h"
19 #include "net/base/test_completion_callback.h"
20 #include "net/base/test_data_directory.h"
21 #include "net/cert/cert_trust_anchor_provider.h"
22 #include "net/cert/cert_verify_result.h"
23 #include "net/cert/nss_cert_database_chromeos.h"
24 #include "net/cert/x509_certificate.h"
25 #include "net/test/cert_test_util.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27
28 namespace policy {
29
30 class PolicyCertVerifierTest : public testing::Test {
31  public:
32   PolicyCertVerifierTest()
33       : trust_anchor_used_(false), test_nss_user_("user1") {}
34
35   virtual ~PolicyCertVerifierTest() {}
36
37   virtual void SetUp() override {
38     ASSERT_TRUE(test_nss_user_.constructed_successfully());
39     test_nss_user_.FinishInit();
40
41     test_cert_db_.reset(new net::NSSCertDatabaseChromeOS(
42         crypto::GetPublicSlotForChromeOSUser(test_nss_user_.username_hash()),
43         crypto::GetPrivateSlotForChromeOSUser(
44             test_nss_user_.username_hash(),
45             base::Callback<void(crypto::ScopedPK11Slot)>())));
46     test_cert_db_->SetSlowTaskRunnerForTest(base::MessageLoopProxy::current());
47
48     cert_verifier_.reset(new PolicyCertVerifier(base::Bind(
49         &PolicyCertVerifierTest::OnTrustAnchorUsed, base::Unretained(this))));
50     cert_verifier_->InitializeOnIOThread(new chromeos::CertVerifyProcChromeOS(
51         crypto::GetPublicSlotForChromeOSUser(test_nss_user_.username_hash())));
52
53     test_ca_cert_ = LoadCertificate("root_ca_cert.pem", net::CA_CERT);
54     ASSERT_TRUE(test_ca_cert_.get());
55     test_server_cert_ = LoadCertificate("ok_cert.pem", net::SERVER_CERT);
56     ASSERT_TRUE(test_server_cert_.get());
57     test_ca_cert_list_.push_back(test_ca_cert_);
58   }
59
60   virtual void TearDown() override {
61     // Destroy |cert_verifier_| before destroying the ThreadBundle, otherwise
62     // BrowserThread::CurrentlyOn checks fail.
63     cert_verifier_.reset();
64   }
65
66  protected:
67   int VerifyTestServerCert(const net::TestCompletionCallback& test_callback,
68                            net::CertVerifyResult* verify_result,
69                            net::CertVerifier::RequestHandle* request_handle) {
70     return cert_verifier_->Verify(test_server_cert_.get(),
71                                   "127.0.0.1",
72                                   0,
73                                   NULL,
74                                   verify_result,
75                                   test_callback.callback(),
76                                   request_handle,
77                                   net::BoundNetLog());
78   }
79
80   bool SupportsAdditionalTrustAnchors() {
81     scoped_refptr<net::CertVerifyProc> proc =
82         net::CertVerifyProc::CreateDefault();
83     return proc->SupportsAdditionalTrustAnchors();
84   }
85
86   // Returns whether |cert_verifier| signalled usage of one of the additional
87   // trust anchors (i.e. of |test_ca_cert_|) for the first time or since the
88   // last call of this function.
89   bool WasTrustAnchorUsedAndReset() {
90     base::RunLoop().RunUntilIdle();
91     bool result = trust_anchor_used_;
92     trust_anchor_used_ = false;
93     return result;
94   }
95
96   // |test_ca_cert_| is the issuer of |test_server_cert_|.
97   scoped_refptr<net::X509Certificate> test_ca_cert_;
98   scoped_refptr<net::X509Certificate> test_server_cert_;
99   net::CertificateList test_ca_cert_list_;
100   scoped_ptr<net::NSSCertDatabaseChromeOS> test_cert_db_;
101   scoped_ptr<PolicyCertVerifier> cert_verifier_;
102
103  private:
104   void OnTrustAnchorUsed() {
105     trust_anchor_used_ = true;
106   }
107
108   scoped_refptr<net::X509Certificate> LoadCertificate(const std::string& name,
109                                                       net::CertType type) {
110     scoped_refptr<net::X509Certificate> cert =
111         net::ImportCertFromFile(net::GetTestCertsDirectory(), name);
112
113     // No certificate is trusted right after it's loaded.
114     net::NSSCertDatabase::TrustBits trust =
115         test_cert_db_->GetCertTrust(cert.get(), type);
116     EXPECT_EQ(net::NSSCertDatabase::TRUST_DEFAULT, trust);
117
118     return cert;
119   }
120
121   bool trust_anchor_used_;
122   crypto::ScopedTestNSSChromeOSUser test_nss_user_;
123   content::TestBrowserThreadBundle thread_bundle_;
124 };
125
126 TEST_F(PolicyCertVerifierTest, VerifyUntrustedCert) {
127   // |test_server_cert_| is untrusted, so Verify() fails.
128   {
129     net::CertVerifyResult verify_result;
130     net::TestCompletionCallback callback;
131     net::CertVerifier::RequestHandle request_handle = NULL;
132     int error = VerifyTestServerCert(callback, &verify_result, &request_handle);
133     ASSERT_EQ(net::ERR_IO_PENDING, error);
134     EXPECT_TRUE(request_handle);
135     error = callback.WaitForResult();
136     EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID, error);
137   }
138
139   // Issuing the same request again hits the cache. This tests the synchronous
140   // path.
141   {
142     net::CertVerifyResult verify_result;
143     net::TestCompletionCallback callback;
144     net::CertVerifier::RequestHandle request_handle = NULL;
145     int error = VerifyTestServerCert(callback, &verify_result, &request_handle);
146     EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID, error);
147   }
148
149   EXPECT_FALSE(WasTrustAnchorUsedAndReset());
150 }
151
152 TEST_F(PolicyCertVerifierTest, VerifyTrustedCert) {
153   // Make the database trust |test_ca_cert_|.
154   net::NSSCertDatabase::ImportCertFailureList failure_list;
155   ASSERT_TRUE(test_cert_db_->ImportCACerts(
156       test_ca_cert_list_, net::NSSCertDatabase::TRUSTED_SSL, &failure_list));
157   ASSERT_TRUE(failure_list.empty());
158
159   // Verify that it is now trusted.
160   net::NSSCertDatabase::TrustBits trust =
161       test_cert_db_->GetCertTrust(test_ca_cert_.get(), net::CA_CERT);
162   EXPECT_EQ(net::NSSCertDatabase::TRUSTED_SSL, trust);
163
164   // Verify() successfully verifies |test_server_cert_| after it was imported.
165   net::CertVerifyResult verify_result;
166   net::TestCompletionCallback callback;
167   net::CertVerifier::RequestHandle request_handle = NULL;
168   int error = VerifyTestServerCert(callback, &verify_result, &request_handle);
169   ASSERT_EQ(net::ERR_IO_PENDING, error);
170   EXPECT_TRUE(request_handle);
171   error = callback.WaitForResult();
172   EXPECT_EQ(net::OK, error);
173
174   // The additional trust anchors were not used, since the certificate is
175   // trusted from the database.
176   EXPECT_FALSE(WasTrustAnchorUsedAndReset());
177 }
178
179 TEST_F(PolicyCertVerifierTest, VerifyUsingAdditionalTrustAnchor) {
180   ASSERT_TRUE(SupportsAdditionalTrustAnchors());
181
182   // |test_server_cert_| is untrusted, so Verify() fails.
183   {
184     net::CertVerifyResult verify_result;
185     net::TestCompletionCallback callback;
186     net::CertVerifier::RequestHandle request_handle = NULL;
187     int error = VerifyTestServerCert(callback, &verify_result, &request_handle);
188     ASSERT_EQ(net::ERR_IO_PENDING, error);
189     EXPECT_TRUE(request_handle);
190     error = callback.WaitForResult();
191     EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID, error);
192   }
193   EXPECT_FALSE(WasTrustAnchorUsedAndReset());
194
195   // Verify() again with the additional trust anchors.
196   cert_verifier_->SetTrustAnchors(test_ca_cert_list_);
197   {
198     net::CertVerifyResult verify_result;
199     net::TestCompletionCallback callback;
200     net::CertVerifier::RequestHandle request_handle = NULL;
201     int error = VerifyTestServerCert(callback, &verify_result, &request_handle);
202     ASSERT_EQ(net::ERR_IO_PENDING, error);
203     EXPECT_TRUE(request_handle);
204     error = callback.WaitForResult();
205     EXPECT_EQ(net::OK, error);
206   }
207   EXPECT_TRUE(WasTrustAnchorUsedAndReset());
208
209   // Verify() again with the additional trust anchors will hit the cache.
210   cert_verifier_->SetTrustAnchors(test_ca_cert_list_);
211   {
212     net::CertVerifyResult verify_result;
213     net::TestCompletionCallback callback;
214     net::CertVerifier::RequestHandle request_handle = NULL;
215     int error = VerifyTestServerCert(callback, &verify_result, &request_handle);
216     EXPECT_EQ(net::OK, error);
217   }
218   EXPECT_TRUE(WasTrustAnchorUsedAndReset());
219
220   // Verifying after removing the trust anchors should now fail.
221   cert_verifier_->SetTrustAnchors(net::CertificateList());
222   {
223     net::CertVerifyResult verify_result;
224     net::TestCompletionCallback callback;
225     net::CertVerifier::RequestHandle request_handle = NULL;
226     int error = VerifyTestServerCert(callback, &verify_result, &request_handle);
227     // Note: this hits the cached result from the first Verify() in this test.
228     EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID, error);
229   }
230   // The additional trust anchors were reset, thus |cert_verifier_| should not
231   // signal it's usage anymore.
232   EXPECT_FALSE(WasTrustAnchorUsedAndReset());
233 }
234
235 }  // namespace policy