CPKIFRevocationStatusMediator2.cpp

Go to the documentation of this file.
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     //CACMonitorDataPtr m_md;
00052     boost::recursive_mutex m_me;
00053 
00054     //Declare a vector to contain pointers to all colleagues associated with this instance.
00055     std::vector<IPKIFColleaguePtr> m_vModules;
00056 
00057     //Declare a vector to contain pointers to colleagues that should be deleted when this
00058     //instance is destroyed, i.e. those added by calling AddColleague with transferOwnership
00059     //equal to true.
00060     //std::vector<IPKIFColleague*> m_vModulesToDelete;
00061 
00062     std::vector<IPKIFRevocationStatusPtr> m_vRevocStatModules;
00063 
00064     bool m_addDefaultColleagues;
00065 };
00067 //added interface stuff 8/21/2004
00076 IPKIFRevocationStatus::IPKIFRevocationStatus()
00077 {
00078 }
00079 
00080 void CPKIFRevocationStatusMediator2::SetCacheCertStatus(bool bCacheCertStatus)
00081 {
00082     if(bCacheCertStatus && !m_impl->m_bCacheCertStatus)
00083     {
00084         //create a new cache object
00085         CPKIFCertStatusCachePtr tempCache(new CPKIFCertStatusCache);
00086         m_impl->m_certStatusCache = tempCache;
00087     }
00088     else if(!bCacheCertStatus)
00089     {
00090         //set cache to NULL
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     //CCACSynchronizedObject so(m_impl->m_md);
00156     boost::recursive_mutex::scoped_lock(m_impl->m_me);
00157     try
00158     {
00159         //inform our children that we are dying
00160         RemoveParentRelationships(m_impl->m_vModules, this);
00161 
00162         RemoveMediatorAssociations();
00163 
00164         //clean up any modules that were added using AddColleague
00165 //      FreeAdditionalModules(m_impl->m_vModulesToDelete, this);
00166 
00167         //added 7/17/2004
00168         IPKIFMediator::Terminate();
00169 
00170         m_impl->m_vModules.clear();
00171         m_impl->m_vRevocStatModules.clear();
00172     }
00173     catch(CPKIFException& )
00174     {
00175         //EXCEPTION DELETION
00176         //no purpose is served by passing on this exception - log it and forget it
00177         LOG_STRING_ERROR("CPKIFException encountered during CPKIFRevocationStatusMediator2 mediator termination", thisComponent, COMMON_TERMINATION_ERROR, this);
00178         //delete e;
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     //CCACSynchronizedObject so(m_impl->m_md);
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         // GCC doesn't see the result of the dynamic_pointer_cast as a reference when used
00239         // inside the function call
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     //CCACSynchronizedObject so(m_impl->m_md);
00265     boost::recursive_mutex::scoped_lock(m_impl->m_me);
00266     if(!module)
00267         return;
00268 
00269     //if the module throws an exception let the caller catch it
00270     module->Initialize();
00271     module->AddParent(this);
00272 
00273     try
00274     {
00275         //set up a vector containing pointers that we will need to delete
00276         //if(transferOwnership)
00277         //  m_impl->m_vModulesToDelete.push_back(module);
00278 
00279         //create a guard on the vector so if the push onto the primary vector fails we can
00280         //pop the one off of m_impl->m_vModulesToDelete
00281 //      ScopeGuard guard = MakeObjGuard(m_impl->m_vModulesToDelete, &vector<IPKIFColleague*>::pop_back);
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 //      guard.Dismiss();
00286     }
00287     catch(...)
00288     {
00289         throw;
00290     }
00291 }
00292 
00293 //GENERAL PHILOSOPHY OF FOLLOWING FUNCTIONS
00294 //  This mediator catches all exceptions that emanate from lower-level PKIF objects.  Exception
00295 //contents are recorded in the audit log but the exceptions are NOT throw to the application.  The
00296 //application will remain unaware of the exception.  This allows other colleagues an opportunity to
00297 //satisfy the request.  In the event that an unsatisfied request leaves results in the failure of
00298 //a higher level operation, the application will be notified of the higher level failure, possibly
00299 //by an exception.  If no colleague supports the requested operation an exception is thrown indicating
00300 //that the operation was not handled.
00301 //  The bools returned by the colleagues indicated whether or not revocation status could be determined
00302 //NOT whether or not the status of the cert or path.  This mediator iterates over colleagues until a 
00303 //colleague reports that a definitive answer was determined.
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     //CCACSynchronizedObject so(m_impl->m_md);
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     //iterate over all until someone returns a definitive answer
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                 //delete e;
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     //CCACSynchronizedObject so(m_impl->m_md);
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     //iterate over all until someone returns a definitive answer
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                 //delete e;
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 }

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