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
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
00069
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
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;
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
00132
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
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
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;
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;
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
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
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
00362
00363 NodeNotInNodeListAndNotIgnoredAndIssuedBy n;
00364 n.SetNodeList(&builtPath);
00365 n.SetPathSettings(settings);
00366 n.SetIssuer(dynamic_cast<IPKIFNameAndKey*>(&(*issuer)));
00367
00368
00369 CPKIFCertificateNodeList::iterator pathPos = pos->begin();
00370 CPKIFCertificateNodeList::iterator pathEnd = pos->end();
00371
00372
00373
00374
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
00384
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
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
00423
00424 NodeNotInNodeListAndNotIgnoredAndIssuedBy n;
00425 n.SetNodeList(&builtPath);
00426 n.SetPathSettings(settings);
00427 n.SetIssuer(dynamic_cast<IPKIFNameAndKey*>(&(*issuer)));
00428
00429
00430 CPKIFNameAndKeyWithScoreList::iterator pathPos = pos->begin();
00431 CPKIFNameAndKeyWithScoreList::iterator pathEnd = pos->end();
00432
00433
00434
00435
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
00445
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
00459 return tmp;
00460 }
00461
00462
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
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
00582
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