00001
00010 #include "CPKIFRevocationStatusMediator2.h"
00011 #include "ScopeGuard.h"
00012 #include "PKIFX509CRLChecker.h"
00013
00014 #include "boost/thread/recursive_mutex.hpp"
00015
00016 #include "ToolkitUtils.h"
00017 #include "PKIFPathException.h"
00018 #include "PKIFErrors.h"
00019 #include "PKIFLog.h"
00020 #include "CertStatusCache.h"
00021
00022 #ifdef _WIN32
00023 #ifdef _DEBUG
00024 #include "crtdbg.h"
00025 #endif //_DEBUG
00026 #endif //_WIN32
00027
00028 using namespace std;
00029 using namespace boost;
00030
00032 struct CPKIFRevocationStatusMediator2Impl
00033 {
00034 CPKIFCertStatusCachePtr m_certStatusCache;
00035 bool m_bCacheCertStatus;
00036
00044 CPKIFRevocationStatusMediator2Impl ():m_me()
00045 {
00046 m_bCacheCertStatus = true;
00047 CPKIFCertStatusCachePtr tempCache(new CPKIFCertStatusCache);
00048 m_certStatusCache = tempCache;
00049 }
00050
00051
00052 boost::recursive_mutex m_me;
00053
00054
00055 std::vector<IPKIFColleaguePtr> m_vModules;
00056
00057
00058
00059
00060
00061
00062 std::vector<IPKIFRevocationStatusPtr> m_vRevocStatModules;
00063
00064 bool m_addDefaultColleagues;
00065 };
00067
00076 IPKIFRevocationStatus::IPKIFRevocationStatus()
00077 {
00078 }
00079
00080 void CPKIFRevocationStatusMediator2::SetCacheCertStatus(bool bCacheCertStatus)
00081 {
00082 if(bCacheCertStatus && !m_impl->m_bCacheCertStatus)
00083 {
00084
00085 CPKIFCertStatusCachePtr tempCache(new CPKIFCertStatusCache);
00086 m_impl->m_certStatusCache = tempCache;
00087 }
00088 else if(!bCacheCertStatus)
00089 {
00090
00091 CPKIFCertStatusCachePtr tempCache;
00092 m_impl->m_certStatusCache = tempCache;
00093 }
00094
00095 m_impl->m_bCacheCertStatus = bCacheCertStatus;
00096 }
00097
00098 bool CPKIFRevocationStatusMediator2::GetCacheCertStatus() const
00099 {
00100 return m_impl->m_bCacheCertStatus;
00101 }
00102
00114 CPKIFRevocationStatusMediator2::CPKIFRevocationStatusMediator2(
00116 bool addDefaultColleagues)
00117 : m_impl(new CPKIFRevocationStatusMediator2Impl)
00118 {
00119 LOG_STRING_DEBUG("CPKIFRevocationStatusMediator2::CPKIFRevocationStatusMediator2(void)", TOOLKIT_PATH_MEDIATOR, 0, this);
00120
00121 m_impl->m_addDefaultColleagues = addDefaultColleagues;
00122 }
00131 CPKIFRevocationStatusMediator2::~CPKIFRevocationStatusMediator2(void)
00132 {
00133 LOG_STRING_DEBUG("CPKIFRevocationStatusMediator2::~CPKIFRevocationStatusMediator2(void)", TOOLKIT_PATH_MEDIATOR, 0, this);
00134
00135 Terminate();
00136
00137 delete m_impl;
00138 m_impl = '\0';
00139 }
00140
00151 void CPKIFRevocationStatusMediator2::Terminate()
00152 {
00153 LOG_STRING_DEBUG("CPKIFRevocationStatusMediator2::Terminate()", TOOLKIT_PATH_MEDIATOR, 0, this);
00154
00155
00156 boost::recursive_mutex::scoped_lock(m_impl->m_me);
00157 try
00158 {
00159
00160 RemoveParentRelationships(m_impl->m_vModules, this);
00161
00162 RemoveMediatorAssociations();
00163
00164
00165
00166
00167
00168 IPKIFMediator::Terminate();
00169
00170 m_impl->m_vModules.clear();
00171 m_impl->m_vRevocStatModules.clear();
00172 }
00173 catch(CPKIFException& )
00174 {
00175
00176
00177 LOG_STRING_ERROR("CPKIFException encountered during CPKIFRevocationStatusMediator2 mediator termination", thisComponent, COMMON_TERMINATION_ERROR, this);
00178
00179 _ASSERT(false);
00180 }
00181 catch(...)
00182 {
00183 LOG_STRING_FATAL("Unknown exception encountered during CPKIFRevocationStatusMediator2 mediator termination", thisComponent, COMMON_TERMINATION_ERROR, this);
00184 _ASSERT(false);
00185 }
00186 }
00187
00201 void CPKIFRevocationStatusMediator2::Initialize()
00202 {
00203 InitializeMediator(NULL);
00204 }
00223 void CPKIFRevocationStatusMediator2::InitializeMediator(
00225 std::vector<CPKIFException*>* errorInfo)
00226 {
00227 LOG_STRING_DEBUG("CPKIFRevocationStatusMediator2::Initialize", TOOLKIT_PATH_MEDIATOR, 0, this);
00228
00229
00230 boost::recursive_mutex::scoped_lock(m_impl->m_me);
00231 LOG_STRING_DEBUG("Initializing CPKIFRevocationStatusMediator2 mediator", thisComponent, 0, this);
00232 if(!m_impl->m_vModules.empty())
00233 throw CPKIFPathException(thisComponent, COMMON_ALREADY_INITIALIZED, "This instance has already been initialized. Call Terminate prior to re-initializing.");
00234
00235 if(m_impl->m_addDefaultColleagues)
00236 {
00237 CPKIFX509CRLCheckerPtr crlChecker(new CPKIFX509CRLChecker());
00238
00239
00240 IPKIFColleaguePtr cp = dynamic_pointer_cast<IPKIFColleague,CPKIFX509CRLChecker>(crlChecker);
00241 AddColleague(cp);
00242 }
00243 }
00244
00258 void CPKIFRevocationStatusMediator2::AddColleague(
00260 IPKIFColleaguePtr& module)
00261 {
00262 LOG_STRING_DEBUG("CPKIFRevocationStatusMediator2::AddColleague", TOOLKIT_PATH_MEDIATOR, 0, this);
00263
00264
00265 boost::recursive_mutex::scoped_lock(m_impl->m_me);
00266 if(!module)
00267 return;
00268
00269
00270 module->Initialize();
00271 module->AddParent(this);
00272
00273 try
00274 {
00275
00276
00277
00278
00279
00280
00281
00282 m_impl->m_vModules.push_back(module);
00283 if(dynamic_pointer_cast<IPKIFRevocationStatus, IPKIFColleague>(module))
00284 m_impl->m_vRevocStatModules.push_back(dynamic_pointer_cast<IPKIFRevocationStatus, IPKIFColleague>(module));
00285
00286 }
00287 catch(...)
00288 {
00289 throw;
00290 }
00291 }
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00314 bool CPKIFRevocationStatusMediator2::CheckStatus(
00317 const CPKIFCertificatePtr& cert,
00320 const CPKIFCertificatePtr& issuersCert,
00322 RevocationStatus& status,
00325 CPKIFCertStatusPtr& certStatus)
00326 {
00327 LOG_STRING_DEBUG("CPKIFRevocationStatusMediator2::CheckStatus", TOOLKIT_PATH_MEDIATOR, 0, this);
00328
00329
00330 boost::recursive_mutex::scoped_lock(m_impl->m_me);
00331 bool retVal = false;
00332 vector<IPKIFRevocationStatusPtr>::iterator pos;
00333 vector<IPKIFRevocationStatusPtr>::iterator end = m_impl->m_vRevocStatModules.end();
00334 bool opAttempted = false;
00335
00336 if(m_impl->m_bCacheCertStatus && m_impl->m_certStatusCache)
00337 {
00338 if(m_impl->m_certStatusCache->CheckStatus(cert, issuersCert, status, certStatus))
00339 return true;
00340 }
00341
00342
00343 for(pos = m_impl->m_vRevocStatModules.begin(); pos != end; ++pos)
00344 {
00345 opAttempted = true;
00346 try
00347 {
00348 bool b = (*pos)->CheckStatus(cert, issuersCert, status, certStatus);
00349 if(b)
00350 {
00351 if(m_impl->m_bCacheCertStatus && m_impl->m_certStatusCache)
00352 {
00353 m_impl->m_certStatusCache->PutObject(cert, issuersCert, status, certStatus);
00354 }
00355
00356 retVal = true;
00357 break;
00358 }
00359 }
00360 catch(CPKIFException& e)
00361 {
00362 std::string reason = "A revocation status check-related exception was thrown. ";
00363 reason.append(*e.print());
00364 AuditString(EVENTLOG_WARNING_TYPE, CAT_PKIF_PATH, PKIF_UNEXPECTED_EXCEPTION, reason.c_str(), thisComponent, COMMON_UNKNOWN_ERROR, this);
00365
00366 }
00367 }
00368
00369 if(!opAttempted)
00370 throw CPKIFPathException(thisComponent, COMMON_OPERATION_NOT_HANDLED);
00371
00372 return retVal;
00373 }
00374
00375
00387 bool CPKIFRevocationStatusMediator2::CheckStatusPath(
00390 CPKIFCertificatePath& path,
00393 RevocationStatus& status)
00394 {
00395 LOG_STRING_DEBUG("CPKIFRevocationStatusMediator2::CheckStatusPath", TOOLKIT_PATH_MEDIATOR, 0, this);
00396
00397
00398 boost::recursive_mutex::scoped_lock(m_impl->m_me);
00399 bool retVal = false;
00400 vector<IPKIFRevocationStatusPtr>::iterator pos;
00401 vector<IPKIFRevocationStatusPtr>::iterator end = m_impl->m_vRevocStatModules.end();
00402 bool opAttempted = false;
00403
00404 if(m_impl->m_bCacheCertStatus && m_impl->m_certStatusCache)
00405 {
00406 if(m_impl->m_certStatusCache->CheckStatusPath(path, status))
00407 return true;
00408 }
00409
00410
00411 for(pos = m_impl->m_vRevocStatModules.begin(); pos != end; ++pos)
00412 {
00413 opAttempted = true;
00414
00415 try
00416 {
00417 if((*pos)->CheckStatusPath(path, status))
00418 {
00419 retVal = true;
00420
00421 if(m_impl->m_bCacheCertStatus && m_impl->m_certStatusCache)
00422 {
00423 m_impl->m_certStatusCache->PutObjectsInPath(path);
00424 }
00425
00426 break;
00427 }
00428 }
00429 catch(CPKIFException& e)
00430 {
00431 std::string reason = "A revocation status check-related exception was thrown. ";
00432 reason.append(*e.print());
00433 AuditString(EVENTLOG_WARNING_TYPE, CAT_PKIF_PATH, PKIF_UNEXPECTED_EXCEPTION, reason.c_str(), thisComponent, COMMON_UNKNOWN_ERROR, this);
00434
00435 }
00436 }
00437
00438 if(!opAttempted)
00439 throw CPKIFPathException(thisComponent, COMMON_OPERATION_NOT_HANDLED);
00440
00441 return retVal;
00442 }
00450 void CPKIFRevocationStatusMediator2::GetColleagues(
00452 std::vector<IPKIFColleaguePtr>& v) const
00453 {
00454 copy(m_impl->m_vModules.begin(),m_impl->m_vModules.end(), back_inserter(v));
00455 }