xref: /aosp_15_r20/external/cronet/net/cert/internal/trust_store_nss_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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/internal/trust_store_features.h"
22 #include "net/cert/scoped_nss_types.h"
23 #include "net/cert/x509_util.h"
24 #include "net/cert/x509_util_nss.h"
25 #include "net/test/cert_test_util.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:
TrustStoreNSSTestBase(bool trusted_leaf_support,bool enforce_local_anchor_constraints)89   explicit TrustStoreNSSTestBase(bool trusted_leaf_support,
90                                  bool enforce_local_anchor_constraints)
91       : trusted_leaf_support_(trusted_leaf_support),
92         enforce_local_anchor_constraints_(enforce_local_anchor_constraints),
93         scoped_enforce_local_anchor_constraints_(
94             enforce_local_anchor_constraints) {
95     if (trusted_leaf_support) {
96       feature_list_.InitAndEnableFeature(
97           features::kTrustStoreTrustedLeafSupport);
98     } else {
99       feature_list_.InitAndDisableFeature(
100           features::kTrustStoreTrustedLeafSupport);
101     }
102   }
103 
TrustStoreNSSTestBase()104   TrustStoreNSSTestBase() : TrustStoreNSSTestBase(true, true) {}
105 
ExpectedTrustedLeafSupportEnabled() const106   bool ExpectedTrustedLeafSupportEnabled() const {
107     return trusted_leaf_support_;
108   }
109 
ExpectedEnforceLocalAnchorConstraintsEnabled() const110   bool ExpectedEnforceLocalAnchorConstraintsEnabled() const {
111     return enforce_local_anchor_constraints_;
112   }
113 
ExpectedTrustForBuiltinAnchor() const114   bssl::CertificateTrust ExpectedTrustForBuiltinAnchor() const {
115     return bssl::CertificateTrust::ForTrustAnchor();
116   }
117 
ExpectedTrustForAnchor() const118   bssl::CertificateTrust ExpectedTrustForAnchor() const {
119     bssl::CertificateTrust trust = bssl::CertificateTrust::ForTrustAnchor();
120     if (ExpectedEnforceLocalAnchorConstraintsEnabled()) {
121       trust = trust.WithEnforceAnchorConstraints().WithEnforceAnchorExpiry();
122     }
123     return trust;
124   }
125 
ExpectedTrustForAnchorOrLeaf() const126   bssl::CertificateTrust ExpectedTrustForAnchorOrLeaf() const {
127     bssl::CertificateTrust trust;
128     if (ExpectedTrustedLeafSupportEnabled()) {
129       trust = bssl::CertificateTrust::ForTrustAnchorOrLeaf();
130     } else {
131       trust = bssl::CertificateTrust::ForTrustAnchor();
132     }
133     if (ExpectedEnforceLocalAnchorConstraintsEnabled()) {
134       trust = trust.WithEnforceAnchorConstraints().WithEnforceAnchorExpiry();
135     }
136     return trust;
137   }
138 
ExpectedTrustForLeaf() const139   bssl::CertificateTrust ExpectedTrustForLeaf() const {
140     if (ExpectedTrustedLeafSupportEnabled()) {
141       return bssl::CertificateTrust::ForTrustedLeaf();
142     } else {
143       return bssl::CertificateTrust::ForUnspecified();
144     }
145   }
146 
SetUp()147   void SetUp() override {
148     ASSERT_TRUE(first_test_nssdb_.is_open());
149     ASSERT_TRUE(test_nssdb_.is_open());
150     ASSERT_TRUE(other_test_nssdb_.is_open());
151     bssl::ParsedCertificateList chain;
152     ReadCertChainFromFile(
153         "net/data/verify_certificate_chain_unittest/key-rollover/oldchain.pem",
154         &chain);
155 
156     ASSERT_EQ(3U, chain.size());
157     target_ = chain[0];
158     oldintermediate_ = chain[1];
159     oldroot_ = chain[2];
160     ASSERT_TRUE(target_);
161     ASSERT_TRUE(oldintermediate_);
162     ASSERT_TRUE(oldroot_);
163 
164     ReadCertChainFromFile(
165         "net/data/verify_certificate_chain_unittest/"
166         "key-rollover/longrolloverchain.pem",
167         &chain);
168 
169     ASSERT_EQ(5U, chain.size());
170     newintermediate_ = chain[1];
171     newroot_ = chain[2];
172     newrootrollover_ = chain[3];
173     ASSERT_TRUE(newintermediate_);
174     ASSERT_TRUE(newroot_);
175     ASSERT_TRUE(newrootrollover_);
176 
177     trust_store_nss_ = CreateTrustStoreNSS();
178   }
179 
180   // Creates the TrustStoreNSS instance. Subclasses will customize the slot
181   // filtering behavior here.
182   virtual std::unique_ptr<TrustStoreNSS> CreateTrustStoreNSS() = 0;
183 
GetUniqueNickname()184   std::string GetUniqueNickname() {
185     return "trust_store_nss_unittest" +
186            base::NumberToString(nickname_counter_++);
187   }
188 
AddCertToNSSSlot(const bssl::ParsedCertificate * cert,PK11SlotInfo * slot)189   void AddCertToNSSSlot(const bssl::ParsedCertificate* cert,
190                         PK11SlotInfo* slot) {
191     ScopedCERTCertificate nss_cert(
192         x509_util::CreateCERTCertificateFromBytes(cert->der_cert()));
193     ASSERT_TRUE(nss_cert);
194     SECStatus srv = PK11_ImportCert(slot, nss_cert.get(), CK_INVALID_HANDLE,
195                                     GetUniqueNickname().c_str(),
196                                     PR_FALSE /* includeTrust (unused) */);
197     ASSERT_EQ(SECSuccess, srv);
198   }
199 
200   // Import `cert` into `slot` and create a trust record with `trust` type.
201   // Tries to ensure that the created trust record ends up in the same `slot`.
202   // (That isn't always the case if `cert` exists in multiple slots and
203   // CERT_ChangeCertTrust was just used on an arbitrary CERTCertificate handle
204   // for `cert`.)
AddCertToNSSSlotWithTrust(const bssl::ParsedCertificate * cert,PK11SlotInfo * slot,bssl::CertificateTrustType trust)205   void AddCertToNSSSlotWithTrust(const bssl::ParsedCertificate* cert,
206                                  PK11SlotInfo* slot,
207                                  bssl::CertificateTrustType trust) {
208     AddCertToNSSSlot(cert, slot);
209     ChangeCertTrustInSlot(cert, slot, trust);
210   }
211 
AddCertsToNSS()212   void AddCertsToNSS() {
213     AddCertToNSSSlot(target_.get(), test_nssdb_.slot());
214     AddCertToNSSSlot(oldintermediate_.get(), test_nssdb_.slot());
215     AddCertToNSSSlot(newintermediate_.get(), test_nssdb_.slot());
216     AddCertToNSSSlot(oldroot_.get(), test_nssdb_.slot());
217     AddCertToNSSSlot(newroot_.get(), test_nssdb_.slot());
218     AddCertToNSSSlot(newrootrollover_.get(), test_nssdb_.slot());
219 
220     // Check that the certificates can be retrieved as expected.
221     EXPECT_TRUE(
222         TrustStoreContains(target_, {newintermediate_, oldintermediate_}));
223 
224     EXPECT_TRUE(TrustStoreContains(newintermediate_,
225                                    {newroot_, newrootrollover_, oldroot_}));
226     EXPECT_TRUE(TrustStoreContains(oldintermediate_,
227                                    {newroot_, newrootrollover_, oldroot_}));
228     EXPECT_TRUE(TrustStoreContains(newrootrollover_,
229                                    {newroot_, newrootrollover_, oldroot_}));
230     EXPECT_TRUE(
231         TrustStoreContains(oldroot_, {newroot_, newrootrollover_, oldroot_}));
232     EXPECT_TRUE(
233         TrustStoreContains(newroot_, {newroot_, newrootrollover_, oldroot_}));
234   }
235 
236   // Trusts |cert|. Assumes the cert was already imported into NSS.
TrustCert(const bssl::ParsedCertificate * cert)237   void TrustCert(const bssl::ParsedCertificate* cert) {
238     ChangeCertTrust(cert, CERTDB_TRUSTED_CA | CERTDB_VALID_CA);
239   }
240 
241   // Trusts |cert| as a server, but not as a CA. Assumes the cert was already
242   // imported into NSS.
TrustServerCert(const bssl::ParsedCertificate * cert)243   void TrustServerCert(const bssl::ParsedCertificate* cert) {
244     ChangeCertTrust(cert, CERTDB_TERMINAL_RECORD | CERTDB_TRUSTED);
245   }
246 
247   // Trusts |cert| as both a server and as a CA. Assumes the cert was already
248   // imported into NSS.
TrustCaAndServerCert(const bssl::ParsedCertificate * cert)249   void TrustCaAndServerCert(const bssl::ParsedCertificate* cert) {
250     ChangeCertTrust(cert, CERTDB_TERMINAL_RECORD | CERTDB_TRUSTED |
251                               CERTDB_TRUSTED_CA | CERTDB_VALID_CA);
252   }
253 
254   // Distrusts |cert|. Assumes the cert was already imported into NSS.
DistrustCert(const bssl::ParsedCertificate * cert)255   void DistrustCert(const bssl::ParsedCertificate* cert) {
256     ChangeCertTrust(cert, CERTDB_TERMINAL_RECORD);
257   }
258 
ChangeCertTrust(const bssl::ParsedCertificate * cert,int flags)259   void ChangeCertTrust(const bssl::ParsedCertificate* cert, int flags) {
260     SECItem der_cert;
261     der_cert.data = const_cast<uint8_t*>(cert->der_cert().data());
262     der_cert.len = base::checked_cast<unsigned>(cert->der_cert().size());
263     der_cert.type = siDERCertBuffer;
264 
265     ScopedCERTCertificate nss_cert(
266         CERT_FindCertByDERCert(CERT_GetDefaultCertDB(), &der_cert));
267     ASSERT_TRUE(nss_cert);
268 
269     CERTCertTrust trust = {0};
270     trust.sslFlags = flags;
271     SECStatus srv =
272         CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), nss_cert.get(), &trust);
273     ASSERT_EQ(SECSuccess, srv);
274   }
275 
276   // Change the trust for `cert` in `slot` to `trust`.
277   // `cert` must already exist in `slot'.
278   // Tries to ensure that the created trust record ends up in the same `slot`.
279   // (That isn't always the case if `cert` exists in multiple slots and
280   // CERT_ChangeCertTrust was just used on an arbitrary CERTCertificate handle
281   // for `cert`.)
282   // (An alternative approach would be to create the CKO_NSS_TRUST object
283   // directly using PK11_CreateManagedGenericObject, which has the advantage of
284   // being able to specify the slot directly, but the disadvantage that there's
285   // no guarantee the way the test creates the trust object matches what NSS
286   // actually does. See
287   // https://crrev.com/c/3732801/9/net/cert/internal/trust_store_nss_unittest.cc#412
288   // for some example code if that's ever needed.)
ChangeCertTrustInSlot(const bssl::ParsedCertificate * cert,PK11SlotInfo * slot,bssl::CertificateTrustType trust)289   void ChangeCertTrustInSlot(const bssl::ParsedCertificate* cert,
290                              PK11SlotInfo* slot,
291                              bssl::CertificateTrustType trust) {
292     crypto::ScopedCERTCertList cert_list(PK11_ListCertsInSlot(slot));
293     ASSERT_TRUE(cert_list);
294 
295     for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list);
296          !CERT_LIST_END(node, cert_list); node = CERT_LIST_NEXT(node)) {
297       if (x509_util::IsSameCertificate(node->cert, cert->cert_buffer())) {
298         CERTCertTrust nss_trust = {0};
299         nss_trust.sslFlags = TrustTypeToNSSTrust(trust);
300         if (CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), node->cert,
301                                  &nss_trust) != SECSuccess) {
302           ADD_FAILURE() << "CERT_ChangeCertTrust failed: " << PORT_GetError();
303         }
304         return;
305       }
306     }
307     ADD_FAILURE() << "cert not found in slot";
308   }
309 
310  protected:
TrustStoreContains(std::shared_ptr<const bssl::ParsedCertificate> cert,bssl::ParsedCertificateList expected_matches)311   bool TrustStoreContains(std::shared_ptr<const bssl::ParsedCertificate> cert,
312                           bssl::ParsedCertificateList expected_matches) {
313     bssl::ParsedCertificateList matches;
314     trust_store_nss_->SyncGetIssuersOf(cert.get(), &matches);
315 
316     std::vector<std::string> name_result_matches;
317     for (const auto& it : matches)
318       name_result_matches.push_back(GetCertString(it));
319     std::sort(name_result_matches.begin(), name_result_matches.end());
320 
321     std::vector<std::string> name_expected_matches;
322     for (const auto& it : expected_matches)
323       name_expected_matches.push_back(GetCertString(it));
324     std::sort(name_expected_matches.begin(), name_expected_matches.end());
325 
326     if (name_expected_matches == name_result_matches)
327       return true;
328 
329     // Print some extra information for debugging.
330     EXPECT_EQ(name_expected_matches, name_result_matches);
331     return false;
332   }
333 
334   // Give simpler names to certificate DER (for identifying them in tests by
335   // their symbolic name).
GetCertString(const std::shared_ptr<const bssl::ParsedCertificate> & cert) const336   std::string GetCertString(
337       const std::shared_ptr<const bssl::ParsedCertificate>& cert) const {
338     if (cert->der_cert() == oldroot_->der_cert())
339       return "oldroot_";
340     if (cert->der_cert() == newroot_->der_cert())
341       return "newroot_";
342     if (cert->der_cert() == target_->der_cert())
343       return "target_";
344     if (cert->der_cert() == oldintermediate_->der_cert())
345       return "oldintermediate_";
346     if (cert->der_cert() == newintermediate_->der_cert())
347       return "newintermediate_";
348     if (cert->der_cert() == newrootrollover_->der_cert())
349       return "newrootrollover_";
350     return cert->der_cert().AsString();
351   }
352 
HasTrust(const bssl::ParsedCertificateList & certs,bssl::CertificateTrust expected_trust)353   bool HasTrust(const bssl::ParsedCertificateList& certs,
354                 bssl::CertificateTrust expected_trust) {
355     bool success = true;
356     for (const std::shared_ptr<const bssl::ParsedCertificate>& cert : certs) {
357       bssl::CertificateTrust trust = trust_store_nss_->GetTrust(cert.get());
358       std::string trust_string = trust.ToDebugString();
359       std::string expected_trust_string = expected_trust.ToDebugString();
360       if (trust_string != expected_trust_string) {
361         EXPECT_EQ(expected_trust_string, trust_string) << GetCertString(cert);
362         success = false;
363       }
364     }
365 
366     return success;
367   }
368 
369   base::test::ScopedFeatureList feature_list_;
370   const bool trusted_leaf_support_;
371   const bool enforce_local_anchor_constraints_;
372   ScopedLocalAnchorConstraintsEnforcementForTesting
373       scoped_enforce_local_anchor_constraints_;
374 
375   std::shared_ptr<const bssl::ParsedCertificate> oldroot_;
376   std::shared_ptr<const bssl::ParsedCertificate> newroot_;
377 
378   std::shared_ptr<const bssl::ParsedCertificate> target_;
379   std::shared_ptr<const bssl::ParsedCertificate> oldintermediate_;
380   std::shared_ptr<const bssl::ParsedCertificate> newintermediate_;
381   std::shared_ptr<const bssl::ParsedCertificate> newrootrollover_;
382   crypto::ScopedTestNSSDB first_test_nssdb_;
383   crypto::ScopedTestNSSDB test_nssdb_;
384   crypto::ScopedTestNSSDB other_test_nssdb_;
385   std::unique_ptr<TrustStoreNSS> trust_store_nss_;
386   unsigned nickname_counter_ = 0;
387 };
388 
389 // Specifies which kind of per-slot filtering the TrustStoreNSS is supposed to
390 // perform in the parametrized TrustStoreNSSTestWithSlotFilterType.
391 enum class SlotFilterType {
392   kDontFilter,
393   kDoNotAllowUserSlots,
394   kAllowSpecifiedUserSlot
395 };
396 
SlotFilterTypeToString(SlotFilterType slot_filter_type)397 std::string SlotFilterTypeToString(SlotFilterType slot_filter_type) {
398   switch (slot_filter_type) {
399     case SlotFilterType::kDontFilter:
400       return "DontFilter";
401     case SlotFilterType::kDoNotAllowUserSlots:
402       return "DoNotAllowUserSlots";
403     case SlotFilterType::kAllowSpecifiedUserSlot:
404       return "AllowSpecifiedUserSlot";
405   }
406 }
407 
408 // Used for testing a TrustStoreNSS with the slot filter type specified by the
409 // test parameter. These tests are cases that are expected to be the same
410 // regardless of the slot filter type.
411 class TrustStoreNSSTestWithSlotFilterType
412     : public TrustStoreNSSTestBase,
413       public testing::WithParamInterface<SlotFilterType> {
414  public:
415   TrustStoreNSSTestWithSlotFilterType() = default;
416   ~TrustStoreNSSTestWithSlotFilterType() override = default;
417 
slot_filter_type() const418   SlotFilterType slot_filter_type() const { return GetParam(); }
419 
CreateTrustStoreNSS()420   std::unique_ptr<TrustStoreNSS> CreateTrustStoreNSS() override {
421     switch (slot_filter_type()) {
422       case SlotFilterType::kDontFilter:
423         return std::make_unique<TrustStoreNSS>(
424             TrustStoreNSS::UseTrustFromAllUserSlots());
425       case SlotFilterType::kDoNotAllowUserSlots:
426         return std::make_unique<TrustStoreNSS>(
427             /*user_slot_trust_setting=*/nullptr);
428       case SlotFilterType::kAllowSpecifiedUserSlot:
429         return std::make_unique<TrustStoreNSS>(
430             crypto::ScopedPK11Slot(PK11_ReferenceSlot(test_nssdb_.slot())));
431     }
432   }
433 };
434 
435 // Without adding any certs to the NSS DB, should get no anchor results for
436 // any of the test certs.
TEST_P(TrustStoreNSSTestWithSlotFilterType,CertsNotPresent)437 TEST_P(TrustStoreNSSTestWithSlotFilterType, CertsNotPresent) {
438   EXPECT_TRUE(TrustStoreContains(target_, bssl::ParsedCertificateList()));
439   EXPECT_TRUE(
440       TrustStoreContains(newintermediate_, bssl::ParsedCertificateList()));
441   EXPECT_TRUE(TrustStoreContains(newroot_, bssl::ParsedCertificateList()));
442   EXPECT_TRUE(HasTrust({target_}, bssl::CertificateTrust::ForUnspecified()));
443   EXPECT_TRUE(
444       HasTrust({newintermediate_}, bssl::CertificateTrust::ForUnspecified()));
445   EXPECT_TRUE(HasTrust({newroot_}, bssl::CertificateTrust::ForUnspecified()));
446 }
447 
448 // TrustStoreNSS should return temporary certs on Chrome OS, because on Chrome
449 // OS temporary certs are used to supply policy-provided untrusted authority
450 // certs. (See https://crbug.com/978854)
451 // On other platforms it's not required but doesn't hurt anything.
TEST_P(TrustStoreNSSTestWithSlotFilterType,TempCertPresent)452 TEST_P(TrustStoreNSSTestWithSlotFilterType, TempCertPresent) {
453   ScopedCERTCertificate temp_nss_cert(
454       x509_util::CreateCERTCertificateFromBytes(newintermediate_->der_cert()));
455   EXPECT_TRUE(TrustStoreContains(target_, {newintermediate_}));
456   EXPECT_TRUE(HasTrust({target_}, bssl::CertificateTrust::ForUnspecified()));
457 }
458 
459 // Independent of the specified slot-based filtering mode, built-in root certs
460 // should never be trusted.
TEST_P(TrustStoreNSSTestWithSlotFilterType,TrustAllowedForBuiltinRootCerts)461 TEST_P(TrustStoreNSSTestWithSlotFilterType, TrustAllowedForBuiltinRootCerts) {
462   auto builtin_root_cert = GetASSLTrustedBuiltinRoot();
463   ASSERT_TRUE(builtin_root_cert);
464   EXPECT_TRUE(
465       HasTrust({builtin_root_cert}, bssl::CertificateTrust::ForUnspecified()));
466 }
467 
468 INSTANTIATE_TEST_SUITE_P(
469     All,
470     TrustStoreNSSTestWithSlotFilterType,
471     ::testing::Values(SlotFilterType::kDontFilter,
472                       SlotFilterType::kDoNotAllowUserSlots,
473                       SlotFilterType::kAllowSpecifiedUserSlot),
474     [](const testing::TestParamInfo<
__anonbbcba6540202(const testing::TestParamInfo< TrustStoreNSSTestWithSlotFilterType::ParamType>& info) 475         TrustStoreNSSTestWithSlotFilterType::ParamType>& info) {
476       return SlotFilterTypeToString(info.param);
477     });
478 
479 // Tests a TrustStoreNSS that ignores system root certs.
480 class TrustStoreNSSTestIgnoreSystemCerts
481     : public TrustStoreNSSTestBase,
482       public testing::WithParamInterface<std::tuple<bool, bool>> {
483  public:
TrustStoreNSSTestIgnoreSystemCerts()484   TrustStoreNSSTestIgnoreSystemCerts()
485       : TrustStoreNSSTestBase(std::get<0>(GetParam()),
486                               std::get<1>(GetParam())) {}
487   ~TrustStoreNSSTestIgnoreSystemCerts() override = default;
488 
CreateTrustStoreNSS()489   std::unique_ptr<TrustStoreNSS> CreateTrustStoreNSS() override {
490     return std::make_unique<TrustStoreNSS>(
491         TrustStoreNSS::UseTrustFromAllUserSlots());
492   }
493 };
494 
TEST_P(TrustStoreNSSTestIgnoreSystemCerts,UnknownCertIgnored)495 TEST_P(TrustStoreNSSTestIgnoreSystemCerts, UnknownCertIgnored) {
496   EXPECT_TRUE(HasTrust({newroot_}, bssl::CertificateTrust::ForUnspecified()));
497 }
498 
499 // An NSS CERTCertificate object exists for the cert, but it is not
500 // imported into any DB. Should be unspecified trust.
TEST_P(TrustStoreNSSTestIgnoreSystemCerts,TemporaryCertIgnored)501 TEST_P(TrustStoreNSSTestIgnoreSystemCerts, TemporaryCertIgnored) {
502   ScopedCERTCertificate nss_cert(
503       x509_util::CreateCERTCertificateFromBytes(newroot_->der_cert()));
504   EXPECT_TRUE(HasTrust({newroot_}, bssl::CertificateTrust::ForUnspecified()));
505 }
506 
507 // Cert is added to user DB, but without explicitly calling
508 // CERT_ChangeCertTrust. Should be unspecified trust.
TEST_P(TrustStoreNSSTestIgnoreSystemCerts,UserCertWithNoTrust)509 TEST_P(TrustStoreNSSTestIgnoreSystemCerts, UserCertWithNoTrust) {
510   AddCertsToNSS();
511   EXPECT_TRUE(HasTrust({newroot_}, bssl::CertificateTrust::ForUnspecified()));
512 }
513 
TEST_P(TrustStoreNSSTestIgnoreSystemCerts,UserRootTrusted)514 TEST_P(TrustStoreNSSTestIgnoreSystemCerts, UserRootTrusted) {
515   AddCertsToNSS();
516   TrustCert(newroot_.get());
517   EXPECT_TRUE(HasTrust({newroot_}, ExpectedTrustForAnchor()));
518 }
519 
TEST_P(TrustStoreNSSTestIgnoreSystemCerts,UserRootDistrusted)520 TEST_P(TrustStoreNSSTestIgnoreSystemCerts, UserRootDistrusted) {
521   AddCertsToNSS();
522   DistrustCert(newroot_.get());
523   EXPECT_TRUE(HasTrust({newroot_}, bssl::CertificateTrust::ForDistrusted()));
524 }
525 
TEST_P(TrustStoreNSSTestIgnoreSystemCerts,UserTrustedServer)526 TEST_P(TrustStoreNSSTestIgnoreSystemCerts, UserTrustedServer) {
527   AddCertsToNSS();
528   TrustServerCert(target_.get());
529   EXPECT_TRUE(HasTrust({target_}, ExpectedTrustForLeaf()));
530 }
531 
TEST_P(TrustStoreNSSTestIgnoreSystemCerts,UserTrustedCaAndServer)532 TEST_P(TrustStoreNSSTestIgnoreSystemCerts, UserTrustedCaAndServer) {
533   AddCertsToNSS();
534   TrustCaAndServerCert(target_.get());
535   EXPECT_TRUE(HasTrust({target_}, ExpectedTrustForAnchorOrLeaf()));
536 }
537 
TEST_P(TrustStoreNSSTestIgnoreSystemCerts,SystemRootCertIgnored)538 TEST_P(TrustStoreNSSTestIgnoreSystemCerts, SystemRootCertIgnored) {
539   std::shared_ptr<const bssl::ParsedCertificate> system_root =
540       GetASSLTrustedBuiltinRoot();
541   ASSERT_TRUE(system_root);
542   EXPECT_TRUE(
543       HasTrust({system_root}, bssl::CertificateTrust::ForUnspecified()));
544 }
545 
546 // A system trusted root is also present in a user DB, but without any trust
547 // settings in the user DB. The system trust settings should not be used.
TEST_P(TrustStoreNSSTestIgnoreSystemCerts,SystemRootCertIgnoredWhenPresentInUserDb)548 TEST_P(TrustStoreNSSTestIgnoreSystemCerts,
549        SystemRootCertIgnoredWhenPresentInUserDb) {
550   std::shared_ptr<const bssl::ParsedCertificate> system_root =
551       GetASSLTrustedBuiltinRoot();
552   ASSERT_TRUE(system_root);
553 
554   AddCertToNSSSlot(system_root.get(), test_nssdb_.slot());
555 
556   // TrustStoreNSS should see an Unspecified since we are ignoring the system
557   // slot.
558   EXPECT_TRUE(
559       HasTrust({system_root}, bssl::CertificateTrust::ForUnspecified()));
560 }
561 
562 // A system trusted root is also present in a user DB, with TRUSTED_CA settings
563 // in the user DB. The system trust settings should not be used, but the trust
564 // from the user DB should be honored.
TEST_P(TrustStoreNSSTestIgnoreSystemCerts,UserDbTrustForSystemRootHonored)565 TEST_P(TrustStoreNSSTestIgnoreSystemCerts, UserDbTrustForSystemRootHonored) {
566   std::shared_ptr<const bssl::ParsedCertificate> system_root =
567       GetASSLTrustedBuiltinRoot();
568   ASSERT_TRUE(system_root);
569 
570   AddCertToNSSSlotWithTrust(system_root.get(), test_nssdb_.slot(),
571                             bssl::CertificateTrustType::TRUSTED_ANCHOR);
572   // NSS should see the cert as trusted.
573   EXPECT_EQ(CERTDB_TRUSTED_CA | CERTDB_VALID_CA,
574             GetNSSTrustForCert(system_root.get()));
575 
576   // TrustStoreNSS should see as TrustAnchor since the cert was trusted in the
577   // user slot.
578   EXPECT_TRUE(HasTrust({system_root}, ExpectedTrustForAnchor()));
579 }
580 
581 // A system trusted root is also present in a user DB, with leaf trust in the
582 // user DB. The system trust settings should not be used, but the trust from
583 // the user DB should be honored.
TEST_P(TrustStoreNSSTestIgnoreSystemCerts,UserDbLeafTrustForSystemRootHonored)584 TEST_P(TrustStoreNSSTestIgnoreSystemCerts,
585        UserDbLeafTrustForSystemRootHonored) {
586   std::shared_ptr<const bssl::ParsedCertificate> system_root =
587       GetASSLTrustedBuiltinRoot();
588   ASSERT_TRUE(system_root);
589 
590   // Add unrelated trust record to test that we find the correct one.
591   AddCertToNSSSlotWithTrust(newroot_.get(), test_nssdb_.slot(),
592                             bssl::CertificateTrustType::TRUSTED_ANCHOR);
593 
594   // Trust the system cert as a leaf.
595   AddCertToNSSSlotWithTrust(system_root.get(), test_nssdb_.slot(),
596                             bssl::CertificateTrustType::TRUSTED_LEAF);
597 
598   // Add unrelated trust record to test that we find the correct one.
599   AddCertToNSSSlotWithTrust(newintermediate_.get(), test_nssdb_.slot(),
600                             bssl::CertificateTrustType::DISTRUSTED);
601 
602   // NSS should see the cert as a trusted leaf.
603   EXPECT_EQ(CERTDB_TRUSTED | CERTDB_TERMINAL_RECORD,
604             GetNSSTrustForCert(system_root.get()));
605 
606   // TrustStoreNSS should see as TrustedLeaf since the cert was trusted in the
607   // user slot.
608   EXPECT_TRUE(HasTrust({system_root}, ExpectedTrustForLeaf()));
609 }
610 
611 // A system trusted root is also present in a user DB, with both CA and leaf
612 // trust in the user DB. The system trust settings should not be used, but the
613 // trust from the user DB should be honored.
TEST_P(TrustStoreNSSTestIgnoreSystemCerts,UserDbAnchorAndLeafTrustForSystemRootHonored)614 TEST_P(TrustStoreNSSTestIgnoreSystemCerts,
615        UserDbAnchorAndLeafTrustForSystemRootHonored) {
616   std::shared_ptr<const bssl::ParsedCertificate> system_root =
617       GetASSLTrustedBuiltinRoot();
618   ASSERT_TRUE(system_root);
619 
620   AddCertToNSSSlotWithTrust(system_root.get(), test_nssdb_.slot(),
621                             bssl::CertificateTrustType::TRUSTED_ANCHOR_OR_LEAF);
622 
623   // NSS should see the cert as both trusted leaf and CA.
624   EXPECT_EQ(CERTDB_TRUSTED_CA | CERTDB_VALID_CA | CERTDB_TRUSTED |
625                 CERTDB_TERMINAL_RECORD,
626             GetNSSTrustForCert(system_root.get()));
627 
628   // TrustStoreNSS should see as TrustAnchor since the cert was trusted in the
629   // user slot. The TrustStoreNSS implementation isn't able to pick up both the
630   // CA and Leaf trust in this case, but we don't really care.
631   EXPECT_TRUE(HasTrust({system_root}, ExpectedTrustForAnchor()));
632 }
633 
634 // A system trusted root is also present in a user DB, with TERMINAL_RECORD
635 // settings in the user DB. The system trust settings should not be used, and
636 // the distrust from the user DB should be honored.
TEST_P(TrustStoreNSSTestIgnoreSystemCerts,UserDbDistrustForSystemRootHonored)637 TEST_P(TrustStoreNSSTestIgnoreSystemCerts, UserDbDistrustForSystemRootHonored) {
638   std::shared_ptr<const bssl::ParsedCertificate> system_root =
639       GetASSLTrustedBuiltinRoot();
640   ASSERT_TRUE(system_root);
641 
642   AddCertToNSSSlotWithTrust(system_root.get(), test_nssdb_.slot(),
643                             bssl::CertificateTrustType::DISTRUSTED);
644 
645   // NSS should see the cert as distrusted.
646   EXPECT_EQ(CERTDB_TERMINAL_RECORD, GetNSSTrustForCert(system_root.get()));
647 
648   // TrustStoreNSS should see as Distrusted since the cert was distrusted in
649   // the user slot.
650   EXPECT_TRUE(HasTrust({system_root}, bssl::CertificateTrust::ForDistrusted()));
651 }
652 
653 // A system trusted root is also present in a user DB, with a trust object with
654 // no SSL trust flags set in the user DB. The system trust settings should not
655 // be used, and the lack of trust flags in the user DB should result in
656 // unspecified trust.
TEST_P(TrustStoreNSSTestIgnoreSystemCerts,UserDbUnspecifiedTrustForSystemRootHonored)657 TEST_P(TrustStoreNSSTestIgnoreSystemCerts,
658        UserDbUnspecifiedTrustForSystemRootHonored) {
659   std::shared_ptr<const bssl::ParsedCertificate> system_root =
660       GetASSLTrustedBuiltinRoot();
661   ASSERT_TRUE(system_root);
662 
663   AddCertToNSSSlotWithTrust(system_root.get(), test_nssdb_.slot(),
664                             bssl::CertificateTrustType::UNSPECIFIED);
665 
666   // NSS should see the cert as unspecified trust.
667   EXPECT_EQ(0u, GetNSSTrustForCert(system_root.get()));
668 
669   // TrustStoreNSS should see as Unspecified since the cert was marked
670   // unspecified in the user slot.
671   EXPECT_TRUE(
672       HasTrust({system_root}, bssl::CertificateTrust::ForUnspecified()));
673 }
674 
675 INSTANTIATE_TEST_SUITE_P(
676     All,
677     TrustStoreNSSTestIgnoreSystemCerts,
678     testing::Combine(testing::Bool(), testing::Bool()),
679     [](const testing::TestParamInfo<
__anonbbcba6540302(const testing::TestParamInfo< TrustStoreNSSTestIgnoreSystemCerts::ParamType>& info) 680         TrustStoreNSSTestIgnoreSystemCerts::ParamType>& info) {
681       return std::string(std::get<0>(info.param) ? "TrustedLeafSupported"
682                                                  : "TrustAnchorOnly") +
683              (std::get<1>(info.param) ? "EnforceLocalAnchorConstraints"
684                                       : "NoLocalAnchorConstraints");
685     });
686 
687 // Tests a TrustStoreNSS that does not filter which certificates
688 class TrustStoreNSSTestWithoutSlotFilter
689     : public TrustStoreNSSTestBase,
690       public testing::WithParamInterface<std::tuple<bool, bool>> {
691  public:
TrustStoreNSSTestWithoutSlotFilter()692   TrustStoreNSSTestWithoutSlotFilter()
693       : TrustStoreNSSTestBase(std::get<0>(GetParam()),
694                               std::get<1>(GetParam())) {}
695 
696   ~TrustStoreNSSTestWithoutSlotFilter() override = default;
697 
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_P(TrustStoreNSSTestWithoutSlotFilter,CertsPresentButNotTrusted)706 TEST_P(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_P(TrustStoreNSSTestWithoutSlotFilter,TrustedCA)716 TEST_P(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_P(TrustStoreNSSTestWithoutSlotFilter,DistrustedCA)729 TEST_P(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_P(TrustStoreNSSTestWithoutSlotFilter,TrustedIntermediate)742 TEST_P(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_P(TrustStoreNSSTestWithoutSlotFilter,DistrustedIntermediate)753 TEST_P(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_P(TrustStoreNSSTestWithoutSlotFilter,TrustedServer)765 TEST_P(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_P(TrustStoreNSSTestWithoutSlotFilter,TrustedCaAndServer)776 TEST_P(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_P(TrustStoreNSSTestWithoutSlotFilter,MultipleTrustedCAWithSameSubject)787 TEST_P(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_P(TrustStoreNSSTestWithoutSlotFilter,DifferingTrustCAWithSameSubject)800 TEST_P(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 INSTANTIATE_TEST_SUITE_P(
813     All,
814     TrustStoreNSSTestWithoutSlotFilter,
815     testing::Combine(testing::Bool(), testing::Bool()),
816     [](const testing::TestParamInfo<
__anonbbcba6540402(const testing::TestParamInfo< TrustStoreNSSTestWithoutSlotFilter::ParamType>& info) 817         TrustStoreNSSTestWithoutSlotFilter::ParamType>& info) {
818       return std::string(std::get<0>(info.param) ? "TrustedLeafSupported"
819                                                  : "TrustAnchorOnly") +
820              (std::get<1>(info.param) ? "EnforceLocalAnchorConstraints"
821                                       : "NoLocalAnchorConstraints");
822     });
823 
824 // Tests for a TrustStoreNSS which does not allow certificates on user slots
825 // to be trusted.
826 class TrustStoreNSSTestDoNotAllowUserSlots : public TrustStoreNSSTestBase {
827  public:
828   TrustStoreNSSTestDoNotAllowUserSlots() = default;
829   ~TrustStoreNSSTestDoNotAllowUserSlots() override = default;
830 
CreateTrustStoreNSS()831   std::unique_ptr<TrustStoreNSS> CreateTrustStoreNSS() override {
832     return std::make_unique<TrustStoreNSS>(
833         /*user_slot_trust_setting=*/nullptr);
834   }
835 };
836 
837 // A certificate that is stored on a "user slot" is not trusted if the
838 // TrustStoreNSS is not allowed to trust certificates on user slots.
TEST_F(TrustStoreNSSTestDoNotAllowUserSlots,CertOnUserSlot)839 TEST_F(TrustStoreNSSTestDoNotAllowUserSlots, CertOnUserSlot) {
840   AddCertToNSSSlotWithTrust(newroot_.get(), test_nssdb_.slot(),
841                             bssl::CertificateTrustType::TRUSTED_ANCHOR);
842   EXPECT_TRUE(HasTrust({newroot_}, bssl::CertificateTrust::ForUnspecified()));
843 
844   // We don't do any filtering of the certs returned by GetIssuersOf since
845   // there isn't a security reason to.
846   EXPECT_TRUE(TrustStoreContains(newintermediate_, {newroot_}));
847 }
848 
849 // If an NSS trusted root is present in a user slot but
850 // user_slot_trust_setting=null, that trust setting should be ignored.
TEST_F(TrustStoreNSSTestDoNotAllowUserSlots,UserDbTrustForSystemRootIgnored)851 TEST_F(TrustStoreNSSTestDoNotAllowUserSlots, UserDbTrustForSystemRootIgnored) {
852   std::shared_ptr<const bssl::ParsedCertificate> system_root =
853       GetASSLTrustedBuiltinRoot();
854   ASSERT_TRUE(system_root);
855   EXPECT_EQ(CERTDB_TRUSTED_CA | CERTDB_VALID_CA,
856             GetNSSTrustForCert(system_root.get()));
857 
858   AddCertToNSSSlotWithTrust(system_root.get(), test_nssdb_.slot(),
859                             bssl::CertificateTrustType::TRUSTED_LEAF);
860 
861   EXPECT_TRUE(
862       HasTrust({system_root}, bssl::CertificateTrust::ForUnspecified()));
863 }
864 
865 // Tests for a TrustStoreNSS which does allows certificates on user slots to
866 // be only trusted if they are on a specific user slot.
867 class TrustStoreNSSTestAllowSpecifiedUserSlot : public TrustStoreNSSTestBase {
868  public:
869   TrustStoreNSSTestAllowSpecifiedUserSlot() = default;
870   ~TrustStoreNSSTestAllowSpecifiedUserSlot() override = default;
871 
CreateTrustStoreNSS()872   std::unique_ptr<TrustStoreNSS> CreateTrustStoreNSS() override {
873     return std::make_unique<TrustStoreNSS>(
874         crypto::ScopedPK11Slot(PK11_ReferenceSlot(test_nssdb_.slot())));
875   }
876 };
877 
878 // A certificate that is stored on a "user slot" is trusted if the
879 // TrustStoreNSS is allowed to trust that user slot.
TEST_F(TrustStoreNSSTestAllowSpecifiedUserSlot,CertOnUserSlot)880 TEST_F(TrustStoreNSSTestAllowSpecifiedUserSlot, CertOnUserSlot) {
881   AddCertToNSSSlotWithTrust(newroot_.get(), test_nssdb_.slot(),
882                             bssl::CertificateTrustType::TRUSTED_ANCHOR);
883   EXPECT_TRUE(HasTrust({newroot_}, ExpectedTrustForAnchor()));
884 }
885 
886 // A certificate that is stored on a "user slot" is not trusted if the
887 // TrustStoreNSS is allowed to trust a user slot, but the certificate is
888 // stored on another user slot.
TEST_F(TrustStoreNSSTestAllowSpecifiedUserSlot,CertOnOtherUserSlot)889 TEST_F(TrustStoreNSSTestAllowSpecifiedUserSlot, CertOnOtherUserSlot) {
890   AddCertToNSSSlotWithTrust(newroot_.get(), other_test_nssdb_.slot(),
891                             bssl::CertificateTrustType::TRUSTED_ANCHOR);
892   EXPECT_TRUE(HasTrust({newroot_}, bssl::CertificateTrust::ForUnspecified()));
893 }
894 
895 // The same certificate is stored in multiple user slots with different trust
896 // settings. Ensure that the correct trust setting is used.
TEST_F(TrustStoreNSSTestAllowSpecifiedUserSlot,CertOnMultipleSlots)897 TEST_F(TrustStoreNSSTestAllowSpecifiedUserSlot, CertOnMultipleSlots) {
898   // Add unrelated trust record to test that we find the correct one.
899   AddCertToNSSSlotWithTrust(newintermediate_.get(), test_nssdb_.slot(),
900                             bssl::CertificateTrustType::DISTRUSTED);
901 
902   AddCertToNSSSlotWithTrust(newroot_.get(), first_test_nssdb_.slot(),
903                             bssl::CertificateTrustType::DISTRUSTED);
904   AddCertToNSSSlotWithTrust(newroot_.get(), test_nssdb_.slot(),
905                             bssl::CertificateTrustType::TRUSTED_ANCHOR);
906   AddCertToNSSSlotWithTrust(newroot_.get(), other_test_nssdb_.slot(),
907                             bssl::CertificateTrustType::TRUSTED_LEAF);
908 
909   // Add unrelated trust record to test that we find the correct one.
910   AddCertToNSSSlotWithTrust(target_.get(), test_nssdb_.slot(),
911                             bssl::CertificateTrustType::DISTRUSTED);
912 
913   EXPECT_TRUE(HasTrust({newroot_}, ExpectedTrustForAnchor()));
914 }
915 
916 // A NSS trusted root certificate is also stored in multiple user slots with
917 // different trust settings. Ensure that the correct trust setting is used.
TEST_F(TrustStoreNSSTestAllowSpecifiedUserSlot,SystemRootCertOnMultipleSlots)918 TEST_F(TrustStoreNSSTestAllowSpecifiedUserSlot, SystemRootCertOnMultipleSlots) {
919   std::shared_ptr<const bssl::ParsedCertificate> system_root =
920       GetASSLTrustedBuiltinRoot();
921   ASSERT_TRUE(system_root);
922   EXPECT_EQ(CERTDB_TRUSTED_CA | CERTDB_VALID_CA,
923             GetNSSTrustForCert(system_root.get()));
924 
925   AddCertToNSSSlotWithTrust(system_root.get(), first_test_nssdb_.slot(),
926                             bssl::CertificateTrustType::DISTRUSTED);
927   AddCertToNSSSlotWithTrust(system_root.get(), test_nssdb_.slot(),
928                             bssl::CertificateTrustType::TRUSTED_LEAF);
929   AddCertToNSSSlotWithTrust(system_root.get(), other_test_nssdb_.slot(),
930                             bssl::CertificateTrustType::UNSPECIFIED);
931 
932   EXPECT_TRUE(HasTrust({system_root}, ExpectedTrustForLeaf()));
933 }
934 
935 // TODO(https://crbug.com/980443): If the internal non-removable slot is
936 // relevant on Chrome OS, add a test for allowing trust for certificates
937 // stored on that slot.
938 
939 class TrustStoreNSSTestDelegate {
940  public:
TrustStoreNSSTestDelegate()941   TrustStoreNSSTestDelegate()
942       : trust_store_nss_(TrustStoreNSS::UseTrustFromAllUserSlots()) {}
943 
AddCert(std::shared_ptr<const bssl::ParsedCertificate> cert)944   void AddCert(std::shared_ptr<const bssl::ParsedCertificate> cert) {
945     ASSERT_TRUE(test_nssdb_.is_open());
946     ScopedCERTCertificate nss_cert(
947         x509_util::CreateCERTCertificateFromBytes(cert->der_cert()));
948     ASSERT_TRUE(nss_cert);
949     SECStatus srv = PK11_ImportCert(
950         test_nssdb_.slot(), nss_cert.get(), CK_INVALID_HANDLE,
951         GetUniqueNickname().c_str(), PR_FALSE /* includeTrust (unused) */);
952     ASSERT_EQ(SECSuccess, srv);
953   }
954 
source()955   bssl::CertIssuerSource& source() { return trust_store_nss_; }
956 
957  protected:
GetUniqueNickname()958   std::string GetUniqueNickname() {
959     return "cert_issuer_source_nss_unittest" +
960            base::NumberToString(nickname_counter_++);
961   }
962 
963   crypto::ScopedTestNSSDB test_nssdb_;
964   TrustStoreNSS trust_store_nss_;
965   unsigned int nickname_counter_ = 0;
966 };
967 
968 INSTANTIATE_TYPED_TEST_SUITE_P(TrustStoreNSSTest2,
969                                CertIssuerSourceSyncTest,
970                                TrustStoreNSSTestDelegate);
971 // NSS doesn't normalize UTF8String values, so use the not-normalized version
972 // of those tests.
973 INSTANTIATE_TYPED_TEST_SUITE_P(TrustStoreNSSNotNormalizedTest,
974                                CertIssuerSourceSyncNotNormalizedTest,
975                                TrustStoreNSSTestDelegate);
976 }  // namespace
977 
978 }  // namespace net
979