PKIFSynonymousSourceStore.cpp

Go to the documentation of this file.
00001 
00010 #include "PKIFSynonymousSourceStore.h"
00011 #include "PKIFCRLNodeEntry.h"
00012 #include "PKIFCertificateNodeEntry.h"
00013 #include "Name.h"
00014 #include "CRL.h"
00015 #include "Certificate.h"
00016 #include "CRLDistributionPoints.h"
00017 #include "CRLDistributionPoint.h"
00018 #include "DistributionPointName.h"
00019 #include "GottaMatch.h"
00020 #include "IssuingDistributionPoint.h"
00021 #include "Duration.h"
00022 #include "PKIFTime.h"
00023 #include "GeneralName.h"
00024 #include "ToolkitUtils.h"
00025 #include "PKIFCacheException.h"
00026 #include "PKIFCacheErrors.h"
00027 
00028 #include <map>
00029 #include <string>
00030 #include <vector>
00031 #include <iostream>
00032 #include <iterator>
00033 
00034 #include "boost/numeric/conversion/cast.hpp"
00035 
00036 using boost::numeric_cast;
00037 using boost::bad_numeric_cast;
00038 using namespace std;
00039 
00040 //#define _DEBUG_CACHE 1
00041 #ifdef _DEBUG_CACHE
00042 #include <fstream>
00043 #endif
00044 
00045 //#define _DEBUG_URI_DUMP 1
00046 #ifdef _DEBUG_URI_DUMP
00047 #include <fstream>
00048 ofstream g_cacheLogFile;
00049 #endif
00050 
00051 //----------------------------------------------------------------------------------------------------
00052 // Impl details
00053 //----------------------------------------------------------------------------------------------------
00055 
00063 template <class T>
00064 class GottaMatchCRLNodePair
00065 {
00066 public:
00074     bool operator()(std::pair<T, CPKIFCRLNodeEntryPtr> t);
00082     void SetRHS(const T& rhs) {m_rhs = rhs;}
00083 private:
00084     T m_rhs;
00085 };
00086 template <class T>
00094 bool GottaMatchCRLNodePair<T>::operator()(std::pair<T, CPKIFCRLNodeEntryPtr> t)
00095 {
00096     return *t.first == *m_rhs;      
00097 }
00099 
00104 class CPKIFSynonymousSourceStoreImpl
00105 {
00106 public:
00114     CPKIFSynonymousSourceStoreImpl()
00115     {
00116         m_lastClean = 0;
00117 #ifdef _DEBUG_CACHE
00118         m_maxTimeBetweenCleaning = 240000; //4 minute
00119 
00120         CPKIFDurationPtr tmp(new CPKIFDuration());
00121         tmp->setSeconds(480); //8 minutes
00122         m_maxAge = tmp;
00123 #else
00124         m_maxTimeBetweenCleaning = 3600000; //one hour
00125 
00126         CPKIFDurationPtr tmp(new CPKIFDuration());
00127         tmp->setDays(1);
00128         m_maxAge = tmp;
00129 #endif
00130     }
00131 
00132     //Functions related to nodes in PAS_PENDING state
00133     void AddPendingCrl(CPKIFCRLNodeEntryPtr& crl);
00134     void AddPendingCert(CPKIFCertificateNodeEntryPtr& cert);
00135 
00136     //Functions to add CRLs to the store
00137     void AddUriEntry(std::string& uri, CPKIFCRLNodeEntryPtr& crlNode);
00138     CPKIFCRLNodeEntryPtr AddDPEntry(std::string& uri, CPKIFCRLNodeEntryPtr& crlNode);
00139     CPKIFCRLNodeEntryPtr AddIssuerNameEntry(std::string& uri, CPKIFCRLNodeEntryPtr& crlNode);
00140 
00141     //Functions to add CRLs to the store
00142     void AddUriEntry(std::string& uri, CPKIFCertificateNodeEntryPtr& crlNode);
00143 
00144     //Functions to retrieve CRLs from the store
00145     CPKIFCRLNodeEntryPtr GetCachedCrlByIssuerOrDp(const CPKIFCertificatePtr& cert);
00146     CPKIFCRLNodeEntryPtr GetCachedCrlByIssuer(const CPKIFNamePtr& issuerName);
00147     CPKIFCRLNodeEntryPtr GetCachedCrlByDp(const CPKIFDistributionPointNamePtr& dp);
00148     CPKIFCRLNodeEntryPtr GetCachedCrlByUri(const std::string& uri);
00149 
00150     //Functions to retrieve certs from the store
00151     void GetCachedCertByUri(const std::string& uri, CPKIFCertificateNodeList& nodeList);
00152 
00153     //Debugging functions to output a textual listing store contents
00154     void WriteCacheContentsToConsole(std::ostream& out);
00155     void CleanIfNecessary();
00156 
00157 private:
00158     //the primary index is URI, since this is driven by the GetCRLSources interface
00159     std::map<std::string, CPKIFCRLNodeEntryPtr> m_crlMap;
00160     std::map<std::string, std::vector<CPKIFCertificateNodeEntryPtr> > m_certMap;
00161 
00162     std::vector<std::string> m_unavailableUris;
00163 
00164     //secondary indices are also maintained for CRLs over issuerDN and distribution point
00165     //the issuer name map is only used to store full CRLs
00166     std::map<CPKIFNamePtr, CPKIFCRLNodeEntryPtr> m_crlMapIssuerName;
00167     std::map<CPKIFDistributionPointNamePtr, CPKIFCRLNodeEntryPtr> m_crlMapDP;
00168 
00169     //safe keeping for pending nodes
00170     std::vector<CPKIFCRLNodeEntryPtr> m_pendingCRLs;
00171     std::vector<CPKIFCertificateNodeEntryPtr> m_pendingCerts;
00172 
00173     unsigned long m_lastClean;
00174     unsigned long m_maxTimeBetweenCleaning;
00175     CPKIFDurationPtr m_maxAge;
00176 };
00182 class IsOldCacheEntry
00183 {
00184 public:
00185     bool operator()(const std::pair<std::string, CPKIFCRLNodeEntryPtr>& t);
00186     bool operator()(const CPKIFCertificateNodeEntryPtr& t);
00187     void SetTimeOfInterest(CPKIFTimePtr& toi) {m_toi = toi;}
00188 private:
00189     CPKIFTimePtr m_toi;
00190 };
00198 bool IsOldCacheEntry::operator()(const std::pair<std::string, CPKIFCRLNodeEntryPtr>& t)
00199 {
00200     CPKIFTimePtr retrievalTime = t.second->GetLatestRetrievalTime();
00201     return *m_toi > *retrievalTime;
00202 }
00210 bool IsOldCacheEntry::operator()(const CPKIFCertificateNodeEntryPtr& t)
00211 {
00212     CPKIFTimePtr retrievalTime = t->GetLatestRetrievalTime();
00213     return *m_toi > *retrievalTime;
00214 }
00220 class IsCertCacheEntryEmpty
00221 {
00222 public:
00223     bool operator()(const std::pair<std::string, std::vector<CPKIFCertificateNodeEntryPtr> >& t);
00224 };
00225 
00226 bool IsCertCacheEntryEmpty::operator()(const std::pair<std::string, std::vector<CPKIFCertificateNodeEntryPtr> >& t)
00227 {
00228     return t.second.empty();
00229 }
00237 void CPKIFSynonymousSourceStoreImpl::CleanIfNecessary()
00238 {
00239     if(0 == m_lastClean)
00240     {
00241         m_lastClean = GetTickCount();
00242         return;
00243     }
00244 
00245     unsigned long curTicks = GetTickCount();
00246     if((curTicks - m_lastClean) > m_maxTimeBetweenCleaning)
00247     {
00248 #ifdef _DEBUG_CACHE
00249     CPKIFTimePtr t1 = CPKIFTime::CurrentTime();
00250     ofstream f1;
00251     std::string s1 = t1->GetTime();
00252     s1.append("preClean.txt");
00253     f1.open(s1.c_str(), ios::out);
00254     WriteCacheContentsToConsole(f1);
00255     f1.close();
00256 #endif
00257 
00258         m_lastClean = curTicks;
00259         CPKIFTimePtr timeOfInterest = CPKIFTime::CurrentTime();
00260         *timeOfInterest -= *m_maxAge;
00261 
00262         IsOldCacheEntry ioce;
00263         ioce.SetTimeOfInterest(timeOfInterest);
00264 
00265         std::map<std::string, std::vector<CPKIFCertificateNodeEntryPtr> >::iterator certPos;
00266         std::map<std::string, std::vector<CPKIFCertificateNodeEntryPtr> >::iterator certEnd = m_certMap.end();
00267         for(certPos = m_certMap.begin(); certPos != certEnd; )
00268         {
00269             std::vector<CPKIFCertificateNodeEntryPtr>::iterator newEnd = 
00270                 remove_if((*certPos).second.begin(), (*certPos).second.end(), ioce);
00271             (*certPos).second.erase(newEnd, (*certPos).second.end());
00272 
00273             if((*certPos).second.empty())
00274             {
00275                 m_certMap.erase(certPos++);
00276             }
00277             else
00278             {
00279                 ++certPos;
00280             }
00281         }
00282 
00283         std::map<std::string, CPKIFCRLNodeEntryPtr>::iterator crlPos;
00284         std::map<std::string, CPKIFCRLNodeEntryPtr>::iterator crlEnd = m_crlMap.end();
00285         for(crlPos = m_crlMap.begin(); crlPos != crlEnd; )
00286         {
00287             if(timeOfInterest < (*crlPos).second->GetLatestRetrievalTime())
00288             {
00289                 CPKIFCRLPtr crl = (*crlPos).second->GetCRL();
00290                 CPKIFNamePtr issuerName = crl->Issuer();
00291 
00292                 m_crlMapIssuerName.erase(issuerName);
00293 
00294                 CPKIFIssuingDistributionPointPtr idp = crl->GetExtension<CPKIFIssuingDistributionPoint>();
00295                 if(idp != (CPKIFIssuingDistributionPoint*)NULL)
00296                 {
00297                     GottaMatchCRLNodePair<CPKIFDistributionPointNamePtr> gm;
00298                     CPKIFDistributionPointNamePtr dp = idp->DistributionPoint();
00299                     if(dp != (CPKIFDistributionPointName*)NULL)
00300                     {
00301                         m_crlMapDP.erase(dp);
00302                     }
00303                 }
00304 
00305                 m_crlMap.erase(crlPos++);
00306             }
00307             else
00308             {
00309                 ++crlPos;
00310             }
00311         }
00312 #ifdef _DEBUG_CACHE
00313     CPKIFTimePtr t2 = CPKIFTime::CurrentTime();
00314     ofstream f2;
00315     std::string s2 = t2->GetTime();
00316     s2.append("postClean.txt");
00317     f2.open(s2.c_str(), ios::out);
00318     WriteCacheContentsToConsole(f2);
00319     f2.close();
00320 #endif
00321     }
00322 }
00323 
00331 void CPKIFSynonymousSourceStoreImpl::AddPendingCrl(
00333     CPKIFCRLNodeEntryPtr& crl)
00334 {
00335     m_pendingCRLs.push_back(crl);
00336 }
00344 void CPKIFSynonymousSourceStoreImpl::AddPendingCert(
00346     CPKIFCertificateNodeEntryPtr& cert)
00347 {
00348     m_pendingCerts.push_back(cert);
00349 }
00357 void CPKIFSynonymousSourceStoreImpl::WriteCacheContentsToConsole(
00359     std::ostream& out)
00360 {
00361     out << "Listing CRLs..." << endl;
00362     int index = 0;
00363     std::map<std::string, CPKIFCRLNodeEntryPtr>::iterator pos;
00364     std::map<std::string, CPKIFCRLNodeEntryPtr>::iterator end = m_crlMap.end();
00365     for(pos = m_crlMap.begin(); pos != end; ++pos, ++index)
00366     {
00367         out << "Node[" << index << "]: " << (*pos).first << endl;
00368         if((*pos).second != (CPKIFCRLNodeEntry*)NULL)
00369         {
00370             switch((*pos).second->GetState())
00371             {
00372             case PAS_PENDING:
00373                 out << "State: PAS_PENDING" << endl;
00374                 break;
00375             case PAS_AVAILABLE:
00376                 out << "State: PAS_AVAILABLE" << endl;
00377                 out << "CRL issued by: " << (*pos).second->GetCRL()->Issuer()->ToString() << endl;
00378                 break;
00379             case PAS_UNAVAILABLE:
00380                 out << "State: PAS_UNAVAILABLE" << endl;
00381                 break;
00382             }
00383 
00384             vector<string> sources;
00385             (*pos).second->GetSources(sources);
00386 
00387             int sourceIndex = 0;
00388             vector<string>::iterator sourcePos;
00389             vector<string>::iterator sourceEnd = sources.end();
00390             for(sourcePos = sources.begin(); sourcePos != sourceEnd; ++sourcePos, ++sourceIndex)
00391             {
00392                 out << "Source[" << sourceIndex << "]: " << (*sourcePos) << endl;
00393             }
00394         }
00395         out << endl;
00396     }
00397 
00398     out << "Listing CRLs from issuer map..." << endl;
00399     index = 0;
00400     std::map<CPKIFNamePtr, CPKIFCRLNodeEntryPtr>::iterator ipos;
00401     std::map<CPKIFNamePtr, CPKIFCRLNodeEntryPtr>::iterator iend = m_crlMapIssuerName.end();
00402     for(ipos = m_crlMapIssuerName.begin(); ipos != iend; ++ipos, ++index)
00403     {
00404         out << "Node[" << index << "]: " << (*ipos).first->ToString() << endl;
00405         if((*ipos).second != (CPKIFCRLNodeEntry*)NULL)
00406         {
00407             switch((*ipos).second->GetState())
00408             {
00409             case PAS_PENDING:
00410                 out << "State: PAS_PENDING" << endl;
00411                 break;
00412             case PAS_AVAILABLE:
00413                 out << "State: PAS_AVAILABLE" << endl;
00414                 out << "CRL issued by: " << (*ipos).second->GetCRL()->Issuer()->ToString() << endl;
00415                 break;
00416             case PAS_UNAVAILABLE:
00417                 out << "State: PAS_UNAVAILABLE" << endl;
00418                 break;
00419             }
00420 
00421             vector<string> sources;
00422             (*ipos).second->GetSources(sources);
00423 
00424             int sourceIndex = 0;
00425             vector<string>::iterator sourcePos;
00426             vector<string>::iterator sourceEnd = sources.end();
00427             for(sourcePos = sources.begin(); sourcePos != sourceEnd; ++sourcePos, ++sourceIndex)
00428             {
00429                 out << "Source[" << sourceIndex << "]: " << (*sourcePos) << endl;
00430             }
00431         }
00432         out << endl;
00433     }
00434 
00435     out << "Listing CRLs from DP map..." << endl;
00436     index = 0;
00437     std::map<CPKIFDistributionPointNamePtr, CPKIFCRLNodeEntryPtr>::iterator dppos;
00438     std::map<CPKIFDistributionPointNamePtr, CPKIFCRLNodeEntryPtr>::iterator dpend = m_crlMapDP.end();
00439     for(dppos = m_crlMapDP.begin(); dppos != dpend; ++dppos, ++index)
00440     {
00441         std::string dpName;
00442         CPKIFDistributionPointNamePtr dp = (*dppos).first;
00443         if(!dp->NameRelativeToIssuerPresent())
00444         {
00445             CPKIFGeneralNameList gns;
00446             dp->FullName(gns);
00447 
00448             CPKIFGeneralNameList::iterator gnPos;
00449             CPKIFGeneralNameList::iterator gnEnd = gns.end();
00450             for(gnPos = gns.begin(); gnPos != gnEnd; ++gnPos)
00451             {
00452                 switch((*gnPos)->GetType())
00453                 {
00454                 case CPKIFGeneralName::OTHERNAME:
00455                     break;
00456                 case CPKIFGeneralName::RFC822:
00457                     dpName = (*gnPos)->rfc822Name();
00458                     break;
00459                 case CPKIFGeneralName::DNSNAME:
00460                     dpName = (*gnPos)->dnsName();
00461                     break;
00462                 case CPKIFGeneralName::X400ADDRESS:
00463                     break;
00464                 case CPKIFGeneralName::DIRECTORYNAME:
00465                     {
00466                     CPKIFNamePtr dpDN = (*gnPos)->directoryName();
00467                     if(dpDN)
00468                         dpName = dpDN->ToString();
00469                     }
00470                     break;
00471                 case CPKIFGeneralName::EDIPARTYNAME:
00472                     break;
00473                 case CPKIFGeneralName::URI:
00474                     dpName = (*gnPos)->uri();
00475                     break;
00476                 case CPKIFGeneralName::IPADDRESS:
00477                     break;
00478                 case CPKIFGeneralName::OID:
00479                     break;
00480                 }
00481 
00482                 //don't worry about each DP - just output one and move on
00483                 if(!dpName.empty())
00484                     break;
00485             }
00486 
00487         }
00488         else
00489         {
00490             CPKIFCRLPtr c = (*dppos).second->GetCRL();
00491             if(c)
00492             {
00493                 CPKIFNamePtr tmpIssuer = c->Issuer();
00494                 CPKIFNamePtr n = dp->GetRelativeNameAsFullName(tmpIssuer);
00495                 if(n)
00496                 {
00497                     dpName = n->ToString();
00498                 }
00499             }
00500         }
00501 
00502         if(dpName.empty())
00503             dpName = "Undetermined DP value";
00504 
00505         out << "Node[" << index << "]: " << dpName.c_str() << endl;
00506         if((*dppos).second != (CPKIFCRLNodeEntry*)NULL)
00507         {
00508             switch((*dppos).second->GetState())
00509             {
00510             case PAS_PENDING:
00511                 out << "State: PAS_PENDING" << endl;
00512                 break;
00513             case PAS_AVAILABLE:
00514                 out << "State: PAS_AVAILABLE" << endl;
00515                 out << "CRL issued by: " << (*dppos).second->GetCRL()->Issuer()->ToString() << endl;
00516                 break;
00517             case PAS_UNAVAILABLE:
00518                 out << "State: PAS_UNAVAILABLE" << endl;
00519                 break;
00520             }
00521 
00522             vector<string> sources;
00523             (*dppos).second->GetSources(sources);
00524 
00525             int sourceIndex = 0;
00526             vector<string>::iterator sourcePos;
00527             vector<string>::iterator sourceEnd = sources.end();
00528             for(sourcePos = sources.begin(); sourcePos != sourceEnd; ++sourcePos, ++sourceIndex)
00529             {
00530                 out << "Source[" << sourceIndex << "]: " << (*sourcePos) << endl;
00531             }
00532         }
00533         out << endl;
00534     }
00535 
00536     out << "Listing Certs..." << endl;
00537     index = 0;
00538     std::map<std::string, std::vector<CPKIFCertificateNodeEntryPtr> >::iterator certPos;
00539     std::map<std::string, std::vector<CPKIFCertificateNodeEntryPtr> >::iterator certEnd = m_certMap.end();
00540     for(certPos = m_certMap.begin(); certPos != certEnd; ++certPos, ++index)
00541     {
00542         out << "Node[" << index << "]: " << (*certPos).first << endl;
00543         if(!(*certPos).second.empty())
00544         {
00545             std::vector<CPKIFCertificateNodeEntryPtr>::iterator certNodePos;
00546             std::vector<CPKIFCertificateNodeEntryPtr>::iterator certNodeEnd = (*certPos).second.end();
00547             for(certNodePos = (*certPos).second.begin(); certNodePos != certNodeEnd; ++certNodePos)
00548             {
00549                 switch((*certNodePos)->GetState())
00550                 {
00551                 case PAS_PENDING:
00552                     out << "State: PAS_PENDING" << endl;
00553                     break;
00554                 case PAS_AVAILABLE:
00555                     out << "State: PAS_AVAILABLE" << endl;
00556                     out << "Cert issued by: " << (*certNodePos)->GetCert()->Issuer()->ToString() << endl;
00557                     out << "Cert issued to: " << (*certNodePos)->GetCert()->Subject()->ToString() << endl;
00558                     break;
00559                 case PAS_UNAVAILABLE:
00560                     out << "State: PAS_UNAVAILABLE" << endl;
00561                     break;
00562                 }
00563 
00564                 vector<string> sources;
00565                 (*certNodePos)->GetSources(sources);
00566 
00567                 int sourceIndex = 0;
00568                 vector<string>::iterator sourcePos;
00569                 vector<string>::iterator sourceEnd = sources.end();
00570                 for(sourcePos = sources.begin(); sourcePos != sourceEnd; ++sourcePos, ++sourceIndex)
00571                 {
00572                     out << "Source[" << sourceIndex << "]: " << (*sourcePos) << endl;
00573                 }
00574             }
00575         }
00576         out << endl;
00577     }
00578 }
00586 void CPKIFSynonymousSourceStoreImpl::GetCachedCertByUri(
00588     const std::string& uri,
00589     CPKIFCertificateNodeList& certNodeList)
00590 {
00591 #ifdef _DEBUG_URI_DUMP
00592     if(!g_cacheLogFile.is_open())
00593     {
00594         g_cacheLogFile.open("_DEBUG_URI_DUMP_CacheLog.txt", ios::out);
00595     }
00596 #endif
00597     if(m_certMap.count(uri))
00598     {
00599 #ifdef _DEBUG_URI_DUMP
00600     g_cacheLogFile << "CACHE HIT - " << uri << endl;
00601 #endif
00602 
00603         GottaMatch<CPKIFCertificateNodeEntryPtr> gm;
00604 
00605         std::vector<CPKIFCertificateNodeEntryPtr>::iterator pos;
00606         std::vector<CPKIFCertificateNodeEntryPtr>::iterator end = m_certMap[uri].end();
00607         for(pos = m_certMap[uri].begin(); pos != end; ++pos)
00608         {
00609             gm.SetRHS(*pos);
00610             if(certNodeList.end() == find_if(certNodeList.begin(), certNodeList.end(), gm))
00611             {
00612                 if(PAS_AVAILABLE == (*pos)->GetState())
00613                 {
00614                     CPKIFCertificateNodeEntryPtr newEntry(new CPKIFCertificateNodeEntry);
00615                     CPKIFCertificatePtr certFromList = (*pos)->GetCert();
00616                     newEntry->SetCert(certFromList);
00617                     newEntry->SetSource((*pos)->GetSource());
00618                     certNodeList.push_back(newEntry);
00619                 }
00620                 else
00621                 {
00622                     //no need to copy if not available
00623                     certNodeList.push_back(*pos);
00624                 }
00625             }
00626         }
00627     }
00628     else
00629     {
00630 #ifdef _DEBUG_URI_DUMP
00631     g_cacheLogFile << "CACHE MISS - " << uri << endl;
00632 #endif
00633     }
00634 }
00642 CPKIFCRLNodeEntryPtr CPKIFSynonymousSourceStoreImpl::GetCachedCrlByUri(
00644     const std::string& uri)
00645 {
00646 #ifdef _DEBUG_URI_DUMP
00647     if(!g_cacheLogFile.is_open())
00648     {
00649         g_cacheLogFile.open("_DEBUG_URI_DUMP_CacheLog.txt", ios::out);
00650     }
00651 #endif
00652 
00653     if(m_crlMap.count(uri))
00654     {
00655 #ifdef _DEBUG_URI_DUMP
00656     g_cacheLogFile << "CACHE HIT - " << uri << endl;
00657 #endif
00658         return m_crlMap[uri];
00659     }
00660     else
00661     {
00662 #ifdef _DEBUG_URI_DUMP
00663     g_cacheLogFile << "CACHE MISS - " << uri << endl;
00664 #endif
00665         CPKIFCRLNodeEntryPtr empty;
00666         return empty;
00667     }
00668 }
00676 CPKIFCRLNodeEntryPtr CPKIFSynonymousSourceStoreImpl::GetCachedCrlByIssuer(
00678     const CPKIFNamePtr& issuerName)
00679 {
00680     CPKIFCRLNodeEntryPtr cachedEntry;
00681 
00682     if(issuerName == (CPKIFName*)NULL)
00683         return cachedEntry;
00684 
00685     GottaMatchCRLNodePair<CPKIFNamePtr> gm;
00686     gm.SetRHS(issuerName);
00687 
00688     std::map<CPKIFNamePtr, CPKIFCRLNodeEntryPtr>::iterator end = m_crlMapIssuerName.end();
00689     std::map<CPKIFNamePtr, CPKIFCRLNodeEntryPtr>::iterator match = find_if(m_crlMapIssuerName.begin(), m_crlMapIssuerName.end(), gm);
00690 
00691     if(end != match)
00692         return (*match).second;
00693     else
00694         return cachedEntry;
00695 }
00703 CPKIFCRLNodeEntryPtr CPKIFSynonymousSourceStoreImpl::GetCachedCrlByDp(
00705     const CPKIFDistributionPointNamePtr& dp)
00706 {
00707     CPKIFCRLNodeEntryPtr cachedEntry;
00708 
00709     if(dp == (CPKIFDistributionPointName*)NULL)
00710         return cachedEntry;
00711 
00712     GottaMatchCRLNodePair<CPKIFDistributionPointNamePtr> gm;
00713     gm.SetRHS(dp);
00714 
00715     std::map<CPKIFDistributionPointNamePtr, CPKIFCRLNodeEntryPtr>::iterator end = m_crlMapDP.end();
00716     std::map<CPKIFDistributionPointNamePtr, CPKIFCRLNodeEntryPtr>::iterator match = find_if(m_crlMapDP.begin(), m_crlMapDP.end(), gm);
00717 
00718     if(end != match)
00719         return (*match).second;
00720     else
00721         return cachedEntry;
00722 }
00730 CPKIFCRLNodeEntryPtr CPKIFSynonymousSourceStoreImpl::GetCachedCrlByIssuerOrDp(
00732     const CPKIFCertificatePtr& cert)
00733 {
00734     CPKIFCRLNodeEntryPtr cachedEntry;
00735 
00736     if(cert == (CPKIFCertificate*)NULL)
00737         return cachedEntry;
00738 
00739     //look for DP CRLs first, since these may be smaller
00740     CPKIFCRLDistributionPointsPtr crlDPs = cert->GetExtension<CPKIFCRLDistributionPoints>();
00741     if(crlDPs != (CPKIFCRLDistributionPoints*)NULL)
00742     {
00743         CPKIFCRLDistributionPointListPtr dps = crlDPs->DPs();
00744 
00745         CPKIFCRLDistributionPointList::iterator pos;
00746         CPKIFCRLDistributionPointList::iterator end = dps->end();
00747         for(pos = dps->begin(); pos != end; ++pos)
00748         {
00749             cachedEntry = GetCachedCrlByDp((*pos)->DistributionPoint());
00750             if(cachedEntry != (CPKIFCRLNodeEntry*)NULL)
00751                 return cachedEntry;
00752         }
00753     }
00754 
00755     //then look for a full CRL if no DP CRL is found
00756     CPKIFNamePtr issuerName = cert->Issuer();
00757     cachedEntry = GetCachedCrlByIssuer(issuerName);
00758     if(cachedEntry != (CPKIFCRLNodeEntry*)NULL)
00759         return cachedEntry;
00760 
00761     return cachedEntry;
00762 }
00770 void CPKIFSynonymousSourceStoreImpl::AddUriEntry(
00772     std::string& uri, 
00774     CPKIFCertificateNodeEntryPtr& certNode)
00775 {
00776     if(0 == m_certMap.count(uri))
00777         m_certMap[uri].push_back(certNode);
00778     else
00779     {
00780         if(PAS_AVAILABLE == certNode->GetState())
00781         {
00782             GottaMatch<CPKIFCertificateNodeEntryPtr> gm;
00783             gm.SetRHS(certNode);
00784             if(m_certMap[uri].end() == find_if(m_certMap[uri].begin(), m_certMap[uri].end(), gm))
00785                 m_certMap[uri].push_back(certNode);
00786         }
00787     }
00788 }
00789 
00798 void CPKIFSynonymousSourceStoreImpl::AddUriEntry(
00800     std::string& uri,
00802     CPKIFCRLNodeEntryPtr& crlNode)
00803 {
00804     CPKIFCRLNodeEntryPtr cachedEntry = AddDPEntry(uri, crlNode);
00805     if(cachedEntry != (CPKIFCRLNodeEntry*)NULL)
00806         crlNode = cachedEntry;
00807 
00808     cachedEntry = AddIssuerNameEntry(uri, crlNode);
00809     if(cachedEntry != (CPKIFCRLNodeEntry*)NULL)
00810         crlNode = cachedEntry;
00811 
00812     m_crlMap[uri] = crlNode;
00813 }
00814 
00822 CPKIFCRLNodeEntryPtr CPKIFSynonymousSourceStoreImpl::AddDPEntry(
00824     std::string& uri,
00826     CPKIFCRLNodeEntryPtr& crlNode)
00827 {
00828     CPKIFCRLNodeEntryPtr cachedEntry;
00829     if(PAS_AVAILABLE == crlNode->GetState())
00830     {
00831         CPKIFCRLPtr crl = crlNode->GetCRL();
00832 
00833         CPKIFIssuingDistributionPointPtr idp = crl->GetExtension<CPKIFIssuingDistributionPoint>();
00834         if(idp != (CPKIFIssuingDistributionPoint*)NULL)
00835         {
00836             GottaMatchCRLNodePair<CPKIFDistributionPointNamePtr> gm;
00837             CPKIFDistributionPointNamePtr dp = idp->DistributionPoint();
00838             if(dp != (CPKIFDistributionPointName*)NULL)
00839             {
00840                 gm.SetRHS(dp);
00841 
00842                 std::map<CPKIFDistributionPointNamePtr, CPKIFCRLNodeEntryPtr>::iterator end = m_crlMapDP.end();
00843                 std::map<CPKIFDistributionPointNamePtr, CPKIFCRLNodeEntryPtr>::iterator match = find_if(m_crlMapDP.begin(), m_crlMapDP.end(), gm);
00844 
00845                 if(end != match)
00846                 {
00847                     (*match).second->AddSource(uri);
00848                     return (*match).second;
00849                 }
00850                 else
00851                 {
00852                     m_crlMapDP[dp] = crlNode;
00853                     return cachedEntry;
00854                 }
00855             }
00856         }
00857     }
00858 
00859     return cachedEntry;
00860 }
00862 
00869 CPKIFCRLNodeEntryPtr CPKIFSynonymousSourceStoreImpl::AddIssuerNameEntry(
00871     std::string& uri, 
00873     CPKIFCRLNodeEntryPtr& crlNode)
00874 {
00875     CPKIFCRLNodeEntryPtr emptyNode;
00876     if(PAS_AVAILABLE == crlNode->GetState())
00877     {
00878         CPKIFCRLPtr crl = crlNode->GetCRL();
00879 
00880         //if it is not a full CRL, then drop it (it'll be in the DP index)
00881         CPKIFIssuingDistributionPointPtr idp = crl->GetExtension<CPKIFIssuingDistributionPoint>();
00882         if(idp != (CPKIFIssuingDistributionPoint*)NULL)
00883             return emptyNode;
00884 
00885         CPKIFNamePtr issuerName = crl->Issuer();
00886         GottaMatchCRLNodePair<CPKIFNamePtr> gm;
00887         gm.SetRHS(issuerName);
00888 
00889         std::map<CPKIFNamePtr, CPKIFCRLNodeEntryPtr>::iterator end = m_crlMapIssuerName.end();
00890         std::map<CPKIFNamePtr, CPKIFCRLNodeEntryPtr>::iterator match = find_if(m_crlMapIssuerName.begin(), m_crlMapIssuerName.end(), gm);
00891 
00892         if(end != match)
00893         {
00894             //we found a node in the cache, return it so the new node falls out of use and dies
00895             (*match).second->AddSource(uri);
00896             return (*match).second;
00897         }
00898         else
00899         {
00900             m_crlMapIssuerName[issuerName] = crlNode;
00901             return emptyNode;
00902         }
00903     }
00904 
00905     return emptyNode;
00906 }
00908 
00909 //----------------------------------------------------------------------------------------------------
00910 // Class details
00911 //----------------------------------------------------------------------------------------------------
00919 CPKIFSynonymousSourceStore::CPKIFSynonymousSourceStore(void) : m_impl(new CPKIFSynonymousSourceStoreImpl)
00920 {
00921 }
00922 
00930 CPKIFSynonymousSourceStore::~CPKIFSynonymousSourceStore(void)
00931 {
00932     if(m_impl) delete m_impl;
00933 }
00934 
00942 void CPKIFSynonymousSourceStore::Initialize()
00943 {
00944     //There's nothing to do here for now, but future serialization efforts may utilize this function.
00945 }
00946 
00961 void CPKIFSynonymousSourceStore::GetCRLs(
00962     const CPKIFCertificatePtr& cert, 
00963     CPKIFCrlSourceList& crlSourceList, 
00964     CPKIFCRLNodeList& crlNodeList)
00965 {
00966     m_impl->CleanIfNecessary();
00967 
00968     CPKIFCRLNodeList rv;
00969 
00970     //First, iterate over the nodes in the inbound node list and see if we can fulfill any
00971     //pending nodes (while adding any new nodes to the store)
00972     CPKIFCrlSourceList::iterator pos;
00973     CPKIFCrlSourceList::iterator end = crlSourceList.end();
00974     for(pos = crlSourceList.begin(); pos != end; ++pos)
00975     {
00976         //get the list of sources from the node
00977         vector<string> sources;
00978         (*pos)->GetSources(sources);
00979 
00980         vector<string>::iterator sourcePos;
00981         vector<string>::iterator sourceEnd = sources.end();
00982         for(sourcePos = sources.begin(); sourcePos != sourceEnd; ++sourcePos)
00983         {
00984             //for each source, see if it's in the cache
00985             CPKIFCRLNodeEntryPtr cachedEntry = m_impl->GetCachedCrlByUri(*sourcePos);
00986             if(cachedEntry != (CPKIFCRLNodeEntry*)NULL)
00987             {
00988 /*              //if it is and the inbound node is not available but the cached node is, then update the inbound node
00989                 if(PAS_PENDING == (*pos)->GetState() && PAS_AVAILABLE == cachedEntry->GetState())
00990                 {
00991                     (*pos)->SetCRL(cachedEntry->GetCRL());
00992                     (*pos)->SetState(PAS_AVAILABLE);
00993                 }
00994                 else if(PAS_PENDING == (*pos)->GetState() && PAS_UNAVAILABLE == cachedEntry->GetState())
00995                 {
00996                     (*pos)->SetState(PAS_UNAVAILABLE);
00997                 }*/
00998 
00999                 GottaMatch<CPKIFCRLNodeEntryPtr> gm;
01000                 gm.SetRHS(cachedEntry);
01001                 if(rv.end() == find_if(rv.begin(), rv.end(), gm))
01002                     rv.push_back(cachedEntry);
01003             }
01004 /*          else
01005             {
01006                 //if it's not in our cache then add it provided it is not in a pending state
01007                 if(PAS_PENDING != (*pos)->GetState())
01008                     m_impl->AddUriEntry(*sourcePos, *pos);
01009 
01010                 rv.push_back(*pos);
01011             }*/
01012         }
01013     }
01014 
01015     //next, use information from the certificate to see if we have anything in the store 
01016     //that would be useful in determining its revocation status.  This call will return
01017     //a DP CRL, if available, else a full CRL, if available.
01018     CPKIFCRLNodeEntryPtr cachedEntry = m_impl->GetCachedCrlByIssuerOrDp(cert);
01019     if(cachedEntry != (CPKIFCRLNodeEntry*)NULL)
01020     {
01021         GottaMatch<CPKIFCRLNodeEntryPtr> gm;
01022         gm.SetRHS(cachedEntry);
01023         if(rv.end() == find_if(rv.begin(), rv.end(), gm))
01024             rv.push_back(cachedEntry);
01025     }
01026 
01027     crlNodeList.clear();
01028     copy(rv.begin(), rv.end(), back_inserter(crlNodeList));
01029 }
01038 void CPKIFSynonymousSourceStore::GetCerts(
01040     CPKIFCertificateSourceList& certSources, 
01042     CPKIFCertificateNodeList& certNodeList, 
01043     PathBuildingDirection pbd)
01044 {
01045     m_impl->CleanIfNecessary();
01046 
01047     GottaMatch<CPKIFCertificateNodeEntryPtr> gm;
01048 
01049     CPKIFCertificateSourceList::iterator pos;
01050     CPKIFCertificateSourceList::iterator end = certSources.end();
01051     for(pos = certSources.begin(); pos != end; ++pos)
01052     {
01053         vector<string> sources;
01054         (*pos)->GetSources(sources);
01055 
01056         CPKIFCertificateNodeList alreadyAvailNodeList;
01057         if(PAS_AVAILABLE == (*pos)->GetState())
01058         {
01059             (*pos)->GetCertificates(alreadyAvailNodeList, pbd);
01060         }
01061 
01062         vector<string>::iterator sourcePos;
01063         vector<string>::iterator sourceEnd = sources.end();
01064         for(sourcePos = sources.begin(); sourcePos != sourceEnd; ++sourcePos)
01065         {
01066             if(PAS_PENDING == (*pos)->GetState())
01067             {
01068                 CPKIFCertificateNodeList tempList;
01069                 m_impl->GetCachedCertByUri(*sourcePos, tempList);
01070                 if(!tempList.empty())
01071                 {
01072                     int sizeBefore = 0;
01073                     try {
01074                         sizeBefore = boost::numeric_cast<int,size_t>(certNodeList.size());
01075                     }catch(std::exception &e){
01076                         throw CPKIFCacheException(TOOLKIT_SR_MISC, COMMON_INVALID_INPUT, e.what());
01077                     }
01078                     CPKIFCertificateNodeList::iterator tempListPos;
01079                     CPKIFCertificateNodeList::iterator tempListEnd = tempList.end();
01080                     for(tempListPos = tempList.begin(); tempListPos != tempListEnd; ++tempListPos)
01081                     {
01082                         gm.SetRHS(*tempListPos);
01083                         if(PAS_UNAVAILABLE != (*tempListPos)->GetState() && certNodeList.end() == find_if(certNodeList.begin(), certNodeList.end(), gm))
01084                             certNodeList.push_back(*tempListPos);
01085                     }
01086 
01087                     if(sizeBefore != certNodeList.size())
01088                         (*pos)->SetState(PAS_AVAILABLE);
01089                     else
01090                         (*pos)->SetState(PAS_UNAVAILABLE);
01091                 }
01092             }
01093             if(PAS_AVAILABLE == (*pos)->GetState())
01094             {
01095                 CPKIFCertificateNodeList::iterator availListPos;
01096                 CPKIFCertificateNodeList::iterator availListEnd = alreadyAvailNodeList.end();
01097                 for(availListPos = alreadyAvailNodeList.begin(); availListPos != availListEnd; ++availListPos)
01098                     m_impl->AddUriEntry(*sourcePos, *availListPos);
01099             }
01100         }
01101     }
01102 }
01103 
01116 void CPKIFSynonymousSourceStore::AddCRL(
01118     CPKIFCRLNodeEntryPtr& crl)
01119 {
01120     if(crl == (CPKIFCRLNodeEntry*)NULL)
01121         return;
01122 
01123     if(PAS_PENDING == crl->GetState())
01124     {
01125         m_impl->AddPendingCrl(crl);
01126         return;
01127     }
01128 
01129     vector<string> sources;
01130     crl->GetSources(sources);
01131 
01132     vector<string>::iterator pos;
01133     vector<string>::iterator end = sources.end();
01134     for(pos = sources.begin(); pos != end; ++pos)
01135     {
01136         m_impl->AddUriEntry(*pos, crl);
01137     }
01138 }
01146 void CPKIFSynonymousSourceStore::AddCert(
01148     CPKIFCertificateNodeEntryPtr& cert)
01149 {
01150     if(cert == (CPKIFCertificateNodeEntry*)NULL)
01151         return;
01152 
01153     vector<string> sources;
01154     cert->GetSources(sources);
01155 
01156     vector<string>::iterator pos;
01157     vector<string>::iterator end = sources.end();
01158     for(pos = sources.begin(); pos != end; ++pos)
01159     {
01160         m_impl->AddUriEntry(*pos, cert);
01161     }
01162 }
01163 
01171 void CPKIFSynonymousSourceStore::WriteCacheContentsToConsole(
01173     std::ostream& out)
01174 {
01175     m_impl->WriteCacheContentsToConsole(out);
01176 }
01177 
01178 //XXX***The CRL name list could be problematic is multiple CAs with the same name are encountered.
01179 //XXX***The CRL DP retrieval function always returns the first matching CRL (there may be other inaccessible ones)

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