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 30namespace psm = mozilla_security_manager; 31 32namespace net { 33 34namespace { 35 36// Returns a FilePath object representing the src/net/data/ssl/certificates 37// directory in the source tree. 38FilePath 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 48CertificateList 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 67bool 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 78std::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 85bool 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.) 105class 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 138base::LazyInstance<ScopedTempDir> CertDatabaseNSSTest::temp_db_dir_( 139 base::LINKER_INITIALIZED); 140bool CertDatabaseNSSTest::temp_db_initialized_ = false; 141 142TEST_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 152TEST_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 164TEST_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 186TEST_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 218TEST_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 249TEST_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 280TEST_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 303TEST_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 329TEST_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 366TEST_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 386TEST_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 407TEST_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 435TEST_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 469TEST_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