PKIFNSSDatabase.cpp

Go to the documentation of this file.
00001 
00009 #include "PKIFNSSDatabase.h"
00010 #include "PKIFNSSHelper.h"
00011 
00012 #include "ToolkitUtils.h"
00013 #include "components.h"
00014 #include "PKIFCryptoException.h"
00015 #include "PKIFNSSErrors.h"
00016 
00017 #include "PKIFNSSConfig.h"
00018 #include "nspr.h"
00019 
00020 #include <sstream>
00021 
00022 CPKIFNSSDatabase * CPKIFNSSDatabase::m_instance = 0;
00023 static const int thisComponent = TOOLKIT_CRYPTO_NSS;
00024 
00032 CPKIFNSSDatabase::CPKIFNSSDatabase()
00033 {
00034 }
00035 
00044 CPKIFNSSDatabase * CPKIFNSSDatabase::GetInstance(void)
00045 {
00046     if(0 == m_instance) {
00047         m_instance = GetInstance("");
00048     }
00049     return m_instance;
00050 }
00051 
00052 
00063 CPKIFNSSDatabase * CPKIFNSSDatabase::GetInstance(const std::string & dbdir)
00064 {
00065     // if no instance exists, create one, initialize it, and return,
00066     // otherwise make sure it's the same as the db requested before returning;
00067     if(m_instance == 0) {
00068         m_instance = new CPKIFNSSDatabase();
00069         m_instance->Initialize(dbdir);
00070     } else if(m_instance->m_dbdir != dbdir) {
00071         std::ostringstream os;
00072         os << "CPKIFNSSDatabase is currently initialized ";
00073         if(m_instance->m_dbdir == "") {
00074             os << "without a database. ";
00075         } else {
00076             os << "with a database in " << m_instance->m_dbdir << ".";
00077         }
00078         if(dbdir == "") {
00079             os << " An instance with no database";
00080         } else {
00081             os << " An instance with a database in " << dbdir;
00082         }
00083         os << " was requested without shutting down the old one first.";
00084         RAISE_CRYPTO_EXCEPTION(os.str().c_str(), thisComponent, PKIFNSS_DB_ALREADY_INITED, NULL);
00085     }
00086     return m_instance;
00087 }
00088 
00098 void CPKIFNSSDatabase::Shutdown()
00099 {
00100     /* callers assume this to be safe and may call it even if nss was unavailable.
00101        just return if it isn't */
00102     if(!CPKIFNSSHelper::NSSAvaliable()) return;
00103     SECStatus rv = NSS_Shutdown();
00104     PKIFDelete(m_instance);
00105     m_instance = 0;
00106     if(SECSuccess != rv) {
00107         std::ostringstream os;
00108         os << "NSS Shutdown failed. That shouldn't happen: " << rv;
00109         RAISE_CRYPTO_EXCEPTION(os.str().c_str(), thisComponent, PKIFNSS_SHUTDOWN_FAILED, NULL);
00110     }
00111 }
00122 void CPKIFNSSDatabase::Initialize(
00124     const std::string & dbdir)
00125 {
00126     if(!CPKIFNSSHelper::NSSAvaliable()) {
00127         RAISE_CRYPTO_EXCEPTION("NSS could not be loaded.",thisComponent,PKIFNSS_INIT_FAILED,this);
00128     }
00129     m_dbdir = dbdir;
00130     if(m_dbdir == "") {
00131         // this should never fail if the NSS installation is healthy.
00132         SECStatus rv = NSS_NoDB_Init(NULL);
00133         if(SECSuccess != rv) {
00134             RAISE_CRYPTO_EXCEPTION("NSS could not be initialized without a database.", 
00135                 thisComponent, PKIFNSS_NODB_INIT_FAILED, this);
00136         }
00137     } else {
00138         SECStatus rv = NSS_InitReadWrite(m_dbdir.c_str());
00139         if(SECSuccess != rv) {
00140             std::ostringstream os;
00141             os << "NSS initialization failed for the database in " << m_dbdir << ": error " << rv;
00142             RAISE_CRYPTO_EXCEPTION(os.str().c_str(), 
00143                 thisComponent, PKIFNSS_INIT_FAILED, this);
00144         }
00145     }
00146 }
00154 std::string CPKIFNSSDatabase::GetDBDir(void)
00155 {
00156     return m_instance->m_dbdir;
00157 }
00158 
00159 
00167 bool CPKIFNSSDatabase::IsInitialized(void)
00168 {
00169     bool rv = false;
00170         
00171     if(NULL != m_instance)
00172         rv = true;
00173 
00174     return rv;
00175 }

Generated on Mon Nov 15 11:15:55 2010 for PublicKeyInfrastructureFramework(PKIF) by  doxygen 1.5.6