00001
00010 #include "ASN1Helper.h"
00011 #include "BasicChecksUtils.h"
00012 #include "BasicConstraints.h"
00013 #include "BuilderStatistics.h"
00014 #include "BuilderUtils.h"
00015 #include "Certificate.h"
00016 #include "GottaMatch.h"
00017 #include "Name.h"
00018 #include "PathResults.h"
00019 #include "IPKIFCertRepository.h"
00020 #include "IPKIFCertRepositoryUpdate.h"
00021 #include "IPKIFTrustCache.h"
00022 #include "IPKIFCRLRepository.h"
00023 #include "IPKIFNameAndKey.h"
00024 #include "IPKIFSupportsSynonymousSources.h"
00025 #include "IssuedBy.h"
00026 #include "NodeInNodeList.h"
00027 #include "PKIFCertificateNodeEntry.h"
00028 #include "PKIFCertificatePath.h"
00029 #include "PKIFCertStatus.h"
00030 #include "PKIFErrors.h"
00031 #include "PKIFMediators.h"
00032 #include "PKIFNameAndKeyWithScore.h"
00033 #include "PKIFPathException.h"
00034 #include "PKIFPathLogger.h"
00035 #include "PKIFPathSettings.h"
00036 #include "PKIFReversiblePathBuilder.h"
00037 #include "PKIFReversePathState.h"
00038 #include "PKIFTrustRoot.h"
00039 #include "PKIX1Explicit88.h"
00040 #include "ToolkitUtils.h"
00041 #include <sstream>
00042 #include "PKIFDefaultScoring.h"
00043
00044 #include "boost/numeric/conversion/cast.hpp"
00045
00046 using boost::numeric_cast;
00047 using boost::bad_numeric_cast;
00048
00049
00050 #include <iterator>
00051
00052 using namespace std;
00053 using namespace boost;
00054
00063 void RemoveNotIssuedTo(CPKIFNamePtr& name, CPKIFCertificateNodeList& certList)
00064 {
00065 NotIssuedTo notIssuedTo;
00066 notIssuedTo.SetRHS(name);
00067 CPKIFCertificateNodeList::iterator end;
00068 end = remove_if(certList.begin(), certList.end(), notIssuedTo);
00069 certList.erase(end, certList.end());
00070 }
00079 void RemoveNotIssuedBy(CPKIFNamePtr& name, CPKIFCertificateNodeList& certList)
00080 {
00081 NotIssuedBy notIssuedBy;
00082 notIssuedBy.SetRHS(name);
00083 CPKIFCertificateNodeList::iterator end;
00084 end = remove_if(certList.begin(), certList.end(), notIssuedBy);
00085 certList.erase(end, certList.end());
00086 }
00087
00088
00089 bool RDNsMatch(
00091 CACX509V3RelativeDistinguishedName* lhs,
00093 CACX509V3RelativeDistinguishedName* rhs);
00094
00095
00102 class NameAndKeyNodeMatch
00103 {
00104 public:
00105 bool operator()(const CPKIFNameAndKeyWithScorePtr& t);
00106
00114 void SetRHS(const IPKIFNameAndKeyPtr& rhs) {m_rhs = rhs;}
00115 private:
00116 IPKIFNameAndKeyPtr m_rhs;
00117 };
00118
00127 bool NameAndKeyNodeMatch::operator()(const CPKIFNameAndKeyWithScorePtr& t)
00128 {
00129 return *t == *m_rhs;
00130 }
00131
00132 #define NAME_MATCHES_TARGET_ISSUER 5000
00133 #define ISSUED_BY_TRUST_ROOT 5000
00134 #define ISSUED_BY_CERT_IN_CACHE 500
00135 #define BASIC_CONSTRAINTS_PRESENT_AND_SET 75
00136 #define VAL_PERIOD_OK 75
00137 #define ALGS_MATCH 100
00138 #define KEY_IDS_MATCH 6000
00139 #define NOT_SELF_ISSUED 50
00140 #define NOT_SELF_SIGNED 50
00141
00142
00143 #define HAS_AT_ONE_POLICY 25
00144 #define MATCH_POLICY_WITH_PREV_CERT 25
00145 #define MATCH_POLICY_WITH_SETTINGS 25
00146
00155 bool scoreCompare(
00157 const CPKIFNameAndKeyWithScorePtr& lhs,
00159 const CPKIFNameAndKeyWithScorePtr& rhs)
00160 {
00161 LOG_STRING_DEBUG("scoreCompare(const CPKIFCertificateNodeEntryPtr& lhs, const CPKIFCertificateNodeEntryPtr& rhs)", TOOLKIT_PATH_MISC, 0, NULL);
00162
00163 int rhsScore = rhs->GetScore();
00164 int lhsScore = lhs->GetScore();
00165 return lhsScore > rhsScore;
00166 }
00167
00176 int GetNumMatchingRdns(CPKIFNamePtr& name1, CPKIFNamePtr& name2)
00177 {
00178 CACASNWRAPPER_CREATE(CACX509V3Name, objPDU1);
00179 CPKIFBufferPtr name1Buf = name1->rawName();
00180 objPDU1.Decode(name1Buf->GetBuffer(), name1Buf->GetLength());
00181
00182 CACASNWRAPPER_CREATE(CACX509V3Name, objPDU2);
00183 CPKIFBufferPtr name2Buf = name2->rawName();
00184 objPDU2.Decode(name2Buf->GetBuffer(), name2Buf->GetLength());
00185
00186
00187 DListNode* curLHS = objPDU1->u.rdnSequence->head;
00188 DListNode* curRHS = objPDU2->u.rdnSequence->head;
00189 unsigned int max = 0;
00190 if(objPDU1->u.rdnSequence->count > objPDU2->u.rdnSequence->count)
00191 max = objPDU2->u.rdnSequence->count;
00192 else
00193 max = objPDU1->u.rdnSequence->count;
00194
00195 for(unsigned int ii = 0; ii < max; ++ii)
00196 {
00197
00198 ASN1OpenType* lhsP = (ASN1OpenType*)curLHS->data;
00199 ASN1OpenType* rhsP = (ASN1OpenType*)curRHS->data;
00200 if(lhsP->numocts != rhsP->numocts || 0 != memcmp(lhsP->data, rhsP->data, rhsP->numocts))
00201 {
00202
00203 CACASNWRAPPER_CREATE(CACX509V3RelativeDistinguishedName, tmpPDULHS);
00204 CACX509V3RelativeDistinguishedName* lhs = tmpPDULHS.Decode(*lhsP);
00205
00206 CACASNWRAPPER_CREATE(CACX509V3RelativeDistinguishedName, tmpPDURHS);
00207 CACX509V3RelativeDistinguishedName* rhs = tmpPDURHS.Decode(*rhsP);
00208
00209 if(!RDNsMatch(lhs, rhs))
00210 return ii;
00211 }
00212 curLHS = curLHS->next;
00213 curRHS = curRHS->next;
00214 }
00215 return max;
00216 }
00217
00227 void ScoreAndSortNodes(
00229 CPKIFNameAndKeyWithScoreListPtr& listToSort,
00231 CPKIFCertificatePtr& targetCert,
00233 IPKIFNameAndKeyPtr& issuerNameAndKey,
00235 CPKIFPathSettingsPtr& settings,
00237 bool toToSortContainsTrustAnchors)
00238 {
00239 CPKIFNamePtr targetIssuerName = targetCert->Issuer();
00240 CPKIFPolicyInformationListPtr initPolSet;
00241 settings->GetInitialPolicySet(initPolSet);
00242
00243 CPKIFNamePtr curCertIssuerName;
00244 if(issuerNameAndKey != (IPKIFNameAndKey*)NULL)
00245 curCertIssuerName = issuerNameAndKey->GetSubjectName();
00246
00247 CPKIFNameAndKeyWithScoreList::iterator pos;
00248 CPKIFNameAndKeyWithScoreList::iterator end = listToSort->end();
00249 for(pos = listToSort->begin(); pos != end; ++pos)
00250 {
00251 (*pos)->ClearScore();
00252 IPKIFNameAndKeyPtr curNameAndKey = (*pos)->GetNameAndKey();
00253
00254
00255 if(*targetIssuerName == *curNameAndKey->GetSubjectName())
00256 (*pos)->AddToScore(NAME_MATCHES_TARGET_ISSUER);
00257
00258
00259 CPKIFNamePtr tmpName = curNameAndKey->GetSubjectName();
00260 int namePoints = 1000 * GetNumMatchingRdns(targetIssuerName, tmpName);
00261 (*pos)->AddToScore(namePoints);
00262
00263 if(curCertIssuerName != (CPKIFName*)NULL && !(*curCertIssuerName == *curNameAndKey->GetIssuerName()))
00264 {
00265 (*pos)->ClearScore();
00266 continue;
00267 }
00268
00269
00270 CPKIFCertificatePtr curCert = dynamic_pointer_cast<CPKIFCertificate, IPKIFNameAndKey>(curNameAndKey);
00271 if(curCert != (CPKIFCertificate*)NULL)
00272 {
00273 CPKIFBasicConstraintsPtr basicConstraints = curCert->GetExtension<CPKIFBasicConstraints>();
00274 bool isCA = false;
00275 if(basicConstraints != (CPKIFBasicConstraints*)NULL)
00276 {
00277 if(basicConstraints->isCA())
00278 (*pos)->AddToScore(BASIC_CONSTRAINTS_PRESENT_AND_SET);
00279 else
00280 {
00281 (*pos)->ClearScore();
00282 continue;
00283 }
00284 }
00285
00286
00287 }
00288 }
00289
00290 sort(listToSort->begin(), listToSort->end(), scoreCompare);
00291
00292 #ifdef _DEBUG
00293 IPKIFNameAndKeyPtr frontNK = listToSort->front()->GetNameAndKey();
00294 int score = listToSort->front()->GetScore();
00295 CPKIFNamePtr frontNKName = frontNK->GetSubjectName();
00296 const char* frontNKNameStr = frontNKName->ToString();
00297 #endif
00298 }
00299
00301 struct CPKIFReversiblePathBuilderImpl
00302 {
00303 PathBuildingDirection m_pbd;
00304 CPKIFReversiblePathBuilder *m_parent;
00305 std::vector<CPKIFNameAndKeyWithScoreList> m_previouslyTriedPaths;
00306 bool TriedBefore(CPKIFNameAndKeyWithScoreList& builtPathNK);
00307
00308
00309 bool BuildOrGrowTable(CPKIFReversePathStatePtr& reverseState);
00310
00311
00312 bool CheckAlternatives(CPKIFCertificatePath& path, CPKIFReversePathStatePtr& reverseState);
00313
00314
00315 void PuntTopRow(CPKIFReversePathStatePtr& reverseState);
00316
00317 bool GrowRows(CPKIFReversePathStatePtr& reverseState);
00318
00319
00320 void RemoveLoopMakers(CPKIFCertificateNodeList& certList, CPKIFReversePathStatePtr& reverseState);
00321
00322 void PrepareState_Forward(CPKIFReversePathStatePtr& reverseState, CPKIFCertificatePath& path);
00323 void PrepareState_Reverse(CPKIFReversePathStatePtr& reverseState, CPKIFCertificatePath& path);
00324 void CreateState(CPKIFCertificatePath& path, PathBuildingDirection pbd);
00325 void CheckInputs(CPKIFCertificatePath& path);
00326 bool TargetIsTrustAnchor(CPKIFCertificatePtr& cert);
00327 IPKIFNameAndKeyPtr GetCurrentCert(CPKIFReversePathStatePtr& reverseState);
00328
00329 void GetCerts(CPKIFCertificateSourceListPtr& curSourceList, CPKIFCertificateNodeList& certNodeList, CPKIFReversePathStatePtr& reverseState);
00330 void SortAndSaveLists(CPKIFReversePathStatePtr& reverseState, CPKIFNameAndKeyWithScoreListPtr& newList, CPKIFCertificateSourceListPtr& sources);
00331 void RemoveExtraneous(CPKIFCertificateNodeList& certList, CPKIFReversePathStatePtr& reverseState);
00332 };
00333
00341 void CPKIFReversiblePathBuilderImpl::SortAndSaveLists(CPKIFReversePathStatePtr& reverseState,
00342 CPKIFNameAndKeyWithScoreListPtr& newList, CPKIFCertificateSourceListPtr& sources)
00343 {
00344
00345
00346
00347 if(newList->empty())
00348 {
00349 CPKIFCertificateNodeList certNodeList;
00350 GetCerts(sources, certNodeList, reverseState);
00351
00352
00353 RemoveLoopMakers(certNodeList, reverseState);
00354 RemoveExtraneous(certNodeList, reverseState);
00355
00356 if(!certNodeList.empty())
00357 {
00358
00359
00360
00361 CPKIFCertificateNodeList::iterator cnlPos;
00362 CPKIFCertificateNodeList::iterator cnlEnd = certNodeList.end();
00363 for(cnlPos = certNodeList.begin(); cnlPos != cnlEnd; ++cnlPos)
00364 {
00365 IPKIFNameAndKeyPtr cnlCertAsNameAndKey = dynamic_pointer_cast<IPKIFNameAndKey, CPKIFCertificate>((*cnlPos)->GetCert());
00366 CPKIFNameAndKeyWithScorePtr newNode(new CPKIFNameAndKeyWithScore(cnlCertAsNameAndKey));
00367 newList->push_back(newNode);
00368 }
00369 }
00370 }
00371
00372
00373 if(newList->empty())
00374 return;
00375
00376 if(PBD_FORWARD == reverseState->m_direction)
00377 {
00378
00379
00380 IPKIFTrustCache* iTrust = m_parent->GetMediatorFromParent<IPKIFTrustCache>();
00381 IPKIFCertRepository* iCert = m_parent->GetMediatorFromParent<IPKIFCertRepository>();
00382 IPKIFNameAndKeyPtr curCertAsNameAndKey = GetCurrentCert(reverseState);
00383 CPKIFCertificatePtr curCert = dynamic_pointer_cast<CPKIFCertificate, IPKIFNameAndKey>(curCertAsNameAndKey);
00384
00385 CPKIFDefaultScoring s;
00386 int nCAsBelow = 0;
00387 try {
00388 nCAsBelow = boost::numeric_cast<int,size_t>(reverseState->m_table.size() - 1);
00389 }catch(std::exception &e){
00390 RAISE_PATH_EXCEPTION(e.what(), m_parent->thisComponent, COMMON_INVALID_INPUT, this)
00391 }
00392 s.ScoreAndSortNodes(newList, curCert, reverseState->m_pathSettings, iTrust, nCAsBelow ,iCert);
00393
00394 reverseState->m_table.push_back(newList);
00395 reverseState->m_sourceTable.push_back(sources);
00396
00397 #ifdef _DEBUG
00398 vector<string> v;
00399 vector<CPKIFNameAndKeyWithScoreListPtr>::iterator zzzpos;
00400 vector<CPKIFNameAndKeyWithScoreListPtr>::iterator zzzend = reverseState->m_table.end();
00401 for(zzzpos = reverseState->m_table.begin(); zzzpos != zzzend; ++zzzpos)
00402 {
00403 v.push_back((*zzzpos)->front()->GetNameAndKey()->GetSubjectName()->ToString());
00404 v.push_back((*zzzpos)->front()->GetNameAndKey()->GetIssuerName()->ToString());
00405 }
00406 #endif
00407 }
00408 else
00409 {
00410
00411
00412 reverseState->m_table.insert(reverseState->m_table.begin(), newList);
00413 reverseState->m_sourceTable.insert(reverseState->m_sourceTable.begin(), sources);
00414 }
00415 }
00416
00425 bool CPKIFReversiblePathBuilderImpl::TargetIsTrustAnchor(CPKIFCertificatePtr& cert)
00426 {
00427 IPKIFTrustCache* iTrust = m_parent->GetMediatorFromParent<IPKIFTrustCache>();
00428
00429 IPKIFTrustAnchorList tmpRootList;
00430 iTrust->GetTrustRoots(cert->GetSubjectName(), tmpRootList);
00431 if(!tmpRootList.empty())
00432 {
00433
00434 IPKIFTrustAnchorList::iterator rootPos;
00435 IPKIFTrustAnchorList::iterator rootEnd = tmpRootList.end();
00436 for(rootPos = tmpRootList.begin(); rootPos != rootEnd; ++rootPos)
00437 {
00438 IPKIFNameAndKeyPtr taNameAndKey = dynamic_pointer_cast<IPKIFNameAndKey, IPKIFTrustAnchor>(*rootPos);
00439 IPKIFNameAndKeyPtr certNameAndKey = dynamic_pointer_cast<IPKIFNameAndKey, CPKIFCertificate>(cert);
00440 if(*certNameAndKey == *taNameAndKey)
00441 return true;
00442 }
00443 }
00444
00445 return false;
00446 }
00447
00456 void CPKIFReversiblePathBuilderImpl::PrepareState_Forward(CPKIFReversePathStatePtr& reverseState, CPKIFCertificatePath& path)
00457 {
00458 reverseState->m_direction = PBD_FORWARD;
00459
00460 IPKIFNameAndKeyPtr targetCertAsNameAndKey;
00461 CPKIFCertificatePtr targetCert;
00462 path.GetTarget(targetCert);
00463 targetCertAsNameAndKey = dynamic_pointer_cast<IPKIFNameAndKey, CPKIFCertificate>(targetCert);
00464
00465 reverseState->m_targetCert = targetCert;
00466 reverseState->m_targetCertAsNameAndKey = targetCertAsNameAndKey;
00467
00468 CPKIFCertificateSourceListPtr emptySourceList(new CPKIFCertificateSourceList);
00469 CPKIFNameAndKeyWithScoreListPtr newList(new CPKIFNameAndKeyWithScoreList);
00470 CPKIFNameAndKeyWithScorePtr newNode(new CPKIFNameAndKeyWithScore(reverseState->m_targetCertAsNameAndKey));
00471 newList->push_back(newNode);
00472
00473 reverseState->m_table.push_back(newList);
00474 reverseState->m_sourceTable.push_back(emptySourceList);
00475
00476 #ifdef _DEBUG
00477 vector<string> v;
00478 vector<CPKIFNameAndKeyWithScoreListPtr>::iterator zzzpos;
00479 vector<CPKIFNameAndKeyWithScoreListPtr>::iterator zzzend = reverseState->m_table.end();
00480 for(zzzpos = reverseState->m_table.begin(); zzzpos != zzzend; ++zzzpos)
00481 {
00482 v.push_back((*zzzpos)->front()->GetNameAndKey()->GetSubjectName()->ToString());
00483 v.push_back((*zzzpos)->front()->GetNameAndKey()->GetIssuerName()->ToString());
00484 }
00485 #endif
00486 }
00487
00496 void CPKIFReversiblePathBuilderImpl::PrepareState_Reverse(CPKIFReversePathStatePtr& reverseState, CPKIFCertificatePath& path)
00497 {
00498 reverseState->m_direction = PBD_REVERSE;
00499
00500
00501 IPKIFNameAndKeyPtr targetCertAsNameAndKey;
00502 CPKIFCertificatePtr targetCert;
00503 path.GetTarget(targetCert);
00504 targetCertAsNameAndKey = dynamic_pointer_cast<IPKIFNameAndKey, CPKIFCertificate>(targetCert);
00505
00506 reverseState->m_targetCert = targetCert;
00507 reverseState->m_targetCertAsNameAndKey = targetCertAsNameAndKey;
00508
00509
00510 CPKIFNamePtr emptyName;
00511 IPKIFTrustAnchorList tl;
00512 IPKIFTrustCache* iTrust = m_parent->GetMediatorFromParent<IPKIFTrustCache>();
00513 iTrust->GetTrustRoots(emptyName, tl);
00514
00515
00516
00517 CPKIFNameAndKeyWithScoreListPtr scoreList(new CPKIFNameAndKeyWithScoreList);
00518
00519 IPKIFTrustAnchorList::iterator pos;
00520 IPKIFTrustAnchorList::iterator end = tl.end();
00521 for(pos = tl.begin(); pos != end; ++pos)
00522 {
00523 IPKIFNameAndKeyPtr curTA = dynamic_pointer_cast<IPKIFNameAndKey, IPKIFTrustAnchor>(*pos);
00524
00525 CPKIFNameAndKeyWithScorePtr tmp(new CPKIFNameAndKeyWithScore(curTA));
00526 scoreList->push_back(tmp);
00527 }
00528
00529 IPKIFNameAndKeyPtr emptyNameAndKey;
00530 ScoreAndSortNodes(scoreList, targetCert, emptyNameAndKey, reverseState->m_pathSettings, true);
00531
00532
00533 CPKIFCertificateSourceListPtr sourceList(new CPKIFCertificateSourceList);
00534
00535 reverseState->m_table.push_back(scoreList);
00536 reverseState->m_sourceTable.push_back(sourceList);
00537 }
00538
00547 void CPKIFReversiblePathBuilderImpl::CreateState(CPKIFCertificatePath& path, PathBuildingDirection pbd)
00548 {
00549
00550 CPKIFReversePathStatePtr reverseState(new CPKIFReversePathState);
00551
00552 reverseState->m_sources = LOCAL;
00553 reverseState->m_bTableIsComplete = false;
00554 reverseState->m_bBuildStarted = false;
00555
00556
00557 CPKIFBuilderStatisticsPtr bs(new CPKIFBuilderStatistics);
00558 path.SetBuilderStats(bs);
00559
00560
00561 CPKIFCertificatePathStatePtr tmpState(reverseState);
00562 path.SetState(tmpState);
00563
00564 path.GetPathSettings(reverseState->m_pathSettings);
00565
00566 if(PBD_FORWARD == pbd)
00567 PrepareState_Forward(reverseState, path);
00568 else
00569 PrepareState_Reverse(reverseState, path);
00570 }
00571
00572
00582 void CPKIFReversiblePathBuilderImpl::CheckInputs(CPKIFCertificatePath& path)
00583 {
00584 LOG_STRING_DEBUG("CPKIFReversiblePathBuilder::CreateInputs(CPKIFCertificatePath& path)", m_parent->thisComponent, 0, this);
00585
00586
00587 IPKIFTrustCache* iTrust = m_parent->GetMediatorFromParent<IPKIFTrustCache>();
00588 if(NULL == iTrust)
00589 RAISE_PATH_EXCEPTION("IPKIFTrustCache interface not available.", m_parent->thisComponent, COMMON_MEDIATOR_MISSING, this)
00590
00591 IPKIFCertRepository* iCert = m_parent->GetMediatorFromParent<IPKIFCertRepository>();
00592 if(NULL == iCert)
00593 RAISE_PATH_EXCEPTION("IPKIFCertRepository interface not available.", m_parent->thisComponent, COMMON_MEDIATOR_MISSING, this)
00594
00595
00596 CPKIFPathSettingsPtr settings;
00597 path.GetPathSettings(settings);
00598 if(settings == (CPKIFPathSettings*)NULL)
00599 RAISE_PATH_EXCEPTION("Path parameter contained NULL path settings.", m_parent->thisComponent, COMMON_INVALID_INPUT, this)
00600
00601 CPKIFCertificatePtr curCert;
00602 path.GetTarget(curCert);
00603 if(curCert == (CPKIFCertificate*)NULL)
00604 RAISE_PATH_EXCEPTION("The path parameter did not specify a target certificate.", m_parent->thisComponent, COMMON_INVALID_INPUT, this)
00605 }
00606
00614 size_t GetTableSize(vector<CPKIFNameAndKeyWithScoreListPtr>& v)
00615 {
00616 size_t rowSum = 0;
00617 vector<CPKIFNameAndKeyWithScoreListPtr>::iterator pos;
00618 vector<CPKIFNameAndKeyWithScoreListPtr>::iterator end = v.end();
00619 for(pos = v.begin(); pos != end; ++pos)
00620 rowSum += (*pos)->size();
00621
00622 return rowSum;
00623 }
00624
00633 void CPKIFReversiblePathBuilderImpl::GetCerts(CPKIFCertificateSourceListPtr& curSourceList, CPKIFCertificateNodeList& certNodeList, CPKIFReversePathStatePtr& reverseState)
00634 {
00635 do
00636 {
00637
00638 CPKIFCertificateSourcePtr curSource = curSourceList->back();
00639 curSourceList->pop_back();
00640
00641
00642 curSource->GetCertificates(certNodeList, reverseState->m_direction);
00643
00644
00645 }while(certNodeList.empty() && !curSourceList->empty());
00646
00647 #ifdef _DEBUG
00648 vector<string> v;
00649 CPKIFCertificateNodeList::iterator pos;
00650 CPKIFCertificateNodeList::iterator end = certNodeList.end();
00651 for(pos = certNodeList.begin(); pos != end; ++pos)
00652 {
00653 v.push_back((*pos)->GetCert()->Subject()->ToString());
00654 v.push_back((*pos)->GetCert()->Issuer()->ToString());
00655 }
00656 #endif
00657 }
00658
00667 bool CPKIFReversiblePathBuilderImpl::GrowRows(CPKIFReversePathStatePtr& reverseState)
00668 {
00669 bool rv = false;
00670 int numRows = 0;
00671 try
00672 {
00673 numRows = numeric_cast<int>(reverseState->m_table.size());
00674 }
00675 catch(bad_numeric_cast &)
00676 {
00677 throw CPKIFException(TOOLKIT_PATH, COMMON_INVALID_INPUT, "Table size is an impossibly long number.");
00678 }
00679
00680 assert((reverseState->m_table.empty() &&reverseState->m_sourceTable.empty()) || (reverseState->m_table.size() == reverseState->m_sourceTable.size()));
00681
00682 int ii = PBD_FORWARD == reverseState->m_direction? numRows-2 : 0;
00683 int terminator = PBD_FORWARD == reverseState->m_direction? 0 : numRows-2;
00684 if(ii < 0 || terminator < 0)
00685 {
00686 ii = 0; terminator = 0 ;
00687 }
00688 for(; (PBD_FORWARD == reverseState->m_direction && ii >= terminator) || (PBD_REVERSE == reverseState->m_direction && ii <= terminator);
00689 PBD_FORWARD == reverseState->m_direction? --ii : ++ii)
00690 {
00691 CPKIFNameAndKeyWithScoreListPtr curNameAndKeyList = reverseState->m_table[ii];
00692 CPKIFCertificateSourceListPtr curSourceList = reverseState->m_sourceTable[ii];
00693 if(curSourceList == (CPKIFCertificateSourceList*)NULL || curSourceList->empty())
00694 continue;
00695
00696 CPKIFCertificateNodeList certNodeList;
00697 GetCerts(curSourceList, certNodeList, reverseState);
00698
00699
00700 RemoveLoopMakers(certNodeList, reverseState);
00701 RemoveExtraneous(certNodeList, reverseState);
00702
00703 if(!certNodeList.empty())
00704 {
00705
00706
00707
00708 CPKIFCertificateNodeList::iterator cnlPos;
00709 CPKIFCertificateNodeList::iterator cnlEnd = certNodeList.end();
00710 for(cnlPos = certNodeList.begin(); cnlPos != cnlEnd; ++cnlPos)
00711 {
00712 IPKIFNameAndKeyPtr cnlCertAsNameAndKey = dynamic_pointer_cast<IPKIFNameAndKey, CPKIFCertificate>((*cnlPos)->GetCert());
00713 CPKIFNameAndKeyWithScorePtr newNode(new CPKIFNameAndKeyWithScore(cnlCertAsNameAndKey));
00714 GottaMatch<CPKIFNameAndKeyWithScorePtr> gm;
00715 gm.SetRHS(newNode);
00716 if(curNameAndKeyList->end() == find_if(curNameAndKeyList->begin(), curNameAndKeyList->end(), gm))
00717 {
00718 curNameAndKeyList->push_back(newNode);
00719 rv = true;
00720 }
00721 }
00722 }
00723
00724 if(curSourceList->empty() && curNameAndKeyList->empty())
00725 {
00726 CPKIFCertificateSourceListPtr emptyList;
00727 reverseState->m_sourceTable[ii] = emptyList;
00728 }
00729 }
00730
00731 return rv;
00732 }
00733
00742 void CPKIFReversiblePathBuilderImpl::PuntTopRow(
00744 CPKIFReversePathStatePtr& reverseState)
00745
00746 {
00747 #ifdef _DEBUG
00748 vector<string> v;
00749 vector<CPKIFNameAndKeyWithScoreListPtr>::iterator zzzpos;
00750 vector<CPKIFNameAndKeyWithScoreListPtr>::iterator zzzend = reverseState->m_table.end();
00751 for(zzzpos = reverseState->m_table.begin(); zzzpos != zzzend; ++zzzpos)
00752 {
00753 v.push_back((*zzzpos)->front()->GetNameAndKey()->GetSubjectName()->ToString());
00754 v.push_back((*zzzpos)->front()->GetNameAndKey()->GetIssuerName()->ToString());
00755 }
00756 #endif
00757
00758 CPKIFNamePtr nameOfIssuerToDiscard;
00759
00760
00761
00762 IPKIFNameAndKeyPtr preGrowCur = GetCurrentCert(reverseState);
00763
00764 bool bAddedNewStuff = GrowRows(reverseState);
00765
00766 IPKIFNameAndKeyPtr postGrowCur = GetCurrentCert(reverseState);
00767 if((preGrowCur == (IPKIFNameAndKey*)NULL && postGrowCur != (IPKIFNameAndKey*)NULL) ||
00768 ((preGrowCur != (IPKIFNameAndKey*)NULL && postGrowCur != (IPKIFNameAndKey*)NULL) && !(*preGrowCur == *postGrowCur)))
00769 return;
00770
00771 if(PBD_FORWARD == reverseState->m_direction)
00772 {
00773 int size = 0;
00774 try
00775 {
00776 size = numeric_cast<int>(reverseState->m_table.size());
00777 }
00778 catch(bad_numeric_cast &)
00779 {
00780 throw CPKIFException(TOOLKIT_PATH, COMMON_INVALID_INPUT, "Table size is an impossibly long number.");
00781 }
00782
00783
00784 vector<CPKIFNameAndKeyWithScoreListPtr>::reverse_iterator pos = reverseState->m_table.rbegin();
00785 vector<CPKIFNameAndKeyWithScoreListPtr>::reverse_iterator end = reverseState->m_table.rend();
00786 for(int ii = size - 1; pos != end - 1; ++pos, --ii)
00787 {
00788 if((*pos)->empty())
00789 continue;
00790
00791
00792 if(nameOfIssuerToDiscard == (CPKIFName*)NULL)
00793 nameOfIssuerToDiscard = (*pos)->front()->GetNameAndKey()->GetIssuerName();
00794
00795 CPKIFNamePtr tmpName = (*pos)->front()->GetNameAndKey()->GetSubjectName();
00796
00797 #ifdef _DEBUG
00798 const char* curCertIssuerString = nameOfIssuerToDiscard->ToString();
00799 const char* curCertSubjectString = tmpName->ToString();
00800 size_t size = (*pos)->size();
00801 #endif
00802
00803 RemoveAllIssuedBy(*pos, nameOfIssuerToDiscard);
00804
00805 #ifdef _DEBUG
00806 size = (*pos)->size();
00807 #endif
00808
00809
00810
00811
00812 nameOfIssuerToDiscard = tmpName;
00813
00814
00815 if(!(*pos)->empty())
00816 break;
00817 else
00818 {
00819 CPKIFCertificateSourceListPtr emptySourceList;
00820 reverseState->m_sourceTable[ii] = emptySourceList;
00821 reverseState->m_bTableIsComplete = false;
00822 }
00823 }
00824 }
00825 else
00826 {
00827 vector<CPKIFNameAndKeyWithScoreListPtr>::iterator pos = reverseState->m_table.begin();
00828 vector<CPKIFNameAndKeyWithScoreListPtr>::iterator end = reverseState->m_table.end();
00829 if(reverseState->m_bTableIsComplete)
00830 {
00831 (*pos)->clear();
00832 ++pos;
00833 }
00834
00835 int distanceLen = 0;
00836 try
00837 {
00838 distanceLen = numeric_cast<int>(distance(reverseState->m_table.begin(), pos));
00839 }
00840 catch(bad_numeric_cast &)
00841 {
00842 throw CPKIFException(TOOLKIT_PATH, COMMON_INVALID_INPUT, "Distance is an impossibly long number.");
00843 }
00844
00845
00846 for(int ii = distanceLen; pos != end; ++pos, ++ii)
00847 {
00848 if((*pos)->empty())
00849 continue;
00850
00851
00852 if(nameOfIssuerToDiscard == (CPKIFName*)NULL && pos != reverseState->m_table.begin())
00853 nameOfIssuerToDiscard = (*pos)->front()->GetNameAndKey()->GetSubjectName();
00854 else if(nameOfIssuerToDiscard == (CPKIFName*)NULL)
00855 nameOfIssuerToDiscard = (*pos)->front()->GetNameAndKey()->GetIssuerName();
00856
00857 CPKIFNamePtr tmpName = (*pos)->front()->GetNameAndKey()->GetIssuerName();
00858
00859 #ifdef _DEBUG
00860 const char* curCertIssuerString = nameOfIssuerToDiscard->ToString();
00861 const char* curCertSubjectString = tmpName->ToString();
00862 size_t size = (*pos)->size();
00863 #endif
00864
00865 if(pos != reverseState->m_table.begin())
00866 RemoveAllIssuedTo(*pos, nameOfIssuerToDiscard);
00867 else
00868 RemoveAllIssuedBy(*pos, nameOfIssuerToDiscard);
00869
00870 #ifdef _DEBUG
00871 size = (*pos)->size();
00872 #endif
00873
00874
00875
00876
00877 nameOfIssuerToDiscard = tmpName;
00878
00879
00880 if(!(*pos)->empty())
00881 break;
00882 else
00883 {
00884 CPKIFCertificateSourceListPtr nullSourceList;
00885 reverseState->m_sourceTable[ii] = nullSourceList;
00886 reverseState->m_bTableIsComplete = false;
00887 }
00888 }
00889 }
00890
00891
00892 {
00893 vector<CPKIFNameAndKeyWithScoreListPtr>::iterator nkPos;
00894 vector<CPKIFNameAndKeyWithScoreListPtr>::iterator nkEnd = reverseState->m_table.end();
00895 int ii = 0;
00896 CPKIFCertificateSourceListPtr nullSourceList;
00897 for(nkPos = reverseState->m_table.begin(); nkPos != nkEnd; ++nkPos, ++ii)
00898 {
00899 if((*nkPos)->empty())
00900 reverseState->m_sourceTable[ii] = nullSourceList;
00901 }
00902 }
00903
00904
00905 vector<CPKIFNameAndKeyWithScoreListPtr>::iterator newEnd = remove_if(reverseState->m_table.begin(), reverseState->m_table.end(), IsEmptyNameAndKey);
00906 reverseState->m_table.erase(newEnd, reverseState->m_table.end());
00907
00908 vector<CPKIFCertificateSourceListPtr>::iterator newEndSourceList = remove_if(reverseState->m_sourceTable.begin(), reverseState->m_sourceTable.end(), IsNullCertificateSourceList);
00909 reverseState->m_sourceTable.erase(newEndSourceList, reverseState->m_sourceTable.end());
00910 }
00911
00919 void CPKIFReversiblePathBuilderImpl::RemoveLoopMakers(
00920 CPKIFCertificateNodeList& certList,
00921 CPKIFReversePathStatePtr& reverseState)
00922 {
00923
00924 if(reverseState->m_table.empty() || certList.empty())
00925 return;
00926
00927
00928
00929
00930 CPKIFNameAndKeyWithScoreList builtPath;
00931 vector<CPKIFNameAndKeyWithScoreListPtr>::iterator pos = reverseState->m_table.begin();
00932 vector<CPKIFNameAndKeyWithScoreListPtr>::iterator end = reverseState->m_table.end();
00933 for(; pos != end; ++pos)
00934 {
00935 if(!(*pos)->empty())
00936 {
00937 IPKIFNameAndKeyPtr tmpNameAndKey = (*pos)->front()->GetNameAndKey();
00938 CPKIFNameAndKeyWithScorePtr newNode(new CPKIFNameAndKeyWithScore(tmpNameAndKey));
00939 builtPath.push_back(newNode);
00940 }
00941 }
00942
00943 #ifdef _DEBUG
00944 size_t size = certList.size();
00945 #endif
00946
00947
00948 NodeInNodeList n;
00949 n.SetNodeList(&builtPath);
00950
00951
00952
00953
00954 CPKIFCertificateNodeList::iterator newEnd = remove_if(certList.begin(), certList.end(), n);
00955 certList.erase(newEnd, certList.end());
00956
00957 #ifdef _DEBUG
00958 size = certList.size();
00959 #endif
00960 }
00961
00970 IPKIFNameAndKeyPtr CPKIFReversiblePathBuilderImpl::GetCurrentCert(CPKIFReversePathStatePtr& reverseState)
00971 {
00972 IPKIFNameAndKeyPtr empty;
00973 if(reverseState->m_table.empty())
00974 return empty;
00975
00976 if(PBD_FORWARD == reverseState->m_direction)
00977 {
00978
00979
00980 if(reverseState->m_table.back()->empty())
00981 return empty;
00982 else
00983 return reverseState->m_table.back()->front()->GetNameAndKey();
00984 }
00985 else
00986 {
00987
00988
00989 if(reverseState->m_table.front()->empty())
00990 return empty;
00991 else
00992 return reverseState->m_table.front()->front()->GetNameAndKey();
00993 }
00994 }
00995
01004 bool IsSelfSigned(CPKIFCertificateNodeEntryPtr& certNode)
01005 {
01006 if(certNode == (CPKIFCertificateNodeEntry*)NULL)
01007 return false;
01008
01009 CPKIFCertificatePtr cert = certNode->GetCert();
01010 return cert->IsSelfSigned();
01011 }
01012
01020 void CPKIFReversiblePathBuilderImpl::RemoveExtraneous(CPKIFCertificateNodeList& certList, CPKIFReversePathStatePtr& reverseState)
01021 {
01022 if(certList.empty())
01023 return;
01024
01025 if(PBD_FORWARD == reverseState->m_direction)
01026 {
01027 CPKIFNamePtr tmpName = reverseState->m_table.back()->front()->GetNameAndKey()->GetIssuerName();
01028 RemoveNotIssuedTo(tmpName, certList);
01029 }
01030 else
01031 {
01032
01033
01034 if(!reverseState->m_table.front()->empty())
01035 {
01036 CPKIFNamePtr tmpName = reverseState->m_table.front()->front()->GetNameAndKey()->GetSubjectName();
01037 RemoveNotIssuedBy(tmpName, certList);
01038 }
01039
01040 CPKIFCertificateNodeList::iterator end;
01041 end = remove_if(certList.begin(), certList.end(), IsSelfSigned);
01042 certList.erase(end, certList.end());
01043
01044
01045 CPKIFCertificateNodeList listCopy;
01046
01047 CPKIFCertificateNodeList::iterator clpos;
01048 CPKIFCertificateNodeList::iterator clend = certList.end();
01049 for(clpos = certList.begin(); clpos != clend; ++clpos)
01050 {
01051 GottaMatch<CPKIFCertificateNodeEntryPtr> gm;
01052 gm.SetRHS(*clpos);
01053 if(listCopy.end() == find_if(listCopy.begin(), listCopy.end(), gm))
01054 listCopy.push_back(*clpos);
01055 }
01056
01057 certList.clear();
01058 copy(listCopy.begin(), listCopy.end(), back_inserter(certList));
01059 }
01060 }
01061
01071 bool CPKIFReversiblePathBuilderImpl::BuildOrGrowTable(CPKIFReversePathStatePtr& reverseState)
01072 {
01073
01074
01075 if(reverseState->m_bTableIsComplete && GrowRows(reverseState))
01076 return true;
01077 else if(reverseState->m_bBuildStarted)
01078 {
01079
01080 PuntTopRow(reverseState);
01081 }
01082 else
01083 {
01084
01085
01086 reverseState->m_bBuildStarted = true;
01087 }
01088
01089
01090
01091
01092
01093
01094
01095 IPKIFCertRepository* iCert = m_parent->GetMediatorFromParent<IPKIFCertRepository>();
01096 IPKIFTrustCache* iTrust = m_parent->GetMediatorFromParent<IPKIFTrustCache>();
01097 if(NULL == iCert || NULL == iTrust)
01098 throw CPKIFPathException(m_parent->thisComponent, COMMON_MEDIATOR_MISSING, "IPKIFCertRepository and/or IPKIFTrustCache are not available.");
01099
01100
01101 IPKIFCertRepositoryUpdate* iCertUpdate = m_parent->GetMediatorFromParent<IPKIFCertRepositoryUpdate>();
01102 IPKIFCRLRepository* iCRL = m_parent->GetMediatorFromParent<IPKIFCRLRepository>();
01103 IPKIFSupportsSynonymousCertSources* iCertSS = m_parent->GetMediatorFromParent<IPKIFSupportsSynonymousCertSources>();
01104
01105 #ifdef _DEBUG
01106 const char* targetIssuerName = reverseState->m_targetCertAsNameAndKey->GetIssuerName()->ToString();
01107 const char* targetSubjectName = reverseState->m_targetCertAsNameAndKey->GetSubjectName()->ToString();
01108 #endif
01109
01110 IPKIFTrustAnchorList trustRootList;
01111 IPKIFNameAndKeyPtr curCertAsNameAndKey = GetCurrentCert(reverseState);
01112
01113 do
01114 {
01115 size_t tableSize = reverseState->m_table.size();
01116 CPKIFCertificateSourceList certSourceList;
01117 CPKIFCertificateNodeList certList;
01118
01119 #ifdef _DEBUG
01120 const char* curCertIssuerString = curCertAsNameAndKey->GetIssuerName()->ToString();
01121 const char* curCertSubjectString = curCertAsNameAndKey->GetSubjectName()->ToString();
01122 #endif
01123
01124
01125
01126 if(PBD_FORWARD == reverseState->m_direction &&
01127 iTrust->GetTrustRoots(curCertAsNameAndKey->GetIssuerName(), trustRootList))
01128 {
01129
01130 CPKIFNameAndKeyWithScoreListPtr newList(new CPKIFNameAndKeyWithScoreList);
01131 IPKIFTrustAnchorList::iterator trPos;
01132 IPKIFTrustAnchorList::iterator trEnd = trustRootList.end();
01133 for(trPos = trustRootList.begin(); trPos != trEnd; ++trPos)
01134 {
01135 IPKIFNameAndKeyPtr trPosAsNameAndKey = dynamic_pointer_cast<IPKIFNameAndKey, IPKIFTrustAnchor>(*trPos);
01136 CPKIFNameAndKeyWithScorePtr newNode(new CPKIFNameAndKeyWithScore(trPosAsNameAndKey));
01137 newList->push_back(newNode);
01138 }
01139 CPKIFCertificateSourceListPtr emptySourceList;
01140 reverseState->m_bTableIsComplete = true;
01141
01142 reverseState->m_table.push_back(newList);
01143 reverseState->m_sourceTable.push_back(emptySourceList);
01144
01145 #ifdef _DEBUG
01146 vector<string> v;
01147 vector<CPKIFNameAndKeyWithScoreListPtr>::iterator zzzpos;
01148 vector<CPKIFNameAndKeyWithScoreListPtr>::iterator zzzend = reverseState->m_table.end();
01149 for(zzzpos = reverseState->m_table.begin(); zzzpos != zzzend; ++zzzpos)
01150 {
01151 v.push_back((*zzzpos)->front()->GetNameAndKey()->GetSubjectName()->ToString());
01152 v.push_back((*zzzpos)->front()->GetNameAndKey()->GetIssuerName()->ToString());
01153 }
01154 #endif
01155
01156 return true;
01157 }
01158 else if(PBD_REVERSE == reverseState->m_direction &&
01159 *curCertAsNameAndKey->GetSubjectName() == *reverseState->m_targetCertAsNameAndKey->GetIssuerName())
01160 {
01161
01162 CPKIFNameAndKeyWithScoreListPtr newList(new CPKIFNameAndKeyWithScoreList);
01163 CPKIFNameAndKeyWithScorePtr newNode(new CPKIFNameAndKeyWithScore(reverseState->m_targetCertAsNameAndKey));
01164 newList->push_back(newNode);
01165
01166 CPKIFCertificateSourceListPtr emptySourceList;
01167 reverseState->m_bTableIsComplete = true;
01168
01169 reverseState->m_table.insert(reverseState->m_table.begin(),newList);
01170 reverseState->m_sourceTable.insert(reverseState->m_sourceTable.begin(), emptySourceList);
01171 return true;
01172 }
01173 else
01174 {
01175
01176 CPKIFCertificatePtr curCert = dynamic_pointer_cast<CPKIFCertificate, IPKIFNameAndKey>(curCertAsNameAndKey);
01177 if(curCert == (CPKIFCertificate*)NULL)
01178 {
01179 CPKIFTrustRootPtr tr = dynamic_pointer_cast<CPKIFTrustRoot, IPKIFNameAndKey>(curCertAsNameAndKey);
01180 if(tr != (CPKIFTrustRoot*)NULL)
01181 tr->GetCert(curCert);
01182 }
01183
01184 if(curCert != (CPKIFCertificate*)NULL)
01185 {
01186 iCertSS->GetCertificateSources(curCert, certSourceList, reverseState->m_direction);
01187 }
01188 else if(PBD_FORWARD == reverseState->m_direction)
01189 iCert->GetCertificates(curCertAsNameAndKey->GetIssuerName(), certList, reverseState->m_sources);
01190 else
01191 {
01192 CPKIFException e(m_parent->thisComponent, COMMON_INVALID_INPUT, "Reverse direction building from non-certificate trust anchors is not supported");
01193 throw e;
01194 }
01195
01196 if(certList.size() || certSourceList.size())
01197 {
01198
01199
01200
01201 CPKIFNameAndKeyWithScoreListPtr newList(new CPKIFNameAndKeyWithScoreList);
01202 CPKIFCertificateNodeList::iterator cPos;
01203 CPKIFCertificateNodeList::iterator cEnd = certList.end();
01204 for(cPos = certList.begin(); cPos != cEnd; ++cPos)
01205 {
01206 CPKIFCertificatePtr cPosAsCert = (*cPos)->GetCert();
01207 IPKIFNameAndKeyPtr cPosAsNameAndKey = dynamic_pointer_cast<IPKIFNameAndKey, CPKIFCertificate>(cPosAsCert);
01208 CPKIFNameAndKeyWithScorePtr newNode(new CPKIFNameAndKeyWithScore(cPosAsNameAndKey));
01209 newList->push_back(newNode);
01210 }
01211
01212 CPKIFCertificateSourceListPtr newSourceList(new CPKIFCertificateSourceList);
01213 copy(certSourceList.begin(), certSourceList.end(), back_inserter(*newSourceList));
01214
01215 SortAndSaveLists(reverseState, newList, newSourceList);
01216 }
01217
01218
01219 RemoveLoopMakers(certList, reverseState);
01220
01221 RemoveExtraneous(certList, reverseState);
01222
01223
01224 if(reverseState->m_table.size() == tableSize)
01225 {
01226
01227
01228 PuntTopRow(reverseState);
01229 }
01230 }
01231
01232 curCertAsNameAndKey = GetCurrentCert(reverseState);
01233 }while(curCertAsNameAndKey != (IPKIFNameAndKey*)NULL);
01234
01235 if(curCertAsNameAndKey == (IPKIFNameAndKey*)NULL)
01236 return false;
01237 else
01238 {
01239
01240 CPKIFNamePtr issuerName;
01241 vector<CPKIFNameAndKeyWithScoreListPtr>::reverse_iterator pos;
01242 vector<CPKIFNameAndKeyWithScoreListPtr>::reverse_iterator end = reverseState->m_table.rend();
01243 for(pos = reverseState->m_table.rbegin(); pos != end; ++pos)
01244 {
01245 if(issuerName == (CPKIFName*)NULL)
01246 issuerName = (*pos)->front()->GetNameAndKey()->GetSubjectName();
01247 else
01248 {
01249 IgnoreNotIssuedBy(*pos, issuerName);
01250 issuerName = (*pos)->front()->GetNameAndKey()->GetSubjectName();
01251 }
01252 }
01253
01254 return true;
01255 }
01256
01257 return false;
01258 }
01259
01269 bool CPKIFReversiblePathBuilderImpl::TriedBefore(CPKIFNameAndKeyWithScoreList& builtPathNK)
01270 {
01271 std::vector<CPKIFNameAndKeyWithScoreList>::iterator pos;
01272 std::vector<CPKIFNameAndKeyWithScoreList>::iterator end = m_previouslyTriedPaths.end();
01273 for(pos = m_previouslyTriedPaths.begin(); pos != end; ++pos)
01274 {
01275 if((*pos).size() != builtPathNK.size())
01276 return false;
01277
01278 for(size_t ii = 0; ii < (*pos).size(); ++ii)
01279 {
01280 if(!((*pos)[ii] == builtPathNK[ii]))
01281 return false;
01282 }
01283 }
01284 return !m_previouslyTriedPaths.empty();
01285 }
01286
01296 bool CPKIFReversiblePathBuilderImpl::CheckAlternatives(CPKIFCertificatePath& path, CPKIFReversePathStatePtr& reverseState)
01297 {
01298
01299 if(1 >= reverseState->m_table.size())
01300 return false;
01301
01302 CPKIFBuilderStatisticsPtr bs;
01303 path.GetBuilderStats(bs);
01304
01305 do
01306 {
01307 if(reverseState->m_curRoot == NULL)
01308 {
01309
01310 CPKIFNameAndKeyWithScorePtr rootNK = reverseState->m_table.back()->front();
01311 reverseState->m_curRoot = dynamic_pointer_cast<IPKIFTrustAnchor, IPKIFNameAndKey>(rootNK->GetNameAndKey());
01312 }
01313 else
01314 {
01315
01316 vector<CPKIFNameAndKeyWithScoreListPtr>::iterator tablePos;
01317 vector<CPKIFNameAndKeyWithScoreListPtr>::iterator tableEnd = reverseState->m_table.end();
01318 for(tablePos = reverseState->m_table.begin(); tablePos != tableEnd; ++tablePos)
01319 {
01320
01321 #ifdef _DEBUG
01322 const char* frontNodeInCurRowName = (*tablePos)->front()->GetNameAndKey()->GetSubjectName()->ToString();
01323 #endif
01324 if(!SetNextToIgnore(*tablePos))
01325 {
01326
01327 break;
01328 }
01329 else
01330 {
01331
01332 ClearAllIgnore(*tablePos);
01333 }
01334 }
01335 if(tablePos == tableEnd)
01336 {
01337 bool liveMore = false;
01338
01339
01340 if(reverseState->m_table.front()->size() > 1)
01341 {
01342 bool setNext = false;
01343 CPKIFNameAndKeyWithScoreList::iterator rootPos;
01344 CPKIFNameAndKeyWithScoreList::iterator rootEnd = reverseState->m_table.front()->end();
01345 for(rootPos = reverseState->m_table.front()->begin(); rootPos != rootEnd; ++rootPos)
01346 {
01347 IPKIFTrustAnchorPtr ta = dynamic_pointer_cast<IPKIFTrustAnchor, IPKIFNameAndKey>((*rootPos)->GetNameAndKey());
01348 if(setNext)
01349 {
01350 reverseState->m_curRoot = ta;
01351 liveMore = true;
01352 break;
01353 }
01354 else
01355 {
01356 if(*reverseState->m_curRoot == *ta)
01357 setNext = true;
01358 }
01359 }
01360 }
01361
01362 if(!liveMore)
01363 {
01364 return false;
01365 }
01366 }
01367 }
01368
01369
01370
01371
01372 CPKIFNameAndKeyWithScoreList builtPathNK;
01373 vector<CPKIFNameAndKeyWithScoreListPtr>::reverse_iterator pos;
01374 vector<CPKIFNameAndKeyWithScoreListPtr>::reverse_iterator end = reverseState->m_table.rend();
01375 CPKIFNameAndKeyWithScorePtr curEntry;
01376 bool hasCycle = false;
01377 PKIInfoSource pathMaxSource = LOCAL;
01378
01379 IPKIFNameAndKeyPtr lastCert = dynamic_pointer_cast<IPKIFNameAndKey, IPKIFTrustAnchor>(reverseState->m_curRoot);
01380
01381 CPKIFPathSettingsPtr settings;
01382 path.GetPathSettings(settings);
01383
01384 pos = reverseState->m_table.rbegin();
01385 for(++pos; pos != end; ++pos)
01386 {
01387 curEntry = GetFirstNonIgnoredNodeNotAlreadyInPathIssuedBy(*pos, builtPathNK,lastCert,settings);
01388 if(curEntry != (CPKIFCertificateNodeEntry*)NULL
01389 && !curEntry->GetNameAndKey()->SameDNSameKey(*lastCert))
01390 {
01391 builtPathNK.push_back(curEntry);
01392
01393 IPKIFNameAndKeyPtr emptyNK;
01394 lastCert = emptyNK;
01395 lastCert = curEntry->GetNameAndKey();
01396 }
01397 else
01398 {
01399 hasCycle = true;
01400 break;
01401 }
01402 }
01403
01404 ++bs->m_nTotalPathsDiscovered;
01405
01406
01407
01408 if(hasCycle || TriedBefore(builtPathNK))
01409 continue;
01410
01411 m_previouslyTriedPaths.push_back(builtPathNK);
01412
01413 CPKIFCertificateNodeList builtPath;
01414 CPKIFNameAndKeyWithScoreList::iterator nkPos;
01415 CPKIFNameAndKeyWithScoreList::iterator nkEnd = builtPathNK.end();
01416
01417 for(nkPos = builtPathNK.begin();nkPos != nkEnd; ++nkPos)
01418 {
01419 CPKIFCertificatePtr tmpCert = dynamic_pointer_cast<CPKIFCertificate, IPKIFNameAndKey>((*nkPos)->GetNameAndKey());
01420 CPKIFCertificateNodeEntryPtr newNode(new CPKIFCertificateNodeEntry(tmpCert));
01421 builtPath.push_back(newNode);
01422 }
01423
01424
01425
01426 CPKIFPathValidationResults tmpResults;
01427 if(settings->GetUseValidatorFilterWhenBuilding() && !PathOK(builtPath, reverseState->m_curRoot, settings, tmpResults))
01428 {
01429 ++bs->m_nPathsRejectedDueToValidationErrors;
01430 bs->m_vFailureCodes.push_back(tmpResults.DiagnosticCode());
01431
01432
01433 CPKIFCertificatePath tmpPath;
01434 CPKIFCertificatePtr tmpTarget;
01435 path.GetTarget(tmpTarget);
01436 tmpPath.SetTrustRoot(reverseState->m_curRoot);
01437 tmpPath.SetPath(builtPath);
01438 tmpPath.SetTarget(tmpTarget);
01439
01440 CPKIFPathLogger::LogValidationResults(tmpResults, tmpPath, "Logging builder-rejected path");
01441 continue;
01442 }
01443
01444 path.SetTrustRoot(reverseState->m_curRoot);
01445 path.SetPath(builtPath);
01446
01447 CPKIFCertificateNodeList::iterator dbgpos;
01448 CPKIFCertificateNodeList::iterator dbgend = builtPath.end();
01449 if(LOCAL == pathMaxSource)
01450 {
01451 LOG_STRING_DEBUG("Printing path returned from BuildPath (LOCAL-certs only)...", m_parent->thisComponent, 0, NULL);
01452 }
01453 else
01454 {
01455 LOG_STRING_DEBUG("Printing path returned from BuildPath (LOCAL and REMOTE certs)...", m_parent->thisComponent, 0, NULL);
01456 }
01457 std::string logStr = "Root: ";
01458 logStr.append(((reverseState->m_curRoot))->GetSubjectName()->ToString());
01459 LOG_STRING_DEBUG(logStr.c_str(), m_parent->thisComponent, 0, NULL);
01460
01461 for(dbgpos = builtPath.begin(); dbgpos != dbgend; ++dbgpos)
01462 {
01463 const char* curCertString = (*dbgpos)->GetCert()->Subject()->ToString();
01464 logStr = curCertString;
01465 logStr.append(" ");
01466 logStr.append((*dbgpos)->GetCert()->SerialNumber());
01467 LOG_STRING_DEBUG(logStr.c_str(), m_parent->thisComponent, 0, NULL);
01468 }
01469 ++bs->m_nReturnedPaths;
01470 return true;
01471 }while(1);
01472
01473 }
01474
01476
01484 CPKIFReversiblePathBuilder::CPKIFReversiblePathBuilder(PathBuildingDirection pbd)
01485 :m_impl(new CPKIFReversiblePathBuilderImpl)
01486 {
01487 LOG_STRING_DEBUG("CPKIFReversiblePathBuilder::CPKIFReversiblePathBuilder", thisComponent, 0, this);
01488 m_impl->m_parent = this;
01489 m_impl->m_pbd = pbd;
01490 }
01491
01499 CPKIFReversiblePathBuilder::~CPKIFReversiblePathBuilder(void)
01500 {
01501 if(m_impl)
01502 {
01503 delete m_impl;
01504 m_impl = 0;
01505 }
01506 }
01507
01515 void CPKIFReversiblePathBuilder::Initialize()
01516 {
01517 LOG_STRING_DEBUG("CPKIFReversiblePathBuilder::Initialize()", thisComponent, 0, this);
01518 }
01519
01530 bool CPKIFReversiblePathBuilder::BuildPath(
01534 CPKIFCertificatePath& path)
01535 {
01536 LOG_STRING_DEBUG("CPKIFReversiblePathBuilder::BuildPath(CPKIFCertificatePath& path)", thisComponent, 0, this);
01537
01538
01539
01540 PathBuildingDirection pbd = m_impl->m_pbd;
01541
01542
01543
01544
01545 m_impl->CheckInputs(path);
01546
01547
01548
01549 CPKIFCertificatePtr targetCert;
01550 path.GetTarget(targetCert);
01551 if(m_impl->TargetIsTrustAnchor(targetCert))
01552 {
01553
01554 CPKIFTrustRootPtr tr(new CPKIFTrustRoot());
01555 tr->SetCert(targetCert);
01556 path.SetTrustRoot(tr);
01557
01558
01559 CPKIFCertificateNodeList builtPath;
01560 CPKIFCertificateNodeEntryPtr curEntry(new CPKIFCertificateNodeEntry);
01561 curEntry->SetCert(targetCert);
01562
01563 CPKIFCertStatusPtr newStatus(new CPKIFCertStatus);
01564 newStatus->SetIsTrustAnchor(true);
01565 curEntry->SetStatus(newStatus);
01566
01567 builtPath.push_back(curEntry);
01568 path.SetPath(builtPath);
01569
01570 std::ostringstream os;
01571 os << "Path building is not required. The target certificate is a trust root - subject DN = " << targetCert->GetSubjectName()->ToString();
01572 LOG_STRING_INFO(os.str().c_str(), thisComponent, 0, this);
01573
01574 return true;
01575 }
01576
01577
01578 CPKIFCertificatePathStatePtr state;
01579 path.GetState(state);
01580
01581
01582 CPKIFReversePathStatePtr reverseState = dynamic_pointer_cast<CPKIFReversePathState, CPKIFCertificatePathState>(state);
01583 if(state == (CPKIFCertificatePathState*)NULL || reverseState == (CPKIFReversePathState*)NULL)
01584 {
01585
01586 m_impl->CreateState(path, pbd);
01587 }
01588
01589 path.GetState(state);
01590 reverseState = dynamic_pointer_cast<CPKIFReversePathState, CPKIFCertificatePathState>(state);
01591
01592
01593
01594 do
01595 {
01596
01597 if(reverseState->m_bTableIsComplete && m_impl->CheckAlternatives(path, reverseState))
01598 return true;
01599 }while(m_impl->BuildOrGrowTable(reverseState));
01600
01601
01602 return false;
01603 }
01604
01612 PathBuildingDirection CPKIFReversiblePathBuilder::GetDirection() const
01613 {
01614 return m_impl->m_pbd;
01615 }