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