00001
00009 #include "PKIFNSSCertUpdate.h"
00010
00011 #include "PKIFNSSDatabase.h"
00012 #include "ToolkitUtils.h"
00013 #include "components.h"
00014 #include "PKIFCacheErrors.h"
00015 #include "Buffer.h"
00016 #include "Certificate.h"
00017 #include "CRL.h"
00018 #include "Name.h"
00019 #include "GeneralName.h"
00020 #include "PKIFCacheException.h"
00021 #include "GottaMatch.h"
00022
00023 #include "PKIFNSSConfig.h"
00024
00025 #include <sstream>
00026 using namespace std;
00027
00029 struct PKIFNSSCertUpdateImpl
00030 {
00031 CERTCertDBHandle * m_certDbHandle;
00032 CPKIFNSSDatabase * m_db;
00033 };
00035
00036
00048 CPKIFNSSCertUpdate::CPKIFNSSCertUpdate(
00050 const std::string & dbdir)
00051 :m_impl(new PKIFNSSCertUpdateImpl)
00052 {
00053 LOG_STRING_DEBUG(__FUNCTION__,TOOLKIT_SR_NSSCERTUPDATE,0,this);
00054 m_impl->m_certDbHandle = 0;
00055 m_impl->m_db = 0;
00056
00057
00058 if(dbdir == "") {
00059 m_impl->m_db = CPKIFNSSDatabase::GetInstance();
00060 } else {
00061
00062
00063
00064 m_impl->m_db = CPKIFNSSDatabase::GetInstance(dbdir);
00065 }
00066 }
00074 CPKIFNSSCertUpdate::~CPKIFNSSCertUpdate(void)
00075 {
00076 LOG_STRING_DEBUG(__FUNCTION__,TOOLKIT_SR_NSSCERTUPDATE,0,this);
00077 PKIFDelete(m_impl);
00078 m_impl = 0;
00079 }
00097 void CPKIFNSSCertUpdate::AddCertificate(
00098
00099 CertType certType,
00100
00101 const CPKIFCertificatePtr& cert)
00102 {
00103 LOG_STRING_DEBUG(__FUNCTION__,TOOLKIT_SR_NSSCERTUPDATE,0,this);
00104 if(0 == m_impl->m_certDbHandle)
00105 {
00106 RAISE_CACHE_EXCEPTION("CPKIFNSSCertUpdate instance not initialized.", thisComponent, COMMON_NOT_INITIALIZED, this);
00107 }
00108
00109 SECItem siCert;
00110 siCert.type = siBuffer;
00111 CPKIFBufferPtr encoded = cert->Encoded();
00112 siCert.data = (unsigned char *)encoded->GetBuffer();
00113 siCert.len = encoded->GetLength();
00114
00115 CERTCertificate * nssCert = 0;
00116
00117
00118
00119 nssCert = CERT_FindCertByDERCert(m_impl->m_certDbHandle, &siCert);
00120 if(nssCert) {
00121 CERT_DestroyCertificate(nssCert);
00122 return;
00123 }
00124
00125 SECItem * encCerts[1];
00126 encCerts[0] = &siCert;
00127
00128 CERTCertTrust * trust = 0;
00129
00130 trust = (CERTCertTrust *)PORT_ZAlloc(sizeof(CERTCertTrust));
00131 if(!trust) {
00132 RAISE_CACHE_EXCEPTION("CPKIFNSSCertUpdate unable to allocate trust structure for NSS.", thisComponent, COMMON_MEMORY_ALLOC_FAILURE, this);
00133 }
00134
00135
00136 CERTCertificate ** certs = 0;
00137
00138
00139
00140 SECStatus rv = CERT_ImportCerts(CERT_GetDefaultCertDB(),certUsageUserCertImport,
00141 1,encCerts,&certs,PR_FALSE,PR_FALSE,NULL);
00142
00143 if(SECSuccess != rv) {
00144
00145 PORT_Free(trust);
00146 LOG_STRING_INFO("Unable to import Cert into NSS",TOOLKIT_SR_NSSCERTUPDATE,
00147 CACHE_UPDATE_FAILED,this);
00148 return;
00149 }
00150 nssCert = certs[0];
00151
00152 rv = CERT_DecodeTrustString(trust,"c,c,c");
00153 if(rv != SECSuccess) {
00154 CERT_DestroyCertificate(nssCert);
00155 PORT_Free(certs);
00156 PORT_Free(trust);
00157 RAISE_CACHE_EXCEPTION("CPKIFNSSCertUpdate unable to allocate trust structure for NSS.", thisComponent, COMMON_MEMORY_ALLOC_FAILURE, this);
00158 }
00159 PK11SlotInfo * internalslot = PK11_GetInternalKeySlot();
00160 if(!internalslot) {
00161 CERT_DestroyCertificate(nssCert);
00162 PORT_Free(certs);
00163 PORT_Free(trust);
00164 LOG_STRING_INFO("Unable to access NSS internal slot",TOOLKIT_SR_NSSCERTUPDATE,
00165 CACHE_UPDATE_FAILED,this);
00166 }
00167
00168
00169 rv = PK11_ImportCert(internalslot,nssCert,CK_INVALID_HANDLE,
00170 (char *)cert->Subject()->ToString(),PR_FALSE);
00171
00172 if(SECSuccess == rv) {
00173 rv = CERT_ChangeCertTrust(m_impl->m_certDbHandle,nssCert,trust);
00174 if(SECSuccess != rv) {
00175 LOG_STRING_INFO("Unable to set NSS cert trust",TOOLKIT_SR_NSSCERTUPDATE,
00176 CACHE_UPDATE_FAILED,this);
00177 }
00178 }
00179 PORT_Free(trust);
00180 CERT_DestroyCertificate(nssCert);
00181 PORT_Free(certs);
00182 PK11_FreeSlot(internalslot);
00183 }
00192 void CPKIFNSSCertUpdate::Initialize(void)
00193 {
00194 LOG_STRING_DEBUG(__FUNCTION__,TOOLKIT_SR_NSSCERTUPDATE,0,this);
00195 m_impl->m_certDbHandle = CERT_GetDefaultCertDB();
00196 }