Chromium Code Reviews| 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 |