CACDefaultScoring.cpp

Go to the documentation of this file.
00001 
00009 #include "PKIFDefaultScoring.h"
00010 #include "ToolkitUtils.h"
00011 #include "PKIFCryptUtils.h"
00012 #include "components.h"
00013 #include "GottaMatch.h"
00014 #include "IPKIFCryptoRaw.h"
00015 #include "IPKIFTrustCache.h"
00016 #include "PKIFNameAndKeyWithScore.h"
00017 
00018 #include "BasicConstraintsViolation.h"
00019 
00020 #include "Certificate.h"
00021 #include "PKIFCertificateNodeEntry.h"
00022 #include "GeneralName.h"
00023 #include "Name.h"
00024 #include "Buffer.h"
00025 #include "SubjectPublicKeyInfo.h"
00026 #include "Validity.h"
00027 #include "PolicyInformation.h"
00028 #include "CertificateNodeListWithSourceInfo.h"
00029 #include "PKIFTime.h"
00030 #include "OID.h"
00031 
00032 #include "AuthorityKeyIdentifier.h"
00033 #include "SubjectKeyIdentifier.h"
00034 #include "PolicyInformationSet.h"
00035 #include "PolicyMappings.h"
00036 #include "PolicyMapping.h"
00037 #include "PKIFTrustRoot.h"
00038 #include "PKIFPathSettings.h"
00039 
00040 #include "BasicConstraints.h"
00041 #include "KeyUsage.h"
00042 
00043 #include <vector>
00044 #include <cstring>
00045 
00046 using namespace std;
00047 using namespace boost;
00048 
00049 #ifdef _DEBUG_PATH
00050 #include <iostream>
00051 #endif
00052 
00059 CPKIFDefaultScoring::CPKIFDefaultScoring()
00060 {
00061     LOG_STRING_DEBUG("CPKIFRevocationStatusMediator<DefaultColleagues, DefaultMediators>::~CPKIFRevocationStatusMediator(void)", TOOLKIT_PATH_MISC, 0, this);
00062 }
00070 CPKIFDefaultScoring::~CPKIFDefaultScoring()
00071 {
00072     LOG_STRING_DEBUG("CPKIFRevocationStatusMediator<DefaultColleagues, DefaultMediators>::~CPKIFRevocationStatusMediator(void)", TOOLKIT_PATH_MISC, 0, this);
00073 }
00074 
00075 #define ISSUED_BY_TRUST_ROOT                5000
00076 #define ISSUED_BY_CERT_IN_CACHE             500
00077 #define BASIC_CONSTRAINTS_PRESENT_AND_SET   75
00078 #define VAL_PERIOD_OK                       75
00079 #define ALGS_MATCH                          100
00080 #define KEY_IDS_MATCH                       6000 //changed from 500 to 6000 7/18 to bump preference
00081 #define NOT_SELF_ISSUED                     50
00082 #define NOT_SELF_SIGNED                     50
00083 
00084 //added the following - 7/21/2005
00085 #define HAS_AT_ONE_POLICY                   25
00086 #define MATCH_POLICY_WITH_PREV_CERT         25
00087 #define MATCH_POLICY_WITH_SETTINGS          25
00088 
00095 bool scoreCompare(
00097     const CPKIFCertificateNodeEntryPtr& lhs, 
00099     const CPKIFCertificateNodeEntryPtr& rhs)
00100 {
00101     LOG_STRING_DEBUG("scoreCompare(const CPKIFCertificateNodeEntryPtr& lhs, const CPKIFCertificateNodeEntryPtr& rhs)", TOOLKIT_PATH_MISC, 0, NULL);
00102 
00103     int rhsScore = rhs->GetScore();
00104     int lhsScore = lhs->GetScore();
00105     return lhsScore > rhsScore;
00106 }
00114 bool scoreCompareNK(
00116     const CPKIFNameAndKeyWithScorePtr& lhs, 
00118     const CPKIFNameAndKeyWithScorePtr& rhs)
00119 {
00120     LOG_STRING_DEBUG("scoreCompare(const CPKIFCertificateNodeEntryPtr& lhs, const CPKIFCertificateNodeEntryPtr& rhs)", TOOLKIT_PATH_MISC, 0, NULL);
00121 
00122     int rhsScore = rhs->GetScore();
00123     int lhsScore = lhs->GetScore();
00124     return lhsScore > rhsScore;
00125 }
00133 bool KeyIDsMatch(
00135     CPKIFAuthorityKeyIdentifierPtr& akid, 
00137     CPKIFCertificatePtr& curCert)
00138 {
00139     LOG_STRING_DEBUG("KeyIDsMatch(CPKIFAuthorityKeyIdentifierPtr& akid, CPKIFCertificatePtr& curCert)", TOOLKIT_PATH_MISC, 0, NULL);
00140 
00141     if(akid == (CPKIFAuthorityKeyIdentifier*)NULL)
00142         return false;
00143 
00144     //we'll only compare one - try key ID first
00145     if(akid->KeyIDPresent())
00146     {
00147         CPKIFSubjectKeyIdentifierPtr skid = curCert->GetExtension<CPKIFSubjectKeyIdentifier>();
00148         if(skid != (CPKIFSubjectKeyIdentifier*)NULL)
00149         {
00150             CPKIFBufferPtr akidKeyID = akid->KeyIdentifier();
00151             CPKIFBufferPtr skidKeyID = skid->KeyIdentifier();
00152             if(akidKeyID != (CPKIFBuffer*)NULL && skidKeyID != (CPKIFBuffer*)NULL)
00153             {
00154                 if(*akidKeyID == *skidKeyID)
00155                     return true;
00156             }
00157         }
00158     }
00159     else if(akid->IssDNAndSerialNumberPresent())
00160     {
00161         const char* lhsSN = akid->SerialNumber();
00162         const char* rhsSN = curCert->SerialNumber();
00163         
00164         //reviewed 4/23 - added strlen
00165         if(strlen(lhsSN) != strlen(rhsSN) || 0 != stricmp(lhsSN, rhsSN))
00166             return false;
00167         else
00168         {
00169             CPKIFGeneralNameList gns;
00170             akid->Issuer(gns);
00171 
00172             CPKIFGeneralNameList::iterator gnPos;
00173             CPKIFGeneralNameList::iterator gnEnd = gns.end();
00174             
00175             //spin through them all and if we find a match - good
00176             //if not - big deal - this is just for scoring
00177             //not going to bother comparing curCert issAltNames for this purpose
00178             for(gnPos = gns.begin(); gnPos != gnEnd; ++gnPos)
00179             {
00180                 if(CPKIFGeneralName::DIRECTORYNAME == (*gnPos)->GetType())
00181                 {
00182                     if(*(*gnPos)->directoryName() == *curCert->Issuer())
00183                         return true;
00184                 }
00185             }
00186         }
00187     }
00188 
00189     return false;
00190 }
00191 
00192 
00200 bool KeyIDsMatch(
00202     CPKIFAuthorityKeyIdentifierPtr& akid, 
00204     const IPKIFTrustAnchorPtr& curTA)
00205 {
00206     LOG_STRING_DEBUG("KeyIDsMatch(CPKIFAuthorityKeyIdentifierPtr& akid, CPKIFCertificatePtr& curCert)", TOOLKIT_PATH_MISC, 0, NULL);
00207 
00208     if(akid == (CPKIFAuthorityKeyIdentifier*)NULL)
00209         return false;
00210 
00211     IPKIFHasExtensionsPtr extsInterface;
00212     extsInterface = dynamic_pointer_cast<IPKIFHasExtensions, IPKIFTrustAnchor>(curTA);
00213 
00214     //we'll only compare one - try key ID first
00215     if(akid->KeyIDPresent())
00216     {
00217         CPKIFSubjectKeyIdentifierPtr skid = extsInterface->GetExtension<CPKIFSubjectKeyIdentifier>();
00218         if(skid != (CPKIFSubjectKeyIdentifier*)NULL)
00219         {
00220             CPKIFBufferPtr akidKeyID = akid->KeyIdentifier();
00221             CPKIFBufferPtr skidKeyID = skid->KeyIdentifier();
00222             if(akidKeyID != (CPKIFBuffer*)NULL && skidKeyID != (CPKIFBuffer*)NULL)
00223             {
00224                 if(*akidKeyID == *skidKeyID)
00225                     return true;
00226             }
00227         }
00228         else
00229         {       
00230             CPKIFCertificatePtr curCert;
00231             CPKIFTrustRootPtr tr2 = dynamic_pointer_cast<CPKIFTrustRoot, IPKIFTrustAnchor>(curTA);
00232             if(tr2) 
00233                 tr2->GetCert(curCert);
00234 
00235             if(curCert)
00236             {
00237                 if(KeyIDsMatch(akid, curCert))
00238                     return true;
00239             }
00240         }
00241     }
00242     else if(akid->IssDNAndSerialNumberPresent())
00243     {
00244         CPKIFCertificatePtr curCert;
00245         CPKIFTrustRootPtr tr2 = dynamic_pointer_cast<CPKIFTrustRoot, IPKIFTrustAnchor>(curTA);
00246         if(tr2) 
00247             tr2->GetCert(curCert);
00248 
00249         if(curCert)
00250         {
00251             const char* lhsSN = akid->SerialNumber();
00252             const char* rhsSN = curCert->SerialNumber();
00253             
00254             //reviewed 4/23 - added strlen
00255             if(strlen(lhsSN) != strlen(rhsSN) || 0 != stricmp(lhsSN, rhsSN))
00256                 return false;
00257             else
00258             {
00259                 CPKIFGeneralNameList gns;
00260                 akid->Issuer(gns);
00261 
00262                 CPKIFGeneralNameList::iterator gnPos;
00263                 CPKIFGeneralNameList::iterator gnEnd = gns.end();
00264                 
00265                 //spin through them all and if we find a match - good
00266                 //if not - big deal - this is just for scoring
00267                 //not going to bother comparing curCert issAltNames for this purpose
00268                 for(gnPos = gns.begin(); gnPos != gnEnd; ++gnPos)
00269                 {
00270                     if(CPKIFGeneralName::DIRECTORYNAME == (*gnPos)->GetType())
00271                     {
00272                         if(*(*gnPos)->directoryName() == *curCert->Issuer())
00273                             return true;
00274                     }
00275                 }
00276             }
00277         }
00278     }
00279 
00280     return false;
00281 }
00282 
00283 
00284 
00285 //class NegativeScore
00286 //{
00287 //public:
00288 //  NegativeScore() {}
00289 //  bool operator()(const CPKIFCertificateNodeEntryPtr& entry);
00290 //
00291 //private:
00292 //  NegativeScore& operator=(const NegativeScore& rhs); //added 4/6/2004
00293 //};
00294 //
00295 //bool NegativeScore::operator()(const CPKIFCertificateNodeEntryPtr& entry)
00296 //{
00297 //  if(entry->GetScore() < 0) return true; else return false;
00298 //} 
00306 bool SomeMatch(
00308     CPKIFPolicyInformationSetPtr& fromCert, 
00310     CPKIFPolicyInformationListPtr& polsFromPrevCert, 
00312     CPKIFPolicyMappingsPtr& policyMappings)
00313 {
00314     const CPKIFPolicyInformationListPtr& polsFromCert = fromCert->GetPolicySet();
00315     CPKIFPolicyInformationList::iterator prevEnd = polsFromPrevCert->end();
00316 
00317     {
00318     CPKIFPolicyInformationList::iterator pos;
00319     CPKIFPolicyInformationList::iterator end = polsFromCert->end();
00320     for(pos = polsFromCert->begin(); pos != end; ++pos)
00321     {
00322         if(*g_anyPolicy == *(*pos))
00323             return true;
00324     }
00325     }
00326 
00327     {
00328     CPKIFPolicyInformationList::iterator pos;
00329     CPKIFPolicyInformationList::iterator end = polsFromPrevCert->end();
00330     for(pos = polsFromPrevCert->begin(); pos != end; ++pos)
00331     {
00332         if(*g_anyPolicy == *(*pos))
00333             return true;
00334     }
00335     }
00336 
00337     {
00338     CPKIFPolicyInformationList::iterator pos;
00339     CPKIFPolicyInformationList::iterator end = polsFromCert->end();
00340     for(pos = polsFromCert->begin(); pos != end; ++pos)
00341     {
00342         GottaMatch<CPKIFPolicyInformationPtr> gm;
00343         gm.SetRHS(*pos);
00344         if(prevEnd != find_if(polsFromPrevCert->begin(), prevEnd, gm))
00345             return true;
00346     }
00347     }
00348 
00349     {
00350         if(policyMappings != (CPKIFPolicyMappings*)NULL)
00351         {
00352             vector<CPKIFOIDPtr> subDomainOIDs;
00353             if(policyMappings != (CPKIFPolicyMappings*)NULL)
00354             {
00355                 CPKIFPolicyMappingListPtr policyMappingsList = policyMappings->PolicyMappings();
00356                 CPKIFPolicyMappingList::iterator pmPos;
00357                 CPKIFPolicyMappingList::iterator pmEnd = policyMappingsList->end();
00358                 for(pmPos = policyMappingsList->begin(); pmPos != pmEnd; ++pmPos)
00359                     subDomainOIDs.push_back((*pmPos)->SubjectDomain());
00360             }
00361             CPKIFPolicyInformationList::iterator pos;
00362             CPKIFPolicyInformationList::iterator end = polsFromPrevCert->end();
00363             for(pos = polsFromPrevCert->begin(); pos != end; ++pos)
00364             {
00365                 CPKIFOIDPtr policyOID = (*pos)->PolicyOID();
00366                 vector<CPKIFOIDPtr>::iterator oidPos;
00367                 vector<CPKIFOIDPtr>::iterator oidEnd = subDomainOIDs.end();
00368                 for(oidPos = subDomainOIDs.begin(); oidPos != oidEnd; ++oidPos)
00369                     if(*(*oidPos) == *policyOID)
00370                         return true;
00371             }
00372         }
00373     }
00374 
00375     return false;
00376 }
00384 bool SomeMatch(
00386     CPKIFPolicyInformationSetPtr& fromCert, 
00388     CPKIFPolicyInformationSetPtr& fromPrevCert, 
00390     CPKIFPolicyMappingsPtr& policyMappings)
00391 {
00392     if(fromCert == (CPKIFPolicyInformationSet*)NULL  || fromPrevCert == (CPKIFPolicyInformationSet*)NULL)
00393         return false;
00394     CPKIFPolicyInformationListPtr tmpPrevPolicy = fromPrevCert->GetPolicySet();
00395     return SomeMatch(fromCert, tmpPrevPolicy/*fromPrevCert->GetPolicySet()*/, policyMappings);
00396 }
00421 void CPKIFDefaultScoring::ScoreAndSortNodes(
00423     CPKIFCertificateNodeListWithSourceInfoPtr& nodeList, 
00425     CPKIFCertificatePtr& prevCert, 
00427     CPKIFPathSettingsPtr& settings, 
00429     IPKIFTrustCache* trustCache,
00431     int numOfCAsBelowCurInPath, 
00433     IPKIFCertRepository* iCert)
00434 {
00435     LOG_STRING_DEBUG("CPKIFDefaultScoring::ScoreAndSortNodes", TOOLKIT_PATH_MISC, 0, this);
00436 
00437     IPKIFTrustAnchorList rootList;
00438     CPKIFCertificateList certList;
00439 
00440     //score each node entry
00441     CPKIFCertificateNodeListWithSourceInfo::iterator pos;
00442     CPKIFCertificateNodeListWithSourceInfo::iterator end = nodeList->end();     
00443 
00444     CPKIFPolicyInformationListPtr initPolSet;
00445     settings->GetInitialPolicySet(initPolSet);
00446 
00447     IPKIFCryptoRaw * raw = GetPlatformCryptoRaw();
00448     for(pos = nodeList->begin(); pos != end; ++pos)
00449     {
00450         (*pos)->ClearScore();
00451         CPKIFCertificatePtr curCert = (*pos)->GetCert();
00452         CPKIFNamePtr curIssuer = curCert->Issuer();
00453 
00454 #ifdef _DEBUG_PATH
00455         const char* curSubStr = curCert->Subject()->ToString();
00456 #endif
00457 
00458         //see if cert is issued by someone in the trust store
00459         rootList.clear();
00460         trustCache->GetTrustRoots(curIssuer, rootList);     
00461         if(!rootList.empty())
00462             (*pos)->AddToScore(ISSUED_BY_TRUST_ROOT);
00463 
00464         //see if cert is issued by someone in the local cache
00465         //avoid picking up certs that we are currently operating on
00466         if(!CertIsSelfIssued((*pos)->GetCert()))
00467         {
00468             //cert not self issued
00469             (*pos)->AddToScore(NOT_SELF_ISSUED);
00470 
00471             certList.clear();
00472             //iCert->GetCertificates(curIssuer, certList, LOCAL);
00473             //if(!certList.empty())
00474             //  (*pos)->AddToScore(ISSUED_BY_CERT_IN_CACHE);
00475         }
00476 
00477         if(!curCert->IsSelfSigned())
00478         {
00479             (*pos)->AddToScore(NOT_SELF_SIGNED);
00480         }
00481 
00482         //see if basic constraints is present and ca set
00483         CPKIFBasicConstraintsPtr basicConstraints;
00484         try {
00485         basicConstraints = curCert->GetExtension<CPKIFBasicConstraints>();
00486         }catch(...){}
00487         bool isCA = false;
00488         if(basicConstraints != (CPKIFBasicConstraints*)NULL)
00489         {
00490             if(basicConstraints->isCA())
00491                 (*pos)->AddToScore(BASIC_CONSTRAINTS_PRESENT_AND_SET);
00492             else
00493             {
00494                 (*pos)->ClearScore();
00495                 continue;
00496             }
00497             if(basicConstraints->pathLengthPresent())
00498             {
00499                 if(numOfCAsBelowCurInPath >= 0 && basicConstraints->pathLength() < numOfCAsBelowCurInPath)
00500                 {
00501                     (*pos)->ClearScore();
00502                     continue;
00503                 }
00504             }
00505         }
00506 
00507         //----------------------------------------------------------------------------------------------------
00508         // added code to bump priority of certificates containing policies
00509         // and/or containing policies in the prev cert and/or in the 
00510         // settings object and/or deprioritize those that yield empty
00511         // intersection - 7/21/2005
00512         CPKIFPolicyInformationSetPtr cpsFromCert;
00513         try {
00514         cpsFromCert = curCert->GetExtension<CPKIFPolicyInformationSet>();
00515         }catch(...){}
00516         if(cpsFromCert != (CPKIFPolicyInformationSet*)NULL)
00517         {
00518             //give points for simply having a policy
00519             (*pos)->AddToScore(HAS_AT_ONE_POLICY);
00520 
00521             CPKIFPolicyMappingsPtr policyMappings;
00522             if(SomeMatch(cpsFromCert, initPolSet, policyMappings))
00523                 (*pos)->AddToScore(MATCH_POLICY_WITH_SETTINGS);
00524 
00525             if(prevCert != (CPKIFCertificate*)NULL)
00526             {
00527                 try {
00528                 policyMappings = curCert->GetExtension<CPKIFPolicyMappings>();
00529                 }catch(...) {}
00530                 CPKIFPolicyInformationSetPtr cpsFromPrevCert = prevCert->GetExtension<CPKIFPolicyInformationSet>();
00531                 if(SomeMatch(cpsFromCert, cpsFromPrevCert,policyMappings))
00532                 {
00533                     (*pos)->AddToScore(MATCH_POLICY_WITH_PREV_CERT);                    
00534                 }
00535                 //else if(!initPolSet->empty())
00536                 //{
00537                 //  (*pos)->ClearScore();
00538                 //  (*pos)->SetPolicyIgnore();
00539                 //  continue;
00540                 //}
00541             }
00542         }
00543 
00544         //----------------------------------------------------------------------------------------------------
00545 
00546         //perform validity period check
00547         //changed from current time to settings based time - 7/19/2004
00548         CPKIFTimePtr curTime = settings->GetValidationTime();
00549         CPKIFValidityPtr val = curCert->Validity();
00550         CPKIFTimePtr startTime = val->notBefore();
00551         CPKIFTimePtr endTime = val->notAfter();
00552         if(*curTime > *startTime && *curTime < *endTime)
00553         {
00554             (*pos)->AddToScore(VAL_PERIOD_OK);
00555         }
00556         else
00557         {
00558             (*pos)->ClearScore();
00559             continue;
00560         }
00561 
00562         //see if algs chain properly
00563         if(prevCert != (CPKIFCertificate*)NULL)
00564         {
00565     #ifdef _DEBUG_PATH
00566         const char* prevSubStr = prevCert->Subject()->ToString();
00567     #endif
00568             CPKIFAlgorithmIdentifierPtr prevCertSigAlg = prevCert->SignatureAlgorithm();
00569             CPKIFAlgorithmIdentifierPtr curCertSigAlg = curCert->SubjectPublicKeyInfo()->alg();
00570             if(GetAlgClass(prevCertSigAlg) != GetAlgClass(curCertSigAlg))
00571             {
00572                 (*pos)->ClearScore();
00573                 continue;
00574             }
00575             else
00576             {
00577                 (*pos)->AddToScore(ALGS_MATCH);
00578             }
00579 
00580             //check AKID/SKID chaining
00581             CPKIFAuthorityKeyIdentifierPtr akid;
00582             try {
00583             akid = prevCert->GetExtension<CPKIFAuthorityKeyIdentifier>();
00584             }catch(...) {}
00585             if(akid != (CPKIFAuthorityKeyIdentifier*)NULL)
00586             {
00587                 if(KeyIDsMatch(akid, curCert))
00588                 {
00589                     (*pos)->AddToScore(KEY_IDS_MATCH);
00590                 }
00591                 else
00592                 {
00593                     //if present but no match - clear the score 7/27/2005
00594 //                  (*pos)->ClearScore();
00595                     try
00596                     {
00597                         if(/*CertIsSelfIssued(prevCert) && */!raw->VerifyCertificate(*curCert, *prevCert))
00598                         {
00599                             (*pos)->ClearScore();
00600                             continue;
00601                         }
00602                     }
00603                     catch(...)
00604                     {
00605                     }
00606                 }
00607             }
00608         }
00609     }
00610 
00611     //before sorting remove any offending nodes
00612 //  BasicConstraintsViolation bcv;
00613 //  bcv.SetCACount(numOfCAsBelowCurInPath);
00614 //  CPKIFCertificateNodeListWithSourceInfo::iterator newEnd = remove_if(nodeList->begin(), nodeList->end(), bcv);
00615 //  nodeList->erase(newEnd, nodeList->end());
00616 //  if(nodeList->empty())
00617 //      return;
00618 
00619     //or instead - just set the score on the offending nodes to 0
00620 //  for(;newEnd != nodeList->end(); ++newEnd)
00621 //      (*newEnd)->ClearScore();
00622 
00623     //NegativeScore ns;
00624     //newEnd = remove_if(nodeList->begin(), nodeList->end(), ns);
00625     //nodeList->erase(newEnd, nodeList->end());
00626     //if(nodeList->empty())
00627     //  return;
00628 
00629 #ifdef _DEBUG_PATH
00630     const char* frontSerialNum = nodeList->front()->GetCert()->SerialNumber();
00631 #endif
00632 
00633     //reorder the list based on the scoring
00634     sort(nodeList->begin(), nodeList->end(), scoreCompare);
00635 
00636 #ifdef _DEBUG_PATH
00637     const char* frontSerialNum2 = nodeList->front()->GetCert()->SerialNumber();
00638 
00639     CPKIFCertificateNodeListWithSourceInfo::iterator pos2;
00640     CPKIFCertificateNodeListWithSourceInfo::iterator end2 = nodeList->end();        
00641     cout << endl << "Dumping scoring info for subject" << endl;
00642     for(pos2 = nodeList->begin(); pos2 != end2; ++pos2)
00643     {
00644         const char* tmpSerialNum = (*pos2)->GetCert()->SerialNumber();
00645         const char* tmpIssName = (*pos2)->GetCert()->Issuer()->ToString();
00646         cout << "Issuer: " << tmpIssName << " serial: " << tmpSerialNum << " score: " << (*pos2)->GetScore() << endl;
00647     }
00648 
00649 #endif
00650 }
00651 
00676 void CPKIFDefaultScoring::ScoreAndSortNodes(
00678     CPKIFNameAndKeyWithScoreListPtr& nodeList, 
00680     CPKIFCertificatePtr& prevCert, 
00682     CPKIFPathSettingsPtr& settings, 
00684     IPKIFTrustCache* trustCache,
00686     int numOfCAsBelowCurInPath, 
00688     IPKIFCertRepository* iCert)
00689 {
00690     LOG_STRING_DEBUG("CPKIFDefaultScoring::ScoreAndSortNodes", TOOLKIT_PATH_MISC, 0, this);
00691 
00692     IPKIFTrustAnchorList rootList;
00693     CPKIFCertificateList certList;
00694 
00695     //score each node entry
00696     CPKIFNameAndKeyWithScoreList::iterator pos;
00697     CPKIFNameAndKeyWithScoreList::iterator end = nodeList->end();       
00698 
00699     CPKIFPolicyInformationListPtr initPolSet;
00700     settings->GetInitialPolicySet(initPolSet);
00701 
00702     IPKIFCryptoRaw * raw = GetPlatformCryptoRaw();
00703     for(pos = nodeList->begin(); pos != end; ++pos)
00704     {
00705         (*pos)->ClearScore();
00706         IPKIFNameAndKeyPtr curNK = (*pos)->GetNameAndKey();
00707         CPKIFCertificatePtr curCert = boost::dynamic_pointer_cast<CPKIFCertificate, IPKIFNameAndKey>(curNK);
00708         if(curCert == (CPKIFCertificate*)NULL)
00709             continue;
00710         CPKIFNamePtr curIssuer = curCert->Issuer();
00711 
00712 #ifdef _DEBUG_PATH
00713         const char* curSubStr = curCert->Subject()->ToString();
00714 #endif
00715 
00716         //see if cert is issued by someone in the trust store
00717         rootList.clear();
00718         trustCache->GetTrustRoots(curIssuer, rootList);     
00719         if(!rootList.empty())
00720             (*pos)->AddToScore(ISSUED_BY_TRUST_ROOT);
00721 
00722         //see if cert is issued by someone in the local cache
00723         //avoid picking up certs that we are currently operating on
00724         if(!CertIsSelfIssued(curCert))
00725         {
00726             //cert not self issued
00727             (*pos)->AddToScore(NOT_SELF_ISSUED);
00728 
00729             certList.clear();
00730             //iCert->GetCertificates(curIssuer, certList, LOCAL);
00731             //if(!certList.empty())
00732             //  (*pos)->AddToScore(ISSUED_BY_CERT_IN_CACHE);
00733         }
00734 
00735         if(!curCert->IsSelfSigned())
00736         {
00737             (*pos)->AddToScore(NOT_SELF_SIGNED);
00738         }
00739 
00740         //see if basic constraints is present and ca set
00741         CPKIFBasicConstraintsPtr basicConstraints;
00742         try {
00743         basicConstraints = curCert->GetExtension<CPKIFBasicConstraints>();
00744         } catch(...){}
00745         bool isCA = false;
00746         if(basicConstraints != (CPKIFBasicConstraints*)NULL)
00747         {
00748             if(basicConstraints->isCA())
00749                 (*pos)->AddToScore(BASIC_CONSTRAINTS_PRESENT_AND_SET);
00750             else
00751             {
00752                 (*pos)->ClearScore();
00753                 continue;
00754             }
00755         }
00756 
00757         //----------------------------------------------------------------------------------------------------
00758         // added code to bump priority of certificates containing policies
00759         // and/or containing policies in the prev cert and/or in the 
00760         // settings object and/or deprioritize those that yield empty
00761         // intersection - 7/21/2005
00762         CPKIFPolicyInformationSetPtr cpsFromCert;
00763         try {
00764         cpsFromCert = curCert->GetExtension<CPKIFPolicyInformationSet>();
00765         }catch(...){}
00766         if(cpsFromCert != (CPKIFPolicyInformationSet*)NULL)
00767         {
00768             //give points for simply having a policy
00769             (*pos)->AddToScore(HAS_AT_ONE_POLICY);
00770 
00771             CPKIFPolicyMappingsPtr policyMappings;
00772             if(SomeMatch(cpsFromCert, initPolSet, policyMappings))
00773                 (*pos)->AddToScore(MATCH_POLICY_WITH_SETTINGS);
00774 
00775             if(prevCert != (CPKIFCertificate*)NULL)
00776             {
00777                 try {
00778                 policyMappings = curCert->GetExtension<CPKIFPolicyMappings>();
00779                 }catch(...){}
00780                 CPKIFPolicyInformationSetPtr cpsFromPrevCert = prevCert->GetExtension<CPKIFPolicyInformationSet>();
00781                 if(SomeMatch(cpsFromCert, cpsFromPrevCert,policyMappings))
00782                 {
00783                     (*pos)->AddToScore(MATCH_POLICY_WITH_PREV_CERT);                    
00784                 }
00785                 //else if(!initPolSet->empty())
00786                 //{
00787                 //  (*pos)->ClearScore();
00788                 //  (*pos)->SetPolicyIgnore();
00789                 //  continue;
00790                 //}
00791             }
00792         }
00793 
00794         //----------------------------------------------------------------------------------------------------
00795 
00796         //perform validity period check
00797         //changed from current time to settings based time - 7/19/2004
00798         CPKIFTimePtr curTime = settings->GetValidationTime();
00799         CPKIFValidityPtr val = curCert->Validity();
00800         CPKIFTimePtr startTime = val->notBefore();
00801         CPKIFTimePtr endTime = val->notAfter();
00802         if(*curTime > *startTime && *curTime < *endTime)
00803         {
00804             (*pos)->AddToScore(VAL_PERIOD_OK);
00805         }
00806         else
00807         {
00808             (*pos)->ClearScore();
00809             continue;
00810         }
00811 
00812         //see if algs chain properly
00813         if(prevCert != (CPKIFCertificate*)NULL)
00814         {
00815     #ifdef _DEBUG_PATH
00816         const char* prevSubStr = prevCert->Subject()->ToString();
00817     #endif
00818             CPKIFAlgorithmIdentifierPtr prevCertSigAlg = prevCert->SignatureAlgorithm();
00819             CPKIFAlgorithmIdentifierPtr curCertSigAlg = curCert->SubjectPublicKeyInfo()->alg();
00820             if(GetAlgClass(prevCertSigAlg) != GetAlgClass(curCertSigAlg))
00821             {
00822                 (*pos)->ClearScore();
00823                 continue;
00824             }
00825             else
00826             {
00827                 (*pos)->AddToScore(ALGS_MATCH);
00828             }
00829 
00830             //check AKID/SKID chaining
00831             CPKIFAuthorityKeyIdentifierPtr akid;
00832             try {
00833             akid = prevCert->GetExtension<CPKIFAuthorityKeyIdentifier>();
00834             } catch(...){}
00835             if(akid != (CPKIFAuthorityKeyIdentifier*)NULL)
00836             {
00837                 if(KeyIDsMatch(akid, curCert))
00838                 {
00839                     (*pos)->AddToScore(KEY_IDS_MATCH);
00840                 }
00841                 else
00842                 {
00843                     //if present but no match - clear the score 7/27/2005
00844 //                  (*pos)->ClearScore();
00845                     try
00846                     {
00847                         if(/*CertIsSelfIssued(prevCert) && */!raw->VerifyCertificate(*curCert, *prevCert))
00848                         {
00849                             (*pos)->ClearScore();
00850                             continue;
00851                         }
00852                     }
00853                     catch(...)
00854                     {
00855                     }
00856                 }
00857             }
00858         }
00859     }
00860 
00861     /*
00862     //before sorting remove any offending nodes
00863     BasicConstraintsViolation bcv;
00864     bcv.SetCACount(numOfCAsBelowCurInPath);
00865     CPKIFNameAndKeyWithScoreList::iterator newEnd = remove_if(nodeList->begin(), nodeList->end(), bcv);
00866 
00867     //or instead - just set the score on the offending nodes to 0
00868     for(;newEnd != nodeList->end(); ++newEnd)
00869         (*newEnd)->ClearScore();
00870         */
00871 
00872     //NegativeScore ns;
00873     //newEnd = remove_if(nodeList->begin(), nodeList->end(), ns);
00874     //nodeList->erase(newEnd, nodeList->end());
00875     //if(nodeList->empty())
00876     //  return;
00877 
00878 #ifdef _DEBUG_PATH
00879     //const char* frontSerialNum = nodeList->front()->GetCert()->SerialNumber();
00880 #endif
00881 
00882     //reorder the list based on the scoring
00883     sort(nodeList->begin(), nodeList->end(), scoreCompareNK);
00884 
00885 #ifdef _DEBUG_PATH
00886     //const char* frontSerialNum2 = nodeList->front()->GetCert()->SerialNumber();
00887 
00888     CPKIFNameAndKeyWithScoreList::iterator pos2;
00889     CPKIFNameAndKeyWithScoreList::iterator end2 = nodeList->end();      
00890     cout << endl << "Dumping scoring info for subject" << endl;
00891     for(pos2 = nodeList->begin(); pos2 != end2; ++pos2)
00892     {
00893         //const char* tmpSerialNum = (*pos2)->GetCert()->SerialNumber();
00894         const char* tmpIssName = (*pos2)->GetNameAndKey()->GetIssuerName()->ToString();
00895         cout << "Issuer: " << tmpIssName << " score: " << (*pos2)->GetScore() << endl;
00896     }
00897 
00898 #endif
00899 }

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