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.
5 #include "chrome/browser/chromeos/net/cert_verify_proc_chromeos.h"
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"
19 class CertVerifyProcChromeOSTest
: public testing::Test
{
21 CertVerifyProcChromeOSTest() : user_1_("user1"), user_2_("user2") {}
23 void SetUp() override
{
24 // Initialize nss_util slots.
25 ASSERT_TRUE(user_1_
.constructed_successfully());
26 ASSERT_TRUE(user_2_
.constructed_successfully());
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
)>())));
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());
47 // Load test cert chains from disk.
49 net::CreateCertificateListFromFile(net::GetTestCertsDirectory(),
50 "multi-root-chain1.pem",
51 net::X509Certificate::FORMAT_AUTO
);
52 ASSERT_EQ(4U, certs_1_
.size());
55 net::CreateCertificateListFromFile(net::GetTestCertsDirectory(),
56 "multi-root-chain2.pem",
57 net::X509Certificate::FORMAT_AUTO
);
58 ASSERT_EQ(4U, certs_2_
.size());
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
);
69 root_1_
.push_back(certs_1_
.back());
70 root_2_
.push_back(certs_2_
.back());
72 ASSERT_EQ("D Root CA", root_1_
[0]->subject().common_name
);
73 ASSERT_EQ("E Root CA", root_2_
[0]->subject().common_name
);
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
) {
82 net::CertVerifyResult verify_result
;
84 verify_proc
->Verify(cert
, "127.0.0.1", std::string(), flags
, NULL
,
85 additional_trust_anchors
, &verify_result
);
86 if (verify_result
.verified_cert
.get() &&
87 !verify_result
.verified_cert
->GetIntermediateCertificates().empty()) {
88 net::X509Certificate::OSCertHandle root
=
89 verify_result
.verified_cert
->GetIntermediateCertificates().back();
90 root_subject_name
->assign(root
->subjectName
);
92 root_subject_name
->clear();
97 int Verify(net::CertVerifyProc
* verify_proc
,
98 net::X509Certificate
* cert
,
99 std::string
* root_subject_name
) {
100 net::CertificateList additional_trust_anchors
;
101 return VerifyWithAdditionalTrustAnchors(
102 verify_proc
, additional_trust_anchors
, cert
, root_subject_name
);
106 crypto::ScopedTestNSSChromeOSUser user_1_
;
107 crypto::ScopedTestNSSChromeOSUser user_2_
;
108 scoped_ptr
<net::NSSCertDatabaseChromeOS
> db_1_
;
109 scoped_ptr
<net::NSSCertDatabaseChromeOS
> db_2_
;
110 scoped_refptr
<net::CertVerifyProc
> verify_proc_default_
;
111 scoped_refptr
<net::CertVerifyProc
> verify_proc_1_
;
112 scoped_refptr
<net::CertVerifyProc
> verify_proc_2_
;
113 net::CertificateList certs_1_
;
114 net::CertificateList certs_2_
;
115 net::CertificateList root_1_
;
116 net::CertificateList root_2_
;
119 // Test that the CertVerifyProcChromeOS doesn't trusts roots that are in other
120 // user's slots or that have been deleted, and that verifying done by one user
121 // doesn't affect verifications done by others.
122 TEST_F(CertVerifyProcChromeOSTest
, TestChainVerify
) {
123 scoped_refptr
<net::X509Certificate
> server
= certs_1_
[0];
124 std::string verify_root
;
125 // Before either of the root certs have been trusted, all verifications should
126 // fail with CERT_AUTHORITY_INVALID.
127 EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID
,
128 Verify(verify_proc_default_
.get(), server
.get(), &verify_root
));
129 EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID
,
130 Verify(verify_proc_1_
.get(), server
.get(), &verify_root
));
131 EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID
,
132 Verify(verify_proc_2_
.get(), server
.get(), &verify_root
));
134 // Import and trust the D root for user 1.
135 net::NSSCertDatabase::ImportCertFailureList failed
;
136 EXPECT_TRUE(db_1_
->ImportCACerts(
137 root_1_
, net::NSSCertDatabase::TRUSTED_SSL
, &failed
));
138 EXPECT_EQ(0U, failed
.size());
140 // Imported CA certs are not trusted by default verifier.
141 EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID
,
142 Verify(verify_proc_default_
.get(), server
.get(), &verify_root
));
143 // User 1 should now verify successfully through the D root.
144 EXPECT_EQ(net::OK
, Verify(verify_proc_1_
.get(), server
.get(), &verify_root
));
145 EXPECT_EQ("CN=D Root CA", verify_root
);
146 // User 2 should still fail.
147 EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID
,
148 Verify(verify_proc_2_
.get(), server
.get(), &verify_root
));
150 // Import and trust the E root for user 2.
152 EXPECT_TRUE(db_2_
->ImportCACerts(
153 root_2_
, net::NSSCertDatabase::TRUSTED_SSL
, &failed
));
154 EXPECT_EQ(0U, failed
.size());
156 // Imported CA certs are not trusted by default verifier.
157 EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID
,
158 Verify(verify_proc_default_
.get(), server
.get(), &verify_root
));
159 // User 1 should still verify successfully through the D root.
160 EXPECT_EQ(net::OK
, Verify(verify_proc_1_
.get(), server
.get(), &verify_root
));
161 EXPECT_EQ("CN=D Root CA", verify_root
);
162 // User 2 should now verify successfully through the E root.
163 EXPECT_EQ(net::OK
, Verify(verify_proc_2_
.get(), server
.get(), &verify_root
));
164 EXPECT_EQ("CN=E Root CA", verify_root
);
167 EXPECT_TRUE(db_1_
->DeleteCertAndKey(root_1_
[0].get()));
168 EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID
,
169 Verify(verify_proc_default_
.get(), server
.get(), &verify_root
));
170 // User 1 should now fail to verify.
171 EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID
,
172 Verify(verify_proc_1_
.get(), server
.get(), &verify_root
));
173 // User 2 should still verify successfully through the E root.
174 EXPECT_EQ(net::OK
, Verify(verify_proc_2_
.get(), server
.get(), &verify_root
));
175 EXPECT_EQ("CN=E Root CA", verify_root
);
178 EXPECT_TRUE(db_2_
->DeleteCertAndKey(root_2_
[0].get()));
179 EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID
,
180 Verify(verify_proc_default_
.get(), server
.get(), &verify_root
));
181 // User 1 should still fail to verify.
182 EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID
,
183 Verify(verify_proc_1_
.get(), server
.get(), &verify_root
));
184 // User 2 should now fail to verify.
185 EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID
,
186 Verify(verify_proc_2_
.get(), server
.get(), &verify_root
));
189 // Test that roots specified through additional_trust_anchors are trusted for
190 // that verification, and that there is not any caching that affects later
192 TEST_F(CertVerifyProcChromeOSTest
, TestAdditionalTrustAnchors
) {
193 EXPECT_TRUE(verify_proc_default_
->SupportsAdditionalTrustAnchors());
194 EXPECT_TRUE(verify_proc_1_
->SupportsAdditionalTrustAnchors());
196 scoped_refptr
<net::X509Certificate
> server
= certs_1_
[0];
197 std::string verify_root
;
198 net::CertificateList additional_trust_anchors
;
200 // Before either of the root certs have been trusted, all verifications should
201 // fail with CERT_AUTHORITY_INVALID.
202 EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID
,
203 VerifyWithAdditionalTrustAnchors(verify_proc_default_
.get(),
204 additional_trust_anchors
,
207 EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID
,
208 VerifyWithAdditionalTrustAnchors(verify_proc_1_
.get(),
209 additional_trust_anchors
,
213 // Use D Root CA as additional trust anchor. Verifications should succeed now.
214 additional_trust_anchors
.push_back(root_1_
[0]);
216 VerifyWithAdditionalTrustAnchors(verify_proc_default_
.get(),
217 additional_trust_anchors
,
220 EXPECT_EQ("CN=D Root CA", verify_root
);
222 VerifyWithAdditionalTrustAnchors(verify_proc_1_
.get(),
223 additional_trust_anchors
,
226 EXPECT_EQ("CN=D Root CA", verify_root
);
227 // User 2 should still fail.
228 EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID
,
229 VerifyWithAdditionalTrustAnchors(verify_proc_2_
.get(),
230 net::CertificateList(),
234 // Without additional trust anchors, verification should fail again.
235 additional_trust_anchors
.clear();
236 EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID
,
237 VerifyWithAdditionalTrustAnchors(verify_proc_default_
.get(),
238 additional_trust_anchors
,
241 EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID
,
242 VerifyWithAdditionalTrustAnchors(verify_proc_1_
.get(),
243 additional_trust_anchors
,
247 // Import and trust the D Root CA for user 2.
248 net::CertificateList roots
;
249 roots
.push_back(root_1_
[0]);
250 net::NSSCertDatabase::ImportCertFailureList failed
;
252 db_2_
->ImportCACerts(roots
, net::NSSCertDatabase::TRUSTED_SSL
, &failed
));
253 EXPECT_EQ(0U, failed
.size());
255 // Use D Root CA as additional trust anchor. Verifications should still
256 // succeed even if the cert is trusted by a different profile.
257 additional_trust_anchors
.push_back(root_1_
[0]);
259 VerifyWithAdditionalTrustAnchors(verify_proc_default_
.get(),
260 additional_trust_anchors
,
263 EXPECT_EQ("CN=D Root CA", verify_root
);
265 VerifyWithAdditionalTrustAnchors(verify_proc_1_
.get(),
266 additional_trust_anchors
,
269 EXPECT_EQ("CN=D Root CA", verify_root
);
271 VerifyWithAdditionalTrustAnchors(verify_proc_2_
.get(),
272 additional_trust_anchors
,
275 EXPECT_EQ("CN=D Root CA", verify_root
);
278 class CertVerifyProcChromeOSOrderingTest
279 : public CertVerifyProcChromeOSTest
,
280 public ::testing::WithParamInterface
<
281 std::tr1::tuple
<bool, int, std::string
> > {};
283 // Test a variety of different combinations of (maybe) verifying / (maybe)
284 // importing / verifying again, to try to find any cases where caching might
285 // affect the results.
286 // http://crbug.com/396501
287 TEST_P(CertVerifyProcChromeOSOrderingTest
, DISABLED_TrustThenVerify
) {
288 const ParamType
& param
= GetParam();
289 const bool verify_first
= std::tr1::get
<0>(param
);
290 const int trust_bitmask
= std::tr1::get
<1>(param
);
291 const std::string test_order
= std::tr1::get
<2>(param
);
292 DVLOG(1) << "verify_first: " << verify_first
293 << " trust_bitmask: " << trust_bitmask
294 << " test_order: " << test_order
;
296 scoped_refptr
<net::X509Certificate
> server
= certs_1_
[0];
297 std::string verify_root
;
300 // Before either of the root certs have been trusted, all verifications
301 // should fail with CERT_AUTHORITY_INVALID.
302 EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID
,
303 Verify(verify_proc_default_
.get(), server
.get(), &verify_root
));
304 EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID
,
305 Verify(verify_proc_1_
.get(), server
.get(), &verify_root
));
306 EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID
,
307 Verify(verify_proc_2_
.get(), server
.get(), &verify_root
));
310 int expected_user1_result
= net::ERR_CERT_AUTHORITY_INVALID
;
311 int expected_user2_result
= net::ERR_CERT_AUTHORITY_INVALID
;
313 if (trust_bitmask
& 1) {
314 expected_user1_result
= net::OK
;
315 // Import and trust the D root for user 1.
316 net::NSSCertDatabase::ImportCertFailureList failed
;
317 EXPECT_TRUE(db_1_
->ImportCACerts(
318 root_1_
, net::NSSCertDatabase::TRUSTED_SSL
, &failed
));
319 EXPECT_EQ(0U, failed
.size());
320 for (size_t i
= 0; i
< failed
.size(); ++i
) {
321 LOG(ERROR
) << "import fail " << failed
[i
].net_error
<< " for "
322 << failed
[i
].certificate
->subject().GetDisplayName();
326 if (trust_bitmask
& 2) {
327 expected_user2_result
= net::OK
;
328 // Import and trust the E root for user 2.
329 net::NSSCertDatabase::ImportCertFailureList failed
;
330 EXPECT_TRUE(db_2_
->ImportCACerts(
331 root_2_
, net::NSSCertDatabase::TRUSTED_SSL
, &failed
));
332 EXPECT_EQ(0U, failed
.size());
333 for (size_t i
= 0; i
< failed
.size(); ++i
) {
334 LOG(ERROR
) << "import fail " << failed
[i
].net_error
<< " for "
335 << failed
[i
].certificate
->subject().GetDisplayName();
339 // Repeat the tests twice, they should return the same each time.
340 for (int i
= 0; i
< 2; ++i
) {
342 for (std::string::const_iterator j
= test_order
.begin();
343 j
!= test_order
.end();
347 // Default verifier should always fail.
349 net::ERR_CERT_AUTHORITY_INVALID
,
350 Verify(verify_proc_default_
.get(), server
.get(), &verify_root
));
353 EXPECT_EQ(expected_user1_result
,
354 Verify(verify_proc_1_
.get(), server
.get(), &verify_root
));
355 if (expected_user1_result
== net::OK
)
356 EXPECT_EQ("CN=D Root CA", verify_root
);
359 EXPECT_EQ(expected_user2_result
,
360 Verify(verify_proc_2_
.get(), server
.get(), &verify_root
));
361 if (expected_user2_result
== net::OK
)
362 EXPECT_EQ("CN=E Root CA", verify_root
);
371 INSTANTIATE_TEST_CASE_P(
373 CertVerifyProcChromeOSOrderingTest
,
376 ::testing::Range(0, 1 << 2),
377 ::testing::Values("d12", "d21", "1d2", "12d", "2d1", "21d")));
379 } // namespace chromeos