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"
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
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"
00078 #include "PKIFCryptoPPErrors.h"
00079 #include "PKIFNSSErrors.h"
00080 #include "PKIFKeyMaterial.h"
00081
00082 extern CPKIFOIDPtr g_ocspNoCheck;
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
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
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
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297 #include "CRLType.h"
00299 struct CPKIFX509CRLCheckerImpl {
00300
00301
00302
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
00332 bool CheckStatusInternal(const CPKIFCertificatePtr& targetCert, IPKIFNameAndKey* issuersCertNK, const CPKIFCertificatePtr& issuersCert,
00333 RevocationStatus& status, CPKIFCertStatusPtr& certStatus, bool validatePathToDirectCRLs, CPKIFPathSettingsPtr& settings, IPKIFTrustAnchorPtr& rootFromPath);
00334
00335
00336
00337
00338
00339 void ObtainCRLs(const CPKIFCertificatePtr& targetCert, PKIInfoSource& source, CPKIFCRLList& crlList, CPKIFPathSettingsPtr& settings);
00340
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
00344 bool DoWeHaveEverythingWeNeed(const CPKIFCertificatePtr& targetCert, CPKIFCRLList& crlList, CPKIFCRLList& quarantinedCRLs);
00345
00346 void SeeIfCertHasBeenRevoked(const CPKIFCertificatePtr& targetCert, AssociatedCRLsList& crlList,
00347 RevocationStatus& status, CPKIFCertStatusPtr& certStatus, CPKIFCRLInfoPtr& crlInfo);
00348
00349
00350
00351
00352
00353
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);
00357
00358 };
00360
00361
00362
00363
00364
00372 CPKIFCRLTypePtr _TypeOfCRL(
00374 const CPKIFCRLPtr& crl)
00375 {
00376 LOG_STRING_DEBUG("_TypeOfCRL", TOOLKIT_PATH_MISC, 0, NULL);
00377
00378
00379
00380
00381
00382
00383
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
00390 CPKIFDeltaCRLIndicatorPtr delta = crl->GetExtension<CPKIFDeltaCRLIndicator>();
00391 CPKIFIssuingDistributionPointPtr idp = crl->GetExtension<CPKIFIssuingDistributionPoint>();
00392
00393 CPKIFCRLTypePtr type(new CPKIFCRLType);
00394
00395
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
00406 if(delta != (CPKIFDeltaCRLIndicator*)NULL)
00407 questionnaire.set(ARE_YOU_DELTA, true);
00408
00409
00410 if(idp != (CPKIFIssuingDistributionPoint*)NULL)
00411 {
00412
00413
00414
00415
00416
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
00437 if(idp->IndirectCRL())
00438 questionnaire.set(ARE_YOU_INDIRECT, true);
00439
00440
00441 CPKIFDistributionPointNamePtr dp = idp->DistributionPoint();
00442 if(dp != (CPKIFDistributionPointName*)NULL)
00443 questionnaire.set(ARE_YOU_DP, true);
00444
00445
00446 if(idp->OnlySomeReasons())
00447 questionnaire.set(ONLY_SOME_REASONS, true);
00448
00449 }
00450
00451
00452 if(!questionnaire[ARE_YOU_AA_ONLY])
00453 {
00454
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
00463 if(questionnaire[ARE_YOU_INDIRECT])
00464 type->SetCRLAuthority(CPKIFX509CRLChecker::CA_INDIRECT);
00465 else
00466 type->SetCRLAuthority(CPKIFX509CRLChecker::CA_DIRECT);
00467
00468
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
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
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
00502
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
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
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
00614
00615 CPKIFCRLDistributionPointPtr tmpEmpty;
00616 activeCRLDP = tmpEmpty;
00617
00618
00619
00620
00621
00622 CPKIFNamePtr crlIssuer = crl->Issuer();
00623 CPKIFNamePtr certIssuer = targetCert->Issuer();
00624
00625
00626
00627
00628
00629
00630
00631
00632
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
00644
00645 CPKIFCRLDistributionPointList::iterator pos;
00646 CPKIFCRLDistributionPointList::iterator end = dpsFromCRLDP->end();
00647 for(pos = dpsFromCRLDP->begin(); pos != end; ++pos)
00648 {
00649
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
00671 if(!crlIssuerSpecifiedInDP)
00672 {
00673 if(*crlIssuer == *certIssuer)
00674 return true;
00675 }
00676
00677
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
00702
00703
00704 if(CPKIFX509CRLChecker::CS_DP == scope || CPKIFX509CRLChecker::CS_DELTA_DP == scope)
00705 {
00706
00707 if(dpsFromCRLDP == (CPKIFCRLDistributionPointList*)NULL)
00708 return false;
00709
00710
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
00728
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
00756 CPKIFCRLDistributionPointList::iterator pos;
00757 CPKIFCRLDistributionPointList::iterator end = dpsFromCRLDP->end();
00758 for(pos = dpsFromCRLDP->begin(); pos != end; ++pos)
00759 {
00760
00761
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
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
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
00830 if(!foundMatch)
00831 return false;
00832 }
00833
00835
00836
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
00872 return true;
00873 }
00874
00875
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
00896
00897
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
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
00931 if (lhsLen < 3 || rhsLen < 3)
00932 throw CPKIFPathException(TOOLKIT_PATH_CRL_CHECKER, COMMON_INVALID_INPUT, "Invalid CRL number passed to _CompareCRLNumbers.");
00933
00934
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
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
00947
00948
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
00954 if (ilhsLen < irhsLen)
00955 return 1;
00956 else if(ilhsLen > irhsLen)
00957 return -1;
00958
00959
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
00969 return 0;
00970 }
00971
00972
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
00997 if(CPKIFX509CRLChecker::CS_DELTA != scope && CPKIFX509CRLChecker::CS_DELTA_DP != scope)
00998 {
00999
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
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
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
01035 if(crl == tmpCRL)
01036 continue;
01037
01038
01039 CPKIFNamePtr tmpCRLIssuer = tmpCRL->Issuer();
01040 if(tmpCRLIssuer != (CPKIFCRL*)NULL && !(*crlIssuer == *tmpCRLIssuer))
01041 continue;
01042
01043
01044 if(crlStreamIdentifierSet)
01045 {
01046 CPKIFCRLStreamIdentifierPtr tmpCRLStreamIdentifierExt = tmpCRL->GetExtension<CPKIFCRLStreamIdentifier>();
01047 if(tmpCRLStreamIdentifierExt != (CPKIFCRLStreamIdentifier*)NULL &&
01048 *crlStreamIdentifier != *tmpCRLStreamIdentifierExt->CRLStreamIdentifier())
01049 continue;
01050 }
01051
01052 CPKIFCRLNumberPtr crlNumber = tmpCRL->GetExtension<CPKIFCRLNumber>();
01053 if(crlNumber != (CPKIFCRLNumber*)NULL && _CompareCRLNumbers(baseNumber, crlNumber->CRLNumber()) < 0)
01054 continue;
01055
01056
01057 if(akid != (CPKIFAuthorityKeyIdentifier*)NULL)
01058 {
01059 CPKIFAuthorityKeyIdentifierPtr tmpAKID = tmpCRL->GetExtension<CPKIFAuthorityKeyIdentifier>();
01060 if(tmpAKID != (CPKIFAuthorityKeyIdentifier*)NULL && !(*akid == *tmpAKID))
01061 continue;
01062 }
01063
01064
01065 CPKIFIssuingDistributionPointPtr tmpIDP = tmpCRL->GetExtension<CPKIFIssuingDistributionPoint>();
01066 if(idp == (CPKIFIssuingDistributionPoint*)NULL)
01067 {
01068 if(tmpIDP != (CPKIFIssuingDistributionPoint*)NULL)
01069 continue;
01070 }
01071 else if(tmpIDP == (CPKIFIssuingDistributionPoint*)NULL)
01072 continue;
01073 else if(!(*idp == *tmpIDP))
01074 continue;
01075
01076
01077 foundMatch = true;
01078
01079 (*aclPos)->m_deltas.push_back(crl);
01080 }
01081
01082 if(!foundMatch)
01083 {
01084
01085 quarantinedDeltas.push_back(crl);
01086 }
01087
01088 return foundMatch;
01089 }
01090
01091
01099 bool ProcessCriticalCertExtensions(
01101 const CPKIFCertificatePtr& targetCert,
01103 CPKIFCRLList& crlList)
01104 {
01105 LOG_STRING_DEBUG("ProcessCriticalCertExtensions", TOOLKIT_PATH_MISC, 0, NULL);
01106
01107
01108 CPKIFCRLDistributionPointListPtr dpsFromFresh;
01109 CPKIFCRLDistributionPointListPtr dpsFromCRLDP;
01110
01111
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
01139
01140
01141 if(!foundFreshMatch && CPKIFX509CRLChecker::CS_COMPLETE != scope && _ValidateDP2(dpsFromFresh, *pos, scope, activeCRLDP, reasons))
01142 foundFreshMatch = true;
01143
01144
01145 if(!foundCRLDPMatch && CPKIFX509CRLChecker::CS_COMPLETE != scope && _ValidateDP2(dpsFromCRLDP, *pos, scope, activeCRLDP, reasons))
01146 foundCRLDPMatch = true;
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
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
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
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;
01314 }
01315 else
01316 return true;
01317 }
01318
01319
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
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
01431
01432
01433
01434
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
01476
01477
01478
01489 bool _GetHashOfToBeSignedCRL2(
01491 const CPKIFCRLPtr& crl,
01493 IPKIFCryptoMisc* cryptoMisc,
01495 PKIFCRYPTO::HASH_ALG hashAlg,
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
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
01517 OOCTXT ctxt;
01518 initContext (&ctxt);
01519 setBERDecBufPtr(&ctxt, crlBuf->GetBuffer(), length, NULL, NULL);
01520 OOCTXT* pctxt = &ctxt;
01521
01522
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
01532 size_t byteIndex = ctxt.buffer.byteIndex;
01533
01534
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
01544
01545
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
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
01572 freeEncodeBuffer(&ctxt);
01573 memFreeAll(&ctxt);
01574
01575 throw e;
01576 }
01577
01578
01579 delete hash;
01580
01581
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
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
01622 bool issuedByCertIssuer = false;
01623 if(*crlIssuerName == *targetCertIssuersCertNK->GetSubjectName())
01624 issuedByCertIssuer = true;
01625
01626 if(REMOTE != source)
01627 {
01628
01629 if(*crlIssuerName == *targetCertIssuersCertNK->GetSubjectName() && targetCertIssuersCert != (CPKIFCertificate*)NULL)
01630 crlIssuerCerts.push_back(targetCertIssuersCert);
01631
01632
01633
01634
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
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
01663
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
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
01709 (*nodeListPos)->AddToScore(50);
01710
01711 CPKIFPolicyMappingsPtr policyMappings;
01712 if(SomeMatch(cpsFromCert, initPolSet, policyMappings))
01713 (*nodeListPos)->AddToScore(50);
01714 }
01715
01716
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
01730
01731
01732
01733 }
01734
01735
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
01752
01753
01754
01755
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
01784
01785
01786
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
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
01836
01837
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
01868
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879
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
01915
01916
01917
01918
01919
01920
01921 if(certStatus == (CPKIFCertStatus*)NULL)
01922 {
01923 CPKIFCertStatusPtr newCS(new CPKIFCertStatus);
01924 certStatus = newCS;
01925 }
01926
01927
01928
01929 status = NOT_CHECKED;
01930
01931
01932 CPKIFCRLInfoPtr crlInfo(new CPKIFCRLInfo);
01933
01934
01935 CPKIFCRLList crlList, quarantinedCRLs;
01936 PKIInfoSource source = LOCAL;
01937
01938
01939 const CPKIFX509CRLChecker::CERTTYPES certType = _ClassifyCert(targetCert);
01940
01941
01942
01943
01944
01945
01946
01947
01948 CPKIFFreshestCRLPtr fresh = targetCert->GetExtension<CPKIFFreshestCRL>();
01949 if(fresh != (CPKIFFreshestCRL*)NULL)
01950 source = ALL;
01951
01952 ScopeCompare _scopeCompare;
01953 _scopeCompare.SetIssuer(issuersCert);
01954
01955 AssociatedCRLsList acl;
01956 do
01957 {
01958
01959 ObtainCRLs(targetCert, source, crlList, settings);
01960
01961
01962 copy(quarantinedCRLs.begin(), quarantinedCRLs.end(), back_inserter(crlList));
01963 quarantinedCRLs.clear();
01964
01965
01966 sort(crlList.begin(), crlList.end(), _scopeCompare);
01967
01968 CPKIFCRLList::iterator cur;
01969 CPKIFCRLList::iterator end = crlList.end();
01970
01971 acl.clear();
01972
01973
01974
01975
01976
01977 DetermineCompatibilityAndValidity(targetCert, issuersCertNK, issuersCert, crlList, validatePathToDirectCRLs,
01978 quarantinedCRLs, settings, acl, rootFromPath);
01979
01980
01981 if(DoWeHaveEverythingWeNeed(targetCert, crlList, quarantinedCRLs))
01982 {
01983
01984 try
01985 {
01986 SeeIfCertHasBeenRevoked(targetCert, acl, status, certStatus, crlInfo);
01987
01988
01989 return true;
01990 }
01991 catch(CPKIFException&)
01992 {
01993
01994
01995 }
01996 }
01997 else
01998 {
01999
02000
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
02015
02016 }
02017
02018
02019
02020
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
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
02048 IPKIFCRLRepositoryUpdate* crlCacheUpdate = m_parent->GetMediatorFromParent<IPKIFCRLRepositoryUpdate>();
02049
02050
02051
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
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);
02091 }
02092 catch(CPKIFCacheException& e)
02093 {
02094
02095
02096 if(COMMON_OPERATION_NOT_HANDLED == e.GetErrorCode())
02097 {
02098
02099 break;
02100 }
02101 else
02102 throw e;
02103 }
02104 }
02105 }
02106 }
02107
02108
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
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
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
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
02182
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
02194 if(!g_CompatibleScope[certType][scope] || !g_CompatibleCoverage[certType][coverage])
02195 {
02196 DISCARD_CRL_AND_CONTINUE
02197 }
02198
02199
02200 if(!_ValidateCRLIssuerName2(targetCert, dpsFromCRLDP, *pos, scope, activeCRLDP))
02201 {
02202 DISCARD_CRL_AND_CONTINUE
02203 }
02204
02205
02206 if(!_ValidateDP2(dpsFromCRLDP, *pos, scope, activeCRLDP, reasons))
02207 {
02208 DISCARD_CRL_AND_CONTINUE
02209 }
02210
02211
02212 if(!_ValidateCRLAuthority(targetCert, *pos, authority))
02213 {
02214 DISCARD_CRL_AND_CONTINUE
02215 }
02216
02217
02218
02219
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
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
02248
02249
02250 if(!PerformCurrencyAndSignatureChecks(targetCert, issuersCertNK, issuersCert, *pos, authority, validatePathToDirectCRLs, processedExts, requireFresh, settings, rootFromPath))
02251 {
02252 DISCARD_CRL_AND_CONTINUE
02253 }
02254
02255
02256 if(CPKIFX509CRLChecker::CS_COMPLETE == scope ||
02257 CPKIFX509CRLChecker::CS_DP == scope)
02258 bestNonDelta = *pos;
02259
02260
02261
02262
02263 if(!_ValidateDeltaScope(targetCert, *pos, scope, crlList, quarantinedCRLs, acl))
02264 {
02265 DISCARD_CRL_AND_CONTINUE
02266 }
02267
02268 ++pos;
02269 }
02270 }
02271
02272
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
02293 CPKIFCRLList tmpList;
02294 copy(crlList.begin(), crlList.end(), back_inserter(tmpList));
02295 copy(quarantinedCRLs.begin(), quarantinedCRLs.end(), back_inserter(tmpList));
02296
02297
02298 if(!ProcessCriticalCertExtensions(targetCert, tmpList))
02299 return false;
02300
02301
02302 if(!_ProcessReasonCodesOfInterest(targetCert, crlList, m_reasons))
02303 return false;
02304
02305
02306 _QuarantineExtraneousCRLs(targetCert, crlList, quarantinedCRLs);
02307
02308
02309 return !crlList.empty();
02310 }
02311
02312
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
02338
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
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
02356 onHold = true;
02357 crlInfo->SetCRLEntry(crlEntry);
02358 certStatus->SetDiagnosticCode(PATH_CERT_REVOKED);
02359 status = REVOKED;
02360
02361
02362 processedExts.push_back(reason);
02363 }
02364 else
02365 {
02366
02367 if(reason != (CPKIFCRLReason*)NULL)
02368 processedExts.push_back(reason);
02369
02370
02371 crlInfo->SetCRLEntry(crlEntry);
02372
02373 certStatus->SetDiagnosticCode(PATH_CERT_REVOKED);
02374
02375
02376 status = REVOKED;
02377 break;
02378 }
02379 }
02380
02381
02382 if(crlEntry != (CPKIFCRLEntry*)NULL && crlEntry->AreThereAnyUnprocessedCriticalExtensions(processedExts))
02383 {
02384 throw CPKIFPathException(TOOLKIT_PATH_CRL_CHECKER, PATH_UNPROCESSED_CRITICAL_EXTENSION);
02385 }
02386
02387
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
02398 onHold = false;
02399 certStatus->SetDiagnosticCode(0);
02400 status = NOT_REVOKED;
02401 }
02402 else
02403 {
02404
02405 crlInfo->SetCRLEntry(deltaCRLEntry);
02406
02407 certStatus->SetDiagnosticCode(PATH_CERT_REVOKED);
02408
02409
02410 status = REVOKED;
02411 break;
02412 }
02413 }
02414 }
02415
02416
02417
02418
02419
02420
02421 }
02422
02423
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
02436
02437
02438
02439
02440
02441
02442
02443
02444
02445
02446
02447
02448
02449
02450
02451
02452
02453
02454
02455
02456
02457
02458
02459
02460
02461
02462
02463
02464
02465
02466
02467
02468
02469
02470
02471
02472
02473
02474
02475
02476
02477
02478
02479
02480
02481
02489 void KeyUsageCheckerCRL(
02491 const CPKIFCertificateNodeEntryPtr& certNode,
02493 CPKIFPathValidationResults& results,
02495 CertificateType type)
02496 {
02497 if(EE == type)
02498 {
02499
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
02512 CPKIFBasicConstraintsPtr bc = curCert->GetExtension<CPKIFBasicConstraints>();
02513 if(bc != (CPKIFBasicConstraints*)NULL)
02514 {
02515 CPKIFX509ExtensionPtr bc2 = bc;
02516 certNode->MarkExtensionAsProcessed(bc2);
02517 }
02518 }
02519
02520
02521 }
02522
02523
02524
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
02561 CPKIFTimePtr curTime = settings->GetValidationTime();
02562
02563
02564
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;
02572
02573 CPKIFTimePtr nextUpdate = crl->NextUpdate();
02574 if(requireFresh && nextUpdate != (CPKIFTime*)NULL && *curTime > *nextUpdate)
02575 return false;
02576
02577
02578 char hashResult[MAXHASH];
02579 int nResultLen = MAXHASH;
02580 PKIFCRYPTO::HASH_ALG hashAlg = PKIFCRYPTO::SHA1;
02581
02582
02583 CPKIFAlgorithmIdentifierPtr sigAlg = crl->SignatureAlgorithm();
02584 CPKIFOIDPtr aTmpOID = sigAlg->oid();
02585 if(!GetCACHashAlg(aTmpOID, &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
02592 if(!_GetHashOfToBeSignedCRL2(crl, cryptoMisc, hashAlg, (unsigned char*)hashResult, &nResultLen))
02593 return false;
02594
02595
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
02610
02611
02612 CPKIFKeyMaterial key;
02613 CPKIFSubjectPublicKeyInfoPtr spki = targetCertIssuersCertNK->GetSubjectPublicKeyInfo();
02614 key.SetSubjectPublicKeyInfo(spki);
02615
02616
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
02632 if(!_GetCRLIssuersCert(crl, targetCertIssuersCertNK, issuersCert, crlIssuerCerts, source, m_parent, authority, settings))
02633 {
02634
02635 if(REMOTE == source)
02636 {
02637 break;
02638 }
02639 else
02640 {
02641 source = REMOTE;
02642 continue;
02643 }
02644 }
02645
02646
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
02654 CPKIFAlgorithmIdentifierPtr certAlg = (*pos)->SubjectPublicKeyInfo()->alg();
02655 if(GetAlgClass(certAlg) != GetAlgClass(sigAlg))
02656 continue;
02657
02658
02659 CPKIFKeyUsagePtr ku = (*pos)->GetExtension<CPKIFKeyUsage>();
02660 if(ku != (CPKIFKeyUsage*)NULL && !ku->CRLSign())
02661 continue;
02662
02663
02664 CPKIFKeyMaterial key;
02665 CPKIFBufferPtr certBuf = (*pos)->Encoded();
02666 key.SetCertificate(certBuf->GetBuffer(), certBuf->GetLength());
02667
02668
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(
02687 *posNK == *targetCertIssuersCertNK
02688 && false == validatePathToDirectCRLs && false == reattemptWithWorkingParams)
02689 return true;
02690
02691
02692 if(*targetCert == *(*pos))
02693 return false;
02694
02695
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
02706 bool pB = pb->BuildPath(path);
02707 if(!pB)
02708 break;
02709
02710
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
02719 continue;
02720 }
02721
02722
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);
02763
02764
02765 return false;
02766 }
02767
02768
02769
02770
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,
02824 const CPKIFCertificatePtr& issuersCert,
02826 RevocationStatus& status,
02829 CPKIFCertStatusPtr& certStatus)
02830 {
02831 LOG_STRING_DEBUG("CPKIFX509CRLChecker::CheckStatus", TOOLKIT_PATH_MISC, 0, this);
02832
02833
02834
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,
02859 RevocationStatus& status)
02860 {
02861 LOG_STRING_DEBUG("CPKIFX509CRLChecker::CheckStatusPath", TOOLKIT_PATH_MISC, 0, this);
02862
02863
02864 status = NOT_CHECKED;
02865
02866
02867
02868
02869
02870
02871 CPKIFCertificateNodeList certNodeList;
02872 path.GetPath(certNodeList);
02873
02874
02875 IPKIFTrustAnchorPtr root;
02876 path.GetTrustRoot(root);
02877
02878
02879 bool statusSet = false;
02880 CPKIFCertificatePtr curCert, issuersCert;
02881 IPKIFNameAndKeyPtr issuersCertNK;
02882 CPKIFCertStatusPtr curCertStatus;
02883 RevocationStatus rStatus = NOT_CHECKED, pathStatus = NOT_CHECKED;
02884
02885
02886
02887
02888
02889
02890
02891
02892 issuersCertNK = dynamic_pointer_cast<IPKIFNameAndKey, IPKIFTrustAnchor>(root);
02893
02894
02895 CPKIFPathSettingsPtr settings;
02896 path.GetPathSettings(settings);
02897
02898
02899 CPKIFCertificateNodeList::iterator pos;
02900 CPKIFCertificateNodeList::iterator end = certNodeList.end();
02901 for(pos = certNodeList.begin(); pos != end; ++pos)
02902 {
02903
02904
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
02914 issuersCertNK = dynamic_pointer_cast<IPKIFNameAndKey,CPKIFCertificate>(curCert);
02915 continue;
02916 }
02917 rStatus = NOT_CHECKED;
02918
02919
02920 CPKIFX509ExtensionPtr ext;
02921 curCert->GetExtensionByOID(*g_ocspNoCheck, ext);
02922
02923
02924 if(ext != (CPKIFX509Extension*)NULL)
02925 {
02926 pathStatus = min(status, NOT_REVOKED);
02927 }
02928 else
02929 {
02930
02931
02932
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
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 }