• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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