• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 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/internal/trust_store_nss.h"
6 
7 #include <cert.h>
8 #include <certdb.h>
9 #include <pkcs11n.h>
10 #include <prtypes.h>
11 
12 #include <memory>
13 
14 #include "base/strings/strcat.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "base/test/scoped_feature_list.h"
17 #include "crypto/scoped_test_nss_db.h"
18 #include "net/base/features.h"
19 #include "net/cert/internal/cert_issuer_source_sync_unittest.h"
20 #include "net/cert/internal/test_helpers.h"
21 #include "net/cert/scoped_nss_types.h"
22 #include "net/cert/x509_util.h"
23 #include "net/cert/x509_util_nss.h"
24 #include "net/test/cert_test_util.h"
25 #include "net/test/test_data_directory.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27 #include "third_party/boringssl/src/include/openssl/pool.h"
28 #include "third_party/boringssl/src/pki/parsed_certificate.h"
29 #include "third_party/boringssl/src/pki/trust_store.h"
30 
31 namespace net {
32 
33 namespace {
34 
TrustTypeToNSSTrust(bssl::CertificateTrustType trust)35 unsigned TrustTypeToNSSTrust(bssl::CertificateTrustType trust) {
36   switch (trust) {
37     case bssl::CertificateTrustType::DISTRUSTED:
38       return CERTDB_TERMINAL_RECORD;
39     case bssl::CertificateTrustType::UNSPECIFIED:
40       return 0;
41     case bssl::CertificateTrustType::TRUSTED_ANCHOR:
42       return CERTDB_TRUSTED_CA | CERTDB_VALID_CA;
43     case bssl::CertificateTrustType::TRUSTED_LEAF:
44       return CERTDB_TRUSTED | CERTDB_TERMINAL_RECORD;
45     case bssl::CertificateTrustType::TRUSTED_ANCHOR_OR_LEAF:
46       return CERTDB_TRUSTED_CA | CERTDB_VALID_CA | CERTDB_TRUSTED |
47              CERTDB_TERMINAL_RECORD;
48   }
49 }
50 
GetASSLTrustedBuiltinRoot()51 std::shared_ptr<const bssl::ParsedCertificate> GetASSLTrustedBuiltinRoot() {
52   bssl::CertErrors parsing_errors;
53   ScopedCERTCertificate nss_cert = GetAnNssBuiltinSslTrustedRoot();
54   if (!nss_cert) {
55     return nullptr;
56   }
57   scoped_refptr<X509Certificate> ssl_trusted_root =
58       x509_util::CreateX509CertificateFromCERTCertificate(nss_cert.get());
59   if (!ssl_trusted_root) {
60     return nullptr;
61   }
62   return bssl::ParsedCertificate::Create(
63       bssl::UpRef(ssl_trusted_root->cert_buffer()),
64       x509_util::DefaultParseCertificateOptions(), &parsing_errors);
65 }
66 
GetNSSTrustForCert(const bssl::ParsedCertificate * cert)67 std::optional<unsigned> GetNSSTrustForCert(
68     const bssl::ParsedCertificate* cert) {
69   SECItem der_cert;
70   der_cert.data = const_cast<uint8_t*>(cert->der_cert().data());
71   der_cert.len = base::checked_cast<unsigned>(cert->der_cert().size());
72   der_cert.type = siDERCertBuffer;
73   ScopedCERTCertificate nss_cert(
74       CERT_FindCertByDERCert(CERT_GetDefaultCertDB(), &der_cert));
75   if (!nss_cert) {
76     return std::nullopt;
77   }
78 
79   CERTCertTrust nss_cert_trust;
80   if (CERT_GetCertTrust(nss_cert.get(), &nss_cert_trust) != SECSuccess) {
81     return std::nullopt;
82   }
83 
84   return SEC_GET_TRUST_FLAGS(&nss_cert_trust, trustSSL);
85 }
86 
87 class TrustStoreNSSTestBase : public ::testing::Test {
88  public:
ExpectedTrustForBuiltinAnchor() const89   bssl::CertificateTrust ExpectedTrustForBuiltinAnchor() const {
90     return bssl::CertificateTrust::ForTrustAnchor();
91   }
92 
ExpectedTrustForAnchor() const93   bssl::CertificateTrust ExpectedTrustForAnchor() const {
94     return bssl::CertificateTrust::ForTrustAnchor()
95         .WithEnforceAnchorConstraints()
96         .WithEnforceAnchorExpiry();
97   }
98 
ExpectedTrustForAnchorOrLeaf() const99   bssl::CertificateTrust ExpectedTrustForAnchorOrLeaf() const {
100     return bssl::CertificateTrust::ForTrustAnchorOrLeaf()
101         .WithEnforceAnchorConstraints()
102         .WithEnforceAnchorExpiry();
103   }
104 
ExpectedTrustForLeaf() const105   bssl::CertificateTrust ExpectedTrustForLeaf() const {
106     return bssl::CertificateTrust::ForTrustedLeaf();
107   }
108 
SetUp()109   void SetUp() override {
110     ASSERT_TRUE(first_test_nssdb_.is_open());
111     ASSERT_TRUE(test_nssdb_.is_open());
112     ASSERT_TRUE(other_test_nssdb_.is_open());
113     bssl::ParsedCertificateList chain;
114     ReadCertChainFromFile(
115         "net/data/verify_certificate_chain_unittest/key-rollover/oldchain.pem",
116         &chain);
117 
118     ASSERT_EQ(3U, chain.size());
119     target_ = chain[0];
120     oldintermediate_ = chain[1];
121     oldroot_ = chain[2];
122     ASSERT_TRUE(target_);
123     ASSERT_TRUE(oldintermediate_);
124     ASSERT_TRUE(oldroot_);
125 
126     ReadCertChainFromFile(
127         "net/data/verify_certificate_chain_unittest/"
128         "key-rollover/longrolloverchain.pem",
129         &chain);
130 
131     ASSERT_EQ(5U, chain.size());
132     newintermediate_ = chain[1];
133     newroot_ = chain[2];
134     newrootrollover_ = chain[3];
135     ASSERT_TRUE(newintermediate_);
136     ASSERT_TRUE(newroot_);
137     ASSERT_TRUE(newrootrollover_);
138 
139     trust_store_nss_ = CreateTrustStoreNSS();
140   }
141 
142   // Creates the TrustStoreNSS instance. Subclasses will customize the slot
143   // filtering behavior here.
144   virtual std::unique_ptr<TrustStoreNSS> CreateTrustStoreNSS() = 0;
145 
GetUniqueNickname()146   std::string GetUniqueNickname() {
147     return "trust_store_nss_unittest" +
148            base::NumberToString(nickname_counter_++);
149   }
150 
AddCertToNSSSlot(const bssl::ParsedCertificate * cert,PK11SlotInfo * slot)151   void AddCertToNSSSlot(const bssl::ParsedCertificate* cert,
152                         PK11SlotInfo* slot) {
153     ScopedCERTCertificate nss_cert(
154         x509_util::CreateCERTCertificateFromBytes(cert->der_cert()));
155     ASSERT_TRUE(nss_cert);
156     SECStatus srv = PK11_ImportCert(slot, nss_cert.get(), CK_INVALID_HANDLE,
157                                     GetUniqueNickname().c_str(),
158                                     PR_FALSE /* includeTrust (unused) */);
159     ASSERT_EQ(SECSuccess, srv);
160   }
161 
162   // Import `cert` into `slot` and create a trust record with `trust` type.
163   // Tries to ensure that the created trust record ends up in the same `slot`.
164   // (That isn't always the case if `cert` exists in multiple slots and
165   // CERT_ChangeCertTrust was just used on an arbitrary CERTCertificate handle
166   // for `cert`.)
AddCertToNSSSlotWithTrust(const bssl::ParsedCertificate * cert,PK11SlotInfo * slot,bssl::CertificateTrustType trust)167   void AddCertToNSSSlotWithTrust(const bssl::ParsedCertificate* cert,
168                                  PK11SlotInfo* slot,
169                                  bssl::CertificateTrustType trust) {
170     AddCertToNSSSlot(cert, slot);
171     ChangeCertTrustInSlot(cert, slot, trust);
172   }
173 
AddCertsToNSS()174   void AddCertsToNSS() {
175     AddCertToNSSSlot(target_.get(), test_nssdb_.slot());
176     AddCertToNSSSlot(oldintermediate_.get(), test_nssdb_.slot());
177     AddCertToNSSSlot(newintermediate_.get(), test_nssdb_.slot());
178     AddCertToNSSSlot(oldroot_.get(), test_nssdb_.slot());
179     AddCertToNSSSlot(newroot_.get(), test_nssdb_.slot());
180     AddCertToNSSSlot(newrootrollover_.get(), test_nssdb_.slot());
181 
182     // Check that the certificates can be retrieved as expected.
183     EXPECT_TRUE(
184         TrustStoreContains(target_, {newintermediate_, oldintermediate_}));
185 
186     EXPECT_TRUE(TrustStoreContains(newintermediate_,
187                                    {newroot_, newrootrollover_, oldroot_}));
188     EXPECT_TRUE(TrustStoreContains(oldintermediate_,
189                                    {newroot_, newrootrollover_, oldroot_}));
190     EXPECT_TRUE(TrustStoreContains(newrootrollover_,
191                                    {newroot_, newrootrollover_, oldroot_}));
192     EXPECT_TRUE(
193         TrustStoreContains(oldroot_, {newroot_, newrootrollover_, oldroot_}));
194     EXPECT_TRUE(
195         TrustStoreContains(newroot_, {newroot_, newrootrollover_, oldroot_}));
196   }
197 
198   // Trusts |cert|. Assumes the cert was already imported into NSS.
TrustCert(const bssl::ParsedCertificate * cert)199   void TrustCert(const bssl::ParsedCertificate* cert) {
200     ChangeCertTrust(cert, CERTDB_TRUSTED_CA | CERTDB_VALID_CA);
201   }
202 
203   // Trusts |cert| as a server, but not as a CA. Assumes the cert was already
204   // imported into NSS.
TrustServerCert(const bssl::ParsedCertificate * cert)205   void TrustServerCert(const bssl::ParsedCertificate* cert) {
206     ChangeCertTrust(cert, CERTDB_TERMINAL_RECORD | CERTDB_TRUSTED);
207   }
208 
209   // Trusts |cert| as both a server and as a CA. Assumes the cert was already
210   // imported into NSS.
TrustCaAndServerCert(const bssl::ParsedCertificate * cert)211   void TrustCaAndServerCert(const bssl::ParsedCertificate* cert) {
212     ChangeCertTrust(cert, CERTDB_TERMINAL_RECORD | CERTDB_TRUSTED |
213                               CERTDB_TRUSTED_CA | CERTDB_VALID_CA);
214   }
215 
216   // Distrusts |cert|. Assumes the cert was already imported into NSS.
DistrustCert(const bssl::ParsedCertificate * cert)217   void DistrustCert(const bssl::ParsedCertificate* cert) {
218     ChangeCertTrust(cert, CERTDB_TERMINAL_RECORD);
219   }
220 
ChangeCertTrust(const bssl::ParsedCertificate * cert,int flags)221   void ChangeCertTrust(const bssl::ParsedCertificate* cert, int flags) {
222     SECItem der_cert;
223     der_cert.data = const_cast<uint8_t*>(cert->der_cert().data());
224     der_cert.len = base::checked_cast<unsigned>(cert->der_cert().size());
225     der_cert.type = siDERCertBuffer;
226 
227     ScopedCERTCertificate nss_cert(
228         CERT_FindCertByDERCert(CERT_GetDefaultCertDB(), &der_cert));
229     ASSERT_TRUE(nss_cert);
230 
231     CERTCertTrust trust = {0};
232     trust.sslFlags = flags;
233     SECStatus srv =
234         CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), nss_cert.get(), &trust);
235     ASSERT_EQ(SECSuccess, srv);
236   }
237 
238   // Change the trust for `cert` in `slot` to `trust`.
239   // `cert` must already exist in `slot'.
240   // Tries to ensure that the created trust record ends up in the same `slot`.
241   // (That isn't always the case if `cert` exists in multiple slots and
242   // CERT_ChangeCertTrust was just used on an arbitrary CERTCertificate handle
243   // for `cert`.)
244   // (An alternative approach would be to create the CKO_NSS_TRUST object
245   // directly using PK11_CreateManagedGenericObject, which has the advantage of
246   // being able to specify the slot directly, but the disadvantage that there's
247   // no guarantee the way the test creates the trust object matches what NSS
248   // actually does. See
249   // https://crrev.com/c/3732801/9/net/cert/internal/trust_store_nss_unittest.cc#412
250   // for some example code if that's ever needed.)
ChangeCertTrustInSlot(const bssl::ParsedCertificate * cert,PK11SlotInfo * slot,bssl::CertificateTrustType trust)251   void ChangeCertTrustInSlot(const bssl::ParsedCertificate* cert,
252                              PK11SlotInfo* slot,
253                              bssl::CertificateTrustType trust) {
254     crypto::ScopedCERTCertList cert_list(PK11_ListCertsInSlot(slot));
255     ASSERT_TRUE(cert_list);
256 
257     for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list);
258          !CERT_LIST_END(node, cert_list); node = CERT_LIST_NEXT(node)) {
259       if (x509_util::IsSameCertificate(node->cert, cert->cert_buffer())) {
260         CERTCertTrust nss_trust = {0};
261         nss_trust.sslFlags = TrustTypeToNSSTrust(trust);
262         if (CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), node->cert,
263                                  &nss_trust) != SECSuccess) {
264           ADD_FAILURE() << "CERT_ChangeCertTrust failed: " << PORT_GetError();
265         }
266         return;
267       }
268     }
269     ADD_FAILURE() << "cert not found in slot";
270   }
271 
272  protected:
TrustStoreContains(std::shared_ptr<const bssl::ParsedCertificate> cert,bssl::ParsedCertificateList expected_matches)273   bool TrustStoreContains(std::shared_ptr<const bssl::ParsedCertificate> cert,
274                           bssl::ParsedCertificateList expected_matches) {
275     bssl::ParsedCertificateList matches;
276     trust_store_nss_->SyncGetIssuersOf(cert.get(), &matches);
277 
278     std::vector<std::string> name_result_matches;
279     for (const auto& it : matches)
280       name_result_matches.push_back(GetCertString(it));
281     std::sort(name_result_matches.begin(), name_result_matches.end());
282 
283     std::vector<std::string> name_expected_matches;
284     for (const auto& it : expected_matches)
285       name_expected_matches.push_back(GetCertString(it));
286     std::sort(name_expected_matches.begin(), name_expected_matches.end());
287 
288     if (name_expected_matches == name_result_matches)
289       return true;
290 
291     // Print some extra information for debugging.
292     EXPECT_EQ(name_expected_matches, name_result_matches);
293     return false;
294   }
295 
296   // Give simpler names to certificate DER (for identifying them in tests by
297   // their symbolic name).
GetCertString(const std::shared_ptr<const bssl::ParsedCertificate> & cert) const298   std::string GetCertString(
299       const std::shared_ptr<const bssl::ParsedCertificate>& cert) const {
300     if (cert->der_cert() == oldroot_->der_cert())
301       return "oldroot_";
302     if (cert->der_cert() == newroot_->der_cert())
303       return "newroot_";
304     if (cert->der_cert() == target_->der_cert())
305       return "target_";
306     if (cert->der_cert() == oldintermediate_->der_cert())
307       return "oldintermediate_";
308     if (cert->der_cert() == newintermediate_->der_cert())
309       return "newintermediate_";
310     if (cert->der_cert() == newrootrollover_->der_cert())
311       return "newrootrollover_";
312     return cert->der_cert().AsString();
313   }
314 
HasTrust(const bssl::ParsedCertificateList & certs,bssl::CertificateTrust expected_trust)315   bool HasTrust(const bssl::ParsedCertificateList& certs,
316                 bssl::CertificateTrust expected_trust) {
317     bool success = true;
318     for (const std::shared_ptr<const bssl::ParsedCertificate>& cert : certs) {
319       bssl::CertificateTrust trust = trust_store_nss_->GetTrust(cert.get());
320       std::string trust_string = trust.ToDebugString();
321       std::string expected_trust_string = expected_trust.ToDebugString();
322       if (trust_string != expected_trust_string) {
323         EXPECT_EQ(expected_trust_string, trust_string) << GetCertString(cert);
324         success = false;
325       }
326     }
327 
328     return success;
329   }
330 
331   std::shared_ptr<const bssl::ParsedCertificate> oldroot_;
332   std::shared_ptr<const bssl::ParsedCertificate> newroot_;
333 
334   std::shared_ptr<const bssl::ParsedCertificate> target_;
335   std::shared_ptr<const bssl::ParsedCertificate> oldintermediate_;
336   std::shared_ptr<const bssl::ParsedCertificate> newintermediate_;
337   std::shared_ptr<const bssl::ParsedCertificate> newrootrollover_;
338   crypto::ScopedTestNSSDB first_test_nssdb_;
339   crypto::ScopedTestNSSDB test_nssdb_;
340   crypto::ScopedTestNSSDB other_test_nssdb_;
341   std::unique_ptr<TrustStoreNSS> trust_store_nss_;
342   unsigned nickname_counter_ = 0;
343 };
344 
345 // Specifies which kind of per-slot filtering the TrustStoreNSS is supposed to
346 // perform in the parametrized TrustStoreNSSTestWithSlotFilterType.
347 enum class SlotFilterType {
348   kDontFilter,
349   kAllowSpecifiedUserSlot
350 };
351 
SlotFilterTypeToString(SlotFilterType slot_filter_type)352 std::string SlotFilterTypeToString(SlotFilterType slot_filter_type) {
353   switch (slot_filter_type) {
354     case SlotFilterType::kDontFilter:
355       return "DontFilter";
356     case SlotFilterType::kAllowSpecifiedUserSlot:
357       return "AllowSpecifiedUserSlot";
358   }
359 }
360 
361 // Used for testing a TrustStoreNSS with the slot filter type specified by the
362 // test parameter. These tests are cases that are expected to be the same
363 // regardless of the slot filter type.
364 class TrustStoreNSSTestWithSlotFilterType
365     : public TrustStoreNSSTestBase,
366       public testing::WithParamInterface<SlotFilterType> {
367  public:
368   TrustStoreNSSTestWithSlotFilterType() = default;
369   ~TrustStoreNSSTestWithSlotFilterType() override = default;
370 
slot_filter_type() const371   SlotFilterType slot_filter_type() const { return GetParam(); }
372 
CreateTrustStoreNSS()373   std::unique_ptr<TrustStoreNSS> CreateTrustStoreNSS() override {
374     switch (slot_filter_type()) {
375       case SlotFilterType::kDontFilter:
376         return std::make_unique<TrustStoreNSS>(
377             TrustStoreNSS::UseTrustFromAllUserSlots());
378       case SlotFilterType::kAllowSpecifiedUserSlot:
379         return std::make_unique<TrustStoreNSS>(
380             crypto::ScopedPK11Slot(PK11_ReferenceSlot(test_nssdb_.slot())));
381     }
382   }
383 };
384 
385 // Without adding any certs to the NSS DB, should get no anchor results for
386 // any of the test certs.
TEST_P(TrustStoreNSSTestWithSlotFilterType,CertsNotPresent)387 TEST_P(TrustStoreNSSTestWithSlotFilterType, CertsNotPresent) {
388   EXPECT_TRUE(TrustStoreContains(target_, bssl::ParsedCertificateList()));
389   EXPECT_TRUE(
390       TrustStoreContains(newintermediate_, bssl::ParsedCertificateList()));
391   EXPECT_TRUE(TrustStoreContains(newroot_, bssl::ParsedCertificateList()));
392   EXPECT_TRUE(HasTrust({target_}, bssl::CertificateTrust::ForUnspecified()));
393   EXPECT_TRUE(
394       HasTrust({newintermediate_}, bssl::CertificateTrust::ForUnspecified()));
395   EXPECT_TRUE(HasTrust({newroot_}, bssl::CertificateTrust::ForUnspecified()));
396 }
397 
398 // TrustStoreNSS should return temporary certs on Chrome OS, because on Chrome
399 // OS temporary certs are used to supply policy-provided untrusted authority
400 // certs. (See https://crbug.com/978854)
401 // On other platforms it's not required but doesn't hurt anything.
TEST_P(TrustStoreNSSTestWithSlotFilterType,TempCertPresent)402 TEST_P(TrustStoreNSSTestWithSlotFilterType, TempCertPresent) {
403   ScopedCERTCertificate temp_nss_cert(
404       x509_util::CreateCERTCertificateFromBytes(newintermediate_->der_cert()));
405   EXPECT_TRUE(TrustStoreContains(target_, {newintermediate_}));
406   EXPECT_TRUE(HasTrust({target_}, bssl::CertificateTrust::ForUnspecified()));
407 }
408 
409 // Independent of the specified slot-based filtering mode, built-in root certs
410 // should never be trusted.
TEST_P(TrustStoreNSSTestWithSlotFilterType,TrustAllowedForBuiltinRootCerts)411 TEST_P(TrustStoreNSSTestWithSlotFilterType, TrustAllowedForBuiltinRootCerts) {
412   auto builtin_root_cert = GetASSLTrustedBuiltinRoot();
413   ASSERT_TRUE(builtin_root_cert);
414   EXPECT_TRUE(
415       HasTrust({builtin_root_cert}, bssl::CertificateTrust::ForUnspecified()));
416 }
417 
418 // Check that ListCertsIgnoringNSSRoots and GetAllUserAddedCerts don't
419 // return built-in roots.
TEST_P(TrustStoreNSSTestWithSlotFilterType,ListCertsIgnoresBuiltinRoots)420 TEST_P(TrustStoreNSSTestWithSlotFilterType, ListCertsIgnoresBuiltinRoots) {
421   ScopedCERTCertificate root_cert = GetAnNssBuiltinSslTrustedRoot();
422   ASSERT_TRUE(root_cert);
423 
424   for (const auto& result :
425        trust_store_nss_->TrustStoreNSS::ListCertsIgnoringNSSRoots()) {
426     EXPECT_FALSE(
427         x509_util::IsSameCertificate(result.cert.get(), root_cert.get()));
428   }
429 
430   for (const auto& cert_with_trust : trust_store_nss_->GetAllUserAddedCerts()) {
431     EXPECT_FALSE(x509_util::IsSameCertificate(
432         x509_util::CreateCryptoBuffer(cert_with_trust.cert_bytes).get(),
433         root_cert.get()));
434   }
435 }
436 
437 // Check that GetAllUserAddedCerts doesn't return any client certs, as it is
438 // only supposed to return server certs.
TEST_P(TrustStoreNSSTestWithSlotFilterType,GetAllUserAddedCertsNoClientCerts)439 TEST_P(TrustStoreNSSTestWithSlotFilterType, GetAllUserAddedCertsNoClientCerts) {
440   scoped_refptr<X509Certificate> client_cert =
441       ImportClientCertAndKeyFromFile(GetTestCertsDirectory(), "client_1.pem",
442                                      "client_1.pk8", test_nssdb_.slot());
443   ASSERT_TRUE(client_cert);
444 
445   bool found = false;
446   for (const auto& result :
447        trust_store_nss_->TrustStoreNSS::ListCertsIgnoringNSSRoots()) {
448     found |= x509_util::IsSameCertificate(result.cert.get(), client_cert.get());
449   }
450   EXPECT_TRUE(found);
451 
452   for (const auto& cert_with_trust : trust_store_nss_->GetAllUserAddedCerts()) {
453     EXPECT_FALSE(x509_util::CryptoBufferEqual(
454         x509_util::CreateCryptoBuffer(cert_with_trust.cert_bytes).get(),
455         client_cert->cert_buffer()));
456   }
457 }
458 
459 // Check that GetAllUserAddedCerts will return a client cert that has had trust
460 // bits added for server auth.
TEST_P(TrustStoreNSSTestWithSlotFilterType,GetAllUserAddedCertsManualTrustClientCert)461 TEST_P(TrustStoreNSSTestWithSlotFilterType,
462        GetAllUserAddedCertsManualTrustClientCert) {
463   scoped_refptr<X509Certificate> client_cert =
464       ImportClientCertAndKeyFromFile(GetTestCertsDirectory(), "client_1.pem",
465                                      "client_1.pk8", test_nssdb_.slot());
466   ASSERT_TRUE(client_cert);
467   std::shared_ptr<const bssl::ParsedCertificate> parsed_client_cert =
468       bssl::ParsedCertificate::Create(
469           bssl::UpRef(client_cert->cert_buffer()),
470           x509_util::DefaultParseCertificateOptions(), nullptr);
471   ASSERT_TRUE(parsed_client_cert);
472   TrustCert(parsed_client_cert.get());
473 
474   {
475     bool found = false;
476     for (const auto& result :
477          trust_store_nss_->TrustStoreNSS::ListCertsIgnoringNSSRoots()) {
478       found |=
479           x509_util::IsSameCertificate(result.cert.get(), client_cert.get());
480     }
481     EXPECT_TRUE(found);
482   }
483 
484   {
485     bool found = false;
486     for (const auto& cert_with_trust :
487          trust_store_nss_->GetAllUserAddedCerts()) {
488       found |= x509_util::CryptoBufferEqual(
489           x509_util::CreateCryptoBuffer(cert_with_trust.cert_bytes).get(),
490           client_cert->cert_buffer());
491     }
492     EXPECT_TRUE(found);
493   }
494 }
495 
496 INSTANTIATE_TEST_SUITE_P(
497     All,
498     TrustStoreNSSTestWithSlotFilterType,
499     ::testing::Values(SlotFilterType::kDontFilter,
500                       SlotFilterType::kAllowSpecifiedUserSlot),
501     [](const testing::TestParamInfo<
__anon07ef865a0202(const testing::TestParamInfo< TrustStoreNSSTestWithSlotFilterType::ParamType>& info) 502         TrustStoreNSSTestWithSlotFilterType::ParamType>& info) {
503       return SlotFilterTypeToString(info.param);
504     });
505 
506 // Tests a TrustStoreNSS that ignores system root certs.
507 class TrustStoreNSSTestIgnoreSystemCerts : public TrustStoreNSSTestBase {
508  public:
CreateTrustStoreNSS()509   std::unique_ptr<TrustStoreNSS> CreateTrustStoreNSS() override {
510     return std::make_unique<TrustStoreNSS>(
511         TrustStoreNSS::UseTrustFromAllUserSlots());
512   }
513 };
514 
TEST_F(TrustStoreNSSTestIgnoreSystemCerts,UnknownCertIgnored)515 TEST_F(TrustStoreNSSTestIgnoreSystemCerts, UnknownCertIgnored) {
516   EXPECT_TRUE(HasTrust({newroot_}, bssl::CertificateTrust::ForUnspecified()));
517 }
518 
519 // An NSS CERTCertificate object exists for the cert, but it is not
520 // imported into any DB. Should be unspecified trust.
TEST_F(TrustStoreNSSTestIgnoreSystemCerts,TemporaryCertIgnored)521 TEST_F(TrustStoreNSSTestIgnoreSystemCerts, TemporaryCertIgnored) {
522   ScopedCERTCertificate nss_cert(
523       x509_util::CreateCERTCertificateFromBytes(newroot_->der_cert()));
524   EXPECT_TRUE(HasTrust({newroot_}, bssl::CertificateTrust::ForUnspecified()));
525 }
526 
527 // Cert is added to user DB, but without explicitly calling
528 // CERT_ChangeCertTrust. Should be unspecified trust.
TEST_F(TrustStoreNSSTestIgnoreSystemCerts,UserCertWithNoTrust)529 TEST_F(TrustStoreNSSTestIgnoreSystemCerts, UserCertWithNoTrust) {
530   AddCertsToNSS();
531   EXPECT_TRUE(HasTrust({newroot_}, bssl::CertificateTrust::ForUnspecified()));
532 }
533 
TEST_F(TrustStoreNSSTestIgnoreSystemCerts,UserRootTrusted)534 TEST_F(TrustStoreNSSTestIgnoreSystemCerts, UserRootTrusted) {
535   AddCertsToNSS();
536   TrustCert(newroot_.get());
537   EXPECT_TRUE(HasTrust({newroot_}, ExpectedTrustForAnchor()));
538 }
539 
TEST_F(TrustStoreNSSTestIgnoreSystemCerts,UserRootDistrusted)540 TEST_F(TrustStoreNSSTestIgnoreSystemCerts, UserRootDistrusted) {
541   AddCertsToNSS();
542   DistrustCert(newroot_.get());
543   EXPECT_TRUE(HasTrust({newroot_}, bssl::CertificateTrust::ForDistrusted()));
544 }
545 
TEST_F(TrustStoreNSSTestIgnoreSystemCerts,UserTrustedServer)546 TEST_F(TrustStoreNSSTestIgnoreSystemCerts, UserTrustedServer) {
547   AddCertsToNSS();
548   TrustServerCert(target_.get());
549   EXPECT_TRUE(HasTrust({target_}, ExpectedTrustForLeaf()));
550 }
551 
TEST_F(TrustStoreNSSTestIgnoreSystemCerts,UserTrustedCaAndServer)552 TEST_F(TrustStoreNSSTestIgnoreSystemCerts, UserTrustedCaAndServer) {
553   AddCertsToNSS();
554   TrustCaAndServerCert(target_.get());
555   EXPECT_TRUE(HasTrust({target_}, ExpectedTrustForAnchorOrLeaf()));
556 }
557 
TEST_F(TrustStoreNSSTestIgnoreSystemCerts,SystemRootCertIgnored)558 TEST_F(TrustStoreNSSTestIgnoreSystemCerts, SystemRootCertIgnored) {
559   std::shared_ptr<const bssl::ParsedCertificate> system_root =
560       GetASSLTrustedBuiltinRoot();
561   ASSERT_TRUE(system_root);
562   EXPECT_TRUE(
563       HasTrust({system_root}, bssl::CertificateTrust::ForUnspecified()));
564 }
565 
566 // A system trusted root is also present in a user DB, but without any trust
567 // settings in the user DB. The system trust settings should not be used.
TEST_F(TrustStoreNSSTestIgnoreSystemCerts,SystemRootCertIgnoredWhenPresentInUserDb)568 TEST_F(TrustStoreNSSTestIgnoreSystemCerts,
569        SystemRootCertIgnoredWhenPresentInUserDb) {
570   std::shared_ptr<const bssl::ParsedCertificate> system_root =
571       GetASSLTrustedBuiltinRoot();
572   ASSERT_TRUE(system_root);
573 
574   AddCertToNSSSlot(system_root.get(), test_nssdb_.slot());
575 
576   // TrustStoreNSS should see an Unspecified since we are ignoring the system
577   // slot.
578   EXPECT_TRUE(
579       HasTrust({system_root}, bssl::CertificateTrust::ForUnspecified()));
580 }
581 
582 // A system trusted root is also present in a user DB, with TRUSTED_CA settings
583 // in the user DB. The system trust settings should not be used, but the trust
584 // from the user DB should be honored.
TEST_F(TrustStoreNSSTestIgnoreSystemCerts,UserDbTrustForSystemRootHonored)585 TEST_F(TrustStoreNSSTestIgnoreSystemCerts, UserDbTrustForSystemRootHonored) {
586   std::shared_ptr<const bssl::ParsedCertificate> system_root =
587       GetASSLTrustedBuiltinRoot();
588   ASSERT_TRUE(system_root);
589 
590   AddCertToNSSSlotWithTrust(system_root.get(), test_nssdb_.slot(),
591                             bssl::CertificateTrustType::TRUSTED_ANCHOR);
592   // NSS should see the cert as trusted.
593   EXPECT_EQ(CERTDB_TRUSTED_CA | CERTDB_VALID_CA,
594             GetNSSTrustForCert(system_root.get()));
595 
596   // TrustStoreNSS should see as TrustAnchor since the cert was trusted in the
597   // user slot.
598   EXPECT_TRUE(HasTrust({system_root}, ExpectedTrustForAnchor()));
599 }
600 
601 // A system trusted root is also present in a user DB, with leaf trust in the
602 // user DB. The system trust settings should not be used, but the trust from
603 // the user DB should be honored.
TEST_F(TrustStoreNSSTestIgnoreSystemCerts,UserDbLeafTrustForSystemRootHonored)604 TEST_F(TrustStoreNSSTestIgnoreSystemCerts,
605        UserDbLeafTrustForSystemRootHonored) {
606   std::shared_ptr<const bssl::ParsedCertificate> system_root =
607       GetASSLTrustedBuiltinRoot();
608   ASSERT_TRUE(system_root);
609 
610   // Add unrelated trust record to test that we find the correct one.
611   AddCertToNSSSlotWithTrust(newroot_.get(), test_nssdb_.slot(),
612                             bssl::CertificateTrustType::TRUSTED_ANCHOR);
613 
614   // Trust the system cert as a leaf.
615   AddCertToNSSSlotWithTrust(system_root.get(), test_nssdb_.slot(),
616                             bssl::CertificateTrustType::TRUSTED_LEAF);
617 
618   // Add unrelated trust record to test that we find the correct one.
619   AddCertToNSSSlotWithTrust(newintermediate_.get(), test_nssdb_.slot(),
620                             bssl::CertificateTrustType::DISTRUSTED);
621 
622   // NSS should see the cert as a trusted leaf.
623   EXPECT_EQ(CERTDB_TRUSTED | CERTDB_TERMINAL_RECORD,
624             GetNSSTrustForCert(system_root.get()));
625 
626   // TrustStoreNSS should see as TrustedLeaf since the cert was trusted in the
627   // user slot.
628   EXPECT_TRUE(HasTrust({system_root}, ExpectedTrustForLeaf()));
629 }
630 
631 // A system trusted root is also present in a user DB, with both CA and leaf
632 // trust in the user DB. The system trust settings should not be used, but the
633 // trust from the user DB should be honored.
TEST_F(TrustStoreNSSTestIgnoreSystemCerts,UserDbAnchorAndLeafTrustForSystemRootHonored)634 TEST_F(TrustStoreNSSTestIgnoreSystemCerts,
635        UserDbAnchorAndLeafTrustForSystemRootHonored) {
636   std::shared_ptr<const bssl::ParsedCertificate> system_root =
637       GetASSLTrustedBuiltinRoot();
638   ASSERT_TRUE(system_root);
639 
640   AddCertToNSSSlotWithTrust(system_root.get(), test_nssdb_.slot(),
641                             bssl::CertificateTrustType::TRUSTED_ANCHOR_OR_LEAF);
642 
643   // NSS should see the cert as both trusted leaf and CA.
644   EXPECT_EQ(CERTDB_TRUSTED_CA | CERTDB_VALID_CA | CERTDB_TRUSTED |
645                 CERTDB_TERMINAL_RECORD,
646             GetNSSTrustForCert(system_root.get()));
647 
648   // TrustStoreNSS should see as TrustAnchor since the cert was trusted in the
649   // user slot. The TrustStoreNSS implementation isn't able to pick up both the
650   // CA and Leaf trust in this case, but we don't really care.
651   EXPECT_TRUE(HasTrust({system_root}, ExpectedTrustForAnchor()));
652 }
653 
654 // A system trusted root is also present in a user DB, with TERMINAL_RECORD
655 // settings in the user DB. The system trust settings should not be used, and
656 // the distrust from the user DB should be honored.
TEST_F(TrustStoreNSSTestIgnoreSystemCerts,UserDbDistrustForSystemRootHonored)657 TEST_F(TrustStoreNSSTestIgnoreSystemCerts, UserDbDistrustForSystemRootHonored) {
658   std::shared_ptr<const bssl::ParsedCertificate> system_root =
659       GetASSLTrustedBuiltinRoot();
660   ASSERT_TRUE(system_root);
661 
662   AddCertToNSSSlotWithTrust(system_root.get(), test_nssdb_.slot(),
663                             bssl::CertificateTrustType::DISTRUSTED);
664 
665   // NSS should see the cert as distrusted.
666   EXPECT_EQ(CERTDB_TERMINAL_RECORD, GetNSSTrustForCert(system_root.get()));
667 
668   // TrustStoreNSS should see as Distrusted since the cert was distrusted in
669   // the user slot.
670   EXPECT_TRUE(HasTrust({system_root}, bssl::CertificateTrust::ForDistrusted()));
671 }
672 
673 // A system trusted root is also present in a user DB, with a trust object with
674 // no SSL trust flags set in the user DB. The system trust settings should not
675 // be used, and the lack of trust flags in the user DB should result in
676 // unspecified trust.
TEST_F(TrustStoreNSSTestIgnoreSystemCerts,UserDbUnspecifiedTrustForSystemRootHonored)677 TEST_F(TrustStoreNSSTestIgnoreSystemCerts,
678        UserDbUnspecifiedTrustForSystemRootHonored) {
679   std::shared_ptr<const bssl::ParsedCertificate> system_root =
680       GetASSLTrustedBuiltinRoot();
681   ASSERT_TRUE(system_root);
682 
683   AddCertToNSSSlotWithTrust(system_root.get(), test_nssdb_.slot(),
684                             bssl::CertificateTrustType::UNSPECIFIED);
685 
686   // NSS should see the cert as unspecified trust.
687   EXPECT_EQ(0u, GetNSSTrustForCert(system_root.get()));
688 
689   // TrustStoreNSS should see as Unspecified since the cert was marked
690   // unspecified in the user slot.
691   EXPECT_TRUE(
692       HasTrust({system_root}, bssl::CertificateTrust::ForUnspecified()));
693 }
694 
695 // Tests a TrustStoreNSS that does not filter which certificates
696 class TrustStoreNSSTestWithoutSlotFilter : public TrustStoreNSSTestBase {
697  public:
CreateTrustStoreNSS()698   std::unique_ptr<TrustStoreNSS> CreateTrustStoreNSS() override {
699     return std::make_unique<TrustStoreNSS>(
700         TrustStoreNSS::UseTrustFromAllUserSlots());
701   }
702 };
703 
704 // If certs are present in NSS DB but aren't marked as trusted, should get no
705 // anchor results for any of the test certs.
TEST_F(TrustStoreNSSTestWithoutSlotFilter,CertsPresentButNotTrusted)706 TEST_F(TrustStoreNSSTestWithoutSlotFilter, CertsPresentButNotTrusted) {
707   AddCertsToNSS();
708 
709   // None of the certificates are trusted.
710   EXPECT_TRUE(HasTrust({oldroot_, newroot_, target_, oldintermediate_,
711                         newintermediate_, newrootrollover_},
712                        bssl::CertificateTrust::ForUnspecified()));
713 }
714 
715 // Trust a single self-signed CA certificate.
TEST_F(TrustStoreNSSTestWithoutSlotFilter,TrustedCA)716 TEST_F(TrustStoreNSSTestWithoutSlotFilter, TrustedCA) {
717   AddCertsToNSS();
718   TrustCert(newroot_.get());
719 
720   // Only one of the certificates are trusted.
721   EXPECT_TRUE(HasTrust(
722       {oldroot_, target_, oldintermediate_, newintermediate_, newrootrollover_},
723       bssl::CertificateTrust::ForUnspecified()));
724 
725   EXPECT_TRUE(HasTrust({newroot_}, ExpectedTrustForAnchor()));
726 }
727 
728 // Distrust a single self-signed CA certificate.
TEST_F(TrustStoreNSSTestWithoutSlotFilter,DistrustedCA)729 TEST_F(TrustStoreNSSTestWithoutSlotFilter, DistrustedCA) {
730   AddCertsToNSS();
731   DistrustCert(newroot_.get());
732 
733   // Only one of the certificates are trusted.
734   EXPECT_TRUE(HasTrust(
735       {oldroot_, target_, oldintermediate_, newintermediate_, newrootrollover_},
736       bssl::CertificateTrust::ForUnspecified()));
737 
738   EXPECT_TRUE(HasTrust({newroot_}, bssl::CertificateTrust::ForDistrusted()));
739 }
740 
741 // Trust a single intermediate certificate.
TEST_F(TrustStoreNSSTestWithoutSlotFilter,TrustedIntermediate)742 TEST_F(TrustStoreNSSTestWithoutSlotFilter, TrustedIntermediate) {
743   AddCertsToNSS();
744   TrustCert(newintermediate_.get());
745 
746   EXPECT_TRUE(HasTrust(
747       {oldroot_, newroot_, target_, oldintermediate_, newrootrollover_},
748       bssl::CertificateTrust::ForUnspecified()));
749   EXPECT_TRUE(HasTrust({newintermediate_}, ExpectedTrustForAnchor()));
750 }
751 
752 // Distrust a single intermediate certificate.
TEST_F(TrustStoreNSSTestWithoutSlotFilter,DistrustedIntermediate)753 TEST_F(TrustStoreNSSTestWithoutSlotFilter, DistrustedIntermediate) {
754   AddCertsToNSS();
755   DistrustCert(newintermediate_.get());
756 
757   EXPECT_TRUE(HasTrust(
758       {oldroot_, newroot_, target_, oldintermediate_, newrootrollover_},
759       bssl::CertificateTrust::ForUnspecified()));
760   EXPECT_TRUE(
761       HasTrust({newintermediate_}, bssl::CertificateTrust::ForDistrusted()));
762 }
763 
764 // Trust a single server certificate.
TEST_F(TrustStoreNSSTestWithoutSlotFilter,TrustedServer)765 TEST_F(TrustStoreNSSTestWithoutSlotFilter, TrustedServer) {
766   AddCertsToNSS();
767   TrustServerCert(target_.get());
768 
769   EXPECT_TRUE(HasTrust({oldroot_, newroot_, oldintermediate_, newintermediate_,
770                         newrootrollover_},
771                        bssl::CertificateTrust::ForUnspecified()));
772   EXPECT_TRUE(HasTrust({target_}, ExpectedTrustForLeaf()));
773 }
774 
775 // Trust a single certificate with both CA and server trust bits.
TEST_F(TrustStoreNSSTestWithoutSlotFilter,TrustedCaAndServer)776 TEST_F(TrustStoreNSSTestWithoutSlotFilter, TrustedCaAndServer) {
777   AddCertsToNSS();
778   TrustCaAndServerCert(target_.get());
779 
780   EXPECT_TRUE(HasTrust({oldroot_, newroot_, oldintermediate_, newintermediate_,
781                         newrootrollover_},
782                        bssl::CertificateTrust::ForUnspecified()));
783   EXPECT_TRUE(HasTrust({target_}, ExpectedTrustForAnchorOrLeaf()));
784 }
785 
786 // Trust multiple self-signed CA certificates with the same name.
TEST_F(TrustStoreNSSTestWithoutSlotFilter,MultipleTrustedCAWithSameSubject)787 TEST_F(TrustStoreNSSTestWithoutSlotFilter, MultipleTrustedCAWithSameSubject) {
788   AddCertsToNSS();
789   TrustCert(oldroot_.get());
790   TrustCert(newroot_.get());
791 
792   EXPECT_TRUE(
793       HasTrust({target_, oldintermediate_, newintermediate_, newrootrollover_},
794                bssl::CertificateTrust::ForUnspecified()));
795   EXPECT_TRUE(HasTrust({oldroot_, newroot_}, ExpectedTrustForAnchor()));
796 }
797 
798 // Different trust settings for multiple self-signed CA certificates with the
799 // same name.
TEST_F(TrustStoreNSSTestWithoutSlotFilter,DifferingTrustCAWithSameSubject)800 TEST_F(TrustStoreNSSTestWithoutSlotFilter, DifferingTrustCAWithSameSubject) {
801   AddCertsToNSS();
802   DistrustCert(oldroot_.get());
803   TrustCert(newroot_.get());
804 
805   EXPECT_TRUE(
806       HasTrust({target_, oldintermediate_, newintermediate_, newrootrollover_},
807                bssl::CertificateTrust::ForUnspecified()));
808   EXPECT_TRUE(HasTrust({oldroot_}, bssl::CertificateTrust::ForDistrusted()));
809   EXPECT_TRUE(HasTrust({newroot_}, ExpectedTrustForAnchor()));
810 }
811 
812 // Check that ListCertsIgnoringNssRoots and GetAllUserAddedCerts are correctly
813 // looking at all slots.
TEST_F(TrustStoreNSSTestWithoutSlotFilter,ListCertsLooksAtAllSlots)814 TEST_F(TrustStoreNSSTestWithoutSlotFilter, ListCertsLooksAtAllSlots) {
815   AddCertToNSSSlotWithTrust(oldroot_.get(), first_test_nssdb_.slot(),
816                             bssl::CertificateTrustType::DISTRUSTED);
817   AddCertToNSSSlotWithTrust(newroot_.get(), test_nssdb_.slot(),
818                             bssl::CertificateTrustType::TRUSTED_LEAF);
819 
820   {
821     bool found_newroot = false;
822     bool found_oldroot = false;
823     for (const auto& result :
824          trust_store_nss_->TrustStoreNSS::ListCertsIgnoringNSSRoots()) {
825       found_oldroot |= x509_util::IsSameCertificate(result.cert.get(),
826                                                     oldroot_->cert_buffer());
827       found_newroot |= x509_util::IsSameCertificate(result.cert.get(),
828                                                     newroot_->cert_buffer());
829     }
830     EXPECT_TRUE(found_newroot);
831     EXPECT_TRUE(found_oldroot);
832   }
833 
834   {
835     bool found_newroot = false;
836     bool found_oldroot = false;
837     for (const auto& cert_with_trust :
838          trust_store_nss_->GetAllUserAddedCerts()) {
839       found_oldroot |= x509_util::CryptoBufferEqual(
840           x509_util::CreateCryptoBuffer(cert_with_trust.cert_bytes).get(),
841           oldroot_->cert_buffer());
842       found_newroot |= x509_util::CryptoBufferEqual(
843           x509_util::CreateCryptoBuffer(cert_with_trust.cert_bytes).get(),
844           newroot_->cert_buffer());
845     }
846     EXPECT_TRUE(found_newroot);
847     EXPECT_TRUE(found_oldroot);
848   }
849 }
850 
851 // Tests for a TrustStoreNSS which does allows certificates on user slots to
852 // be only trusted if they are on a specific user slot.
853 class TrustStoreNSSTestAllowSpecifiedUserSlot : public TrustStoreNSSTestBase {
854  public:
855   TrustStoreNSSTestAllowSpecifiedUserSlot() = default;
856   ~TrustStoreNSSTestAllowSpecifiedUserSlot() override = default;
857 
CreateTrustStoreNSS()858   std::unique_ptr<TrustStoreNSS> CreateTrustStoreNSS() override {
859     return std::make_unique<TrustStoreNSS>(
860         crypto::ScopedPK11Slot(PK11_ReferenceSlot(test_nssdb_.slot())));
861   }
862 };
863 
864 // A certificate that is stored on a "user slot" is trusted if the
865 // TrustStoreNSS is allowed to trust that user slot.
TEST_F(TrustStoreNSSTestAllowSpecifiedUserSlot,CertOnUserSlot)866 TEST_F(TrustStoreNSSTestAllowSpecifiedUserSlot, CertOnUserSlot) {
867   AddCertToNSSSlotWithTrust(newroot_.get(), test_nssdb_.slot(),
868                             bssl::CertificateTrustType::TRUSTED_ANCHOR);
869   EXPECT_TRUE(HasTrust({newroot_}, ExpectedTrustForAnchor()));
870 }
871 
872 // A certificate that is stored on a "user slot" is not trusted if the
873 // TrustStoreNSS is allowed to trust a user slot, but the certificate is
874 // stored on another user slot.
TEST_F(TrustStoreNSSTestAllowSpecifiedUserSlot,CertOnOtherUserSlot)875 TEST_F(TrustStoreNSSTestAllowSpecifiedUserSlot, CertOnOtherUserSlot) {
876   AddCertToNSSSlotWithTrust(newroot_.get(), other_test_nssdb_.slot(),
877                             bssl::CertificateTrustType::TRUSTED_ANCHOR);
878   EXPECT_TRUE(HasTrust({newroot_}, bssl::CertificateTrust::ForUnspecified()));
879 }
880 
881 // The same certificate is stored in multiple user slots with different trust
882 // settings. Ensure that the correct trust setting is used.
TEST_F(TrustStoreNSSTestAllowSpecifiedUserSlot,CertOnMultipleSlots)883 TEST_F(TrustStoreNSSTestAllowSpecifiedUserSlot, CertOnMultipleSlots) {
884   // Add unrelated trust record to test that we find the correct one.
885   AddCertToNSSSlotWithTrust(newintermediate_.get(), test_nssdb_.slot(),
886                             bssl::CertificateTrustType::DISTRUSTED);
887 
888   AddCertToNSSSlotWithTrust(newroot_.get(), first_test_nssdb_.slot(),
889                             bssl::CertificateTrustType::DISTRUSTED);
890   AddCertToNSSSlotWithTrust(newroot_.get(), test_nssdb_.slot(),
891                             bssl::CertificateTrustType::TRUSTED_ANCHOR);
892   AddCertToNSSSlotWithTrust(newroot_.get(), other_test_nssdb_.slot(),
893                             bssl::CertificateTrustType::TRUSTED_LEAF);
894 
895   // Add unrelated trust record to test that we find the correct one.
896   AddCertToNSSSlotWithTrust(target_.get(), test_nssdb_.slot(),
897                             bssl::CertificateTrustType::DISTRUSTED);
898 
899   EXPECT_TRUE(HasTrust({newroot_}, ExpectedTrustForAnchor()));
900 }
901 
902 // A NSS trusted root certificate is also stored in multiple user slots with
903 // different trust settings. Ensure that the correct trust setting is used.
TEST_F(TrustStoreNSSTestAllowSpecifiedUserSlot,SystemRootCertOnMultipleSlots)904 TEST_F(TrustStoreNSSTestAllowSpecifiedUserSlot, SystemRootCertOnMultipleSlots) {
905   std::shared_ptr<const bssl::ParsedCertificate> system_root =
906       GetASSLTrustedBuiltinRoot();
907   ASSERT_TRUE(system_root);
908   EXPECT_EQ(CERTDB_TRUSTED_CA | CERTDB_VALID_CA,
909             GetNSSTrustForCert(system_root.get()));
910 
911   AddCertToNSSSlotWithTrust(system_root.get(), first_test_nssdb_.slot(),
912                             bssl::CertificateTrustType::DISTRUSTED);
913   AddCertToNSSSlotWithTrust(system_root.get(), test_nssdb_.slot(),
914                             bssl::CertificateTrustType::TRUSTED_LEAF);
915   AddCertToNSSSlotWithTrust(system_root.get(), other_test_nssdb_.slot(),
916                             bssl::CertificateTrustType::UNSPECIFIED);
917 
918   EXPECT_TRUE(HasTrust({system_root}, ExpectedTrustForLeaf()));
919 }
920 
921 // Check to see ListCertsIgnoringNSSRoots and GetAllUserAddedCerts correctly
922 // enforce slot filters.
TEST_F(TrustStoreNSSTestAllowSpecifiedUserSlot,ListCertsFiltersBySlot)923 TEST_F(TrustStoreNSSTestAllowSpecifiedUserSlot, ListCertsFiltersBySlot) {
924   // Should not be in the results.
925   AddCertToNSSSlotWithTrust(oldroot_.get(), first_test_nssdb_.slot(),
926                             bssl::CertificateTrustType::DISTRUSTED);
927   // Should be in the results.
928   AddCertToNSSSlotWithTrust(newroot_.get(), test_nssdb_.slot(),
929                             bssl::CertificateTrustType::TRUSTED_LEAF);
930 
931   {
932     bool found_newroot = false;
933     for (const auto& result :
934          trust_store_nss_->TrustStoreNSS::ListCertsIgnoringNSSRoots()) {
935       EXPECT_FALSE(x509_util::IsSameCertificate(result.cert.get(),
936                                                 oldroot_->cert_buffer()));
937       found_newroot |= x509_util::IsSameCertificate(result.cert.get(),
938                                                     newroot_->cert_buffer());
939     }
940     EXPECT_TRUE(found_newroot);
941   }
942 
943   {
944     bool found_newroot = false;
945     for (const auto& cert_with_trust :
946          trust_store_nss_->GetAllUserAddedCerts()) {
947       EXPECT_FALSE(x509_util::CryptoBufferEqual(
948           x509_util::CreateCryptoBuffer(cert_with_trust.cert_bytes).get(),
949           oldroot_->cert_buffer()));
950       found_newroot |= x509_util::CryptoBufferEqual(
951           x509_util::CreateCryptoBuffer(cert_with_trust.cert_bytes).get(),
952           newroot_->cert_buffer());
953     }
954     EXPECT_TRUE(found_newroot);
955   }
956 }
957 
958 // TODO(crbug.com/41468842): If the internal non-removable slot is
959 // relevant on Chrome OS, add a test for allowing trust for certificates
960 // stored on that slot.
961 
962 class TrustStoreNSSTestDelegate {
963  public:
TrustStoreNSSTestDelegate()964   TrustStoreNSSTestDelegate()
965       : trust_store_nss_(TrustStoreNSS::UseTrustFromAllUserSlots()) {}
966 
AddCert(std::shared_ptr<const bssl::ParsedCertificate> cert)967   void AddCert(std::shared_ptr<const bssl::ParsedCertificate> cert) {
968     ASSERT_TRUE(test_nssdb_.is_open());
969     ScopedCERTCertificate nss_cert(
970         x509_util::CreateCERTCertificateFromBytes(cert->der_cert()));
971     ASSERT_TRUE(nss_cert);
972     SECStatus srv = PK11_ImportCert(
973         test_nssdb_.slot(), nss_cert.get(), CK_INVALID_HANDLE,
974         GetUniqueNickname().c_str(), PR_FALSE /* includeTrust (unused) */);
975     ASSERT_EQ(SECSuccess, srv);
976   }
977 
source()978   bssl::CertIssuerSource& source() { return trust_store_nss_; }
979 
980  protected:
GetUniqueNickname()981   std::string GetUniqueNickname() {
982     return "cert_issuer_source_nss_unittest" +
983            base::NumberToString(nickname_counter_++);
984   }
985 
986   crypto::ScopedTestNSSDB test_nssdb_;
987   TrustStoreNSS trust_store_nss_;
988   unsigned int nickname_counter_ = 0;
989 };
990 
991 INSTANTIATE_TYPED_TEST_SUITE_P(TrustStoreNSSTest2,
992                                CertIssuerSourceSyncTest,
993                                TrustStoreNSSTestDelegate);
994 // NSS doesn't normalize UTF8String values, so use the not-normalized version
995 // of those tests.
996 INSTANTIATE_TYPED_TEST_SUITE_P(TrustStoreNSSNotNormalizedTest,
997                                CertIssuerSourceSyncNotNormalizedTest,
998                                TrustStoreNSSTestDelegate);
999 }  // namespace
1000 
1001 }  // namespace net
1002