Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / net / cert_verify_proc_chromeos_unittest.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/net/cert_verify_proc_chromeos.h"
6
7 #include "crypto/nss_util_internal.h"
8 #include "crypto/scoped_test_nss_chromeos_user.h"
9 #include "net/base/net_errors.h"
10 #include "net/base/test_data_directory.h"
11 #include "net/cert/cert_verify_proc.h"
12 #include "net/cert/cert_verify_result.h"
13 #include "net/cert/nss_cert_database_chromeos.h"
14 #include "net/test/cert_test_util.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 namespace chromeos {
18
19 class CertVerifyProcChromeOSTest : public testing::Test {
20  public:
21   CertVerifyProcChromeOSTest() : user_1_("user1"), user_2_("user2") {}
22
23   virtual void SetUp() OVERRIDE {
24     // Initialize nss_util slots.
25     ASSERT_TRUE(user_1_.constructed_successfully());
26     ASSERT_TRUE(user_2_.constructed_successfully());
27     user_1_.FinishInit();
28     user_2_.FinishInit();
29
30     // Create NSSCertDatabaseChromeOS for each user.
31     db_1_.reset(new net::NSSCertDatabaseChromeOS(
32         crypto::GetPublicSlotForChromeOSUser(user_1_.username_hash()),
33         crypto::GetPrivateSlotForChromeOSUser(
34             user_1_.username_hash(),
35             base::Callback<void(crypto::ScopedPK11Slot)>())));
36     db_2_.reset(new net::NSSCertDatabaseChromeOS(
37         crypto::GetPublicSlotForChromeOSUser(user_2_.username_hash()),
38         crypto::GetPrivateSlotForChromeOSUser(
39             user_2_.username_hash(),
40             base::Callback<void(crypto::ScopedPK11Slot)>())));
41
42     // Create default verifier and for each user.
43     verify_proc_default_ = new CertVerifyProcChromeOS();
44     verify_proc_1_ = new CertVerifyProcChromeOS(db_1_->GetPublicSlot());
45     verify_proc_2_ = new CertVerifyProcChromeOS(db_2_->GetPublicSlot());
46
47     // Load test cert chains from disk.
48     certs_1_ =
49         net::CreateCertificateListFromFile(net::GetTestCertsDirectory(),
50                                            "multi-root-chain1.pem",
51                                            net::X509Certificate::FORMAT_AUTO);
52     ASSERT_EQ(4U, certs_1_.size());
53
54     certs_2_ =
55         net::CreateCertificateListFromFile(net::GetTestCertsDirectory(),
56                                            "multi-root-chain2.pem",
57                                            net::X509Certificate::FORMAT_AUTO);
58     ASSERT_EQ(4U, certs_2_.size());
59
60     // The chains:
61     //   1. A (end-entity) -> B -> C -> D (self-signed root)
62     //   2. A (end-entity) -> B -> C2 -> E (self-signed root)
63     ASSERT_TRUE(certs_1_[0]->Equals(certs_2_[0].get()));
64     ASSERT_TRUE(certs_1_[1]->Equals(certs_2_[1].get()));
65     ASSERT_FALSE(certs_1_[2]->Equals(certs_2_[2].get()));
66     ASSERT_EQ("C CA", certs_1_[2]->subject().common_name);
67     ASSERT_EQ("C CA", certs_2_[2]->subject().common_name);
68
69     root_1_.push_back(certs_1_.back());
70     root_2_.push_back(certs_2_.back());
71
72     ASSERT_EQ("D Root CA", root_1_[0]->subject().common_name);
73     ASSERT_EQ("E Root CA", root_2_[0]->subject().common_name);
74   }
75
76   int VerifyWithAdditionalTrustAnchors(
77       net::CertVerifyProc* verify_proc,
78       const net::CertificateList& additional_trust_anchors,
79       net::X509Certificate* cert,
80       std::string* root_subject_name) {
81     int flags = 0;
82     net::CertVerifyResult verify_result;
83     int error = verify_proc->Verify(cert,
84                                     "127.0.0.1",
85                                     flags,
86                                     NULL,
87                                     additional_trust_anchors,
88                                     &verify_result);
89     if (verify_result.verified_cert.get() &&
90         !verify_result.verified_cert->GetIntermediateCertificates().empty()) {
91       net::X509Certificate::OSCertHandle root =
92           verify_result.verified_cert->GetIntermediateCertificates().back();
93       root_subject_name->assign(root->subjectName);
94     } else {
95       root_subject_name->clear();
96     }
97     return error;
98   }
99
100   int Verify(net::CertVerifyProc* verify_proc,
101              net::X509Certificate* cert,
102              std::string* root_subject_name) {
103     net::CertificateList additional_trust_anchors;
104     return VerifyWithAdditionalTrustAnchors(
105         verify_proc, additional_trust_anchors, cert, root_subject_name);
106   }
107
108  protected:
109   crypto::ScopedTestNSSChromeOSUser user_1_;
110   crypto::ScopedTestNSSChromeOSUser user_2_;
111   scoped_ptr<net::NSSCertDatabaseChromeOS> db_1_;
112   scoped_ptr<net::NSSCertDatabaseChromeOS> db_2_;
113   scoped_refptr<net::CertVerifyProc> verify_proc_default_;
114   scoped_refptr<net::CertVerifyProc> verify_proc_1_;
115   scoped_refptr<net::CertVerifyProc> verify_proc_2_;
116   net::CertificateList certs_1_;
117   net::CertificateList certs_2_;
118   net::CertificateList root_1_;
119   net::CertificateList root_2_;
120 };
121
122 // Test that the CertVerifyProcChromeOS doesn't trusts roots that are in other
123 // user's slots or that have been deleted, and that verifying done by one user
124 // doesn't affect verifications done by others.
125 TEST_F(CertVerifyProcChromeOSTest, TestChainVerify) {
126   scoped_refptr<net::X509Certificate> server = certs_1_[0];
127   std::string verify_root;
128   // Before either of the root certs have been trusted, all verifications should
129   // fail with CERT_AUTHORITY_INVALID.
130   EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID,
131             Verify(verify_proc_default_.get(), server.get(), &verify_root));
132   EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID,
133             Verify(verify_proc_1_.get(), server.get(), &verify_root));
134   EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID,
135             Verify(verify_proc_2_.get(), server.get(), &verify_root));
136
137   // Import and trust the D root for user 1.
138   net::NSSCertDatabase::ImportCertFailureList failed;
139   EXPECT_TRUE(db_1_->ImportCACerts(
140       root_1_, net::NSSCertDatabase::TRUSTED_SSL, &failed));
141   EXPECT_EQ(0U, failed.size());
142
143   // Imported CA certs are not trusted by default verifier.
144   EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID,
145             Verify(verify_proc_default_.get(), server.get(), &verify_root));
146   // User 1 should now verify successfully through the D root.
147   EXPECT_EQ(net::OK, Verify(verify_proc_1_.get(), server.get(), &verify_root));
148   EXPECT_EQ("CN=D Root CA", verify_root);
149   // User 2 should still fail.
150   EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID,
151             Verify(verify_proc_2_.get(), server.get(), &verify_root));
152
153   // Import and trust the E root for user 2.
154   failed.clear();
155   EXPECT_TRUE(db_2_->ImportCACerts(
156       root_2_, net::NSSCertDatabase::TRUSTED_SSL, &failed));
157   EXPECT_EQ(0U, failed.size());
158
159   // Imported CA certs are not trusted by default verifier.
160   EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID,
161             Verify(verify_proc_default_.get(), server.get(), &verify_root));
162   // User 1 should still verify successfully through the D root.
163   EXPECT_EQ(net::OK, Verify(verify_proc_1_.get(), server.get(), &verify_root));
164   EXPECT_EQ("CN=D Root CA", verify_root);
165   // User 2 should now verify successfully through the E root.
166   EXPECT_EQ(net::OK, Verify(verify_proc_2_.get(), server.get(), &verify_root));
167   EXPECT_EQ("CN=E Root CA", verify_root);
168
169   // Delete D root.
170   EXPECT_TRUE(db_1_->DeleteCertAndKey(root_1_[0].get()));
171   EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID,
172             Verify(verify_proc_default_.get(), server.get(), &verify_root));
173   // User 1 should now fail to verify.
174   EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID,
175             Verify(verify_proc_1_.get(), server.get(), &verify_root));
176   // User 2 should still verify successfully through the E root.
177   EXPECT_EQ(net::OK, Verify(verify_proc_2_.get(), server.get(), &verify_root));
178   EXPECT_EQ("CN=E Root CA", verify_root);
179
180   // Delete E root.
181   EXPECT_TRUE(db_2_->DeleteCertAndKey(root_2_[0].get()));
182   EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID,
183             Verify(verify_proc_default_.get(), server.get(), &verify_root));
184   // User 1 should still fail to verify.
185   EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID,
186             Verify(verify_proc_1_.get(), server.get(), &verify_root));
187   // User 2 should now fail to verify.
188   EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID,
189             Verify(verify_proc_2_.get(), server.get(), &verify_root));
190 }
191
192 // Test that roots specified through additional_trust_anchors are trusted for
193 // that verification, and that there is not any caching that affects later
194 // verifications.
195 TEST_F(CertVerifyProcChromeOSTest, TestAdditionalTrustAnchors) {
196   EXPECT_TRUE(verify_proc_default_->SupportsAdditionalTrustAnchors());
197   EXPECT_TRUE(verify_proc_1_->SupportsAdditionalTrustAnchors());
198
199   scoped_refptr<net::X509Certificate> server = certs_1_[0];
200   std::string verify_root;
201   net::CertificateList additional_trust_anchors;
202
203   // Before either of the root certs have been trusted, all verifications should
204   // fail with CERT_AUTHORITY_INVALID.
205   EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID,
206             VerifyWithAdditionalTrustAnchors(verify_proc_default_.get(),
207                                              additional_trust_anchors,
208                                              server.get(),
209                                              &verify_root));
210   EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID,
211             VerifyWithAdditionalTrustAnchors(verify_proc_1_.get(),
212                                              additional_trust_anchors,
213                                              server.get(),
214                                              &verify_root));
215
216   // Use D Root CA as additional trust anchor. Verifications should succeed now.
217   additional_trust_anchors.push_back(root_1_[0]);
218   EXPECT_EQ(net::OK,
219             VerifyWithAdditionalTrustAnchors(verify_proc_default_.get(),
220                                              additional_trust_anchors,
221                                              server.get(),
222                                              &verify_root));
223   EXPECT_EQ("CN=D Root CA", verify_root);
224   EXPECT_EQ(net::OK,
225             VerifyWithAdditionalTrustAnchors(verify_proc_1_.get(),
226                                              additional_trust_anchors,
227                                              server.get(),
228                                              &verify_root));
229   EXPECT_EQ("CN=D Root CA", verify_root);
230   // User 2 should still fail.
231   EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID,
232             VerifyWithAdditionalTrustAnchors(verify_proc_2_.get(),
233                                              net::CertificateList(),
234                                              server.get(),
235                                              &verify_root));
236
237   // Without additional trust anchors, verification should fail again.
238   additional_trust_anchors.clear();
239   EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID,
240             VerifyWithAdditionalTrustAnchors(verify_proc_default_.get(),
241                                              additional_trust_anchors,
242                                              server.get(),
243                                              &verify_root));
244   EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID,
245             VerifyWithAdditionalTrustAnchors(verify_proc_1_.get(),
246                                              additional_trust_anchors,
247                                              server.get(),
248                                              &verify_root));
249
250   // Import and trust the D Root CA for user 2.
251   net::CertificateList roots;
252   roots.push_back(root_1_[0]);
253   net::NSSCertDatabase::ImportCertFailureList failed;
254   EXPECT_TRUE(
255       db_2_->ImportCACerts(roots, net::NSSCertDatabase::TRUSTED_SSL, &failed));
256   EXPECT_EQ(0U, failed.size());
257
258   // Use D Root CA as additional trust anchor. Verifications should still
259   // succeed even if the cert is trusted by a different profile.
260   additional_trust_anchors.push_back(root_1_[0]);
261   EXPECT_EQ(net::OK,
262             VerifyWithAdditionalTrustAnchors(verify_proc_default_.get(),
263                                              additional_trust_anchors,
264                                              server.get(),
265                                              &verify_root));
266   EXPECT_EQ("CN=D Root CA", verify_root);
267   EXPECT_EQ(net::OK,
268             VerifyWithAdditionalTrustAnchors(verify_proc_1_.get(),
269                                              additional_trust_anchors,
270                                              server.get(),
271                                              &verify_root));
272   EXPECT_EQ("CN=D Root CA", verify_root);
273   EXPECT_EQ(net::OK,
274             VerifyWithAdditionalTrustAnchors(verify_proc_2_.get(),
275                                              additional_trust_anchors,
276                                              server.get(),
277                                              &verify_root));
278   EXPECT_EQ("CN=D Root CA", verify_root);
279 }
280
281 class CertVerifyProcChromeOSOrderingTest
282     : public CertVerifyProcChromeOSTest,
283       public ::testing::WithParamInterface<
284           std::tr1::tuple<bool, int, std::string> > {};
285
286 // Test a variety of different combinations of (maybe) verifying / (maybe)
287 // importing / verifying again, to try to find any cases where caching might
288 // affect the results.
289 // http://crbug.com/396501
290 TEST_P(CertVerifyProcChromeOSOrderingTest, DISABLED_TrustThenVerify) {
291   const ParamType& param = GetParam();
292   const bool verify_first = std::tr1::get<0>(param);
293   const int trust_bitmask = std::tr1::get<1>(param);
294   const std::string test_order = std::tr1::get<2>(param);
295   DVLOG(1) << "verify_first: " << verify_first
296            << " trust_bitmask: " << trust_bitmask
297            << " test_order: " << test_order;
298
299   scoped_refptr<net::X509Certificate> server = certs_1_[0];
300   std::string verify_root;
301
302   if (verify_first) {
303     // Before either of the root certs have been trusted, all verifications
304     // should fail with CERT_AUTHORITY_INVALID.
305     EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID,
306               Verify(verify_proc_default_.get(), server.get(), &verify_root));
307     EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID,
308               Verify(verify_proc_1_.get(), server.get(), &verify_root));
309     EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID,
310               Verify(verify_proc_2_.get(), server.get(), &verify_root));
311   }
312
313   int expected_user1_result = net::ERR_CERT_AUTHORITY_INVALID;
314   int expected_user2_result = net::ERR_CERT_AUTHORITY_INVALID;
315
316   if (trust_bitmask & 1) {
317     expected_user1_result = net::OK;
318     // Import and trust the D root for user 1.
319     net::NSSCertDatabase::ImportCertFailureList failed;
320     EXPECT_TRUE(db_1_->ImportCACerts(
321         root_1_, net::NSSCertDatabase::TRUSTED_SSL, &failed));
322     EXPECT_EQ(0U, failed.size());
323     for (size_t i = 0; i < failed.size(); ++i) {
324       LOG(ERROR) << "import fail " << failed[i].net_error << " for "
325                  << failed[i].certificate->subject().GetDisplayName();
326     }
327   }
328
329   if (trust_bitmask & 2) {
330     expected_user2_result = net::OK;
331     // Import and trust the E root for user 2.
332     net::NSSCertDatabase::ImportCertFailureList failed;
333     EXPECT_TRUE(db_2_->ImportCACerts(
334         root_2_, net::NSSCertDatabase::TRUSTED_SSL, &failed));
335     EXPECT_EQ(0U, failed.size());
336     for (size_t i = 0; i < failed.size(); ++i) {
337       LOG(ERROR) << "import fail " << failed[i].net_error << " for "
338                  << failed[i].certificate->subject().GetDisplayName();
339     }
340   }
341
342   // Repeat the tests twice, they should return the same each time.
343   for (int i = 0; i < 2; ++i) {
344     SCOPED_TRACE(i);
345     for (std::string::const_iterator j = test_order.begin();
346          j != test_order.end();
347          ++j) {
348       switch (*j) {
349         case 'd':
350           // Default verifier should always fail.
351           EXPECT_EQ(
352               net::ERR_CERT_AUTHORITY_INVALID,
353               Verify(verify_proc_default_.get(), server.get(), &verify_root));
354           break;
355         case '1':
356           EXPECT_EQ(expected_user1_result,
357                     Verify(verify_proc_1_.get(), server.get(), &verify_root));
358           if (expected_user1_result == net::OK)
359             EXPECT_EQ("CN=D Root CA", verify_root);
360           break;
361         case '2':
362           EXPECT_EQ(expected_user2_result,
363                     Verify(verify_proc_2_.get(), server.get(), &verify_root));
364           if (expected_user2_result == net::OK)
365             EXPECT_EQ("CN=E Root CA", verify_root);
366           break;
367         default:
368           FAIL();
369       }
370     }
371   }
372 }
373
374 INSTANTIATE_TEST_CASE_P(
375     Variations,
376     CertVerifyProcChromeOSOrderingTest,
377     ::testing::Combine(
378         ::testing::Bool(),
379         ::testing::Range(0, 1 << 2),
380         ::testing::Values("d12", "d21", "1d2", "12d", "2d1", "21d")));
381
382 }  // namespace chromeos