• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
GetTestCertsDirectory()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 
ListCertsInSlot(PK11SlotInfo * slot)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 
CleanupSlotContents(PK11SlotInfo * slot)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 
ReadTestFile(const std::string & name)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 
ReadCertIntoList(const std::string & name,CertificateList * certs)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:
SetUp()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   }
TearDown()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 
TEST_F(CertDatabaseNSSTest,ListCerts)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 
TEST_F(CertDatabaseNSSTest,ImportFromPKCS12WrongPassword)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 
TEST_F(CertDatabaseNSSTest,ImportFromPKCS12AndExportAgain)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 
TEST_F(CertDatabaseNSSTest,ImportCACert_SSLTrust)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 
TEST_F(CertDatabaseNSSTest,ImportCACert_EmailTrust)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 
TEST_F(CertDatabaseNSSTest,ImportCACert_ObjSignTrust)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 
TEST_F(CertDatabaseNSSTest,ImportCA_NotCACert)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 
TEST_F(CertDatabaseNSSTest,ImportCACertHierarchy)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 
TEST_F(CertDatabaseNSSTest,ImportCACertHierarchyDupeRoot)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 
TEST_F(CertDatabaseNSSTest,ImportCACertHierarchyUntrusted)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 
TEST_F(CertDatabaseNSSTest,ImportCACertHierarchyTree)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 
TEST_F(CertDatabaseNSSTest,ImportCACertNotHierarchy)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 
TEST_F(CertDatabaseNSSTest,ImportServerCert)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 
TEST_F(CertDatabaseNSSTest,ImportServerCert_SelfSigned)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