00001
00010 #include "PKIFPathValidator2.h"
00011
00012 #include "ToolkitUtils.h"
00013 #include "IPKIFCryptoRawOperations.h"
00014 #include "IPKIFCryptoMisc.h"
00015 #include "PKIFFuncStorage.h"
00016 #include "PKIFRevocationStatusInterfaces.h"
00017 #include "PKIFMediators.h"
00018 #include "PKIFX509Extensions2.h"
00019
00020 #include "PKIFErrors.h"
00021 #include "PKIFPathException.h"
00022 #include "PKIFCertificatePath.h"
00023 #include "PKIFPathSettings.h"
00024 #include "BasicChecksUtils.h"
00025 #include "CRLEntry.h"
00026
00027 #include "PKIFTrustRoot.h"
00028 #include "Certificate.h"
00029 #include "PKIFCertStatus.h"
00030 #include "PathResults.h"
00031 #include "PKIFCertificateNodeEntry.h"
00032 #include "PKIFPathBasicChecks2.h"
00033 #include "NameConstraints.h"
00034 #include "InhibitAnyPolicy.h"
00035 #include "PolicyConstraints.h"
00036 #include "BasicConstraints.h"
00037 #include "GeneralSubtree.h"
00038 #include "PolicyInformationSet.h"
00039 #include "PolicyInformation.h"
00040
00041 using boost::dynamic_pointer_cast;
00042
00044 struct CPKIFPathValidator2Impl
00045 {
00046 CPKIFFuncStoragePtr m_funcs;
00047 bool m_deleteFunctor;
00048 bool m_bEnforceTrustAnchorConstraints;
00049 };
00051
00058 CPKIFPathValidator2::CPKIFPathValidator2():m_impl (new CPKIFPathValidator2Impl)
00059 {
00060 m_impl->m_deleteFunctor = false;
00061 m_impl->m_bEnforceTrustAnchorConstraints = false;
00062 }
00076 void CPKIFPathValidator2::SetAdditionalCertificateChecks(
00079 CPKIFFuncStoragePtr& funcs)
00080 {
00081 LOG_STRING_DEBUG("CPKIFPathValidator2", TOOLKIT_PATH_VALIDATOR, 0, this);
00082
00083
00084
00085 m_impl->m_funcs = funcs;
00086 }
00087
00095 CPKIFPathValidator2::~CPKIFPathValidator2(void)
00096 {
00097 LOG_STRING_DEBUG("CPKIFPathValidator2", TOOLKIT_PATH_VALIDATOR, 0, this);
00098 delete m_impl;
00099 m_impl = 0;
00100 }
00101
00111 void CPKIFPathValidator2::Initialize()
00112 {
00113 LOG_STRING_DEBUG("CPKIFPathValidator2", TOOLKIT_PATH_VALIDATOR, 0, this);
00114 }
00115
00146 bool CPKIFPathValidator2::ValidatePath(
00148 CPKIFCertificatePath& path,
00150 CPKIFPathValidationResults& results,
00152 CPKIFFuncStoragePtr& thisCallOnlyFuncs)
00153 {
00154 LOG_STRING_DEBUG("CPKIFPathValidator2", TOOLKIT_PATH_VALIDATOR, 0, this);
00155
00156 IPKIFCryptoRawOperations* crypto = GetMediatorFromParent<IPKIFCryptoRawOperations>();
00157 IPKIFCryptoMisc* cryptoMisc = GetMediatorFromParent<IPKIFCryptoMisc>();
00158 if(NULL == crypto || NULL == cryptoMisc)
00159 throw CPKIFPathException(thisComponent,COMMON_MEDIATOR_MISSING,"One or both of the IPKIFCryptoRawOperations and IPKIFCryptoMisc interfaces was not available.");
00160
00161 bool pathGood = false;
00162
00163 IPKIFTrustAnchorPtr root;
00164
00165 IPKIFNameAndKeyPtr targetCertNK, rootCertNK;
00166 CPKIFCertificatePtr targetCert;
00167 path.GetTarget(targetCert);
00168 path.GetTrustRoot(root);
00169 if(root == (CPKIFTrustRoot*)NULL)
00170 throw CPKIFPathException(thisComponent,COMMON_INVALID_INPUT,"The path has no trust root.");
00171
00172 rootCertNK = boost::dynamic_pointer_cast<IPKIFNameAndKey, IPKIFTrustAnchor>(root);
00173
00174 targetCertNK = boost::dynamic_pointer_cast<IPKIFNameAndKey, CPKIFCertificate>(targetCert);
00175
00176
00177 CPKIFCertificateNodeList certs;
00178 path.GetPath(certs);
00179
00180
00181
00182 if(*rootCertNK == *targetCertNK && 1 == certs.size())
00183 {
00184 CPKIFCertStatusPtr newStatus(new CPKIFCertStatus);
00185 newStatus->SetIsTrustAnchor(true);
00186 results.SetCertStatus(newStatus);
00187 results.SetTargetIsTrustAnchor(true);
00188 results.SetRevocationStatusMostSevere(NOT_REVOKED);
00189 results.SetTrustAnchor(root);
00190
00191
00192 certs[0]->SetStatus(newStatus);
00193
00194 return true;
00195 }
00196
00197
00198
00199
00200
00201
00202 if(m_impl->m_bEnforceTrustAnchorConstraints)
00203 {
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215 CPKIFPolicyInformationSetPtr pis;
00216 CPKIFNameConstraintsPtr nc;
00217 CPKIFInhibitAnyPolicyPtr iap;
00218 CPKIFPolicyConstraintsPtr pc;
00219 CPKIFBasicConstraintsPtr bc;
00220
00221
00222 IPKIFTrustAnchorPtr ta;
00223 path.GetTrustRoot(ta);
00224
00225 IPKIFHasExtensionsPtr hep = dynamic_pointer_cast<IPKIFHasExtensions, IPKIFTrustAnchor>(ta);
00226 if(hep)
00227 {
00228 pis = hep->GetExtension<CPKIFPolicyInformationSet>();
00229 nc = hep->GetExtension<CPKIFNameConstraints>();
00230 iap = hep->GetExtension<CPKIFInhibitAnyPolicy>();
00231 pc = hep->GetExtension<CPKIFPolicyConstraints>();
00232 bc = hep->GetExtension<CPKIFBasicConstraints>();
00233 }
00234
00235 std::vector<CPKIFX509ExtensionPtr> exts;
00236 CPKIFX509ExtensionMediator2 * mediator = CPKIFX509ExtensionMediator2::GetInstance();
00237 hep->GetExtensions(mediator, exts);
00238
00239 std::vector<CPKIFX509ExtensionPtr>::iterator pos;
00240 std::vector<CPKIFX509ExtensionPtr>::iterator end = exts.end();
00241 for(pos = exts.begin(); pos != end; ++pos)
00242 {
00243
00244 if(dynamic_pointer_cast<CPKIFPolicyInformationSet, CPKIFX509Extension>(*pos))
00245 continue;
00246 else if(dynamic_pointer_cast<CPKIFNameConstraints, CPKIFX509Extension>(*pos))
00247 continue;
00248 else if(dynamic_pointer_cast<CPKIFInhibitAnyPolicy, CPKIFX509Extension>(*pos))
00249 continue;
00250 else if(dynamic_pointer_cast<CPKIFPolicyConstraints, CPKIFX509Extension>(*pos))
00251 continue;
00252 else if(dynamic_pointer_cast<CPKIFBasicConstraints, CPKIFX509Extension>(*pos))
00253 continue;
00254 else
00255 {
00256
00257 CPKIFOIDPtr cccOid(new CPKIFOID(CPKIFStringPtr(new std::string("1.3.6.1.5.5.7.1.18"))));
00258 CPKIFOIDPtr posOid = (*pos)->oid();
00259 if(*cccOid == *posOid)
00260 continue;
00261 else if((*pos)->isCritical())
00262 {
00263 CPKIFCertificateNodeList certNodeList;
00264 path.GetPath(certNodeList);
00265
00266 CPKIFCertificateNodeEntryPtr node = certNodeList.front();
00267
00268 CPKIFCertStatusPtr status(new CPKIFCertStatus);
00269 status->SetDiagnosticCode(PATH_UNPROCESSED_CRITICAL_EXTENSION);
00270 node->SetStatus(status);
00271 results.SetCertificate(node);
00272 return false;
00273 }
00274 }
00275 }
00276
00277
00278 CPKIFPathSettingsPtr ps;
00279 path.GetPathSettings(ps);
00280
00281 if(pis)
00282 {
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293 CPKIFPolicyInformationListPtr pilFromTa = pis->GetPolicySet();
00294 CPKIFPolicyInformationListPtr pilFromUser;
00295 ps->GetInitialPolicySet(pilFromUser);
00296 if(pilFromTa && pilFromUser)
00297 {
00298 if(!pilFromUser->empty() && *g_anyPolicy == *pilFromUser->front())
00299 {
00300 ps->SetInitialPolicySet(pilFromTa);
00301 }
00302 else
00303 {
00304 CPKIFPolicyInformationListPtr newPil(new CPKIFPolicyInformationList);
00305 IntersectSets(pilFromTa, pilFromUser, newPil);
00306 ps->SetInitialPolicySet(newPil);
00307 }
00308 }
00309 else if(pilFromTa)
00310 {
00311 ps->SetInitialPolicySet(pilFromTa);
00312 }
00313 }
00314
00315 if(nc)
00316 {
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327 CPKIFGeneralSubtreesPtr permFromTa = nc->GetPermitted();
00328 CPKIFGeneralSubtreesPtr permFromUser;
00329 ps->GetInitialPermSubtrees(permFromUser);
00330 if(permFromTa && permFromUser)
00331 {
00332 CPKIFGeneralSubtreesPtr newPerm(new CPKIFGeneralSubtrees);
00333 IntersectSubtrees(permFromTa, permFromUser, newPerm);
00334 ps->SetInitialPermSubtrees(newPerm);
00335 }
00336 else if(permFromTa)
00337 {
00338 ps->SetInitialPermSubtrees(permFromTa);
00339 }
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351 CPKIFGeneralSubtreesPtr exclFromTa = nc->GetExcluded();
00352 CPKIFGeneralSubtreesPtr exclFromUser;
00353 ps->GetInitialExclSubtrees(exclFromUser);
00354 if(exclFromTa && exclFromUser)
00355 {
00356 CPKIFGeneralSubtreesPtr newExcl(new CPKIFGeneralSubtrees);
00357 IntersectSubtrees(exclFromTa, exclFromUser, newExcl);
00358 ps->SetInitialExclSubtrees(newExcl);
00359 }
00360 else if(exclFromTa)
00361 {
00362 ps->SetInitialExclSubtrees(exclFromTa);
00363 }
00364 }
00365
00366 if(iap)
00367 {
00368
00369
00370
00371
00372
00373
00374
00375 ps->SetInitialInhibitAnyPolicyIndicator(true);
00376 }
00377
00378 if(pc)
00379 {
00380 if(pc->InhibitPolicyMappingPresent())
00381 {
00382
00383
00384
00385
00386
00387
00388
00389
00390 ps->SetInitialPolicyMappingInhibitIndicator(true);
00391 }
00392 if(pc->RequireExplicitPolicyPresent())
00393 {
00394
00395
00396
00397
00398
00399
00400
00401 ps->SetInitialExplicitPolicyIndicator(true);
00402 }
00403 }
00404
00405
00406
00407
00408
00409
00410
00411
00412 if(bc && bc->pathLengthPresent())
00413 {
00414
00415
00416
00417
00418 int pathLength = bc->pathLength();
00419
00420 CPKIFCertificateNodeList certsFromPath;
00421 path.GetPath(certsFromPath);
00422
00423 CPKIFCertificateNodeList::iterator pos;
00424 CPKIFCertificateNodeList::iterator end = certsFromPath.end();
00425 for(pos = certsFromPath.begin(); pos != end; ++pos)
00426 {
00427 CPKIFCertificatePtr curCert = (*pos)->GetCert();
00428 if(curCert && !curCert->IsSelfIssued())
00429 {
00430 --pathLength;
00431
00432 if(pathLength < 0)
00433 {
00434 CPKIFCertStatusPtr status(new CPKIFCertStatus);
00435 status->SetDiagnosticCode(PATH_LENGTH_VIOLATION);
00436 (*pos)->SetStatus(status);
00437 results.SetCertificate(*pos);
00438 }
00439 }
00440 }
00441 }
00442 }
00443
00444
00445 if(m_impl->m_funcs == (CPKIFFuncStorage*)NULL)
00446 {
00447 if(thisCallOnlyFuncs == (CPKIFFuncStorage*)NULL)
00448 {
00449 CPKIFFuncStoragePtr empty;
00450 pathGood = CPKIFPathBasicChecks2::DoChecks(path, results, empty);
00451 }
00452 else
00453 pathGood = CPKIFPathBasicChecks2::DoChecks(path, results, thisCallOnlyFuncs);
00454 }
00455 else
00456 {
00457
00458 if(thisCallOnlyFuncs == NULL)
00459 pathGood = CPKIFPathBasicChecks2::DoChecks(path, results, m_impl->m_funcs);
00460 else
00461 {
00462 CPKIFFuncStoragePtr combo(new CPKIFFuncStorage(NULL));
00463 combo->addFuncs(*m_impl->m_funcs);
00464 combo->addFuncs(*thisCallOnlyFuncs);
00465
00466 pathGood = CPKIFPathBasicChecks2::DoChecks(path, results, combo);
00467 }
00468 }
00469
00470
00471 if(!pathGood)
00472 {
00473
00474 FindErrorAndSetOnResults(path, results);
00475 return false;
00476 }
00477
00478
00479 if(!PathSigChecker(path, crypto, cryptoMisc, results))
00480 {
00481
00482 FindErrorAndSetOnResults(path, results);
00483 return false;
00484 }
00485
00486
00487 CPKIFPathSettingsPtr settings;
00488 path.GetPathSettings(settings);
00489
00490 bool bCheckRevStatus = true;
00491 if(settings != (CPKIFPathSettings*)NULL)
00492 bCheckRevStatus = settings->GetCheckRevocationStatus();
00493
00494
00495 IPKIFRevocationStatus* revStatus = GetMediatorFromParent<IPKIFRevocationStatus>();
00496 if(NULL != revStatus && bCheckRevStatus)
00497 {
00498
00499
00500
00501
00502 RevocationStatus rStatus;
00503 CPKIFCRLEntryPtr crlEntry;
00504 bool statusDetermined = revStatus->CheckStatusPath(path, rStatus);
00505 if(NOT_REVOKED != rStatus)
00506 {
00507
00508
00509 FindErrorAndSetOnResults(path, results);
00510
00511
00512 return false;
00513 }
00514
00515
00516 results.SetRevocationStatusMostSevere(rStatus);
00517 }
00518
00519
00520
00521
00522 CPKIFCertificateNodeList nodes;
00523 path.GetPath(nodes);
00524 if(!nodes.empty())
00525 {
00526 CPKIFCertificateNodeEntryPtr target = nodes.back();
00527 if(target != NULL) {
00528 CPKIFCertStatusPtr tmpStatus = target->GetStatus();
00529 results.SetCertStatus(tmpStatus);
00530 }
00531 }
00532
00533 return true;
00534 }
00535
00542 bool CPKIFPathValidator2::GetEnforceTrustAnchorConstraints() const
00543 {
00544 return m_impl->m_bEnforceTrustAnchorConstraints;
00545 }
00553 void CPKIFPathValidator2::SetEnforceTrustAnchorConstraints(bool b)
00554 {
00555 m_impl->m_bEnforceTrustAnchorConstraints = b;
00556 }