00001
00009 #include "AlgorithmIdentifier.h"
00010 #include "BasicChecksUtils.h"
00011 #include "Buffer.h"
00012 #include "Certificate.h"
00013 #include "CertificateNodeListWithSourceInfo.h"
00014 #include "GeneralName.h"
00015 #include "GeneralSubtree.h"
00016 #include "GottaMatch.h"
00017 #include "IPKIFCryptoMisc.h"
00018 #include "IPKIFCryptoRawOperations.h"
00019 #include "IPKIFHashContext.h"
00020 #include "Name.h"
00021 #include "OID.h"
00022 #include "PKIFCertStatus.h"
00023 #include "PKIFCertificateNodeEntry.h"
00024 #include "PKIFCertificatePath.h"
00025 #include "PKIFCommonErrors.h"
00026 #include "PKIFKeyMaterial.h"
00027 #include "PKIFNameAndKeyWithScore.h"
00028 #include "PKIFPATHErrors.h"
00029 #include "PKIFPathException.h"
00030 #include "PKIFPathSettings.h"
00031 #include "PKIFTrustRoot.h"
00032 #include "PathResults.h"
00033 #include "PolicyInformation.h"
00034 #include "PolicyInformationSet.h"
00035 #include "PolicyMapping.h"
00036 #include "PolicyMappings.h"
00037 #include "SubjectAltName.h"
00038 #include "SubjectPublicKeyInfo.h"
00039 #include "SubtreeMatch.h"
00040 #include "ToolkitUtils.h"
00041 #include "Name.h"
00042 #include "PKIFCertificatePath.h"
00043 #include "PKIFTrustRoot.h"
00044 #include "PKIFCertificateNodeEntry.h"
00045 #include "PathResults.h"
00046 #include "ooasn1.h"
00047 #include "asn1ber.h"
00048
00049 #include "boost/numeric/conversion/cast.hpp"
00050
00051 #include <iterator>
00052
00053 using boost::numeric_cast;
00054 using boost::bad_numeric_cast;
00055
00056 using namespace std;
00057
00058
00059 using namespace boost;
00060
00061 #ifdef _DEBUG_PATH_POL
00062 #include <iostream>
00063
00071 void DumpPolicySet(
00073 const char* message,
00074
00075 const vector<CPKIFPolicyInformationListPtr>& authSet )
00076 {
00077 cout << endl << message << endl;
00078
00079 vector<CPKIFPolicyInformationListPtr>::const_iterator authSetPos;
00080 vector<CPKIFPolicyInformationListPtr>::const_iterator authSetEnd = authSet.end();
00081 int rowCount = 0;
00082 for(authSetPos = authSet.begin(); authSetPos != authSetEnd; ++authSetPos,++rowCount)
00083 {
00084 cout << "Row: " << rowCount << endl;
00085 CPKIFPolicyInformationList::const_iterator authSetPolPos;
00086 CPKIFPolicyInformationList::const_iterator authSetPolEnd = (*authSetPos)->end();
00087 for(authSetPolPos = (*authSetPos)->begin(); authSetPolPos != authSetPolEnd; ++authSetPolPos)
00088 {
00089 cout << (*authSetPolPos)->PolicyOID()->ToString() << endl;
00090 }
00091 }
00092 if(authSet.empty())
00093 cout << "Empty" << endl;
00094
00095 }
00096 #endif
00097
00104 bool RowContainsAnyPolicy(
00106 const CPKIFPolicyInformationListPtr& test)
00107 {
00108
00109 if(*g_anyPolicy == *test->back())
00110 return true;
00111 else
00112 return false;
00113 }
00127 void ProcessPolicyMapping(
00129 const CPKIFPolicyMappingsPtr& policyMappings,
00131 const std::bitset<3>& indicators,
00133 vector<CPKIFPolicyInformationListPtr>& authSet)
00134 {
00135 CPKIFOIDPtr anyPolicyOID(new CPKIFOID(CPKIFStringPtr(new std::string("2.5.29.32.0"))));
00136 if(indicators[CPKIFPathSettings::POLICY_MAPPING])
00137 {
00138
00139
00140
00141
00142
00143 CPKIFPolicyMappingListPtr policyMappingList = policyMappings->PolicyMappings();
00144 CPKIFPolicyMappingList::iterator pos;
00145 CPKIFPolicyMappingList::iterator end = policyMappingList->end();
00146 CPKIFOIDPtr issuerDomain;
00147 CPKIFPolicyInformationListPtr piList(new CPKIFPolicyInformationList);
00148 for(pos = policyMappingList->begin(); pos != end; ++pos)
00149 {
00150 issuerDomain = (*pos)->IssuerDomain();
00151
00152
00153
00154 if((*anyPolicyOID == *issuerDomain) || (*anyPolicyOID == *(*pos)->SubjectDomain()))
00155 throw CPKIFPathException(TOOLKIT_PATH_VALIDATOR,COMMON_INVALID_INPUT,"A certificate includes a policy mapping extension that maps to or from anyPolicy.");
00156 else
00157 {
00158 CPKIFPolicyInformationPtr tmpPI(new CPKIFPolicyInformation(issuerDomain));
00159 piList->push_back(tmpPI);
00160 }
00161 }
00162
00163 RowDoesContainPolicyInSet funcObj;
00164 funcObj.SetPolicySet(piList);
00165 vector<CPKIFPolicyInformationListPtr>::iterator authSetEnd = remove_if(authSet.begin(), authSet.end(), funcObj);
00166 authSet.erase(authSetEnd, authSet.end());
00167 }
00168 else
00169 {
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 CIssuerDomainMappingList idml;
00184 CPKIFPolicyMappingListPtr policyMappingList = policyMappings->PolicyMappings();
00185 CPKIFPolicyMappingList::iterator pos;
00186 CPKIFPolicyMappingList::iterator end = policyMappingList->end();
00187 for(pos = policyMappingList->begin(); pos != end; ++pos)
00188 {
00189
00190
00191 if((*anyPolicyOID == *(*pos)->IssuerDomain()) || (*anyPolicyOID == *(*pos)->SubjectDomain()))
00192 throw CPKIFPathException(TOOLKIT_PATH_VALIDATOR,COMMON_INVALID_INPUT,"A certificate includes a policy mapping extension that maps to or from anyPolicy.");
00193 else
00194 idml.AddMapping(*pos);
00195 }
00196
00197 bool zerothRowContainsAnyPolicy = false;
00198 CPKIFPolicyInformationPtr anyPolicy(new CPKIFPolicyInformation(anyPolicyOID));
00199 if(!authSet.empty() && !authSet.front()->empty() && *anyPolicy == *authSet.front()->back())
00200 zerothRowContainsAnyPolicy = true;
00201
00202 struct IssuerDomainMappingList* list = idml.GetList();
00203 while(NULL != list)
00204 {
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219 for(unsigned int ii = 0; ii < authSet.size(); ii++)
00220 {
00221 CPKIFPolicyInformationListPtr curr = authSet[ii];
00222 if(!curr->empty() && (*(list->m_issuerDomain) == *(curr->back())))
00223 {
00224 list->m_bProcessed = true;
00225 CPKIFPolicyInformationListPtr curRow = curr;
00226 CPKIFPolicyInformationList::iterator subDomainPos = list->m_subjectDomains.begin();
00227 CPKIFPolicyInformationList::iterator subDomainEnd = list->m_subjectDomains.end();
00228
00229 CPKIFPolicyInformationPtr tmpPol(new CPKIFPolicyInformation((*subDomainPos)->PolicyOID()));
00230 curr->push_back(tmpPol);
00231 for(++subDomainPos; subDomainPos != subDomainEnd; ++subDomainPos)
00232 {
00233
00234 CPKIFPolicyInformationListPtr newRow(new CPKIFPolicyInformationList);
00235 copy(curRow->begin(),curRow->end(), back_inserter(*newRow));
00236 CPKIFPolicyInformationPtr pathDepthColumn(*subDomainPos);
00237 newRow->pop_back();
00238 newRow->push_back(pathDepthColumn);
00239 authSet.push_back(newRow);
00240 }
00241 }
00242 }
00243
00244 list = list->m_next;
00245 }
00246
00247 if(zerothRowContainsAnyPolicy)
00248 {
00249 CPKIFPolicyInformationListPtr zerothRow = authSet.front();
00250 struct IssuerDomainMappingList* list = idml.GetList();
00251 while(NULL != list)
00252 {
00253 if(!list->m_bProcessed)
00254 {
00255
00256
00257 CPKIFPolicyInformationListPtr newRow(new CPKIFPolicyInformationList);
00258 copy(zerothRow->begin(),zerothRow->end(), back_inserter(*newRow));
00259 CPKIFPolicyInformationPtr pathDepthColumn(list->m_issuerDomain);
00260 newRow->pop_back();
00261 newRow->push_back(pathDepthColumn);
00262
00263 CPKIFPolicyInformationList::iterator subDomainPos = list->m_subjectDomains.begin();
00264 CPKIFPolicyInformationList::iterator subDomainEnd = list->m_subjectDomains.end();
00265
00266 for(; subDomainPos != subDomainEnd; ++subDomainPos)
00267 {
00268
00269
00270 CPKIFPolicyInformationListPtr newRowWithSubDomain(new CPKIFPolicyInformationList);
00271 copy(zerothRow->begin(),zerothRow->end(), back_inserter(*newRowWithSubDomain));
00272 CPKIFPolicyInformationPtr pathDepthColumn(list->m_issuerDomain);
00273 newRowWithSubDomain->push_back(pathDepthColumn);
00274 authSet.push_back(newRowWithSubDomain);
00275 }
00276 }
00277
00278 list = list->m_next;
00279 }
00280 }
00281 }
00282 #ifdef _DEBUG_PATH_POL
00283 DumpPolicySet("Dumping authority constrained set leaving ProcessPolicyMapping", authSet);
00284 #endif
00285 }
00293 void AddPoliciesToAuthSet(
00295 const CPKIFPolicyInformationSetPtr& certPols,
00297 const std::bitset<3>& indicators,
00299 vector<CPKIFPolicyInformationListPtr>& authSet,
00301 bool isSelfIssued,
00303 bool isIntermediate)
00304 {
00305 #ifdef _DEBUG_PATH_POL
00306 DumpPolicySet("Dumping authority constrained set entering AddPoliciesToAuthSet", authSet);
00307 #endif
00308
00309 CPKIFPolicyInformationListPtr certPolList = certPols->GetPolicySet();
00310
00311 CPKIFOIDPtr anyPolicyOID(new CPKIFOID(CPKIFStringPtr(new std::string("2.5.29.32.0"))));
00312 CPKIFPolicyInformationPtr anyPolicy(new CPKIFPolicyInformation(anyPolicyOID));
00313
00314 CPKIFPolicyInformationPtr anyPolicyFromCertPolList;
00315
00316 CPKIFPolicyInformationList::iterator currentPolicy;
00317 CPKIFPolicyInformationList::iterator end = certPolList->end();
00318 bool foundPolicy = false, foundAnyPolicy = false, zerothRowContainsAnyPolicy = false;
00319 vector<CPKIFPolicyInformationListPtr>::iterator authSetPos, authSetEnd;
00320 for(currentPolicy = certPolList->begin(); currentPolicy != end; ++currentPolicy)
00321 {
00322 zerothRowContainsAnyPolicy = false;
00323 if(!authSet.empty() && *anyPolicy == *authSet.front()->back())
00324 zerothRowContainsAnyPolicy = true;
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336 if(*(*currentPolicy) == *anyPolicy)
00337 {
00338 anyPolicyFromCertPolList = *currentPolicy;
00339 foundAnyPolicy = true;
00340 continue;
00341 }
00342
00343 authSetEnd = authSet.end();
00344 foundPolicy = false;
00345
00346
00347 for(authSetPos = authSet.begin(); authSetPos != authSetEnd; ++authSetPos)
00348 {
00349 if(!(*authSetPos)->empty() && *(*currentPolicy) == *((*authSetPos)->back()))
00350 {
00351
00352 foundPolicy = true;
00353
00354
00355 CPKIFPolicyQualifierListPtr qList = (*currentPolicy)->Qualifiers();
00356 if(qList != (CPKIFPolicyQualifierList*)NULL && !qList->empty())
00357 {
00358 CPKIFPolicyQualifierListPtr existingQualifiers = (*authSetPos)->back()->Qualifiers();
00359 if(existingQualifiers != (CPKIFPolicyQualifierList*)NULL)
00360 {
00361
00362
00363 copy(qList->begin(), qList->end(), back_inserter(*existingQualifiers));
00364 }
00365 else
00366 {
00367
00368 CPKIFPolicyQualifierListPtr newQualifiers(new CPKIFPolicyQualifierList);
00369 copy(qList->begin(), qList->end(), back_inserter(*newQualifiers));
00370
00371
00372 (*authSetPos)->back()->SetQualifiers(newQualifiers);
00373 }
00374 }
00375 }
00376 }
00377
00378 if(!foundPolicy && zerothRowContainsAnyPolicy)
00379 {
00380
00381
00382
00383 CPKIFPolicyInformationListPtr newRow(new CPKIFPolicyInformationList);
00384 copy(authSet.front()->begin(), authSet.front()->end(), back_inserter(*newRow));
00385 newRow->pop_back();
00386 newRow->push_back(*currentPolicy);
00387 authSet.push_back(newRow);
00388 }
00389 }
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400 if(!foundAnyPolicy || (indicators[CPKIFPathSettings::ANY_POLICY] && !(isSelfIssued && isIntermediate)))
00401 {
00402
00403
00404
00405 vector<CPKIFPolicyInformationListPtr>::iterator end = remove_if(authSet.begin(), authSet.end(), RowContainsAnyPolicy);
00406 authSet.erase(end, authSet.end());
00407
00408 RowDoesNotContainPolicyInSet funcObj;
00409 funcObj.SetPolicySet(certPolList);
00410 end = remove_if(authSet.begin(), authSet.end(), funcObj);
00411 authSet.erase(end, authSet.end());
00412 }
00413 else if(foundAnyPolicy && !indicators[CPKIFPathSettings::ANY_POLICY])
00414 {
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425 authSetEnd = authSet.end();
00426 for(authSetPos = authSet.begin(); authSetPos != authSetEnd; ++authSetPos)
00427 {
00428 if(!(*authSetPos)->empty())
00429 {
00430
00431
00432 GottaMatch<CPKIFPolicyInformationPtr> gm;
00433 gm.SetRHS((*authSetPos)->back());
00434 if(*anyPolicy == *(*authSetPos)->back() || certPolList->end() == find_if(certPolList->begin(), certPolList->end(), gm))
00435 {
00436
00437 CPKIFPolicyQualifierListPtr qList = anyPolicyFromCertPolList->Qualifiers();
00438 if(qList != (CPKIFPolicyQualifierList*)NULL && !qList->empty())
00439 {
00440 CPKIFPolicyQualifierListPtr existingQualifiers = (*authSetPos)->back()->Qualifiers();
00441 if(existingQualifiers != (CPKIFPolicyQualifierList*)NULL)
00442 {
00443
00444
00445 copy(qList->begin(), qList->end(), back_inserter(*existingQualifiers));
00446 }
00447 else
00448 {
00449
00450 CPKIFPolicyQualifierListPtr newQualifiers(new CPKIFPolicyQualifierList);
00451 copy(qList->begin(), qList->end(), back_inserter(*newQualifiers));
00452
00453
00454 (*authSetPos)->back()->SetQualifiers(newQualifiers);
00455 }
00456 }
00457 }
00458 }
00459 }
00460 }
00461
00462 #ifdef _DEBUG_PATH_POL
00463 DumpPolicySet("Dumping authority constrained set leaving AddPoliciesToAuthSet", authSet);
00464 #endif
00465 }
00473 void CAC_API IntersectSets(
00475 CPKIFPolicyInformationListPtr& authSetCondensed,
00477 CPKIFPolicyInformationListPtr& initSet,
00479 CPKIFPolicyInformationListPtr& userSet)
00480 {
00481
00482 userSet->clear();
00483
00484
00485 MatchesPolicy mp;
00486 CPKIFPolicyInformationList::iterator authBegin = authSetCondensed->begin();
00487 CPKIFPolicyInformationList::iterator authEnd = authSetCondensed->end();
00488
00489
00490
00491 CPKIFPolicyInformationList::iterator initPos;
00492 CPKIFPolicyInformationList::iterator initEnd = initSet->end();
00493 for(initPos = initSet->begin(); initPos != initEnd; ++initPos)
00494 {
00495
00496 mp.SetPolicyToMatch(*initPos);
00497 if(authEnd != find_if(authBegin, authEnd, mp))
00498 {
00499
00500 userSet->push_back(*initPos);
00501 }
00502 }
00503 }
00511 void CAC_API IntersectSubtrees(
00513 CPKIFGeneralSubtreeListPtr& fromExtension,
00515 CPKIFGeneralSubtreeListPtr& curTrees,
00517 CPKIFGeneralSubtreeListPtr& newSet)
00518 {
00519
00520 newSet->clear();
00521
00522 if(curTrees->empty())
00523 {
00524
00525 newSet = fromExtension;
00526 return;
00527 }
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537 SubtreeMatch isImpossible;
00538
00539
00540
00541 CPKIFGeneralSubtreeList::iterator fromExtBegin = fromExtension->begin();
00542 CPKIFGeneralSubtreeList::iterator fromExtEnd = fromExtension->end();
00543 CPKIFGeneralSubtreeList::iterator fromExtTemp = fromExtension->begin();
00544
00545
00546
00547 CPKIFGeneralSubtreeList::iterator curTreesPos;
00548 CPKIFGeneralSubtreeList::iterator curTreesEnd = curTrees->end();
00549 for(curTreesPos = curTrees->begin(); curTreesPos != curTreesEnd; ++curTreesPos)
00550 {
00551 isImpossible.SetRHS(*curTreesPos);
00552 fromExtTemp = find_if(fromExtBegin, fromExtEnd, isImpossible);
00553 if(fromExtTemp != fromExtEnd)
00554 {
00555
00556
00557
00558
00559 CPKIFGeneralSubtreePtr empty((*fromExtTemp)->ShallowCopy());
00560 empty->SetEmpty();
00561 newSet->push_back(empty);
00562 }
00563 }
00564
00565
00566 for(fromExtTemp = fromExtBegin; fromExtTemp != fromExtEnd; ++fromExtTemp)
00567 {
00568 CPKIFGeneralSubtreeList::iterator newTreesPos;
00569 CPKIFGeneralSubtreeList::iterator newTreesEnd = newSet->end();
00570 bool found = false;
00571 for(newTreesPos = newSet->begin();!found && newTreesPos != newTreesEnd; ++newTreesPos)
00572 {
00573 if(*newTreesPos == *fromExtTemp) {
00574 found = true;
00575 }
00576 }
00577 if(!found) {
00578 newSet->push_back(*fromExtTemp);
00579 }
00580 }
00581
00582 }
00590 bool IsInSubtree(
00592 CPKIFGeneralSubtreeListPtr& subtree,
00594 CPKIFCertificatePtr& curCert,
00595 bool bIsPerm)
00596 {
00597
00598
00599
00600 CPKIFGeneralSubtreeList::iterator pos;
00601 CPKIFGeneralSubtreeList::iterator end = subtree->end();
00602
00603 CPKIFGeneralSubtree::MatchState subjectMatch = CPKIFGeneralSubtree::NOT_APPLICABLE;
00604 CPKIFNamePtr subjectName = curCert->Subject();
00605 if(subjectName != (CPKIFName*)NULL && 0 != strcmp(subjectName->ToString(), ""))
00606 {
00607 for(pos = subtree->begin();
00608 subjectMatch != CPKIFGeneralSubtree::MATCH && pos != end;
00609 ++pos)
00610 {
00611 CPKIFGeneralName::GENNAMETYPE stType = (*pos)->GetBase()->GetType();
00612
00613 if(CPKIFGeneralName::DIRECTORYNAME == stType || CPKIFGeneralName::RFC822 == stType)
00614 {
00615 CPKIFGeneralSubtree::MatchState tmpState = (*pos)->IsInSubtree(subjectName);
00616
00617 if(tmpState != CPKIFGeneralSubtree::NOT_APPLICABLE) subjectMatch = tmpState;
00618 }
00619 }
00620 }
00621
00622 CPKIFGeneralSubtree::MatchState sanMatch = CPKIFGeneralSubtree::NOT_APPLICABLE;
00623 CPKIFSubjectAltNamePtr subAltName = curCert->GetExtension<CPKIFSubjectAltName>();
00624 bool hasSAN = (subAltName != (CPKIFSubjectAltName*) 0);
00625 if( hasSAN )
00626 {
00627 CPKIFGeneralNameList genNames;
00628 subAltName->GeneralNames(genNames);
00629 CPKIFGeneralNameList::iterator gnPos;
00630 CPKIFGeneralNameList::iterator gnEnd = genNames.end();
00631 for(gnPos = genNames.begin();
00632 sanMatch != CPKIFGeneralSubtree::MATCH && gnPos != gnEnd;
00633 ++gnPos)
00634 {
00635 end = subtree->end();
00636 for(pos = subtree->begin();
00637 sanMatch != CPKIFGeneralSubtree::MATCH && pos != end;
00638 ++ pos)
00639 {
00640 try {
00641 CPKIFGeneralSubtree::MatchState tmpState = (*pos)->IsInSubtree((*gnPos));
00642
00643 if(tmpState != CPKIFGeneralSubtree::NOT_APPLICABLE)
00644 sanMatch = tmpState;
00645 }catch(CPKIFException &pe){
00646
00647
00648
00649
00650
00651
00652 if(bIsPerm)
00653 throw pe;
00654 }
00655 }
00656 }
00657 }
00658 if(sanMatch == CPKIFGeneralSubtree::NO_MATCH || subjectMatch == CPKIFGeneralSubtree::NO_MATCH)
00659 return false;
00660
00661 return true;
00662 }
00670 bool CheckNameConstraints(
00672 CPKIFCertificatePtr& curCert,
00674 CPKIFGeneralSubtreeListPtr& permSubtrees,
00676 CPKIFGeneralSubtreeListPtr& exclSubtrees,
00678 bool permSubtreesHasBeenSet)
00679 {
00680
00681 if(exclSubtrees && !exclSubtrees->empty() && IsInSubtree(exclSubtrees, curCert, false))
00682 return false;
00683
00684 if(!permSubtrees || (permSubtrees->empty() && !permSubtreesHasBeenSet))
00685 return true;
00686 else
00687 return IsInSubtree(permSubtrees, curCert, true);
00688 }
00689
00690
00698 bool IsEmpty(CPKIFCertificateNodeListWithSourceInfoPtr& node)
00699 {
00700 return node->empty();
00701 }
00709 bool IsEmptyNameAndKey(
00711 CPKIFNameAndKeyWithScoreListPtr& node)
00712 {
00713 return node->empty();
00714 }
00722 bool IsNullCertificateSourceList(CPKIFCertificateSourceListPtr& node)
00723 {
00724 return node == (CPKIFCertificateSourceList*)NULL;
00725 }
00726
00727
00738 bool _GetHashOfToBeSignedCert(
00740 const CPKIFCertificate& cert,
00742 IPKIFCryptoMisc* cryptoMisc,
00744 PKIFCRYPTO::HASH_ALG hashAlg,
00746 unsigned char* hashResult,
00748 int* hashResultLen)
00749 {
00750 int stat = ASN_OK;
00751
00752 if(NULL == cryptoMisc || NULL == hashResult)
00753 throw CPKIFPathException(TOOLKIT_PATH_VALIDATOR,COMMON_INVALID_INPUT,"Invalid input passed to certificate hash calculation function");
00754
00755
00756 CPKIFBufferPtr certBuf = cert.Encoded();
00757 int length = certBuf->GetLength();
00758
00759 if(0 == length)
00760 throw CPKIFPathException(TOOLKIT_PATH_VALIDATOR,COMMON_INVALID_INPUT,"Empty CRL passed to CRL hash calculation function");
00761
00762
00763 OOCTXT ctxt;
00764 initContext (&ctxt);
00765 setBERDecBufPtr(&ctxt, certBuf->GetBuffer(), length, NULL, NULL);
00766 OOCTXT* pctxt = &ctxt;
00767
00768
00769 stat = matchTag (pctxt, TM_UNIV|TM_CONS|16, &length, XM_ADVANCE);
00770 if (stat != ASN_OK)
00771 {
00772 freeEncodeBuffer(&ctxt);
00773 memFreeAll(&ctxt);
00774 return false;
00775 }
00776
00777
00778 size_t byteIndex = ctxt.buffer.byteIndex;
00779
00780
00781 stat = matchTag (pctxt, TM_UNIV|TM_CONS|16, &length, XM_ADVANCE);
00782 if (stat != ASN_OK)
00783 {
00784 freeEncodeBuffer(&ctxt);
00785 memFreeAll(&ctxt);
00786 return false;
00787 }
00788
00789
00790
00791
00792 unsigned char* p = (unsigned char*)ctxt.buffer.data + byteIndex;
00793
00794 size_t tmpST = ctxt.buffer.byteIndex - byteIndex;
00795 unsigned int tmpUI = 0;
00796
00797 try {
00798 tmpUI = numeric_cast<unsigned int>(tmpST);
00799 }catch(bad_numeric_cast &) {
00800 throw CPKIFException(TOOLKIT_PATH, COMMON_INVALID_INPUT, "Byte offset difference too large.");
00801 }
00802
00803 length += (tmpUI);
00804
00805 IPKIFHashContext* hash = NULL;
00806 try
00807 {
00808
00809 hash = cryptoMisc->HashInit(hashAlg);
00810 cryptoMisc->HashUpdate(hash, p, length);
00811 cryptoMisc->HashFinal(hash, (unsigned char*)hashResult, hashResultLen);
00812 }
00813 catch(CPKIFException& e)
00814 {
00815 if(NULL != hash)
00816 delete hash;
00817
00818
00819 freeEncodeBuffer(&ctxt);
00820 memFreeAll(&ctxt);
00821
00822 throw e;
00823 }
00824
00825
00826 delete hash;
00827
00828
00829 freeEncodeBuffer(&ctxt);
00830 memFreeAll(&ctxt);
00831
00832 return true;
00833 }
00834
00835
00836
00837
00850 bool CAC_API PathSigChecker(
00852 const CPKIFCertificatePath& path,
00854 IPKIFCryptoRawOperations* crypto,
00856 IPKIFCryptoMisc* cryptoMisc,
00858 CPKIFPathValidationResults& results)
00859 {
00860
00861 if(NULL == crypto || NULL == cryptoMisc)
00862 {
00863 RAISE_PATH_EXCEPTION("NULL crypto or cryptoMisc parameter.", TOOLKIT_PATH_VALIDATOR, COMMON_INVALID_INPUT, NULL)
00864 }
00865
00866
00867 CPKIFCertificateNodeList certNodeList;
00868 path.GetPath(certNodeList);
00869
00870
00871 if(0 == certNodeList.size())
00872 {
00873 RAISE_PATH_EXCEPTION("Empty certificate path parameter.", TOOLKIT_PATH_VALIDATOR, COMMON_INVALID_INPUT, NULL)
00874 }
00875
00876
00877 CPKIFCertificatePtr curCert;
00878
00879 IPKIFNameAndKeyPtr prevCert;
00880 IPKIFTrustAnchorPtr trustRoot;
00881
00882
00883 path.GetTrustRoot(trustRoot);
00884 if(trustRoot == (IPKIFTrustAnchor*)NULL)
00885 {
00886 RAISE_PATH_EXCEPTION("Path does not specify a trust root.", TOOLKIT_PATH_VALIDATOR, PATH_TRUST_ROOT_NOT_SET, NULL)
00887 }
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901 prevCert = boost::dynamic_pointer_cast<IPKIFNameAndKey, IPKIFTrustAnchor>(trustRoot);
00902
00903
00904 CPKIFAlgorithmIdentifierPtr workingParams = prevCert->GetSubjectPublicKeyInfo()->alg();
00905 AlgClass workingAlg = GetAlgClass(workingParams);
00906
00907
00908 CPKIFCertificateNodeList::iterator pos;
00909 CPKIFCertificateNodeList::iterator end = certNodeList.end();
00910 for(pos = certNodeList.begin(); pos != end; ++pos)
00911 {
00912 curCert = (*pos)->GetCert();
00913 CPKIFCertStatusPtr status = (*pos)->GetStatus();
00914
00915
00916 char hashResult[MAXHASH];
00917 int nResultLen = MAXHASH;
00918 PKIFCRYPTO::HASH_ALG hashAlg = PKIFCRYPTO::SHA1;
00919
00920 CPKIFAlgorithmIdentifierPtr prevCertSigAlg = prevCert->GetSubjectPublicKeyInfo()->alg();
00921 CPKIFAlgorithmIdentifierPtr curCertSigAlg = curCert->SignatureAlgorithm();
00922 AlgClass prevAC = GetAlgClass(prevCertSigAlg);
00923 AlgClass curAC = GetAlgClass(curCertSigAlg);
00924 if(prevAC != curAC)
00925 {
00926 status->SetDiagnosticCode(PATH_SIGNATURE_VERIFICATION_FAILED);
00927 return false;
00928 }
00929
00930
00931 CPKIFAlgorithmIdentifierPtr sigAlg = curCert->SignatureAlgorithm();
00932 CPKIFOIDPtr aTmpOID = sigAlg->oid();
00933 if(!GetCACHashAlg(aTmpOID, &hashAlg))
00934 throw CPKIFPathException(TOOLKIT_PATH_CRL_CHECKER, COMMON_UNSUPPORTED_ALG);
00935
00936
00937 if(!_GetHashOfToBeSignedCert(*curCert, cryptoMisc, hashAlg, (unsigned char*)hashResult, &nResultLen))
00938 return false;
00939
00940
00941 CPKIFBufferPtr sigBuf = curCert->Signature();
00942 CPKIFKeyMaterial key;
00944 CPKIFTrustRootPtr tmpTA = dynamic_pointer_cast<CPKIFTrustRoot, IPKIFNameAndKey>(prevCert);
00945 if(tmpTA != (CPKIFTrustRoot*)NULL)
00946 {
00947 CPKIFCertificatePtr tmpCert;
00948 tmpTA->GetCert(tmpCert);
00949 if(tmpCert != (CPKIFCertificate*)NULL)
00950 {
00951 CPKIFBufferPtr certBuf = tmpCert->Encoded();
00952 key.SetCertificate(certBuf->GetBuffer(), certBuf->GetLength());
00953 }
00954 }
00955 else
00956 {
00957 CPKIFCertificatePtr tmpCert = dynamic_pointer_cast<CPKIFCertificate, IPKIFNameAndKey>(prevCert);
00958 if(tmpCert != (CPKIFCertificate*)NULL)
00959 {
00960 CPKIFBufferPtr certBuf = tmpCert->Encoded();
00961 key.SetCertificate(certBuf->GetBuffer(), certBuf->GetLength());
00962 }
00963 }
00964
00965
00966 CPKIFSubjectPublicKeyInfoPtr spki = prevCert->GetSubjectPublicKeyInfo();
00967 key.SetSubjectPublicKeyInfo(spki);
00968 key.SetWorkingParameters(workingParams);
00969
00970
00971 if(!crypto->Verify(key, (unsigned char*)hashResult, nResultLen, (unsigned char*)sigBuf->GetBuffer(), sigBuf->GetLength(), hashAlg))
00972 {
00973 results.SetCertificate(*pos);
00974 status->SetDiagnosticCode(PATH_SIGNATURE_VERIFICATION_FAILED);
00975 return false;
00976 }
00977 else
00978 status->SetSignatureVerified(true);
00979
00980
00981 prevCert = dynamic_pointer_cast<IPKIFNameAndKey, CPKIFCertificate>(curCert);
00982 CPKIFAlgorithmIdentifierPtr prevAlgParams = prevCert->GetSubjectPublicKeyInfo()->alg();
00983 if(workingAlg != GetAlgClass(prevAlgParams))
00984 {
00985
00986 CPKIFAlgorithmIdentifierPtr tmpAI;
00987 workingParams = tmpAI;
00988 workingAlg = GetAlgClass(prevAlgParams);
00989 }
00990
00991
00992 if(prevCert->GetSubjectPublicKeyInfo()->alg()->hasParameters())
00993 workingParams = prevAlgParams;
00994 }
00995
00996
00997 results.SetCertSignaturesVerified(true);
00998 results.SetWorkingParams(workingParams);
00999
01000 return true;
01001 }
01013 void CAC_API FindErrorAndSetOnResults(
01015 const CPKIFCertificatePath& path,
01018 CPKIFPathValidationResults& results)
01019 {
01020 CPKIFCertificateNodeList pathList;
01021 path.GetPath(pathList);
01022 bool bStatusSet = false;
01023 CPKIFCertificateNodeList::iterator pathPos;
01024 CPKIFCertificateNodeList::iterator pathEnd = pathList.end();
01025 for(pathPos = pathList.begin(); pathPos != pathEnd; ++pathPos)
01026 {
01027 CPKIFCertStatusPtr status = (*pathPos)->GetStatus();
01028 if(status)
01029 {
01030 if(results.GetRevocationStatusMostSevere() > status->GetRevocationStatus())
01031 {
01032 results.SetRevocationStatusMostSevere(status->GetRevocationStatus());
01033
01034
01035
01036 if(REVOKED == status->GetRevocationStatus() && 0 != status->GetDiagnosticCode())
01037 {
01038 results.SetCertificate(*pathPos);
01039 results.SetCertStatus(status);
01040 bStatusSet = true;
01041 }
01042 }
01043 if(!bStatusSet && 0 != status->GetDiagnosticCode())
01044 {
01045 results.SetCertificate(*pathPos);
01046 results.SetCertStatus(status);
01047 bStatusSet = true;
01048 }
01049 }
01050 }
01051 }
01052
01053
01054
01055
01056
01057