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.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_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])); 64 ASSERT_TRUE(certs_1_[1]->Equals(certs_2_[1])); 65 ASSERT_FALSE(certs_1_[2]->Equals(certs_2_[2])); 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])); 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])); 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 TEST_P(CertVerifyProcChromeOSOrderingTest, TrustThenVerify) { 290 const ParamType& param = GetParam(); 291 const bool verify_first = std::tr1::get<0>(param); 292 const int trust_bitmask = std::tr1::get<1>(param); 293 const std::string test_order = std::tr1::get<2>(param); 294 DVLOG(1) << "verify_first: " << verify_first 295 << " trust_bitmask: " << trust_bitmask 296 << " test_order: " << test_order; 297 298 scoped_refptr<net::X509Certificate> server = certs_1_[0]; 299 std::string verify_root; 300 301 if (verify_first) { 302 // Before either of the root certs have been trusted, all verifications 303 // should fail with CERT_AUTHORITY_INVALID. 304 EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID, 305 Verify(verify_proc_default_.get(), server.get(), &verify_root)); 306 EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID, 307 Verify(verify_proc_1_.get(), server.get(), &verify_root)); 308 EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID, 309 Verify(verify_proc_2_.get(), server.get(), &verify_root)); 310 } 311 312 int expected_user1_result = net::ERR_CERT_AUTHORITY_INVALID; 313 int expected_user2_result = net::ERR_CERT_AUTHORITY_INVALID; 314 315 if (trust_bitmask & 1) { 316 expected_user1_result = net::OK; 317 // Import and trust the D root for user 1. 318 net::NSSCertDatabase::ImportCertFailureList failed; 319 EXPECT_TRUE(db_1_->ImportCACerts( 320 root_1_, net::NSSCertDatabase::TRUSTED_SSL, &failed)); 321 EXPECT_EQ(0U, failed.size()); 322 for (size_t i = 0; i < failed.size(); ++i) { 323 LOG(ERROR) << "import fail " << failed[i].net_error << " for " 324 << failed[i].certificate->subject().GetDisplayName(); 325 } 326 } 327 328 if (trust_bitmask & 2) { 329 expected_user2_result = net::OK; 330 // Import and trust the E root for user 2. 331 net::NSSCertDatabase::ImportCertFailureList failed; 332 EXPECT_TRUE(db_2_->ImportCACerts( 333 root_2_, net::NSSCertDatabase::TRUSTED_SSL, &failed)); 334 EXPECT_EQ(0U, failed.size()); 335 for (size_t i = 0; i < failed.size(); ++i) { 336 LOG(ERROR) << "import fail " << failed[i].net_error << " for " 337 << failed[i].certificate->subject().GetDisplayName(); 338 } 339 } 340 341 // Repeat the tests twice, they should return the same each time. 342 for (int i = 0; i < 2; ++i) { 343 SCOPED_TRACE(i); 344 for (std::string::const_iterator j = test_order.begin(); 345 j != test_order.end(); 346 ++j) { 347 switch (*j) { 348 case 'd': 349 // Default verifier should always fail. 350 EXPECT_EQ( 351 net::ERR_CERT_AUTHORITY_INVALID, 352 Verify(verify_proc_default_.get(), server.get(), &verify_root)); 353 break; 354 case '1': 355 EXPECT_EQ(expected_user1_result, 356 Verify(verify_proc_1_.get(), server.get(), &verify_root)); 357 if (expected_user1_result == net::OK) 358 EXPECT_EQ("CN=D Root CA", verify_root); 359 break; 360 case '2': 361 EXPECT_EQ(expected_user2_result, 362 Verify(verify_proc_2_.get(), server.get(), &verify_root)); 363 if (expected_user2_result == net::OK) 364 EXPECT_EQ("CN=E Root CA", verify_root); 365 break; 366 default: 367 FAIL(); 368 } 369 } 370 } 371 } 372 373 INSTANTIATE_TEST_CASE_P( 374 Variations, 375 CertVerifyProcChromeOSOrderingTest, 376 ::testing::Combine( 377 ::testing::Bool(), 378 ::testing::Range(0, 1 << 2), 379 ::testing::Values("d12", "d21", "1d2", "12d", "2d1", "21d"))); 380 381 } // namespace chromeos 382