Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      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 <cert.h>
      6 #include <pk11pub.h>
      7 
      8 #include <algorithm>
      9 
     10 #include "base/file_path.h"
     11 #include "base/file_util.h"
     12 #include "base/lazy_instance.h"
     13 #include "base/memory/scoped_temp_dir.h"
     14 #include "base/path_service.h"
     15 #include "base/string_util.h"
     16 #include "base/utf_string_conversions.h"
     17 #include "crypto/nss_util.h"
     18 #include "crypto/nss_util_internal.h"
     19 #include "crypto/scoped_nss_types.h"
     20 #include "net/base/cert_database.h"
     21 #include "net/base/cert_status_flags.h"
     22 #include "net/base/cert_verify_result.h"
     23 #include "net/base/crypto_module.h"
     24 #include "net/base/net_errors.h"
     25 #include "net/base/x509_certificate.h"
     26 #include "net/third_party/mozilla_security_manager/nsNSSCertificateDB.h"
     27 #include "net/third_party/mozilla_security_manager/nsNSSCertTrust.h"
     28 #include "testing/gtest/include/gtest/gtest.h"
     29 
     30 namespace psm = mozilla_security_manager;
     31 
     32 namespace net {
     33 
     34 namespace {
     35 
     36 // Returns a FilePath object representing the src/net/data/ssl/certificates
     37 // directory in the source tree.
     38 FilePath GetTestCertsDirectory() {
     39   FilePath certs_dir;
     40   PathService::Get(base::DIR_SOURCE_ROOT, &certs_dir);
     41   certs_dir = certs_dir.AppendASCII("net");
     42   certs_dir = certs_dir.AppendASCII("data");
     43   certs_dir = certs_dir.AppendASCII("ssl");
     44   certs_dir = certs_dir.AppendASCII("certificates");
     45   return certs_dir;
     46 }
     47 
     48 CertificateList ListCertsInSlot(PK11SlotInfo* slot) {
     49   CertificateList result;
     50   CERTCertList* cert_list = PK11_ListCertsInSlot(slot);
     51   for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list);
     52        !CERT_LIST_END(node, cert_list);
     53        node = CERT_LIST_NEXT(node)) {
     54     result.push_back(
     55         X509Certificate::CreateFromHandle(
     56             node->cert,
     57             X509Certificate::SOURCE_LONE_CERT_IMPORT,
     58             X509Certificate::OSCertHandles()));
     59   }
     60   CERT_DestroyCertList(cert_list);
     61 
     62   // Sort the result so that test comparisons can be deterministic.
     63   std::sort(result.begin(), result.end(), X509Certificate::LessThan());
     64   return result;
     65 }
     66 
     67 bool CleanupSlotContents(PK11SlotInfo* slot) {
     68   CertDatabase cert_db;
     69   bool ok = true;
     70   CertificateList certs = ListCertsInSlot(slot);
     71   for (size_t i = 0; i < certs.size(); ++i) {
     72     if (!cert_db.DeleteCertAndKey(certs[i]))
     73       ok = false;
     74   }
     75   return ok;
     76 }
     77 
     78 std::string ReadTestFile(const std::string& name) {
     79   std::string result;
     80   FilePath cert_path = GetTestCertsDirectory().AppendASCII(name);
     81   EXPECT_TRUE(file_util::ReadFileToString(cert_path, &result));
     82   return result;
     83 }
     84 
     85 bool ReadCertIntoList(const std::string& name, CertificateList* certs) {
     86   std::string cert_data = ReadTestFile(name);
     87   if (cert_data.empty())
     88     return false;
     89 
     90   X509Certificate* cert = X509Certificate::CreateFromBytes(
     91       cert_data.data(), cert_data.size());
     92   if (!cert)
     93     return false;
     94 
     95   certs->push_back(cert);
     96   return true;
     97 }
     98 
     99 }  // namespace
    100 
    101 // TODO(mattm): when https://bugzilla.mozilla.org/show_bug.cgi?id=588269 is
    102 // fixed, switch back to using a separate userdb for each test.
    103 // (When doing so, remember to add some standalone tests of DeleteCert since it
    104 // won't be tested by TearDown anymore.)
    105 class CertDatabaseNSSTest : public testing::Test {
    106  public:
    107   virtual void SetUp() {
    108     if (!temp_db_initialized_) {
    109       ASSERT_TRUE(temp_db_dir_.Get().CreateUniqueTempDir());
    110       ASSERT_TRUE(
    111           crypto::OpenTestNSSDB(temp_db_dir_.Get().path(),
    112                                 "CertDatabaseNSSTest db"));
    113       temp_db_initialized_ = true;
    114     }
    115     slot_ = cert_db_.GetPublicModule();
    116 
    117     // Test db should be empty at start of test.
    118     EXPECT_EQ(0U, ListCertsInSlot(slot_->os_module_handle()).size());
    119   }
    120   virtual void TearDown() {
    121     // Don't try to cleanup if the setup failed.
    122     ASSERT_TRUE(slot_->os_module_handle());
    123 
    124     EXPECT_TRUE(CleanupSlotContents(slot_->os_module_handle()));
    125     EXPECT_EQ(0U, ListCertsInSlot(slot_->os_module_handle()).size());
    126   }
    127 
    128  protected:
    129   scoped_refptr<CryptoModule> slot_;
    130   CertDatabase cert_db_;
    131 
    132  private:
    133   static base::LazyInstance<ScopedTempDir> temp_db_dir_;
    134   static bool temp_db_initialized_;
    135 };
    136 
    137 // static
    138 base::LazyInstance<ScopedTempDir> CertDatabaseNSSTest::temp_db_dir_(
    139     base::LINKER_INITIALIZED);
    140 bool CertDatabaseNSSTest::temp_db_initialized_ = false;
    141 
    142 TEST_F(CertDatabaseNSSTest, ListCerts) {
    143   // This test isn't terribly useful, though it will at least let valgrind test
    144   // for leaks.
    145   CertificateList certs;
    146   cert_db_.ListCerts(&certs);
    147   // The test DB is empty, but let's assume there will always be something in
    148   // the other slots.
    149   EXPECT_LT(0U, certs.size());
    150 }
    151 
    152 TEST_F(CertDatabaseNSSTest, ImportFromPKCS12WrongPassword) {
    153   std::string pkcs12_data = ReadTestFile("client.p12");
    154 
    155   EXPECT_EQ(ERR_PKCS12_IMPORT_BAD_PASSWORD,
    156             cert_db_.ImportFromPKCS12(slot_,
    157                                       pkcs12_data,
    158                                       ASCIIToUTF16("")));
    159 
    160   // Test db should still be empty.
    161   EXPECT_EQ(0U, ListCertsInSlot(slot_->os_module_handle()).size());
    162 }
    163 
    164 TEST_F(CertDatabaseNSSTest, ImportFromPKCS12AndExportAgain) {
    165   std::string pkcs12_data = ReadTestFile("client.p12");
    166 
    167   EXPECT_EQ(OK, cert_db_.ImportFromPKCS12(slot_,
    168                                           pkcs12_data,
    169                                           ASCIIToUTF16("12345")));
    170 
    171   CertificateList cert_list = ListCertsInSlot(slot_->os_module_handle());
    172   ASSERT_EQ(1U, cert_list.size());
    173   scoped_refptr<X509Certificate> cert(cert_list[0]);
    174 
    175   EXPECT_EQ("testusercert",
    176             cert->subject().common_name);
    177 
    178   // TODO(mattm): move export test to seperate test case?
    179   std::string exported_data;
    180   EXPECT_EQ(1, cert_db_.ExportToPKCS12(cert_list, ASCIIToUTF16("exportpw"),
    181                                        &exported_data));
    182   ASSERT_LT(0U, exported_data.size());
    183   // TODO(mattm): further verification of exported data?
    184 }
    185 
    186 TEST_F(CertDatabaseNSSTest, ImportCACert_SSLTrust) {
    187   std::string cert_data = ReadTestFile("root_ca_cert.crt");
    188 
    189   CertificateList certs =
    190       X509Certificate::CreateCertificateListFromBytes(
    191           cert_data.data(), cert_data.size(), X509Certificate::FORMAT_AUTO);
    192   ASSERT_EQ(1U, certs.size());
    193   EXPECT_FALSE(certs[0]->os_cert_handle()->isperm);
    194 
    195   // Import it.
    196   CertDatabase::ImportCertFailureList failed;
    197   EXPECT_TRUE(cert_db_.ImportCACerts(certs, CertDatabase::TRUSTED_SSL,
    198                                      &failed));
    199 
    200   EXPECT_EQ(0U, failed.size());
    201 
    202   CertificateList cert_list = ListCertsInSlot(slot_->os_module_handle());
    203   ASSERT_EQ(1U, cert_list.size());
    204   scoped_refptr<X509Certificate> cert(cert_list[0]);
    205   EXPECT_EQ("Test CA", cert->subject().common_name);
    206 
    207   EXPECT_EQ(CertDatabase::TRUSTED_SSL,
    208             cert_db_.GetCertTrust(cert.get(), CA_CERT));
    209 
    210   psm::nsNSSCertTrust trust(cert->os_cert_handle()->trust);
    211   EXPECT_TRUE(trust.HasTrustedCA(PR_TRUE, PR_FALSE, PR_FALSE));
    212   EXPECT_FALSE(trust.HasTrustedCA(PR_FALSE, PR_TRUE, PR_FALSE));
    213   EXPECT_FALSE(trust.HasTrustedCA(PR_FALSE, PR_FALSE, PR_TRUE));
    214   EXPECT_FALSE(trust.HasTrustedCA(PR_TRUE, PR_TRUE, PR_TRUE));
    215   EXPECT_TRUE(trust.HasCA(PR_TRUE, PR_TRUE, PR_TRUE));
    216 }
    217 
    218 TEST_F(CertDatabaseNSSTest, ImportCACert_EmailTrust) {
    219   std::string cert_data = ReadTestFile("root_ca_cert.crt");
    220 
    221   CertificateList certs =
    222       X509Certificate::CreateCertificateListFromBytes(
    223           cert_data.data(), cert_data.size(), X509Certificate::FORMAT_AUTO);
    224   ASSERT_EQ(1U, certs.size());
    225   EXPECT_FALSE(certs[0]->os_cert_handle()->isperm);
    226 
    227   // Import it.
    228   CertDatabase::ImportCertFailureList failed;
    229   EXPECT_TRUE(cert_db_.ImportCACerts(certs, CertDatabase::TRUSTED_EMAIL,
    230                                      &failed));
    231 
    232   EXPECT_EQ(0U, failed.size());
    233 
    234   CertificateList cert_list = ListCertsInSlot(slot_->os_module_handle());
    235   ASSERT_EQ(1U, cert_list.size());
    236   scoped_refptr<X509Certificate> cert(cert_list[0]);
    237   EXPECT_EQ("Test CA", cert->subject().common_name);
    238 
    239   EXPECT_EQ(CertDatabase::TRUSTED_EMAIL,
    240             cert_db_.GetCertTrust(cert.get(), CA_CERT));
    241 
    242   psm::nsNSSCertTrust trust(cert->os_cert_handle()->trust);
    243   EXPECT_FALSE(trust.HasTrustedCA(PR_TRUE, PR_FALSE, PR_FALSE));
    244   EXPECT_TRUE(trust.HasTrustedCA(PR_FALSE, PR_TRUE, PR_FALSE));
    245   EXPECT_FALSE(trust.HasTrustedCA(PR_FALSE, PR_FALSE, PR_TRUE));
    246   EXPECT_TRUE(trust.HasCA(PR_TRUE, PR_TRUE, PR_TRUE));
    247 }
    248 
    249 TEST_F(CertDatabaseNSSTest, ImportCACert_ObjSignTrust) {
    250   std::string cert_data = ReadTestFile("root_ca_cert.crt");
    251 
    252   CertificateList certs =
    253       X509Certificate::CreateCertificateListFromBytes(
    254           cert_data.data(), cert_data.size(), X509Certificate::FORMAT_AUTO);
    255   ASSERT_EQ(1U, certs.size());
    256   EXPECT_FALSE(certs[0]->os_cert_handle()->isperm);
    257 
    258   // Import it.
    259   CertDatabase::ImportCertFailureList failed;
    260   EXPECT_TRUE(cert_db_.ImportCACerts(certs, CertDatabase::TRUSTED_OBJ_SIGN,
    261                                      &failed));
    262 
    263   EXPECT_EQ(0U, failed.size());
    264 
    265   CertificateList cert_list = ListCertsInSlot(slot_->os_module_handle());
    266   ASSERT_EQ(1U, cert_list.size());
    267   scoped_refptr<X509Certificate> cert(cert_list[0]);
    268   EXPECT_EQ("Test CA", cert->subject().common_name);
    269 
    270   EXPECT_EQ(CertDatabase::TRUSTED_OBJ_SIGN,
    271             cert_db_.GetCertTrust(cert.get(), CA_CERT));
    272 
    273   psm::nsNSSCertTrust trust(cert->os_cert_handle()->trust);
    274   EXPECT_FALSE(trust.HasTrustedCA(PR_TRUE, PR_FALSE, PR_FALSE));
    275   EXPECT_FALSE(trust.HasTrustedCA(PR_FALSE, PR_TRUE, PR_FALSE));
    276   EXPECT_TRUE(trust.HasTrustedCA(PR_FALSE, PR_FALSE, PR_TRUE));
    277   EXPECT_TRUE(trust.HasCA(PR_TRUE, PR_TRUE, PR_TRUE));
    278 }
    279 
    280 TEST_F(CertDatabaseNSSTest, ImportCA_NotCACert) {
    281   std::string cert_data = ReadTestFile("google.single.pem");
    282 
    283   CertificateList certs =
    284       X509Certificate::CreateCertificateListFromBytes(
    285           cert_data.data(), cert_data.size(), X509Certificate::FORMAT_AUTO);
    286   ASSERT_EQ(1U, certs.size());
    287   EXPECT_FALSE(certs[0]->os_cert_handle()->isperm);
    288 
    289   // Import it.
    290   CertDatabase::ImportCertFailureList failed;
    291   EXPECT_TRUE(cert_db_.ImportCACerts(certs, CertDatabase::TRUSTED_SSL,
    292                                      &failed));
    293   ASSERT_EQ(1U, failed.size());
    294   // Note: this compares pointers directly.  It's okay in this case because
    295   // ImportCACerts returns the same pointers that were passed in.  In the
    296   // general case IsSameOSCert should be used.
    297   EXPECT_EQ(certs[0], failed[0].certificate);
    298   EXPECT_EQ(ERR_IMPORT_CA_CERT_NOT_CA, failed[0].net_error);
    299 
    300   EXPECT_EQ(0U, ListCertsInSlot(slot_->os_module_handle()).size());
    301 }
    302 
    303 TEST_F(CertDatabaseNSSTest, ImportCACertHierarchy) {
    304   CertificateList certs;
    305   ASSERT_TRUE(ReadCertIntoList("dod_root_ca_2_cert.der", &certs));
    306   ASSERT_TRUE(ReadCertIntoList("dod_ca_17_cert.der", &certs));
    307   ASSERT_TRUE(ReadCertIntoList("www_us_army_mil_cert.der", &certs));
    308 
    309   // Import it.
    310   CertDatabase::ImportCertFailureList failed;
    311   // Have to specify email trust for the cert verification of the child cert to
    312   // work (see
    313   // http://mxr.mozilla.org/mozilla/source/security/nss/lib/certhigh/certvfy.c#752
    314   // "XXX This choice of trustType seems arbitrary.")
    315   EXPECT_TRUE(cert_db_.ImportCACerts(
    316       certs, CertDatabase::TRUSTED_SSL | CertDatabase::TRUSTED_EMAIL,
    317       &failed));
    318 
    319   ASSERT_EQ(1U, failed.size());
    320   EXPECT_EQ("www.us.army.mil", failed[0].certificate->subject().common_name);
    321   EXPECT_EQ(ERR_IMPORT_CA_CERT_NOT_CA, failed[0].net_error);
    322 
    323   CertificateList cert_list = ListCertsInSlot(slot_->os_module_handle());
    324   ASSERT_EQ(2U, cert_list.size());
    325   EXPECT_EQ("DoD Root CA 2", cert_list[0]->subject().common_name);
    326   EXPECT_EQ("DOD CA-17", cert_list[1]->subject().common_name);
    327 }
    328 
    329 TEST_F(CertDatabaseNSSTest, ImportCACertHierarchyDupeRoot) {
    330   CertificateList certs;
    331   ASSERT_TRUE(ReadCertIntoList("dod_root_ca_2_cert.der", &certs));
    332 
    333   // First import just the root.
    334   CertDatabase::ImportCertFailureList failed;
    335   EXPECT_TRUE(cert_db_.ImportCACerts(
    336       certs, CertDatabase::TRUSTED_SSL | CertDatabase::TRUSTED_EMAIL,
    337       &failed));
    338 
    339   EXPECT_EQ(0U, failed.size());
    340   CertificateList cert_list = ListCertsInSlot(slot_->os_module_handle());
    341   ASSERT_EQ(1U, cert_list.size());
    342   EXPECT_EQ("DoD Root CA 2", cert_list[0]->subject().common_name);
    343 
    344   ASSERT_TRUE(ReadCertIntoList("dod_ca_17_cert.der", &certs));
    345   ASSERT_TRUE(ReadCertIntoList("www_us_army_mil_cert.der", &certs));
    346 
    347   // Now import with the other certs in the list too.  Even though the root is
    348   // already present, we should still import the rest.
    349   failed.clear();
    350   EXPECT_TRUE(cert_db_.ImportCACerts(
    351       certs, CertDatabase::TRUSTED_SSL | CertDatabase::TRUSTED_EMAIL,
    352       &failed));
    353 
    354   ASSERT_EQ(2U, failed.size());
    355   EXPECT_EQ("DoD Root CA 2", failed[0].certificate->subject().common_name);
    356   EXPECT_EQ(ERR_IMPORT_CERT_ALREADY_EXISTS, failed[0].net_error);
    357   EXPECT_EQ("www.us.army.mil", failed[1].certificate->subject().common_name);
    358   EXPECT_EQ(ERR_IMPORT_CA_CERT_NOT_CA, failed[1].net_error);
    359 
    360   cert_list = ListCertsInSlot(slot_->os_module_handle());
    361   ASSERT_EQ(2U, cert_list.size());
    362   EXPECT_EQ("DoD Root CA 2", cert_list[0]->subject().common_name);
    363   EXPECT_EQ("DOD CA-17", cert_list[1]->subject().common_name);
    364 }
    365 
    366 TEST_F(CertDatabaseNSSTest, ImportCACertHierarchyUntrusted) {
    367   CertificateList certs;
    368   ASSERT_TRUE(ReadCertIntoList("dod_root_ca_2_cert.der", &certs));
    369   ASSERT_TRUE(ReadCertIntoList("dod_ca_17_cert.der", &certs));
    370 
    371   // Import it.
    372   CertDatabase::ImportCertFailureList failed;
    373   EXPECT_TRUE(cert_db_.ImportCACerts(certs, CertDatabase::UNTRUSTED, &failed));
    374 
    375   ASSERT_EQ(1U, failed.size());
    376   EXPECT_EQ("DOD CA-17", failed[0].certificate->subject().common_name);
    377   // TODO(mattm): should check for net error equivalent of
    378   // SEC_ERROR_UNTRUSTED_ISSUER
    379   EXPECT_EQ(ERR_FAILED, failed[0].net_error);
    380 
    381   CertificateList cert_list = ListCertsInSlot(slot_->os_module_handle());
    382   ASSERT_EQ(1U, cert_list.size());
    383   EXPECT_EQ("DoD Root CA 2", cert_list[0]->subject().common_name);
    384 }
    385 
    386 TEST_F(CertDatabaseNSSTest, ImportCACertHierarchyTree) {
    387   CertificateList certs;
    388   ASSERT_TRUE(ReadCertIntoList("dod_root_ca_2_cert.der", &certs));
    389   ASSERT_TRUE(ReadCertIntoList("dod_ca_13_cert.der", &certs));
    390   ASSERT_TRUE(ReadCertIntoList("dod_ca_17_cert.der", &certs));
    391 
    392   // Import it.
    393   CertDatabase::ImportCertFailureList failed;
    394   EXPECT_TRUE(cert_db_.ImportCACerts(
    395       certs, CertDatabase::TRUSTED_SSL | CertDatabase::TRUSTED_EMAIL,
    396       &failed));
    397 
    398   EXPECT_EQ(0U, failed.size());
    399 
    400   CertificateList cert_list = ListCertsInSlot(slot_->os_module_handle());
    401   ASSERT_EQ(3U, cert_list.size());
    402   EXPECT_EQ("DOD CA-13", cert_list[0]->subject().common_name);
    403   EXPECT_EQ("DoD Root CA 2", cert_list[1]->subject().common_name);
    404   EXPECT_EQ("DOD CA-17", cert_list[2]->subject().common_name);
    405 }
    406 
    407 TEST_F(CertDatabaseNSSTest, ImportCACertNotHierarchy) {
    408   std::string cert_data = ReadTestFile("root_ca_cert.crt");
    409   CertificateList certs =
    410       X509Certificate::CreateCertificateListFromBytes(
    411           cert_data.data(), cert_data.size(), X509Certificate::FORMAT_AUTO);
    412   ASSERT_EQ(1U, certs.size());
    413   ASSERT_TRUE(ReadCertIntoList("dod_ca_13_cert.der", &certs));
    414   ASSERT_TRUE(ReadCertIntoList("dod_ca_17_cert.der", &certs));
    415 
    416   // Import it.
    417   CertDatabase::ImportCertFailureList failed;
    418   EXPECT_TRUE(cert_db_.ImportCACerts(
    419       certs, CertDatabase::TRUSTED_SSL | CertDatabase::TRUSTED_EMAIL |
    420       CertDatabase::TRUSTED_OBJ_SIGN, &failed));
    421 
    422   ASSERT_EQ(2U, failed.size());
    423   // TODO(mattm): should check for net error equivalent of
    424   // SEC_ERROR_UNKNOWN_ISSUER
    425   EXPECT_EQ("DOD CA-13", failed[0].certificate->subject().common_name);
    426   EXPECT_EQ(ERR_FAILED, failed[0].net_error);
    427   EXPECT_EQ("DOD CA-17", failed[1].certificate->subject().common_name);
    428   EXPECT_EQ(ERR_FAILED, failed[1].net_error);
    429 
    430   CertificateList cert_list = ListCertsInSlot(slot_->os_module_handle());
    431   ASSERT_EQ(1U, cert_list.size());
    432   EXPECT_EQ("Test CA", cert_list[0]->subject().common_name);
    433 }
    434 
    435 TEST_F(CertDatabaseNSSTest, ImportServerCert) {
    436   // Need to import intermediate cert for the verify of google cert, otherwise
    437   // it will try to fetch it automatically with cert_pi_useAIACertFetch, which
    438   // will cause OCSPCreateSession on the main thread, which is not allowed.
    439   std::string cert_data = ReadTestFile("google.chain.pem");
    440   CertificateList certs =
    441       X509Certificate::CreateCertificateListFromBytes(
    442           cert_data.data(), cert_data.size(), X509Certificate::FORMAT_AUTO);
    443   ASSERT_EQ(2U, certs.size());
    444 
    445   CertDatabase::ImportCertFailureList failed;
    446   EXPECT_TRUE(cert_db_.ImportServerCert(certs, &failed));
    447 
    448   EXPECT_EQ(0U, failed.size());
    449 
    450   CertificateList cert_list = ListCertsInSlot(slot_->os_module_handle());
    451   ASSERT_EQ(2U, cert_list.size());
    452   scoped_refptr<X509Certificate> goog_cert(cert_list[0]);
    453   scoped_refptr<X509Certificate> thawte_cert(cert_list[1]);
    454   EXPECT_EQ("www.google.com", goog_cert->subject().common_name);
    455   EXPECT_EQ("Thawte SGC CA", thawte_cert->subject().common_name);
    456 
    457   EXPECT_EQ(CertDatabase::UNTRUSTED,
    458             cert_db_.GetCertTrust(goog_cert.get(), SERVER_CERT));
    459   psm::nsNSSCertTrust goog_trust(goog_cert->os_cert_handle()->trust);
    460   EXPECT_TRUE(goog_trust.HasPeer(PR_TRUE, PR_TRUE, PR_TRUE));
    461 
    462   int flags = 0;
    463   CertVerifyResult verify_result;
    464   int error = goog_cert->Verify("www.google.com", flags, &verify_result);
    465   EXPECT_EQ(OK, error);
    466   EXPECT_EQ(0, verify_result.cert_status);
    467 }
    468 
    469 TEST_F(CertDatabaseNSSTest, ImportServerCert_SelfSigned) {
    470   CertificateList certs;
    471   ASSERT_TRUE(ReadCertIntoList("punycodetest.der", &certs));
    472 
    473   CertDatabase::ImportCertFailureList failed;
    474   EXPECT_TRUE(cert_db_.ImportServerCert(certs, &failed));
    475 
    476   EXPECT_EQ(0U, failed.size());
    477 
    478   CertificateList cert_list = ListCertsInSlot(slot_->os_module_handle());
    479   ASSERT_EQ(1U, cert_list.size());
    480   scoped_refptr<X509Certificate> puny_cert(cert_list[0]);
    481 
    482   EXPECT_EQ(CertDatabase::UNTRUSTED,
    483             cert_db_.GetCertTrust(puny_cert.get(), SERVER_CERT));
    484   psm::nsNSSCertTrust puny_trust(puny_cert->os_cert_handle()->trust);
    485   EXPECT_TRUE(puny_trust.HasPeer(PR_TRUE, PR_TRUE, PR_TRUE));
    486 
    487   int flags = 0;
    488   CertVerifyResult verify_result;
    489   int error = puny_cert->Verify("xn--wgv71a119e.com", flags, &verify_result);
    490   EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error);
    491   EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, verify_result.cert_status);
    492 
    493   // TODO(mattm): this should be SERVER_CERT, not CA_CERT, but that does not
    494   // work due to NSS bug: https://bugzilla.mozilla.org/show_bug.cgi?id=531160
    495   EXPECT_TRUE(cert_db_.SetCertTrust(
    496       puny_cert.get(), CA_CERT,
    497       CertDatabase::TRUSTED_SSL | CertDatabase::TRUSTED_EMAIL));
    498 
    499   verify_result.Reset();
    500   error = puny_cert->Verify("xn--wgv71a119e.com", flags, &verify_result);
    501   EXPECT_EQ(OK, error);
    502   EXPECT_EQ(0, verify_result.cert_status);
    503 }
    504 
    505 }  // namespace net
    506