Home | History | Annotate | Download | only in crypto
      1 // Copyright 2014 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 "crypto/scoped_test_nss_db.h"
      6 
      7 #include <cert.h>
      8 
      9 #include "base/logging.h"
     10 #include "base/threading/thread_restrictions.h"
     11 #include "crypto/nss_util.h"
     12 #include "crypto/nss_util_internal.h"
     13 
     14 namespace crypto {
     15 
     16 ScopedTestNSSDB::ScopedTestNSSDB() {
     17   EnsureNSSInit();
     18   // NSS is allowed to do IO on the current thread since dispatching
     19   // to a dedicated thread would still have the affect of blocking
     20   // the current thread, due to NSS's internal locking requirements
     21   base::ThreadRestrictions::ScopedAllowIO allow_io;
     22 
     23   if (!temp_dir_.CreateUniqueTempDir())
     24     return;
     25 
     26   const char kTestDescription[] = "Test DB";
     27   slot_ = OpenSoftwareNSSDB(temp_dir_.path(), kTestDescription);
     28 }
     29 
     30 ScopedTestNSSDB::~ScopedTestNSSDB() {
     31   // Remove trust from any certs in the test DB before closing it. Otherwise NSS
     32   // may cache verification results even after the test DB is gone.
     33   if (slot_) {
     34     CERTCertList* cert_list = PK11_ListCertsInSlot(slot_.get());
     35     for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list);
     36          !CERT_LIST_END(node, cert_list);
     37          node = CERT_LIST_NEXT(node)) {
     38       CERTCertTrust trust = {0};
     39       if (CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), node->cert, &trust) !=
     40           SECSuccess) {
     41         LOG(ERROR) << "CERT_ChangeCertTrust failed: " << PORT_GetError();
     42       }
     43     }
     44     CERT_DestroyCertList(cert_list);
     45   }
     46 
     47   // Don't close when NSS is < 3.15.1, because it would require an additional
     48   // sleep for 1 second after closing the database, due to
     49   // http://bugzil.la/875601.
     50   if (!NSS_VersionCheck("3.15.1")) {
     51     LOG(ERROR) << "NSS version is < 3.15.1, test DB will not be closed.";
     52     temp_dir_.Take();
     53     return;
     54   }
     55 
     56   // NSS is allowed to do IO on the current thread since dispatching
     57   // to a dedicated thread would still have the affect of blocking
     58   // the current thread, due to NSS's internal locking requirements
     59   base::ThreadRestrictions::ScopedAllowIO allow_io;
     60 
     61   if (slot_) {
     62     SECStatus status = SECMOD_CloseUserDB(slot_.get());
     63     if (status != SECSuccess)
     64       PLOG(ERROR) << "SECMOD_CloseUserDB failed: " << PORT_GetError();
     65   }
     66 
     67   if (!temp_dir_.Delete())
     68     LOG(ERROR) << "Could not delete temporary directory.";
     69 }
     70 
     71 }  // namespace crypto
     72