00001
00010 #include "PKIFOCSPChecker.h"
00011
00012 #include "PKIFCRLInfo.h"
00013 #include "SingleResponse.h"
00014 #include "OID.h"
00015 #include "Buffer.h"
00016 #include "Certificate.h"
00017 #include "TBSRequest.h"
00018 #include "BasicOCSPResponse.h"
00019 #include "PKIFOCSPInfo.h"
00020 #include "CertID.h"
00021 #include "Request.h"
00022 #include "ResponderID.h"
00023 #include "ResponseData.h"
00024 #include "OCSPCertStatus.h"
00025 #include "GeneralName.h"
00026 #include "X509Extension.h"
00027 #include "AuthorityInfoAccess.h"
00028 #include "ResponseBytes.h"
00029 #include "OCSPResponse.h"
00030 #include "AlgorithmIdentifier.h"
00031 #include "IPKIFCryptoRaw.h"
00032 #include "SubjectKeyIdentifier.h"
00033
00034 #include "PKIFTime.h"
00035 #include "ToolkitUtils.h"
00036 #include "GottaMatch.h"
00037 #include "PKIFFuncStorage.h"
00038
00039 #include "PKIFKeyMaterial.h"
00040 #include "PKIFCertStatus.h"
00041 #include "PKIFCertificatePath.h"
00042 #include "PKIFPathSettings.h"
00043 #include "PathResults.h"
00044 #include "IPKIFPathBuild.h"
00045 #include "IPKIFPathValidate.h"
00046 #include "IPKIFCryptoMisc.h"
00047 #include "IPKIFHashContext.h"
00048 #include "IPKIFCryptoRawOperations.h"
00049 #include "RevocationSource.h"
00050
00051 #include "OCSPException.h"
00052 #include "PKIFOCSPErrors.h"
00053 #include "PKIFPATHErrors.h"
00054
00055 #include "SearchCriteria.h"
00056 #include "SubjectPublicKeyInfo.h"
00057 #include "AccessDescription.h"
00058 #include "ExtendedKeyUsage.h"
00059 #include "OCSPRequest.h"
00060 #include "ASN1Helper.h"
00061 #include "OCSP.h"
00062
00063 #include "IPKIFHashContext.h"
00064 #include "PKIFMediators.h"
00065 #include "IPKIFNameAndKey.h"
00066 #include "GeneralSubtree.h"
00067
00068
00069 #ifdef _DEBUG_URI_DUMP
00070 #include <fstream>
00071 extern ofstream g_uriLogFile;
00072 #endif
00073 using namespace std;
00074
00075 void keyUsageChecker_Any(const CPKIFCertificateNodeEntryPtr& certNode, CPKIFPathValidationResults& results, CertificateType type);
00076 void EKUChecker_OcspSigning(const CPKIFCertificateNodeEntryPtr& certNode, CPKIFPathValidationResults& results, CertificateType type);
00077
00078 CAC_API CPKIFOIDPtr g_adOCSP
00079 (new CPKIFOID(CPKIFStringPtr(new std::string("1.3.6.1.5.5.7.48.1"))));
00080 CAC_API CPKIFOIDPtr g_ocspBasic
00081 (new CPKIFOID(CPKIFStringPtr(new std::string("1.3.6.1.5.5.7.48.1.1"))));
00082 CAC_API CPKIFOIDPtr g_ocspNonce
00083 (new CPKIFOID(CPKIFStringPtr(new std::string("1.3.6.1.5.5.7.48.1.2"))));
00084 CAC_API CPKIFOIDPtr g_ocspNoCheck
00085 (new CPKIFOID(CPKIFStringPtr(new std::string("1.3.6.1.5.5.7.48.1.5"))));
00086
00087
00088
00089
00091 struct CPKIFOCSPCheckerImpl
00092 {
00093 CPKIFOCSPChecker* m_parent;
00101 CPKIFOCSPCheckerImpl ()
00102 {
00103 m_parent = NULL;
00104 m_bRequireThisCert = false;
00105 m_port = 80;
00106 m_bCacheResponders = false;
00107 }
00115 CPKIFOCSPCheckerImpl (CPKIFOCSPChecker *p)
00116 {
00117 m_parent = p;
00118 }
00119 bool m_bGenerateNonce;
00120 bool m_bRequireNonceMatch;
00121 bool m_bMultiCertRequest;
00122 CPKIFStringPtr m_url;
00123 CPKIFStringPtr m_host;
00124 int m_port;
00125 bool m_bLocalConfig;
00126 bool m_bRequireThisCert;
00127 CPKIFCertificatePtr m_responderCert;
00128
00129 CPKIFGeneralSubtreeList m_namespaces;
00130 CPKIFGeneralSubtreeList m_issuerNamespaces;
00131 bool CheckNamespaces(const CPKIFCertificatePtr& cert);
00132 bool CheckIssuerNamespaces(const CPKIFCertificatePtr& cert);
00133
00134 CPKIFPathSettingsPtr m_settings;
00135
00136 CPKIFCredentialPtr m_cred;
00137
00138 void AddValidatedResponderCert(CPKIFCertificatePtr& cert);
00139 bool HasCertBeenValidated(CPKIFCertificatePtr& cert);
00140 vector<CPKIFCertificatePtr> m_validatedResponderCerts;
00141 bool m_bCacheResponders;
00142
00143
00144
00145
00146
00147
00148
00149
00150 bool ProcessResponse(CPKIFBufferPtr& bp, CPKIFBasicOCSPResponsePtr& basicOCSPResponse, CPKIFCertificatePtr& signersCert,
00151 int* error, CPKIFOCSPResponsePtr& response);
00152
00153
00154
00155
00156
00157
00158 bool CheckOCSPStatus_Combo(const char* host, int port, const char* object, const CPKIFCertificatePath& path, const char* url = NULL);
00159 bool CheckOCSPStatus_Local(const char* host, int port, const char* object, CPKIFCertificate& cert,
00160 const IPKIFNameAndKey* issuersCert, CPKIFCertStatusPtr& certStatus, CPKIFPathSettingsPtr& ps, const char* url = NULL, const CPKIFCertificatePath* prevPath = NULL);
00161 bool CheckOCSPStatus_URL(const char* url, CPKIFCertificate& cert, const IPKIFNameAndKey* issuersCert, CPKIFCertStatusPtr& certStatus, CPKIFPathSettingsPtr& ps, const CPKIFCertificatePath* prevPath = NULL);
00162
00163
00164
00165
00166 bool CheckOCSPStatus(const char* host, int port, const char* object, CPKIFBufferPtr& ocspReq,
00167 CPKIFBasicOCSPResponsePtr& basicOCSPResponse, CPKIFCertificatePtr& signersCert,
00168 int* error, CPKIFOCSPResponsePtr& response, CPKIFPathSettingsPtr& ps, const char* url = NULL);
00169
00170
00171 bool CheckCertStatus(CPKIFSingleResponseList& responses, const CPKIFCertificatePtr& ocspSignersCert,
00172 const IPKIFNameAndKey* issuersCert, const CPKIFCertificate& targetCert, RevocationStatus& revStatus,
00173 CPKIFOCSPInfoPtr& ocspInfo, int* error, CPKIFPathSettingsPtr& ps);
00174
00175
00176 CPKIFCertificatePtr CertChooser(CPKIFBasicOCSPResponse& basicOCSPResponse);
00177 bool VerifyBasicOCSPResponseSignature(CPKIFBasicOCSPResponse& basicOCSPResponse, CPKIFCertificatePtr& signersCert);
00178
00179
00180 bool CheckSignerAuth(const IPKIFNameAndKey* issuersCert, const CPKIFCertificate& signersCert);
00181 bool CheckTime(CPKIFSingleResponsePtr& sr, int* error, CPKIFPathSettingsPtr& ps);
00182 bool ValidatePath(CPKIFCertificatePtr& signersCert, int* error, const CPKIFCertificatePath* prevPath = NULL);
00183 };
00191 void CPKIFOCSPCheckerImpl::AddValidatedResponderCert(
00193 CPKIFCertificatePtr& cert)
00194 {
00195 if(!m_bCacheResponders)
00196 return;
00197
00198 if(!HasCertBeenValidated(cert))
00199 m_validatedResponderCerts.push_back(cert);
00200 }
00208 bool CPKIFOCSPCheckerImpl::HasCertBeenValidated(
00210 CPKIFCertificatePtr& cert)
00211 {
00212 if(!m_bCacheResponders)
00213 return false;
00214
00215 GottaMatch<CPKIFCertificatePtr> gm;
00216 gm.SetRHS(cert);
00217 if(m_validatedResponderCerts.end() == find_if(m_validatedResponderCerts.begin(), m_validatedResponderCerts.end(), gm))
00218 return false;
00219 else
00220 return true;
00221 }
00222
00231 bool CPKIFOCSPCheckerImpl::CheckNamespaces(const CPKIFCertificatePtr& cert)
00232 {
00233 if(cert == (CPKIFCertificate*)NULL)
00234 return false;
00235
00236 CPKIFNamePtr subjectName = cert->GetSubjectName();
00237 CPKIFGeneralSubtreeList::iterator pos;
00238 CPKIFGeneralSubtreeList::iterator end = m_namespaces.end();
00239 for(pos = m_namespaces.begin(); pos != end; ++pos)
00240 {
00241 if(CPKIFGeneralSubtree::MATCH == (*pos)->IsInSubtree(subjectName))
00242 return true;
00243 }
00244
00245
00246
00247
00248 return m_namespaces.empty();
00249 }
00250
00259 bool CPKIFOCSPCheckerImpl::CheckIssuerNamespaces(const CPKIFCertificatePtr& cert)
00260 {
00261 if(cert == (CPKIFCertificate*)NULL)
00262 return false;
00263
00264 CPKIFNamePtr issuerName = cert->GetIssuerName();
00265 CPKIFGeneralSubtreeList::iterator pos;
00266 CPKIFGeneralSubtreeList::iterator end = m_issuerNamespaces.end();
00267 for(pos = m_issuerNamespaces.begin(); pos != end; ++pos)
00268 {
00269 if(CPKIFGeneralSubtree::MATCH == (*pos)->IsInSubtree(issuerName))
00270 return true;
00271 }
00272
00273
00274
00275
00276 return m_issuerNamespaces.empty();
00277 }
00278
00280
00287 void CPKIFOCSPChecker::SetCacheValidatedResponders(
00289 bool b)
00290 {
00291 m_impl->m_bCacheResponders = b;
00292 }
00300 bool CPKIFOCSPChecker::GetCacheValidatedResponders()
00301 {
00302 return m_impl->m_bCacheResponders;
00303 }
00304
00305
00313 CAC_API CPKIFOCSPChecker* MakeOCSPChecker()
00314 {
00315 return new CPKIFOCSPChecker();
00316 }
00324 CAC_API void FreeOCSPChecker(
00326 CPKIFOCSPChecker* s)
00327 {
00328 if(s)
00329 {
00330 delete s;
00331 }
00332 }
00333
00334
00335
00336
00337
00338
00339
00340
00352 CPKIFBufferPtr _HashIssuerName(
00354 const CPKIFCertificate& cert,
00356 IPKIFColleague* m)
00357 {
00358 LOG_STRING_DEBUG("_HashIssuerName", TOOLKIT_OCSP_CHECKER, 0, NULL);
00359
00360
00361 IPKIFCryptoMisc* cMisc = m->GetMediatorFromParent<IPKIFCryptoMisc>();
00362 if(NULL == cMisc)
00363 throw CPKIFException(TOOLKIT_OCSP_CHECKER,COMMON_MEDIATOR_MISSING,"IPKIFCryptoMisc interface was not available.");
00364
00365
00366 CPKIFNamePtr issuerName = cert.Issuer();
00367 if(issuerName == (CPKIFName*)NULL)
00368 throw CPKIFException(TOOLKIT_OCSP_CHECKER,COMMON_INVALID_INPUT,"Invalid cert passed to issuer name hashing function");
00369
00370
00371 CPKIFBufferPtr tmp = issuerName->Encoded();
00372
00373
00374 IPKIFHashContext* hi = cMisc->HashInit(PKIFCRYPTO::SHA1);
00375 if(NULL == hi)
00376 throw CPKIFException(TOOLKIT_OCSP_CHECKER,COMMON_UNSUPPORTED_ALG,"");
00377
00378
00379 int hashResultLen = MAXHASH;
00380 unsigned char* hashResult = NULL;
00381
00382 try
00383 {
00384 hashResult = new unsigned char[MAXHASH];
00385 }
00386 catch(std::bad_alloc& ba)
00387 {
00388 delete hi;
00389 throw ba;
00390 }
00391
00392 try
00393 {
00394 cMisc->HashUpdate(hi, (unsigned char*)tmp->GetBuffer(), tmp->GetLength());
00395 cMisc->HashFinal(hi, hashResult, &hashResultLen);
00396 }
00397 catch(CPKIFException& e)
00398 {
00399 delete hi;
00400 delete[] hashResult;
00401 throw e;
00402 }
00403 delete hi;
00404
00405 CPKIFBufferPtr issuerNameHash(new CPKIFBuffer(true, hashResult, hashResultLen));
00406 return issuerNameHash;
00407 }
00420 CPKIFBufferPtr _HashPublicKey(
00422 const IPKIFNameAndKey& cert,
00424 IPKIFColleague* m)
00425 {
00426 LOG_STRING_DEBUG("_HashPublicKey", TOOLKIT_OCSP_CHECKER, 0, NULL);
00427
00428
00429 IPKIFCryptoMisc* cMisc = m->GetMediatorFromParent<IPKIFCryptoMisc>();
00430 if(NULL == cMisc)
00431 throw CPKIFException(TOOLKIT_OCSP_CHECKER,COMMON_MEDIATOR_MISSING,"IPKIFCryptoMisc interface was not available.");
00432
00433
00434 CPKIFBufferPtr key = cert.GetKey();
00435 if(key == (CPKIFBuffer*)NULL)
00436 throw CPKIFException(TOOLKIT_OCSP_CHECKER,COMMON_INVALID_INPUT,"Invalid cert passed to issuer name hashing function");
00437
00438
00439 IPKIFHashContext* hi = cMisc->HashInit(PKIFCRYPTO::SHA1);
00440 if(NULL == hi)
00441 throw CPKIFException(TOOLKIT_OCSP_CHECKER,COMMON_UNSUPPORTED_ALG,"");
00442
00443
00444 int hashResultLen = MAXHASH;
00445 unsigned char* hashResult = NULL;
00446
00447 try
00448 {
00449 hashResult = new unsigned char[MAXHASH];
00450 }
00451 catch(std::bad_alloc& ba)
00452 {
00453 delete hi;
00454 throw ba;
00455 }
00456
00457 try
00458 {
00459
00460 cMisc->HashUpdate(hi, (unsigned char*)key->GetBuffer(), key->GetLength());
00461 cMisc->HashFinal(hi, hashResult, &hashResultLen);
00462 }
00463 catch(CPKIFException& e)
00464 {
00465 delete hi;
00466 delete[] hashResult;
00467 throw e;
00468 }
00469 delete hi;
00470
00471 CPKIFBufferPtr issuerKeyHash(new CPKIFBuffer(true, hashResult, hashResultLen));
00472 return issuerKeyHash;
00473 }
00481 CPKIFBufferPtr _CreateSimpleOCSPRequest(
00482
00483 const CPKIFCertificate& cert,
00484
00485 const IPKIFNameAndKey* issuersCert,
00487 IPKIFColleague* m,
00489 CPKIFBufferPtr& nonce,
00491 bool generateNonce,
00492
00493 CPKIFCredentialPtr& cred)
00494 {
00495 LOG_STRING_DEBUG("_CreateSimpleOCSPRequest", TOOLKIT_OCSP_CHECKER, 0, NULL);
00496
00497
00498 CPKIFBufferPtr issuerNameHash = _HashIssuerName(cert, m);
00499
00500
00501 CPKIFBufferPtr issuerKeyHash = _HashPublicKey(*issuersCert, m);
00502
00503
00504 CPKIFStringPtr targetSerialNumber(new std::string(cert.SerialNumber()));
00505
00506
00507 CPKIFCertIDPtr certID(new CPKIFCertID);
00508 certID->SetHashAlg(g_sha1AI);
00509 certID->SetIssuerNameHash(issuerNameHash);
00510 certID->SetIssuerKeyHash(issuerKeyHash);
00511 certID->SetSerialNumber(targetSerialNumber);
00512
00513
00514 CPKIFRequestPtr req(new CPKIFRequest);
00515 req->SetCertID(certID);
00516
00517
00518 CPKIFTBSRequestPtr tbsReq(new CPKIFTBSRequest);
00519 tbsReq->AddRequest(req);
00520
00521 if(generateNonce)
00522 nonce = tbsReq->GetNonce();
00523 else
00524 tbsReq->SetGenerateNonce(false);
00525
00526
00527 CPKIFOCSPRequest ocspReq;
00528 ocspReq.SetRequest(tbsReq, cred, m->GetMediatorFromParent<IPKIFMediator>());
00529
00530 return ocspReq.Encode();
00531 }
00539 CPKIFBufferPtr _CreateComplexOCSPRequest(
00541 const CPKIFCertificatePath& path,
00543 IPKIFColleague* m,
00545 CPKIFBufferPtr& nonce,
00547 bool generateNonce,
00548
00549 CPKIFCredentialPtr& cred)
00550 {
00551 LOG_STRING_DEBUG("_CreateComplexOCSPRequest", TOOLKIT_OCSP_CHECKER, 0, NULL);
00552
00553
00554 CPKIFCertificateNodeList certPath;
00555 path.GetPath(certPath);
00556
00557
00558 IPKIFTrustAnchorPtr tr;
00559 path.GetTrustRoot(tr);
00560 IPKIFNameAndKeyPtr issuersCert = tr;
00561
00562
00563 CPKIFTBSRequestPtr tbsReq(new CPKIFTBSRequest);
00564 if(generateNonce)
00565 nonce = tbsReq->GetNonce();
00566 else
00567 tbsReq->SetGenerateNonce(false);
00568
00569
00570 CPKIFCertificateNodeList::iterator pathPos;
00571 CPKIFCertificateNodeList::iterator pathEnd = certPath.end();
00572 for(pathPos = certPath.begin(); pathPos != pathEnd; ++pathPos)
00573 {
00574 CPKIFCertificatePtr cert = (*pathPos)->GetCert();
00575 CPKIFCertStatusPtr cs = (*pathPos)->GetStatus();
00576 RevocationStatus rs = cs->GetRevocationStatus();
00577 if(NOT_CHECKED == rs)
00578 {
00579
00580 CPKIFBufferPtr issuerNameHash = _HashIssuerName(*cert, m);
00581
00582
00583 CPKIFBufferPtr issuerKeyHash = _HashPublicKey(*issuersCert, m);
00584
00585
00586 CPKIFStringPtr targetSerialNumber(new std::string(cert->SerialNumber()));
00587
00588
00589 CPKIFCertIDPtr certID(new CPKIFCertID);
00590 certID->SetHashAlg(g_sha1AI);
00591 certID->SetIssuerNameHash(issuerNameHash);
00592 certID->SetIssuerKeyHash(issuerKeyHash);
00593 certID->SetSerialNumber(targetSerialNumber);
00594
00595
00596 CPKIFRequestPtr req(new CPKIFRequest);
00597 req->SetCertID(certID);
00598
00599
00600 tbsReq->AddRequest(req);
00601 }
00602
00603
00604 issuersCert = cert;
00605 }
00606
00607
00608 CPKIFOCSPRequest ocspReq;
00609 ocspReq.SetRequest(tbsReq, cred, m->GetMediatorFromParent<IPKIFMediator>());
00610
00611 return ocspReq.Encode();
00612 }
00620 bool _CertIDMatchesCert(
00622 CPKIFCertIDPtr& cid,
00624 const CPKIFCertificate& cert,
00626 IPKIFColleague* m)
00627 {
00628 LOG_STRING_DEBUG("_CertIDMatchesCert", TOOLKIT_OCSP_CHECKER, 0, NULL);
00629
00630
00631 const char* cidSN = cid->GetSerialNumber();
00632 const char* certSN = cert.SerialNumber();
00633
00634
00635
00636 if(NULL == cidSN || NULL == certSN || strlen(cidSN) != strlen(certSN) ||
00637 0 != stricmp(cidSN, certSN))
00638 return false;
00639
00640
00641 CPKIFBufferPtr certHashBuf = _HashIssuerName(cert, m);
00642 CPKIFBufferPtr cidHashBuf = cid->GetIssuerNameHash();
00643
00644
00645 if(!(*certHashBuf == *cidHashBuf))
00646 return false;
00647
00648
00649 return true;
00650 }
00658 bool _MatchSignersCertAndResponderID(
00660 CPKIFBasicOCSPResponse& basicOCSPResponse,
00662 CPKIFCertificatePtr& signersCert,
00664 IPKIFColleague* m)
00665 {
00666 LOG_STRING_DEBUG("_MatchSignersCertAndResponderID", TOOLKIT_OCSP_CHECKER, 0, NULL);
00667
00668 CPKIFResponseDataPtr rdp = basicOCSPResponse.GetResponseData();
00669 CPKIFResponderIDPtr ridp = rdp->GetResponderID();
00670
00671 switch(ridp->GetChoice())
00672 {
00673 case CPKIFResponderID::NAME:
00674 {
00675 CPKIFNamePtr name = ridp->GetName();
00676 return *name == *signersCert->Subject();
00677 }
00678 break;
00679 case CPKIFResponderID::KEYHASH:
00680 {
00681 CPKIFBufferPtr hashFromResponse = ridp->GetHash();
00682 CPKIFBufferPtr hashOfPublicKey = _HashPublicKey(*signersCert, m);
00683 return *hashFromResponse == *hashOfPublicKey;
00684 }
00685 break;
00686 default:
00687 return false;
00688 }
00689 }
00690
00691
00692
00693
00694
00695
00703 CPKIFCertificatePtr CPKIFOCSPCheckerImpl::CertChooser(
00705 CPKIFBasicOCSPResponse& basicOCSPResponse)
00706 {
00707 LOG_STRING_DEBUG("CPKIFOCSPChecker::CertChooser", TOOLKIT_OCSP_CHECKER, 0, this);
00708
00709 CPKIFCertificatePtr noCert;
00710
00711 CPKIFResponseDataPtr rd = basicOCSPResponse.GetResponseData();
00712 CPKIFResponderIDPtr rid = rd->GetResponderID();
00713 CPKIFResponderID::ResponderIDType ridType = rid->GetChoice();
00714
00715
00716
00717 CPKIFCertificateList certs;
00718 basicOCSPResponse.GetCerts(certs);
00719 if(!certs.empty())
00720 {
00721 CPKIFNamePtr name;
00722 CPKIFBufferPtr hashFromResponse;
00723 if(CPKIFResponderID::NAME == ridType)
00724 name = rid->GetName();
00725 else if(CPKIFResponderID::KEYHASH == ridType)
00726 {
00727 hashFromResponse = rid->GetHash();
00728 }
00729
00730 CPKIFCertificateList::iterator pos;
00731 CPKIFCertificateList::iterator end = certs.end();
00732 for(pos = certs.begin(); pos != end; ++pos)
00733 {
00734 if(CPKIFResponderID::NAME == ridType && name != (CPKIFName*)NULL)
00735 {
00736 if(*name == *(*pos)->Subject())
00737 return *pos;
00738 }
00739 else if(CPKIFResponderID::KEYHASH == ridType && hashFromResponse != (CPKIFBuffer*)NULL)
00740 {
00741 CPKIFBufferPtr hashOfPublicKey = _HashPublicKey(*(*pos), m_parent);
00742 if( *hashFromResponse == *hashOfPublicKey)
00743 return *pos;
00744 }
00745 else
00746 {
00747
00748 return certs.front();
00749 }
00750 }
00751 }
00752 else
00753 {
00754 if(CPKIFResponderID::NAME == ridType)
00755 {
00756
00757 IPKIFTrustCache* trustCache = m_parent->GetMediatorFromParent<IPKIFTrustCache>();
00758 if(NULL != trustCache)
00759 {
00760 CPKIFNamePtr name = rid->GetName();
00761
00762 IPKIFTrustAnchorList TAs;
00763 trustCache->GetTrustRoots(name, TAs);
00764
00765 IPKIFTrustAnchorList::iterator taPos;
00766 IPKIFTrustAnchorList::iterator taEnd = TAs.end();
00767 for(taPos = TAs.begin(); taPos != taEnd; ++taPos)
00768 {
00769 CPKIFCertificatePtr taCert = (*taPos)->GetCertificate();
00770 if(taCert)
00771 return taCert;
00772 }
00773 }
00774
00775
00776
00777 IPKIFCertSearch* certSearch = m_parent->GetMediatorFromParent<IPKIFCertSearch>();
00778 if(NULL != certSearch)
00779 {
00780 CPKIFNamePtr name = rid->GetName();
00781
00782 #ifdef _DEBUG
00783 const char* nameString = name->ToString();
00784 #endif
00785
00786 CPKIFNameBasedSearch nbs;
00787 nbs.SetName(name);
00788 certSearch->FindCertificates(&nbs, certs, ALL);
00789
00790 if(!certs.empty())
00791 return certs.front();
00792 }
00793 }
00794 else if(CPKIFResponderID::KEYHASH == ridType)
00795 {
00796 try
00797 {
00798 CPKIFBufferPtr keyHash = rid->GetHash();
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828 IPKIFCertSearch* certSearch = m_parent->GetMediatorFromParent<IPKIFCertSearch>();
00829 if(keyHash && NULL != certSearch)
00830 {
00831 #ifdef _DEBUG
00832 const unsigned char* nameString = keyHash->GetBuffer();
00833 #endif
00834
00835 CPKIFKeyIDBasedSearch kibs;
00836 kibs.SetKeyID(keyHash);
00837 certSearch->FindCertificates(&kibs, certs, ALL);
00838
00839 if(!certs.empty())
00840 return certs.front();
00841 }
00842 }
00843 catch(...)
00844 {
00845
00846 }
00847 }
00848 }
00849
00850 return noCert;
00851 }
00864 bool CPKIFOCSPCheckerImpl::VerifyBasicOCSPResponseSignature(
00866 CPKIFBasicOCSPResponse& basicOCSPResponse,
00868 CPKIFCertificatePtr& signersCert)
00869 {
00870 LOG_STRING_DEBUG("CPKIFOCSPChecker::VerifyBasicOCSPResponseSignature", TOOLKIT_OCSP_CHECKER, 0, this);
00871
00872
00873 CPKIFResponseDataPtr responseData = basicOCSPResponse.GetResponseData();
00874 if(responseData == (CPKIFResponseData*)NULL)
00875 throw CPKIFException(m_parent->thisComponent,COMMON_INVALID_INPUT,"NULL response passed to response verification function");
00876
00877
00878 CPKIFAlgorithmIdentifierPtr sigAlg = basicOCSPResponse.GetSignatureAlg();
00879 if(sigAlg == (CPKIFAlgorithmIdentifier*)NULL)
00880 throw CPKIFException(m_parent->thisComponent,COMMON_INVALID_INPUT,"Response containing no signature algorithm passed to response verification function");
00881
00882
00883 CPKIFBufferPtr sig = basicOCSPResponse.GetSignature();
00884 if(sig == (CPKIFBuffer*)NULL)
00885 throw CPKIFException(m_parent->thisComponent,COMMON_INVALID_INPUT,"Response containing no signature passed to response verification function");
00886
00887
00888 IPKIFCryptoMisc* cMisc = m_parent->GetMediatorFromParent<IPKIFCryptoMisc>();
00889 IPKIFCryptoRawOperations* crypto = m_parent->GetMediatorFromParent<IPKIFCryptoRawOperations>();
00890 if(NULL == cMisc || NULL == crypto)
00891 throw CPKIFException(m_parent->thisComponent,COMMON_MEDIATOR_MISSING,"One or both of the IPKIFCryptoRawOperations or IPKIFCryptoMisc interfaces was not available.");
00892
00893
00894 PKIFCRYPTO::HASH_ALG ha;
00895 CPKIFOIDPtr anOID = sigAlg->oid();
00896 GetCACHashAlg(anOID, &ha);
00897
00898
00899 unsigned char hashResult[MAXHASH];
00900 int hashResultLen = MAXHASH;
00901 IPKIFHashContext* h = cMisc->HashInit(ha);
00902 if(NULL == h)
00903 throw CPKIFException(m_parent->thisComponent,COMMON_UNSUPPORTED_ALG,"Response signed using unsupported hashing algorithm.");
00904
00905
00906 CPKIFBufferPtr eRDP = responseData->toBeSigned();
00907
00908 try
00909 {
00910
00911 cMisc->HashUpdate(h, (unsigned char*)eRDP->GetBuffer(), eRDP->GetLength());
00912
00913
00914 cMisc->HashFinal(h, hashResult, &hashResultLen);
00915 }
00916 catch(CPKIFException& e)
00917 {
00918 delete h;
00919 throw e;
00920 }
00921 delete h; h = NULL;
00922
00923
00924 CPKIFCertificatePtr cert = CertChooser(basicOCSPResponse);
00925 if(cert == (CPKIFCertificate*)NULL)
00926 return false;
00927
00928
00929 CPKIFKeyMaterial key;
00930 key.SetCertificate(cert->Encoded()->GetBuffer(), cert->Encoded()->GetLength());
00931
00932
00933 if(!crypto->Verify(key, hashResult, ha, (unsigned char*)sig->GetBuffer(), sig->GetLength(), ha))
00934 return false;
00935
00936
00937 signersCert = cert;
00938
00939 return true;
00940 }
00941
00942 bool VerifyCertificateWithCryptoPP(CPKIFSubjectPublicKeyInfoPtr& spki, const CPKIFCertificate& subCert);
00943
00960 bool CPKIFOCSPCheckerImpl::CheckSignerAuth(
00962 const IPKIFNameAndKey* issuersCert,
00964 const CPKIFCertificate& signersCert)
00965 {
00966 LOG_STRING_DEBUG("CPKIFOCSPChecker::CheckSignerAuth", TOOLKIT_OCSP_CHECKER, 0, this);
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977 if(m_bLocalConfig)
00978 {
00979 if(m_responderCert == (CPKIFCertificate*)NULL)
00980 return true;
00981 else
00982 {
00983 if(m_bRequireThisCert)
00984 {
00985 if(signersCert == *m_responderCert)
00986 return true;
00987 else
00988 return false;
00989 }
00990 else
00991 {
00992 if(signersCert.SameDNSameKey(*m_responderCert))
00993 return true;
00994 else
00995 return false;
00996 }
00997 }
00998 }
00999
01000
01001 if(issuersCert->SameDNSameKey(signersCert))
01002 return true;
01003
01004 IPKIFCryptoRawOperations* cRaw = m_parent->GetMediatorFromParent<IPKIFCryptoRawOperations>();
01005 if(NULL == cRaw)
01006 throw CPKIFOCSPException(m_parent->thisComponent, COMMON_MEDIATOR_MISSING, "IPKIFCryptoRawOperations interface was not available");
01007
01008
01009 CPKIFExtendedKeyUsagePtr eku = const_cast<CPKIFCertificate*>(&signersCert)->GetExtension<CPKIFExtendedKeyUsage>();
01010 if(eku != (CPKIFExtendedKeyUsage*) NULL)
01011 {
01012 bool ocspEKUPresent = false;
01013
01014 vector<CPKIFOIDPtr> keyPurposeIDs;
01015 eku->KeyPurposeIDs(keyPurposeIDs);
01016
01017
01018 GottaMatch<CPKIFOIDPtr> gm;
01019 gm.SetRHS(g_ocspSigningEKU);
01020
01021 vector<CPKIFOIDPtr>::iterator end = keyPurposeIDs.end();
01022 if(end != find_if(keyPurposeIDs.begin(), keyPurposeIDs.end(), gm))
01023 {
01024 ocspEKUPresent = true;
01025
01026 }
01027
01028 IPKIFCryptoRaw* crypto = m_parent->GetMediatorFromParent<IPKIFCryptoRaw>();
01029 bool sigVerified = false;
01030 bool namesMatch = false;
01031 try
01032 {
01033 CPKIFSubjectPublicKeyInfoPtr spki = issuersCert->GetSubjectPublicKeyInfo();
01034 sigVerified = VerifyCertificateWithCryptoPP(spki, signersCert);
01035
01036
01037
01038 if(*issuersCert->GetSubjectName() == *signersCert.Issuer())
01039 namesMatch = true;
01040 }
01041 catch(...)
01042 {
01043 return false;
01044 }
01045
01046 if(ocspEKUPresent && sigVerified && namesMatch)
01047 return true;
01048 }
01049
01050 return false;
01051 }
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01072 bool CPKIFOCSPCheckerImpl::CheckTime(
01074 CPKIFSingleResponsePtr& sr,
01076 int* error,
01078 CPKIFPathSettingsPtr& ps)
01079 {
01080 LOG_STRING_DEBUG("CPKIFOCSPChecker::CheckTime", TOOLKIT_OCSP_CHECKER, 0, this);
01081
01082
01083
01084 CPKIFTimePtr curTime = ps->GetValidationTime();
01085 CPKIFDurationPtr duration = ps->GetDuration();
01086 bool requireRecent = ps->GetRequireSufficientlyRecent();
01087 CPKIFTimePtr sufficientlyRecent(new CPKIFTime(*curTime - *duration));
01088 CPKIFTimePtr thisUpdate = sr->GetThisUpdate();
01089 if(requireRecent && *thisUpdate < *sufficientlyRecent)
01090 {
01091 *error = OCSP_STATUS_NOT_SUFFICIENTLY_RECENT;
01092 return false;
01093 }
01094
01095
01096
01097
01098 CPKIFTimePtr nextUpdate = sr->GetNextUpdate();
01099 bool requireFresh = ps->GetRequireFreshRevocationData();
01100 if(nextUpdate != (CPKIFTime*)NULL)
01101 {
01102 if(requireFresh && *curTime > *nextUpdate)
01103 {
01104 *error = OCSP_NEXT_UPDATE_PASSED;
01105 return false;
01106 }
01107 }
01108
01109 return true;
01110 }
01121 bool CPKIFOCSPCheckerImpl::CheckCertStatus(
01123 CPKIFSingleResponseList& responses,
01125 const CPKIFCertificatePtr& ocspSignersCert,
01127 const IPKIFNameAndKey* issuersCert,
01129 const CPKIFCertificate& targetCert,
01131 RevocationStatus& revStatus,
01133 CPKIFOCSPInfoPtr& ocspInfo,
01135 int* error,
01137 CPKIFPathSettingsPtr& ps)
01138 {
01139 LOG_STRING_DEBUG("CPKIFOCSPChecker::CheckCertStatus", TOOLKIT_OCSP_CHECKER, 0, this);
01140
01141 revStatus = NOT_CHECKED;
01142
01143 *error = 0;
01144
01145
01146
01147
01148 CPKIFSingleResponseList::iterator pos;
01149 CPKIFSingleResponseList::iterator end = responses.end();
01150 CPKIFSingleResponsePtr targetResponse;
01151 for(pos = responses.begin(); pos != end; ++pos)
01152 {
01153
01154
01155
01156 CPKIFCertIDPtr cid = (*pos)->GetCertID();
01157 if(_CertIDMatchesCert(cid, targetCert, m_parent))
01158 {
01159 targetResponse = *pos;
01160 break;
01161 }
01162 }
01163
01164 if(targetResponse == (CPKIFSingleResponse*)NULL)
01165 {
01166 *error = OCSP_TARGET_RESPONSE_NOT_INCLUDED;
01167 return false;
01168 }
01169
01170
01171
01172 ocspInfo->SetSingleResponse(targetResponse);
01173
01174
01175 if(*ocspSignersCert == targetCert)
01176 {
01177 *error = OCSP_RESPONDER_IS_TARGET;
01178 return false;
01179 }
01180
01181
01182 if(!CheckSignerAuth(issuersCert, *ocspSignersCert))
01183 {
01184 ocspInfo->SetSingleResponse(targetResponse);
01185 *error = OCSP_RESPONDER_NOT_AUTHORIZED;
01186 return false;
01187 }
01188
01189 std::vector<CPKIFX509ExtensionPtr> processedExts;
01190 if(targetResponse->AreThereAnyUnprocessedCriticalExtensions(processedExts))
01191 {
01192 *error = OCSP_UNPROCESSED_CRITICAL_EXTENSION;
01193 return false;
01194 }
01195
01196
01197 if(!CheckTime(targetResponse, error, ps))
01198 {
01199 return false;
01200 }
01201
01202 bool bDefinitiveAnswer = false;
01203
01204
01205
01206 CPKIFOCSPCertStatusPtr cs = targetResponse->GetCertStatus();
01207 CPKIFOCSPCertStatus::CertStatusChoice choice = cs->GetChoice();
01208
01209 switch(choice)
01210 {
01211 case CPKIFOCSPCertStatus::GOOD:
01212 bDefinitiveAnswer = true;
01213 revStatus = NOT_REVOKED;
01214 break;
01215 case CPKIFOCSPCertStatus::REVOKED:
01216 {
01217 bDefinitiveAnswer = true;
01218 revStatus = REVOKED;
01219 }
01220 break;
01221 case CPKIFOCSPCertStatus::UNKNOWN:
01222 case CPKIFOCSPCertStatus::UNSET:
01223 revStatus = NOT_CHECKED;
01224 *error = OCSP_UNKNOWN_CERT_STATUS;
01225 break;
01226 }
01227
01228 return bDefinitiveAnswer;
01229 }
01237 void CPKIFOCSPChecker::SetPathSettings(
01239 CPKIFPathSettingsPtr& settings)
01240 {
01241 m_impl->m_settings = settings;
01242 }
01243
01244
01252 void CPKIFOCSPChecker::SetGenerateNonce(
01254 bool bGenerateNonce)
01255 {
01256 m_impl->m_bGenerateNonce = bGenerateNonce;
01257 }
01265 bool CPKIFOCSPChecker::GetGenerateNonce()
01266 {
01267 return m_impl->m_bGenerateNonce;
01268 }
01276 void CPKIFOCSPChecker::SetRequireNonceMatch(
01278 bool bRequireNonceMatch)
01279 {
01280 m_impl->m_bRequireNonceMatch = bRequireNonceMatch;
01281 }
01289 bool CPKIFOCSPChecker::GetRequireNonceMatch()
01290 {
01291 return m_impl->m_bRequireNonceMatch;
01292 }
01293
01303 bool CPKIFOCSPCheckerImpl::ValidatePath(
01305 CPKIFCertificatePtr& signersCert,
01307 int* error,
01309 const CPKIFCertificatePath* prevPath)
01310 {
01311 try
01312 {
01313 LOG_STRING_DEBUG("CPKIFOCSPChecker::ValidatePath", TOOLKIT_OCSP_CHECKER, 0, this);
01314
01315 if(HasCertBeenValidated(signersCert))
01316 {
01317 *error = 0;
01318 return true;
01319 }
01320
01321
01322 IPKIFPathValidate* pv = m_parent->GetMediatorFromParent<IPKIFPathValidate>();
01323 IPKIFPathBuild* pb = m_parent->GetMediatorFromParent<IPKIFPathBuild>();
01324 if(NULL == pv || NULL == pb)
01325 throw CPKIFException(m_parent->thisComponent,COMMON_MEDIATOR_MISSING,"One or both of the IPKIFPathValidate or IPKIFPathBuild interfaces was not available.");
01326
01327
01328 CPKIFCertificatePath path;
01329 path.SetTarget(signersCert);
01330
01331
01332 if(m_settings != (CPKIFPathSettings*)NULL)
01333 {
01334 CPKIFPathSettingsPtr copy(new CPKIFPathSettings(*m_settings));
01335 path.SetPathSettings(copy);
01336 }
01337 else
01338 {
01339
01340 CPKIFPathSettingsPtr settings(new CPKIFPathSettings);
01341 path.SetPathSettings(m_settings);
01342 }
01343
01344
01345
01346 RevocationStatus minAcceptable = NOT_REVOKED;
01347 CPKIFX509ExtensionPtr ext;
01348 signersCert->GetExtensionByOID(*g_ocspNoCheck, ext);
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358 do
01359 {
01360
01361
01362 if(!pb->BuildPath(path))
01363 {
01364 *error = OCSP_PATH_BUILDING_FAILED;
01365
01366 break;
01367 }
01368
01369
01370
01371 if(NULL != prevPath)
01372 {
01373 CPKIFCertificatePtr prevTarget;
01374 prevPath->GetTarget(prevTarget);
01375
01376 if(prevTarget != (CPKIFCertificate*)NULL)
01377 {
01378 CPKIFCertificateNodeList curPathNodeList;
01379 path.GetPath(curPathNodeList);
01380
01381 CPKIFCertificateNodeList::iterator nodePos;
01382 CPKIFCertificateNodeList::iterator nodeEnd = curPathNodeList.end();
01383 for(nodePos = curPathNodeList.begin(); nodePos != nodeEnd; ++nodePos)
01384 {
01385 CPKIFCertificatePtr tmpCurCert = (*nodePos)->GetCert();
01386 if(!(tmpCurCert == (CPKIFCertificate*)NULL) && *prevTarget == *tmpCurCert)
01387 {
01388 *error = OCSP_RESPONDER_NOT_AUTHORIZED;
01389
01390 continue;
01391 }
01392 }
01393 }
01394 }
01395
01396
01397 CPKIFPathValidationResults results;
01398
01399
01400 CPKIFFuncStoragePtr keyUsageAny(new CPKIFFuncStorage(keyUsageChecker_Any));
01401 keyUsageAny->addFunc(EKUChecker_OcspSigning);
01402 pv->ValidatePath(path, results, keyUsageAny);
01403
01404
01405 if((!results.GetBasicChecksSuccessfullyPerformed() ||
01406 !results.GetCertSignaturesVerified()) && !results.GetTargetIsTrustAnchor())
01407 {
01408 *error = OCSP_PATH_VALIDATION_FAILED;
01409
01410 continue;
01411 }
01412
01413 if(!ext)
01414 {
01415
01416 RevocationStatus rStatus = results.GetRevocationStatusMostSevere();
01417 if(rStatus >= minAcceptable)
01418 {
01419 AddValidatedResponderCert(signersCert);
01420 return true;
01421 }
01422 else
01423 {
01424 *error = OCSP_PATH_VALIDATION_FAILED;
01425
01426 continue;
01427 }
01428 }
01429 else
01430 {
01431
01432 CPKIFCertificateNodeList nodes;
01433 path.GetPath(nodes);
01434
01435 CPKIFCertificateNodeList::iterator nodePos;
01436 CPKIFCertificateNodeList::iterator nodeEnd = nodes.end();
01437 for(nodePos = nodes.begin(); nodePos != nodeEnd; ++nodePos)
01438 {
01439 CPKIFCertStatusPtr certStatusFromNode = (*nodePos)->GetStatus();
01440
01441
01442 if(certStatusFromNode && (nodePos+1) != nodeEnd)
01443 {
01444 RevocationStatus rsFromNode = certStatusFromNode->GetRevocationStatus();
01445 if(NOT_REVOKED != rsFromNode)
01446 {
01447 *error = OCSP_PATH_VALIDATION_FAILED;
01448
01449 continue;
01450 }
01451 }
01452 }
01453
01454 if(0 == *error)
01455 {
01456 AddValidatedResponderCert(signersCert);
01457 return true;
01458 }
01459 }
01460 }while(1);
01461 }
01462 catch(CPKIFException& pe)
01463 {
01464 *error = pe.GetErrorCode();
01465 if(0 == *error)
01466 *error = COMMON_UNKNOWN_ERROR;
01467 return false;
01468 }
01469
01470 return false;
01471 }
01479 bool CPKIFOCSPCheckerImpl::ProcessResponse(
01481 CPKIFBufferPtr& bp,
01483 CPKIFBasicOCSPResponsePtr& basicOCSPResponse,
01485 CPKIFCertificatePtr& signersCert,
01487 int* error,
01489 CPKIFOCSPResponsePtr& response)
01490 {
01491 LOG_STRING_DEBUG("CPKIFOCSPChecker::ProcessResponse", TOOLKIT_OCSP_CHECKER, 0, this);
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510 CPKIFOCSPResponsePtr tmpOCSPResponse(new CPKIFOCSPResponse);
01511 tmpOCSPResponse->Decode(bp);
01512
01513
01514 response = tmpOCSPResponse;
01515
01516
01517 OCSPResponseStatus ocspResponseStatus = tmpOCSPResponse->GetResponseStatus();
01518 if(successful != ocspResponseStatus)
01519 {
01520 *error = OCSP_RECEIVED_NON_SUCCESSFUL_RESPONSE;
01521 return false;
01522 }
01523
01524
01525 CPKIFResponseBytesPtr responseBytes = tmpOCSPResponse->GetResponseBytes();
01526 if(responseBytes == (CPKIFResponseBytes*)NULL)
01527 {
01528 *error = OCSP_NO_RESPONSE_BODY;
01529 return false;
01530 }
01531
01532
01533 if(!(*g_ocspBasic == responseBytes->GetResponseType()))
01534 {
01535
01536 *error = OCSP_UNSUPPORTED_RESPONSE_TYPE;
01537 return false;
01538 }
01539
01540
01541 CPKIFBufferPtr responseBuf = responseBytes->GetResponse();
01542
01543
01544 CPKIFBasicOCSPResponsePtr tmpBasicOCSPResponse(new CPKIFBasicOCSPResponse);
01545 tmpBasicOCSPResponse->Decode(responseBuf);
01546
01547
01548
01549
01550 if(!VerifyBasicOCSPResponseSignature(*tmpBasicOCSPResponse, signersCert))
01551 {
01552 *error = OCSP_RESPONSE_SIG_VERIFICATION_FAILED;
01553 return false;
01554 }
01555
01556
01557
01558
01559
01560 if(!_MatchSignersCertAndResponderID(*tmpBasicOCSPResponse, signersCert, m_parent))
01561 {
01562 *error = OCSP_SIGNER_MISMATCH;
01563 return false;
01564 }
01565
01566 basicOCSPResponse = tmpBasicOCSPResponse;
01567 return true;
01568 }
01579 bool CPKIFOCSPCheckerImpl::CheckOCSPStatus(
01581 const char* host,
01583 int port,
01585 const char* object,
01587 CPKIFBufferPtr& ocspReq,
01589 CPKIFBasicOCSPResponsePtr& basicOCSPResponse,
01591 CPKIFCertificatePtr& signersCert,
01593 int* error,
01595 CPKIFOCSPResponsePtr& response,
01597 CPKIFPathSettingsPtr& ps,
01599 const char* url)
01600 {
01601 LOG_STRING_DEBUG("CPKIFOCSPChecker::CheckOCSPStatus", TOOLKIT_OCSP_CHECKER, 0, this);
01602
01603 CPKIFBufferPtr bp;
01604 if(NULL != host)
01605 PostRequest(ocspReq, bp, host, port, object, PKIF_OCSP);
01606 else
01607 {
01608 #ifdef _DEBUG_URI_DUMP
01609 if(!g_uriLogFile.is_open())
01610 {
01611 g_uriLogFile.open("_DEBUG_URI_DUMP_URILog.txt", ios::out);
01612 }
01613 DWORD __ticks = GetTickCount();
01614
01615 #ifdef _DEBUG_URI_DUMP
01616 g_uriLogFile << GetTickCount() - __ticks << " milliseconds elapsed retrieving from " << url << endl;
01617 #endif
01618 #endif
01619
01620 PostRequestURL(ocspReq, bp, url, PKIF_OCSP);
01621 }
01622
01623 if(NULL == host && (bp == (CPKIFBuffer*)NULL || 0 == bp->GetLength()))
01624 {
01625 throw CPKIFOCSPException(TOOLKIT_OCSP_ASN, COMMON_URL_OPERATION_FAILED);
01626 }
01627 return ProcessResponse(bp, basicOCSPResponse, signersCert, error, response);
01628 }
01642 bool CPKIFOCSPChecker::ProcessOfflineResponse(
01645 CPKIFCertificatePtr& targetCert,
01647 CPKIFCertificatePtr& targetCertIssuer,
01649 bool responderIsTrusted,
01652 CPKIFBufferPtr& ocspResponse,
01654 CPKIFCertStatusPtr& targetCertStatus)
01655 {
01656 LOG_STRING_DEBUG("CPKIFOCSPChecker::ProcessOfflineResponse", TOOLKIT_OCSP_CHECKER, 0, this);
01657
01658 bool bSomeNonDefinitive = false, bSomeDefinitive = false;
01659 bool bValPath = false;
01660 try
01661 {
01662 m_impl->m_bLocalConfig = responderIsTrusted;
01663
01664
01665 CPKIFBasicOCSPResponsePtr basicOCSPResponse;
01666 CPKIFCertificatePtr signersCert;
01667 int error = 0;
01668 CPKIFOCSPResponsePtr response;
01669 m_impl->ProcessResponse(ocspResponse, basicOCSPResponse, signersCert, &error, response);
01670
01671 CPKIFResponseDataPtr responseData = basicOCSPResponse->GetResponseData();
01672
01673 std::vector<CPKIFX509ExtensionPtr> processedExts;
01674
01675
01676 CPKIFX509ExtensionPtr ext;
01677 responseData->GetExtensionByOID(*g_ocspNonce, ext);
01678 if(ext != (CPKIFBuffer*)NULL)
01679 {
01680 processedExts.push_back(ext);
01681 }
01682
01683 if(responseData->AreThereAnyUnprocessedCriticalExtensions(processedExts))
01684 {
01685 error = OCSP_UNPROCESSED_CRITICAL_EXTENSION;
01686 return false;
01687 }
01688
01689
01690 CPKIFSingleResponseList responses;
01691 responseData->GetResponses(responses);
01692
01693
01694 if(targetCertStatus == (CPKIFCertStatus*)NULL)
01695 {
01696 CPKIFCertStatusPtr tmpCS(new CPKIFCertStatus);
01697 targetCertStatus = tmpCS;
01698 }
01699
01700
01701 RevocationStatus rs;
01702 CPKIFOCSPInfoPtr ocspInfo(new CPKIFOCSPInfo);
01703
01704 ocspInfo->SetOCSPResponse(response);
01705
01706
01707 IPKIFNameAndKey* targetCertIssuerNK = dynamic_cast<IPKIFNameAndKey*>(targetCertIssuer.get());
01708 if(!m_impl->CheckCertStatus(responses, signersCert, targetCertIssuerNK, *targetCert, rs, ocspInfo, &error, m_impl->m_settings))
01709 bSomeNonDefinitive = true;
01710 else
01711 bSomeDefinitive = true;
01712
01713
01714 targetCertStatus->AddRevocationSource(REVSOURCE_OCSP, REV_INFO_CAST(ocspInfo), rs, error);
01715
01716
01717 targetCertStatus->SetRevocationStatus(rs);
01718 if(REVOKED == rs)
01719 targetCertStatus->SetDiagnosticCode(PATH_CERT_REVOKED);
01720 else if (NOT_CHECKED == rs)
01721 targetCertStatus->SetDiagnosticCode(PATH_CERT_REVOCATION_STATUS_NOT_DETERMINED);
01722 else
01723 targetCertStatus->SetDiagnosticCode(0);
01724
01725 if(bSomeDefinitive)
01726 {
01727
01728
01729 bValPath = m_impl->ValidatePath(signersCert, &error);
01730 }
01731 }
01732 catch(CPKIFException&)
01733 {
01734 }
01735
01736
01737 return !bSomeNonDefinitive && bValPath;
01738 }
01747 bool CPKIFOCSPCheckerImpl::CheckOCSPStatus_Combo(
01749 const char* host,
01751 int port,
01753 const char* object,
01755 const CPKIFCertificatePath& path,
01757 const char* url )
01758 {
01759 LOG_STRING_DEBUG("CPKIFOCSPChecker::CheckOCSPStatus_Combo", TOOLKIT_OCSP_CHECKER, 0, this);
01760
01761 bool bSomeNonDefinitive = false, bSomeDefinitive = false;
01762 bool bValPath = false;
01763 try
01764 {
01765
01766
01767 CPKIFBufferPtr nonce;
01768 CPKIFBufferPtr ocspReq = _CreateComplexOCSPRequest(path, m_parent, nonce, m_bGenerateNonce, m_cred);
01769
01770
01771 CPKIFBasicOCSPResponsePtr basicOCSPResponse;
01772
01773
01774 CPKIFCertificatePtr signersCert;
01775
01776 int error = 0;
01777 CPKIFOCSPResponsePtr response;
01778
01779 CPKIFPathSettingsPtr ps;
01780 path.GetPathSettings(ps);
01781
01782
01783
01784 if(host)
01785 {
01786 if(!CheckOCSPStatus(host, port, object, ocspReq, basicOCSPResponse, signersCert, &error, response, ps))
01787 return false;
01788 }
01789 else
01790 {
01791 if(!CheckOCSPStatus(NULL, port, object, ocspReq, basicOCSPResponse, signersCert, &error, response, ps, url))
01792 return false;
01793 }
01794 CPKIFResponseDataPtr responseData = basicOCSPResponse->GetResponseData();
01795
01796 std::vector<CPKIFX509ExtensionPtr> processedExts;
01797
01798
01799 if(nonce != (CPKIFBuffer*)NULL)
01800 {
01801 CPKIFX509ExtensionPtr ext;
01802 responseData->GetExtensionByOID(*g_ocspNonce, ext);
01803 if(ext == (CPKIFBuffer*)NULL)
01804 {
01805 if(m_bRequireNonceMatch)
01806 {
01807 error = OCSP_NONCE_MISSING;
01808 return false;
01809 }
01810 }
01811 else
01812 {
01813 CPKIFBufferPtr value = ext->value();
01814 if(value == (CPKIFBuffer*)NULL || !(*nonce == *value))
01815 {
01816 if(m_bRequireNonceMatch)
01817 {
01818 error = OCSP_NONCE_MISMATCH;
01819 return false;
01820 }
01821 }
01822 }
01823
01824 processedExts.push_back(ext);
01825 }
01826
01827 if(responseData->AreThereAnyUnprocessedCriticalExtensions(processedExts))
01828 {
01829 error = OCSP_UNPROCESSED_CRITICAL_EXTENSION;
01830 return false;
01831 }
01832
01833
01834 CPKIFSingleResponseList responses;
01835 responseData->GetResponses(responses);
01836
01837
01838 CPKIFCertificateNodeList certPath;
01839 path.GetPath(certPath);
01840
01841
01842 IPKIFTrustAnchorPtr tr;
01843 path.GetTrustRoot(tr);
01844 CPKIFCertificatePtr issuersCert;
01845
01846 CPKIFTrustRootPtr ta = boost::dynamic_pointer_cast<CPKIFTrustRoot, IPKIFTrustAnchor>(tr);
01847 if(ta)
01848 ta->GetCert(issuersCert);
01849 else
01850 {
01851 throw CPKIFException(TOOLKIT_OCSP_CHECKER, COMMON_INVALID_INPUT, "CPKIFOCSPChecker does not support non-certificate trust anchors.");
01852 }
01853
01854 vector<IPKIFRevSourceInfoPtr> rslCollected;
01855
01856
01857 CPKIFCertificateNodeList::iterator pathPos;
01858 CPKIFCertificateNodeList::iterator pathEnd = certPath.end();
01859 for(pathPos = certPath.begin(); pathPos != pathEnd; ++pathPos)
01860 {
01861
01862 CPKIFCertificatePtr cert = (*pathPos)->GetCert();
01863
01864 CPKIFCertStatusPtr aCertStatus = (*pathPos)->GetStatus();
01865 CPKIFCertStatusPtr& certStatus = aCertStatus;
01866
01867
01868 int error = 0;
01869 RevocationStatus rs;
01870 CPKIFOCSPInfoPtr ocspInfo(new CPKIFOCSPInfo);
01871
01872 ocspInfo->SetOCSPResponse(response);
01873
01874
01875 IPKIFNameAndKey* issuersCertNK = dynamic_cast<IPKIFNameAndKey*>(issuersCert.get());
01876 if(!CheckCertStatus(responses, signersCert, issuersCertNK, *cert, rs, ocspInfo, &error, ps))
01877 bSomeNonDefinitive = true;
01878 else
01879 bSomeDefinitive = true;
01880
01881
01882 certStatus->AddRevocationSource(REVSOURCE_OCSP, REV_INFO_CAST(ocspInfo), rs, error);
01883 IPKIFRevSourceInfoPtr tmpRevSource = REV_INFO_CAST(ocspInfo);
01884 rslCollected.push_back(tmpRevSource);
01885
01886
01887 certStatus->SetRevocationStatus(rs);
01888 if(REVOKED == rs)
01889 certStatus->SetDiagnosticCode(PATH_CERT_REVOKED);
01890 else if (NOT_CHECKED == rs)
01891 certStatus->SetDiagnosticCode(PATH_CERT_REVOCATION_STATUS_NOT_DETERMINED);
01892 else
01893 certStatus->SetDiagnosticCode(0);
01894
01895 issuersCert = cert;
01896 }
01897
01898
01899
01900 pathEnd = certPath.end();
01901 int ii = 0;
01902 bool bSkipValPath = false;
01903 for(pathPos = certPath.begin(), ii = 0; pathPos != pathEnd; ++pathPos, ++ii)
01904 {
01905 CPKIFCertificatePtr tmpCert = (*pathPos)->GetCert();
01906 if(*tmpCert == *signersCert)
01907 {
01908 CPKIFCertStatusPtr cs = (*pathPos)->GetStatus();
01909 if(NOT_REVOKED == cs->GetRevocationStatus())
01910 {
01911 bSkipValPath = true;
01912 break;
01913 }
01914 }
01915 }
01916
01917 if(bSomeDefinitive)
01918 {
01919
01920
01921 if(!bSkipValPath)
01922 {
01923 bValPath = ValidatePath(signersCert, &error);
01924 if(!bValPath)
01925 {
01926
01927 CPKIFCertificateNodeList::iterator pathPos;
01928 CPKIFCertificateNodeList::iterator pathEnd = certPath.end();
01929 for(pathPos = certPath.begin(); pathPos != pathEnd; ++pathPos)
01930 {
01931
01932 CPKIFCertificatePtr cert = (*pathPos)->GetCert();
01933
01934 CPKIFCertStatusPtr aCertStatus = (*pathPos)->GetStatus();
01935 CPKIFCertStatusPtr& certStatus = aCertStatus;
01936
01937 CPKIFOCSPInfoPtr ocspInfo(new CPKIFOCSPInfo);
01938 RevocationStatus rs = NOT_CHECKED;
01939 RevocationSourceList list;
01940 certStatus->GetRevocationSources(list);
01941 RevocationSourceList::iterator rslPos;
01942 RevocationSourceList::iterator rslEnd = list.end();
01943 int count = 0;
01944 for(rslPos = list.begin(); rslPos != rslEnd; ++rslPos)
01945 {
01946 vector<IPKIFRevSourceInfoPtr>::iterator rslCollectedPos;
01947 vector<IPKIFRevSourceInfoPtr>::iterator rslCollectedEnd = rslCollected.end();
01948 for(rslCollectedPos = rslCollected.begin(); rslCollectedPos != rslCollectedEnd; ++rslCollectedPos)
01949 {
01950 if((*rslPos)->m_sourceInfo == (*rslCollectedPos))
01951 {
01952 (*rslPos)->m_status = rs;
01953 (*rslPos)->m_errorCode = OCSP_PATH_BUILDING_FAILED;
01954 }
01955 }
01956 }
01957 certStatus->SetRevocationStatus(rs);
01958 certStatus->SetDiagnosticCode(PATH_CERT_REVOCATION_STATUS_NOT_DETERMINED);
01959 }
01960 }
01961 }
01962 else
01963 bValPath = true;
01964 if(bValPath)
01965 {
01966
01967 pathEnd = certPath.end();
01968 for(pathPos = certPath.begin(), ii = 0; pathPos != pathEnd; ++pathPos, ++ii)
01969 {
01970 CPKIFCertStatusPtr cs = (*pathPos)->GetStatus();
01971
01972 }
01973 }
01974 }
01975 }
01976 catch(CPKIFException&)
01977 {
01978 }
01979
01980
01981 return !bSomeNonDefinitive && bValPath;
01982 }
01993 bool CPKIFOCSPCheckerImpl::CheckOCSPStatus_Local(
01995 const char* host,
01997 int port,
01999 const char* object,
02001 CPKIFCertificate& cert,
02003 const IPKIFNameAndKey* issuersCert,
02005 CPKIFCertStatusPtr& certStatus,
02007 CPKIFPathSettingsPtr& ps,
02009 const char* url,
02011 const CPKIFCertificatePath* prevPath)
02012 {
02013 LOG_STRING_DEBUG("CPKIFOCSPChecker::CheckOCSPStatus_Local", TOOLKIT_OCSP_CHECKER, 0, this);
02014
02015 int error = 0;
02016
02017
02018 CPKIFOCSPInfoPtr ocspInfo;
02019 RevocationStatus rs = NOT_CHECKED;
02020
02021
02022
02023 CPKIFX509ExtensionPtr ext;
02024 cert.GetExtensionByOID(*g_ocspNoCheck, ext);
02025 if(ext != (CPKIFX509Extension*)NULL)
02026 {
02027 certStatus->SetRevocationStatus(NOT_REVOKED);
02028 return true;
02029 }
02030
02031 do
02032 {
02033 CPKIFBufferPtr ocspReq;
02034 try
02035 {
02036 CPKIFBufferPtr nonce;
02037
02038
02039 ocspReq = _CreateSimpleOCSPRequest(cert, issuersCert, m_parent, nonce, m_bGenerateNonce, m_cred);
02040
02041 CPKIFOCSPResponsePtr response;
02042 CPKIFBasicOCSPResponsePtr basicOCSPResponse;
02043 CPKIFCertificatePtr signersCert;
02044
02045
02046
02047 if(!CheckOCSPStatus(host, port, object, ocspReq, basicOCSPResponse, signersCert, &error, response, ps, url))
02048 break;
02049
02050
02051 CPKIFResponseDataPtr responseData = basicOCSPResponse->GetResponseData();
02052
02053 std::vector<CPKIFX509ExtensionPtr> processedExts;
02054
02055
02056 if(nonce != (CPKIFBuffer*)NULL)
02057 {
02058 CPKIFX509ExtensionPtr ext;
02059 responseData->GetExtensionByOID(*g_ocspNonce, ext);
02060 if(ext == (CPKIFBuffer*)NULL)
02061 {
02062 if(m_bRequireNonceMatch)
02063 {
02064 error = OCSP_NONCE_MISSING;
02065 break;
02066 }
02067 }
02068 else
02069 {
02070 CPKIFBufferPtr value = ext->value();
02071 if(value == (CPKIFBuffer*)NULL || !(*nonce == *value))
02072 {
02073 if(m_bRequireNonceMatch)
02074 {
02075 error = OCSP_NONCE_MISMATCH;
02076 break;
02077 }
02078 }
02079 }
02080
02081 processedExts.push_back(ext);
02082 }
02083
02084 if(responseData->AreThereAnyUnprocessedCriticalExtensions(processedExts))
02085 {
02086 error = OCSP_UNPROCESSED_CRITICAL_EXTENSION;
02087 break;
02088 }
02089
02090
02091 CPKIFSingleResponseList responses;
02092 responseData->GetResponses(responses);
02093
02094
02095
02096 CPKIFOCSPInfoPtr tmpOCSPInfo(new CPKIFOCSPInfo);
02097 ocspInfo = tmpOCSPInfo;
02098 ocspInfo->SetOCSPResponse(response);
02099 if(!CheckCertStatus(responses, signersCert, issuersCert, cert, rs, tmpOCSPInfo, &error, ps))
02100 break;
02101
02102
02103 if(!ValidatePath(signersCert, &error, prevPath))
02104 {
02105
02106 rs = NOT_CHECKED;
02107 break;
02108 }
02109 }
02110 catch(CPKIFException& e)
02111 {
02112
02113 error = e.GetErrorCode();
02114 break;
02115 }
02116 }while(0);
02117
02118
02119
02120
02121 certStatus->SetRevocationStatus(rs);
02122 certStatus->AddRevocationSource(REVSOURCE_OCSP, REV_INFO_CAST(ocspInfo), rs, error);
02123 if(REVOKED == rs)
02124 certStatus->SetDiagnosticCode(PATH_CERT_REVOKED);
02125 else if (NOT_CHECKED == rs)
02126 certStatus->SetDiagnosticCode(PATH_CERT_REVOCATION_STATUS_NOT_DETERMINED);
02127 else
02128 certStatus->SetDiagnosticCode(0);
02129
02130 return 0 == error;
02131 }
02139 bool CPKIFOCSPCheckerImpl::CheckOCSPStatus_URL(const char* url, CPKIFCertificate& cert, const IPKIFNameAndKey* issuersCert, CPKIFCertStatusPtr& certStatus, CPKIFPathSettingsPtr& ps, const CPKIFCertificatePath* prevPath)
02140 {
02141 LOG_STRING_DEBUG("CPKIFOCSPChecker::CheckOCSPStatus_URL(const char* url, const CPKIFCertificate& cert, const CPKIFCertificate& issuersCert, CPKIFCertStatusPtr& certStatus)", TOOLKIT_OCSP_CHECKER, 0, this);
02142
02143
02144 return CheckOCSPStatus_Local(NULL, 0, NULL, cert, issuersCert, certStatus, ps, url, prevPath);
02145 }
02146
02147
02148
02149
02150
02151
02168 CPKIFOCSPChecker::CPKIFOCSPChecker(void)
02169 :m_impl (new CPKIFOCSPCheckerImpl)
02170 {
02171 LOG_STRING_DEBUG("CPKIFOCSPChecker::CPKIFOCSPChecker(void)", TOOLKIT_OCSP_CHECKER, 0, this);
02172
02173 m_impl->m_parent = this;
02174 m_impl->m_bLocalConfig = false;
02175
02176
02177
02178
02179
02180
02181 m_impl->m_port = 80;
02182
02183 m_impl->m_bGenerateNonce = false;
02184 m_impl->m_bRequireNonceMatch = true;
02185 m_impl->m_bMultiCertRequest = true;
02186 m_impl->m_bCacheResponders = false;
02187
02188
02189 CPKIFPathSettingsPtr settings(new CPKIFPathSettings);
02190 m_impl->m_settings = settings;
02191 }
02199 CPKIFOCSPChecker::CPKIFOCSPChecker(
02201 const CPKIFOCSPChecker& copy):m_impl (new CPKIFOCSPCheckerImpl)
02202 {
02203 m_impl->m_parent = this;
02204 m_impl->m_bLocalConfig = copy.m_impl->m_bLocalConfig;
02205 m_impl->m_bMultiCertRequest = copy.m_impl->m_bMultiCertRequest;
02206
02207
02208
02209
02210
02211
02212 m_impl->m_port = copy.m_impl->m_port;
02213
02214 m_impl->m_bGenerateNonce = copy.m_impl->m_bGenerateNonce;
02215 m_impl->m_bRequireNonceMatch = copy.m_impl->m_bRequireNonceMatch;
02216
02217
02218 CPKIFPathSettingsPtr settings(new CPKIFPathSettings(*copy.m_impl->m_settings));
02219 m_impl->m_settings = settings;
02220
02221 if(copy.m_impl->m_url != (std::string*)NULL)
02222 {
02223 std::string* urlCopy = new std::string(*copy.m_impl->m_url);
02224 CPKIFStringPtr newUrlCopy(urlCopy);
02225 m_impl->m_url = newUrlCopy;
02226 }
02227
02228 if(copy.m_impl->m_host != (std::string*)NULL)
02229 {
02230 std::string* hostCopy = new std::string(*copy.m_impl->m_host);
02231 CPKIFStringPtr newHostCopy(hostCopy);
02232 m_impl->m_host = newHostCopy;
02233 }
02234
02235 m_impl->m_port = copy.m_impl->m_port;
02236 m_impl->m_bLocalConfig = copy.m_impl->m_bLocalConfig;
02237 m_impl->m_bRequireThisCert = copy.m_impl->m_bRequireThisCert;
02238
02239 m_impl->m_responderCert = copy.m_impl->m_responderCert;
02240 m_impl->m_cred = copy.m_impl->m_cred;
02241
02242 m_impl->m_namespaces = copy.m_impl->m_namespaces;
02243 m_impl->m_issuerNamespaces = copy.m_impl->m_issuerNamespaces;
02244
02245 m_impl->m_bMultiCertRequest = copy.m_impl->m_bMultiCertRequest;
02246 m_impl->m_bCacheResponders = copy.m_impl->m_bCacheResponders;
02247 }
02248
02256 CPKIFOCSPChecker::~CPKIFOCSPChecker(void)
02257 {
02258 LOG_STRING_DEBUG("CPKIFOCSPChecker::~CPKIFOCSPChecker()", TOOLKIT_OCSP_CHECKER, 0, this);
02259
02260 delete m_impl;
02261 m_impl = NULL;
02262 }
02270 void CPKIFOCSPChecker::Initialize()
02271 {
02272 LOG_STRING_DEBUG("CPKIFOCSPChecker::Initialize()", TOOLKIT_OCSP_CHECKER, 0, this);
02273 }
02291 void CPKIFOCSPChecker::SetHost(
02293 const char* host)
02294 {
02295
02296 if(NULL == host)
02297 {
02298 throw CPKIFException(thisComponent,COMMON_INVALID_INPUT, "NULL host passed to CPKIFLDAPRepository::SetHost.");
02299 }
02300
02301 CPKIFStringPtr tmpSP(new std::string(host));
02302 m_impl->m_host = tmpSP;
02303
02304 CPKIFStringPtr nullSP((std::string *)NULL);
02305 m_impl->m_url = nullSP;
02306 m_impl->m_bLocalConfig = true;
02307 }
02308
02326 void CPKIFOCSPChecker::SetURL(
02328 const char* url)
02329 {
02330
02331 if(NULL == url)
02332 {
02333 throw CPKIFException(thisComponent,COMMON_INVALID_INPUT, "NULL URL passed to CPKIFOCSPChecker::SetHost.");
02334 }
02335
02336 CPKIFStringPtr tmpSP(new std::string(url));
02337 m_impl->m_url = tmpSP;
02338
02339 CPKIFStringPtr nullSP((std::string *)NULL);
02340 m_impl->m_host = nullSP;
02341 m_impl->m_bLocalConfig = true;
02342 }
02343
02356 void CPKIFOCSPChecker::Set_Port(
02358 int port)
02359 {
02360
02361 if(65535 < port)
02362 {
02363 throw CPKIFException(thisComponent,COMMON_INVALID_INPUT, "Port greater than 65535 passed to CPKIFLDAPRepository::Set_Port.");
02364 }
02365 m_impl->m_port = port;
02366 m_impl->m_bLocalConfig = true;
02367 }
02368
02369
02382 bool CPKIFOCSPChecker::CheckStatus(
02385 const CPKIFCertificatePtr& targetCert,
02388 const CPKIFCertificatePtr& issuersCert,
02390 RevocationStatus& status,
02392 CPKIFCertStatusPtr& certStatus)
02393 {
02394 LOG_STRING_DEBUG("CPKIFOCSPChecker::CheckStatus", TOOLKIT_OCSP_CHECKER, 0, this);
02395
02396 status = NOT_CHECKED;
02397
02398 if(targetCert == (CPKIFCertificate*)NULL || issuersCert == (CPKIFCertificate*)NULL)
02399 throw CPKIFException(thisComponent,COMMON_INVALID_INPUT,"Invalid input passed to OCSP status verification function");
02400
02401
02402 IPKIFCryptoMisc* cMisc = GetMediatorFromParent<IPKIFCryptoMisc>();
02403 IPKIFCryptoRawOperations* crypto = GetMediatorFromParent<IPKIFCryptoRawOperations>();
02404 if(NULL == cMisc || NULL == crypto)
02405 throw CPKIFException(thisComponent,COMMON_MEDIATOR_MISSING,"One or both of the IPKIFCryptoRawOperations or IPKIFCryptoMisc interfaces was not available.");
02406
02407 if(certStatus == (CPKIFCertStatus*)NULL)
02408 {
02409
02410 CPKIFCertStatusPtr tmpCS(new CPKIFCertStatus);
02411 certStatus = tmpCS;
02412 }
02413
02414
02415
02416 CPKIFX509ExtensionPtr ext;
02417 targetCert->GetExtensionByOID(*g_ocspNoCheck, ext);
02418 if(ext != (CPKIFX509Extension*)NULL)
02419 {
02420 certStatus->SetRevocationStatus(NOT_REVOKED);
02421 return true;
02422 }
02423
02424 if(!m_impl->CheckNamespaces(targetCert))
02425 return false;
02426
02427 if(!m_impl->CheckIssuerNamespaces(targetCert))
02428 return false;
02429
02430
02431 IPKIFNameAndKey* issuersCertNK = dynamic_cast<IPKIFNameAndKey*>(issuersCert.get());
02432 if(!issuersCertNK)
02433 return false;
02434
02435 bool bDefinitiveAnswer = false;
02436 if(m_impl->m_bLocalConfig)
02437 {
02438
02439
02440 if(m_impl->m_host)
02441 {
02442 bDefinitiveAnswer = m_impl->CheckOCSPStatus_Local(m_impl->m_host->c_str(),
02443 m_impl->m_port, "/", *targetCert, issuersCertNK, certStatus, m_impl->m_settings);
02444 }
02445 else
02446 {
02447 bDefinitiveAnswer = m_impl->CheckOCSPStatus_Local(NULL,
02448 m_impl->m_port, "/", *targetCert, issuersCertNK, certStatus, m_impl->m_settings, m_impl->m_url->c_str());
02449 }
02450
02451 }
02452
02453 if(!bDefinitiveAnswer)
02454 {
02455
02456 CPKIFAuthorityInfoAccessPtr aia = targetCert->GetExtension<CPKIFAuthorityInfoAccess>();
02457 if(aia != (CPKIFAuthorityInfoAccess*)NULL)
02458 {
02459 CPKIFAccessDescriptionListPtr ads = aia->GetAccessDescriptions();
02460
02461 CPKIFAccessDescriptionList::iterator pos;
02462 CPKIFAccessDescriptionList::iterator end = ads->end();
02463 for(pos = ads->begin(); pos != end; ++pos)
02464 {
02465 CPKIFOIDPtr aOID = (*pos)->AccessMethod();
02466 if(aOID != (CPKIFOID*)NULL && *aOID == *g_adOCSP)
02467 {
02468 const char* url = (*pos)->AccessLocation()->uri();
02469 bDefinitiveAnswer = m_impl->CheckOCSPStatus_URL(url, *targetCert, issuersCertNK, certStatus, m_impl->m_settings);
02470 if(bDefinitiveAnswer)
02471 break;
02472 }
02473 }
02474 }
02475 }
02476
02477 if(bDefinitiveAnswer)
02478 status = certStatus->GetRevocationStatus();
02479
02480 return bDefinitiveAnswer;
02481 }
02492 bool CPKIFOCSPChecker::CheckStatusPath(
02494
02495 CPKIFCertificatePath& path,
02498 RevocationStatus& status)
02499 {
02500 LOG_STRING_DEBUG("CPKIFOCSPChecker::CheckStatusPath(CPKIFCertificatePath& path, RevocationStatus& status)", TOOLKIT_OCSP_CHECKER, 0, this);
02501
02502 status = NOT_CHECKED;
02503 bool statusSet = false;
02504
02505 RevocationStatus pathStatus = NOT_CHECKED;
02506
02507
02508 IPKIFCryptoMisc* cMisc = GetMediatorFromParent<IPKIFCryptoMisc>();
02509 IPKIFCryptoRawOperations* crypto = GetMediatorFromParent<IPKIFCryptoRawOperations>();
02510 if(NULL == cMisc || NULL == crypto)
02511 throw CPKIFException(thisComponent,COMMON_MEDIATOR_MISSING,"One or both of the IPKIFCryptoRawOperations or IPKIFCryptoMisc interfaces was not available.");
02512
02513 CPKIFCertificateNodeList certPath;
02514 path.GetPath(certPath);
02515
02516 CPKIFPathSettingsPtr ps;
02517 path.GetPathSettings(ps);
02518
02519 CPKIFCertificatePtr targetCert;
02520 path.GetTarget(targetCert);
02521 if(targetCert == (CPKIFCertificate*)NULL || (!m_impl->CheckNamespaces(targetCert) && !m_impl->CheckIssuerNamespaces(targetCert)))
02522 return false;
02523
02524 if(m_impl->m_bLocalConfig && m_impl->m_bMultiCertRequest)
02525 {
02526
02527 if(m_impl->m_host)
02528 {
02529 m_impl->CheckOCSPStatus_Combo(m_impl->m_host->c_str(), m_impl->m_port, "/", path);
02530 }
02531
02532 else
02533 {
02534 m_impl->CheckOCSPStatus_Combo(NULL, m_impl->m_port, "/", path, m_impl->m_url->c_str());
02535 }
02536 }
02537
02538
02539 bool allGood = true;
02540 CPKIFCertificateNodeList::iterator pathPos;
02541 CPKIFCertificateNodeList::iterator pathEnd = certPath.end();
02542 for(pathPos = certPath.begin(); pathPos != pathEnd; ++pathPos)
02543 {
02544 CPKIFCertStatusPtr cs = (*pathPos)->GetStatus();
02545 if(!statusSet)
02546 {
02547 pathStatus = cs->GetRevocationStatus();
02548 if(!statusSet && NOT_CHECKED != pathStatus)
02549 statusSet = true;
02550 }
02551 else
02552 pathStatus = min(pathStatus, cs->GetRevocationStatus());
02553 if(NOT_CHECKED == cs->GetRevocationStatus())
02554 {
02555 allGood = false;
02556 break;
02557 }
02558 }
02559
02560
02561 if(allGood)
02562 {
02563 status = pathStatus;
02564 return true;
02565 }
02566
02567 IPKIFTrustAnchorPtr root;
02568 path.GetTrustRoot(root);
02569
02570 IPKIFNameAndKey* prevCert = dynamic_cast<IPKIFNameAndKey*>(root.get());
02571 if(!prevCert)
02572 {
02573 throw CPKIFException(TOOLKIT_OCSP_CHECKER, COMMON_INVALID_INPUT, "CPKIFOCSPChecker does not support non-certificate trust anchors.");
02574 }
02575
02576 if(m_impl->m_bLocalConfig)
02577 {
02578
02579 pathEnd = certPath.end();
02580 for(pathPos = certPath.begin(); pathPos != pathEnd; ++pathPos)
02581 {
02582 CPKIFCertificatePtr cert = (*pathPos)->GetCert();
02583
02584 if(m_impl->CheckNamespaces(cert) && m_impl->CheckIssuerNamespaces(cert))
02585 {
02586 CPKIFCertStatusPtr cs = (*pathPos)->GetStatus();
02587
02588 if(NOT_CHECKED == cs->GetRevocationStatus())
02589 {
02590 if(m_impl->m_host)
02591 {
02592 m_impl->CheckOCSPStatus_Local(m_impl->m_host->c_str(), m_impl->m_port, "/", *cert, prevCert, cs, ps, NULL, &path);
02593 }
02594 else
02595 {
02596 m_impl->CheckOCSPStatus_Local(NULL, m_impl->m_port, "/", *cert, prevCert, cs, ps, m_impl->m_url->c_str(), &path);
02597 }
02598 }
02599 }
02600 prevCert = dynamic_cast<IPKIFNameAndKey*>(cert.get());
02601 }
02602 }
02603 if(allGood)
02604 {
02605 status = pathStatus;
02606 return true;
02607 }
02608
02609
02610 prevCert = dynamic_cast<IPKIFNameAndKey*>(root.get());
02611 if(!prevCert)
02612 {
02613 throw CPKIFException(TOOLKIT_OCSP_CHECKER, COMMON_INVALID_INPUT, "CPKIFOCSPChecker does not support non-certificate trust anchors.");
02614 }
02615
02616
02617 if(!m_impl->m_bLocalConfig)
02618 {
02619 pathEnd = certPath.end();
02620 for(pathPos = certPath.begin(); pathPos != pathEnd; ++pathPos)
02621 {
02622 CPKIFCertificatePtr cert = (*pathPos)->GetCert();
02623 CPKIFCertStatusPtr cs = (*pathPos)->GetStatus();
02624
02625
02626
02627
02628 CPKIFX509ExtensionPtr ext;
02629 cert->GetExtensionByOID(*g_ocspNoCheck, ext);
02630 if(ext != (CPKIFX509Extension*)NULL)
02631 {
02632 cs->SetRevocationStatus(NOT_REVOKED);
02633 continue;
02634 }
02635
02636 if(NOT_CHECKED == cs->GetRevocationStatus())
02637 {
02638 CPKIFAuthorityInfoAccessPtr aia = cert->GetExtension<CPKIFAuthorityInfoAccess>();
02639 if(aia != (CPKIFAuthorityInfoAccess*)NULL)
02640 {
02641 CPKIFAccessDescriptionListPtr ads = aia->GetAccessDescriptions();
02642
02643 CPKIFAccessDescriptionList::iterator pos;
02644 CPKIFAccessDescriptionList::iterator end = ads->end();
02645 for(pos = ads->begin(); pos != end; ++pos)
02646 {
02647
02648
02649 CPKIFOIDPtr accessMethod = (*pos)->AccessMethod();
02650 if(accessMethod != (CPKIFOID*)NULL && *g_adOCSP == *accessMethod)
02651 {
02652 const char* url = (*pos)->AccessLocation()->uri();
02653 if(m_impl->CheckOCSPStatus_URL(url, *cert, prevCert, cs, ps, &path))
02654 break;
02655 }
02656 }
02657 }
02658 }
02659
02660 prevCert = dynamic_cast<IPKIFNameAndKey*>(cert.get());
02661 }
02662 }
02663
02664 statusSet = false;
02665 allGood = true;
02666 pathEnd = certPath.end();
02667 for(pathPos = certPath.begin(); pathPos != pathEnd; ++pathPos)
02668 {
02669 CPKIFCertStatusPtr cs = (*pathPos)->GetStatus();
02670 if(!statusSet)
02671 {
02672 pathStatus = cs->GetRevocationStatus();
02673 statusSet = true;
02674 }
02675 else
02676 pathStatus = min(pathStatus, cs->GetRevocationStatus());
02677 if(NOT_CHECKED == cs->GetRevocationStatus())
02678 {
02679 allGood = false;
02680 break;
02681 }
02682 }
02683
02684 status = pathStatus;
02685 return allGood;
02686 }
02694 void CPKIFOCSPChecker::SetSigningCredential(
02696 CPKIFCredentialPtr& cred)
02697 {
02698 m_impl->m_cred = cred;
02699 }
02700
02711 void CPKIFOCSPChecker::SetResponderPublicKey(
02713 CPKIFCertificatePtr& cert,
02715 bool bRequireThisCert)
02716 {
02717 m_impl->m_responderCert = cert;
02718 m_impl->m_bRequireThisCert = bRequireThisCert;
02719 }
02720
02730 CPKIFStringPtr CPKIFOCSPChecker::GetHost() const
02731 {
02732 return m_impl->m_host;
02733 }
02743 CPKIFStringPtr CPKIFOCSPChecker::GetURL() const
02744 {
02745 return m_impl->m_url;
02746 }
02755 int CPKIFOCSPChecker::GetPort() const
02756 {
02757 return m_impl->m_port;
02758 }
02766 CPKIFCredentialPtr CPKIFOCSPChecker::GetSigningCredential() const
02767 {
02768 return m_impl->m_cred;
02769 }
02777 CPKIFCertificatePtr CPKIFOCSPChecker::GetResponderPublicKey() const
02778 {
02779 return m_impl->m_responderCert;
02780 }
02788 bool CPKIFOCSPChecker::GetRequireSpecificCert() const
02789 {
02790 return m_impl->m_bRequireThisCert;
02791 }
02792
02803 void CPKIFOCSPChecker::AddNamespace(
02805 CPKIFGeneralSubtreePtr& name)
02806 {
02807 if(name == (CPKIFGeneralSubtree*)NULL)
02808 return;
02809
02810 m_impl->m_namespaces.push_back(name);
02811 }
02820 CPKIFGeneralSubtreeList CPKIFOCSPChecker::GetNamespaces()
02821 {
02822 return m_impl->m_namespaces;
02823 }
02824
02835 void CPKIFOCSPChecker::AddIssuerNamespace(
02837 CPKIFGeneralSubtreePtr& name)
02838 {
02839 if(name == (CPKIFGeneralSubtree*)NULL)
02840 return;
02841
02842 m_impl->m_issuerNamespaces.push_back(name);
02843 }
02852 CPKIFGeneralSubtreeList CPKIFOCSPChecker::GetIssuerNamespaces()
02853 {
02854 return m_impl->m_issuerNamespaces;
02855 }
02856
02865 void CPKIFOCSPChecker::SetMultiCertRequest(
02867 bool bDoMultiCertRequests)
02868 {
02869 m_impl->m_bMultiCertRequest = bDoMultiCertRequests;
02870 }
02871
02880 bool CPKIFOCSPChecker::GetMultiCertRequest()
02881 {
02882 return m_impl->m_bMultiCertRequest;
02883 }