1 // Copyright 2012 The Chromium Authors
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/nss_cert_database.h"
6
7 #include <cert.h>
8 #include <certdb.h>
9 #include <pk11pub.h>
10 #include <seccomon.h>
11
12 #include <algorithm>
13 #include <memory>
14 #include <string>
15
16 #include "base/files/file_path.h"
17 #include "base/files/file_util.h"
18 #include "base/functional/bind.h"
19 #include "base/lazy_instance.h"
20 #include "base/run_loop.h"
21 #include "base/strings/string_util.h"
22 #include "base/strings/utf_string_conversions.h"
23 #include "base/test/test_future.h"
24 #include "crypto/scoped_nss_types.h"
25 #include "crypto/scoped_test_nss_db.h"
26 #include "net/base/features.h"
27 #include "net/base/hash_value.h"
28 #include "net/base/net_errors.h"
29 #include "net/cert/cert_database.h"
30 #include "net/cert/cert_net_fetcher.h"
31 #include "net/cert/cert_status_flags.h"
32 #include "net/cert/cert_verify_proc.h"
33 #include "net/cert/cert_verify_result.h"
34 #include "net/cert/crl_set.h"
35 #include "net/cert/mock_cert_verifier.h"
36 #include "net/cert/x509_certificate.h"
37 #include "net/cert/x509_util_nss.h"
38 #include "net/log/net_log_with_source.h"
39 #include "net/test/cert_builder.h"
40 #include "net/test/cert_test_util.h"
41 #include "net/test/gtest_util.h"
42 #include "net/test/test_data_directory.h"
43 #include "net/test/test_with_task_environment.h"
44 #include "net/third_party/mozilla_security_manager/nsNSSCertificateDB.h"
45 #include "testing/gmock/include/gmock/gmock.h"
46 #include "testing/gtest/include/gtest/gtest.h"
47
48 using base::ASCIIToUTF16;
49 using net::test::IsError;
50 using net::test::IsOk;
51
52 namespace net {
53
54 namespace {
55
GetSubjectCN(CERTCertificate * cert)56 std::string GetSubjectCN(CERTCertificate* cert) {
57 char* cn = CERT_GetCommonName(&cert->subject);
58 std::string s = cn;
59 PORT_Free(cn);
60 return s;
61 }
62
GetCertIsPerm(const CERTCertificate * cert)63 bool GetCertIsPerm(const CERTCertificate* cert) {
64 PRBool is_perm;
65 CHECK_EQ(CERT_GetCertIsPerm(cert, &is_perm), SECSuccess);
66 return is_perm != PR_FALSE;
67 }
68
FindCertInfoForCert(const NSSCertDatabase::CertInfoList & cert_info_list,CERTCertificate * target_cert)69 const NSSCertDatabase::CertInfo* FindCertInfoForCert(
70 const NSSCertDatabase::CertInfoList& cert_info_list,
71 CERTCertificate* target_cert) {
72 for (const auto& c : cert_info_list) {
73 if (x509_util::IsSameCertificate(c.cert.get(), target_cert)) {
74 return &c;
75 }
76 }
77 return nullptr;
78 }
79
80 class MockCertDatabaseObserver : public CertDatabase::Observer {
81 public:
MockCertDatabaseObserver()82 MockCertDatabaseObserver() { CertDatabase::GetInstance()->AddObserver(this); }
83
~MockCertDatabaseObserver()84 ~MockCertDatabaseObserver() override {
85 CertDatabase::GetInstance()->RemoveObserver(this);
86 }
87
OnTrustStoreChanged()88 void OnTrustStoreChanged() override { trust_store_changes_++; }
89
OnClientCertStoreChanged()90 void OnClientCertStoreChanged() override { client_cert_store_changes_++; }
91
92 int trust_store_changes_ = 0;
93 int client_cert_store_changes_ = 0;
94 };
95
96 class MockNSSCertDatabaseObserver : public NSSCertDatabase::Observer {
97 public:
MockNSSCertDatabaseObserver(NSSCertDatabase * nss_cert_database)98 explicit MockNSSCertDatabaseObserver(NSSCertDatabase* nss_cert_database)
99 : nss_cert_database_(nss_cert_database) {
100 nss_cert_database_->AddObserver(this);
101 }
102
~MockNSSCertDatabaseObserver()103 ~MockNSSCertDatabaseObserver() override {
104 nss_cert_database_->RemoveObserver(this);
105 }
106
OnTrustStoreChanged()107 void OnTrustStoreChanged() override { trust_store_changes_++; }
108
OnClientCertStoreChanged()109 void OnClientCertStoreChanged() override { client_cert_store_changes_++; }
110
trust_store_changes() const111 int trust_store_changes() const {
112 // Also check that the NSSCertDatabase notifications were mirrored to the
113 // CertDatabase observers.
114 EXPECT_EQ(global_db_observer_.trust_store_changes_, trust_store_changes_);
115
116 return trust_store_changes_;
117 }
118
client_cert_store_changes() const119 int client_cert_store_changes() const {
120 // Also check that the NSSCertDatabase notifications were mirrored to the
121 // CertDatabase observers.
122 EXPECT_EQ(global_db_observer_.client_cert_store_changes_,
123 client_cert_store_changes_);
124
125 return client_cert_store_changes_;
126 }
127
all_changes() const128 int all_changes() const {
129 return trust_store_changes() + client_cert_store_changes();
130 }
131
132 private:
133 raw_ptr<NSSCertDatabase> nss_cert_database_;
134 MockCertDatabaseObserver global_db_observer_;
135 int trust_store_changes_ = 0;
136 int client_cert_store_changes_ = 0;
137 };
138
139 } // namespace
140
141 class CertDatabaseNSSTest : public TestWithTaskEnvironment {
142 public:
SetUp()143 void SetUp() override {
144 ASSERT_TRUE(test_nssdb_.is_open());
145 cert_db_ = std::make_unique<NSSCertDatabase>(
146 crypto::ScopedPK11Slot(
147 PK11_ReferenceSlot(test_nssdb_.slot())) /* public slot */,
148 crypto::ScopedPK11Slot(
149 PK11_ReferenceSlot(test_nssdb_.slot())) /* private slot */);
150 observer_ = std::make_unique<MockNSSCertDatabaseObserver>(cert_db_.get());
151 public_slot_ = cert_db_->GetPublicSlot();
152 crl_set_ = CRLSet::BuiltinCRLSet();
153
154 // Test db should be empty at start of test.
155 EXPECT_EQ(0U, ListCerts().size());
156 }
157
TearDown()158 void TearDown() override {
159 // Run the message loop to process any observer callbacks (e.g. for the
160 // ClientSocketFactory singleton) so that the scoped ref ptrs created in
161 // NSSCertDatabase::NotifyObservers* get released.
162 base::RunLoop().RunUntilIdle();
163 }
164
165 protected:
GetPublicSlot()166 PK11SlotInfo* GetPublicSlot() { return public_slot_.get(); }
167
ReadTestFile(const std::string & name)168 static std::string ReadTestFile(const std::string& name) {
169 std::string result;
170 base::FilePath cert_path = GetTestCertsDirectory().AppendASCII(name);
171 EXPECT_TRUE(base::ReadFileToString(cert_path, &result));
172 return result;
173 }
174
ReadCertIntoList(const std::string & name,ScopedCERTCertificateList * certs)175 static bool ReadCertIntoList(const std::string& name,
176 ScopedCERTCertificateList* certs) {
177 ScopedCERTCertificate cert =
178 ImportCERTCertificateFromFile(GetTestCertsDirectory(), name);
179 if (!cert)
180 return false;
181
182 certs->push_back(std::move(cert));
183 return true;
184 }
185
ListCerts()186 ScopedCERTCertificateList ListCerts() {
187 ScopedCERTCertificateList result;
188 crypto::ScopedCERTCertList cert_list(
189 PK11_ListCertsInSlot(test_nssdb_.slot()));
190 if (!cert_list)
191 return result;
192 for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list);
193 !CERT_LIST_END(node, cert_list);
194 node = CERT_LIST_NEXT(node)) {
195 result.push_back(x509_util::DupCERTCertificate(node->cert));
196 }
197
198 // Sort the result so that test comparisons can be deterministic.
199 std::sort(
200 result.begin(), result.end(),
201 [](const ScopedCERTCertificate& lhs, const ScopedCERTCertificate& rhs) {
202 return x509_util::CalculateFingerprint256(lhs.get()) <
203 x509_util::CalculateFingerprint256(rhs.get());
204 });
205 return result;
206 }
207
208 std::unique_ptr<NSSCertDatabase> cert_db_;
209 std::unique_ptr<MockNSSCertDatabaseObserver> observer_;
210 crypto::ScopedTestNSSDB test_nssdb_;
211 crypto::ScopedPK11Slot public_slot_;
212 scoped_refptr<CRLSet> crl_set_;
213 };
214
TEST_F(CertDatabaseNSSTest,ListCerts)215 TEST_F(CertDatabaseNSSTest, ListCerts) {
216 // This test isn't terribly useful, though it might help with memory
217 // leak tests.
218 base::test::TestFuture<ScopedCERTCertificateList> future;
219 cert_db_->ListCerts(future.GetCallback());
220
221 ScopedCERTCertificateList certs = future.Take();
222 // The test DB is empty, but let's assume there will always be something in
223 // the other slots.
224 EXPECT_LT(0U, certs.size());
225 }
226
TEST_F(CertDatabaseNSSTest,ListCertsInfo)227 TEST_F(CertDatabaseNSSTest, ListCertsInfo) {
228 // Since ListCertsInfo queries all the "permanent" certs NSS knows about,
229 // including NSS builtin trust anchors and any locally installed certs of the
230 // user running the test, it's hard to do really precise testing here. Try to
231 // do some general testing as well as testing that a cert added through
232 // ScopedTestNSSDB is handled properly.
233
234 // Load a test certificate
235 ScopedCERTCertificateList test_root_certs = CreateCERTCertificateListFromFile(
236 GetTestCertsDirectory(), "root_ca_cert.pem",
237 X509Certificate::FORMAT_AUTO);
238 ASSERT_EQ(1U, test_root_certs.size());
239 // Should be only a temp certificate at this point, and thus not be returned
240 // in the listed certs.
241 EXPECT_FALSE(GetCertIsPerm(test_root_certs[0].get()));
242
243 // Get lists of all certs both including and excluding NSS roots.
244 NSSCertDatabase::CertInfoList certs_including_nss;
245 NSSCertDatabase::CertInfoList certs_excluding_nss;
246 {
247 base::test::TestFuture<NSSCertDatabase::CertInfoList> future;
248 cert_db_->ListCertsInfo(future.GetCallback(),
249 NSSCertDatabase::NSSRootsHandling::kInclude);
250 certs_including_nss = future.Take();
251 }
252 {
253 base::test::TestFuture<NSSCertDatabase::CertInfoList> future;
254 cert_db_->ListCertsInfo(future.GetCallback(),
255 NSSCertDatabase::NSSRootsHandling::kExclude);
256 certs_excluding_nss = future.Take();
257 }
258
259 // The tests based on GetAnNssSslTrustedBuiltinRoot could be flaky in obscure
260 // local configurations (if the user running the test has manually imported
261 // the same certificate into their user NSS DB.) Oh well.
262 ScopedCERTCertificate nss_root = GetAnNssBuiltinSslTrustedRoot();
263 // (Also this will fail if we ever do the "don't load libnssckbi.so" thing.)
264 ASSERT_TRUE(nss_root);
265 {
266 const NSSCertDatabase::CertInfo* nss_root_info =
267 FindCertInfoForCert(certs_including_nss, nss_root.get());
268 ASSERT_TRUE(nss_root_info);
269 EXPECT_TRUE(nss_root_info->web_trust_anchor);
270 EXPECT_FALSE(nss_root_info->untrusted);
271 EXPECT_FALSE(nss_root_info->device_wide);
272 EXPECT_FALSE(nss_root_info->hardware_backed);
273 EXPECT_TRUE(nss_root_info->on_read_only_slot);
274 }
275 EXPECT_FALSE(FindCertInfoForCert(certs_excluding_nss, nss_root.get()));
276
277 // Test root cert should not be in the lists retrieved before it was imported.
278 EXPECT_FALSE(
279 FindCertInfoForCert(certs_including_nss, test_root_certs[0].get()));
280 EXPECT_FALSE(
281 FindCertInfoForCert(certs_excluding_nss, test_root_certs[0].get()));
282
283 // Import the NSS root into the test DB.
284 SECStatus srv =
285 PK11_ImportCert(test_nssdb_.slot(), nss_root.get(), CK_INVALID_HANDLE,
286 net::x509_util::GetDefaultUniqueNickname(
287 nss_root.get(), net::CA_CERT, test_nssdb_.slot())
288 .c_str(),
289 PR_FALSE /* includeTrust (unused) */);
290 ASSERT_EQ(SECSuccess, srv);
291
292 // Import test certificate to the test DB.
293 NSSCertDatabase::ImportCertFailureList failed;
294 EXPECT_TRUE(cert_db_->ImportCACerts(test_root_certs,
295 NSSCertDatabase::TRUSTED_SSL, &failed));
296 EXPECT_EQ(0U, failed.size());
297
298 // Get new lists of all certs both including and excluding NSS roots, which
299 // should now also include the test db certificates.
300 NSSCertDatabase::CertInfoList certs_including_nss_with_local;
301 NSSCertDatabase::CertInfoList certs_excluding_nss_with_local;
302 {
303 base::test::TestFuture<NSSCertDatabase::CertInfoList> future;
304 cert_db_->ListCertsInfo(future.GetCallback(),
305 NSSCertDatabase::NSSRootsHandling::kInclude);
306 certs_including_nss_with_local = future.Take();
307 }
308 {
309 base::test::TestFuture<NSSCertDatabase::CertInfoList> future;
310 cert_db_->ListCertsInfo(future.GetCallback(),
311 NSSCertDatabase::NSSRootsHandling::kExclude);
312 certs_excluding_nss_with_local = future.Take();
313 }
314
315 // After adding the certs to the test db, the number certs returned should be
316 // 1 more than before in kInclude and and 2 more in kExclude cases.
317 EXPECT_EQ(certs_including_nss_with_local.size(),
318 1 + certs_including_nss.size());
319 EXPECT_EQ(certs_excluding_nss_with_local.size(),
320 2 + certs_excluding_nss.size());
321
322 // Using kExclude should give a smaller number of results than kInclude.
323 // (Although this would be wrong if we ever do the "don't load libnssckbi.so"
324 // thing.)
325 EXPECT_LT(certs_excluding_nss_with_local.size(),
326 certs_including_nss_with_local.size());
327
328 // The NSS root that was imported to the test db should be in both lists now.
329 {
330 const NSSCertDatabase::CertInfo* nss_root_info =
331 FindCertInfoForCert(certs_including_nss_with_local, nss_root.get());
332 ASSERT_TRUE(nss_root_info);
333 EXPECT_TRUE(nss_root_info->web_trust_anchor);
334 EXPECT_FALSE(nss_root_info->untrusted);
335 EXPECT_FALSE(nss_root_info->device_wide);
336 EXPECT_FALSE(nss_root_info->hardware_backed);
337 // `on_read_only_slot` is not tested here as the way it is calculated could
338 // be potentially flaky if the cert exists on both a readonly and
339 // non-readonly slot.
340 }
341 {
342 const NSSCertDatabase::CertInfo* nss_root_info =
343 FindCertInfoForCert(certs_excluding_nss_with_local, nss_root.get());
344 ASSERT_TRUE(nss_root_info);
345 EXPECT_FALSE(nss_root_info->web_trust_anchor);
346 EXPECT_TRUE(nss_root_info->untrusted);
347 EXPECT_FALSE(nss_root_info->device_wide);
348 EXPECT_FALSE(nss_root_info->hardware_backed);
349 // `on_read_only_slot` is not tested here as the way it is calculated could
350 // be potentially flaky if the cert exists on both a readonly and
351 // non-readonly slot.
352 }
353
354 // Ensure the test root cert is present in the lists retrieved after it was
355 // imported, and that the info returned is as expected.
356 {
357 const NSSCertDatabase::CertInfo* test_cert_info = FindCertInfoForCert(
358 certs_including_nss_with_local, test_root_certs[0].get());
359 ASSERT_TRUE(test_cert_info);
360 EXPECT_TRUE(test_cert_info->web_trust_anchor);
361 EXPECT_FALSE(test_cert_info->untrusted);
362 EXPECT_FALSE(test_cert_info->device_wide);
363 EXPECT_FALSE(test_cert_info->hardware_backed);
364 EXPECT_FALSE(test_cert_info->on_read_only_slot);
365 }
366 {
367 const NSSCertDatabase::CertInfo* test_cert_info = FindCertInfoForCert(
368 certs_excluding_nss_with_local, test_root_certs[0].get());
369 ASSERT_TRUE(test_cert_info);
370 EXPECT_TRUE(test_cert_info->web_trust_anchor);
371 EXPECT_FALSE(test_cert_info->untrusted);
372 EXPECT_FALSE(test_cert_info->device_wide);
373 EXPECT_FALSE(test_cert_info->hardware_backed);
374 EXPECT_FALSE(test_cert_info->on_read_only_slot);
375 }
376 }
377
TEST_F(CertDatabaseNSSTest,ImportFromPKCS12WrongPassword)378 TEST_F(CertDatabaseNSSTest, ImportFromPKCS12WrongPassword) {
379 std::string pkcs12_data = ReadTestFile("client.p12");
380
381 EXPECT_EQ(
382 ERR_PKCS12_IMPORT_BAD_PASSWORD,
383 cert_db_->ImportFromPKCS12(GetPublicSlot(), pkcs12_data, std::u16string(),
384 true, // is_extractable
385 nullptr));
386
387 // Test db should still be empty.
388 EXPECT_EQ(0U, ListCerts().size());
389
390 base::RunLoop().RunUntilIdle();
391 EXPECT_EQ(0, observer_->all_changes());
392 }
393
TEST_F(CertDatabaseNSSTest,ImportFromPKCS12AsExtractableAndExportAgain)394 TEST_F(CertDatabaseNSSTest, ImportFromPKCS12AsExtractableAndExportAgain) {
395 std::string pkcs12_data = ReadTestFile("client.p12");
396
397 EXPECT_EQ(OK,
398 cert_db_->ImportFromPKCS12(GetPublicSlot(), pkcs12_data, u"12345",
399 true, // is_extractable
400 nullptr));
401
402 base::RunLoop().RunUntilIdle();
403 EXPECT_EQ(1, observer_->client_cert_store_changes());
404 EXPECT_EQ(0, observer_->trust_store_changes());
405
406 ScopedCERTCertificateList cert_list = ListCerts();
407 ASSERT_EQ(1U, cert_list.size());
408 EXPECT_EQ("testusercert", GetSubjectCN(cert_list[0].get()));
409
410 // TODO(mattm): move export test to separate test case?
411 std::string exported_data;
412 EXPECT_EQ(1,
413 cert_db_->ExportToPKCS12(cert_list, u"exportpw", &exported_data));
414 ASSERT_LT(0U, exported_data.size());
415 // TODO(mattm): further verification of exported data?
416
417 base::RunLoop().RunUntilIdle();
418 // Exporting should not cause an observer notification.
419 EXPECT_EQ(1, observer_->all_changes());
420 }
421
TEST_F(CertDatabaseNSSTest,ImportFromPKCS12Twice)422 TEST_F(CertDatabaseNSSTest, ImportFromPKCS12Twice) {
423 std::string pkcs12_data = ReadTestFile("client.p12");
424
425 EXPECT_EQ(OK,
426 cert_db_->ImportFromPKCS12(GetPublicSlot(), pkcs12_data, u"12345",
427 true, // is_extractable
428 nullptr));
429 EXPECT_EQ(1U, ListCerts().size());
430
431 base::RunLoop().RunUntilIdle();
432 EXPECT_EQ(1, observer_->client_cert_store_changes());
433 EXPECT_EQ(0, observer_->trust_store_changes());
434
435 // NSS has a SEC_ERROR_PKCS12_DUPLICATE_DATA error, but it doesn't look like
436 // it's ever used. This test verifies that.
437 EXPECT_EQ(OK,
438 cert_db_->ImportFromPKCS12(GetPublicSlot(), pkcs12_data, u"12345",
439 true, // is_extractable
440 nullptr));
441 EXPECT_EQ(1U, ListCerts().size());
442
443 base::RunLoop().RunUntilIdle();
444 // Theoretically it should not send another notification for re-importing the
445 // same thing, but probably not worth the effort to try to detect this case.
446 EXPECT_EQ(2, observer_->client_cert_store_changes());
447 EXPECT_EQ(0, observer_->trust_store_changes());
448 }
449
TEST_F(CertDatabaseNSSTest,ImportFromPKCS12AsUnextractableAndExportAgain)450 TEST_F(CertDatabaseNSSTest, ImportFromPKCS12AsUnextractableAndExportAgain) {
451 std::string pkcs12_data = ReadTestFile("client.p12");
452
453 EXPECT_EQ(OK,
454 cert_db_->ImportFromPKCS12(GetPublicSlot(), pkcs12_data, u"12345",
455 false, // is_extractable
456 nullptr));
457
458 ScopedCERTCertificateList cert_list = ListCerts();
459 ASSERT_EQ(1U, cert_list.size());
460 EXPECT_EQ("testusercert", GetSubjectCN(cert_list[0].get()));
461
462 std::string exported_data;
463 EXPECT_EQ(0,
464 cert_db_->ExportToPKCS12(cert_list, u"exportpw", &exported_data));
465 }
466
467 // Importing a PKCS#12 file with a certificate but no corresponding
468 // private key should not mark an existing private key as unextractable.
TEST_F(CertDatabaseNSSTest,ImportFromPKCS12OnlyMarkIncludedKey)469 TEST_F(CertDatabaseNSSTest, ImportFromPKCS12OnlyMarkIncludedKey) {
470 std::string pkcs12_data = ReadTestFile("client.p12");
471 EXPECT_EQ(OK,
472 cert_db_->ImportFromPKCS12(GetPublicSlot(), pkcs12_data, u"12345",
473 true, // is_extractable
474 nullptr));
475
476 ScopedCERTCertificateList cert_list = ListCerts();
477 ASSERT_EQ(1U, cert_list.size());
478
479 // Now import a PKCS#12 file with just a certificate but no private key.
480 pkcs12_data = ReadTestFile("client-nokey.p12");
481 EXPECT_EQ(OK,
482 cert_db_->ImportFromPKCS12(GetPublicSlot(), pkcs12_data, u"12345",
483 false, // is_extractable
484 nullptr));
485
486 cert_list = ListCerts();
487 ASSERT_EQ(1U, cert_list.size());
488
489 // Make sure the imported private key is still extractable.
490 std::string exported_data;
491 EXPECT_EQ(1,
492 cert_db_->ExportToPKCS12(cert_list, u"exportpw", &exported_data));
493 ASSERT_LT(0U, exported_data.size());
494 }
495
TEST_F(CertDatabaseNSSTest,ImportFromPKCS12InvalidFile)496 TEST_F(CertDatabaseNSSTest, ImportFromPKCS12InvalidFile) {
497 std::string pkcs12_data = "Foobarbaz";
498
499 EXPECT_EQ(
500 ERR_PKCS12_IMPORT_INVALID_FILE,
501 cert_db_->ImportFromPKCS12(GetPublicSlot(), pkcs12_data, std::u16string(),
502 true, // is_extractable
503 nullptr));
504
505 // Test db should still be empty.
506 EXPECT_EQ(0U, ListCerts().size());
507 }
508
TEST_F(CertDatabaseNSSTest,ImportFromPKCS12EmptyPassword)509 TEST_F(CertDatabaseNSSTest, ImportFromPKCS12EmptyPassword) {
510 std::string pkcs12_data = ReadTestFile("client-empty-password.p12");
511
512 EXPECT_EQ(OK, cert_db_->ImportFromPKCS12(GetPublicSlot(), pkcs12_data,
513 std::u16string(),
514 true, // is_extractable
515 nullptr));
516 EXPECT_EQ(1U, ListCerts().size());
517 }
518
TEST_F(CertDatabaseNSSTest,ImportFromPKCS12NullPassword)519 TEST_F(CertDatabaseNSSTest, ImportFromPKCS12NullPassword) {
520 std::string pkcs12_data = ReadTestFile("client-null-password.p12");
521
522 EXPECT_EQ(OK, cert_db_->ImportFromPKCS12(GetPublicSlot(), pkcs12_data,
523 std::u16string(),
524 true, // is_extractable
525 nullptr));
526 EXPECT_EQ(1U, ListCerts().size());
527 }
528
TEST_F(CertDatabaseNSSTest,ImportCACert_SSLTrust)529 TEST_F(CertDatabaseNSSTest, ImportCACert_SSLTrust) {
530 ScopedCERTCertificateList certs = CreateCERTCertificateListFromFile(
531 GetTestCertsDirectory(), "root_ca_cert.pem",
532 X509Certificate::FORMAT_AUTO);
533 ASSERT_EQ(1U, certs.size());
534 EXPECT_FALSE(GetCertIsPerm(certs[0].get()));
535
536 // Import it.
537 NSSCertDatabase::ImportCertFailureList failed;
538 EXPECT_TRUE(cert_db_->ImportCACerts(certs, NSSCertDatabase::TRUSTED_SSL,
539 &failed));
540
541 EXPECT_EQ(0U, failed.size());
542
543 ScopedCERTCertificateList cert_list = ListCerts();
544 ASSERT_EQ(1U, cert_list.size());
545 CERTCertificate* cert = cert_list[0].get();
546 EXPECT_EQ("Test Root CA", GetSubjectCN(cert));
547
548 EXPECT_EQ(NSSCertDatabase::TRUSTED_SSL,
549 cert_db_->GetCertTrust(cert, CA_CERT));
550
551 EXPECT_EQ(
552 unsigned(CERTDB_VALID_CA | CERTDB_TRUSTED_CA | CERTDB_TRUSTED_CLIENT_CA),
553 cert->trust->sslFlags);
554 EXPECT_EQ(unsigned(CERTDB_VALID_CA), cert->trust->emailFlags);
555 EXPECT_EQ(unsigned(CERTDB_VALID_CA), cert->trust->objectSigningFlags);
556
557 base::RunLoop().RunUntilIdle();
558 EXPECT_EQ(0, observer_->client_cert_store_changes());
559 EXPECT_EQ(1, observer_->trust_store_changes());
560 }
561
TEST_F(CertDatabaseNSSTest,ImportCACert_EmailTrust)562 TEST_F(CertDatabaseNSSTest, ImportCACert_EmailTrust) {
563 ScopedCERTCertificateList certs = CreateCERTCertificateListFromFile(
564 GetTestCertsDirectory(), "root_ca_cert.pem",
565 X509Certificate::FORMAT_AUTO);
566 ASSERT_EQ(1U, certs.size());
567 EXPECT_FALSE(GetCertIsPerm(certs[0].get()));
568
569 // Import it.
570 NSSCertDatabase::ImportCertFailureList failed;
571 EXPECT_TRUE(cert_db_->ImportCACerts(certs, NSSCertDatabase::TRUSTED_EMAIL,
572 &failed));
573
574 EXPECT_EQ(0U, failed.size());
575
576 ScopedCERTCertificateList cert_list = ListCerts();
577 ASSERT_EQ(1U, cert_list.size());
578 CERTCertificate* cert = cert_list[0].get();
579 EXPECT_EQ("Test Root CA", GetSubjectCN(cert));
580
581 EXPECT_EQ(NSSCertDatabase::TRUSTED_EMAIL,
582 cert_db_->GetCertTrust(cert, CA_CERT));
583
584 EXPECT_EQ(unsigned(CERTDB_VALID_CA), cert->trust->sslFlags);
585 EXPECT_EQ(
586 unsigned(CERTDB_VALID_CA | CERTDB_TRUSTED_CA | CERTDB_TRUSTED_CLIENT_CA),
587 cert->trust->emailFlags);
588 EXPECT_EQ(unsigned(CERTDB_VALID_CA), cert->trust->objectSigningFlags);
589
590 base::RunLoop().RunUntilIdle();
591 EXPECT_EQ(0, observer_->client_cert_store_changes());
592 // Theoretically we could avoid notifying for changes that aren't relevant
593 // for server auth, but probably not worth the effort.
594 EXPECT_EQ(1, observer_->trust_store_changes());
595 }
596
TEST_F(CertDatabaseNSSTest,ImportCACert_ObjSignTrust)597 TEST_F(CertDatabaseNSSTest, ImportCACert_ObjSignTrust) {
598 ScopedCERTCertificateList certs = CreateCERTCertificateListFromFile(
599 GetTestCertsDirectory(), "root_ca_cert.pem",
600 X509Certificate::FORMAT_AUTO);
601 ASSERT_EQ(1U, certs.size());
602 EXPECT_FALSE(GetCertIsPerm(certs[0].get()));
603
604 // Import it.
605 NSSCertDatabase::ImportCertFailureList failed;
606 EXPECT_TRUE(cert_db_->ImportCACerts(certs, NSSCertDatabase::TRUSTED_OBJ_SIGN,
607 &failed));
608
609 EXPECT_EQ(0U, failed.size());
610
611 ScopedCERTCertificateList cert_list = ListCerts();
612 ASSERT_EQ(1U, cert_list.size());
613 CERTCertificate* cert = cert_list[0].get();
614 EXPECT_EQ("Test Root CA", GetSubjectCN(cert));
615
616 EXPECT_EQ(NSSCertDatabase::TRUSTED_OBJ_SIGN,
617 cert_db_->GetCertTrust(cert, CA_CERT));
618
619 EXPECT_EQ(unsigned(CERTDB_VALID_CA), cert->trust->sslFlags);
620 EXPECT_EQ(unsigned(CERTDB_VALID_CA), cert->trust->emailFlags);
621 EXPECT_EQ(
622 unsigned(CERTDB_VALID_CA | CERTDB_TRUSTED_CA | CERTDB_TRUSTED_CLIENT_CA),
623 cert->trust->objectSigningFlags);
624
625 base::RunLoop().RunUntilIdle();
626 EXPECT_EQ(0, observer_->client_cert_store_changes());
627 // Theoretically we could avoid notifying for changes that aren't relevant
628 // for server auth, but probably not worth the effort.
629 EXPECT_EQ(1, observer_->trust_store_changes());
630 }
631
TEST_F(CertDatabaseNSSTest,ImportCA_NotCACert)632 TEST_F(CertDatabaseNSSTest, ImportCA_NotCACert) {
633 ScopedCERTCertificateList certs = CreateCERTCertificateListFromFile(
634 GetTestCertsDirectory(), "ok_cert.pem", X509Certificate::FORMAT_AUTO);
635 ASSERT_EQ(1U, certs.size());
636 EXPECT_FALSE(GetCertIsPerm(certs[0].get()));
637
638 // Import it.
639 NSSCertDatabase::ImportCertFailureList failed;
640 EXPECT_TRUE(cert_db_->ImportCACerts(certs, NSSCertDatabase::TRUSTED_SSL,
641 &failed));
642 ASSERT_EQ(1U, failed.size());
643 // Note: this compares pointers directly. It's okay in this case because
644 // ImportCACerts returns the same pointers that were passed in. In the
645 // general case x509_util::CryptoBufferEqual should be used.
646 EXPECT_EQ(certs[0], failed[0].certificate);
647 EXPECT_THAT(failed[0].net_error, IsError(ERR_IMPORT_CA_CERT_NOT_CA));
648
649 EXPECT_EQ(0U, ListCerts().size());
650 }
651
TEST_F(CertDatabaseNSSTest,ImportCACertHierarchy)652 TEST_F(CertDatabaseNSSTest, ImportCACertHierarchy) {
653 ScopedCERTCertificateList certs;
654 ASSERT_TRUE(ReadCertIntoList("multi-root-D-by-D.pem", &certs));
655 ASSERT_TRUE(ReadCertIntoList("multi-root-C-by-D.pem", &certs));
656 ASSERT_TRUE(ReadCertIntoList("multi-root-B-by-C.pem", &certs));
657 ASSERT_TRUE(ReadCertIntoList("multi-root-A-by-B.pem", &certs));
658
659 // Import it.
660 NSSCertDatabase::ImportCertFailureList failed;
661 // Have to specify email trust for the cert verification of the child cert to
662 // work (see
663 // http://mxr.mozilla.org/mozilla/source/security/nss/lib/certhigh/certvfy.c#752
664 // "XXX This choice of trustType seems arbitrary.")
665 EXPECT_TRUE(cert_db_->ImportCACerts(
666 certs, NSSCertDatabase::TRUSTED_SSL | NSSCertDatabase::TRUSTED_EMAIL,
667 &failed));
668
669 ASSERT_EQ(1U, failed.size());
670 EXPECT_EQ("127.0.0.1", GetSubjectCN(failed[0].certificate.get()));
671 EXPECT_THAT(failed[0].net_error, IsError(ERR_IMPORT_CA_CERT_NOT_CA));
672
673 ScopedCERTCertificateList cert_list = ListCerts();
674 ASSERT_EQ(3U, cert_list.size());
675 EXPECT_EQ("B CA - Multi-root", GetSubjectCN(cert_list[0].get()));
676 EXPECT_EQ("D Root CA - Multi-root", GetSubjectCN(cert_list[1].get()));
677 EXPECT_EQ("C CA - Multi-root", GetSubjectCN(cert_list[2].get()));
678
679 base::RunLoop().RunUntilIdle();
680 EXPECT_EQ(0, observer_->client_cert_store_changes());
681 EXPECT_EQ(1, observer_->trust_store_changes());
682 }
683
TEST_F(CertDatabaseNSSTest,ImportCACertHierarchyDupeRoot)684 TEST_F(CertDatabaseNSSTest, ImportCACertHierarchyDupeRoot) {
685 ScopedCERTCertificateList certs;
686 ASSERT_TRUE(ReadCertIntoList("multi-root-D-by-D.pem", &certs));
687
688 // First import just the root.
689 NSSCertDatabase::ImportCertFailureList failed;
690 EXPECT_TRUE(cert_db_->ImportCACerts(
691 certs, NSSCertDatabase::TRUSTED_SSL | NSSCertDatabase::TRUSTED_EMAIL,
692 &failed));
693
694 EXPECT_EQ(0U, failed.size());
695 ScopedCERTCertificateList cert_list = ListCerts();
696 ASSERT_EQ(1U, cert_list.size());
697 EXPECT_EQ("D Root CA - Multi-root", GetSubjectCN(cert_list[0].get()));
698
699 ASSERT_TRUE(ReadCertIntoList("multi-root-C-by-D.pem", &certs));
700 ASSERT_TRUE(ReadCertIntoList("multi-root-B-by-C.pem", &certs));
701 ASSERT_TRUE(ReadCertIntoList("multi-root-A-by-B.pem", &certs));
702
703 // Now import with the other certs in the list too. Even though the root is
704 // already present, we should still import the rest.
705 failed.clear();
706 EXPECT_TRUE(cert_db_->ImportCACerts(
707 certs, NSSCertDatabase::TRUSTED_SSL | NSSCertDatabase::TRUSTED_EMAIL,
708 &failed));
709
710 ASSERT_EQ(2U, failed.size());
711 EXPECT_EQ("D Root CA - Multi-root",
712 GetSubjectCN(failed[0].certificate.get()));
713 EXPECT_THAT(failed[0].net_error, IsError(ERR_IMPORT_CERT_ALREADY_EXISTS));
714 EXPECT_EQ("127.0.0.1", GetSubjectCN(failed[1].certificate.get()));
715 EXPECT_THAT(failed[1].net_error, IsError(ERR_IMPORT_CA_CERT_NOT_CA));
716
717 cert_list = ListCerts();
718 ASSERT_EQ(3U, cert_list.size());
719 EXPECT_EQ("B CA - Multi-root", GetSubjectCN(cert_list[0].get()));
720 EXPECT_EQ("D Root CA - Multi-root", GetSubjectCN(cert_list[1].get()));
721 EXPECT_EQ("C CA - Multi-root", GetSubjectCN(cert_list[2].get()));
722
723 base::RunLoop().RunUntilIdle();
724 EXPECT_EQ(0, observer_->client_cert_store_changes());
725 EXPECT_EQ(2, observer_->trust_store_changes());
726 }
727
TEST_F(CertDatabaseNSSTest,ImportCACertHierarchyUntrusted)728 TEST_F(CertDatabaseNSSTest, ImportCACertHierarchyUntrusted) {
729 ScopedCERTCertificateList certs;
730 ASSERT_TRUE(ReadCertIntoList("multi-root-D-by-D.pem", &certs));
731 ASSERT_TRUE(ReadCertIntoList("multi-root-C-by-D.pem", &certs));
732
733 // Import it.
734 NSSCertDatabase::ImportCertFailureList failed;
735 EXPECT_TRUE(cert_db_->ImportCACerts(certs, NSSCertDatabase::TRUST_DEFAULT,
736 &failed));
737
738 ASSERT_EQ(1U, failed.size());
739 EXPECT_EQ("C CA - Multi-root", GetSubjectCN(failed[0].certificate.get()));
740 // TODO(mattm): should check for net error equivalent of
741 // SEC_ERROR_UNTRUSTED_ISSUER
742 EXPECT_THAT(failed[0].net_error, IsError(ERR_FAILED));
743
744 ScopedCERTCertificateList cert_list = ListCerts();
745 ASSERT_EQ(1U, cert_list.size());
746 EXPECT_EQ("D Root CA - Multi-root", GetSubjectCN(cert_list[0].get()));
747
748 base::RunLoop().RunUntilIdle();
749 EXPECT_EQ(0, observer_->client_cert_store_changes());
750 // We generate a notification even if not trusting the root. The certs could
751 // still affect trust decisions by affecting path building.
752 EXPECT_EQ(1, observer_->trust_store_changes());
753 }
754
TEST_F(CertDatabaseNSSTest,ImportCACertHierarchyTree)755 TEST_F(CertDatabaseNSSTest, ImportCACertHierarchyTree) {
756 ScopedCERTCertificateList certs;
757 ASSERT_TRUE(ReadCertIntoList("multi-root-E-by-E.pem", &certs));
758 ASSERT_TRUE(ReadCertIntoList("multi-root-C-by-E.pem", &certs));
759 ASSERT_TRUE(ReadCertIntoList("multi-root-F-by-E.pem", &certs));
760
761 // Import it.
762 NSSCertDatabase::ImportCertFailureList failed;
763 EXPECT_TRUE(cert_db_->ImportCACerts(
764 certs, NSSCertDatabase::TRUSTED_SSL | NSSCertDatabase::TRUSTED_EMAIL,
765 &failed));
766
767 ScopedCERTCertificateList cert_list = ListCerts();
768 ASSERT_EQ(3U, cert_list.size());
769 EXPECT_EQ("F CA - Multi-root", GetSubjectCN(cert_list[0].get()));
770 EXPECT_EQ("C CA - Multi-root", GetSubjectCN(cert_list[1].get()));
771 EXPECT_EQ("E Root CA - Multi-root", GetSubjectCN(cert_list[2].get()));
772 }
773
TEST_F(CertDatabaseNSSTest,ImportCACertNotHierarchy)774 TEST_F(CertDatabaseNSSTest, ImportCACertNotHierarchy) {
775 ScopedCERTCertificateList certs = CreateCERTCertificateListFromFile(
776 GetTestCertsDirectory(), "root_ca_cert.pem",
777 X509Certificate::FORMAT_AUTO);
778 ASSERT_EQ(1U, certs.size());
779 ASSERT_TRUE(ReadCertIntoList("multi-root-F-by-E.pem", &certs));
780 ASSERT_TRUE(ReadCertIntoList("multi-root-C-by-E.pem", &certs));
781
782 // Import it.
783 NSSCertDatabase::ImportCertFailureList failed;
784 EXPECT_TRUE(cert_db_->ImportCACerts(
785 certs, NSSCertDatabase::TRUSTED_SSL | NSSCertDatabase::TRUSTED_EMAIL,
786 &failed));
787
788 ASSERT_EQ(2U, failed.size());
789 // TODO(mattm): should check for net error equivalent of
790 // SEC_ERROR_UNKNOWN_ISSUER
791 EXPECT_EQ("F CA - Multi-root", GetSubjectCN(failed[0].certificate.get()));
792 EXPECT_THAT(failed[0].net_error, IsError(ERR_FAILED));
793 EXPECT_EQ("C CA - Multi-root", GetSubjectCN(failed[1].certificate.get()));
794 EXPECT_THAT(failed[1].net_error, IsError(ERR_FAILED));
795
796 ScopedCERTCertificateList cert_list = ListCerts();
797 ASSERT_EQ(1U, cert_list.size());
798 EXPECT_EQ("Test Root CA", GetSubjectCN(cert_list[0].get()));
799 }
800
801 // Test importing a server cert + chain to the NSS DB with default trust. After
802 // importing, all the certs should be found in the DB and should have default
803 // trust flags.
TEST_F(CertDatabaseNSSTest,ImportServerCert)804 TEST_F(CertDatabaseNSSTest, ImportServerCert) {
805 // Import the server and its chain.
806 ScopedCERTCertificateList certs_to_import;
807 ASSERT_TRUE(
808 ReadCertIntoList("ok_cert_by_intermediate.pem", &certs_to_import));
809 ASSERT_TRUE(ReadCertIntoList("intermediate_ca_cert.pem", &certs_to_import));
810 ASSERT_TRUE(ReadCertIntoList("root_ca_cert.pem", &certs_to_import));
811
812 NSSCertDatabase::ImportCertFailureList failed;
813 EXPECT_TRUE(cert_db_->ImportServerCert(
814 certs_to_import, NSSCertDatabase::TRUST_DEFAULT, &failed));
815 EXPECT_EQ(0U, failed.size());
816
817 // All the certs in the imported list should now be found in the NSS DB.
818 ScopedCERTCertificateList cert_list = ListCerts();
819 ASSERT_EQ(3U, cert_list.size());
820 CERTCertificate* found_server_cert = nullptr;
821 CERTCertificate* found_intermediate_cert = nullptr;
822 CERTCertificate* found_root_cert = nullptr;
823 for (const auto& cert : cert_list) {
824 if (GetSubjectCN(cert.get()) == "127.0.0.1")
825 found_server_cert = cert.get();
826 else if (GetSubjectCN(cert.get()) == "Test Intermediate CA")
827 found_intermediate_cert = cert.get();
828 else if (GetSubjectCN(cert.get()) == "Test Root CA")
829 found_root_cert = cert.get();
830 }
831 ASSERT_TRUE(found_server_cert);
832 ASSERT_TRUE(found_intermediate_cert);
833 ASSERT_TRUE(found_root_cert);
834
835 EXPECT_EQ(NSSCertDatabase::TRUST_DEFAULT,
836 cert_db_->GetCertTrust(found_server_cert, SERVER_CERT));
837 EXPECT_EQ(0U, found_server_cert->trust->sslFlags);
838 EXPECT_EQ(NSSCertDatabase::TRUST_DEFAULT,
839 cert_db_->GetCertTrust(found_intermediate_cert, CA_CERT));
840 EXPECT_EQ(0U, found_intermediate_cert->trust->sslFlags);
841 EXPECT_EQ(NSSCertDatabase::TRUST_DEFAULT,
842 cert_db_->GetCertTrust(found_root_cert, CA_CERT));
843 EXPECT_EQ(0U, found_root_cert->trust->sslFlags);
844
845 // Verification fails, as the intermediate & CA certs are imported without
846 // trust.
847 scoped_refptr<X509Certificate> x509_found_server_cert =
848 x509_util::CreateX509CertificateFromCERTCertificate(found_server_cert);
849 ASSERT_TRUE(x509_found_server_cert);
850 scoped_refptr<CertVerifyProc> verify_proc(
851 CertVerifyProc::CreateBuiltinWithChromeRootStore(
852 /*cert_net_fetcher=*/nullptr, crl_set_, /*root_store_data=*/nullptr,
853 /*instance_params=*/{}));
854 int flags = 0;
855 CertVerifyResult verify_result;
856 int error = verify_proc->Verify(x509_found_server_cert.get(), "127.0.0.1",
857 /*ocsp_response=*/std::string(),
858 /*sct_list=*/std::string(), flags,
859 &verify_result, NetLogWithSource());
860 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
861 EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, verify_result.cert_status);
862
863 base::RunLoop().RunUntilIdle();
864 EXPECT_EQ(0, observer_->client_cert_store_changes());
865 EXPECT_EQ(0, observer_->trust_store_changes());
866 }
867
TEST_F(CertDatabaseNSSTest,ImportServerCert_SelfSigned)868 TEST_F(CertDatabaseNSSTest, ImportServerCert_SelfSigned) {
869 ScopedCERTCertificateList certs;
870 ASSERT_TRUE(ReadCertIntoList("punycodetest.pem", &certs));
871
872 NSSCertDatabase::ImportCertFailureList failed;
873 EXPECT_TRUE(cert_db_->ImportServerCert(certs, NSSCertDatabase::TRUST_DEFAULT,
874 &failed));
875
876 EXPECT_EQ(0U, failed.size());
877
878 ScopedCERTCertificateList cert_list = ListCerts();
879 ASSERT_EQ(1U, cert_list.size());
880 CERTCertificate* puny_cert = cert_list[0].get();
881
882 EXPECT_EQ(NSSCertDatabase::TRUST_DEFAULT,
883 cert_db_->GetCertTrust(puny_cert, SERVER_CERT));
884 EXPECT_EQ(0U, puny_cert->trust->sslFlags);
885
886 scoped_refptr<X509Certificate> x509_puny_cert =
887 x509_util::CreateX509CertificateFromCERTCertificate(puny_cert);
888 ASSERT_TRUE(x509_puny_cert);
889 scoped_refptr<CertVerifyProc> verify_proc(
890 CertVerifyProc::CreateBuiltinWithChromeRootStore(
891 /*cert_net_fetcher=*/nullptr, crl_set_, /*root_store_data=*/nullptr,
892 /*instance_params=*/{}));
893 int flags = 0;
894 CertVerifyResult verify_result;
895 int error = verify_proc->Verify(x509_puny_cert.get(), "xn--wgv71a119e.com",
896 /*ocsp_response=*/std::string(),
897 /*sct_list=*/std::string(), flags,
898 &verify_result, NetLogWithSource());
899 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
900 EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, verify_result.cert_status);
901
902 base::RunLoop().RunUntilIdle();
903 EXPECT_EQ(0, observer_->client_cert_store_changes());
904 EXPECT_EQ(0, observer_->trust_store_changes());
905 }
906
TEST_F(CertDatabaseNSSTest,ImportServerCert_SelfSigned_Trusted)907 TEST_F(CertDatabaseNSSTest, ImportServerCert_SelfSigned_Trusted) {
908 ScopedCERTCertificateList certs;
909 ASSERT_TRUE(ReadCertIntoList("punycodetest.pem", &certs));
910
911 NSSCertDatabase::ImportCertFailureList failed;
912 EXPECT_TRUE(cert_db_->ImportServerCert(certs, NSSCertDatabase::TRUSTED_SSL,
913 &failed));
914
915 EXPECT_EQ(0U, failed.size());
916
917 ScopedCERTCertificateList cert_list = ListCerts();
918 ASSERT_EQ(1U, cert_list.size());
919 CERTCertificate* puny_cert = cert_list[0].get();
920
921 EXPECT_EQ(NSSCertDatabase::TRUSTED_SSL,
922 cert_db_->GetCertTrust(puny_cert, SERVER_CERT));
923 EXPECT_EQ(unsigned(CERTDB_TRUSTED | CERTDB_TERMINAL_RECORD),
924 puny_cert->trust->sslFlags);
925
926 scoped_refptr<X509Certificate> x509_puny_cert =
927 x509_util::CreateX509CertificateFromCERTCertificate(puny_cert);
928 ASSERT_TRUE(x509_puny_cert);
929 scoped_refptr<CertVerifyProc> verify_proc(
930 CertVerifyProc::CreateBuiltinWithChromeRootStore(
931 /*cert_net_fetcher=*/nullptr, crl_set_, /*root_store_data=*/nullptr,
932 /*instance_params=*/{}));
933 int flags = 0;
934 CertVerifyResult verify_result;
935 int error = verify_proc->Verify(x509_puny_cert.get(), "xn--wgv71a119e.com",
936 /*ocsp_response=*/std::string(),
937 /*sct_list=*/std::string(), flags,
938 &verify_result, NetLogWithSource());
939 if (base::FeatureList::IsEnabled(features::kTrustStoreTrustedLeafSupport)) {
940 EXPECT_THAT(error, IsOk());
941 EXPECT_EQ(0U, verify_result.cert_status);
942 } else {
943 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
944 EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, verify_result.cert_status);
945 }
946
947 base::RunLoop().RunUntilIdle();
948 EXPECT_EQ(0, observer_->client_cert_store_changes());
949 // TODO(mattm): this should be 1, but ImportServerCert doesn't currently
950 // generate notifications.
951 EXPECT_EQ(0, observer_->trust_store_changes());
952 }
953
TEST_F(CertDatabaseNSSTest,ImportCaAndServerCert)954 TEST_F(CertDatabaseNSSTest, ImportCaAndServerCert) {
955 ScopedCERTCertificateList ca_certs = CreateCERTCertificateListFromFile(
956 GetTestCertsDirectory(), "root_ca_cert.pem",
957 X509Certificate::FORMAT_AUTO);
958 ASSERT_EQ(1U, ca_certs.size());
959
960 // Import CA cert and trust it.
961 NSSCertDatabase::ImportCertFailureList failed;
962 EXPECT_TRUE(cert_db_->ImportCACerts(ca_certs, NSSCertDatabase::TRUSTED_SSL,
963 &failed));
964 EXPECT_EQ(0U, failed.size());
965
966 ScopedCERTCertificateList certs = CreateCERTCertificateListFromFile(
967 GetTestCertsDirectory(), "ok_cert.pem", X509Certificate::FORMAT_AUTO);
968 ASSERT_EQ(1U, certs.size());
969
970 // Import server cert with default trust.
971 EXPECT_TRUE(cert_db_->ImportServerCert(certs, NSSCertDatabase::TRUST_DEFAULT,
972 &failed));
973 EXPECT_EQ(0U, failed.size());
974
975 // Server cert should verify.
976 scoped_refptr<X509Certificate> x509_server_cert =
977 x509_util::CreateX509CertificateFromCERTCertificate(certs[0].get());
978 ASSERT_TRUE(x509_server_cert);
979 scoped_refptr<CertVerifyProc> verify_proc(
980 CertVerifyProc::CreateBuiltinWithChromeRootStore(
981 /*cert_net_fetcher=*/nullptr, crl_set_, /*root_store_data=*/nullptr,
982 /*instance_params=*/{}));
983 int flags = 0;
984 CertVerifyResult verify_result;
985 int error = verify_proc->Verify(x509_server_cert.get(), "127.0.0.1",
986 /*ocsp_response=*/std::string(),
987 /*sct_list=*/std::string(), flags,
988 &verify_result, NetLogWithSource());
989 EXPECT_THAT(error, IsOk());
990 EXPECT_EQ(0U, verify_result.cert_status);
991 }
992
TEST_F(CertDatabaseNSSTest,ImportCaAndServerCert_DistrustServer)993 TEST_F(CertDatabaseNSSTest, ImportCaAndServerCert_DistrustServer) {
994 ScopedCERTCertificateList ca_certs = CreateCERTCertificateListFromFile(
995 GetTestCertsDirectory(), "root_ca_cert.pem",
996 X509Certificate::FORMAT_AUTO);
997 ASSERT_EQ(1U, ca_certs.size());
998
999 // Import CA cert and trust it.
1000 NSSCertDatabase::ImportCertFailureList failed;
1001 EXPECT_TRUE(cert_db_->ImportCACerts(ca_certs, NSSCertDatabase::TRUSTED_SSL,
1002 &failed));
1003 EXPECT_EQ(0U, failed.size());
1004
1005 ScopedCERTCertificateList certs = CreateCERTCertificateListFromFile(
1006 GetTestCertsDirectory(), "ok_cert.pem", X509Certificate::FORMAT_AUTO);
1007 ASSERT_EQ(1U, certs.size());
1008
1009 // Import server cert without inheriting trust from issuer (explicit
1010 // distrust).
1011 EXPECT_TRUE(cert_db_->ImportServerCert(certs, NSSCertDatabase::DISTRUSTED_SSL,
1012 &failed));
1013 EXPECT_EQ(0U, failed.size());
1014 EXPECT_EQ(NSSCertDatabase::DISTRUSTED_SSL,
1015 cert_db_->GetCertTrust(certs[0].get(), SERVER_CERT));
1016
1017 EXPECT_EQ(unsigned(CERTDB_TERMINAL_RECORD), certs[0]->trust->sslFlags);
1018
1019 // Server cert should fail to verify.
1020 scoped_refptr<X509Certificate> x509_server_cert =
1021 x509_util::CreateX509CertificateFromCERTCertificate(certs[0].get());
1022 ASSERT_TRUE(x509_server_cert);
1023 scoped_refptr<CertVerifyProc> verify_proc(
1024 CertVerifyProc::CreateBuiltinWithChromeRootStore(
1025 /*cert_net_fetcher=*/nullptr, crl_set_, /*root_store_data=*/nullptr,
1026 /*instance_params=*/{}));
1027 int flags = 0;
1028 CertVerifyResult verify_result;
1029 int error = verify_proc->Verify(x509_server_cert.get(), "127.0.0.1",
1030 /*ocsp_response=*/std::string(),
1031 /*sct_list=*/std::string(), flags,
1032 &verify_result, NetLogWithSource());
1033 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
1034 EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, verify_result.cert_status);
1035 }
1036
TEST_F(CertDatabaseNSSTest,TrustIntermediateCa)1037 TEST_F(CertDatabaseNSSTest, TrustIntermediateCa) {
1038 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
1039
1040 ScopedCERTCertificateList ca_certs =
1041 x509_util::CreateCERTCertificateListFromX509Certificate(
1042 root->GetX509Certificate().get());
1043 ASSERT_EQ(1U, ca_certs.size());
1044
1045 // Import Root CA cert and distrust it.
1046 NSSCertDatabase::ImportCertFailureList failed;
1047 EXPECT_TRUE(cert_db_->ImportCACerts(ca_certs, NSSCertDatabase::DISTRUSTED_SSL,
1048 &failed));
1049 EXPECT_EQ(0U, failed.size());
1050
1051 base::RunLoop().RunUntilIdle();
1052 EXPECT_EQ(0, observer_->client_cert_store_changes());
1053 EXPECT_EQ(1, observer_->trust_store_changes());
1054
1055 ScopedCERTCertificateList intermediate_certs =
1056 x509_util::CreateCERTCertificateListFromX509Certificate(
1057 intermediate->GetX509Certificate().get());
1058 ASSERT_EQ(1U, intermediate_certs.size());
1059
1060 // Import Intermediate CA cert and trust it.
1061 EXPECT_TRUE(cert_db_->ImportCACerts(intermediate_certs,
1062 NSSCertDatabase::TRUSTED_SSL, &failed));
1063 EXPECT_EQ(0U, failed.size());
1064
1065 base::RunLoop().RunUntilIdle();
1066 EXPECT_EQ(0, observer_->client_cert_store_changes());
1067 EXPECT_EQ(2, observer_->trust_store_changes());
1068
1069 scoped_refptr<X509Certificate> x509_server_cert = leaf->GetX509Certificate();
1070 ScopedCERTCertificateList certs =
1071 x509_util::CreateCERTCertificateListFromX509Certificate(
1072 x509_server_cert.get());
1073 ASSERT_EQ(1U, certs.size());
1074
1075 // Import server cert with default trust.
1076 EXPECT_TRUE(cert_db_->ImportServerCert(certs, NSSCertDatabase::TRUST_DEFAULT,
1077 &failed));
1078 EXPECT_EQ(0U, failed.size());
1079 EXPECT_EQ(NSSCertDatabase::TRUST_DEFAULT,
1080 cert_db_->GetCertTrust(certs[0].get(), SERVER_CERT));
1081
1082 // Server cert should verify.
1083 scoped_refptr<CertVerifyProc> verify_proc(
1084 CertVerifyProc::CreateBuiltinWithChromeRootStore(
1085 /*cert_net_fetcher=*/nullptr, crl_set_, /*root_store_data=*/nullptr,
1086 /*instance_params=*/{}));
1087 int flags = 0;
1088 CertVerifyResult verify_result;
1089 int error = verify_proc->Verify(x509_server_cert.get(), "www.example.com",
1090 /*ocsp_response=*/std::string(),
1091 /*sct_list=*/std::string(), flags,
1092 &verify_result, NetLogWithSource());
1093 EXPECT_THAT(error, IsOk());
1094 EXPECT_EQ(0U, verify_result.cert_status);
1095
1096 // Trust the root cert and distrust the intermediate.
1097 EXPECT_TRUE(cert_db_->SetCertTrust(
1098 ca_certs[0].get(), CA_CERT, NSSCertDatabase::TRUSTED_SSL));
1099 EXPECT_TRUE(cert_db_->SetCertTrust(
1100 intermediate_certs[0].get(), CA_CERT, NSSCertDatabase::DISTRUSTED_SSL));
1101 EXPECT_EQ(
1102 unsigned(CERTDB_VALID_CA | CERTDB_TRUSTED_CA | CERTDB_TRUSTED_CLIENT_CA),
1103 ca_certs[0]->trust->sslFlags);
1104 EXPECT_EQ(unsigned(CERTDB_VALID_CA), ca_certs[0]->trust->emailFlags);
1105 EXPECT_EQ(unsigned(CERTDB_VALID_CA), ca_certs[0]->trust->objectSigningFlags);
1106 EXPECT_EQ(unsigned(CERTDB_TERMINAL_RECORD),
1107 intermediate_certs[0]->trust->sslFlags);
1108 EXPECT_EQ(unsigned(CERTDB_VALID_CA),
1109 intermediate_certs[0]->trust->emailFlags);
1110 EXPECT_EQ(unsigned(CERTDB_VALID_CA),
1111 intermediate_certs[0]->trust->objectSigningFlags);
1112
1113 // Server cert should fail to verify.
1114 CertVerifyResult verify_result2;
1115 error = verify_proc->Verify(x509_server_cert.get(), "www.example.com",
1116 /*ocsp_response=*/std::string(),
1117 /*sct_list=*/std::string(), flags,
1118 &verify_result2, NetLogWithSource());
1119 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
1120 EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, verify_result2.cert_status);
1121 }
1122
TEST_F(CertDatabaseNSSTest,TrustIntermediateCa2)1123 TEST_F(CertDatabaseNSSTest, TrustIntermediateCa2) {
1124 NSSCertDatabase::ImportCertFailureList failed;
1125 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
1126
1127 ScopedCERTCertificateList intermediate_certs =
1128 x509_util::CreateCERTCertificateListFromX509Certificate(
1129 intermediate->GetX509Certificate().get());
1130 ASSERT_EQ(1U, intermediate_certs.size());
1131
1132 // Import Intermediate CA cert and trust it.
1133 EXPECT_TRUE(cert_db_->ImportCACerts(intermediate_certs,
1134 NSSCertDatabase::TRUSTED_SSL, &failed));
1135 EXPECT_EQ(0U, failed.size());
1136
1137 scoped_refptr<X509Certificate> x509_server_cert = leaf->GetX509Certificate();
1138 ScopedCERTCertificateList certs =
1139 x509_util::CreateCERTCertificateListFromX509Certificate(
1140 x509_server_cert.get());
1141
1142 // Import server cert with default trust.
1143 EXPECT_TRUE(cert_db_->ImportServerCert(certs, NSSCertDatabase::TRUST_DEFAULT,
1144 &failed));
1145 EXPECT_EQ(0U, failed.size());
1146 EXPECT_EQ(NSSCertDatabase::TRUST_DEFAULT,
1147 cert_db_->GetCertTrust(certs[0].get(), SERVER_CERT));
1148
1149 // Server cert should verify.
1150 scoped_refptr<CertVerifyProc> verify_proc(
1151 CertVerifyProc::CreateBuiltinWithChromeRootStore(
1152 /*cert_net_fetcher=*/nullptr, crl_set_, /*root_store_data=*/nullptr,
1153 /*instance_params=*/{}));
1154 int flags = 0;
1155 CertVerifyResult verify_result;
1156 int error = verify_proc->Verify(x509_server_cert.get(), "www.example.com",
1157 /*ocsp_response=*/std::string(),
1158 /*sct_list=*/std::string(), flags,
1159 &verify_result, NetLogWithSource());
1160 EXPECT_THAT(error, IsOk());
1161 EXPECT_EQ(0U, verify_result.cert_status);
1162
1163 // Without explicit trust of the intermediate, verification should fail.
1164 EXPECT_TRUE(cert_db_->SetCertTrust(
1165 intermediate_certs[0].get(), CA_CERT, NSSCertDatabase::TRUST_DEFAULT));
1166
1167 // Server cert should fail to verify.
1168 CertVerifyResult verify_result2;
1169 error = verify_proc->Verify(x509_server_cert.get(), "www.example.com",
1170 /*ocsp_response=*/std::string(),
1171 /*sct_list=*/std::string(), flags,
1172 &verify_result2, NetLogWithSource());
1173 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
1174 EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, verify_result2.cert_status);
1175 }
1176
TEST_F(CertDatabaseNSSTest,TrustIntermediateCa3)1177 TEST_F(CertDatabaseNSSTest, TrustIntermediateCa3) {
1178 NSSCertDatabase::ImportCertFailureList failed;
1179 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
1180
1181 ScopedCERTCertificateList ca_certs =
1182 x509_util::CreateCERTCertificateListFromX509Certificate(
1183 root->GetX509Certificate().get());
1184 ASSERT_EQ(1U, ca_certs.size());
1185
1186 // Import Root CA cert and default trust it.
1187 EXPECT_TRUE(cert_db_->ImportCACerts(ca_certs, NSSCertDatabase::TRUST_DEFAULT,
1188 &failed));
1189 EXPECT_EQ(0U, failed.size());
1190
1191 ScopedCERTCertificateList intermediate_certs =
1192 x509_util::CreateCERTCertificateListFromX509Certificate(
1193 intermediate->GetX509Certificate().get());
1194 ASSERT_EQ(1U, intermediate_certs.size());
1195
1196 // Import Intermediate CA cert and trust it.
1197 EXPECT_TRUE(cert_db_->ImportCACerts(intermediate_certs,
1198 NSSCertDatabase::TRUSTED_SSL, &failed));
1199 EXPECT_EQ(0U, failed.size());
1200
1201 scoped_refptr<X509Certificate> x509_server_cert = leaf->GetX509Certificate();
1202 ScopedCERTCertificateList certs =
1203 x509_util::CreateCERTCertificateListFromX509Certificate(
1204 x509_server_cert.get());
1205 ASSERT_EQ(1U, certs.size());
1206
1207 // Import server cert with default trust.
1208 EXPECT_TRUE(cert_db_->ImportServerCert(certs, NSSCertDatabase::TRUST_DEFAULT,
1209 &failed));
1210 EXPECT_EQ(0U, failed.size());
1211 EXPECT_EQ(NSSCertDatabase::TRUST_DEFAULT,
1212 cert_db_->GetCertTrust(certs[0].get(), SERVER_CERT));
1213
1214 // Server cert should verify.
1215 scoped_refptr<CertVerifyProc> verify_proc(
1216 CertVerifyProc::CreateBuiltinWithChromeRootStore(
1217 /*cert_net_fetcher=*/nullptr, crl_set_, /*root_store_data=*/nullptr,
1218 /*instance_params=*/{}));
1219 int flags = 0;
1220 CertVerifyResult verify_result;
1221 int error = verify_proc->Verify(x509_server_cert.get(), "www.example.com",
1222 /*ocsp_response=*/std::string(),
1223 /*sct_list=*/std::string(), flags,
1224 &verify_result, NetLogWithSource());
1225 EXPECT_THAT(error, IsOk());
1226 EXPECT_EQ(0U, verify_result.cert_status);
1227
1228 // Without explicit trust of the intermediate, verification should fail.
1229 EXPECT_TRUE(cert_db_->SetCertTrust(
1230 intermediate_certs[0].get(), CA_CERT, NSSCertDatabase::TRUST_DEFAULT));
1231
1232 // Server cert should fail to verify.
1233 CertVerifyResult verify_result2;
1234 error = verify_proc->Verify(x509_server_cert.get(), "www.example.com",
1235 /*ocsp_response=*/std::string(),
1236 /*sct_list=*/std::string(), flags,
1237 &verify_result2, NetLogWithSource());
1238 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
1239 EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, verify_result2.cert_status);
1240 }
1241
TEST_F(CertDatabaseNSSTest,TrustIntermediateCa4)1242 TEST_F(CertDatabaseNSSTest, TrustIntermediateCa4) {
1243 NSSCertDatabase::ImportCertFailureList failed;
1244 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
1245
1246 ScopedCERTCertificateList ca_certs =
1247 x509_util::CreateCERTCertificateListFromX509Certificate(
1248 root->GetX509Certificate().get());
1249 ASSERT_EQ(1U, ca_certs.size());
1250
1251 // Import Root CA cert and trust it.
1252 EXPECT_TRUE(cert_db_->ImportCACerts(ca_certs, NSSCertDatabase::TRUSTED_SSL,
1253 &failed));
1254 EXPECT_EQ(0U, failed.size());
1255
1256 ScopedCERTCertificateList intermediate_certs =
1257 x509_util::CreateCERTCertificateListFromX509Certificate(
1258 intermediate->GetX509Certificate().get());
1259 ASSERT_EQ(1U, intermediate_certs.size());
1260
1261 // Import Intermediate CA cert and distrust it.
1262 EXPECT_TRUE(cert_db_->ImportCACerts(
1263 intermediate_certs, NSSCertDatabase::DISTRUSTED_SSL, &failed));
1264 EXPECT_EQ(0U, failed.size());
1265
1266 scoped_refptr<X509Certificate> x509_server_cert = leaf->GetX509Certificate();
1267 ScopedCERTCertificateList certs =
1268 x509_util::CreateCERTCertificateListFromX509Certificate(
1269 x509_server_cert.get());
1270 ASSERT_EQ(1U, certs.size());
1271
1272 // Import server cert with default trust.
1273 EXPECT_TRUE(cert_db_->ImportServerCert(certs, NSSCertDatabase::TRUST_DEFAULT,
1274 &failed));
1275 EXPECT_EQ(0U, failed.size());
1276 EXPECT_EQ(NSSCertDatabase::TRUST_DEFAULT,
1277 cert_db_->GetCertTrust(certs[0].get(), SERVER_CERT));
1278
1279 // Server cert should not verify.
1280 scoped_refptr<CertVerifyProc> verify_proc(
1281 CertVerifyProc::CreateBuiltinWithChromeRootStore(
1282 /*cert_net_fetcher=*/nullptr, crl_set_, /*root_store_data=*/nullptr,
1283 /*instance_params=*/{}));
1284 int flags = 0;
1285 CertVerifyResult verify_result;
1286 int error = verify_proc->Verify(x509_server_cert.get(), "www.example.com",
1287 /*ocsp_response=*/std::string(),
1288 /*sct_list=*/std::string(), flags,
1289 &verify_result, NetLogWithSource());
1290 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
1291 EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, verify_result.cert_status);
1292
1293 // Without explicit distrust of the intermediate, verification should succeed.
1294 EXPECT_TRUE(cert_db_->SetCertTrust(
1295 intermediate_certs[0].get(), CA_CERT, NSSCertDatabase::TRUST_DEFAULT));
1296
1297 // Server cert should verify.
1298 CertVerifyResult verify_result2;
1299 error = verify_proc->Verify(x509_server_cert.get(), "www.example.com",
1300 /*ocsp_response=*/std::string(),
1301 /*sct_list=*/std::string(), flags,
1302 &verify_result2, NetLogWithSource());
1303 EXPECT_THAT(error, IsOk());
1304 EXPECT_EQ(0U, verify_result2.cert_status);
1305 }
1306
1307 // Importing two certificates with the same issuer and subject common name,
1308 // but overall distinct subject names, should succeed and generate a unique
1309 // nickname for the second certificate.
TEST_F(CertDatabaseNSSTest,ImportDuplicateCommonName)1310 TEST_F(CertDatabaseNSSTest, ImportDuplicateCommonName) {
1311 ScopedCERTCertificateList certs = CreateCERTCertificateListFromFile(
1312 GetTestCertsDirectory(), "duplicate_cn_1.pem",
1313 X509Certificate::FORMAT_AUTO);
1314 ASSERT_EQ(1U, certs.size());
1315
1316 EXPECT_EQ(0U, ListCerts().size());
1317
1318 // Import server cert with default trust.
1319 NSSCertDatabase::ImportCertFailureList failed;
1320 EXPECT_TRUE(cert_db_->ImportServerCert(certs, NSSCertDatabase::TRUST_DEFAULT,
1321 &failed));
1322 EXPECT_EQ(0U, failed.size());
1323 EXPECT_EQ(NSSCertDatabase::TRUST_DEFAULT,
1324 cert_db_->GetCertTrust(certs[0].get(), SERVER_CERT));
1325
1326 ScopedCERTCertificateList new_certs = ListCerts();
1327 ASSERT_EQ(1U, new_certs.size());
1328
1329 // Now attempt to import a different certificate with the same common name.
1330 ScopedCERTCertificateList certs2 = CreateCERTCertificateListFromFile(
1331 GetTestCertsDirectory(), "duplicate_cn_2.pem",
1332 X509Certificate::FORMAT_AUTO);
1333 ASSERT_EQ(1U, certs2.size());
1334
1335 // Import server cert with default trust.
1336 EXPECT_TRUE(cert_db_->ImportServerCert(certs2, NSSCertDatabase::TRUST_DEFAULT,
1337 &failed));
1338 EXPECT_EQ(0U, failed.size());
1339 EXPECT_EQ(NSSCertDatabase::TRUST_DEFAULT,
1340 cert_db_->GetCertTrust(certs2[0].get(), SERVER_CERT));
1341
1342 new_certs = ListCerts();
1343 ASSERT_EQ(2U, new_certs.size());
1344 EXPECT_STRNE(new_certs[0]->nickname, new_certs[1]->nickname);
1345 }
1346
1347 } // namespace net
1348