CACPathBasicChecks2.cpp

Go to the documentation of this file.
00001 
00009 #include "PKIFPathBasicChecks2.h"
00010 
00011 #include "ToolkitUtils.h"
00012 #include "BasicChecksUtils.h"
00013 #include "PKIFErrors.h"
00014 
00015 #include "PKIFCertificatePath.h"
00016 #include "PKIFTrustRoot.h"
00017 #include "PKIFCertStatus.h"
00018 #include "PKIFCertificateNodeEntry.h"
00019 #include "PKIFTime.h"
00020 #include "PolicyInformation.h"
00021 #include "OID.h"
00022 #include "PKIFPathSettings.h"
00023 #include "PathResults.h"
00024 #include "GeneralSubtree.h"
00025 #include "Certificate.h"
00026 #include "SubjectPublicKeyInfo.h"
00027 #include "Validity.h"
00028 #include "PolicyInformationSet.h"
00029 #include "Name.h"
00030 #include "PolicyConstraints.h"
00031 #include "BasicConstraints.h"
00032 #include "KeyUsage.h"
00033 #include "NameConstraints.h"
00034 #include "InhibitAnyPolicy.h"
00035 #include "PKIFFuncStorage.h"
00036 #include "SubjectAltName.h"
00037 #include "X509Extension.h"
00038 #include "PolicyMappings.h"
00039 
00040 #ifdef _DEBUG_PATH
00041 #include <iostream>
00042 #endif
00043 using namespace std;
00044 #include <cstring>
00045 
00053 CPKIFPathBasicChecks2::CPKIFPathBasicChecks2(void)
00054 {
00055     LOG_STRING_DEBUG("CPKIFPathBasicChecks2::CPKIFPathBasicChecks2(void)", TOOLKIT_PATH_BASIC_CHECKS, 0, this);
00056 }
00064 CPKIFPathBasicChecks2::~CPKIFPathBasicChecks2(void)
00065 {
00066     LOG_STRING_DEBUG("CPKIFPathBasicChecks2::~CPKIFPathBasicChecks2(void)", TOOLKIT_PATH_BASIC_CHECKS, 0, this);
00067 }
00124 bool CPKIFPathBasicChecks2::DoChecks(
00126     const CPKIFCertificatePath& path, 
00128     CPKIFPathValidationResults& results, 
00131     CPKIFFuncStoragePtr& funcs)
00132 {
00133 #undef ERROR_OVERRIDE
00134 #define ERROR_OVERRIDE(errCode) \
00135 { \
00136     bool override = false;\
00137     bool (*fp) (int, CPKIFCertificatePtr&,const CPKIFCertificatePath&) = settings->GetOverrideCallback(); \
00138     if(NULL != fp) \
00139     { \
00140         if(fp(errCode, curCert, path))\
00141             override = true; \
00142     } \
00143     if(!override) \
00144     {\
00145         CPKIFCertStatusPtr status(new CPKIFCertStatus); \
00146         status->SetDiagnosticCode(errCode); \
00147         (*pos)->SetStatus(status);  \
00148         results.SetCertificate(*pos); \
00149         isPathGood = false; \
00150         break;\
00151     }\
00152 }\
00153 
00154 
00155     LOG_STRING_DEBUG("CPKIFPathBasicChecks2::DoChecks", TOOLKIT_PATH_BASIC_CHECKS, 0, NULL);
00156 
00157     //X.509 path processing inputs
00158     //  a) set of certs comprising a path
00159     //  b) trusted public key
00160     //  c) initial policy set
00161     //  d) initial explcit policy indicator
00162     //  e) initial policy mapping inhibit indicator
00163     //  f) initial inhibit any policy indicator
00164     //  g) current date/time
00165 
00166     //  a) set of certs comprising a path
00167     //  b) trusted public key
00168     CPKIFCertificateNodeList certNodeList;
00169     path.GetPath(certNodeList);
00170 
00171     //make sure the list is not NULL and is not empty
00172     if(0 == certNodeList.size())
00173     {
00174         RAISE_PATH_EXCEPTION("Empty certificate path parameter.", thisComponent, COMMON_INVALID_INPUT, NULL)
00175     }
00176 
00177     IPKIFTrustAnchorPtr trustRoot;
00178     path.GetTrustRoot(trustRoot);
00179     if(trustRoot == (IPKIFTrustAnchor*)NULL)
00180     {
00181         RAISE_PATH_EXCEPTION("Path does not specify a trust root.", thisComponent, PATH_TRUST_ROOT_NOT_SET, NULL)
00182     }
00183     else
00184         results.SetTrustAnchor(trustRoot);
00185 
00186     IPKIFNameAndKey* prevCert = dynamic_cast<IPKIFNameAndKey*>(&(*(trustRoot)));
00187 
00188     //get the name of the trust root so we can perform name chaining against the first cert in the path
00189     CPKIFNamePtr lastCertName;
00190     lastCertName = trustRoot->GetSubjectName();
00191     if(lastCertName == (CPKIFName*)NULL)
00192     {
00193         RAISE_PATH_EXCEPTION("Trust root is not a certificate.", thisComponent, PATH_TRUST_ROOT_NO_CERT, NULL)
00194     }
00195 
00196     //walk the path and unset all of the cert status values by assigning a new, empty status
00197     {
00198         CPKIFCertificateNodeList::iterator pos;
00199         CPKIFCertificateNodeList::iterator end = certNodeList.end();
00200         for(pos = certNodeList.begin(); pos != end; ++pos)
00201         {
00202             CPKIFCertStatusPtr newStatus(new CPKIFCertStatus);
00203             (*pos)->SetStatus(newStatus);
00204         }
00205     }
00206 
00207     //  c) initial policy set
00208     //  d) initial explcit policy indicator
00209     //  e) initial policy mapping inhibit indicator
00210     //  f) initial inhibit any policy indicator
00211     CPKIFPathSettingsPtr settings;
00212     path.GetPathSettings(settings);
00213 
00214     //  g) current date/time
00215 
00216     //first check to see if a time was specified in the settings
00217     CPKIFTimePtr curTime = settings->GetValidationTime();
00218     if(curTime == (CPKIFTime*)NULL)
00219         curTime = CPKIFTime::CurrentTime();
00220 
00221     //prepare state variables...
00222     //  a) authority constrained policy set
00223     //  b) permitted subtrees
00224     //  c) excluded subtrees
00225     //  d) explicit policy indicator
00226     //  e) path depth
00227     //  f) policy mapping inhibit indicator
00228     //  g) inhibit any policy indicator
00229     //  h) pending constraints
00230 
00231     //  a) authority constrained policy set
00232     vector<CPKIFPolicyInformationListPtr>* authSet = new vector<CPKIFPolicyInformationListPtr>;
00233 
00234     //set up the results of this validation effort (moved here 12/5/2003 to avoid leaks when name constraints throws)
00235     results.SetAuthorityConstrainedSet(authSet);
00236 
00237     CPKIFPolicyInformationListPtr zeroRow(new CPKIFPolicyInformationList);
00238     CPKIFOIDPtr anyPolicy(new CPKIFOID(CPKIFStringPtr(new std::string("2.5.29.32.0"))));
00239     zeroRow->push_back(CPKIFPolicyInformationPtr(new CPKIFPolicyInformation(anyPolicy)));
00240     zeroRow->push_back(CPKIFPolicyInformationPtr(new CPKIFPolicyInformation(anyPolicy)));
00241     authSet->push_back(zeroRow);
00242 
00243     //  b) permitted subtrees
00244     //  c) excluded subtrees
00245     //CPKIFGeneralSubtreeListPtr permSubtrees(new CPKIFGeneralSubtreeList); //initialize to unbounded
00246     //CPKIFGeneralSubtreeListPtr exclSubtrees(new CPKIFGeneralSubtreeList); //initialize to empty
00247     //                                                            //note how empty looks just like unbounded
00248     //                                                            //make wisecrack and continue
00249 
00250 
00251     CPKIFGeneralSubtreeListPtr permSubtrees;
00252     CPKIFGeneralSubtreeListPtr exclSubtrees;
00253     settings->GetInitialPermSubtrees(permSubtrees);
00254     settings->GetInitialExclSubtrees(exclSubtrees);
00255 
00256     if(permSubtrees == (CPKIFGeneralSubtreeList*)NULL)
00257     {
00258         CPKIFGeneralSubtreeListPtr tmp(new CPKIFGeneralSubtreeList);
00259         permSubtrees = tmp;
00260     }
00261     if(exclSubtrees == (CPKIFGeneralSubtreeList*)NULL)
00262     {
00263         CPKIFGeneralSubtreeListPtr tmp(new CPKIFGeneralSubtreeList);
00264         exclSubtrees = tmp;
00265     }
00266 
00267     //  d) explicit policy indicator
00268     //  f) policy mapping inhibit indicator
00269     //  g) inhibit any policy indicator
00270     std::bitset<3> indicators;
00271     indicators.reset();
00272     if(settings != (CPKIFPathSettings*)NULL)
00273     {
00274         indicators.set(CPKIFPathSettings::EXPLICIT_POLICY, settings->GetInitialExplicitPolicyIndicator());
00275         indicators.set(CPKIFPathSettings::POLICY_MAPPING, settings->GetInitialPolicyMappingInhibitIndicator());
00276         indicators.set(CPKIFPathSettings::ANY_POLICY, settings->GetInitialInhibitAnyPolicyIndicator());
00277     }
00278 
00279     //  e) path depth
00280     int pathDepth = 1;
00281 
00282     //  h) pending constraints
00283     bool bPendingExplicitPolicy = false;
00284     int nPendingExplicitPolicy = -1;
00285     bool bPendingPolicyMapping = false;
00286     int nPendingPolicyMapping = -1;
00287     bool bPendingAnyPolicy = false;
00288     int nPendingAnyPolicy = -1;
00289     bool bPathLength = false;
00290     int nPathLength = -1;
00291 
00292     bool permSubtreesSet = false; //added 12/03/2003
00293 
00294 #ifdef _DEBUG_PATH
00295     {
00296         cout << "Dumping path..." << endl;
00297         cout << "Trust root: " << lastCertName->ToString() << endl;
00298 
00299         CPKIFCertificateNodeList::iterator pos;
00300         CPKIFCertificateNodeList::iterator end = certNodeList.end();
00301         for(pos = certNodeList.begin(); pos != end; ++pos)
00302             cout << "Cert: " << (*pos)->GetCert()->Subject()->ToString() << endl;
00303     }
00304 #endif
00305 
00306     //iterate over all certs in the path
00307     bool isPathGood = true; //be optimistic
00308     CPKIFCertificatePtr curCert;
00309     CPKIFCertificateNodeList::iterator pos;
00310     CPKIFCertificateNodeList::iterator end = certNodeList.end();
00311     for(pos = certNodeList.begin(); pos != end; ++pos)
00312     {
00313         //get the cert to process this iteration
00314         curCert = (*pos)->GetCert();
00315         (*pos)->ClearProcessedExtensions();
00316 
00317         //bool isSelfIssued = CertIsSelfIssued(curCert);
00318         bool isSelfIssued = curCert->IsSelfIssued();
00319 
00320         //mod to support Technical Corrigendum 2 - 02/13/03 CRW
00321         //Technical Corrigendum 2 Item 2) Self-signed certs, if encountered in the path, are ignored
00322         if(isSelfIssued)
00323         {
00324             //CPKIFCertificatePtr curCert2 = curCert;
00325             //CPKIFCAPIRaw raw;
00326 
00330             //if(raw.VerifyCertificate(*curCert, *curCert2))
00331             //  continue;
00332             if(curCert->IsSelfSigned())
00333                 continue;
00334         }
00335         else 
00336         {
00337             //prepare for next cert
00338             //if cert is not self-issued decrement the path length
00339             if(bPathLength)
00340                 --nPathLength;
00341         }
00342 
00343         //10.5.1 a) Check that the signature verifies, that dates are valid, that the certificate 
00344         //          subject and certificate issuer names chain correctly, and that the certificate 
00345         //          has not been revoked.
00346         //alg check is precursor to signature check, which occurs outside of this function
00347         CPKIFAlgorithmIdentifierPtr prevCertSigAlg = prevCert->GetSubjectPublicKeyInfo()->alg();
00348         CPKIFAlgorithmIdentifierPtr curCertSigAlg = curCert->SignatureAlgorithm();
00349         AlgClass prevAC = GetAlgClass(prevCertSigAlg);
00350         AlgClass curAC = GetAlgClass(curCertSigAlg);
00351         if(prevAC != curAC)
00352         {
00353             ERROR_OVERRIDE(PATH_SIGNATURE_VERIFICATION_FAILED);
00354         }
00355 
00356 #ifdef _DEBUG_PATH
00357         const char* curCertString = curCert->Subject()->ToString();
00358         cout << "Processing certificate with subject: " << curCertString << endl;
00359 #endif
00360 
00361         //perform name chaining check
00362         if(!(*lastCertName == *curCert->Issuer()))
00363         {
00364 #ifdef _DEBUG_PATH
00365             cout << lastCertName->ToString() << " != " <<  curCert->Issuer()->ToString() << endl;
00366 #endif
00367             
00368             ERROR_OVERRIDE(PATH_NAME_CHAINING_VIOLATION);
00369         }
00370 
00371         lastCertName = curCert->Subject();
00372         prevCert = dynamic_cast<IPKIFNameAndKey*>(&(*(curCert)));
00373 
00374         //perform validity period check
00375         CPKIFValidityPtr val = curCert->Validity();
00376         CPKIFTimePtr startTime = val->notBefore();
00377         CPKIFTimePtr endTime = val->notAfter();
00378         if(*curTime < *startTime)
00379         {
00380             ERROR_OVERRIDE(PATH_VALIDITY_PERIOD_VIOLATION_NOT_YET_VALID);
00381         }
00382 
00383         if(*curTime > *endTime)
00384         {
00385             ERROR_OVERRIDE(PATH_VALIDITY_PERIOD_VIOLATION_EXPIRED);
00386         }
00387 
00388         //check policy stuff
00389         CPKIFPolicyInformationSetPtr certPols = curCert->GetExtension<CPKIFPolicyInformationSet>();
00390         if(certPols != (CPKIFPolicyInformationSet*)NULL)
00391         {
00392             //10.5.1 d), e) and f) inside AddPoliciesToAuthSet
00393             AddPoliciesToAuthSet(certPols, indicators, *authSet, isSelfIssued, pos+1 != end);
00394             CPKIFX509ExtensionPtr cp2 = certPols;
00395             (*pos)->MarkExtensionAsProcessed(cp2);
00396         }
00397         else
00398         {
00399             //certificate policies extension was not present
00400             //remove all rows from the authority constrained set
00401             //10.5.1 c) If the certificate policies extension is not present, then set 
00402             //          the authorities-constrained-policy-set to null by deleting all 
00403             //          rows from the authorities-constrained-policy-set table.
00404             authSet->clear();
00405         }
00406 
00407         //10.5.1 g) If the certificate is not an intermediate self-issued certificate, 
00408         //          check that the subject name is within the name-space given by the 
00409         //          value of permitted-subtrees and is not within the name-space given 
00410         //          by the value of excluded-subtrees.
00411         if(!(pos+1 != end && isSelfIssued))
00412         {
00413             try
00414             {
00415                 //inspect name constraints
00416                 if(!CheckNameConstraints(curCert, permSubtrees, exclSubtrees, permSubtreesSet))
00417                 {
00418                     ERROR_OVERRIDE(PATH_NAME_CONSTRAINTS_VIOLATION);
00419                 }
00420             }
00421             catch(CPKIFException&e)
00422             {
00423                 if(e.GetErrorCode() == ASN1_DECODE_ERROR && strcmp(e.GetDescription(), "encountered malformed uriName") ==  0)
00424                 {
00425                     ERROR_OVERRIDE(PATH_NAME_CONSTRAINTS_VIOLATION);
00426                 }
00427                 else
00428                 {
00429                     throw e;
00430                 }
00431             }
00432         }
00433 
00434         //we'll need policy constraints both in the intermediate cert check block and below out of the block
00435         CPKIFPolicyConstraintsPtr policyConstraints = curCert->GetExtension<CPKIFPolicyConstraints>();
00436 
00437         if(pos+1 != end)//perform intermediate only processing
00438         {
00439             if(bPathLength && nPathLength < 0)
00440             {
00441                 ERROR_OVERRIDE(PATH_LENGTH_VIOLATION);
00442             }
00443 
00444             //basicConstraints (incl. path length)
00445             CPKIFBasicConstraintsPtr basicConstraints = curCert->GetExtension<CPKIFBasicConstraints>();
00446             bool isCA = false;
00447             if(basicConstraints != (CPKIFBasicConstraints*)NULL)
00448             {
00449                 CPKIFX509ExtensionPtr basicConstraints2 = basicConstraints;
00450                 (*pos)->MarkExtensionAsProcessed(basicConstraints2);
00451 
00452                 if(basicConstraints->isCA())
00453                     isCA = true;
00454 
00455                 if(basicConstraints->pathLengthPresent())
00456                 {
00457                     if(bPathLength)
00458                         nPathLength = min(nPathLength, basicConstraints->pathLength());
00459                     else
00460                     {
00461                         bPathLength = true;
00462                         nPathLength = basicConstraints->pathLength();
00463                     }
00464                 }
00465             }
00466 
00467             if(!isCA)
00468             {
00469                 //either there's no basicConstraints or there is one and CA is not set to true
00470                 ERROR_OVERRIDE(PATH_BASIC_CONSTRAINTS_VIOLATION);
00471             }
00472 
00473             CPKIFKeyUsagePtr keyUsage = curCert->GetExtension<CPKIFKeyUsage>();
00474             if(keyUsage != (CPKIFKeyUsage*)NULL)
00475             {
00476                 CPKIFX509ExtensionPtr keyUsage2 = keyUsage;
00477                 (*pos)->MarkExtensionAsProcessed(keyUsage2);
00478 
00479                 //if there's a key usage present (critical or otherwise) we process it
00480                 if(!keyUsage->KeyCertSign())
00481                 {
00482                     ERROR_OVERRIDE(PATH_KEY_USAGE_VIOLATION);
00483                 }
00484             }
00485 
00486             //10.5.2 a) If the nameConstraints extension with a permittedSubtrees component is present 
00487             //          in the certificate, set the permitted-subtrees state variable to the intersection 
00488             //          of its previous value and the value indicated in the certificate extension.
00489             //10.5.2 b) If the nameConstraints extension with an excludedSubtrees component is present 
00490             //          in the certificate, set the excluded-subtrees state variable to the union of its 
00491             //          previous value and the value indicated in the certificate extension.
00492             //check name constraints
00493             CPKIFNameConstraintsPtr nameConstraints = curCert->GetExtension<CPKIFNameConstraints>();
00494             if(nameConstraints != (CPKIFNameConstraints*)NULL)
00495             {
00496                 try
00497                 {
00498                     //get the permitted subtrees and calculate the intersection
00499                     CPKIFGeneralSubtreeListPtr perm = nameConstraints->GetPermitted();
00500                     if(perm != (CPKIFGeneralSubtreeList*)NULL)
00501                     {
00502                         CPKIFGeneralSubtreeListPtr tmpSubtrees(new CPKIFGeneralSubtreeList);
00503                         IntersectSubtrees(perm, permSubtrees, tmpSubtrees);
00504                         permSubtrees = tmpSubtrees;
00505                         if(!permSubtreesSet)
00506                             permSubtreesSet = permSubtrees->empty();
00507                     }
00508 
00509                     CPKIFGeneralSubtreeListPtr excl = nameConstraints->GetExcluded();
00510                     if(excl != (CPKIFGeneralSubtreeList*)NULL)
00511                     {
00512                         CPKIFGeneralSubtreeList::iterator exclPos;
00513                         CPKIFGeneralSubtreeList::iterator exclEnd = excl->end();
00514                         for(exclPos = excl->begin(); exclEnd != exclPos; ++exclPos)
00515                             exclSubtrees->push_back(*exclPos);
00516                     }
00517 
00518                     CPKIFX509ExtensionPtr nameConstraints2 = nameConstraints;
00519                     (*pos)->MarkExtensionAsProcessed(nameConstraints2);
00520                 }
00521                 catch(CPKIFException& e)
00522                 {
00523                     //if name constraints is critical and we don't understand a name form - fail
00524                     //otherwise continue processing
00525                     if(nameConstraints->isCritical())
00526                         throw e;
00527                     //else
00528                     //  delete e;
00529                 }
00530             }
00531 
00532             //process policy mapping
00533             CPKIFPolicyMappingsPtr policyMappings = curCert->GetExtension<CPKIFPolicyMappings>();
00534             if(policyMappings != (CPKIFPolicyMappings*)NULL)
00535             {
00536                 ProcessPolicyMapping(policyMappings, indicators, *authSet);
00537                 CPKIFX509ExtensionPtr policyMappings2 = policyMappings;
00538                 (*pos)->MarkExtensionAsProcessed(policyMappings2);
00539             }
00540 
00541             //10.5.2 d) if the policy-mapping-inhibit-pending indicator is set and the certificate 
00542             //is not self-issued, decrement the corresponding skip-certificates value 
00543             //and, if this value becomes zero, set the policy-mapping-inhibit-indicator.
00544             if(bPendingPolicyMapping && !isSelfIssued && !indicators[CPKIFPathSettings::POLICY_MAPPING])
00545             {
00546                 --nPendingPolicyMapping;
00547                 if(0 == nPendingPolicyMapping)
00548                 {
00549                     indicators.set(CPKIFPathSettings::POLICY_MAPPING);
00550                 }
00551             }
00552 
00553             if(policyConstraints != (CPKIFPolicyConstraints*)NULL)
00554             {
00555                 if(policyConstraints->InhibitPolicyMappingPresent())
00556                 {
00557                     if(bPendingPolicyMapping)
00558                         nPendingPolicyMapping = min(nPendingPolicyMapping, policyConstraints->InhibitPolicyMapping());
00559                     else
00560                     {
00561                         bPendingPolicyMapping = true;
00562                         nPendingPolicyMapping = policyConstraints->InhibitPolicyMapping();
00563                     }
00564                 }
00565 
00566                 //added 02/10/03 - CRW
00567                 if(0 == nPendingPolicyMapping)
00568                     indicators.set(CPKIFPathSettings::POLICY_MAPPING);
00569 
00570                 CPKIFX509ExtensionPtr policyConstraints2 = policyConstraints;
00571                 (*pos)->MarkExtensionAsProcessed(policyConstraints2);
00572             }
00573 
00574             //10.5.2 e) For any row not modified in either step c) or d), above (and every row in 
00575             //the case that there is no mapping extension present in the certificate), write the 
00576             //policy identifier from [path-depth] column in the [path-depth+1] column of the row.
00577             vector<CPKIFPolicyInformationListPtr>::iterator authSetPos;
00578             vector<CPKIFPolicyInformationListPtr>::iterator authSetEnd = authSet->end();
00579             const size_t pathDepthPlusOne = pathDepth + 1;
00580             for(authSetPos = authSet->begin(); authSetPos != authSetEnd; ++authSetPos)
00581             {
00582                 const size_t curSize = (*authSetPos)->size();
00583                 if(curSize == pathDepthPlusOne)
00584                 {
00585                     CPKIFPolicyInformationPtr lastPol = (*authSetPos)->back();
00586                     (*authSetPos)->push_back(lastPol);
00587                 }
00588             }
00589 
00590             //10.5.2 f) f)  If inhibit-any-policy-indicator is not set:
00591             //If the inhibit-any-policy-pending indicator is set and the certificate is not self-issued, 
00592             //decrement the corresponding skip-certificates value and, if this value becomes zero, set the 
00593             //inhibit-any-policy-indicator.
00594             //If the inhibitAnyPolicy constraint is present in the certificate, perform the following. 
00595             //For a SkipCerts value of 0, set the inhibit-any-policy-indicator. For any other SkipCerts value, 
00596             //set the inhibit-any-policy-pending indicator, and set the corresponding skip-certificates value 
00597             //to the lesser of the SkipCerts value and the previous skip-certificates value (if the 
00598             //inhibit-any-policy-pending indicator was already set).
00599             if(bPendingAnyPolicy && !isSelfIssued && !indicators[CPKIFPathSettings::ANY_POLICY])
00600             {
00601                 --nPendingAnyPolicy;
00602                 if(0 == nPendingAnyPolicy)
00603                 {
00604                     indicators.set(CPKIFPathSettings::ANY_POLICY);
00605                 }
00606             }
00607 
00608             CPKIFInhibitAnyPolicyPtr inhibitAnyPolicy = curCert->GetExtension<CPKIFInhibitAnyPolicy>();
00609             if(inhibitAnyPolicy != (CPKIFInhibitAnyPolicy*)NULL)
00610             {
00611                 CPKIFX509ExtensionPtr inhibitAnyPolicy2 = inhibitAnyPolicy;
00612                 (*pos)->MarkExtensionAsProcessed(inhibitAnyPolicy2);
00613 
00614                 if(!indicators[CPKIFPathSettings::ANY_POLICY])
00615                 {
00616                     if(bPendingAnyPolicy)
00617                         nPendingAnyPolicy = min(nPendingAnyPolicy, inhibitAnyPolicy->SkipCerts());
00618                     else
00619                     {
00620                         bPendingAnyPolicy = true;
00621                         nPendingAnyPolicy = inhibitAnyPolicy->SkipCerts();
00622                     }
00623 
00624                     //added 02/10/03 - CRW
00625                     if(0 == nPendingAnyPolicy)
00626                         indicators.set(CPKIFPathSettings::ANY_POLICY);
00627                 }
00628             }
00629 
00630         }//end intermediate-only processing
00631         else //perform end entity processing
00632         {
00633             //check-off any of the extensions we'd typically process for an intermediate cert
00634             //but do not care about in this case so we can avoid failure due to unhandled critical extensions
00635     
00636             //do not process key usage - the application should have to provide a functor (i.e. callback) for that
00637 
00638             CPKIFBasicConstraintsPtr basicConstraints = curCert->GetExtension<CPKIFBasicConstraints>();
00639             bool isCA = false;
00640             if(basicConstraints != (CPKIFBasicConstraints*)NULL)
00641             {
00642                 CPKIFX509ExtensionPtr basicConstraints2 = basicConstraints;
00643                 (*pos)->MarkExtensionAsProcessed(basicConstraints2);
00644             }
00645 
00646             CPKIFPolicyMappingsPtr policyMappings = curCert->GetExtension<CPKIFPolicyMappings>();
00647             if(policyMappings != (CPKIFPolicyMappings*)NULL)
00648             {
00649                 //Added this non-standard row per Santosh's analysis.  This may ultimately be reflected in 3280bis.
00650                 ProcessPolicyMapping(policyMappings, indicators, *authSet);
00651 
00652                 CPKIFX509ExtensionPtr policyMappings2 = policyMappings;
00653                 (*pos)->MarkExtensionAsProcessed(policyMappings2);
00654             }
00655 
00656             CPKIFNameConstraintsPtr nameConstraints = curCert->GetExtension<CPKIFNameConstraints>();
00657             if(nameConstraints != (CPKIFNameConstraints*)NULL)
00658             {
00659                 CPKIFX509ExtensionPtr nameConstraints2 = nameConstraints;
00660                 (*pos)->MarkExtensionAsProcessed(nameConstraints2);
00661             }
00662             
00663             if(policyConstraints != (CPKIFPolicyConstraints*)NULL)
00664             {
00665                 CPKIFX509ExtensionPtr policyConstraints2 = policyConstraints;
00666                 (*pos)->MarkExtensionAsProcessed(policyConstraints2);
00667             }       
00668 
00669             CPKIFInhibitAnyPolicyPtr inhibitAnyPolicy = curCert->GetExtension<CPKIFInhibitAnyPolicy>();
00670             if(inhibitAnyPolicy != (CPKIFInhibitAnyPolicy*)NULL)
00671             {
00672                 CPKIFX509ExtensionPtr inhibitAnyPolicy2 = inhibitAnyPolicy;
00673                 (*pos)->MarkExtensionAsProcessed(inhibitAnyPolicy2);
00674             }
00675         }
00676 
00677         //10.5.3 a) if the explicit-policy-pending indicator is set and the certificate is not a 
00678         //self-issued intermediate certificate, decrement the corresponding skip-certificates value 
00679         //and, if this value becomes zero, set explicit-policy-indicator.       
00680     
00681         //changed !isSelfIssued to !(isSelfIssued && pos+1 != end) 3/11/2003 CRW
00682         //check should apply to end certs self issued or otherwise (if pos+1!=end then its an intermediate cert)
00683         if(bPendingExplicitPolicy && !(isSelfIssued && pos+1 != end) && !indicators[CPKIFPathSettings::EXPLICIT_POLICY])
00684         {
00685             --nPendingExplicitPolicy;
00686             if(0 == nPendingExplicitPolicy)
00687             {
00688                 indicators.set(CPKIFPathSettings::EXPLICIT_POLICY);
00689             }
00690         }
00691 
00692         if(policyConstraints != (CPKIFPolicyConstraints*)NULL)
00693         {
00694             //already flagged this extension as processed above
00695             if(policyConstraints->RequireExplicitPolicyPresent())
00696             {
00697                 if(bPendingExplicitPolicy)
00698                     nPendingExplicitPolicy = min(nPendingExplicitPolicy, policyConstraints->RequireExplicitPolicy());
00699                 else
00700                 {
00701                     bPendingExplicitPolicy = true;
00702                     nPendingExplicitPolicy = policyConstraints->RequireExplicitPolicy();
00703                 }
00704 
00705                 if(0 == nPendingExplicitPolicy)
00706                 {
00707                     indicators.set(CPKIFPathSettings::EXPLICIT_POLICY);
00708                 }
00709             }
00710         }
00711 
00712         if(indicators[CPKIFPathSettings::EXPLICIT_POLICY] && authSet->empty())
00713         {
00714             //go ahead and bail out if the authority set becomes NULL and 
00715             //require explicit policy is set.
00716             ERROR_OVERRIDE(PATH_NULL_AUTH_POLICY_SET);
00717         }
00718 
00719         CPKIFFuncStorageSingleton* fss = CPKIFFuncStorageSingleton::GetInstance();
00720         if(fss != (CPKIFFuncStorageSingleton*)NULL && !fss->empty())
00721         {
00722             try
00723             {
00724                 if(pos+1 == end)
00725                     (*fss)(*pos, results, EE);
00726                 else
00727                     (*fss)(*pos, results, INTERMEDIATE);
00728             }
00729             catch(CPKIFException&)
00730             {
00731                 //delete e;
00732 
00733                 ERROR_OVERRIDE(PATH_APP_DEFINED_CHECK_FAILED);
00734             }
00735         }
00736 
00737         //if there are any additional checks to perform do so now
00738         if(funcs != (CPKIFFuncStorage*)NULL && !funcs->empty())
00739         {
00740             try
00741             {
00742                 if(pos+1 == end)
00743                     (*funcs)(*pos, results, EE);
00744                 else
00745                     (*funcs)(*pos, results, INTERMEDIATE);
00746             }
00747             catch(CPKIFException&)
00748             {
00749                 //delete e;
00750 
00751                 ERROR_OVERRIDE(PATH_APP_DEFINED_CHECK_FAILED);
00752             }
00753         }
00754 
00755         //make sure critical subAltNames do not trip us up - 12/3/2003
00756         CPKIFSubjectAltNamePtr san = curCert->GetExtension<CPKIFSubjectAltName>();
00757         if(san != (CPKIFSubjectAltName*)NULL)
00758         {
00759             CPKIFX509ExtensionPtr san2 = san;
00760             (*pos)->MarkExtensionAsProcessed(san2);
00761         }
00762 
00763         //make sure all critical extensions have been processed
00764         if((*pos)->AreThereAnyUnprocessedCriticalExtensions())
00765         {
00766             ERROR_OVERRIDE(PATH_UNPROCESSED_CRITICAL_EXTENSION);
00767         }
00768 
00769         //update the status for the current node to reflect the fact that all 
00770         //basic validation checks were successfully performed
00771         (*pos)->GetStatus()->SetPassedValidationChecks(true);
00772     }//end iteration over path members
00773 
00774     //set up the results of this validation effort
00775 //  results.SetAuthorityConstrainedSet(authSet);
00776 
00777     CPKIFPolicyInformationListPtr userSet(new CPKIFPolicyInformationList), initSet, authSetCondensed;
00778     results.GetAuthorityConstrainedSet(authSetCondensed);
00779 
00780     if(settings != (CPKIFPathSettings*)NULL)
00781         settings->GetInitialPolicySet(initSet);
00782     
00783     CPKIFPolicyInformationPtr anyPolicyPI(new CPKIFPolicyInformation(anyPolicy));
00784 
00785     if(initSet != (CPKIFPolicyInformationList*)NULL && !initSet->empty() && *anyPolicyPI == *initSet->front())
00786     {
00787         //if the initial policy set is not NULL, not empty and contains any policy then the
00788         //user set is the auth set
00789         userSet = authSetCondensed; 
00790     }
00791     else if(authSetCondensed != (CPKIFPolicyInformationList*)NULL && !authSetCondensed->empty() && *anyPolicyPI == *authSetCondensed->front())
00792     {
00793         //if the auth set is not empty and contains any policy then the user set is the initial set
00794         userSet = initSet; 
00795     }
00796     else if(initSet != (CPKIFPolicyInformationList*)NULL && !initSet->empty())
00797     {
00798         //otherwise we need the intersection of the two
00799         IntersectSets(authSetCondensed, initSet, userSet);
00800     }
00801     //otherwise userSet is empty
00802     if(permSubtreesSet)
00803         results.SetPermittedSubtrees(permSubtrees);
00804     results.SetExcludedSubtrees(exclSubtrees);
00805     if(bPendingExplicitPolicy)
00806         results.SetPendingExplicitPolicy(nPendingExplicitPolicy);
00807     if(bPendingPolicyMapping)
00808         results.SetPendingPolicyMapping(nPendingPolicyMapping);
00809     if(bPendingAnyPolicy)
00810         results.SetPendingAnyPolicy(nPendingAnyPolicy);
00811     if(bPathLength)
00812         results.SetPendingPathLength(nPathLength);
00813 
00814     //return the userSet and the require explicit policy indicator
00815     results.SetUserConstrainedSet(userSet);
00816     results.SetExplicitPolicyIndicator(indicators[CPKIFPathSettings::EXPLICIT_POLICY]);
00817 
00818     if(isPathGood && indicators[CPKIFPathSettings::EXPLICIT_POLICY] && userSet->empty())
00819     {
00820         //if the require explicit policy indicator is true and the user set is empty then
00821         //return failure
00822 
00823         //associate the failure with the last cert in the path
00824         CPKIFCertificateNodeEntryPtr lastCert = certNodeList.back();
00825         bool override = false;
00826         bool (*fp) (int, CPKIFCertificatePtr&,const CPKIFCertificatePath&) = settings->GetOverrideCallback(); 
00827         if(NULL != fp) 
00828         { 
00829             CPKIFCertificatePtr tmpCert = lastCert->GetCert();  
00830             if(fp(PATH_NULL_USER_POLICY_SET, tmpCert/*lastCert->GetCert()*/, path))
00831                 override = true; 
00832         } 
00833         if(!override) 
00834         {
00835             CPKIFCertStatusPtr status(new CPKIFCertStatus); 
00836             status->SetDiagnosticCode(PATH_NULL_USER_POLICY_SET); 
00837             lastCert->SetStatus(status);    
00838             results.SetCertificate(lastCert); 
00839             isPathGood = false; 
00840             return false;
00841         }
00842 
00843     }
00844 
00845     //the path has earned a check mark
00846     //this should not always be setting this to true.  it should only set to true when the path is valid
00847     //fixed by changing from true to isPathGood - 2/25/2005
00848     results.SetBasicChecksSuccessfullyPerformed(isPathGood);
00849 
00850     //otherwise return the indication as set above (could be success or failure)
00851     return isPathGood;
00852 }

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