OLD | NEW |
---|---|
(Empty) | |
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 "net/cert/cert_verify_proc_chromeos.h" | |
6 | |
7 #include "crypto/nss_util.h" | |
8 #include "crypto/nss_util_internal.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_proc_chromeos.h" | |
13 #include "net/cert/cert_verify_result.h" | |
14 #include "net/cert/nss_cert_database_chromeos.h" | |
15 #include "net/test/cert_test_util.h" | |
16 #include "testing/gtest/include/gtest/gtest.h" | |
17 | |
18 namespace net { | |
19 | |
20 class CertVerifyProcChromeOSTest : public testing::Test { | |
21 public: | |
22 CertVerifyProcChromeOSTest() : user_1_("user1"), user_2_("user2") {} | |
23 | |
24 virtual void SetUp() OVERRIDE { | |
25 // Initialize nss_util slots. | |
26 ASSERT_TRUE(user_1_.constructed_successfully()); | |
27 ASSERT_TRUE(user_2_.constructed_successfully()); | |
28 user_1_.FinishInit(); | |
29 user_2_.FinishInit(); | |
30 | |
31 // Create NSSCertDatabaseChromeOS for each user. | |
32 db_1_.reset(new NSSCertDatabaseChromeOS( | |
33 crypto::GetPublicSlotForChromeOSUser(user_1_.username_hash()), | |
34 crypto::GetPrivateSlotForChromeOSUser( | |
35 user_1_.username_hash(), | |
36 base::Callback<void(crypto::ScopedPK11Slot)>()))); | |
37 db_2_.reset(new NSSCertDatabaseChromeOS( | |
38 crypto::GetPublicSlotForChromeOSUser(user_2_.username_hash()), | |
39 crypto::GetPrivateSlotForChromeOSUser( | |
40 user_2_.username_hash(), | |
41 base::Callback<void(crypto::ScopedPK11Slot)>()))); | |
42 | |
43 // Create default verifier and for each user. | |
44 verify_proc_default_ = CertVerifyProc::CreateDefault(); | |
45 verify_proc_1_ = new CertVerifyProcChromeOS( | |
46 crypto::GetPublicSlotForChromeOSUser(user_1_.username_hash()), | |
47 crypto::GetPrivateSlotForChromeOSUser( | |
48 user_1_.username_hash(), | |
49 base::Callback<void(crypto::ScopedPK11Slot)>())); | |
50 verify_proc_2_ = new CertVerifyProcChromeOS( | |
51 crypto::GetPublicSlotForChromeOSUser(user_2_.username_hash()), | |
52 crypto::GetPrivateSlotForChromeOSUser( | |
53 user_2_.username_hash(), | |
54 base::Callback<void(crypto::ScopedPK11Slot)>())); | |
55 | |
56 // Load test cert chains from disk. | |
57 certs_1_ = CreateCertificateListFromFile(GetTestCertsDirectory(), | |
58 "foo-chain1.pem", | |
59 X509Certificate::FORMAT_AUTO); | |
60 ASSERT_EQ(4U, certs_1_.size()); | |
61 | |
62 certs_2_ = CreateCertificateListFromFile(GetTestCertsDirectory(), | |
63 "foo-chain2.pem", | |
64 X509Certificate::FORMAT_AUTO); | |
65 ASSERT_EQ(4U, certs_2_.size()); | |
66 | |
67 // The chains: | |
68 // 1. A (end-entity) -> B -> C -> D (self-signed root) | |
69 // 2. A (end-entity) -> B -> C2 -> E (self-signed root) | |
70 ASSERT_TRUE(certs_1_[0]->Equals(certs_2_[0])); | |
71 ASSERT_TRUE(certs_1_[1]->Equals(certs_2_[1])); | |
72 ASSERT_FALSE(certs_1_[2]->Equals(certs_2_[2])); | |
73 ASSERT_EQ("C CA", certs_1_[2]->subject().common_name); | |
74 ASSERT_EQ("C CA", certs_2_[2]->subject().common_name); | |
75 | |
76 root_1_.push_back(certs_1_.back()); | |
77 root_2_.push_back(certs_2_.back()); | |
78 | |
79 ASSERT_EQ("D Root CA", root_1_[0]->subject().common_name); | |
80 ASSERT_EQ("E Root CA", root_2_[0]->subject().common_name); | |
81 } | |
82 | |
83 int Verify(CertVerifyProc* verify_proc, | |
84 X509Certificate* cert, | |
85 std::string* root_subject_name) { | |
86 int flags = 0; | |
87 CertVerifyResult verify_result; | |
88 CertificateList additional_trust_anchors; | |
89 int error = verify_proc->Verify(cert, | |
90 "127.0.0.1", | |
91 flags, | |
92 NULL, | |
93 additional_trust_anchors, | |
94 &verify_result); | |
95 if (verify_result.verified_cert.get() && | |
96 !verify_result.verified_cert->GetIntermediateCertificates().empty()) { | |
97 X509Certificate::OSCertHandle root = | |
98 verify_result.verified_cert->GetIntermediateCertificates().back(); | |
99 *root_subject_name = root->subjectName; | |
100 } else { | |
101 *root_subject_name = ""; | |
102 } | |
103 return error; | |
104 } | |
105 | |
106 protected: | |
107 crypto::ScopedTestNSSChromeOSUser user_1_; | |
108 crypto::ScopedTestNSSChromeOSUser user_2_; | |
109 scoped_ptr<NSSCertDatabaseChromeOS> db_1_; | |
110 scoped_ptr<NSSCertDatabaseChromeOS> db_2_; | |
111 scoped_refptr<CertVerifyProc> verify_proc_default_; | |
112 scoped_refptr<CertVerifyProc> verify_proc_1_; | |
113 scoped_refptr<CertVerifyProc> verify_proc_2_; | |
114 CertificateList certs_1_; | |
115 CertificateList certs_2_; | |
116 CertificateList root_1_; | |
117 CertificateList root_2_; | |
118 }; | |
119 | |
120 // XXX | |
121 TEST_F(CertVerifyProcChromeOSTest, TestChainVerify) { | |
122 scoped_refptr<X509Certificate> server = certs_1_[0]; | |
123 std::string verify_root; | |
124 // Before either of the root certs have been trusted, all verifications should | |
125 // fail with CERT_AUTHORITY_INVALID. | |
126 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, | |
127 Verify(verify_proc_default_.get(), server.get(), &verify_root)); | |
128 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, | |
129 Verify(verify_proc_1_.get(), server.get(), &verify_root)); | |
130 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, | |
131 Verify(verify_proc_2_.get(), server.get(), &verify_root)); | |
132 | |
133 // Import and trust the D root for user 1. | |
134 NSSCertDatabase::ImportCertFailureList failed; | |
135 EXPECT_TRUE( | |
136 db_1_->ImportCACerts(root_1_, NSSCertDatabase::TRUSTED_SSL, &failed)); | |
137 EXPECT_EQ(0U, failed.size()); | |
138 | |
139 // Imported CA certs are not trusted by default verifier. | |
140 EXPECT_EQ(ERR_CERT_REVOKED, | |
141 Verify(verify_proc_default_.get(), server.get(), &verify_root)); | |
142 // User 1 should now verify successfully through the D root. | |
143 EXPECT_EQ(OK, Verify(verify_proc_1_.get(), server.get(), &verify_root)); | |
144 EXPECT_EQ("CN=D Root CA", verify_root); | |
145 // User 2 should still fail. | |
146 EXPECT_EQ(ERR_CERT_REVOKED, | |
147 Verify(verify_proc_2_.get(), server.get(), &verify_root)); | |
148 | |
149 // Import and trust the E root for user 2. | |
150 failed.clear(); | |
151 EXPECT_TRUE( | |
152 db_2_->ImportCACerts(root_2_, NSSCertDatabase::TRUSTED_SSL, &failed)); | |
153 EXPECT_EQ(0U, failed.size()); | |
154 | |
155 // Imported CA certs are not trusted by default verifier. | |
156 EXPECT_EQ(ERR_CERT_REVOKED, | |
Ryan Sleevi
2014/01/25 01:50:17
wrong error code?? revoked isnt right, should be u
mattm
2014/01/28 04:36:44
Done.
| |
157 Verify(verify_proc_default_.get(), server.get(), &verify_root)); | |
158 // User 1 should still verify successfully through the D root. | |
159 EXPECT_EQ(OK, Verify(verify_proc_1_.get(), server.get(), &verify_root)); | |
160 EXPECT_EQ("CN=D Root CA", verify_root); | |
161 // User 2 should now verify successfully through the E root. | |
162 EXPECT_EQ(OK, Verify(verify_proc_2_.get(), server.get(), &verify_root)); | |
163 EXPECT_EQ("CN=E Root CA", verify_root); | |
164 | |
165 // Delete D root. | |
166 EXPECT_TRUE(db_1_->DeleteCertAndKey(root_1_[0])); | |
167 EXPECT_EQ(ERR_CERT_REVOKED, | |
168 Verify(verify_proc_default_.get(), server.get(), &verify_root)); | |
169 // User 1 should now fail to verify. | |
170 EXPECT_EQ(ERR_CERT_REVOKED, | |
171 Verify(verify_proc_1_.get(), server.get(), &verify_root)); | |
172 // User 2 should still verify successfully through the E root. | |
173 EXPECT_EQ(OK, Verify(verify_proc_2_.get(), server.get(), &verify_root)); | |
174 EXPECT_EQ("CN=E Root CA", verify_root); | |
175 | |
176 // Delete E root. | |
177 EXPECT_TRUE(db_2_->DeleteCertAndKey(root_2_[0])); | |
178 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, | |
179 Verify(verify_proc_default_.get(), server.get(), &verify_root)); | |
180 // User 1 should still fail to verify. | |
181 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, | |
182 Verify(verify_proc_1_.get(), server.get(), &verify_root)); | |
183 // User 2 should now fail to verify. | |
184 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, | |
185 Verify(verify_proc_2_.get(), server.get(), &verify_root)); | |
186 } | |
187 | |
188 class CertVerifyProcChromeOSOrderingTest | |
189 : public CertVerifyProcChromeOSTest, | |
190 public ::testing::WithParamInterface< | |
191 std::tr1::tuple<bool, int, std::string> > {}; | |
192 | |
193 TEST_P(CertVerifyProcChromeOSOrderingTest, TrustThenVerify) { | |
194 const ParamType& param = GetParam(); | |
195 const bool verify_first = std::tr1::get<0>(param); | |
196 const int trust_bitmask = std::tr1::get<1>(param); | |
197 const std::string test_order = std::tr1::get<2>(param); | |
198 DVLOG(1) << "verify_first: " << verify_first | |
199 << " trust_bitmask: " << trust_bitmask | |
200 << " test_order: " << test_order; | |
201 | |
202 scoped_refptr<X509Certificate> server = certs_1_[0]; | |
203 std::string verify_root; | |
204 | |
205 if (verify_first) { | |
206 // Before either of the root certs have been trusted, all verifications | |
207 // should fail with CERT_AUTHORITY_INVALID. | |
208 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, | |
209 Verify(verify_proc_default_.get(), server.get(), &verify_root)); | |
210 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, | |
211 Verify(verify_proc_1_.get(), server.get(), &verify_root)); | |
212 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, | |
213 Verify(verify_proc_2_.get(), server.get(), &verify_root)); | |
214 } | |
215 | |
216 int expected_fail_value = | |
217 trust_bitmask ? ERR_CERT_REVOKED : ERR_CERT_AUTHORITY_INVALID; | |
218 int expected_user1_result = expected_fail_value; | |
219 int expected_user2_result = expected_fail_value; | |
220 | |
221 if (trust_bitmask & 1) { | |
222 expected_user1_result = OK; | |
223 // Import and trust the D root for user 1. | |
224 NSSCertDatabase::ImportCertFailureList failed; | |
225 EXPECT_TRUE( | |
226 db_1_->ImportCACerts(root_1_, NSSCertDatabase::TRUSTED_SSL, &failed)); | |
227 EXPECT_EQ(0U, failed.size()); | |
228 } | |
229 | |
230 if (trust_bitmask & 2) { | |
231 expected_user2_result = OK; | |
232 // Import and trust the E root for user 2. | |
233 NSSCertDatabase::ImportCertFailureList failed; | |
234 EXPECT_TRUE( | |
235 db_2_->ImportCACerts(root_2_, NSSCertDatabase::TRUSTED_SSL, &failed)); | |
236 EXPECT_EQ(0U, failed.size()); | |
237 } | |
238 | |
239 // Repeat the tests twice, they should return the same each time. | |
240 for (int i = 0; i < 2; ++i) { | |
241 SCOPED_TRACE(i); | |
242 for (std::string::const_iterator j = test_order.begin(); | |
243 j != test_order.end(); | |
244 ++j) { | |
245 switch (*j) { | |
246 case 'd': | |
247 // Default verifier should always fail. | |
248 EXPECT_EQ( | |
249 expected_fail_value, | |
250 Verify(verify_proc_default_.get(), server.get(), &verify_root)); | |
251 break; | |
252 case '1': | |
253 EXPECT_EQ(expected_user1_result, | |
254 Verify(verify_proc_1_.get(), server.get(), &verify_root)); | |
255 if (expected_user1_result == OK) | |
256 EXPECT_EQ("CN=D Root CA", verify_root); | |
257 break; | |
258 case '2': | |
259 EXPECT_EQ(expected_user2_result, | |
260 Verify(verify_proc_2_.get(), server.get(), &verify_root)); | |
261 if (expected_user2_result == OK) | |
262 EXPECT_EQ("CN=E Root CA", verify_root); | |
263 break; | |
264 default: | |
265 ASSERT_TRUE(false); | |
266 } | |
267 } | |
268 } | |
269 } | |
270 | |
271 INSTANTIATE_TEST_CASE_P( | |
272 Variations, | |
273 CertVerifyProcChromeOSOrderingTest, | |
274 ::testing::Combine( | |
275 ::testing::Bool(), | |
276 ::testing::Range(0, 1 << 2), | |
277 ::testing::Values("d12", "d21", "1d2", "12d", "2d1", "21d"))); | |
278 | |
279 } // namespace net | |
OLD | NEW |