BuilderUtils.cpp

Go to the documentation of this file.
00001 
00009 #include "BuilderUtils.h"
00010 #include "PKIFPathBasicChecks2.h"
00011 #include "ToolkitUtils.h"
00012 #include "PKIFPathException.h"
00013 #include "PKIFFuncStorage.h"
00014 #include "PKIFCryptUtils.h"
00015 #include "IPKIFCryptoRaw.h"
00016 #include "PKIFX509Extensions2.h"
00017 
00018 #include "AuthorityKeyIdentifier.h"
00019 #include "SubjectKeyIdentifier.h"
00020 #include "PKIFPathSettings.h"
00021 #include "BasicConstraints.h"
00022 #include "PolicyMappings.h"
00023 #include "PolicyInformationSet.h"
00024 #include "AuthorityKeyIdentifier.h"
00025 #include "Certificate.h"
00026 #include "KeyUsage.h"
00027 #include "ExtendedKeyUsage.h"
00028 #include "PathResults.h"
00029 #include "CertificateNodeListWithSourceInfo.h"
00030 #include "NodeNotInNodeListAndNotIgnoredAndIssuedBy.h"
00031 #include "OID.h"
00032 #include "GottaMatch.h"
00033 #include "PolicyInformation.h"
00034 #include "IssuedBy.h"
00035 #include "IgnoreNotIssuedByOp.h"
00036 #include "PKIFCertificateNodeEntry.h"
00037 #include "Name.h"
00038 #include "OID.h"
00039 #include "PKIFCertificatePath.h"
00040 #include "IPKIFTrustAnchor.h"
00041 #include "PKIFReversePathState.h"
00042 #include "PKIFNameAndKeyWithScore.h"
00043 
00044 #include <vector>
00045 using namespace std;
00046 
00047 //implemented in CACDefaultScoring
00048 extern bool SomeMatch(CPKIFPolicyInformationSetPtr& fromCert, CPKIFPolicyInformationSetPtr& fromPrevCert, CPKIFPolicyMappingsPtr& policyMappings);
00049 extern bool SomeMatch(CPKIFPolicyInformationSetPtr& fromCert, CPKIFPolicyInformationListPtr& polsFromPrevCert, CPKIFPolicyMappingsPtr& policyMappings);
00050 bool KeyIDsMatch(CPKIFAuthorityKeyIdentifierPtr& akid, CPKIFCertificatePtr& curCert);
00058 bool CheckPolicies(
00060     CPKIFCertificatePtr& subjectCert, 
00062     CPKIFCertificatePtr& issuerCert, 
00064     CPKIFPathSettingsPtr& settings)
00065 {
00066     CPKIFPolicyInformationListPtr initPolSet;
00067     settings->GetInitialPolicySet(initPolSet);
00068     //if(initPolSet->empty()) return true;
00069     //Added 8/1/2005 Armen
00070     if(initPolSet->empty())   
00071           return true;  
00072      else  
00073      {  
00074           CPKIFPolicyInformationList::iterator pos;  
00075           CPKIFPolicyInformationList::iterator end = initPolSet->end();  
00076           for(pos = initPolSet->begin(); pos != end; ++pos)  
00077           {  
00078                if(*g_anyPolicy == *(*pos))  
00079                     return true;  
00080           }  
00081      }
00082 
00083     CPKIFPolicyInformationSetPtr cpsFromIssuerCert = issuerCert->GetExtension<CPKIFPolicyInformationSet>();
00084     if(cpsFromIssuerCert != (CPKIFPolicyInformationSet*)NULL)
00085     {
00086 //      if(!SomeMatch(cpsFromIssuerCert, initPolSet)) return false;
00087 
00088         CPKIFPolicyInformationSetPtr cpsFromSubCert = subjectCert->GetExtension<CPKIFPolicyInformationSet>();
00089         CPKIFPolicyMappingsPtr policyMappings = issuerCert->GetExtension<CPKIFPolicyMappings>();
00090         if(!SomeMatch(cpsFromIssuerCert, cpsFromSubCert, policyMappings)) 
00091             return false;
00092         else 
00093             return true;
00094     }
00095     else
00096         return true; // no policies == NULL intersection //Changed from return false on 8/1/2005 Armen
00097 }
00106 bool CheckKIDsAndSignatures(
00108     CPKIFCertificatePtr& subjectCert, 
00110     CPKIFCertificatePtr& issuerCert)
00111 {
00112     CPKIFAuthorityKeyIdentifierPtr akid = subjectCert->GetExtension<CPKIFAuthorityKeyIdentifier>();
00113     if(KeyIDsMatch(akid, issuerCert))
00114         return true;
00115     else
00116     {
00117         IPKIFCryptoRaw * raw = GetPlatformCryptoRaw();
00118         bool sigVerified = false;
00119         try
00120         {
00121             sigVerified = raw->VerifyCertificate(*issuerCert, *subjectCert);
00122         }
00123         catch(...)
00124         {
00125         }
00126         return sigVerified;
00127     }
00128 }
00129 
00130 
00131 //walks a cert node list and clears the ignore flag on each entry
00132 //removed export declarations 8/18/2004
00140 void ClearAllIgnore(
00142     CPKIFCertificateNodeListWithSourceInfoPtr& tablePos)
00143 {
00144     CPKIFCertificateNodeList::iterator pos;
00145     CPKIFCertificateNodeList::iterator end = tablePos->end();
00146     for(pos = tablePos->begin(); pos != end; ++pos)
00147         (*pos)->ClearIgnore();
00148 }
00156 void ClearAllIgnore(
00158     CPKIFNameAndKeyWithScoreListPtr& tablePos)
00159 {
00160     CPKIFNameAndKeyWithScoreList::iterator pos;
00161     CPKIFNameAndKeyWithScoreList::iterator end = tablePos->end();
00162     for(pos = tablePos->begin(); pos != end; ++pos)
00163         (*pos)->ClearIgnore();
00164 }
00165 
00166 //returns true if all nodes in a node list are set to ignore - false otherwise
00167 //bool AllAreSetToIgnore(CPKIFCertificateNodeListWithSourceInfoPtr& tablePos)
00168 //{
00169 //  CPKIFCertificateNodeList::iterator pos;
00170 //  CPKIFCertificateNodeList::iterator end = tablePos->end();
00171 //  for(pos = tablePos->begin(); pos != end; ++pos)
00172 //  {
00173 //      if(false == (*pos)->GetIgnore())
00174 //          return false;
00175 //  }
00176 //
00177 //  return true;
00178 //}
00179 
00180 
00188 bool SetNextToIgnore(
00190     CPKIFCertificateNodeListWithSourceInfoPtr& tablePos)
00191 {
00192     CPKIFCertificateNodeList::iterator pos;
00193     CPKIFCertificateNodeList::iterator end = tablePos->end();
00194     bool set = false;
00195     for(pos = tablePos->begin(); pos != end; ++pos)
00196     {
00197         if(set)
00198         {
00199             if(false == (*pos)->GetIgnore() && false == (*pos)->GetHardIgnore())
00200                 return false;
00201         }
00202         else if(false == (*pos)->GetIgnore() && false == (*pos)->GetHardIgnore())
00203         {
00204             (*pos)->SetIgnore();
00205             set = true;
00206         }
00207     }
00208 
00209     return true; //need to advance the row
00210 }
00211 
00219 bool SetNextToIgnore(
00221     CPKIFNameAndKeyWithScoreListPtr& tablePos)
00222 {
00223     CPKIFNameAndKeyWithScoreList::iterator pos;
00224     CPKIFNameAndKeyWithScoreList::iterator end = tablePos->end();
00225     bool set = false;
00226     for(pos = tablePos->begin(); pos != end; ++pos)
00227     {
00228         if(set)
00229         {
00230             if(false == (*pos)->GetIgnore())
00231                 return false;
00232         }
00233         else if(false == (*pos)->GetIgnore())
00234         {
00235             (*pos)->SetIgnore();
00236             set = true;
00237         }
00238     }
00239 
00240     return true; //need to advance the row
00241 }
00242 
00250 void RemoveAllIssuedBy(
00252     CPKIFCertificateNodeListWithSourceInfoPtr& pos,
00254     CPKIFNamePtr& prevName)
00255 {
00256     IssuedBy issuedBy;
00257     issuedBy.SetRHS(prevName);
00258     CPKIFCertificateNodeList::iterator end;
00259     end = remove_if(pos->begin(), pos->end(), issuedBy);
00260     pos->erase(end, pos->end());
00261 }
00262 
00270 void RemoveAllIssuedBy(
00272     CPKIFNameAndKeyWithScoreListPtr& pos,
00274     CPKIFNamePtr& prevName)
00275 {
00276     IssuedByNameAndKey issuedBy;
00277     issuedBy.SetRHS(prevName);
00278     CPKIFNameAndKeyWithScoreList::iterator end;
00279     end = remove_if(pos->begin(), pos->end(), issuedBy);
00280     pos->erase(end, pos->end());
00281 }
00282 
00290 void RemoveAllIssuedTo(
00292     CPKIFNameAndKeyWithScoreListPtr& pos,
00294     CPKIFNamePtr& prevName)
00295 {
00296     IssuedTo issuedTo;
00297     issuedTo.SetRHS(prevName);
00298     CPKIFNameAndKeyWithScoreList::iterator end;
00299     end = remove_if(pos->begin(), pos->end(), issuedTo);
00300     pos->erase(end, pos->end());
00301 }
00302 
00303 //removed export declarations 8/18/2004
00311 void IgnoreNotIssuedBy(
00313     CPKIFCertificateNodeListWithSourceInfoPtr& pos, 
00315     CPKIFNamePtr& issuerName)
00316 {
00317     IgnoreNotIssuedByOp ignoreNotIssuedBy;
00318     ignoreNotIssuedBy.SetRHS(issuerName);
00319     transform(pos->begin(), pos->end(), pos->begin(), ignoreNotIssuedBy);
00320 }
00328 void IgnoreNotIssuedBy(
00330     CPKIFNameAndKeyWithScoreListPtr& pos, 
00332     CPKIFNamePtr& issuerName)
00333 {
00334     IgnoreNotIssuedByOp ignoreNotIssuedBy;
00335     ignoreNotIssuedBy.SetRHS(issuerName);
00336     transform(pos->begin(), pos->end(), pos->begin(), ignoreNotIssuedBy);
00337 }
00338 //the function name says it all (now also checks signatures, where KIDs miss, and policies)
00348 CPKIFCertificateNodeEntryPtr GetFirstNonIgnoredNodeNotAlreadyInPathIssuedBy(
00350     CPKIFCertificateNodeListWithSourceInfoPtr& pos, 
00352     CPKIFCertificateNodeList& builtPath, 
00354     IPKIFNameAndKey* issuer,
00356     CPKIFPathSettingsPtr& settings)
00357 {
00358     CPKIFCertificateNodeEntryPtr tmp;
00359     if(!builtPath.empty())
00360     {
00361         //if the path is not empty then we must factor the path into our search
00362         //first, set up the predicate object with the path and the issuer
00363         NodeNotInNodeListAndNotIgnoredAndIssuedBy n;
00364         n.SetNodeList(&builtPath);
00365         n.SetPathSettings(settings);
00366         n.SetIssuer(dynamic_cast<IPKIFNameAndKey*>(&(*issuer)));
00367 
00368         //next get iterators that bound the node list
00369         CPKIFCertificateNodeList::iterator pathPos = pos->begin();
00370         CPKIFCertificateNodeList::iterator pathEnd = pos->end();
00371 
00372         //then invoke find_if using the predicate - if the returned value
00373         //is not the end of the node list then return it (i.e. it points
00374         //to the first non-ignored node issued by issuer that isn't in builtPath)
00375         CPKIFCertificateNodeList::iterator retPos = find_if(pathPos, pathEnd, n);
00376         if(retPos != pathEnd)
00377             tmp = *retPos;
00378     }
00379     else if(!pos->empty())
00380     {
00381         CPKIFNamePtr issuerName = issuer->GetSubjectName();
00382 
00383         //if the path is empty and the node list is not empty then we search 
00384         //for the first non-ignored node in the list and return it
00385         CPKIFCertificateNodeList::iterator pathPos = pos->begin();
00386         CPKIFCertificateNodeList::iterator pathEnd = pos->end();
00387         for(pathPos = pos->begin(); pathPos != pathEnd; ++pathPos)
00388         {
00389             if(!(*pathPos)->GetIgnore() && *issuerName == *(*pathPos)->GetCert()->Issuer())
00390             {
00391                 tmp = *pathPos;
00392                 break;
00393             }
00394         }
00395     }
00396 
00397     //return our findings (possibly empty)
00398     return tmp;
00399 }
00409 CPKIFNameAndKeyWithScorePtr GetFirstNonIgnoredNodeNotAlreadyInPathIssuedBy(
00411     CPKIFNameAndKeyWithScoreListPtr& pos, 
00413     CPKIFNameAndKeyWithScoreList& builtPath, 
00415     IPKIFNameAndKeyPtr& issuer,
00417     CPKIFPathSettingsPtr& settings)
00418 {
00419     CPKIFNameAndKeyWithScorePtr tmp;
00420     if(!builtPath.empty())
00421     {
00422         //if the path is not empty then we must factor the path into our search
00423         //first, set up the predicate object with the path and the issuer
00424         NodeNotInNodeListAndNotIgnoredAndIssuedBy n;
00425         n.SetNodeList(&builtPath);
00426         n.SetPathSettings(settings);
00427         n.SetIssuer(dynamic_cast<IPKIFNameAndKey*>(&(*issuer)));
00428 
00429         //next get iterators that bound the node list
00430         CPKIFNameAndKeyWithScoreList::iterator pathPos = pos->begin();
00431         CPKIFNameAndKeyWithScoreList::iterator pathEnd = pos->end();
00432 
00433         //then invoke find_if using the predicate - if the returned value
00434         //is not the end of the node list then return it (i.e. it points
00435         //to the first non-ignored node issued by issuer that isn't in builtPath)
00436         CPKIFNameAndKeyWithScoreList::iterator retPos = find_if(pathPos, pathEnd, n);
00437         if(retPos != pathEnd)
00438             tmp = *retPos;
00439     }
00440     else if(!pos->empty())
00441     {
00442         CPKIFNamePtr issuerName = issuer->GetSubjectName();
00443 
00444         //if the path is empty and the node list is not empty then we search 
00445         //for the first non-ignored node in the list and return it
00446         CPKIFNameAndKeyWithScoreList::iterator pathPos = pos->begin();
00447         CPKIFNameAndKeyWithScoreList::iterator pathEnd = pos->end();
00448         for(pathPos = pos->begin(); pathPos != pathEnd; ++pathPos)
00449         {
00450             if(!(*pathPos)->GetIgnore() && *issuerName == *(*pathPos)->GetNameAndKey()->GetIssuerName())
00451             {
00452                 tmp = *pathPos;
00453                 break;
00454             }
00455         }
00456     }
00457 
00458     //return our findings (possibly empty)
00459     return tmp;
00460 }
00461 
00462 //#ifdef _DEBUG_PATH
00463 #include <iostream>
00464 #include <fstream>
00465 ofstream g_pathTableLogFile;
00473 void DumpTable( 
00475     vector<CPKIFCertificateNodeListWithSourceInfoPtr>& table, const char * title)
00476 {
00477     try
00478     {
00479         if(!g_pathTableLogFile.is_open())
00480         {
00481             g_pathTableLogFile.open("_DEBUG_PATH_TABLE_Log.txt", ios::out);
00482         }
00483 
00484         g_pathTableLogFile << endl << "Dumping table from " << title << endl;
00485 
00486         vector<CPKIFCertificateNodeListWithSourceInfoPtr>::iterator pos;
00487         vector<CPKIFCertificateNodeListWithSourceInfoPtr>::iterator end = table.end();
00488         int rowNum = 0;
00489         for(pos = table.begin(); pos != end; ++pos)
00490         {
00491             g_pathTableLogFile << "Dumping row #" << ++rowNum << endl;
00492             if(!(*pos)->empty())
00493                 g_pathTableLogFile << "Subject: " << (*pos)->front()->GetCert()->Subject()->ToString() << endl;
00494             else
00495                 g_pathTableLogFile << "Subject: EMPTY ROW" << endl;
00496 
00497             CPKIFCertificateNodeListWithSourceInfo::iterator rowPos;
00498             CPKIFCertificateNodeListWithSourceInfo::iterator rowEnd = (*pos)->end();
00499             for(rowPos = (*pos)->begin(); rowPos != rowEnd; ++rowPos)
00500             {
00501                 g_pathTableLogFile << "\t" << (*rowPos)->GetCert()->Issuer()->ToString();
00502                 g_pathTableLogFile << "\t" << (*rowPos)->GetCert()->SerialNumber();
00503                 if((*rowPos)->GetIgnore())
00504                     g_pathTableLogFile << "\t" << "IGNORED" << endl;
00505                 else if((*rowPos)->GetHardIgnore())
00506                     g_pathTableLogFile << "\t" << "HARD IGNORED" << endl;
00507                 else
00508                     g_pathTableLogFile << endl;
00509             }
00510         }
00511     }
00512     catch(CPKIFException& pe)
00513     {
00514         cout << "CPKIFException in DumpTable: " << pe.print() << endl;
00515     }
00516     catch(std::exception& se)
00517     {
00518         cout << "std::exception in DumpTable: " << se.what() << endl;
00519     }
00520     catch(...)
00521     {
00522         cout << "Unknown error in DumpTable" << endl;
00523     }
00524 }
00525 
00526 void anythingGoes(
00528     const CPKIFCertificateNodeEntryPtr& certNode, 
00530     CPKIFPathValidationResults& results,
00532     CertificateType type)
00533 {
00534     CPKIFCertificatePtr curCert = certNode->GetCert();
00535     if(curCert)
00536     {
00537         std::vector<CPKIFX509ExtensionPtr> exts;
00538         CPKIFX509ExtensionMediator2 * mediator = CPKIFX509ExtensionMediator2::GetInstance();
00539         curCert->GetExtensions(mediator, exts);
00540 
00541         std::vector<CPKIFX509ExtensionPtr>::iterator pos;
00542         std::vector<CPKIFX509ExtensionPtr>::iterator end = exts.end();
00543         for(pos = exts.begin(); pos != end; ++pos)
00544         {
00545             certNode->MarkExtensionAsProcessed(*pos);
00546         }
00547     }
00548 }
00549 
00550 CPKIFOIDPtr g_entuOid;
00551 
00552 //#endif
00560 bool PathOK(
00562     CPKIFCertificateNodeList& builtPath, 
00564     IPKIFTrustAnchorPtr& curRoot, 
00566     CPKIFPathSettingsPtr& settings, 
00568     CPKIFPathValidationResults& tmpResults)
00569 {
00570     CPKIFCertificatePath tmpPath;
00571     tmpPath.SetPathSettings(settings);
00572     tmpPath.SetTrustRoot(curRoot);
00573     tmpPath.SetPath(builtPath);
00574     CPKIFFuncStoragePtr pfs(new CPKIFFuncStorage(anythingGoes));
00575     try
00576     {
00577         if(CPKIFPathBasicChecks2::DoChecks(tmpPath, tmpResults, pfs))
00578         {
00579             bool retVal = true;
00580 
00581             //fail on key identifier mismatches when the subject certificate is self-issued
00582             //or when the entrust version ext is present
00583             CPKIFSubjectKeyIdentifierPtr skid = curRoot->GetKeyIdentifier();
00584 
00585             bool prevCertSelfIssued = true;
00586             bool curCertSelfIssued = false;
00587             bool prevHadEntuExt = false;
00588             CPKIFCertificatePtr curCert;
00589             CPKIFCertificateNodeList::iterator pos;
00590             CPKIFCertificateNodeList::iterator end = builtPath.end();
00591             for(pos = builtPath.begin(); pos != end; ++pos)
00592             {
00593                 curCert = (*pos)->GetCert();
00594 
00595                 if(skid)
00596                 {
00597                     if(!g_entuOid)
00598                     {
00599                         CPKIFOIDPtr entuOid(new CPKIFOID(CPKIFStringPtr(new std::string("1.2.840.113533.7.65.0"))));
00600                         g_entuOid = entuOid;
00601                     }
00602 
00603                     CPKIFAuthorityKeyIdentifierPtr akid = curCert->GetExtension<CPKIFAuthorityKeyIdentifier>();
00604                     CPKIFX509ExtensionPtr entuExt;
00605                     curCert->GetExtensionByOID(*g_entuOid, entuExt);
00606                     curCertSelfIssued = curCert->IsSelfIssued();
00607                     if(akid  && akid->KeyIDPresent() && (prevHadEntuExt || prevCertSelfIssued || curCertSelfIssued))
00608                     {
00609                         CPKIFBufferPtr akidKeyID = akid->KeyIdentifier();
00610                         CPKIFBufferPtr skidKeyID = skid->KeyIdentifier();
00611                         if(akidKeyID != (CPKIFBuffer*)NULL && skidKeyID != (CPKIFBuffer*)NULL)
00612                         {
00613                             if(!(*akidKeyID == *skidKeyID))
00614                                 retVal = false;
00615                         }
00616                     }
00617                     if(entuExt)
00618                         prevHadEntuExt = true;
00619                     else
00620                         prevHadEntuExt = false;
00621                 }
00622 
00623                 skid = curCert->GetExtension<CPKIFSubjectKeyIdentifier>();
00624                 prevCertSelfIssued = curCertSelfIssued;
00625             }
00626 
00627             return retVal;
00628         }
00629         else
00630             return false;
00631     }
00632     catch(CPKIFException&)
00633     {
00634         return false;
00635     }
00636 }
00637 

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