CCACX509CRLChecker.cpp

Go to the documentation of this file.
00001 
00010 #include "PKIFX509CRLChecker.h"
00011 #include "PKIFCertificatePath.h"
00012 #include "PKIFErrors.h"
00013 
00014 #include "PKIFCacheInterfaces.h"
00015 #include "PKIFPathInterfaces.h"
00016 #include "PKIFCertificatePath.h"
00017 #include "PKIFBasicPathState2.h"    //added 7/21/2005
00018 #include "GeneralNamesCompare.h"
00019 
00020 #include "Certificate.h"
00021 #include "SubjectPublicKeyInfo.h"
00022 #include "CRL.h"
00023 #include "CRLEntry.h"
00024 #include "PKIFCRLNodeEntry.h"
00025 
00026 #include "AuthorityKeyIdentifier.h"
00027 #include "SubjectKeyIdentifier.h"
00028 #include "PolicyInformationSet.h"
00029 #include "PolicyMappings.h"
00030 #include "DeltaCRLIndicator.h"
00031 
00032 #include "IssuingDistributionPoint.h"
00033 #include "CRLDistributionPoints.h"
00034 #include "CRLDistributionPoint.h"
00035 #include "DistributionPointName.h"
00036 #include "PKIFCRLInfo.h"
00037 #include "GeneralName.h"
00038 #include "AlgorithmIdentifier.h"
00039 
00040 #include "BasicConstraints.h"
00041 #include "CRLNumber.h"
00042 #include "CRLStreamIdentifier.h"
00043 #include "KeyUsage.h"
00044 #include "FreshestCRL.h"
00045 #include "Buffer.h"
00046 #include "CRLReason.h"
00047 #include "GottaMatch.h"
00048 #include "PKIFTime.h"
00049 #include "IPKIFCryptoMisc.h"
00050 #include "IPKIFCryptoRawOperations.h"
00051 #include "IPKIFHashContext.h"
00052 #include "CertificateNodeListWithSourceInfo.h"
00053 #include "PKIFPathSettings.h"
00054 #include "PKIFCertStatus.h"
00055 #include "ReasonFlags.h"
00056 #include "ASN1Helper.h"
00057 #include "PKIX1Explicit88.h"
00058 
00059 #include "IPKIFCRLRepository.h"
00060 
00061 #include "boost/numeric/conversion/cast.hpp"
00062 
00063 #include <iterator>
00064 
00065 using boost::numeric_cast;
00066 using boost::bad_numeric_cast;
00067 
00068 using namespace boost;
00069 using namespace std;
00070 
00071 //added declarations 7/21/2005 - implemented in CACDefaultScoring.cpp
00072 extern bool scoreCompare(const CPKIFCertificateNodeEntryPtr& lhs, const CPKIFCertificateNodeEntryPtr& rhs);
00073 extern bool KeyIDsMatch(CPKIFAuthorityKeyIdentifierPtr& akid, CPKIFCertificatePtr& curCert);
00074 extern bool SomeMatch(CPKIFPolicyInformationSetPtr& fromCert, CPKIFPolicyInformationListPtr& polsFromPrevCert, CPKIFPolicyMappingsPtr& policyMappings);
00075 
00076 #include "ToolkitUtils.h"
00077 #include "PKIFCryptoErrors.h"               //crypto errors
00078 #include "PKIFCryptoPPErrors.h"
00079 #include "PKIFNSSErrors.h"
00080 #include "PKIFKeyMaterial.h"
00081 
00082 extern CPKIFOIDPtr g_ocspNoCheck;
00083 
00084 //CRLs are classified based on the values found in the IssuingDistributionPoint and DeltaCRLIndicator
00085 //extension, if present, without regard for criticality.  IssuingDistributionPoint is defined as follows
00086 //(with related PKIF enumerations given as a ASN.1 comments for each field):
00087 //
00088 //  IssuingDistPointSyntax ::= SEQUENCE 
00089 //  {
00090 //      distributionPoint           [0] DistributionPointName   OPTIONAL,       -- CRLSCOPE
00091 //      onlyContainsUserCerts       [1] BOOLEAN                 DEFAULT FALSE,  -- CRLCOVERAGE
00092 //      onlyContainsAuthorityCerts  [2] BOOLEAN                 DEFAULT FALSE,  -- CRLCOVERAGE
00093 //      onlySomeReasons             [3] ReasonFlags             OPTIONAL,       -- CRLREASONS
00094 //      indirectCRL                 [4] BOOLEAN                 DEFAULT FALSE,  -- CRLAUTHORITY
00095 //      onlyContainsAttributeCerts  [5] BOOLEAN                 DEFAULT FALSE   -- CRLCOVERAGE
00096 //  }
00097 
00098 //
00099 //The DeltaCRLIndicator extension is simply an integer as defined below:
00100 //
00101 //  BaseCRLNumber ::= CRLNumber
00102 //
00103 
00104 //The CRLSCOPE enum indicates the scope of the CRL, i.e. complete, delta or distribution point (scoped by
00105 //reason or other factors).  The value is determined by inspection of the DeltaCRLIndicator and/or
00106 //the distributionPoint field of the IssuingDistributionPoint extension of the CRL.
00107 //enum CRLSCOPE {CS_COMPLETE, CS_DP, CS_DELTA, CS_DELTA_DP, CS_UNSUPPORTED};
00108 //CS_COMPLETE   : The CRL contains no DeltaCRLIndicator indicator and either has no IssuingDistributionPoint
00109 //                  extension or has an IssuingDistributionPoint extension with no distributionPoint field.
00110 //CS_DP         : The CRL contains no DeltaCRLIndicator indicator and has an IssuingDistributionPoint extension 
00111 //                  with a distributionPoint field.
00112 //CS_DELTA      : The CRL contains a DeltaCRLIndicator indicator and either has no IssuingDistributionPoint
00113 //                  extension or has an IssuingDistributionPoint extension with no distributionPoint field.
00114 //CS_DELTA_DP   : The CRL contains a DeltaCRLIndicator indicator and has an IssuingDistributionPoint extension 
00115 //                  with a distributionPoint field.
00116 //CS_UNSUPPORTED: Unsupported by PKIF - to be determined
00117 
00118 //The CRLCOVERAGE enum indicates the type(s) of entities covered by the CRL.  The value is
00119 //determined by inspection of the onlyContainsUserCerts, onlyContainsAuthorityCerts and
00120 //onlyContainsAttributeCerts fields of the IssuingDistributionPoint extension in the CRL.  CRLs that
00121 //contain more than one onlyContainsXXX field can be considered invalid and discarded.  (The fields
00122 //are logically a CHOICE and should've been defined as such.)
00123 //enum CRLCOVERAGE {CC_ALL, CC_EEONLY, CC_CAONLY, CC_UNSUPPORTED};
00124 //CC_ALL        : The CRL contains no IssuingDistributionPoint extension or has an IssuingDistributionPoint 
00125 //                  extension with no onlyContainsUserCerts, onlyContainsAuthorityCerts or onlyContainsAttributeCerts
00126 //                  fields.
00127 //CC_EEONLY     : The CRL contains an IssuingDistributionPoint extension with onlyContainsUserCerts present.
00128 //CC_CAONLY     : The CRL contains an IssuingDistributionPoint extension with onlyContainsAuthorityCerts present.
00129 //CC_UNSUPPORTED: Unsupported by PKIF - the CRL contains an IssuingDistributionPoint extension with 
00130 //                  onlyContainsAttributeCerts present.
00131 
00132 //The CRLCOVERAGE value determines the attributes to search when retrieving CRLs from a directory.
00133 //Below are the relationship between each enumerated value and directory attributes:
00134 //  CC_ALL      : certificateRevocationList, authorityRevocationList
00135 //  CC_EEONLY   : certificateRevocationList
00136 //  CC_CAONLY   : authorityRevocationList
00137 
00138 //The CRLAUTHORITY enum indicates whether or not the CRL includes revocation notifications for CAs other
00139 //than the issuer of the CRL.  The value is determined by inspection of the indirectCRL field of the 
00140 //IssuingDistributionPoint extension of the CRL.
00141 //enum CRLAUTHORITY {CA_DIRECT, CA_INDIRECT};
00142 //CA_DIRECT     : The CRL contains no IssuingDistributionPoint extension or has an IssuingDistributionPoint 
00143 //                  extension with no indirectCRL field.
00144 //CA_INDIRECT   : The CRL contains an IssuingDistributionPoint extension with indirectCRL present.
00145 
00146 //The CRLREASONS enum indicates whether or not the CRL covers all reason codes or a subset.  The value is 
00147 //determined by inspection of the onlySomeReasons field of the IssuingDistributionPoint extension of the CRL.
00148 //enum CRLREASONS {CR_ALLREASONS, CR_SOMEREASONS};
00149 //CR_ALLREASONS : The CRL contains no IssuingDistributionPoint extension or has an IssuingDistributionPoint 
00150 //                  extension with no onlySomeReasons field.
00151 //CR_SOMEREASONS: The CRL contains an IssuingDistributionPoint extension with onlySomeReasons present.
00152 
00153 //Annex B of X.509 defines the following types of CRLs (given below along with CRLCOVERAGE, CRLSCOPE
00154 //and CRLAUTHORITY values that define the type)
00155 //- Full and complete CRL,              (CC_ALL,    CS_COMPLETE,    CA_DIRECT)
00156 //                    EPRL,             (CC_EEONLY, CS_COMPLETE,    CA_DIRECT)
00157 //                    or CARL;          (CC_CAONLY, CS_COMPLETE,    CA_DIRECT)
00158 
00159 //- Indirect CRL,                       (CC_ALL,    CS_COMPLETE,    CA_INDIRECT) 
00160 //           EPRL                       (CC_EEONLY, CS_COMPLETE,    CA_INDIRECT)
00161 //           or CARL (ICRL);            (CC_CAONLY, CS_COMPLETE,    CA_INDIRECT)
00162 
00163 //- Delta CRL (dCRL),                   (CC_ALL,    CS_DELTA,       CA_DIRECT)
00164 //        dEPRL                         (CC_EEONLY, CS_DELTA,       CA_DIRECT)
00165 //        or dCARL;                     (CC_CAONLY, CS_DELTA,       CA_DIRECT)
00166 
00167 //- Indirect dCRL,                      (CC_ALL,    CS_DELTA,       CA_INDIRECT)
00168 //           dEPRL                      (CC_EEONLY, CS_DELTA,       CA_INDIRECT)
00169 //           or dCARL.                  (CC_CAONLY, CS_DELTA,       CA_INDIRECT)
00170 
00171 //- Distribution Point CRL,             (CC_ALL,    CS_DP,          CA_DIRECT)
00172 //                     EPRL             (CC_EEONLY, CS_DP,          CA_DIRECT)
00173 //                     or CARL;         (CC_CAONLY, CS_DP,          CA_DIRECT)
00174 
00175 //Annex B of X.509 does not identify Indirect Distribution Point CRLs, Delta Distribution Point CRLs
00176 //or Indirect Delta Distribution Point CRLs
00177 //- Indirect Distribution Point CRL,    (CC_ALL,    CS_DP,          CA_INDIRECT)
00178 //                              EPRL    (CC_EEONLY, CS_DP,          CA_INDIRECT)
00179 //                              or CARL;(CC_CAONLY, CS_DP,          CA_INDIRECT)
00180 
00181 //- Delta Distribution Point CRL,       (CC_ALL,    CS_DELTA_DP,    CA_DIRECT)
00182 //        EPRL                          (CC_EEONLY, CS_DELTA_DP,    CA_DIRECT)
00183 //        or CARL;                      (CC_CAONLY, CS_DELTA_DP,    CA_DIRECT)
00184 
00185 //- Indirect Delta Distrib. Point CRL,  (CC_ALL,    CS_DELTA_DP,    CA_INDIRECT)
00186 //           EPRL                       (CC_EEONLY, CS_DELTA_DP,    CA_INDIRECT)
00187 //           or CARL.                   (CC_CAONLY, CS_DELTA_DP,    CA_INDIRECT)
00188 
00189 //For each of the 24 types of CRLs identified above there are 2 possible varieties: CR_ALLREASONS, CR_SOMEREASONS.
00190 //There are 48 types of CRLs in total.
00191 
00192 //6 types of certificates are defined (in CPKIFX509CRLChecker.h)
00193 //enum CERTTYPES {CT_EE_CRIT, CT_EE_NONCRIT, CT_EE, CT_CA_CRIT, CT_CA_NONCRIT, CT_CA, CT_UNSUPPORTED};
00194 //enum CRLSCOPE {CS_COMPLETE, CS_DP, CS_DELTA, CS_DELTA_DP, CS_UNSUPPORTED};
00195 bool g_CompatibleScope[CPKIFX509CRLChecker::CT_UNSUPPORTED][CPKIFX509CRLChecker::CS_UNSUPPORTED] = {
00196     {true, true, true, true},
00197     {true, false, true, false},
00198     {true, true, true, true},
00199     {true, false, true, false}
00200 };
00201 
00202 //enum CRLCOVERAGE {CC_ALL, CC_EEONLY, CC_CAONLY, CC_UNSUPPORTED};
00203 bool g_CompatibleCoverage[CPKIFX509CRLChecker::CT_UNSUPPORTED][CPKIFX509CRLChecker::CC_UNSUPPORTED] = {
00204     {true, true, false},
00205     {true, true, false},
00206     {true, false, true},
00207     {true, false, true}
00208 };
00209 
00210 //
00211 //End-entity certificate with critical CRL DP or freshestCRL        (CT_EE_CRIT)
00212 //End-entity certificate with non-critical CRL DP or freshestCRL    (CT_EE_NONCRIT)
00213 //End-entity certificate with no CRL DP nor freshestCRL             (CT_EE)
00214 
00215 //CA certificate with critical CRL DP or freshestCRL                (CT_CA_CRIT)
00216 //CA certificate with non-critical CRL DP or freshestCRL            (CT_CA_NONCRIT)
00217 //CA certificate with no CRL DP nor freshestCRL                     (CT_CA)
00218 
00219 //The CRL types that are permissible for each type of certificate are given below.
00220 //CRLREASONS are not considered as either value is always permissible from a validation point of view
00221 //and depend on the reason codes of interest indicated by an application.  CRLAUTHORITY is not considered
00222 //as either value is always permissible.  The total number of permissible CRLs for each cert type is 
00223 //always the number identified below multiplied by four.
00224 
00225 //End-entity certificate with non-critical CRL DP or freshestCRL    (CT_EE_CRIT)
00226 //PERMISSIBLE TYPES (8)
00227 //  - CRLSCOPE      : CS_COMPLETE, CS_DP, CS_DELTA, CS_DELTA_DP
00228 //  - CRLCOVERAGE   : CC_ALL, CC_EEONLY
00229 
00230 //End-entity certificate with non-critical CRL DP or freshestCRL    (CT_EE_NONCRIT)
00231 //PERMISSIBLE TYPES (8)
00232 //  - CRLSCOPE      : CS_COMPLETE, CS_DP, CS_DELTA, CS_DELTA_DP
00233 //  - CRLCOVERAGE   : CC_ALL, CC_EEONLY
00234 
00235 //End-entity certificate with no CRL DP nor freshestCRL             (CT_EE)
00236 //PERMISSIBLE TYPES (4)
00237 //  - CRLSCOPE      : CS_COMPLETE, CS_DELTA
00238 //  - CRLCOVERAGE   : CC_ALL, CC_EEONLY
00239 
00240 //CA certificate with non-critical CRL DP or freshestCRL            (CT_CA_CRIT)
00241 //PERMISSIBLE TYPES (8)
00242 //  - CRLSCOPE      : CS_COMPLETE, CS_DP, CS_DELTA, CS_DELTA_DP
00243 //  - CRLCOVERAGE   : CC_ALL, CC_CAONLY
00244 
00245 //CA certificate with non-critical CRL DP or freshestCRL            (CT_CA_NONCRIT)
00246 //PERMISSIBLE TYPES (8)
00247 //  - CRLSCOPE      : CS_COMPLETE, CS_DP, CS_DELTA, CS_DELTA_DP
00248 //  - CRLCOVERAGE   : CC_ALL, CC_CAONLY
00249 
00250 //CA certificate with no CRL DP nor freshestCRL                     (CT_CA)
00251 //PERMISSIBLE TYPES (4)
00252 //  - CRLSCOPE      : CS_COMPLETE, CS_DELTA
00253 //  - CRLCOVERAGE   : CC_ALL, CC_CAONLY
00254 
00255 //CRL Processing Steps 
00256 //
00257 //1)    Classify the target certificate as one of the 4 types of certificate 
00258 //2)    Determine the CRLs to obtain  
00259 //      a.  Identify the CRL types that apply (i.e. consult a static table w/ permissible CRLCOVERAGE and 
00260 //          CRLSCOPE values for each cert type) 
00261 //      b.  Identify locations from which to retrieve CRLs (i.e. certificate issuer directory entry vs. 
00262 //          CRLDP/freshestCRL) 
00263 //3)    Obtain CRL(s) - fail if no CRLs can be obtained 
00264 //4)    For each CRL, determine CRL and cert compatibility 
00265 //      a.  Confirm that the CRL type and cert type are compatible (discard CRL upon failure) 
00266 //      b.  Validate CRL issuer name (discard CRL upon failure) 
00267 //          i.  One of the names in a CRL DP crlIssuer field or the cert issuer shall match the CRL issuer.  
00268 //              If a CRL DP produced the match, set the active CRLDP state variable to the CRL DP containing 
00269 //              matching crlIssuer field.  
00270 //      c.  Validate DP (discard CRL upon failure) 
00271 //          i.  If the active CRL DP is set and an IDP w/distribution point field is present in the CRL, one 
00272 //              of the names in the active CRL DP shall match one of the names in the IDP DP.  If the active 
00273 //              CRL DP is not set and an IDP w/distribution point field is present, one of the names in a CRL 
00274 //              DP shall match one of the names in the IDP DP and the active CRL DP should be set to the CRL 
00275 //              DP that matches the IDP.  
00276 //          ii. If reasons field is present in the active CRL DP, the onlySomeReasons field of the IDP shall 
00277 //              be absent or contain at least one of the reason codes asserted in the CRL DP 
00278 //      d.  Validate CRL authority (discard CRL upon failure) 
00279 //          i.  If the CRL issuer name does not match the cert issuer name, the indirectCRL field must be 
00280 //              present in the IDP. 
00281 //5)    For each CRL, determine CRL validity
00282 //      a.  Currency check (discard CRL upon failure)
00283 //      b.  Signature check (discard CRL upon failure)
00284 //      c.  Validate delta scope (upon failure discard the CRL or set it aside pending acquisition of 
00285 //          additional CRLs)
00286 //      d.  Process remaining CRL extensions
00287 //6)    Determine if all necessary CRLs were obtained 
00288 //      a.  Process critical CRL DP and/or freshestCRL extensions (if requirements are not met try to obtain 
00289 //          additional CRLs or fail)
00290 //      b.  Process reason codes of interest (If requirements are not met try to obtain additional CRLs or fail) 
00291 //      c.  Discard extraneous CRLs (optional) 
00292 //7)    For each CRL, review revocation notifications
00293 //      a.  Check certificate status 
00294 //          i.  If certificate is found on a CRL, process any CRL entry extensions
00295 
00296 
00297 #include "CRLType.h"
00299 struct CPKIFX509CRLCheckerImpl {
00300   // "parent" will hold a pointer to encapsulating class.
00301   // This is used so we have a handle to CPKIFX509CRLChecker,
00302   // allowing us to access its attributes.
00303   CPKIFX509CRLChecker *m_parent;
00304 
00312     CPKIFX509CRLCheckerImpl () 
00313     {
00314     m_parent = 0;
00315     }
00323     CPKIFX509CRLCheckerImpl (CPKIFX509CRLChecker  *p) 
00324     {
00325     m_parent = p;
00326     }
00327   
00328   CPKIFReasonFlagsPtr m_reasons;
00329   CPKIFPathSettingsPtr m_settings;
00330 
00331   //status check function that is invoked by both CheckStatus and CheckStatusPath from the public interface
00332   bool CheckStatusInternal(const CPKIFCertificatePtr& targetCert, IPKIFNameAndKey* issuersCertNK, const CPKIFCertificatePtr& issuersCert,
00333                            RevocationStatus& status, CPKIFCertStatusPtr& certStatus, bool validatePathToDirectCRLs, CPKIFPathSettingsPtr& settings, IPKIFTrustAnchorPtr& rootFromPath);
00334 
00335   //functions that implement the CRL processing steps defined at the top of CACX509CRLChecker.cpp
00336   //1) performed in CheckStatusInternal (simple call to ClassifyCert)
00337   //2) handled by cache colleagues
00338   //3)
00339   void ObtainCRLs(const CPKIFCertificatePtr& targetCert, PKIInfoSource& source, CPKIFCRLList& crlList, CPKIFPathSettingsPtr& settings);
00340   //4 & 5)
00341   void DetermineCompatibilityAndValidity(const CPKIFCertificatePtr& targetCert, IPKIFNameAndKey* issuersCertNK,  const CPKIFCertificatePtr& issuersCert,
00342                                          CPKIFCRLList& crlList, bool validatePathToDirectCRLs, CPKIFCRLList& quarantinedCRLs, CPKIFPathSettingsPtr& settings,AssociatedCRLsList& acl, IPKIFTrustAnchorPtr& rootFromPath);
00343   //6)
00344   bool DoWeHaveEverythingWeNeed(const CPKIFCertificatePtr& targetCert, CPKIFCRLList& crlList, CPKIFCRLList& quarantinedCRLs); 
00345   //7) performed by following two functions
00346   void SeeIfCertHasBeenRevoked(const CPKIFCertificatePtr& targetCert, AssociatedCRLsList& crlList,
00347                                RevocationStatus& status, CPKIFCertStatusPtr& certStatus, CPKIFCRLInfoPtr& crlInfo);
00348 
00349   //functions that are called by the above functions
00350   //commented out unused function - the path building stuff was 
00351   //directly invoked in indirectCRL cases without using this function
00352   //8/26/2004
00353   //    bool ValidatePath(CPKIFCertificatePtr& signersCert);
00354   bool PerformCurrencyAndSignatureChecks(const CPKIFCertificatePtr& targetCert, 
00355                                          IPKIFNameAndKey* issuersCertNK, const CPKIFCertificatePtr& issuersCert, CPKIFCRLPtr& crl, const CPKIFX509CRLChecker::CRLAUTHORITY authority, 
00356                                          bool validatePathToDirectCRLs, std::vector<CPKIFX509ExtensionPtr>& processedExts, bool requireFresh, CPKIFPathSettingsPtr& settings, IPKIFTrustAnchorPtr& rootFromPath); //added settings param 9/26/03
00357                                                                                                                                                                                                                 //added root param 4/6/06
00358 };
00360 //----------------------------------------------------------------------------------------------------
00361 //
00362 //  functions classify certs and crls
00363 //
00364 //----------------------------------------------------------------------------------------------------
00372 CPKIFCRLTypePtr _TypeOfCRL(
00374     const CPKIFCRLPtr& crl)
00375 {
00376     LOG_STRING_DEBUG("_TypeOfCRL", TOOLKIT_PATH_MISC, 0, NULL);
00377 
00378     //This function will determine the "type" of CRL in terms of X.509 Annex B.  The are 48 types
00379     //of CRLs.  Four enumerations comprise the CRL classification system.
00380 
00381     //Below we will inspect the extensions in the CRL and ask a series of yes/no questions.  
00382     //The answers to these questions will be collected in the following bitset
00383     //and analyzed below to determine the "type" of CRL.
00384     enum QUESTIONS {ARE_YOU_EE_ONLY = 0, ARE_YOU_CA_ONLY, ARE_YOU_AA_ONLY,
00385                     ARE_YOU_DELTA, ARE_YOU_DP, ARE_YOU_INDIRECT, ONLY_SOME_REASONS};
00386     std::bitset<7> questionnaire;
00387     questionnaire.reset();
00388 
00389     //get the extensions of interest, if present
00390     CPKIFDeltaCRLIndicatorPtr delta = crl->GetExtension<CPKIFDeltaCRLIndicator>();
00391     CPKIFIssuingDistributionPointPtr idp = crl->GetExtension<CPKIFIssuingDistributionPoint>();
00392 
00393     CPKIFCRLTypePtr type(new CPKIFCRLType);
00394 
00395     //if neither are present then we have a complete CRL
00396     if(delta == (CPKIFDeltaCRLIndicator*)NULL && idp == (CPKIFIssuingDistributionPoint*)NULL)
00397     {
00398         type->SetCRLCoverage(CPKIFX509CRLChecker::CC_ALL);
00399         type->SetCRLScope(CPKIFX509CRLChecker::CS_COMPLETE);
00400         type->SetCRLAuthority(CPKIFX509CRLChecker::CA_DIRECT);
00401         type->SetCRLReasons(CPKIFX509CRLChecker::CR_ALLREASONS);
00402         return type;
00403     }
00404 
00405     //if delta extension is present, set corresponding flag in questionnaire
00406     if(delta != (CPKIFDeltaCRLIndicator*)NULL)
00407         questionnaire.set(ARE_YOU_DELTA, true);
00408 
00409     //if delta extension is present, ask series of questions
00410     if(idp != (CPKIFIssuingDistributionPoint*)NULL)
00411     {
00412         //The IDP structure is clumsily constructed.  We will query the 
00413         //three "only contains" fields as if they were a choice, as they should've
00414         //been defined in the first place.  If after discovering a set "only contains" 
00415         //flag we learn that other flags are set we leave the type set to UNSUPPORTED
00416         //(in absence of a BUSTED enum value) and return.
00417         if(idp->OnlyContainsUserCerts())
00418         {
00419             if(idp->OnlyContainsAuthorityCerts() || idp->OnlyContainsAttributeCerts())
00420                 return type;
00421             questionnaire.set(ARE_YOU_EE_ONLY, true);
00422         }
00423         else if(idp->OnlyContainsAuthorityCerts())
00424         {
00425             if(idp->OnlyContainsUserCerts() || idp->OnlyContainsAttributeCerts())
00426                 return type;
00427             questionnaire.set(ARE_YOU_CA_ONLY, true);
00428         }
00429         else if(idp->OnlyContainsAttributeCerts())
00430         {
00431             if(idp->OnlyContainsUserCerts() || idp->OnlyContainsAuthorityCerts())
00432                 return type;
00433             questionnaire.set(ARE_YOU_AA_ONLY, true);
00434         }
00435 
00436         //next ask if it's indirect
00437         if(idp->IndirectCRL())
00438             questionnaire.set(ARE_YOU_INDIRECT, true);
00439 
00440         //now see if it's a DP
00441         CPKIFDistributionPointNamePtr dp = idp->DistributionPoint();
00442         if(dp != (CPKIFDistributionPointName*)NULL)
00443             questionnaire.set(ARE_YOU_DP, true);
00444 
00445         //see if it has some reasons or all
00446         if(idp->OnlySomeReasons())
00447             questionnaire.set(ONLY_SOME_REASONS, true);
00448 
00449     }
00450 
00451     //having completed the questionnaire, analyze the results
00452     if(!questionnaire[ARE_YOU_AA_ONLY])
00453     {
00454         //determine coverage
00455         if(questionnaire[ARE_YOU_EE_ONLY])
00456             type->SetCRLCoverage(CPKIFX509CRLChecker::CC_EEONLY);
00457         else if(questionnaire[ARE_YOU_CA_ONLY])
00458             type->SetCRLCoverage(CPKIFX509CRLChecker::CC_CAONLY);
00459         else
00460             type->SetCRLCoverage(CPKIFX509CRLChecker::CC_ALL);
00461 
00462         //determine authority
00463         if(questionnaire[ARE_YOU_INDIRECT])
00464             type->SetCRLAuthority(CPKIFX509CRLChecker::CA_INDIRECT);
00465         else
00466             type->SetCRLAuthority(CPKIFX509CRLChecker::CA_DIRECT);
00467 
00468         //determine scope
00469         if(questionnaire[ARE_YOU_DP])
00470             type->SetCRLScope(CPKIFX509CRLChecker::CS_DP);
00471         else if(questionnaire[ARE_YOU_DELTA])
00472             type->SetCRLScope(CPKIFX509CRLChecker::CS_DELTA);
00473         else
00474             type->SetCRLScope(CPKIFX509CRLChecker::CS_COMPLETE);
00475 
00476         //determine reasons
00477         if(questionnaire[ONLY_SOME_REASONS])
00478             type->SetCRLReasons(CPKIFX509CRLChecker::CR_SOMEREASONS);
00479         else
00480             type->SetCRLReasons(CPKIFX509CRLChecker::CR_ALLREASONS);
00481     }
00482     else
00483     {
00484         //XXX-DEFER Do work here to support ACRL, AARL, etc.
00485     }
00486     return type;
00487 }
00495 CPKIFX509CRLChecker::CERTTYPES _ClassifyCert(
00497     const CPKIFCertificatePtr& targetCert)
00498 {
00499     LOG_STRING_DEBUG("_ClassifyCert", TOOLKIT_PATH_MISC, 0, NULL);
00500 
00501     //One enumeration defines the cert classification system, which is nothing more
00502     //than a check of basicConstraints and CRL DP extensions.
00503 
00504     bool isCA = false, hasCRLDP = false;
00505     CPKIFBasicConstraintsPtr bc = targetCert->GetExtension<CPKIFBasicConstraints>();
00506     if(bc != (CPKIFBasicConstraints*)NULL)
00507     {
00508         if(bc->isCA())
00509             isCA = true;
00510     }
00511 
00512     CPKIFCRLDistributionPointsPtr crlDP = targetCert->GetExtension<CPKIFCRLDistributionPoints>();
00513     if(crlDP != (CPKIFCRLDistributionPoints*)NULL)
00514     {
00515         hasCRLDP = true;
00516     }
00517 
00518     if(isCA && hasCRLDP)
00519         return CPKIFX509CRLChecker::CT_CA_DP;
00520     else if(!isCA && hasCRLDP)
00521         return CPKIFX509CRLChecker::CT_EE_DP;
00522     else if(isCA)
00523         return CPKIFX509CRLChecker::CT_CA;
00524     else
00525         return CPKIFX509CRLChecker::CT_EE;
00526 }
00527 
00528 //commented out unused functions 8/26/2004
00529 //bool _IsEE(CPKIFX509CRLChecker::CERTTYPES& ct)
00530 //{
00531 //  return ct <= CPKIFX509CRLChecker::CERTTYPES::CT_EE;
00532 //}
00533 //bool _IsCA(CPKIFX509CRLChecker::CERTTYPES& ct)
00534 //{
00535 //  return !_IsEE(ct);
00536 //}
00537 
00538 //----------------------------------------------------------------------------------------------------
00539 //
00540 //  functions that perform lower level CRL processing steps
00541 //
00542 //----------------------------------------------------------------------------------------------------
00543 //4-b
00544 /*
00545 //this function was deprecated and replaced by _ValidateCRLIssuerName2
00546 //it was commented out because it is not used 8/26/2004
00547 bool _ValidateCRLIssuerName(const CPKIFCertificatePtr& targetCert, CPKIFCRLDistributionPointListPtr& dpsFromCRLDP, 
00548                             const CPKIFCRLPtr& crl, CPKIFX509CRLChecker::CRLSCOPE scope, CPKIFCRLDistributionPointPtr& activeCRLDP)
00549 {
00550     LOG_STRING_DEBUG("_ValidateCRLIssuerName", TOOLKIT_PATH_MISC, 0, NULL);
00551 
00552     //This function assumes that the CRL type and cert type are compatible.  If they are not - BOOM!
00553     //Thus, make sure this function is only called after checking type compatibility.
00554     bool foundMatch = false;
00555     if(activeCRLDP != (CPKIFCRLDistributionPoints*)NULL)
00556     {
00557         //next see if any crlIssuer from the current distribution point matches a name from the IDP
00558         CPKIFGeneralNameList crlIssuersFromCRLDP;
00559         activeCRLDP->CRLIssuer(crlIssuersFromCRLDP);
00560 
00561         CPKIFNamePtr crlIssuer = crl->Issuer();
00562         bool foundMatch = false;
00563 
00564         CPKIFGeneralNameList::iterator pos;
00565         CPKIFGeneralNameList::iterator end = crlIssuersFromCRLDP.end();
00566         for(pos = crlIssuersFromCRLDP.begin(); pos != end; ++pos)
00567         {
00568             if(CPKIFGeneralName::GENNAMETYPE::DIRECTORYNAME == (*pos)->GetType())
00569             {
00570                 CPKIFNamePtr tmpName = (*pos)->directoryName();
00571                 if(*tmpName == *crlIssuer)
00572                 {
00573                     foundMatch = true;
00574                     break;
00575                 }
00576             }
00577         }
00578     }
00579     else
00580     {
00581         //if we get here then the issuer of the certificate must be the issuer of the CRL
00582         CPKIFNamePtr crlIssuer = crl->Issuer();
00583         CPKIFNamePtr certIssuer = targetCert->Issuer();
00584         if(*crlIssuer == *certIssuer)
00585             foundMatch = true;
00586     }
00587 
00588     return foundMatch;
00589 }
00590 */
00598 bool _ValidateCRLIssuerName2(
00600     const CPKIFCertificatePtr& targetCert,
00602     CPKIFCRLDistributionPointListPtr& dpsFromCRLDP, 
00604     const CPKIFCRLPtr& crl,
00606     CPKIFX509CRLChecker::CRLSCOPE scope, 
00608     CPKIFCRLDistributionPointPtr& activeCRLDP)
00609 {
00610     LOG_STRING_DEBUG("_ValidateCRLIssuerName2", TOOLKIT_PATH_MISC, 0, NULL);
00611 
00612     //----------------------------------------------------------------------------------------------------
00613     //clear active CRL DP
00614     //----------------------------------------------------------------------------------------------------
00615     CPKIFCRLDistributionPointPtr tmpEmpty;
00616     activeCRLDP = tmpEmpty;
00617 
00618     //----------------------------------------------------------------------------------------------------
00619     // see if the CRL issuer matches the cert issuer
00620     //      if it does return true w/o setting active CRLDP
00621     //----------------------------------------------------------------------------------------------------
00622     CPKIFNamePtr crlIssuer = crl->Issuer();
00623     CPKIFNamePtr certIssuer = targetCert->Issuer();
00624 
00625     //relocated this check to below if no DPs are present - 12/7/2003
00626     //if(*crlIssuer == *certIssuer)
00627     //  return true;
00628 
00629     //----------------------------------------------------------------------------------------------------
00630     // see if the CRL issuer matches a CRL DP
00631     //----------------------------------------------------------------------------------------------------
00632     //if no DPs were passed in then none match - return false
00633     if(dpsFromCRLDP == (CPKIFCRLDistributionPointList*)NULL)
00634     {
00635         if(*crlIssuer == *certIssuer)
00636             return true;
00637         else
00638             return false;
00639     }
00640 
00641     bool crlIssuerSpecifiedInDP = false;
00642 
00643     //iterate over all DPs from the CRL DP and see if any match the IDP
00644     //(either the DP or crlIssuer from the CRL DP can produce the match)
00645     CPKIFCRLDistributionPointList::iterator pos;
00646     CPKIFCRLDistributionPointList::iterator end = dpsFromCRLDP->end();
00647     for(pos = dpsFromCRLDP->begin(); pos != end; ++pos)
00648     {
00649         //see if the crlIssuer from the current CRL DP matches the CRL issuer
00650         CPKIFGeneralNameList fromPosCrlIssuer;
00651         (*pos)->CRLIssuer(fromPosCrlIssuer);
00652 
00653         CPKIFGeneralNameList::iterator gnPos;
00654         CPKIFGeneralNameList::iterator gnEnd = fromPosCrlIssuer.end();
00655         for(gnPos = fromPosCrlIssuer.begin(); gnPos != gnEnd; ++gnPos)
00656         {
00657             crlIssuerSpecifiedInDP = true;
00658             if(CPKIFGeneralName::DIRECTORYNAME == (*gnPos)->GetType())
00659             {
00660                 CPKIFNamePtr fromCRLDP = (*gnPos)->directoryName();
00661                 if(fromCRLDP != (CPKIFName*)NULL && *fromCRLDP == *crlIssuer)
00662                 {
00663                     activeCRLDP = *pos;
00664                     return true;
00665                 }
00666             }
00667         }
00668     }
00669 
00670     //added this check 12/7/2003
00671     if(!crlIssuerSpecifiedInDP)
00672     {
00673         if(*crlIssuer == *certIssuer)
00674             return true;
00675     }
00676 
00677     //if neither the cert issuer nor a CRL DP matched the CRL issuer...
00678     return false;
00679 }
00687 bool _ValidateDP2(
00689     CPKIFCRLDistributionPointListPtr& dpsFromCRLDP, 
00691     const CPKIFCRLPtr& crl, 
00693     CPKIFX509CRLChecker::CRLSCOPE scope,
00695     CPKIFCRLDistributionPointPtr& activeCRLDP, 
00697     CPKIFX509CRLChecker::CRLREASONS reasons)
00698 {
00699     LOG_STRING_DEBUG("_ValidateDP2", TOOLKIT_PATH_MISC, 0, NULL);
00700 
00701     //  4- c) Validate DP (discard CRL upon failure)
00702     //      If IDP w/distribution point field is present, one of the names in the CRL DP shall match one
00703     //      of the names in the IDP.  
00704     if(CPKIFX509CRLChecker::CS_DP == scope || CPKIFX509CRLChecker::CS_DELTA_DP == scope)
00705     {
00706         //if it's a DP CRL but cert has no CRL DP then return false
00707         if(dpsFromCRLDP == (CPKIFCRLDistributionPointList*)NULL)
00708             return false;
00709 
00710         //otherwise grab the IDP and DP name from the IDP (assume there is an IDP w/DP thanks to scope)
00711         CPKIFIssuingDistributionPointPtr idp = crl->GetExtension<CPKIFIssuingDistributionPoint>();
00712         CPKIFDistributionPointNamePtr dpFromIDP = idp->DistributionPoint();
00713         CPKIFGeneralNameList gnsFromIDP;
00714         if(!dpFromIDP->NameRelativeToIssuerPresent())
00715             dpFromIDP->FullName(gnsFromIDP);
00716         else
00717         {
00718             CPKIFNamePtr iss = crl->Issuer();
00719             CPKIFNamePtr relAsFull = dpFromIDP->GetRelativeNameAsFullName(iss);
00720             CPKIFGeneralNamePtr gnp(new CPKIFGeneralName(relAsFull));
00721             gnsFromIDP.push_back(gnp);          
00722         }
00723 
00724         bool foundMatch = false;
00725         if(activeCRLDP != (CPKIFCRLDistributionPoint*)NULL)
00726         {
00727             //if there's an active CRL DP, i.e. on that produced a match in the CRL issuer validation
00728             //function - then use require that DP to match here
00729             CPKIFDistributionPointNamePtr fromActive = activeCRLDP->DistributionPoint();
00730             if(!fromActive->NameRelativeToIssuerPresent())
00731             {
00732                 if(*fromActive == *dpFromIDP)
00733                     foundMatch = true;
00734             }
00735             else
00736             {
00737                 CPKIFNamePtr iss = crl->Issuer();
00738                 CPKIFNamePtr relName = fromActive->GetRelativeNameAsFullName(iss);
00739                 CPKIFGeneralNamePtr gnpFromCrlDp(new CPKIFGeneralName(relName));    
00740                 CPKIFGeneralNameList gnsFromCDP;
00741                 gnsFromCDP.push_back(gnpFromCrlDp);
00742 
00743                 GeneralNamesCompare gnc;
00744                 gnc.SetGeneralNames(&gnsFromCDP);
00745 
00746                 CPKIFGeneralNameList::iterator idpEnd = gnsFromIDP.end();
00747                 if(idpEnd != find_if(gnsFromIDP.begin(), gnsFromIDP.end(), gnc))
00748                 {
00749                     foundMatch = true;
00750                 }
00751             }
00752         }
00753         else
00754         {
00755             //if there is no active CRL DP then any CRL DP can produce a match
00756             CPKIFCRLDistributionPointList::iterator pos;
00757             CPKIFCRLDistributionPointList::iterator end = dpsFromCRLDP->end();
00758             for(pos = dpsFromCRLDP->begin(); pos != end; ++pos)
00759             {
00760                 //first see if a distribution point name from the current distribution point
00761                 //matches a name from the IDP
00762                 CPKIFDistributionPointNamePtr fromPos = (*pos)->DistributionPoint();
00763                 if(!fromPos->NameRelativeToIssuerPresent())
00764                 {
00765                     if(!dpFromIDP->NameRelativeToIssuerPresent())
00766                     {
00767                         if(*fromPos == *dpFromIDP)
00768                         {
00769                             foundMatch = true;
00770                             break;
00771                         }
00772                     }
00773                     else
00774                     {
00775                         CPKIFGeneralNameList gnsFromCDP;
00776                         fromPos->FullName(gnsFromCDP);
00777 
00778                         GeneralNamesCompare gnc;
00779                         gnc.SetGeneralNames(&gnsFromCDP);
00780 
00781                         CPKIFGeneralNameList::iterator idpEnd = gnsFromIDP.end();
00782                         if(idpEnd != find_if(gnsFromIDP.begin(), gnsFromIDP.end(), gnc))
00783                         {
00784                             foundMatch = true;
00785                             break;
00786                         }
00787                     }
00788 
00789                     //next see if any crlIssuer from the current distribution point matches a name from the IDP
00790                     CPKIFGeneralNameList crlIssuer;
00791                     (*pos)->CRLIssuer(crlIssuer);
00792 
00793                     if(!crlIssuer.empty())
00794                     {
00795                         GeneralNamesCompare gnc;
00796                         gnc.SetGeneralNames(&crlIssuer);
00797 
00798                         CPKIFGeneralNameList::iterator idpEnd = gnsFromIDP.end();
00799                         if(idpEnd != find_if(gnsFromIDP.begin(), gnsFromIDP.end(), gnc))
00800                         {
00801                             foundMatch = true;
00802                             break;
00803                         }
00804                     }
00805                 }
00806                 else
00807                 {
00808                     CPKIFNamePtr iss = crl->Issuer();
00809                     CPKIFNamePtr cdpRelNameAsFull = fromPos->GetRelativeNameAsFullName(iss);
00810                     CPKIFGeneralNamePtr gnpFromCrlDp(new CPKIFGeneralName(cdpRelNameAsFull));   
00811                     CPKIFGeneralNameList gnsFromCDP;
00812                     gnsFromCDP.push_back(gnpFromCrlDp);
00813 
00814 
00815                     //compare it to the DP from the IDP
00816                     GeneralNamesCompare gnc;
00817                     gnc.SetGeneralNames(&gnsFromCDP);
00818 
00819                     CPKIFGeneralNameList::iterator idpEnd = gnsFromIDP.end();
00820                     if(idpEnd != find_if(gnsFromIDP.begin(), gnsFromIDP.end(), gnc))
00821                     {
00822                         foundMatch = true;
00823                         break;
00824                     }
00825                 }
00826             }
00827         }
00828 
00829         //if no DP matches then return false
00830         if(!foundMatch)
00831             return false;
00832     }
00833 
00835     //contain at least one of the reason codes asserted in the CRL DP (but, in this version, reason-based 
00836     //partitioning not supported)
00837     if(CPKIFX509CRLChecker::CR_ALLREASONS != reasons)
00838     {
00839         CPKIFIssuingDistributionPointPtr idp = crl->GetExtension<CPKIFIssuingDistributionPoint>();
00840         if(activeCRLDP != (CPKIFCRLDistributionPoint*)NULL)
00841         {
00842             CPKIFReasonFlagsPtr idpRF = idp->GetReasons();
00843             CPKIFReasonFlagsPtr cdpRF = activeCRLDP->Reasons();
00844 
00845             if(idpRF != (CPKIFReasonFlags*)NULL && cdpRF != (CPKIFReasonFlags*)NULL)
00846             {
00847                 if(idpRF->GetCACompromise() && cdpRF->GetCACompromise())
00848                     return true;
00849                 else if(idpRF->GetKeyCompromise() && cdpRF->GetKeyCompromise())
00850                     return true;
00851                 else if(idpRF->GetAACompromise() && cdpRF->GetAACompromise())
00852                     return true;
00853                 else if(idpRF->GetPrivilegeWithdrawn() && cdpRF->GetPrivilegeWithdrawn())
00854                     return true;
00855                 else if(idpRF->GetCertificateHold() && cdpRF->GetCertificateHold())
00856                     return true;
00857                 else if(idpRF->GetCessationOfOperation() && cdpRF->GetCessationOfOperation())
00858                     return true;
00859                 else if(idpRF->GetSuperseded() && cdpRF->GetSuperseded())
00860                     return true;
00861                 else if(idpRF->GetAffiliationChanged() && cdpRF->GetAffiliationChanged())
00862                     return true;
00863                 else if(idpRF->GetUnused() && cdpRF->GetUnused())
00864                     return true;
00865                 else
00866                     return false;
00867             }
00868         }
00869     }
00870 
00871     //if we get here then the CRL is: OK DP-wise and not partitioned using reason codes
00872     return true;
00873 }
00874 
00875 //4-d
00885 bool _ValidateCRLAuthority(
00887     const CPKIFCertificatePtr& targetCert, 
00889     const CPKIFCRLPtr& crl, 
00891     CPKIFX509CRLChecker::CRLAUTHORITY authority)
00892 {
00893     LOG_STRING_DEBUG("_ValidateCRLAuthority", TOOLKIT_PATH_MISC, 0, NULL);
00894 
00895     //  d) Validate CRL authority (discard CRL upon failure)
00896     //      If the CRL issuer name does not match the cert issuer name, the indirectCRL field must be present
00897     //      in the IDP.
00898     const CPKIFNamePtr& certIssuer = targetCert->Issuer();
00899     const CPKIFNamePtr& crlIssuer = crl->Issuer();
00900     if(!(*crlIssuer == *certIssuer) && CPKIFX509CRLChecker::CA_INDIRECT != authority)
00901         return false;
00902     else
00903         return true;
00904 }
00905 
00906 // If lhs > rhs return -1.  If lhs == rhs return 0.  If lhs < rhs   return 1
00916 int _CompareCRLNumbers(
00918     const char* lhs, 
00920     const char* rhs)
00921 {
00922     LOG_STRING_DEBUG("_CompareCRLNumbers", TOOLKIT_PATH_MISC, 0, NULL);
00923 
00924     if (NULL == lhs || NULL == rhs)
00925         throw CPKIFPathException(TOOLKIT_PATH_CRL_CHECKER, COMMON_INVALID_INPUT, "NULL CRL number passed to _CompareCRLNumbers.");
00926 
00927     size_t lhsLen = strlen(lhs);
00928     size_t rhsLen = strlen(rhs);
00929 
00930     //min length must account for 0x and at least one byte
00931     if (lhsLen < 3 || rhsLen < 3)
00932         throw CPKIFPathException(TOOLKIT_PATH_CRL_CHECKER, COMMON_INVALID_INPUT, "Invalid CRL number passed to _CompareCRLNumbers.");
00933 
00934     // Skip the first 2 bytes and strip the leading zeros
00935     char* left = const_cast<char*>(lhs) + 2; lhsLen -= 2;
00936     for(; lhsLen > 1 && *left == '0'; ++left, --lhsLen);
00937 
00938     char* right = const_cast<char*>(rhs) + 2; rhsLen -= 2;
00939     for(; rhsLen > 1 && *right == '0'; ++right, --rhsLen);
00940 
00941     //max length we'll set to more than the 20 bytes allowed by PKIX
00942     if (lhsLen > 60 || rhsLen > 60)
00943         throw CPKIFPathException(TOOLKIT_PATH_CRL_CHECKER, COMMON_INVALID_INPUT, "CRL number passed to _CompareCRLNumbers too big.");
00944 
00945     unsigned char rhsBin[30], lhsBin[30];
00946     // GIB: this is OK because we just checked these above and no platform
00947     // has max_int anything like 60.
00948     // However, on some platforms &size_t won't work the same as &unsigned int!
00949     unsigned int irhsLen = (unsigned int)rhsLen, ilhsLen = (unsigned int)lhsLen;
00950     atob((char*)rhsBin, right, &irhsLen);
00951     atob((char*)lhsBin, left, &ilhsLen);
00952 
00953     // be sure to use irhsLen and ilhsLen from here forward
00954         if (ilhsLen < irhsLen)
00955         return 1;
00956     else if(ilhsLen > irhsLen)
00957         return -1;
00958 
00959     // Compare the two numbers byte by byte
00960     for (unsigned int ii = 0; ii < ilhsLen; ++ii)
00961     {
00962         if(lhsBin[ii] > rhsBin[ii])
00963             return -1;
00964         if(lhsBin[ii] < rhsBin[ii])
00965             return 1;
00966     }
00967 
00968     //if we get here then the two values matched in all bytes
00969     return 0;
00970 }
00971 
00972 //5-c) Validate delta scope
00980 bool _ValidateDeltaScope(
00982     const CPKIFCertificatePtr& targetCert, 
00984     const CPKIFCRLPtr& crl, 
00986     CPKIFX509CRLChecker::CRLSCOPE scope,
00988     CPKIFCRLList& crlList, 
00990     CPKIFCRLList& quarantinedDeltas, 
00992     AssociatedCRLsList& acl)
00993 {
00994     LOG_STRING_DEBUG("_ValidateDeltaScope", TOOLKIT_PATH_MISC, 0, NULL);
00995 
00996     //if we ain't dealing with a delta - return now
00997     if(CPKIFX509CRLChecker::CS_DELTA != scope && CPKIFX509CRLChecker::CS_DELTA_DP != scope)
00998     {
00999         //create an entry in the associated CRL list then return true
01000         AssociatedCRLsPtr ac(new AssociatedCRLs);
01001         ac->m_base = crl;
01002         acl.push_back(ac);
01003 
01004         return true;
01005     }
01006 
01007     CPKIFNamePtr crlIssuer = crl->Issuer();
01008 
01009     //make sure we have a base CRL for this delta - if not quarantine the delta
01010     CPKIFDeltaCRLIndicatorPtr deltaIndicatorExt = crl->GetExtension<CPKIFDeltaCRLIndicator>();
01011     const char* baseNumber = deltaIndicatorExt->BaseCRLNumber();
01012 
01013     CPKIFCRLStreamIdentifierPtr crlStreamIdentifierExt = crl->GetExtension<CPKIFCRLStreamIdentifier>();
01014     bool crlStreamIdentifierSet = false;
01015     const char* crlStreamIdentifier = 0;
01016     if(crlStreamIdentifierExt != (CPKIFCRLStreamIdentifier*)NULL)
01017     {
01018         crlStreamIdentifier = crlStreamIdentifierExt->CRLStreamIdentifier();
01019         crlStreamIdentifierSet = true;
01020     }
01021 
01022     //grab IDP and AKID extensions (if present)
01023     CPKIFAuthorityKeyIdentifierPtr akid = crl->GetExtension<CPKIFAuthorityKeyIdentifier>();
01024     CPKIFIssuingDistributionPointPtr idp = crl->GetExtension<CPKIFIssuingDistributionPoint>();
01025 
01026     bool foundMatch = false;
01027 
01028     AssociatedCRLsList::iterator aclPos;
01029     AssociatedCRLsList::iterator aclEnd = acl.end();
01030     for(aclPos = acl.begin(); aclPos != aclEnd; ++aclPos)
01031     {
01032         CPKIFCRLPtr tmpCRL = (*aclPos)->m_base;
01033 
01034         //don't compare to current crl
01035         if(crl == tmpCRL)
01036             continue;
01037 
01038         //see if issuers match - if not move on
01039         CPKIFNamePtr tmpCRLIssuer = tmpCRL->Issuer();
01040         if(tmpCRLIssuer != (CPKIFCRL*)NULL && !(*crlIssuer == *tmpCRLIssuer))
01041             continue;
01042 
01043         //if crlStream was set in the delta check it here - if not don't bother
01044         if(crlStreamIdentifierSet)
01045         {
01046             CPKIFCRLStreamIdentifierPtr tmpCRLStreamIdentifierExt = tmpCRL->GetExtension<CPKIFCRLStreamIdentifier>();
01047             if(tmpCRLStreamIdentifierExt != (CPKIFCRLStreamIdentifier*)NULL &&
01048                 *crlStreamIdentifier != *tmpCRLStreamIdentifierExt->CRLStreamIdentifier())
01049                 continue;//if streams do not match - move on
01050         }
01051 
01052         CPKIFCRLNumberPtr crlNumber = tmpCRL->GetExtension<CPKIFCRLNumber>();
01053         if(crlNumber != (CPKIFCRLNumber*)NULL && _CompareCRLNumbers(baseNumber, crlNumber->CRLNumber()) < 0)
01054             continue; //if delta applies to a later base - move on
01055 
01056         //compare AKIDs
01057         if(akid != (CPKIFAuthorityKeyIdentifier*)NULL)
01058         {
01059             CPKIFAuthorityKeyIdentifierPtr tmpAKID = tmpCRL->GetExtension<CPKIFAuthorityKeyIdentifier>();
01060             if(tmpAKID != (CPKIFAuthorityKeyIdentifier*)NULL && !(*akid == *tmpAKID))
01061                 continue; //if AKIDs do not match - keep going (PKIX rule)
01062         }
01063 
01064         //compare IDPs
01065         CPKIFIssuingDistributionPointPtr tmpIDP = tmpCRL->GetExtension<CPKIFIssuingDistributionPoint>();
01066         if(idp == (CPKIFIssuingDistributionPoint*)NULL)
01067         {
01068             if(tmpIDP != (CPKIFIssuingDistributionPoint*)NULL)
01069                 continue; //if crl IDP is NULL then cur IDP must be NULL too (PKIX rule)
01070         }
01071         else if(tmpIDP == (CPKIFIssuingDistributionPoint*)NULL)
01072             continue; //crl IDP is non-NULL but tmp IDP is NULL
01073         else if(!(*idp == *tmpIDP))
01074             continue; //idps do not match (PKIX rule)
01075 
01076         //if all of the above checks passed - then set foundMatch to true
01077         foundMatch = true;
01078 
01079         (*aclPos)->m_deltas.push_back(crl);
01080     }
01081 
01082     if(!foundMatch)
01083     {
01084         //add it to quarantine - by returning false it will be removed from the crlList
01085         quarantinedDeltas.push_back(crl);
01086     }
01087 
01088     return foundMatch;
01089 }
01090 
01091 //5-a) Process critical CRL DP and/or freshestCRL
01099 bool ProcessCriticalCertExtensions(
01101     const CPKIFCertificatePtr& targetCert, 
01103     CPKIFCRLList& crlList)
01104 {
01105     LOG_STRING_DEBUG("ProcessCriticalCertExtensions", TOOLKIT_PATH_MISC, 0, NULL);
01106 
01107     //declare two lists of DPs (one from freshestCRL and the other from CRLDP)
01108     CPKIFCRLDistributionPointListPtr dpsFromFresh; 
01109     CPKIFCRLDistributionPointListPtr dpsFromCRLDP; 
01110 
01111     //declare a bool for each extension indicating that processing is done
01112     bool foundFreshMatch = true, foundCRLDPMatch = true;
01113 
01114     CPKIFFreshestCRLPtr fresh = targetCert->GetExtension<CPKIFFreshestCRL>();
01115     if(fresh != (CPKIFFreshestCRL*)NULL && fresh->isCritical())
01116     {
01117         dpsFromFresh = fresh->DPs();
01118         foundFreshMatch = false;
01119     }
01120 
01121     CPKIFCRLDistributionPointsPtr crlDP = targetCert->GetExtension<CPKIFCRLDistributionPoints>();
01122     if(crlDP != (CPKIFCRLDistributionPoints*)NULL && crlDP->isCritical())
01123     {
01124         dpsFromCRLDP = crlDP->DPs();
01125         foundCRLDPMatch = false;
01126     }
01127 
01128     CPKIFCRLDistributionPointPtr activeCRLDP;
01129 
01130     CPKIFCRLList::iterator pos;
01131     CPKIFCRLList::iterator end = crlList.end();
01132     for(pos = crlList.begin(); pos != end; ++pos)
01133     {
01134         const CPKIFCRLTypePtr crlType = _TypeOfCRL(*pos);
01135         const CPKIFX509CRLChecker::CRLSCOPE scope = crlType->GetCRLScope();
01136         const CPKIFX509CRLChecker::CRLREASONS reasons = crlType->GetCRLReasons();
01137 
01138         //added scope check to following conditions 04/28/03 CRW
01139 
01140         //if we haven't already found a match - try to validate current crl against dps
01141         if(!foundFreshMatch && CPKIFX509CRLChecker::CS_COMPLETE != scope && _ValidateDP2(dpsFromFresh, *pos, scope, activeCRLDP, reasons))
01142             foundFreshMatch = true; //when we find a match set flag so we stop looking
01143 
01144         //if we haven't already found a match - try to validate current crl against dps
01145         if(!foundCRLDPMatch && CPKIFX509CRLChecker::CS_COMPLETE != scope && _ValidateDP2(dpsFromCRLDP, *pos, scope, activeCRLDP, reasons))
01146             foundCRLDPMatch = true;//when we find a match set flag so we stop looking
01147     }
01148 
01149     return foundCRLDPMatch && foundFreshMatch;
01150 }
01151 
01152 
01158 class ReasonCodeCheck
01159 {
01160 public:
01161     bool operator()(const CPKIFCRLPtr& lhs);
01162     void SetTargetCert(const CPKIFCertificatePtr& target);
01163     void SetReasonCodesOfInterest(CPKIFReasonFlagsPtr& flags);
01164 private:
01165     CPKIFCertificatePtr m_targetCert;
01166     bool m_bTargetIsCA;
01167     CPKIFReasonFlagsPtr m_rf;
01168 };
01169 
01178 void ReasonCodeCheck::SetReasonCodesOfInterest(CPKIFReasonFlagsPtr& flags)
01179 {
01180     m_rf = flags;
01181 }
01190 void ReasonCodeCheck::SetTargetCert(const CPKIFCertificatePtr& target)
01191 {
01192     m_targetCert = target;
01193 
01194     if(m_targetCert != (CPKIFCertificatePtr*)NULL)
01195     {
01196         //determine if the certificate is a CA cert or an EE cert
01197         CPKIFBasicConstraintsPtr bc = m_targetCert->GetExtension<CPKIFBasicConstraints>();
01198         if(bc != (CPKIFBasicConstraints*)NULL)
01199             m_bTargetIsCA = bc->isCA();
01200     }
01201     else
01202         m_bTargetIsCA = false;
01203 }
01213 bool ReasonCodeCheck::operator()(
01215     const CPKIFCRLPtr& lhs)
01216 {
01217     CPKIFIssuingDistributionPointPtr idp = lhs->GetExtension<CPKIFIssuingDistributionPoint>();
01218     if(idp != (CPKIFIssuingDistributionPoint*)NULL)
01219     {
01220         if(idp->OnlyContainsAttributeCerts())
01221             return true;
01222 
01223         CPKIFReasonFlagsPtr idpRF = idp->GetReasons();
01224         if(idpRF != (CPKIFReasonFlags*)NULL && m_rf != (CPKIFReasonFlags*)NULL)
01225         {
01226             if(m_bTargetIsCA && idp->OnlyContainsUserCerts())
01227                 return true;
01228             if(!m_bTargetIsCA && idp->OnlyContainsAuthorityCerts())
01229                 return true;
01230 
01231             if(idpRF->GetCACompromise() && m_rf->GetCACompromise())
01232                 return false;
01233             else if(idpRF->GetKeyCompromise() && m_rf->GetKeyCompromise())
01234                 return false;
01235             else if(idpRF->GetAACompromise() && m_rf->GetAACompromise())
01236                 return false;
01237             else if(idpRF->GetPrivilegeWithdrawn() && m_rf->GetPrivilegeWithdrawn())
01238                 return false;
01239             else if(idpRF->GetCertificateHold() && m_rf->GetCertificateHold())
01240                 return false;
01241             else if(idpRF->GetCessationOfOperation() && m_rf->GetCessationOfOperation())
01242                 return false;
01243             else if(idpRF->GetSuperseded() && m_rf->GetSuperseded())
01244                 return true;
01245             else if(idpRF->GetAffiliationChanged() && m_rf->GetAffiliationChanged())
01246                 return false;
01247             else if(idpRF->GetUnused() && m_rf->GetUnused())
01248                 return false;
01249             else
01250                 return true;
01251         }
01252     }
01253 
01254     return false;
01255 }
01256 
01257 //5-b) Process reason codes of interest
01265 bool _ProcessReasonCodesOfInterest(
01267     const CPKIFCertificatePtr& targetCert, 
01269     CPKIFCRLList& crlList, 
01271     CPKIFReasonFlagsPtr reasons)
01272 {
01273     ReasonCodeCheck rcc;
01274     rcc.SetTargetCert(targetCert);
01275     rcc.SetReasonCodesOfInterest(reasons);
01276 
01277     CPKIFCRLList::iterator newEnd = remove_if(crlList.begin(), crlList.end(), rcc);
01278     crlList.erase(newEnd, crlList.end());
01279 
01280     //iterate over all CRLs and make sure we cover the full set of reasons
01281     CPKIFReasonFlags controlRF;
01282 
01283     CPKIFCRLList::iterator pos;
01284     CPKIFCRLList::iterator end = crlList.end();
01285     for(pos = crlList.begin(); pos != end; ++pos)
01286     {
01287         CPKIFIssuingDistributionPointPtr idp = (*pos)->GetExtension<CPKIFIssuingDistributionPoint>();
01288         if(idp != (CPKIFIssuingDistributionPoint*)NULL)
01289         {
01290             CPKIFReasonFlagsPtr idpRF = idp->GetReasons();
01291             if(idpRF != (CPKIFReasonFlags*)NULL)
01292             {
01293                 if(     idpRF->GetCACompromise())
01294                     controlRF.SetCACompromise();
01295                 if(idpRF->GetKeyCompromise())
01296                     controlRF.SetKeyCompromise();
01297                 if(idpRF->GetAACompromise())
01298                     controlRF.SetAACompromise();
01299                 if(idpRF->GetPrivilegeWithdrawn())
01300                     controlRF.SetPrivilegeWithdrawn();
01301                 if(idpRF->GetCertificateHold())
01302                     controlRF.SetCertificateHold();
01303                 if(idpRF->GetCessationOfOperation())
01304                     controlRF.SetCessationOfOperation();
01305                 if(idpRF->GetSuperseded())
01306                     controlRF.SetSuperseded();
01307                 if(idpRF->GetAffiliationChanged())
01308                     controlRF.SetAffiliationChanged();
01309                 if(idpRF->GetUnused())
01310                     controlRF.SetUnused();
01311             }
01312             else
01313                 return true; // reason flags, thus all reasons present
01314         }
01315         else
01316             return true; //no IDP, thus all reasons present
01317     }
01318 
01319     //if we get here, then we may not have everything we need
01320     if(!controlRF.GetUnused() ||
01321         !controlRF.GetAffiliationChanged() ||
01322         !controlRF.GetSuperseded() ||
01323         !controlRF.GetCessationOfOperation() ||
01324         !controlRF.GetPrivilegeWithdrawn() ||
01325         !controlRF.GetAACompromise() ||
01326         !controlRF.GetKeyCompromise() ||
01327         !controlRF.GetCACompromise() ||
01328         !controlRF.GetUnused())
01329         return false;
01330 
01331     return !crlList.empty();
01332 }
01339 class DPCompare
01340 {
01341 public:
01342 
01350     bool operator()(CPKIFCRLDistributionPointPtr& rhsDP)
01351     {
01352         if(m_lhsName != (CPKIFDistributionPointName*)NULL)
01353         {
01354             CPKIFDistributionPointNamePtr rhsName = rhsDP->DistributionPoint();
01355             if(rhsName != (CPKIFDistributionPointName*)NULL)
01356                 return *m_lhsName == *rhsName;
01357         }
01358 
01359         return false;
01360     }
01368     void SetIDPName(const CPKIFIssuingDistributionPointPtr& lhsName) {m_idp = lhsName; m_lhsName = lhsName->DistributionPoint();}
01369 private:
01370     CPKIFIssuingDistributionPointPtr m_idp;
01371     CPKIFDistributionPointNamePtr m_lhsName;
01372 };
01373 
01380 template <class T>
01381 class NottaMatch
01382 {
01383 public:
01384     bool operator()(const T& t);
01385 
01393     void SetRHS(const T& rhs) {m_rhs = rhs;}
01394 private:
01395     T m_rhs;
01396 };
01397 
01406 template <class T>
01407 bool NottaMatch<T>::operator()(const T& t)
01408 {
01409     return !(*t == *m_rhs);     
01410 }
01411 
01412 //5-d) Discard extraneous CRLs
01420 void _QuarantineExtraneousCRLs(
01422     const CPKIFCertificatePtr& targetCert, 
01424     CPKIFCRLList& crlList, 
01426     CPKIFCRLList& quarantinedCRLs)
01427 {
01428     LOG_STRING_DEBUG("_QuarantineExtraneousCRLs", TOOLKIT_PATH_MISC, 0, NULL);
01429 
01430     //sift through the mess and sort out the "best" CRLs - quarantine the left-overs
01431     
01432     //----------------------------------------------------------------------------------------------------
01433     //new code to favor IDP matches and to quarantine additional CRLs where
01434     //an IDP match exists - added 7/21/2005 CRW
01435 
01436     CPKIFCRLDistributionPointsPtr crlDPs = targetCert->GetExtension<CPKIFCRLDistributionPoints>();
01437 
01438     CPKIFCRLPtr match;
01439     if(crlDPs != (CPKIFCRLDistributionPoints*)NULL)
01440     {
01441         CPKIFCRLDistributionPointListPtr dps = crlDPs->DPs();
01442 
01443         CPKIFCRLList::iterator pos;
01444         CPKIFCRLList::iterator end = crlList.end();
01445         for(pos = crlList.begin(); pos != end; ++pos)
01446         {
01447             CPKIFIssuingDistributionPointPtr idp = (*pos)->GetExtension<CPKIFIssuingDistributionPoint>();
01448             if(idp != (CPKIFIssuingDistributionPoint*)NULL)
01449             {
01450                 DPCompare _dpCompare;
01451                 _dpCompare.SetIDPName(idp);
01452                 if(dps->end() != find_if(dps->begin(), dps->end(), _dpCompare))
01453                 {
01454                     match = *pos;
01455                     break;
01456                 }
01457             }
01458         }
01459     }
01460 
01461     if(match != (CPKIFCRL*)NULL)
01462     {
01463         NottaMatch<CPKIFCRLPtr> nm;
01464         nm.SetRHS(match);
01465         CPKIFCRLList::iterator newEnd = remove_if(crlList.begin(), crlList.end(), nm);
01466         copy(newEnd, crlList.end(), back_inserter(quarantinedCRLs));
01467         crlList.erase(newEnd, crlList.end());
01468     }   
01469 
01470     //----------------------------------------------------------------------------------------------------
01471 }
01472 
01473 //----------------------------------------------------------------------------------------------------
01474 //
01475 //  utility functions
01476 //
01477 //----------------------------------------------------------------------------------------------------
01478 
01489 bool _GetHashOfToBeSignedCRL2(
01491     const CPKIFCRLPtr& crl,
01493     IPKIFCryptoMisc* cryptoMisc, 
01495     PKIFCRYPTO::HASH_ALG hashAlg, //input, input, input
01497     unsigned char* hashResult, 
01499     int* hashResultLen)
01500 {
01501     LOG_STRING_DEBUG("_GetHashOfToBeSignedCRL2", TOOLKIT_PATH_MISC, 0, NULL);
01502 
01503     int stat = ASN_OK;
01504     int reqcnt = 0;
01505 
01506     if(crl == (CPKIFCRL*)NULL || NULL == cryptoMisc || NULL == hashResult)
01507         throw CPKIFPathException(TOOLKIT_PATH_CRL_CHECKER,COMMON_INVALID_INPUT,"Invalid input passed to CRL hash calculation function");
01508 
01509     //get a pointer to the encoded CRL and the length of the encoded CRL
01510     CPKIFBufferPtr crlBuf = crl->Encoded();
01511     int length = crlBuf->GetLength();
01512 
01513     if(0 == length)
01514         throw CPKIFPathException(TOOLKIT_PATH_CRL_CHECKER,COMMON_INVALID_INPUT,"Empty CRL passed to CRL hash calculation function");
01515 
01516     //prepare an OOCTXT object with the CRL buffer and length
01517     OOCTXT ctxt;
01518     initContext (&ctxt);
01519     setBERDecBufPtr(&ctxt, crlBuf->GetBuffer(), length, NULL, NULL);
01520     OOCTXT* pctxt = &ctxt;
01521 
01522     //parse the first sequence (SIGNED macro)
01523     stat = matchTag (pctxt, TM_UNIV|TM_CONS|16, &length, XM_ADVANCE);
01524     if (stat != ASN_OK)
01525     {
01526         freeEncodeBuffer(&ctxt);
01527         memFreeAll(&ctxt);
01528         return false;
01529     }
01530 
01531     //save the offset
01532     size_t byteIndex = ctxt.buffer.byteIndex;
01533 
01534     //parse the next sequence to get the length
01535     stat = matchTag (pctxt, TM_UNIV|TM_CONS|16, &length, XM_ADVANCE);
01536     if (stat != ASN_OK)
01537     {
01538         freeEncodeBuffer(&ctxt);
01539         memFreeAll(&ctxt);
01540         return false;
01541     }
01542 
01543     //set the pointer to the offset collected above and the length to the length
01544     //returned by the second parse operation plus the offset difference.  this is the
01545     //to be signed CRL to pass to the hash function below.
01546     unsigned char* p = (unsigned char*)ctxt.buffer.data + byteIndex; 
01547     size_t tmpST = ctxt.buffer.byteIndex - byteIndex;
01548     unsigned int tmpUI = 0;
01549 
01550     try {
01551         tmpUI = numeric_cast<unsigned int>(tmpST);
01552     }catch(bad_numeric_cast &) {
01553         throw CPKIFException(TOOLKIT_PATH, COMMON_INVALID_INPUT, "Byte offset difference too large.");
01554     }
01555 
01556     length += (tmpUI);
01557 
01558     IPKIFHashContext* hash = NULL;
01559     try
01560     {
01561         //create a hash object, pass the buffer and length we calculated and obtain the result
01562         hash = cryptoMisc->HashInit(hashAlg);
01563         cryptoMisc->HashUpdate(hash, p, length);
01564         cryptoMisc->HashFinal(hash, (unsigned char*)hashResult, hashResultLen);
01565     }
01566     catch(CPKIFException& e)
01567     {
01568         if(NULL != hash)
01569             delete hash;
01570 
01571         //clean up the context
01572         freeEncodeBuffer(&ctxt);
01573         memFreeAll(&ctxt);
01574 
01575         throw e;
01576     }
01577 
01578     //clean up the hash
01579     delete hash; 
01580 
01581     //clean up the context
01582     freeEncodeBuffer(&ctxt);
01583     memFreeAll(&ctxt);
01584 
01585     return true;
01586 }
01594 bool _GetCRLIssuersCert(
01596     CPKIFCRLPtr& crl,
01598     IPKIFNameAndKey* targetCertIssuersCertNK, 
01599     const CPKIFCertificatePtr& targetCertIssuersCert,
01601     CPKIFCertificateList& crlIssuerCerts,
01602     //[out] PKIInfoSource value indicating the type of location from which the associated certificate object was retrieved
01603     PKIInfoSource source, 
01605     IPKIFColleague* c,
01607     const CPKIFX509CRLChecker::CRLAUTHORITY authority, 
01609     CPKIFPathSettingsPtr& settings)
01610 {
01611     LOG_STRING_DEBUG("_GetCRLIssuersCert", TOOLKIT_PATH_MISC, 0, NULL);
01612 
01613     crlIssuerCerts.clear();
01614     CPKIFNamePtr crlIssuerName = crl->Issuer();
01615 
01616     #ifdef _DEBUG
01617         const char* crlIssuerNameString = crlIssuerName->ToString();
01618         const char* targetCertIssuersCertNKString = targetCertIssuersCertNK->GetSubjectName()->ToString();
01619     #endif
01620 
01621     //added this check 7/18
01622     bool issuedByCertIssuer = false;
01623     if(*crlIssuerName == *targetCertIssuersCertNK->GetSubjectName())
01624         issuedByCertIssuer = true;
01625 
01626     if(REMOTE != source)
01627     {
01628         //if the source is not REMOTE then check the targetCertIssuersCert and...
01629         if(*crlIssuerName == *targetCertIssuersCertNK->GetSubjectName() && targetCertIssuersCert != (CPKIFCertificate*)NULL)
01630             crlIssuerCerts.push_back(targetCertIssuersCert);
01631 
01632         //altered direct/indirect conditions here and below 7/18
01633         //  - to permit discovery of direct issuer with different key 
01634         //check the trust root store (if available and CRL is indirect)
01635         IPKIFTrustCache* tc = c->GetMediatorFromParent<IPKIFTrustCache>();
01636         if(tc && (issuedByCertIssuer || CPKIFX509CRLChecker::CA_INDIRECT == authority))
01637         {
01638             IPKIFTrustAnchorList rootList;
01639             tc->GetTrustRoots(crlIssuerName, rootList);
01640 
01641             IPKIFTrustAnchorList::iterator pos;
01642             IPKIFTrustAnchorList::iterator end = rootList.end();
01643             for(pos = rootList.begin(); pos != end; ++pos)
01644             {
01645                 CPKIFCertificatePtr rootCert = (*pos)->GetCertificate();
01646                 if(rootCert)
01647                 {
01648                     crlIssuerCerts.push_back(rootCert);
01649                 }
01650             }
01651         }
01652     }
01653 
01654     //check cert repository (if available and CRL is indirect)
01655     IPKIFCertRepository* cr = c->GetMediatorFromParent<IPKIFCertRepository>();
01656     if(c && (issuedByCertIssuer || CPKIFX509CRLChecker::CA_INDIRECT == authority))
01657     {
01658         cr->GetCertificates(crlIssuerName, crlIssuerCerts, source);
01659     }
01660 
01661     //----------------------------------------------------------------------------------------------------
01662     //added 7/21/2005 to sort CRL issuers to avoid chasing certs with 
01663     //incorrect public key if possible
01664     CPKIFAuthorityKeyIdentifierPtr akid = crl->GetExtension<CPKIFAuthorityKeyIdentifier>();
01665 
01666     CPKIFCertificateNodeListWithSourceInfo nodeList;
01667     CPKIFCertificateList::iterator pos;
01668     CPKIFCertificateList::iterator end = crlIssuerCerts.end();
01669     for(pos = crlIssuerCerts.begin(); pos != end; ++pos)
01670     {
01671         CPKIFCertificateNodeEntryPtr entry(new CPKIFCertificateNodeEntry);
01672         entry->SetCert(*pos);
01673         nodeList.push_back(entry);
01674     }
01675 
01676     IPKIFTrustAnchorList rootList;
01677     CPKIFCertificateList certList;
01678 
01679     //score each node entry
01680     CPKIFCertificateNodeListWithSourceInfo::iterator nodeListPos;
01681     CPKIFCertificateNodeListWithSourceInfo::iterator nodeListEnd = nodeList.end();      
01682 
01683     CPKIFNamePtr targetIssuer = targetCertIssuersCertNK->GetSubjectName();
01684     CPKIFPolicyInformationListPtr initPolSet;
01685     settings->GetInitialPolicySet(initPolSet);
01686 
01687     for(nodeListPos = nodeList.begin(); nodeListPos != nodeListEnd; ++nodeListPos)
01688     {
01689         (*nodeListPos)->ClearScore();
01690         CPKIFCertificatePtr curCert = (*nodeListPos)->GetCert();
01691         CPKIFNamePtr curIssuer = curCert->Issuer();
01692 
01693         if(*curIssuer == *targetIssuer)
01694             (*nodeListPos)->AddToScore(200);
01695 
01696         IPKIFNameAndKey* curCertNK = dynamic_cast<IPKIFNameAndKey*>(&(*curCert));
01697         if(curCertNK && *curCertNK == *targetCertIssuersCertNK)
01698             (*nodeListPos)->AddToScore(200);
01699 
01700         if(!CertIsSelfIssued(curCert))
01701         {
01702             (*nodeListPos)->AddToScore(100);
01703         }
01704 
01705         CPKIFPolicyInformationSetPtr cpsFromCert = curCert->GetExtension<CPKIFPolicyInformationSet>();
01706         if(cpsFromCert != (CPKIFPolicyInformationSet*)NULL)
01707         {
01708             //give points for simply having a policy
01709             (*nodeListPos)->AddToScore(50);
01710 
01711             CPKIFPolicyMappingsPtr policyMappings;
01712             if(SomeMatch(cpsFromCert, initPolSet, policyMappings))
01713                 (*nodeListPos)->AddToScore(50);
01714         }
01715 
01716         //check AKID/SKID chaining
01717         if(akid != (CPKIFAuthorityKeyIdentifier*)NULL)
01718         {
01719             if(KeyIDsMatch(akid, curCert))
01720             {
01721                 (*nodeListPos)->AddToScore(800);
01722             }
01723             else
01724             {
01725                 (*nodeListPos)->ClearScore();
01726             }
01727         }
01728         
01729         //if(!curCert->IsSelfSigned())
01730         //{
01731         //  (*nodeListPos)->AddToScore(100);
01732         //}
01733     }
01734 
01735     //reorder the list based on the scoring
01736     sort(nodeList.begin(), nodeList.end(), scoreCompare);
01737 
01738     crlIssuerCerts.clear();
01739     nodeListEnd = nodeList.end();       
01740     for(nodeListPos = nodeList.begin(); nodeListPos != nodeListEnd; ++nodeListPos)
01741     {
01742         crlIssuerCerts.push_back((*nodeListPos)->GetCert());
01743     }   
01744     //----------------------------------------------------------------------------------------------------
01745 
01746     return !crlIssuerCerts.empty();
01747 }
01748 
01749 //----------------------------------------------------------------------------------------------------
01750 //
01751 //  PRIVATE MEMBER FUNCTIONS
01752 //
01753 //----------------------------------------------------------------------------------------------------
01754 
01755 //modified 12/4/2003
01761 class ScopeCompare
01762 {
01763 public:
01771     bool operator()(const CPKIFCRLPtr& lhsCRL, const CPKIFCRLPtr& rhsCRL)
01772     {
01773         LOG_STRING_DEBUG("_scopeCompare(CPKIFCRLPtr& lhsCRL, CPKIFCRLPtr& rhsCRL)", TOOLKIT_PATH_MISC, 0, NULL);
01774 
01775         int lhsScore = 0, rhsScore = 0;
01776 
01777         CPKIFCRLTypePtr tmpLHS = _TypeOfCRL(lhsCRL);
01778         const CPKIFCRLTypePtr crlTypeLHS = tmpLHS;
01779 
01780         CPKIFCRLTypePtr tmpRHS = _TypeOfCRL(rhsCRL);
01781         const CPKIFCRLTypePtr crlTypeRHS = tmpRHS;
01782 
01783         // const CPKIFCRLTypePtr crlTypeLHS = _TypeOfCRL(lhsCRL);
01784                 // const CPKIFCRLTypePtr crlTypeRHS = _TypeOfCRL(rhsCRL);
01785 
01786         //we want complete CRLs at the front - hence less than compare operation
01787         if(crlTypeLHS->GetCRLScope() > crlTypeRHS->GetCRLScope())
01788             rhsScore+=5;
01789         else if(crlTypeLHS->GetCRLScope() < crlTypeRHS->GetCRLScope())
01790             lhsScore+=5;
01791 
01792         if(m_issuer == (CPKIFCertificate*)NULL)
01793             return lhsScore > rhsScore;
01794 
01795         CPKIFAuthorityKeyIdentifierPtr lhsAKID = lhsCRL->GetExtension<CPKIFAuthorityKeyIdentifier>();
01796         CPKIFAuthorityKeyIdentifierPtr rhsAKID = rhsCRL->GetExtension<CPKIFAuthorityKeyIdentifier>();
01797         CPKIFSubjectKeyIdentifierPtr issSKID = m_issuer->GetExtension<CPKIFSubjectKeyIdentifier>();
01798         CPKIFAuthorityKeyIdentifierPtr akids[2] = {lhsAKID, rhsAKID};
01799         int* scores[2] = {&lhsScore, &rhsScore};
01800         
01801         for(int ii = 0; ii < 2; ++ii)
01802         {
01803             if(akids[ii] != (CPKIFAuthorityKeyIdentifier*)NULL)
01804             {
01805                 if(akids[ii]->KeyIDPresent())
01806                 {
01807                     if(issSKID != (CPKIFSubjectKeyIdentifier*)NULL)
01808                     {
01809                         CPKIFBufferPtr akidKeyID = akids[ii]->KeyIdentifier();
01810                         CPKIFBufferPtr skidKeyID = issSKID->KeyIdentifier();
01811                         if(akidKeyID != (CPKIFBuffer*)NULL && skidKeyID != (CPKIFBuffer*)NULL)
01812                         {
01813                             if(*akidKeyID == *skidKeyID)
01814                                 *scores[ii]+=10;
01815                             else
01816                                 *scores[ii]-=10;
01817                         }
01818                     }
01819                 }
01820                 else if(akids[ii]->IssDNAndSerialNumberPresent() && m_issuer != (CPKIFCertificate*)NULL)
01821                 {
01822                     const char* lhsSN = akids[ii]->SerialNumber();
01823                     const char* rhsSN = m_issuer->SerialNumber();
01824                     //reviewed 4/24 - added strlen check
01825                     if(strlen(lhsSN) != strlen(rhsSN) || 0 != stricmp(lhsSN, rhsSN))
01826                         *scores[ii]-=10;
01827                     else
01828                     {
01829                         CPKIFGeneralNameList gns;
01830                         akids[ii]->Issuer(gns);
01831 
01832                         CPKIFGeneralNameList::iterator gnPos;
01833                         CPKIFGeneralNameList::iterator gnEnd = gns.end();
01834                         
01835                         //spin through them all and if we find a match - good
01836                         //if not - big deal - this is just for scoring
01837                         //not going to bother comparing curCert issAltNames for this purpose
01838                         for(gnPos = gns.begin(); gnPos != gnEnd; ++gnPos)
01839                         {
01840                             if(CPKIFGeneralName::DIRECTORYNAME == (*gnPos)->GetType())
01841                             {
01842                                 if(*(*gnPos)->directoryName() == *m_issuer->Issuer())
01843                                     scores[ii]+=10;
01844                             }
01845                         }
01846                     }
01847                 }
01848             }
01849         }
01850 
01851         return lhsScore > rhsScore;
01852     }
01860     void SetIssuer(
01862         const CPKIFCertificatePtr& issuer) {m_issuer = issuer;}
01863 private:
01864     CPKIFCertificatePtr m_issuer;
01865 };
01866 
01867 //bool _scopeCompare(CPKIFCRLPtr& lhsCRL, CPKIFCRLPtr& rhsCRL)
01868 //{
01869 //  LOG_STRING_DEBUG("_scopeCompare(CPKIFCRLPtr& lhsCRL, CPKIFCRLPtr& rhsCRL)", TOOLKIT_PATH_MISC, 0, NULL);
01870 //
01871 //  const CPKIFCRLTypePtr crlTypeLHS = _TypeOfCRL(lhsCRL);
01872 //  const CPKIFCRLTypePtr crlTypeRHS = _TypeOfCRL(rhsCRL);
01873 //
01874 //  //we want complete CRLs at the front - hence less than compare operation
01875 //  return crlTypeLHS->GetCRLScope() < crlTypeRHS->GetCRLScope();
01876 //}
01877 
01878 
01879 //status check function that is invoked by both CheckStatus and CheckStatusPath from the public interface
01894 bool CPKIFX509CRLCheckerImpl::CheckStatusInternal(
01896     const CPKIFCertificatePtr& targetCert, 
01898     IPKIFNameAndKey* issuersCertNK, 
01900     const CPKIFCertificatePtr& issuersCert,
01902     RevocationStatus& status, 
01904     CPKIFCertStatusPtr& certStatus, 
01906     bool validatePathToDirectCRLs,
01908     CPKIFPathSettingsPtr& settings,
01910     IPKIFTrustAnchorPtr& rootFromPath)
01911 {
01912     LOG_STRING_DEBUG("CPKIFX509CRLCheckerImpl::CheckStatusInternal", TOOLKIT_PATH_MISC, 0, this);
01913 
01914     //This function takes the following params:
01915     //  - target cert (the cert for which revocation status is sought)  : IN
01916     //  - issuer's cert (the certificate of the issuer of the target cert) : IN
01917     //  - revocation status (low water mark for revocation status) : OUT
01918     //  - certificate status (in which crl and crl entry info may be optionally stored) : IN/OUT
01919 
01920     //added 11/12/2003
01921     if(certStatus == (CPKIFCertStatus*)NULL)
01922     {
01923         CPKIFCertStatusPtr newCS(new CPKIFCertStatus);
01924         certStatus = newCS;
01925     }
01926 
01927 
01928     //initialize the outbound revocation status indicator to NOT_CHECKED
01929     status = NOT_CHECKED;
01930 
01931     //create a CRL info object to receive CRL and CRL entry info for inclusion in outbound cert status object
01932     CPKIFCRLInfoPtr crlInfo(new CPKIFCRLInfo);
01933 
01934     //declare a list to hold the retrieved CRLs and an initial source indicator
01935     CPKIFCRLList crlList, quarantinedCRLs;
01936     PKIInfoSource source = LOCAL;
01937 
01938     //1) Classify the target certificate as one of the 10 types
01939     const CPKIFX509CRLChecker::CERTTYPES certType = _ClassifyCert(targetCert);
01940     
01941     //2) Determine the CRLs to obtain
01942     //  a) Identify the CRL types that apply (i.e. consult a static table w/ CRLCOVERAGEs for each cert type)
01943     //  b) Identify locations from which to retrieve CRLs (i.e. issuer directory entry vs. CRLDP/freshestCRL)
01944     //This is performed by the cache colleagues.  Some colleagues may not maintain info on the source of a CRL
01945     //and may return more than we need, in which case we'll prune the list in step 4.
01946 
01947     //if a freshest CRL extension was present set the source to REMOTE
01948     CPKIFFreshestCRLPtr fresh = targetCert->GetExtension<CPKIFFreshestCRL>();
01949     if(fresh != (CPKIFFreshestCRL*)NULL)
01950         source = ALL;//go ahead and turn on REMOTE searching but also leave on LOCAL
01951 
01952     ScopeCompare _scopeCompare;
01953     _scopeCompare.SetIssuer(issuersCert);
01954 
01955     AssociatedCRLsList acl;
01956     do
01957     {
01958         //3) Obtain CRL(s) - fail if no CRLs can be obtained 
01959         ObtainCRLs(targetCert, source, crlList, settings);
01960 
01961         //move any CRLs from quarantine to active list then clear the quarantine
01962         copy(quarantinedCRLs.begin(), quarantinedCRLs.end(), back_inserter(crlList));
01963         quarantinedCRLs.clear();
01964 
01965         //order the CRLs in crlList such that deltas are at the rear
01966         sort(crlList.begin(), crlList.end(), _scopeCompare);
01967 
01968         CPKIFCRLList::iterator cur;  
01969         CPKIFCRLList::iterator end = crlList.end();  
01970         //clear the associated CRL list - it will be (re)populated by the call to DetermineCompatibilityAndValidity below
01971         acl.clear();
01972 
01973         //4) For each CRL, determine CRL and cert compatibility (type compatibility, dp compatibility,
01974         //   crl issuer compatibility and reason code compatibility (wrt to crl dp reasons).
01975         //5) For each CRL, determine CRL validity (i.e. check currency, verify signature,
01976         //   validate delta scope and process remaining CRL extensions)
01977         DetermineCompatibilityAndValidity(targetCert, issuersCertNK, issuersCert, crlList, validatePathToDirectCRLs, 
01978                                             quarantinedCRLs, settings, acl, rootFromPath);
01979 
01980         //6) Determine if all necessary CRLs were obtained
01981         if(DoWeHaveEverythingWeNeed(targetCert, crlList, quarantinedCRLs))
01982         {
01983             //7) For each CRL, check cert status
01984             try
01985             {
01986                 SeeIfCertHasBeenRevoked(targetCert, acl, status, certStatus, crlInfo);
01987 
01988                 //prepare bools to bail out since we have made our final determination
01989                 return true;
01990             }
01991             catch(CPKIFException&)
01992             {
01993                 //added this 4/7/2004
01994                 //only get here if there's a critical CRLEntry extension
01995             }
01996         }
01997         else
01998         {
01999             //if we do not have all of the crls we need then check additional sources (if possible) or
02000             //terminate the loop 
02001             if(LOCAL == source)
02002             {
02003                 LOG_STRING_INFO("Failed to find necessary CRL(s) using LOCAL sources.  Checking REMOTE sources.", m_parent->thisComponent, 0, this);
02004                 source = REMOTE;
02005             }
02006             else
02007             {
02008                 if(certStatus->GetRevocationStatus() == NOT_CHECKED)
02009                     certStatus->SetDiagnosticCode(PATH_CERT_REVOCATION_STATUS_NOT_DETERMINED);
02010                 return false;
02011             }
02012         }
02013     }while(1);
02014     //Loop terminiation is assured as the source is guaranteed to not be LOCAL on the second loop.  The 
02015     //loop executes a MAX of two times.
02016 }
02017 
02018 //1) performed in CheckStatusInternal (simple call to _ClassifyCert)
02019 //2) handled by cache colleagues
02020 //3)
02030 void CPKIFX509CRLCheckerImpl::ObtainCRLs(
02032     const CPKIFCertificatePtr& targetCert, 
02034     PKIInfoSource& source, 
02036     CPKIFCRLList& crlList,
02038     CPKIFPathSettingsPtr& settings)
02039 {
02040     LOG_STRING_DEBUG("CPKIFX509CRLCheckerImpl::ObtainCRLs", TOOLKIT_PATH_MISC, 0, this);
02041 
02042     //get required interface pointer
02043     IPKIFCRLRepository* crlCache = m_parent->GetMediatorFromParent<IPKIFCRLRepository>();
02044     if(NULL == crlCache)
02045         throw CPKIFPathException(TOOLKIT_PATH_CRL_CHECKER,COMMON_MEDIATOR_MISSING,"IPKIFCRLRepository interface was not available.");
02046 
02047     //get optional interface pointer
02048     IPKIFCRLRepositoryUpdate* crlCacheUpdate = m_parent->GetMediatorFromParent<IPKIFCRLRepositoryUpdate>();
02049 
02050     //testing with syn sources...
02051     //crlCache->GetCRLs(targetCert, crlList, source);
02052 
02053     CPKIFCRLNodeList crlNodeList;
02054     crlCache->GetCRLs(targetCert, crlNodeList, source,settings);
02055 
02056     CPKIFCRLNodeList::iterator pos;
02057     CPKIFCRLNodeList::iterator end = crlNodeList.end();
02058     for(pos = crlNodeList.begin(); pos != end; ++pos)
02059     {
02060         CPKIFCRLPtr crl = (*pos)->GetCRL();
02061         if(crl != (CPKIFCRL*)NULL)
02062         {
02063             crlList.push_back(crl);
02064         }       
02065     }
02066 
02067     CPKIFTimePtr valTime;
02068     if(settings)
02069         valTime = settings->GetValidationTime();
02070 
02071     if(valTime && settings->GetRequireValidationTimeNesting())
02072     {
02073         CRLCoversTimeOfInterest cctoi;
02074         cctoi.SetTimeOfInterest(valTime);
02075         CPKIFCRLList::iterator newEnd = remove_if(crlList.begin(), crlList.end(), cctoi);
02076         crlList.erase(newEnd, crlList.end());
02077     }
02078 
02079     
02080     if(NULL != crlCacheUpdate)
02081     {
02082         //iterate over the CRLs
02083         CPKIFCRLList::iterator pos;
02084         CPKIFCRLList::iterator end = crlList.end();
02085         for(pos = crlList.begin(); pos != end; ++pos)
02086         {
02087             try
02088             {
02089                 CPKIFGeneralNamePtr dummy;
02090                 crlCacheUpdate->AddCRL(*pos, dummy);//XXX-DEFER need means of knowing source of CRL to update cache
02091             }
02092             catch(CPKIFCacheException& e)
02093             {
02094                 //EXCEPTION DELETION
02095                 //don't throw simply because we have no in-memory cache or whatever
02096                 if(COMMON_OPERATION_NOT_HANDLED == e.GetErrorCode())
02097                 {
02098                     //delete e; 
02099                     break;
02100                 }
02101                 else
02102                     throw e;
02103             }
02104         }
02105     }
02106 }
02107 
02108 //4)
02129 void CPKIFX509CRLCheckerImpl::DetermineCompatibilityAndValidity(
02131     const CPKIFCertificatePtr& targetCert,  
02133     IPKIFNameAndKey* issuersCertNK,
02135     const CPKIFCertificatePtr& issuersCert,
02137     CPKIFCRLList& crlList, 
02139     bool validatePathToDirectCRLs, 
02141     CPKIFCRLList& quarantinedCRLs, 
02143     CPKIFPathSettingsPtr& settings,
02145     AssociatedCRLsList& acl,
02147     IPKIFTrustAnchorPtr& rootFromPath)
02148 {
02149 //macro to remove the CRL from the list (erase returns next iterator position hence continue)
02150 #undef DISCARD_CRL_AND_CONTINUE
02151 #define DISCARD_CRL_AND_CONTINUE \
02152 { \
02153     pos = crlList.erase(pos);\
02154     end = crlList.end();\
02155     continue;\
02156 }
02157 
02158     LOG_STRING_DEBUG("CPKIFX509CRLCheckerImpl::DetermineCompatibilityAndValidity", TOOLKIT_PATH_MISC, 0, this);
02159 
02160     //get CRL DP from the target cert, if present, then get DPs from the extension
02161     CPKIFCRLDistributionPointsPtr crlDP = targetCert->GetExtension<CPKIFCRLDistributionPoints>();
02162     CPKIFCRLDistributionPointListPtr dpsFromCRLDP;
02163     if(crlDP != (CPKIFCRLDistributionPoints*)NULL)
02164         dpsFromCRLDP = crlDP->DPs();
02165 
02166     bool requireFresh = false;
02167     
02168     if(settings != (CPKIFPathSettings*)NULL)
02169         requireFresh = settings->GetRequireFreshRevocationData();
02170 
02171     CPKIFCRLPtr bestNonDelta;
02172 
02173     //iterate over all CRLs and perform simple sanity checks, signature checks, etc.
02174     CPKIFCRLList::iterator pos;
02175     CPKIFCRLList::iterator end = crlList.end();
02176     for(pos = crlList.begin(); pos != end;)
02177     {
02178         #ifdef _DEBUG
02179             const char* curCRLIssuerString = (*pos)->Issuer()->ToString();
02180         #endif
02181         //If the CRL is a DP CRL then we need to validate the scope of the CRL with regard to
02182         //the target certificate.
02183         const CPKIFCRLTypePtr crlType = _TypeOfCRL(*pos);
02184         const CPKIFX509CRLChecker::CRLCOVERAGE coverage = crlType->GetCRLCoverage();
02185         const CPKIFX509CRLChecker::CRLSCOPE scope = crlType->GetCRLScope();
02186         const CPKIFX509CRLChecker::CRLAUTHORITY authority = crlType->GetCRLAuthority();
02187         const CPKIFX509CRLChecker::CERTTYPES certType = _ClassifyCert(targetCert);
02188         const CPKIFX509CRLChecker::CRLREASONS reasons = crlType->GetCRLReasons();
02189 
02190         std::vector<CPKIFX509ExtensionPtr> processedExts;
02191         CPKIFCRLDistributionPointPtr activeCRLDP;
02192 
02193         //4-a) confirm that the CRL type and cert type are compatible
02194         if(!g_CompatibleScope[certType][scope] || !g_CompatibleCoverage[certType][coverage])
02195         {
02196             DISCARD_CRL_AND_CONTINUE
02197         }
02198 
02199         //4-b) validate the CRL issuer name
02200         if(!_ValidateCRLIssuerName2(targetCert, dpsFromCRLDP, *pos, scope, activeCRLDP))
02201         {
02202             DISCARD_CRL_AND_CONTINUE
02203         }
02204 
02205         //4-c) Validate DP (sets activeCRLDP as necessary)
02206         if(!_ValidateDP2(dpsFromCRLDP, *pos, scope, activeCRLDP, reasons))
02207         {
02208             DISCARD_CRL_AND_CONTINUE
02209         }
02210 
02211         //4-d) Validate CRL authority
02212         if(!_ValidateCRLAuthority(targetCert, *pos, authority))
02213         {
02214             DISCARD_CRL_AND_CONTINUE
02215         }
02216 
02217         //5-d) Check for critical, unprocessed extensions (assume delta and IDP are processed)
02218         //We currently only handle 2 CRL extensions.  Grab pointers to each (if present) and push them
02219         //into the processedExts list.  They were each fully processed above (or below) if present.
02220         CPKIFDeltaCRLIndicatorPtr delta = (*pos)->GetExtension<CPKIFDeltaCRLIndicator>();
02221         if(delta != (CPKIFDeltaCRLIndicator*)NULL)
02222             processedExts.push_back(delta);
02223 
02224         CPKIFIssuingDistributionPointPtr idp = (*pos)->GetExtension<CPKIFIssuingDistributionPoint>();
02225         if(idp != (CPKIFIssuingDistributionPoint*)NULL)
02226             processedExts.push_back(idp);
02227 
02228         if((*pos)->AreThereAnyUnprocessedCriticalExtensions(processedExts))
02229         {
02230             DISCARD_CRL_AND_CONTINUE
02231         }
02232 
02233         //added 7/21/2005 CRW
02234         if(bestNonDelta != (CPKIFCRL*)NULL && 
02235             (CPKIFX509CRLChecker::CS_COMPLETE == scope ||
02236             CPKIFX509CRLChecker::CS_DP == scope) &&
02237             CPKIFX509CRLChecker::CR_SOMEREASONS != reasons)
02238         {
02239             CPKIFTimePtr curThis = (*pos)->ThisUpdate();
02240             CPKIFTimePtr prevThis = bestNonDelta->ThisUpdate();
02241             if(*prevThis >= *curThis)
02242             {
02243                 DISCARD_CRL_AND_CONTINUE
02244             }
02245         }
02246 
02247         //5-a) Currency check
02248         //5-b) Signature check
02249         //added settings param 9/26/03
02250         if(!PerformCurrencyAndSignatureChecks(targetCert, issuersCertNK, issuersCert, *pos, authority, validatePathToDirectCRLs, processedExts, requireFresh, settings, rootFromPath))
02251         {
02252             DISCARD_CRL_AND_CONTINUE
02253         }
02254 
02255         //added 7/21/2005 CRW
02256         if(CPKIFX509CRLChecker::CS_COMPLETE == scope || 
02257             CPKIFX509CRLChecker::CS_DP == scope)
02258             bestNonDelta = *pos;
02259 
02260         //MOVED DOWN HERE FROM ABOVE 04/28/03 CRW
02261         //SHOULDN"T BE POPULATING  ACL PRIOR TO COMPLETION OF ALL CHECKS
02262         //5-c) Validate delta scope (don't discard on failure - quarantine)
02263         if(!_ValidateDeltaScope(targetCert, *pos, scope, crlList, quarantinedCRLs, acl))
02264         {
02265             DISCARD_CRL_AND_CONTINUE
02266         }
02267 
02268         ++pos; //update here instead of in for statement to account for calls to erase
02269     }
02270 }
02271 
02272 //5
02282 bool CPKIFX509CRLCheckerImpl::DoWeHaveEverythingWeNeed(
02284     const CPKIFCertificatePtr& targetCert, 
02286     CPKIFCRLList& crlList,
02288     CPKIFCRLList& quarantinedCRLs)
02289 {
02290     LOG_STRING_DEBUG("CPKIFX509CRLCheckerImpl::DoWeHaveEverythingWeNeed", TOOLKIT_PATH_MISC, 0, this);
02291 
02292     //added list compilation 04/28/03 CRW
02293     CPKIFCRLList tmpList;
02294     copy(crlList.begin(), crlList.end(), back_inserter(tmpList));
02295     copy(quarantinedCRLs.begin(), quarantinedCRLs.end(), back_inserter(tmpList));
02296 
02297     //5-a) Process critical CRL DP and/or freshestCRL
02298     if(!ProcessCriticalCertExtensions(targetCert, tmpList))
02299         return false;
02300 
02301     //5-b) Process reason codes of interest
02302     if(!_ProcessReasonCodesOfInterest(targetCert, crlList, m_reasons))
02303         return false;
02304 
02305     //5-d) Discard extraneous CRLs
02306     _QuarantineExtraneousCRLs(targetCert, crlList, quarantinedCRLs);
02307 
02308     //return empty check just for sake of sanity
02309     return !crlList.empty();
02310 }
02311 
02312 //6) 
02320 void CPKIFX509CRLCheckerImpl::SeeIfCertHasBeenRevoked(
02322     const CPKIFCertificatePtr& targetCert, 
02324     AssociatedCRLsList& crlList,
02326     RevocationStatus& status, 
02328     CPKIFCertStatusPtr& certStatus,
02330     CPKIFCRLInfoPtr& crlInfo)
02331 {
02332     LOG_STRING_DEBUG("CPKIFX509CRLCheckerImpl::SeeIfCertHasBeenRevoked", TOOLKIT_PATH_MISC, 0, this);
02333 
02334     CPKIFCRLEntryPtr crlEntry, deltaCRLEntry;
02335     status = NOT_REVOKED;
02336 
02337     //this function assumes that the list of CRLs passed in is complete with regard to the target cert and
02338     //simply iterates over the list asking each CRL is the cert has been revoked.
02339     AssociatedCRLsList::iterator pos;
02340     AssociatedCRLsList::iterator end = crlList.end();
02341     for(pos = crlList.begin(); pos != end; ++pos)
02342     {
02343         std::vector<CPKIFX509ExtensionPtr> processedExts;
02344         CPKIFCRLPtr base = (*pos)->m_base;
02345         bool onHold = false;
02346 
02347         //all CRLs that we check get reported back
02348         crlInfo->AddCRL(base);
02349 
02350         if(base->CertOnThisCRL(targetCert, crlEntry))
02351         {
02352             CPKIFCRLReasonPtr reason = crlEntry->GetExtension<CPKIFCRLReason>();
02353             if(reason != (CPKIFCRLReason*)NULL && reason->CertificateHold())
02354             {
02355                 //if cert is on hold then sit tight and inspect the delta
02356                 onHold = true;
02357                 crlInfo->SetCRLEntry(crlEntry);
02358                 certStatus->SetDiagnosticCode(PATH_CERT_REVOKED);
02359                 status = REVOKED;
02360 
02361                 //added 4/7/2004
02362                 processedExts.push_back(reason);
02363             }
02364             else
02365             {
02366                 //added 4/7/2004
02367                 if(reason != (CPKIFCRLReason*)NULL)
02368                     processedExts.push_back(reason);
02369 
02370                 //prepare CRL info w/ CRL entry
02371                 crlInfo->SetCRLEntry(crlEntry);
02372 
02373                 certStatus->SetDiagnosticCode(PATH_CERT_REVOKED);
02374 
02375                 //change the status to revoked
02376                 status = REVOKED;
02377                 break;
02378             }
02379         }
02380 
02381         //added 4/7/2004
02382         if(crlEntry != (CPKIFCRLEntry*)NULL && crlEntry->AreThereAnyUnprocessedCriticalExtensions(processedExts))
02383         {
02384             throw CPKIFPathException(TOOLKIT_PATH_CRL_CHECKER, PATH_UNPROCESSED_CRITICAL_EXTENSION);
02385         }
02386 
02387         //just check the frontmost delta
02388         if(!(*pos)->m_deltas.empty())
02389         {
02390             CPKIFCRLPtr delta = (*pos)->m_deltas.front();
02391             crlInfo->AddCRL(delta);
02392             if(delta->CertOnThisCRL(targetCert, deltaCRLEntry))
02393             {
02394                 CPKIFCRLReasonPtr deltaReason = deltaCRLEntry->GetExtension<CPKIFCRLReason>();
02395                 if(deltaReason != (CPKIFCRLReason*)NULL && deltaReason->RemoveFromCRL())
02396                 {
02397                     //if cert is on hold then sit tight and inspect the delta
02398                     onHold = false;
02399                     certStatus->SetDiagnosticCode(0);
02400                     status = NOT_REVOKED;
02401                 }
02402                 else
02403                 {
02404                     //prepare CRL info w/ CRL entry
02405                     crlInfo->SetCRLEntry(deltaCRLEntry);
02406 
02407                     certStatus->SetDiagnosticCode(PATH_CERT_REVOKED);
02408 
02409                     //change the status to revoked
02410                     status = REVOKED;
02411                     break;
02412                 }
02413             }
02414         }
02415 
02416         //go ahead and bail out after checking the front crl/delta group (the frontmost
02417         //should always be most recent).  remove following line if checking all
02418         //available CRLs is desired (it's not necessary and could lead to trouble
02419         //in onHold cases)
02420         //break; //added 04/26/2003 - removed 4/25/2006 to permit checking where reason codes are checked
02421     }
02422 
02423     //update certStatus with status and crlInfo
02424     certStatus->AddRevocationSource(REVSOURCE_CRL, REV_INFO_CAST(crlInfo), status);
02425     certStatus->SetRevocationStatus(status);
02426     if(REVOKED == status)
02427         certStatus->SetDiagnosticCode(PATH_CERT_REVOKED);
02428     else if (NOT_CHECKED == status)
02429         certStatus->SetDiagnosticCode(PATH_CERT_REVOCATION_STATUS_NOT_DETERMINED);
02430     else
02431         certStatus->SetDiagnosticCode(0);
02432     return;
02433 }
02434 
02435 //functions that are called by the above functions
02436 //commented out 8/26/2004 - unused
02437 /*bool CPKIFX509CRLChecker::ValidatePath(CPKIFCertificatePtr& signersCert)
02438 {
02439     LOG_STRING_DEBUG("CPKIFX509CRLChecker::ValidatePath(CPKIFCertificatePtr& signersCert)", TOOLKIT_PATH_MISC, 0, this);
02440 
02441     //get pointer to necessary interfaces
02442     IPKIFPathValidate* pv = GetMediatorFromParent<IPKIFPathValidate>();
02443     IPKIFPathBuild* pb = GetMediatorFromParent<IPKIFPathBuild>();
02444     if(NULL == pv || NULL == pb)
02445         throw CPKIFPathException(TOOLKIT_PATH_CRL_CHECKER,COMMON_MEDIATOR_MISSING,"One or both of the IPKIFPathValidate or IPKIFPathBuild interfaces was not available.");
02446 
02447     //declare a path and set the target cert
02448     CPKIFCertificatePath path;
02449     path.SetTarget(signersCert);
02450 
02451     //prepare path settings
02452     if(m_impl->m_settings != (CPKIFPathSettings*)NULL)
02453     {
02454         //if settings have been set from outside - use those
02455         path.SetPathSettings(m_impl->m_settings);
02456     }
02457     else
02458     {
02459         //otherwise declare default settings
02460         CPKIFPathSettingsPtr settings(new CPKIFPathSettings);
02461         path.SetPathSettings(m_impl->m_settings);
02462     }
02463 
02464     //try to build a path
02465     if(!pb->BuildPath(path))
02466         return false;
02467 
02468     //validate the path
02469     CPKIFPathValidationResults results;
02470     CPKIFFuncStoragePtr empty;
02471     if(!pv->ValidatePath(path, results, empty))
02472         return false;
02473     
02474     RevocationStatus minAcceptable = NOT_REVOKED;
02475 
02476     //return a bool reflecting the status
02477     RevocationStatus rStatus = results.GetRevocationStatusMostSevere();
02478     return rStatus == minAcceptable;
02479 }
02480 */
02481 //ADDED 7/18
02489 void KeyUsageCheckerCRL(
02491     const CPKIFCertificateNodeEntryPtr& certNode, 
02493     CPKIFPathValidationResults& results, 
02495     CertificateType type)
02496 {
02497     if(EE == type)
02498     {
02499         //make sure EE cert has a key usage extension with CRLSign
02500         CPKIFCertificatePtr curCert = certNode->GetCert();
02501         CPKIFKeyUsagePtr keyUsage = curCert->GetExtension<CPKIFKeyUsage>();
02502         if(keyUsage != (CPKIFKeyUsage*)NULL)
02503         {
02504             if(keyUsage->CRLSign())
02505             {
02506                 CPKIFX509ExtensionPtr keyUsage2 = keyUsage;
02507                 certNode->MarkExtensionAsProcessed(keyUsage2);
02508             }
02509         }
02510 
02511         //don't let unprocessed basic constraints foul us up
02512         CPKIFBasicConstraintsPtr bc = curCert->GetExtension<CPKIFBasicConstraints>();
02513         if(bc != (CPKIFBasicConstraints*)NULL)
02514         {
02515             CPKIFX509ExtensionPtr bc2 = bc;
02516             certNode->MarkExtensionAsProcessed(bc2);
02517         }
02518     }
02519 
02520     //process CA certs here or in a different functor
02521 }
02522 //Functor<void, TYPELIST_3(const CPKIFCertificateNodeEntryPtr&,CPKIFPathValidationResults&, CertificateType)> keyUsageFunctor_CRL(KeyUsageCheckerCRL);
02523 
02524 //added settings param 9/26/03
02535 bool CPKIFX509CRLCheckerImpl::PerformCurrencyAndSignatureChecks(
02537     const CPKIFCertificatePtr& targetCert, 
02539     IPKIFNameAndKey* targetCertIssuersCertNK, 
02540     const CPKIFCertificatePtr& issuersCert, 
02542     CPKIFCRLPtr& crl, 
02544     const CPKIFX509CRLChecker::CRLAUTHORITY authority,
02546     bool validatePathToDirectCRLs, 
02548     std::vector<CPKIFX509ExtensionPtr>& processedExts, 
02550     bool requireFresh, 
02552     CPKIFPathSettingsPtr& settings,
02554     IPKIFTrustAnchorPtr& rootFromPath)
02555 {
02556     LOG_STRING_DEBUG("CPKIFX509CRLCheckerImpl::PerformCurrencyAndSignatureChecks", TOOLKIT_PATH_MISC, 0, this);
02557 
02558     CPKIFFuncStoragePtr keyUsageFunctor_CRL(new CPKIFFuncStorage(KeyUsageCheckerCRL));
02559 
02560     //changed from current time to settings-based time - 7/19/2004
02561     CPKIFTimePtr curTime = settings->GetValidationTime();
02562 
02563     //check the date on the CRL
02564     //added thisUpdate check - 7/19/2004
02565     CPKIFTimePtr thisUpdate = crl->ThisUpdate();
02566     CPKIFDurationPtr duration = settings->GetDuration();
02567     bool requireRecent = settings->GetRequireSufficientlyRecent();
02568     CPKIFTimePtr sufficientlyRecent(new CPKIFTime(*curTime - *duration));
02569 
02570     if(requireRecent && (thisUpdate != (CPKIFTime*)NULL && *thisUpdate < *sufficientlyRecent))
02571         return false; //if we require fresh CRLs and the curTime is past the nextUpdate then return false
02572 
02573     CPKIFTimePtr nextUpdate = crl->NextUpdate();
02574     if(requireFresh && nextUpdate != (CPKIFTime*)NULL && *curTime > *nextUpdate)
02575         return false; //if we require fresh CRLs and the curTime is past the nextUpdate then return false
02576 
02577     //set up some variables for use in calculating hash of CRL (alg will be set up below)
02578     char hashResult[MAXHASH];
02579     int nResultLen = MAXHASH;
02580     PKIFCRYPTO::HASH_ALG hashAlg = PKIFCRYPTO::SHA1;
02581 
02582     //for now we are supporting MD5 and SHA1 only adjust the below code accordingly when and if that changes
02583     CPKIFAlgorithmIdentifierPtr sigAlg = crl->SignatureAlgorithm();
02584     CPKIFOIDPtr aTmpOID = sigAlg->oid();
02585     if(!GetCACHashAlg(aTmpOID/*sigAlg->oid()*/, &hashAlg))
02586         throw CPKIFPathException(TOOLKIT_PATH_CRL_CHECKER, CRYPTO_ALG_NOT_SUPPORTED);
02587 
02588     IPKIFCryptoMisc* cryptoMisc = m_parent->GetMediatorFromParent<IPKIFCryptoMisc>();
02589     IPKIFCryptoRawOperations* crypto = m_parent->GetMediatorFromParent<IPKIFCryptoRawOperations>();
02590 
02591     //obtain the hash of the to-be-signed CRL
02592     if(!_GetHashOfToBeSignedCRL2(crl, cryptoMisc, hashAlg, (unsigned char*)hashResult, &nResultLen))
02593         return false;
02594 
02595     //get the CRL signature in a buffer
02596     CPKIFBufferPtr sigBuf = crl->Signature();
02597 
02598     PKIInfoSource source = LOCAL;
02599     CPKIFCertificateList crlIssuerCerts;
02600 
02601     IPKIFPathValidate* pv = m_parent->GetMediatorFromParent<IPKIFPathValidate>();
02602     IPKIFPathBuild* pb = m_parent->GetMediatorFromParent<IPKIFPathBuild>();
02603 
02604     //----------------------------------------------------------------------------------------------------
02605     CPKIFTrustRoot* issAsCertTa = dynamic_cast<CPKIFTrustRoot*>(targetCertIssuersCertNK);
02606     CPKIFCertificate* issAsCert = dynamic_cast<CPKIFCertificate*>(targetCertIssuersCertNK);
02607     if(!issAsCertTa && !issAsCert)
02608     {
02609         //the issuer is a non-cert TA object
02610 
02611         //stuff the cert in a key material object
02612         CPKIFKeyMaterial key;
02613         CPKIFSubjectPublicKeyInfoPtr spki = targetCertIssuersCertNK->GetSubjectPublicKeyInfo();
02614         key.SetSubjectPublicKeyInfo(spki);
02615 
02616         //see if it verifies - if not move on
02617         try
02618         {
02619             if(crypto->Verify(key, (unsigned char*)hashResult, nResultLen, (unsigned char*)sigBuf->GetBuffer(), sigBuf->GetLength(), hashAlg))
02620             {
02621                 return true;
02622             }
02623         }
02624         catch(CPKIFException&)
02625         {
02626         }
02627     }
02628     //----------------------------------------------------------------------------------------------------
02629     do
02630     {
02631         //get a list of candidate CRL issuer certs
02632         if(!_GetCRLIssuersCert(crl, targetCertIssuersCertNK, issuersCert, crlIssuerCerts, source, m_parent/*this*/, authority, settings))
02633         {
02634             //changed from simple break to conditional break 12/8/2003
02635             if(REMOTE == source)
02636             {
02637                 break;
02638             }
02639             else
02640             {
02641                 source = REMOTE;
02642                 continue;
02643             }
02644         }
02645 
02646         //added verification re-attempt w/ working params stuff - 04/18/2003
02647         bool reattemptWithWorkingParams = false;
02648         
02649         CPKIFCertificateList::iterator pos;
02650         CPKIFCertificateList::iterator end = crlIssuerCerts.end();
02651         for(pos = crlIssuerCerts.begin(); pos != end; ++pos)
02652         {
02653             //check the public key alg of the cert - if it doesn't match try the next one
02654             CPKIFAlgorithmIdentifierPtr certAlg = (*pos)->SubjectPublicKeyInfo()->alg();
02655             if(GetAlgClass(certAlg) != GetAlgClass(sigAlg))
02656                 continue;
02657 
02658             //make sure cert has proper key usage - if not move on to the next one
02659             CPKIFKeyUsagePtr ku = (*pos)->GetExtension<CPKIFKeyUsage>();
02660             if(ku != (CPKIFKeyUsage*)NULL && !ku->CRLSign())
02661                 continue;
02662 
02663             //stuff the cert in a key material object
02664             CPKIFKeyMaterial key;
02665             CPKIFBufferPtr certBuf = (*pos)->Encoded();
02666             key.SetCertificate(certBuf->GetBuffer(), certBuf->GetLength());
02667 
02668             //see if it verifies - if not move on
02669             try
02670             {
02671                 if(!crypto->Verify(key, (unsigned char*)hashResult, nResultLen, (unsigned char*)sigBuf->GetBuffer(), sigBuf->GetLength(), hashAlg))
02672                     continue;
02673             }
02674             catch(CPKIFException& e)
02675             {
02676                 if( PKIFCAPING_KEY_IMPORT_FAILED == e.GetErrorCode() || 
02677                     PKIFCAPI_KEY_IMPORT_FAILED == e.GetErrorCode() || 
02678                     PKIF_CRYPTOPP_RAW_IMPORT_FAILED == e.GetErrorCode() ||
02679                     PKIFNSS_CERT_IMPORT_FAILED == e.GetErrorCode())
02680                         reattemptWithWorkingParams = true;
02681                 else
02682                     throw e;
02683             }
02684 
02685             IPKIFNameAndKey* posNK = dynamic_cast<IPKIFNameAndKey*>(&(*(*pos)));
02686             if(/*CPKIFX509CRLChecker::CRLAUTHORITY::CA_DIRECT == authority*/
02687                 *posNK == *targetCertIssuersCertNK
02688                 && false == validatePathToDirectCRLs && false == reattemptWithWorkingParams)
02689                 return true;
02690 
02691             //guard against infinite loop (replaced with better guard below)
02692             if(*targetCert == *(*pos))
02693                 return false; //changed from return false 9/12/03 then back again - 12/4/2003
02694 
02695             //prepare a path object
02696             CPKIFCertificatePath path;
02697             path.SetTarget(*pos);
02698             path.SetPathSettings(settings);
02699 
02700             CPKIFCertificateNodeEntryPtr targetAsNode(new CPKIFCertificateNodeEntry);
02701             targetAsNode->SetCert(targetCert);
02702 
02703             do
02704             {
02705                 //build and validate a path to the cert - if it fails move on
02706                 bool pB = pb->BuildPath(path);
02707                 if(!pB)
02708                     break;
02709 
02710                 //guard against infinite loop - 9/12/03
02711                 CPKIFCertificateNodeList certsFromPath;
02712                 path.GetPath(certsFromPath);
02713                 GottaMatch<CPKIFCertificateNodeEntryPtr> gm;
02714                 gm.SetRHS(targetAsNode);
02715                 CPKIFCertificateNodeList::iterator certsFromPathEnd = certsFromPath.end();
02716                 if(certsFromPathEnd != find_if(certsFromPath.begin(), certsFromPath.end(), gm))
02717                 {
02718                     //if we found the target on the path to the CRL then ignore this path
02719                     continue;
02720                 }
02721 
02722                 //require the same trust anchor as the certification path
02723                 if(rootFromPath != (CPKIFTrustRoot*)NULL)
02724                 {
02725                     IPKIFTrustAnchorPtr candidateRoot;
02726                     path.GetTrustRoot(candidateRoot);
02727                     if(candidateRoot != (CPKIFTrustRoot*)NULL)
02728                     {
02729                         if(!(*candidateRoot == *rootFromPath))
02730                                 continue;
02731                     }
02732                 }
02733 
02734                 CPKIFPathValidationResults results;
02735                 CPKIFFuncStoragePtr empty;
02736                 pv->SetAdditionalCertificateChecks(keyUsageFunctor_CRL);
02737                 pv->ValidatePath(path, results, empty);
02738                 if(results.PathSuccessfullyValidated())
02739                 {
02740                     if(reattemptWithWorkingParams)
02741                     {
02742                         CPKIFAlgorithmIdentifierPtr wp = results.GetWorkingParams();
02743                         key.SetWorkingParameters(wp);
02744                         if(!crypto->Verify(key, (unsigned char*)hashResult, nResultLen, (unsigned char*)sigBuf->GetBuffer(), sigBuf->GetLength(), hashAlg))
02745                             continue;
02746                         else
02747                             return true;
02748                     }
02749                     else
02750                         return true;
02751                 }
02752             }while(1);
02753         }
02754 
02755         if(LOCAL == source)
02756         {
02757             source = REMOTE;
02758             LOG_STRING_INFO("Failed to find necessary CRL signer certificate using LOCAL sources.  Checking REMOTE sources.", m_parent->thisComponent, 0, this);
02759         }
02760         else
02761             break;
02762     }while(1);  //loop termination occurs when _GetCRLIssuersCert fails to return any candidate certs
02763                 //or when validation is successful
02764 
02765     return false;
02766 }
02767 
02768 //----------------------------------------------------------------------------------------------------
02769 //
02770 //  PUBLIC MEMBER FUNCTIONS
02771 //
02772 //----------------------------------------------------------------------------------------------------
02780 CPKIFX509CRLChecker::CPKIFX509CRLChecker(void):m_impl(new CPKIFX509CRLCheckerImpl)
02781 {
02782     m_impl->m_parent = this;
02783     LOG_STRING_DEBUG("CPKIFX509CRLChecker::CPKIFX509CRLChecker(void)", TOOLKIT_PATH_MISC, 0, this);
02784 }
02792 CPKIFX509CRLChecker::~CPKIFX509CRLChecker(void)
02793 {
02794     LOG_STRING_DEBUG("CPKIFX509CRLChecker::~CPKIFX509CRLChecker(void)", TOOLKIT_PATH_MISC, 0, this);
02795     delete m_impl;
02796     m_impl = '\0';
02797 }
02805 void CPKIFX509CRLChecker::Initialize() 
02806 {
02807     LOG_STRING_DEBUG("CPKIFX509CRLChecker::Initialize()", TOOLKIT_PATH_MISC, 0, this);
02808 }
02818 bool CPKIFX509CRLChecker::CheckStatus(
02821     const CPKIFCertificatePtr& targetCert,  //IN: cert for which revocation status is sought
02824     const CPKIFCertificatePtr& issuersCert, //IN: cert of targetCert's issuer
02826     RevocationStatus& status,               //OUT: revocation status
02829     CPKIFCertStatusPtr& certStatus)         //OUT: status info (i.e. CRLs, CRL entry)
02830 {
02831     LOG_STRING_DEBUG("CPKIFX509CRLChecker::CheckStatus", TOOLKIT_PATH_MISC, 0, this);
02832 
02833     //This function simply calls the internal status checker with the flag to verify 
02834     //path to direct CRLs issuer set to true.
02835     if(!m_impl->m_settings)
02836     {
02837         CPKIFPathSettingsPtr settings(new CPKIFPathSettings);
02838         m_impl->m_settings = settings;
02839     }
02840     IPKIFTrustAnchorPtr emptyRoot;
02841 
02842     IPKIFNameAndKey* issuersCertNK = dynamic_cast<IPKIFNameAndKey*>(&(*issuersCert));
02843     return m_impl->CheckStatusInternal(targetCert, issuersCertNK, issuersCert, status, certStatus, true, m_impl->m_settings, emptyRoot);
02844 }
02853 bool CPKIFX509CRLChecker::CheckStatusPath(
02856     CPKIFCertificatePath& path, //IN/OUT: validated path w/ certs for which revocation status is sought
02859     RevocationStatus& status)   //OUT: low-water mark of revocation status in path                                       
02860 {
02861     LOG_STRING_DEBUG("CPKIFX509CRLChecker::CheckStatusPath", TOOLKIT_PATH_MISC, 0, this);
02862 
02863     //initialize the outbound low-water revocation status
02864     status = NOT_CHECKED;
02865 
02866     //remove any CRLs from the path's CRL list - we'll populate it below
02867     //rev status info is now stored solely on cert status object
02868     //path.ClearCRLs(); 
02869 
02870     //get certs from path
02871     CPKIFCertificateNodeList certNodeList;
02872     path.GetPath(certNodeList);
02873 
02874     //get the trust root from the path
02875     IPKIFTrustAnchorPtr root;
02876     path.GetTrustRoot(root);
02877 
02878     //variables used in the following loop
02879     bool statusSet = false;                     //iterator to indicate if status has been set
02880     CPKIFCertificatePtr curCert, issuersCert;   //pointers to relevant certs
02881     IPKIFNameAndKeyPtr issuersCertNK;       
02882     CPKIFCertStatusPtr curCertStatus;           //pointer to cert status object for current cert
02883     RevocationStatus rStatus = NOT_CHECKED, pathStatus = NOT_CHECKED;                   //revocation status of current cert
02884 
02885     //set the initial curCert value to the trust root of the path to prepare for first iteration
02886     //CPKIFTrustRoot* ta = dynamic_cast<CPKIFTrustRoot*>(&(*(root)));
02887     //if(ta != NULL)
02888     //  ta->GetCert(issuersCert);
02889 
02890     //issuersCertNK = dynamic_cast<IPKIFNameAndKey*>(&(*(root)));
02891 
02892     issuersCertNK = dynamic_pointer_cast<IPKIFNameAndKey, IPKIFTrustAnchor>(root);
02893 
02894 
02895     CPKIFPathSettingsPtr settings;
02896     path.GetPathSettings(settings);
02897 
02898     //iterate over all certs in the path and invoke the CheckStatusInternal function
02899     CPKIFCertificateNodeList::iterator pos;
02900     CPKIFCertificateNodeList::iterator end = certNodeList.end();
02901     for(pos = certNodeList.begin(); pos != end; ++pos)
02902     {
02903         //initialize loop variables for this iteration
02904         //issuersCert = curCert;
02905         curCert = (*pos)->GetCert();
02906         curCertStatus = (*pos)->GetStatus();
02907 
02908         if(NOT_CHECKED != curCertStatus->GetRevocationStatus())
02909         {
02910             pathStatus = min(pathStatus, curCertStatus->GetRevocationStatus());
02911 
02912             issuersCert = curCert;
02913             //issuersCertNK = dynamic_cast<IPKIFNameAndKey*>(&(*(curCert)));
02914             issuersCertNK = dynamic_pointer_cast<IPKIFNameAndKey,CPKIFCertificate>(curCert);
02915             continue;
02916         }
02917         rStatus = NOT_CHECKED;
02918 
02919         //added noCheck check 2/4/2004
02920         CPKIFX509ExtensionPtr ext;
02921         curCert->GetExtensionByOID(*g_ocspNoCheck, ext);
02922 
02923         //if nocheck extension is present then relax requirement to check revocation
02924         if(ext != (CPKIFX509Extension*)NULL)
02925         {
02926             pathStatus = min(status, NOT_REVOKED);
02927         }
02928         else
02929         {
02930             //We pass false for the last parameter as this function assumes that the path
02931             //has been validated and thus we need not build/validate a path to issuers of 
02932             //direct CRLs. 
02933             m_impl->CheckStatusInternal(curCert, issuersCertNK.get(), issuersCert, rStatus, curCertStatus, false, settings, root);
02934             if(!statusSet)
02935             {
02936                 pathStatus = rStatus;
02937                 statusSet = true;
02938             }
02939             else
02940                 pathStatus = min(pathStatus, rStatus);
02941         }
02942 
02943         issuersCert = curCert;
02944         //issuersCertNK = dynamic_cast<IPKIFNameAndKey*>(&(*(curCert)));
02945         issuersCertNK = dynamic_pointer_cast<IPKIFNameAndKey,CPKIFCertificate>(curCert);
02946     }
02947 
02948     status = pathStatus;
02949     return status != NOT_CHECKED;
02950 }
02960 void CPKIFX509CRLChecker::SetReasonCodesOfInterest(
02962     CPKIFReasonFlagsPtr& reasons)
02963 {
02964     m_impl->m_reasons = reasons;
02965 }
02976 CPKIFReasonFlagsPtr CPKIFX509CRLChecker::GetReasonCodesOfInterest() const
02977 {
02978     return m_impl->m_reasons;
02979 }
02980 
02981 CPKIFPathSettingsPtr CPKIFX509CRLChecker::GetPathSettings() const
02982 {
02983     return m_impl->m_settings;
02984 }
02985 void CPKIFX509CRLChecker::SetPathSettings(CPKIFPathSettingsPtr& settings)
02986 {
02987     m_impl->m_settings = settings;
02988 }

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