// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "net/cert/internal/trust_store_nss.h" #include <cert.h> #include <certdb.h> #include <pkcs11n.h> #include <prtypes.h> #include <memory> #include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" #include "base/test/scoped_feature_list.h" #include "crypto/scoped_test_nss_db.h" #include "net/base/features.h" #include "net/cert/internal/cert_issuer_source_sync_unittest.h" #include "net/cert/internal/test_helpers.h" #include "net/cert/scoped_nss_types.h" #include "net/cert/x509_util.h" #include "net/cert/x509_util_nss.h" #include "net/test/cert_test_util.h" #include "net/test/test_data_directory.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/boringssl/src/include/openssl/pool.h" #include "third_party/boringssl/src/pki/parsed_certificate.h" #include "third_party/boringssl/src/pki/trust_store.h" namespace net { namespace { unsigned TrustTypeToNSSTrust(bssl::CertificateTrustType trust) { … } std::shared_ptr<const bssl::ParsedCertificate> GetASSLTrustedBuiltinRoot() { … } std::optional<unsigned> GetNSSTrustForCert( const bssl::ParsedCertificate* cert) { … } class TrustStoreNSSTestBase : public ::testing::Test { … }; // Specifies which kind of per-slot filtering the TrustStoreNSS is supposed to // perform in the parametrized TrustStoreNSSTestWithSlotFilterType. enum class SlotFilterType { … }; std::string SlotFilterTypeToString(SlotFilterType slot_filter_type) { … } // Used for testing a TrustStoreNSS with the slot filter type specified by the // test parameter. These tests are cases that are expected to be the same // regardless of the slot filter type. class TrustStoreNSSTestWithSlotFilterType : public TrustStoreNSSTestBase, public testing::WithParamInterface<SlotFilterType> { … }; // Without adding any certs to the NSS DB, should get no anchor results for // any of the test certs. TEST_P(TrustStoreNSSTestWithSlotFilterType, CertsNotPresent) { … } // TrustStoreNSS should return temporary certs on Chrome OS, because on Chrome // OS temporary certs are used to supply policy-provided untrusted authority // certs. (See https://crbug.com/978854) // On other platforms it's not required but doesn't hurt anything. TEST_P(TrustStoreNSSTestWithSlotFilterType, TempCertPresent) { … } // Independent of the specified slot-based filtering mode, built-in root certs // should never be trusted. TEST_P(TrustStoreNSSTestWithSlotFilterType, TrustAllowedForBuiltinRootCerts) { … } // Check that ListCertsIgnoringNSSRoots and GetAllUserAddedCerts don't // return built-in roots. TEST_P(TrustStoreNSSTestWithSlotFilterType, ListCertsIgnoresBuiltinRoots) { … } // Check that GetAllUserAddedCerts doesn't return any client certs, as it is // only supposed to return server certs. TEST_P(TrustStoreNSSTestWithSlotFilterType, GetAllUserAddedCertsNoClientCerts) { … } // Check that GetAllUserAddedCerts will return a client cert that has had trust // bits added for server auth. TEST_P(TrustStoreNSSTestWithSlotFilterType, GetAllUserAddedCertsManualTrustClientCert) { … } INSTANTIATE_TEST_SUITE_P(…); // Tests a TrustStoreNSS that ignores system root certs. class TrustStoreNSSTestIgnoreSystemCerts : public TrustStoreNSSTestBase { … }; TEST_F(TrustStoreNSSTestIgnoreSystemCerts, UnknownCertIgnored) { … } // An NSS CERTCertificate object exists for the cert, but it is not // imported into any DB. Should be unspecified trust. TEST_F(TrustStoreNSSTestIgnoreSystemCerts, TemporaryCertIgnored) { … } // Cert is added to user DB, but without explicitly calling // CERT_ChangeCertTrust. Should be unspecified trust. TEST_F(TrustStoreNSSTestIgnoreSystemCerts, UserCertWithNoTrust) { … } TEST_F(TrustStoreNSSTestIgnoreSystemCerts, UserRootTrusted) { … } TEST_F(TrustStoreNSSTestIgnoreSystemCerts, UserRootDistrusted) { … } TEST_F(TrustStoreNSSTestIgnoreSystemCerts, UserTrustedServer) { … } TEST_F(TrustStoreNSSTestIgnoreSystemCerts, UserTrustedCaAndServer) { … } TEST_F(TrustStoreNSSTestIgnoreSystemCerts, SystemRootCertIgnored) { … } // A system trusted root is also present in a user DB, but without any trust // settings in the user DB. The system trust settings should not be used. TEST_F(TrustStoreNSSTestIgnoreSystemCerts, SystemRootCertIgnoredWhenPresentInUserDb) { … } // A system trusted root is also present in a user DB, with TRUSTED_CA settings // in the user DB. The system trust settings should not be used, but the trust // from the user DB should be honored. TEST_F(TrustStoreNSSTestIgnoreSystemCerts, UserDbTrustForSystemRootHonored) { … } // A system trusted root is also present in a user DB, with leaf trust in the // user DB. The system trust settings should not be used, but the trust from // the user DB should be honored. TEST_F(TrustStoreNSSTestIgnoreSystemCerts, UserDbLeafTrustForSystemRootHonored) { … } // A system trusted root is also present in a user DB, with both CA and leaf // trust in the user DB. The system trust settings should not be used, but the // trust from the user DB should be honored. TEST_F(TrustStoreNSSTestIgnoreSystemCerts, UserDbAnchorAndLeafTrustForSystemRootHonored) { … } // A system trusted root is also present in a user DB, with TERMINAL_RECORD // settings in the user DB. The system trust settings should not be used, and // the distrust from the user DB should be honored. TEST_F(TrustStoreNSSTestIgnoreSystemCerts, UserDbDistrustForSystemRootHonored) { … } // A system trusted root is also present in a user DB, with a trust object with // no SSL trust flags set in the user DB. The system trust settings should not // be used, and the lack of trust flags in the user DB should result in // unspecified trust. TEST_F(TrustStoreNSSTestIgnoreSystemCerts, UserDbUnspecifiedTrustForSystemRootHonored) { … } // Tests a TrustStoreNSS that does not filter which certificates class TrustStoreNSSTestWithoutSlotFilter : public TrustStoreNSSTestBase { … }; // If certs are present in NSS DB but aren't marked as trusted, should get no // anchor results for any of the test certs. TEST_F(TrustStoreNSSTestWithoutSlotFilter, CertsPresentButNotTrusted) { … } // Trust a single self-signed CA certificate. TEST_F(TrustStoreNSSTestWithoutSlotFilter, TrustedCA) { … } // Distrust a single self-signed CA certificate. TEST_F(TrustStoreNSSTestWithoutSlotFilter, DistrustedCA) { … } // Trust a single intermediate certificate. TEST_F(TrustStoreNSSTestWithoutSlotFilter, TrustedIntermediate) { … } // Distrust a single intermediate certificate. TEST_F(TrustStoreNSSTestWithoutSlotFilter, DistrustedIntermediate) { … } // Trust a single server certificate. TEST_F(TrustStoreNSSTestWithoutSlotFilter, TrustedServer) { … } // Trust a single certificate with both CA and server trust bits. TEST_F(TrustStoreNSSTestWithoutSlotFilter, TrustedCaAndServer) { … } // Trust multiple self-signed CA certificates with the same name. TEST_F(TrustStoreNSSTestWithoutSlotFilter, MultipleTrustedCAWithSameSubject) { … } // Different trust settings for multiple self-signed CA certificates with the // same name. TEST_F(TrustStoreNSSTestWithoutSlotFilter, DifferingTrustCAWithSameSubject) { … } // Check that ListCertsIgnoringNssRoots and GetAllUserAddedCerts are correctly // looking at all slots. TEST_F(TrustStoreNSSTestWithoutSlotFilter, ListCertsLooksAtAllSlots) { … } // Tests for a TrustStoreNSS which does allows certificates on user slots to // be only trusted if they are on a specific user slot. class TrustStoreNSSTestAllowSpecifiedUserSlot : public TrustStoreNSSTestBase { … }; // A certificate that is stored on a "user slot" is trusted if the // TrustStoreNSS is allowed to trust that user slot. TEST_F(TrustStoreNSSTestAllowSpecifiedUserSlot, CertOnUserSlot) { … } // A certificate that is stored on a "user slot" is not trusted if the // TrustStoreNSS is allowed to trust a user slot, but the certificate is // stored on another user slot. TEST_F(TrustStoreNSSTestAllowSpecifiedUserSlot, CertOnOtherUserSlot) { … } // The same certificate is stored in multiple user slots with different trust // settings. Ensure that the correct trust setting is used. TEST_F(TrustStoreNSSTestAllowSpecifiedUserSlot, CertOnMultipleSlots) { … } // A NSS trusted root certificate is also stored in multiple user slots with // different trust settings. Ensure that the correct trust setting is used. TEST_F(TrustStoreNSSTestAllowSpecifiedUserSlot, SystemRootCertOnMultipleSlots) { … } // Check to see ListCertsIgnoringNSSRoots and GetAllUserAddedCerts correctly // enforce slot filters. TEST_F(TrustStoreNSSTestAllowSpecifiedUserSlot, ListCertsFiltersBySlot) { … } // TODO(crbug.com/41468842): If the internal non-removable slot is // relevant on Chrome OS, add a test for allowing trust for certificates // stored on that slot. class TrustStoreNSSTestDelegate { … }; INSTANTIATE_TYPED_TEST_SUITE_P(…); // NSS doesn't normalize UTF8String values, so use the not-normalized version // of those tests. INSTANTIATE_TYPED_TEST_SUITE_P(…); } // namespace } // namespace net