CACOCSPChecker.cpp

Go to the documentation of this file.
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"             //path errors
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 // Added during porting
00063 #include "IPKIFHashContext.h"
00064 #include "PKIFMediators.h"
00065 #include "IPKIFNameAndKey.h"
00066 #include "GeneralSubtree.h"
00067 
00068 //#define _DEBUG_URI_DUMP 1
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"))));//id-pkix-ad-ocsp
00080 CAC_API CPKIFOIDPtr g_ocspBasic
00081     (new CPKIFOID(CPKIFStringPtr(new std::string("1.3.6.1.5.5.7.48.1.1"))));//id-pkix-ocsp-basic
00082 CAC_API CPKIFOIDPtr g_ocspNonce
00083     (new CPKIFOID(CPKIFStringPtr(new std::string("1.3.6.1.5.5.7.48.1.2"))));//id-pkix-ocsp-nonce
00084 CAC_API CPKIFOIDPtr g_ocspNoCheck
00085     (new CPKIFOID(CPKIFStringPtr(new std::string("1.3.6.1.5.5.7.48.1.5"))));//id-pkix-ocsp-nocheck //corrected OID 8/23/2004
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     //relocated these to path settings 7/18/2004 
00144 //  CPKIFDurationPtr m_duration;
00145 //  bool m_bRequireSufficientlyRecent;
00146 
00147     //----------------------------------------------------------------------------------------------------
00148     //private member functions
00149     //----------------------------------------------------------------------------------------------------
00150     bool ProcessResponse(CPKIFBufferPtr& bp, CPKIFBasicOCSPResponsePtr& basicOCSPResponse, CPKIFCertificatePtr& signersCert, 
00151                     int* error, CPKIFOCSPResponsePtr& response);
00152 
00153     //These three functions are logical "revocation sources".  it is possible to generate two revocations sources
00154     //in a call to the public interface CheckStatus or CheckStatusPath functions.  this can occur if there is
00155     //an error (or incomplete response) when consulting a local responder and success w/ a responder identified
00156     //by an AIA extension.  These functions are responsible for insuring that all cert status objects are populated
00157     //with an OCSP info object.
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); //added path param 8/23/2004
00161     bool CheckOCSPStatus_URL(const char* url, CPKIFCertificate& cert, const IPKIFNameAndKey* issuersCert, CPKIFCertStatusPtr& certStatus, CPKIFPathSettingsPtr& ps, const CPKIFCertificatePath* prevPath = NULL); //added path param 8/23/2004
00162 
00163     //The remaining private functions are all utility in nature.
00164 
00165     //the following two functions submit a request, retrieve the response then perform basic checks on the response.
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     //the following function searches an ocsp response for a specific cert.
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     //the following functions verify signature on the response (including selection of signer's cert)
00176     CPKIFCertificatePtr CertChooser(CPKIFBasicOCSPResponse& basicOCSPResponse);
00177     bool VerifyBasicOCSPResponseSignature(CPKIFBasicOCSPResponse& basicOCSPResponse, CPKIFCertificatePtr& signersCert);
00178 
00179     //the following functions implement some of the basic checks
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); //added path param 8/23/2004
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     //if we get here then either it's not a match (cause the list isn't empty)
00246     //or it is a match (cause the list is empty).  when the list is empty, we
00247     //accept all comers.
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     //if we get here then either it's not a match (cause the list isn't empty)
00274     //or it is a match (cause the list is empty).  when the list is empty, we
00275     //accept all comers.
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 //  Non-member functions
00336 //
00337 //----------------------------------------------------------------------------------------------------
00338 //If the following 2 functions are altered such that SHA1 is no longer used
00339 //then the code below that creates the CertID objects MUST be altered to 
00340 //include a different algorithm identifier.
00352 CPKIFBufferPtr _HashIssuerName(
00354     const CPKIFCertificate& cert, 
00356     IPKIFColleague* m)
00357 {
00358     LOG_STRING_DEBUG("_HashIssuerName", TOOLKIT_OCSP_CHECKER, 0, NULL);
00359 
00360     //get the necessary interface
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     //get the issuer name from the cert
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     //encode it
00371     CPKIFBufferPtr tmp = issuerName->Encoded();
00372 
00373     //get a hash context
00374     IPKIFHashContext* hi = cMisc->HashInit(PKIFCRYPTO::SHA1);
00375     if(NULL == hi)
00376         throw CPKIFException(TOOLKIT_OCSP_CHECKER,COMMON_UNSUPPORTED_ALG,"");
00377 
00378     //allocate memory for hash result - this will be handed off to the buffer pointer below
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     //get the necessary interface
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     //ASN1DynBitStr* key = cert.SubjectPublicKeyInfo()->rawKey();
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     //get a hash context
00439     IPKIFHashContext* hi = cMisc->HashInit(PKIFCRYPTO::SHA1);
00440     if(NULL == hi)
00441         throw CPKIFException(TOOLKIT_OCSP_CHECKER,COMMON_UNSUPPORTED_ALG,"");
00442 
00443     //allocate memory for hash result - this will be handed off to the buffer pointer below
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         //cMisc->HashUpdate(hi, (unsigned char*)key->data, key->numbits/8);
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     //[in] A reference to CPKIFCertificate object which contain the certificate we what to find out status for
00483     const CPKIFCertificate& cert,
00484     //[in] A reference to CPKIFCertificate object which contains the issuer certificate
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     //get hash of the issuer DN
00498     CPKIFBufferPtr issuerNameHash = _HashIssuerName(cert, m);
00499 
00500     //hash issuer's public key
00501     CPKIFBufferPtr issuerKeyHash = _HashPublicKey(*issuersCert, m);
00502 
00503     //get target cert's serial number
00504     CPKIFStringPtr targetSerialNumber(new std::string(cert.SerialNumber()));
00505 
00506     //prepare certID
00507     CPKIFCertIDPtr certID(new CPKIFCertID);
00508     certID->SetHashAlg(g_sha1AI);
00509     certID->SetIssuerNameHash(issuerNameHash);
00510     certID->SetIssuerKeyHash(issuerKeyHash);
00511     certID->SetSerialNumber(targetSerialNumber);
00512 
00513     //create a new request (we use no request extensions presently)
00514     CPKIFRequestPtr req(new CPKIFRequest);
00515     req->SetCertID(certID);
00516 
00517     //create a to-be-signed request the add the request to it
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     //hand the to-be-signed request to the ocsp request then encode it
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     //[in] A reference to a smart pointer to a CPKIFCredential object
00549     CPKIFCredentialPtr& cred)
00550 {
00551     LOG_STRING_DEBUG("_CreateComplexOCSPRequest", TOOLKIT_OCSP_CHECKER, 0, NULL);
00552 
00553     //get list of certs that comprise the path
00554     CPKIFCertificateNodeList certPath;
00555     path.GetPath(certPath);
00556 
00557     //harvest the trust root cert
00558     IPKIFTrustAnchorPtr tr;
00559     path.GetTrustRoot(tr);
00560     IPKIFNameAndKeyPtr issuersCert = tr;
00561 
00562     //create a to-be-signed request
00563     CPKIFTBSRequestPtr tbsReq(new CPKIFTBSRequest);
00564     if(generateNonce)
00565         nonce = tbsReq->GetNonce();
00566     else
00567         tbsReq->SetGenerateNonce(false);
00568 
00569     //iterate over all certs in the path and prepare a request object for each
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             //get hash of the issuer DN
00580             CPKIFBufferPtr issuerNameHash = _HashIssuerName(*cert, m);
00581 
00582             //hash issuer's public key
00583             CPKIFBufferPtr issuerKeyHash = _HashPublicKey(*issuersCert, m);
00584 
00585             //get target cert's serial number
00586             CPKIFStringPtr targetSerialNumber(new std::string(cert->SerialNumber()));
00587 
00588             //prepare certID
00589             CPKIFCertIDPtr certID(new CPKIFCertID);
00590             certID->SetHashAlg(g_sha1AI);
00591             certID->SetIssuerNameHash(issuerNameHash);
00592             certID->SetIssuerKeyHash(issuerKeyHash);
00593             certID->SetSerialNumber(targetSerialNumber);
00594 
00595             //create a new request (we use no request extensions presently)
00596             CPKIFRequestPtr req(new CPKIFRequest);
00597             req->SetCertID(certID);
00598 
00599             //add the request to the to-be-signed request collection
00600             tbsReq->AddRequest(req);
00601         }
00602 
00603         //prepare issuersCert for next loop
00604         issuersCert = cert;
00605     }
00606 
00607     //hand the to-be-signed request to the ocsp request then encode it
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     //get serial number from cert ID and certificate
00631     const char* cidSN = cid->GetSerialNumber();
00632     const char* certSN = cert.SerialNumber();
00633 
00634     //fail if either are NULL or if they do not match
00635     //reviewed 4/24 - added strlen
00636     if(NULL == cidSN || NULL == certSN || strlen(cidSN) != strlen(certSN) ||
00637         0 != stricmp(cidSN, certSN))
00638         return false;
00639 
00640     //generate a hash of the certificate's issuer and get pointer to issuer hash from cert ID
00641     CPKIFBufferPtr certHashBuf = _HashIssuerName(cert, m);
00642     CPKIFBufferPtr cidHashBuf = cid->GetIssuerNameHash();
00643 
00644     //fail if they do not match
00645     if(!(*certHashBuf == *cidHashBuf))
00646         return false;
00647 
00648     //if we get here then we have a match
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 //  Private member functions
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     //This function is used to select a certificate for use in verifying the signature on
00716     //an OCSP response.
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                 //give the front cert a shot - we should never get here anyway
00748                 return certs.front();
00749             }
00750         }
00751     }
00752     else
00753     {
00754         if(CPKIFResponderID::NAME == ridType)
00755         {
00756             //look for TA - added 6/3/2004
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             //if we have a by Name responder ID then we can search for the certs
00776             //(if we have a key hash then we'll just fail to verify - sorry)
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                 //IPKIFTrustCache* trustCache = m_parent->GetMediatorFromParent<IPKIFTrustCache>();
00801                 //if(keyHash && NULL != trustCache)
00802                 //{
00803                 //  CPKIFNamePtr name = rid->GetName();
00804 
00805                 //  IPKIFTrustAnchorList TAs;
00806                 //  trustCache->GetTrustRoots(name, TAs);
00807 
00808                 //  IPKIFTrustAnchorList::iterator taPos;
00809                 //  IPKIFTrustAnchorList::iterator taEnd = TAs.end();
00810                 //  for(taPos = TAs.begin(); taPos != taEnd; ++taPos)
00811                 //  {
00812                 //      CPKIFSubjectKeyIdentifierPtr skid = (*taPos)->GetKeyIdentifier();
00813                 //      if(skid)
00814                 //      {
00815                 //          CPKIFBufferPtr skidBuf = skid->KeyIdentifier();
00816                 //          if(skidBuf && (*skidBuf == *keyHash))
00817                 //          {
00818                 //              CPKIFCertificatePtr taCert = (*taPos)->GetCertificate();
00819                 //              if(taCert)
00820                 //                  return taCert;
00821                 //              }
00822                 //      }
00823                 //  }
00824                 //}
00825 
00826                 //if we have a by Name responder ID then we can search for the certs
00827                 //(if we have a key hash then we'll just fail to verify - sorry)
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                 //failed in our search by key ID, do
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     //get the ResponseData
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     //get pointer to signature alg (should also identify hash alg)
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     //get a pointer to the signature
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     //get pointers to necessary interfaces
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     //setup hash alg
00894     PKIFCRYPTO::HASH_ALG ha;
00895     CPKIFOIDPtr anOID = sigAlg->oid();
00896     GetCACHashAlg(anOID, &ha); //GetCACHashAlg(sigAlg->oid(), &ha);
00897 
00898     //create a hash object
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     //get pointer to to-be-signed buffer
00906     CPKIFBufferPtr eRDP = responseData->toBeSigned();
00907 
00908     try
00909     {
00910         //hash the data
00911         cMisc->HashUpdate(h, (unsigned char*)eRDP->GetBuffer(), eRDP->GetLength());
00912 
00913         //get the result then destroy the hash context
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     //obtain a cert with which to verify the response
00924     CPKIFCertificatePtr cert = CertChooser(basicOCSPResponse);
00925     if(cert == (CPKIFCertificate*)NULL)
00926         return false;
00927 
00928     //setup a raw key material object...
00929     CPKIFKeyMaterial key;
00930     key.SetCertificate(cert->Encoded()->GetBuffer(), cert->Encoded()->GetLength());
00931 
00932     //then verify the signature
00933     if(!crypto->Verify(key, hashResult, ha, (unsigned char*)sig->GetBuffer(), sig->GetLength(), ha))
00934         return false;   
00935 
00936     //pass a pointer to the signer's cert back to the caller
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    //1. Matches a local configuration of OCSP signing authority for the
00969    //certificate in question; or
00970    //2. Is the certificate of the CA that issued the certificate in
00971    //question; or
00972    //3. Includes a value of id-ad-ocspSigning in an ExtendedKeyUsage
00973    //extension and is issued by the CA that issued the certificate in
00974    //question."
00975 
00976     //1. if local config (i.e. a host and port specified via Setxxx methods)
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     //2. if the OCSP signers cert is the cert issuers cert
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     //3. if the OCSP signers cert is issued by the cert issuer and contain OCSP signing EKU
01009     CPKIFExtendedKeyUsagePtr eku = const_cast<CPKIFCertificate*>(&signersCert)->GetExtension<CPKIFExtendedKeyUsage>();
01010     if(eku != (CPKIFExtendedKeyUsage*) NULL)
01011     {
01012         bool ocspEKUPresent = false;
01013         //get list of EKUs
01014         vector<CPKIFOIDPtr> keyPurposeIDs;
01015         eku->KeyPurposeIDs(keyPurposeIDs);
01016         
01017         //search list for OCSP signing EKU
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             //return true;
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             //sigVerified = crypto->VerifyCertificate(*issAsCert, signersCert);
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 void CPKIFOCSPChecker::SetSufficientlyRecent(int seconds)
01054 {
01055     m_duration->setSeconds(seconds);
01056 }
01057 void CPKIFOCSPChecker::SetRequireSufficientlyRecent(bool requireSufficientlyRecent)
01058 {
01059     m_bRequireSufficientlyRecent = requireSufficientlyRecent;
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     //5. The time at which the status being indicated is known to be
01083     //  correct (thisUpdate) is sufficiently recent.  
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     //6. When available, the time at or before which newer information will
01096     //  be available about the status of the certificate (nextUpdate) is
01097     //  greater than the current time.
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; //be optimistic
01144 
01145     //This function takes a vector of SingleResponses, the signer of the OCSPResponse that contained
01146     //the SingleResponses, an issuer cert and a target cert.  It searches the list of responses for
01147     //the target cert, determines if the ocsp signer is authorized, then determines the status.
01148     CPKIFSingleResponseList::iterator pos;
01149     CPKIFSingleResponseList::iterator end = responses.end();
01150     CPKIFSingleResponsePtr targetResponse;
01151     for(pos = responses.begin(); pos != end; ++pos)
01152     {
01153         //1. The certificate identified in a received response corresponds to
01154         //that which was identified in the corresponding request; (i.e. find the 
01155         //target cert in the list of responses)
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     //moved here from below so it gets returned in failure cases too
01171     //(like invalid time)
01172     ocspInfo->SetSingleResponse(targetResponse);
01173 
01174     //if OCSP signer is the target - return false (this prevents looping)
01175     if(*ocspSignersCert == targetCert)
01176     {
01177         *error = OCSP_RESPONDER_IS_TARGET;
01178         return false;
01179     }
01180 
01181     //4. found a response, check signer authorization
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     //check time
01197     if(!CheckTime(targetResponse, error, ps))
01198     {
01199         return false;
01200     }
01201 
01202     bool bDefinitiveAnswer = false;
01203 
01204     //check status (revocation status in cert status is ONLY updated here - 
01205     //until this point it should remain unknown)
01206     CPKIFOCSPCertStatusPtr cs = targetResponse->GetCertStatus();
01207     CPKIFOCSPCertStatus::CertStatusChoice choice = cs->GetChoice();
01208 //  ocspInfo->SetSingleResponse(targetResponse);
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:    //this one shouldn't happen but might as well treat as unknown
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 //added two nonce flags and supporting code 6/9/2004
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         //get pointer to necessary interfaces
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         //declare a path and set the target cert
01328         CPKIFCertificatePath path;
01329         path.SetTarget(signersCert);
01330 
01331         //prepare path settings
01332         if(m_settings != (CPKIFPathSettings*)NULL)
01333         {
01334             CPKIFPathSettingsPtr copy(new CPKIFPathSettings(*m_settings));
01335             path.SetPathSettings(copy);
01336         }
01337         else
01338         {
01339             //otherwise declare default settings
01340             CPKIFPathSettingsPtr settings(new CPKIFPathSettings);
01341             path.SetPathSettings(m_settings);
01342         }
01343 
01344         //next determine if the revocation status was determined (and if not
01345         //if our minimum requirements were met)
01346         RevocationStatus minAcceptable = NOT_REVOKED;
01347         CPKIFX509ExtensionPtr ext;
01348         signersCert->GetExtensionByOID(*g_ocspNoCheck, ext);
01349 
01350         //if nocheck extension is present then relax requirement to check revocation
01351         //if(ext != (CPKIFX509Extension*)NULL)
01352         //{
01353         //  minAcceptable = NOT_CHECKED;
01354         //}
01355 
01356         //This do/while will iteratively call Build and Validate until all paths have been tried
01357         //or a good path has been found.  
01358         do
01359         {
01360 
01361             //try to build a path
01362             if(!pb->BuildPath(path))
01363             {
01364                 *error = OCSP_PATH_BUILDING_FAILED;
01365                 //return false;
01366                 break;
01367             }
01368 
01369             //added this goo 8/23/2004 to ensure that we do not loop in broken PKIs
01370             //where a CA resorts to a subordinate for revocation status
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                             //return false;
01390                             continue;
01391                         }
01392                     }
01393                 }
01394             }
01395 
01396             //validate the path
01397             CPKIFPathValidationResults results;
01398             //CPKIFFuncStoragePtr empty;
01399             //Added key usage checker 3/25/2005  Armen
01400             CPKIFFuncStoragePtr keyUsageAny(new CPKIFFuncStorage(keyUsageChecker_Any));
01401             keyUsageAny->addFunc(EKUChecker_OcspSigning); //added EKU checker 7/13/2005 Armen
01402             pv->ValidatePath(path, results, keyUsageAny);
01403             
01404             //next see if basic checks passed and all signatures verified
01405             if((!results.GetBasicChecksSuccessfullyPerformed() ||
01406                 !results.GetCertSignaturesVerified()) && !results.GetTargetIsTrustAnchor()) //added TA check 6/9/04
01407             {
01408                 *error = OCSP_PATH_VALIDATION_FAILED;
01409                 //return false;
01410                 continue;
01411             }
01412 
01413             if(!ext)
01414             {
01415                 //if there's no noCheck extension, then everything must be NOT_REVOKED (the value in minAcceptable)
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                     //return false;
01426                     continue;
01427                 }
01428             }
01429             else
01430             {
01431                 //the EE cert is allowed to be NOT_CHECKED, must walk the path
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                     //skip the EE cert since noCheck applies to it
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                             //return false;     
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     //from RFC 2560 (manner in which each is met is described inline below with numeric references)
01494     //3.2  Signed Response Acceptance Requirements
01495     //  Prior to accepting a signed response as valid, OCSP clients SHALL
01496     //  confirm that:
01497     //  1. The certificate identified in a received response corresponds to
01498     //  that which was identified in the corresponding request;
01499     //  2. The signature on the response is valid;
01500     //  3. The identity of the signer matches the intended recipient of the
01501     //  request.
01502     //  4. The signer is currently authorized to sign the response.
01503     //  5. The time at which the status being indicated is known to be
01504     //  correct (thisUpdate) is sufficiently recent.
01505     //  6. When available, the time at or before which newer information will
01506     //  be available about the status of the certificate (nextUpdate) is
01507     //  greater than the current time.
01508 
01509     //First, parse the response
01510     CPKIFOCSPResponsePtr tmpOCSPResponse(new CPKIFOCSPResponse);
01511     tmpOCSPResponse->Decode(bp);
01512 
01513     //after parsing save the response to the outbound response parameter
01514     response = tmpOCSPResponse;
01515 
01516     //get the status of the protocol response
01517     OCSPResponseStatus ocspResponseStatus = tmpOCSPResponse->GetResponseStatus();
01518     if(successful != ocspResponseStatus)
01519     {
01520         *error = OCSP_RECEIVED_NON_SUCCESSFUL_RESPONSE;
01521         return false;
01522     }
01523 
01524     //then get the actual OCSP response from the protocol layer
01525     CPKIFResponseBytesPtr responseBytes = tmpOCSPResponse->GetResponseBytes();
01526     if(responseBytes == (CPKIFResponseBytes*)NULL)
01527     {
01528         *error = OCSP_NO_RESPONSE_BODY;
01529         return false;
01530     }
01531 
01532     //make sure it's a response type we support (currently basic only)
01533     if(!(*g_ocspBasic == responseBytes->GetResponseType()))
01534     {
01535         //unknown response type
01536         *error = OCSP_UNSUPPORTED_RESPONSE_TYPE;
01537         return false;
01538     }
01539 
01540     //get the encoded basic response
01541     CPKIFBufferPtr responseBuf = responseBytes->GetResponse();
01542 
01543     //decode the basic response
01544     CPKIFBasicOCSPResponsePtr tmpBasicOCSPResponse(new CPKIFBasicOCSPResponse);
01545     tmpBasicOCSPResponse->Decode(responseBuf);
01546 
01547     //2. The signature on the response is valid;
01548     //Before processing the response, verify the signature on the request
01549     //  (path validation is done elsewhere to prevent looping)
01550     if(!VerifyBasicOCSPResponseSignature(*tmpBasicOCSPResponse, signersCert))
01551     {
01552         *error = OCSP_RESPONSE_SIG_VERIFICATION_FAILED;
01553         return false;
01554     }
01555 
01556     //3. The identity of the signer matches the intended recipient of the request.
01557     //How, exactly, are we supposed to know who the "intended" recipient
01558     //  of the request was?  We don't.  Match the signer's cert info with
01559     //  the responderID instead
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         //m_bRequireSufficientlyRecent = false;
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         //ignore nonces for offline processing
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         //get the list of responses
01690         CPKIFSingleResponseList responses;
01691         responseData->GetResponses(responses);
01692 
01693         //grab a pointer to the current cert and current cert status objects
01694         if(targetCertStatus == (CPKIFCertStatus*)NULL)
01695         {
01696             CPKIFCertStatusPtr tmpCS(new CPKIFCertStatus);
01697             targetCertStatus = tmpCS; 
01698         }
01699 
01700         //declare some variables specific to this interation for use in setting up a revocation source
01701         RevocationStatus rs;
01702         CPKIFOCSPInfoPtr ocspInfo(new CPKIFOCSPInfo);
01703 
01704         ocspInfo->SetOCSPResponse(response); //set the response (single response is set in CheckCertStatus)
01705 
01706         //check response to determine the status of the current cert
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         //add a revocation source to the cert status object
01714         targetCertStatus->AddRevocationSource(REVSOURCE_OCSP, REV_INFO_CAST(ocspInfo), rs, error);
01715 
01716         //set up the status info (and possibly diagnostic info) for the cert status object
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             //if there are no definitive responses do we really care if there is a valid path?
01728             //this may help prevent looping when an OCSP server returns status on itself.
01729             bValPath = m_impl->ValidatePath(signersCert, &error);
01730         }
01731     }
01732     catch(CPKIFException&)
01733     {
01734     }
01735 
01736     //to return true we must have a definitive answer for each as well as a validated path
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         //This function takes a path and creates a single request containing 
01766         //info about each cert in the path.
01767         CPKIFBufferPtr nonce;
01768         CPKIFBufferPtr ocspReq = _CreateComplexOCSPRequest(path, m_parent, nonce, m_bGenerateNonce, m_cred);
01769 
01770         //declare a pointer to receive the basic response
01771         CPKIFBasicOCSPResponsePtr basicOCSPResponse;
01772 
01773         //declare a pointer to receive the OCSP signer's certificate
01774         CPKIFCertificatePtr signersCert;
01775 
01776         int error = 0;
01777         CPKIFOCSPResponsePtr response;
01778 
01779         CPKIFPathSettingsPtr ps;
01780         path.GetPathSettings(ps);
01781 
01782         //call a function to post the request, receive the response and process the generic 
01783         //portion of the response. 
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         //compare nonces
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         //get the list of responses
01834         CPKIFSingleResponseList responses;
01835         responseData->GetResponses(responses);
01836 
01837         //get the cert path as a list of cert nodes
01838         CPKIFCertificateNodeList certPath;
01839         path.GetPath(certPath);
01840 
01841         //harvest the trust root cert so we have the issuer of the first cert in the path
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         //iterate over the path.  for each cert in the path determine if the status has been
01856         //reported in the response
01857         CPKIFCertificateNodeList::iterator pathPos;
01858         CPKIFCertificateNodeList::iterator pathEnd = certPath.end();
01859         for(pathPos = certPath.begin(); pathPos != pathEnd; ++pathPos)
01860         {
01861             //grab a pointer to the current cert and current cert status objects
01862             CPKIFCertificatePtr cert = (*pathPos)->GetCert();
01863             
01864             CPKIFCertStatusPtr aCertStatus = (*pathPos)->GetStatus();
01865             CPKIFCertStatusPtr& certStatus = aCertStatus;
01866 
01867             //declare some variables specific to this interation for use in setting up a revocation source
01868             int error = 0;
01869             RevocationStatus rs;
01870             CPKIFOCSPInfoPtr ocspInfo(new CPKIFOCSPInfo);
01871 
01872             ocspInfo->SetOCSPResponse(response); //set the response (single response is set in CheckCertStatus)
01873 
01874             //check response to determine the status of the current cert
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             //add a revocation source to the cert status object
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             //set up the status info (and possibly diagnostic info) for the cert status object
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         //anti-looping measures: walk the path looking for the signersCert.  if it's there and the
01899         //status is NOT_REVOKED then consider the path validated.
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             //if there are no definitive responses do we really care if there is a valid path?
01920             //this may help prevent looping when an OCSP server returns status on itself.
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                         //grab a pointer to the current cert and current cert status objects
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                 //if path validation was successful - update the cert status of each cert in the path
01967                 pathEnd = certPath.end();
01968                 for(pathPos = certPath.begin(), ii = 0; pathPos != pathEnd; ++pathPos, ++ii)
01969                 {
01970                     CPKIFCertStatusPtr cs = (*pathPos)->GetStatus();
01971 //                  cs->SetRevocationStatus(rv[ii]);
01972                 }
01973             }
01974         }
01975     }
01976     catch(CPKIFException&)
01977     {
01978     }
01979 
01980     //to return true we must have a definitive answer for each as well as a validated path
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     //revocation source info
02018     CPKIFOCSPInfoPtr ocspInfo;
02019     RevocationStatus rs = NOT_CHECKED;
02020 
02021     //added this to avoid proceeding when noCheck is presented
02022     //if nocheck extension is present then relax requirement to check revocation
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             //create a response
02039             ocspReq = _CreateSimpleOCSPRequest(cert, issuersCert, m_parent, nonce, m_bGenerateNonce, m_cred);
02040 
02041             CPKIFOCSPResponsePtr response;                  //the entire response (for the OCSP info object)
02042             CPKIFBasicOCSPResponsePtr basicOCSPResponse;    //the basic response (to process)
02043             CPKIFCertificatePtr signersCert;                    //signers cert (to which a path should be built and verified)
02044 
02045             //submit the request to the OCSP server and retrieve the response (also verify the 
02046             //signature on the response and perform other basic checks)
02047             if(!CheckOCSPStatus(host, port, object, ocspReq, basicOCSPResponse, signersCert, &error, response, ps, url))
02048                 break;
02049 
02050             //get the response bytes out of the response
02051             CPKIFResponseDataPtr responseData = basicOCSPResponse->GetResponseData();
02052 
02053             std::vector<CPKIFX509ExtensionPtr> processedExts;
02054 
02055             //compare nonces
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             //get the list of responses
02091             CPKIFSingleResponseList responses;
02092             responseData->GetResponses(responses);
02093 
02094             //create an OCSP info object - stuff the response into it (the specific entry in the response
02095             //will be identified and saved in CheckCertStatus
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             //build and validate a path to the signer
02103             if(!ValidatePath(signersCert, &error, prevPath))
02104             {
02105                 //if validate path fails then we need to undo the status that we set above
02106                 rs = NOT_CHECKED;
02107                 break;
02108             }
02109         }
02110         catch(CPKIFException& e)
02111         {
02112             //if we failed to create a request - save the error code and break out of this block
02113             error = e.GetErrorCode();
02114             break;
02115         }
02116     }while(0);
02117 
02118     //we get here by success or error - need to set the necessary goo on the status object
02119     //the diagnostic code on the certStatus object is not related to an error here.  those
02120     //errors are returned as part of the revocation source info.
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     //This function takes a url, parses it then invokes CheckOCSPStatus_Local.
02144     return CheckOCSPStatus_Local(NULL, 0, NULL, cert, issuersCert, certStatus, ps, url, prevPath);
02145 }
02146 
02147 //----------------------------------------------------------------------------------------------------
02148 //
02149 //  Public Member functions
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     //m_bRequireSufficientlyRecent = true;
02176 
02177     //CPKIFDurationPtr d(new CPKIFDuration);
02178     //m_duration = d;
02179     //m_duration->setSeconds(2592000); //30 days
02180 
02181     m_impl->m_port = 80; //added 3/12/2004
02182 
02183     m_impl->m_bGenerateNonce = false;   //added 6/9/2004; changed 10/13/2006
02184     m_impl->m_bRequireNonceMatch = true;//added 6/9/2004
02185     m_impl->m_bMultiCertRequest = true;
02186     m_impl->m_bCacheResponders = false;
02187 
02188     //added 7/18/2004
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     //m_bRequireSufficientlyRecent = true;
02207 
02208     //CPKIFDurationPtr d(new CPKIFDuration);
02209     //m_duration = d;
02210     //m_duration->setSeconds(2592000); //30 days
02211 
02212     m_impl->m_port = copy.m_impl->m_port; //added 3/12/2004
02213 
02214     m_impl->m_bGenerateNonce = copy.m_impl->m_bGenerateNonce;   //added 6/9/2004
02215     m_impl->m_bRequireNonceMatch = copy.m_impl->m_bRequireNonceMatch;//added 6/9/2004
02216 
02217     //added 7/18/2004
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     //added check for NULL  2/23/2005
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     // can only have a host or a URL, not both
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     //added check for NULL  2/23/2005
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     // can only have a host or a URL, not both
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     //added port check 2/23/2005
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 //check the status of a single cert given the certificate and the issuer's certificate
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;//added 2/26 CRW
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     //get pointers to the necessary interfaces here
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         //if no cert status was provide then create one for the caller
02410         CPKIFCertStatusPtr tmpCS(new CPKIFCertStatus);
02411         certStatus = tmpCS;
02412     }
02413 
02414     //added this to avoid proceeding when noCheck is presented
02415     //if nocheck extension is present then relax requirement to check revocation
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         //this instance is associated with an OCSP server - try it first
02439         // add support for a local URL
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         //if no definitive answer is known so far then we need to consult any OCSP server identified by AIA extension
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;//if we found a definitive answer we need not continue searching
02472                 }
02473             }
02474         }
02475     }
02476 
02477     if(bDefinitiveAnswer)
02478         status = certStatus->GetRevocationStatus();//added 2/26 CRW
02479 
02480     return bDefinitiveAnswer; 
02481 }
02492 bool CPKIFOCSPChecker::CheckStatusPath(
02494     //@sought; status information is directly associated with each entry in the path
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;//added 2/26 CRW
02503     bool statusSet = false;
02504 
02505     RevocationStatus pathStatus = NOT_CHECKED;
02506 
02507     //get pointers to the necessary interfaces here
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         //we can prepare a single request and try to determine status for all in one shot
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     //determine if we found a definitive answer for all certs in the path
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)//modified status setting 3/29 CRW
02546         {
02547             pathStatus = cs->GetRevocationStatus();
02548             if(!statusSet && NOT_CHECKED != pathStatus) //added 3/25/2005 CRW
02549                 statusSet = true;
02550         }
02551         else
02552             pathStatus = min(pathStatus, cs->GetRevocationStatus()); //added 3/29 CRW
02553         if(NOT_CHECKED == cs->GetRevocationStatus())
02554         {
02555             allGood = false;
02556             break;
02557         }
02558     }
02559 
02560     //if we did - return true
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         //otherwise walk the path and query individual certs
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     //otherwise walk the path in search of AIA extensions with additional servers to query
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     //if we are locally configured, then we should not chase AIAs
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             //added 8/24/2004
02626             //added this to avoid proceeding when noCheck is presented
02627             //if nocheck extension is present then relax requirement to check revocation
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                         //added access method check 10/13/2003 - should've been
02648                         //here all along!
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; //if we found a definitive answer we need not continue searching
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)//modified status setting 3/29 CRW
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 }

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