PKIFCAPIRepository2.cpp

Go to the documentation of this file.
00001 
00009 #include "PKIFCAPIRepository2.h"
00010 #include "CAPIUtils.h" //added here 7/29/2004
00011 
00012 #include "PKIFCacheErrors.h"
00013 #include "PKIFCacheException.h"
00014 #include "ToolkitUtils.h"
00015 
00016 #include "Certificate.h"
00017 #include "Buffer.h"
00018 #include "CRL.h"
00019 #include "CapiCRL.h"
00020 #include "GottaMatch.h"
00021 #include "PKIFCRLNodeEntry.h"
00022 #include "PKIFLocalCertNode.h"
00023 #include "PKIFLocalCrlNode.h"
00024 #include "IssuingDistributionPoint.h"
00025 
00026 #include "IPKIFSearchCriteria.h"
00027 #include "KeyIDBasedSearch.h"
00028 #include "NameBasedSearch.h"
00029 #include "IssuerNameAndSerialNumberBasedSearch.h"
00030 
00031 #include "boost/numeric/conversion/cast.hpp"
00032 #include "boost/numeric/conversion/bounds.hpp"
00033 #include "boost/limits.hpp"
00034 
00035 using boost::numeric_cast;
00036 using boost::bad_numeric_cast;
00037 
00038 #include <atlbase.h>
00039 #include <sstream>
00040 
00041 using namespace boost;
00042 using namespace std;
00043 
00044 bool CharIsSpace(char c);
00045 //added this interface stuff 8/21/2004
00046 
00048 struct CPKIFCAPIRepository2Impl
00049 {
00050     HCERTSTORE m_hSto;
00051     int m_nSysStoRegLoc;
00052     char* m_szStore;
00053     
00054     CPKIFCAPIRepository2 *m_parent;
00062     CPKIFCAPIRepository2Impl () 
00063     {
00064         m_parent = NULL;
00065     }
00073     CPKIFCAPIRepository2Impl (CPKIFCAPIRepository2  *p) 
00074     {
00075         m_parent = p;
00076     }
00077 
00078     //added 8/12/2004
00079     DWORD m_ticksCerts;
00080     DWORD m_ticksCRLs;
00081 
00082     //added 05/12/2003 CRW
00084     void OpenCertStore();
00086     void CloseCertStore();
00087 
00088 };
00090 
00108 CPKIFCAPIRepository2::CPKIFCAPIRepository2(
00110     int sysStoRegLoc,
00112     const char* store)
00113     :m_impl (new CPKIFCAPIRepository2Impl), IPKIFCAPISource(sysStoRegLoc, store)
00114 {
00115     LOG_STRING_DEBUG("CPKIFCAPIRepository2::CPKIFCAPIRepository2(void)", TOOLKIT_SR_CAPIREPOSITORY, 0, this);
00116 
00117     m_impl->m_parent = this;
00118     m_impl->m_hSto = NULL;
00119 
00120     m_impl->m_nSysStoRegLoc = sysStoRegLoc;
00121 
00122     //Added 8/12/2004
00123     m_impl->m_ticksCerts = 0;
00124     m_impl->m_ticksCRLs = 0;
00125 
00126     m_impl->m_szStore = NULL;
00127     size_t len = 0;
00128     if(store)
00129     {
00130         len = strlen(store);
00131         m_impl->m_szStore = new char[len + 1];
00132 
00133         //reviewed 4/24
00134         strcpy(m_impl->m_szStore, store);
00135     }
00136 }
00144 CPKIFCAPIRepository2::~CPKIFCAPIRepository2(void)
00145 {
00146     LOG_STRING_DEBUG("CPKIFCAPIRepository2::~CPKIFCAPIRepository2(void)", TOOLKIT_SR_CAPIREPOSITORY, 0, this);
00147 
00148     if(m_impl->m_szStore)
00149         delete[] m_impl->m_szStore;
00150 
00151     m_impl->CloseCertStore();
00152 
00153     delete m_impl;
00154     m_impl = NULL;
00155 }
00165 void CPKIFCAPIRepository2Impl::OpenCertStore()
00166 {
00167     LOG_STRING_DEBUG("CPKIFCAPIRepository2::OpenCertStore", TOOLKIT_SR_CAPIREPOSITORY, 0, this);
00168 
00169     USES_CONVERSION;
00170     //read only access - 8/26/2004
00171     m_hSto =  CertOpenStore(CERT_STORE_PROV_SYSTEM, X509_ASN_ENCODING, NULL, 
00172                                 CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG | m_nSysStoRegLoc , T2OLE(m_szStore));
00173     if(NULL == m_hSto)
00174     {
00175         std::ostringstream os;
00176         os << "CertOpenStore failed: " << GetLastError();
00177         RAISE_CACHE_EXCEPTION(os.str().c_str(), m_parent->thisComponent, CACHE_CERT_STORE_OPEN_FAILED, this)
00178     }
00179 }
00187 void CPKIFCAPIRepository2Impl::CloseCertStore()
00188 {
00189     LOG_STRING_DEBUG("CPKIFCAPIRepository2::CloseCertStore()", TOOLKIT_SR_CAPIREPOSITORY, 0, this);
00190     if(NULL != m_hSto)
00191     {
00192         CertCloseStore(m_hSto, 0); m_hSto = NULL;
00193     }
00194 }
00206 void CPKIFCAPIRepository2::Initialize(void)
00207 {
00208     LOG_STRING_DEBUG("CPKIFCAPIRepository2::Initialize(void)", TOOLKIT_SR_CAPIREPOSITORY, 0, this);
00209 
00210     if(NULL != m_impl->m_hSto)
00211     {
00212         LOG_STRING_WARN("Skipping initialization - CPKIFCAPIRepository2 instance already initialized", TOOLKIT_SR_CAPIREPOSITORY, COMMON_ALREADY_INITIALIZED, this);
00213         return; //already initialized - just log it, return and don't bother with exception
00214     }
00215 
00216     //generate any store open exceptions during initialization
00217     m_impl->OpenCertStore();
00218     m_impl->m_ticksCerts = GetTickCount();
00219     m_impl->m_ticksCRLs = GetTickCount();
00220 }
00230 void CPKIFCAPIRepository2::GetCertificates(
00232     const CPKIFNamePtr& subDN, 
00234     CPKIFCertificateList& certList,
00236     PKIInfoSource source)
00237 {
00238     LOG_STRING_DEBUG("CPKIFCAPIRepository2::GetCertificates(const CPKIFNamePtr& subDN, CPKIFCertificateList& certList, PKIInfoSource source)", TOOLKIT_SR_CAPIREPOSITORY, 0, this);
00239 
00240     //ignore requests for remote certificates
00241     if(REMOTE == source)
00242     {
00243         LOG_STRING_DEBUG("Skipping CPKIFCAPIRepository2 - searching REMOTE sources only", thisComponent, 0, this);
00244         return;
00245     }
00246 
00247     DWORD curr = GetTickCount();
00248     if(curr - m_impl->m_ticksCerts > 120000)
00249     {
00250         m_impl->CloseCertStore();
00251         m_impl->OpenCertStore();
00252         m_impl->m_ticksCerts = curr;
00253     }
00254     const size_t origSize = certList.size();
00255 
00256     if(subDN)
00257     {
00258         PCCERT_CONTEXT cert = NULL;
00259         CERT_NAME_BLOB nameBlob; 
00260         nameBlob.cbData = 0; 
00261         nameBlob.pbData = NULL;
00262 
00263         //replaced reliance on CAPI DN encoder with Objective encoder
00264         CPKIFBufferPtr encName = subDN->Encoded();
00265         nameBlob.pbData = (BYTE*)encName->GetBuffer();
00266         nameBlob.cbData = encName->GetLength();
00267 
00268         //CACX509V3Name* raw = subDN->rawName();
00269         //CACASNWRAPPER_CREATE(CACX509V3Name, objPDU);
00270         //ASN1OpenType* data1 = objPDU.Encode(raw);
00271         //nameBlob.pbData = (BYTE*)data1->data;
00272         //nameBlob.cbData = data1->numocts;
00273 
00274         do
00275         {
00276             cert = CertFindCertificateInStore(m_impl->m_hSto, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 
00277                 0, CERT_FIND_SUBJECT_NAME, &nameBlob, cert);
00278             if(NULL == cert)
00279                 break;
00280 
00281             //create a CCACCert and stuff it into the list
00282             CPKIFCertificatePtr tmpCert(new CPKIFCertificate);
00283             try
00284             {
00285                 tmpCert->Decode(cert->pbCertEncoded, cert->cbCertEncoded);
00286             }
00287             catch(CPKIFException& )
00288             {
00289                 //EXCEPTION DELETION
00290                 //don't fail due to parse errors - log the failure and continue searching
00291                 //if nothing is found that actually parses then an error will be generated
00292                 //delete e;
00293 
00294                 #ifndef DISABLE_LOGGING_MACROS
00295                 std::ostringstream os;
00296                 os << "Failed to parse certificate from CAPI store searching for certificates issued to: " << subDN->ToString();
00297                 #endif
00298                 LOG_STRING_ERROR(os.str().c_str(), thisComponent, CACHE_PARSE_ERROR, this)
00299             }
00300             
00301             GottaMatch<CPKIFCertificatePtr> gm;
00302             gm.SetRHS(tmpCert);
00303             if(certList.end() == find_if(certList.begin(), certList.end(), gm))
00304                 certList.push_back(tmpCert);
00305 
00306         }while(NULL != cert);
00307     }
00308     else
00309     {
00310         PCCERT_CONTEXT pPrevCertContext = NULL;
00311 
00312         try
00313         {
00314             pPrevCertContext = CertEnumCertificatesInStore(m_impl->m_hSto, pPrevCertContext);
00315             while(NULL != pPrevCertContext)
00316             {
00317                 try
00318                 {
00319                     CPKIFCertificatePtr tmpCert(new CPKIFCertificate);
00320                     tmpCert->Decode(pPrevCertContext->pbCertEncoded, pPrevCertContext->cbCertEncoded);
00321 
00322                     GottaMatch<CPKIFCertificatePtr> gm;
00323                     gm.SetRHS(tmpCert);
00324                     if(certList.end() == find_if(certList.begin(), certList.end(), gm))
00325                         certList.push_back(tmpCert);
00326                 }
00327                 catch(...)
00328                 {
00329                     //ignore decoding errors
00330                 }
00331                 pPrevCertContext = CertEnumCertificatesInStore(m_impl->m_hSto, pPrevCertContext);
00332             }
00333         }
00334         catch(...)
00335         {
00336             if(NULL != pPrevCertContext)
00337             {
00338                 //if we threw before freeing cert context, clean up
00339                 CertFreeCertificateContext(pPrevCertContext); pPrevCertContext = NULL;
00340             }
00341 
00342             std::ostringstream os;
00343             os << "Unknown failure in GetCertificates while enumerating all trust anchors in the certificate store.  GetLastError returns: " << GetLastError();
00344             RAISE_CACHE_EXCEPTION(os.str().c_str(), thisComponent, COMMON_UNKNOWN_ERROR, this);
00345         }
00346     }
00347 
00348     //free the memory allocated in call to StrToName
00349     //if(NULL != nameBlob.pbData)
00350     //  PKIFDelete(nameBlob.pbData); //changed to PKIFDelete 12/7/2003
00351 
00352     if(origSize != certList.size())
00353     {
00354         #ifndef DISABLE_LOGGING_MACROS
00355         std::ostringstream os;
00356         os << "Found one or more certificates for subject: ";
00357         if(subDN)
00358             os << subDN->ToString();
00359         else
00360             os << "empty";
00361         #endif
00362         LOG_STRING_DEBUG(os.str().c_str(), thisComponent, 0, this);
00363     }
00364     else
00365     {
00366         #ifndef DISABLE_LOGGING_MACROS
00367         std::ostringstream os;
00368         os << "Failed to find a certificate for subject: ";
00369         if(subDN)
00370             os << subDN->ToString();
00371         else
00372             os << "empty";
00373         #endif
00374         LOG_STRING_INFO(os.str().c_str(), thisComponent, 0, this);
00375     }
00376 }
00389 void CPKIFCAPIRepository2::GetCRLs(
00391     const CPKIFCertificatePtr& cert, 
00393     CPKIFCRLList& crlList, 
00395     PKIInfoSource source)
00396 {
00397     LOG_STRING_DEBUG("CPKIFCAPIRepository2::GetCRLs(const CPKIFCertificatePtr& cert, CPKIFCRLList& crlList, PKIInfoSource source)", TOOLKIT_SR_CAPIREPOSITORY, 0, this);
00398 
00399     //ignore requests for remote certificates
00400     if(REMOTE == source)
00401     {
00402         LOG_STRING_DEBUG("Skipping CPKIFCAPIRepository2 - searching REMOTE sources only", thisComponent, 0, this);
00403         return;
00404     }
00405 
00406     DWORD curr = GetTickCount();
00407     if(curr - m_impl->m_ticksCRLs > 120000)
00408     {
00409         m_impl->CloseCertStore();
00410         m_impl->OpenCertStore();
00411         m_impl->m_ticksCRLs = curr;
00412     }
00413 
00414     const size_t origSize = crlList.size();
00415 
00416     PCCRL_CONTEXT crl = NULL;
00417     PCCERT_CONTEXT certCtx = NULL;
00418     PCCERT_CONTEXT issuerCtx = NULL;
00419 
00420     if(cert == (CPKIFCertificate*)NULL)
00421     {
00422         RAISE_CACHE_EXCEPTION("NULL certificate passed to GetCRLs.", thisComponent, COMMON_INVALID_INPUT, this)
00423     }
00424 
00425     certCtx = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, cert->Encoded()->GetBuffer(), cert->Encoded()->GetLength());
00426     if(NULL == certCtx)
00427     {
00428         std::ostringstream os;
00429         os << "Failed to parse certificate passed to GetCRLs.  CertCreateCertificateContext failed: " << GetLastError();
00430         RAISE_CACHE_EXCEPTION(os.str().c_str(), thisComponent, CACHE_PARSE_ERROR, this)
00431     }
00432 
00433     issuerCtx = CertFindCertificateInStore(m_impl->m_hSto, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_NAME, &certCtx->pCertInfo->Issuer, NULL);
00434     CertFreeCertificateContext(certCtx); certCtx = NULL;
00435     
00436     if(NULL == issuerCtx)
00437     {
00438         #ifndef DISABLE_LOGGING_MACROS
00439         std::ostringstream os;
00440         os << "Failed to find a CRL issued by: " << cert->Issuer()->ToString();
00441         #endif
00442         LOG_STRING_INFO(os.str().c_str(), thisComponent, 0, this);
00443         return;
00444     }
00445 
00446     do
00447     {   
00448         
00449         crl = CertFindCRLInStore(m_impl->m_hSto, 0, 0, CRL_FIND_ISSUED_BY, issuerCtx, crl);
00450         if(NULL == crl)
00451             break;
00452 
00453         //create a CPKIFCRL and stuff it into the list
00454         CPKIFCapiCRLPtr tmpCapiCRL(new CPKIFCapiCRL());
00455         tmpCapiCRL->SetCRL(CertDuplicateCRLContext(crl));
00456         CPKIFCRLPtr tmpCRL;
00457         CPKIFIssuingDistributionPointPtr idp = tmpCapiCRL->GetExtension<CPKIFIssuingDistributionPoint>();
00458         if(idp == (CPKIFIssuingDistributionPoint*)NULL || !idp->IndirectCRL())
00459         {
00460             //not indirect, use MSFT goo
00461             tmpCRL = dynamic_pointer_cast<CPKIFCRL, CPKIFCapiCRL>(tmpCapiCRL);
00462         }
00463         else
00464         {
00465             CPKIFCRLPtr tmpNonCapiCRL(new CPKIFCRL);
00466             tmpNonCapiCRL->Decode(crl->pbCrlEncoded, crl->cbCrlEncoded);
00467             tmpCRL = tmpNonCapiCRL;
00468         }
00469 
00470         GottaMatch<CPKIFCRLPtr> gm;
00471         gm.SetRHS(tmpCRL);
00472         if(crlList.end() == find_if(crlList.begin(), crlList.end(), gm))
00473             crlList.push_back(tmpCRL);
00474 
00475     }while(NULL != crl);
00476 
00477     CertFreeCertificateContext(issuerCtx);
00478     
00479 
00480     if(origSize != crlList.size())
00481     {
00482         #ifndef DISABLE_LOGGING_MACROS
00483         std::ostringstream os;
00484         os << "Found one or more CRLs issued by: " << cert->Issuer()->ToString();
00485         #endif
00486         LOG_STRING_DEBUG(os.str().c_str(), thisComponent, 0, this);
00487     }
00488     else
00489     {
00490         #ifndef DISABLE_LOGGING_MACROS
00491         std::ostringstream os;
00492         os << "Failed to find a CRL issued by: " << cert->Issuer()->ToString();
00493         #endif
00494         LOG_STRING_INFO(os.str().c_str(), thisComponent, 0, this);
00495     }
00496 }
00509 void CPKIFCAPIRepository2::GetCRLSources(
00511     const CPKIFCertificatePtr& cert,
00513     CPKIFCrlSourceList& crlSourceList,
00515     PKIInfoSource source)
00516 {
00517     LOG_STRING_DEBUG("CPKIFCAPIRepository2::GetCRLs(const CPKIFCertificatePtr& cert, CPKIFCRLList& crlList, PKIInfoSource source)", TOOLKIT_SR_CAPIREPOSITORY, 0, this);
00518 
00519     //ignore requests for remote certificates
00520     if(REMOTE == source)
00521     {
00522         LOG_STRING_DEBUG("Skipping CPKIFCAPIRepository2 - searching REMOTE sources only", thisComponent, 0, this);
00523         return;
00524     }
00525 
00526     DWORD curr = GetTickCount();
00527     if(curr - m_impl->m_ticksCRLs > 120000)
00528     {
00529         m_impl->CloseCertStore();
00530         m_impl->OpenCertStore();
00531         m_impl->m_ticksCRLs = curr;
00532     }
00533 
00534     const size_t origSize = crlSourceList.size();
00535 
00536     PCCRL_CONTEXT crl = NULL;
00537     PCCERT_CONTEXT certCtx = NULL;
00538     PCCERT_CONTEXT issuerCtx = NULL;
00539 
00540     if(cert == (CPKIFCertificate*)NULL)
00541     {
00542         RAISE_CACHE_EXCEPTION("NULL certificate passed to GetCRLSources.", thisComponent, COMMON_INVALID_INPUT, this)
00543     }
00544 
00545     certCtx = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, cert->Encoded()->GetBuffer(), cert->Encoded()->GetLength());
00546     if(NULL == certCtx)
00547     {
00548         std::ostringstream os;
00549         os << "Failed to parse certificate passed to GetCRLs.  CertCreateCertificateContext failed: " << GetLastError();
00550         RAISE_CACHE_EXCEPTION(os.str().c_str(), thisComponent, CACHE_PARSE_ERROR, this)
00551     }
00552 
00553     issuerCtx = CertFindCertificateInStore(m_impl->m_hSto, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_NAME, &certCtx->pCertInfo->Issuer, NULL);
00554     CertFreeCertificateContext(certCtx); certCtx = NULL;
00555     
00556     if(NULL == issuerCtx)
00557     {
00558         #ifndef DISABLE_LOGGING_MACROS
00559         std::ostringstream os;
00560         os << "Failed to find a CRL issued by: " << cert->Issuer()->ToString();
00561         #endif
00562         LOG_STRING_INFO(os.str().c_str(), thisComponent, 0, this);
00563         return;
00564     }
00565 
00566     do
00567     {   
00568         crl = CertFindCRLInStore(m_impl->m_hSto, 0, 0, CRL_FIND_ISSUED_BY, issuerCtx, crl);
00569         if(NULL == crl)
00570             break;
00571 
00572         CPKIFCRLNodeEntryPtr crlNode(new CPKIFCRLNodeEntry);
00573 
00574         //create a CPKIFCapiCRL and stuff it into the list
00575         CPKIFCapiCRLPtr tmpCapiCRL(new CPKIFCapiCRL());
00576         try
00577         {
00578             tmpCapiCRL->SetCRL(CertDuplicateCRLContext(crl));
00579 
00580             CPKIFIssuingDistributionPointPtr idp = tmpCapiCRL->GetExtension<CPKIFIssuingDistributionPoint>();
00581             if(idp == (CPKIFIssuingDistributionPoint*)NULL || !idp->IndirectCRL())
00582             {
00583                 //not indirect, use MSFT goo
00584                 CPKIFCRLPtr tmpCRL = dynamic_pointer_cast<CPKIFCRL, CPKIFCapiCRL>(tmpCapiCRL);
00585                 crlNode->SetCRL(tmpCRL);
00586             }
00587             else
00588             {
00589                 CPKIFCRLPtr tmpCRL(new CPKIFCRL);
00590                 tmpCRL->Decode(crl->pbCrlEncoded, crl->cbCrlEncoded);
00591                 crlNode->SetCRL(tmpCRL);
00592             }
00593             ostringstream ostr;
00594             ostr << "CAPI://";
00595             switch(m_impl->m_nSysStoRegLoc)
00596             {
00597             case CERT_SYSTEM_STORE_CURRENT_USER:
00598                 ostr << "CERT_SYSTEM_STORE_CURRENT_USER";
00599                 break;
00600             case CERT_SYSTEM_STORE_LOCAL_MACHINE:
00601                 ostr << "CERT_SYSTEM_STORE_LOCAL_MACHINE";
00602                 break;
00603             default:
00604                 ostr << m_impl->m_nSysStoRegLoc;
00605                 break;
00606             }
00607             ostr << "/" << m_impl->m_szStore << "/" << cert->GetIssuerName()->ToString() << ends;
00608 
00609             CPKIFLocalCrlNodePtr lcn(new CPKIFLocalCrlNode());
00610             lcn->SetState(PAS_AVAILABLE);
00611 
00612             std::string capiURI = ostr.str();
00613             crlNode->AddSource(capiURI);
00614             lcn->AddCrl(crlNode);
00615             crlSourceList.push_back(lcn);
00616         }
00617         catch(CPKIFException& )
00618         {
00619             //EXCEPTION DELETION
00620             //don't fail due to parse errors - log the failure and continue searching
00621             //if nothing is found that actually parses then an error will be generated
00622             //delete e;
00623 
00624             #ifndef DISABLE_LOGGING_MACROS
00625             std::ostringstream os;
00626             os << "Failed to parse CRL from CAPI store searching for certificates CRLs issued by: " << cert->Issuer()->ToString();
00627             #endif
00628             LOG_STRING_ERROR(os.str().c_str(), thisComponent, CACHE_PARSE_ERROR, this)
00629         }
00630     }while(NULL != crl);
00631 
00632     CertFreeCertificateContext(issuerCtx);
00633     
00634     if(origSize != crlSourceList.size())
00635     {
00636         #ifndef DISABLE_LOGGING_MACROS
00637         std::ostringstream os;
00638         os << "Found one or more CRLs issued by: " << cert->Issuer()->ToString();
00639         #endif
00640         LOG_STRING_DEBUG(os.str().c_str(), thisComponent, 0, this);
00641     }
00642     else
00643     {
00644         #ifndef DISABLE_LOGGING_MACROS
00645         std::ostringstream os;
00646         os << "Failed to find a CRL issued by: " << cert->Issuer()->ToString();
00647         #endif
00648         LOG_STRING_INFO(os.str().c_str(), thisComponent, 0, this);
00649     }
00650 }
00662 void CPKIFCAPIRepository2::GetCertificates(
00664     const CPKIFCertificatePtr& certOfInterest, 
00666     CPKIFCertificateList& certList,     
00668     PKIInfoSource source, 
00670     PathBuildingDirection pbd)
00671 {
00672     LOG_STRING_DEBUG("CPKIFCAPIRepository2::GetCertificates(const CPKIFCertificatePtr& cert, CPKIFCertificateList& certList, PKIInfoSource source = ALL, PathBuildingDirection pbd = PBD_FORWARD)", TOOLKIT_SR_CAPIREPOSITORY, 0, this);
00673 
00674     //ignore requests for remote certificates
00675     if(REMOTE == source)
00676     {
00677         LOG_STRING_DEBUG("Skipping CPKIFCAPIRepository2 - searching REMOTE sources only", thisComponent, 0, this);
00678         return;
00679     }
00680 
00681     DWORD curr = GetTickCount();
00682     if(curr - m_impl->m_ticksCerts > 120000)
00683     {
00684         m_impl->CloseCertStore();
00685         m_impl->OpenCertStore();
00686         m_impl->m_ticksCerts = curr;
00687     }
00688     const size_t origSize = certList.size();
00689 
00690     PCCERT_CONTEXT cert = NULL;
00691     CERT_NAME_BLOB nameBlob; 
00692     nameBlob.cbData = 0; 
00693     nameBlob.pbData = NULL;
00694 
00695     //replaced reliance on CAPI DN encoder with Objective encoder
00696     CPKIFNamePtr issDN = certOfInterest->Issuer();
00697     CPKIFBufferPtr encName = issDN->Encoded();
00698     nameBlob.pbData = (BYTE*)encName->GetBuffer();
00699     nameBlob.cbData = encName->GetLength();
00700 
00701     do
00702     {
00703         if(PBD_FORWARD == pbd)
00704             cert = CertFindCertificateInStore(m_impl->m_hSto, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 
00705                 0, CERT_FIND_SUBJECT_NAME, &nameBlob, cert);
00706         else
00707             cert = CertFindCertificateInStore(m_impl->m_hSto, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 
00708                 0, CERT_FIND_ISSUER_NAME, &nameBlob, cert);
00709         if(NULL == cert)
00710             break;
00711 
00712         //create a CCACCert and stuff it into the list
00713         CPKIFCertificatePtr tmpCert(new CPKIFCertificate);
00714         try
00715         {
00716             tmpCert->Decode(cert->pbCertEncoded, cert->cbCertEncoded);
00717         }
00718         catch(CPKIFException& )
00719         {
00720             //EXCEPTION DELETION
00721             //don't fail due to parse errors - log the failure and continue searching
00722             //if nothing is found that actually parses then an error will be generated
00723             //delete e;
00724 
00725             #ifndef DISABLE_LOGGING_MACROS
00726             std::ostringstream os;
00727             os << "Failed to parse certificate from CAPI store searching for certificates issued by: " << issDN->ToString();
00728             #endif
00729             LOG_STRING_ERROR(os.str().c_str(), thisComponent, CACHE_PARSE_ERROR, this)
00730         }
00731         
00732         GottaMatch<CPKIFCertificatePtr> gm;
00733         gm.SetRHS(tmpCert);
00734         if(certList.end() == find_if(certList.begin(), certList.end(), gm))
00735             certList.push_back(tmpCert);
00736 
00737     }while(NULL != cert);
00738 
00739     //free the memory allocated in call to StrToName
00740     //if(NULL != nameBlob.pbData)
00741     //  PKIFDelete(nameBlob.pbData); //changed to PKIFDelete 12/7/2003
00742 
00743     if(origSize != certList.size())
00744     {
00745         #ifndef DISABLE_LOGGING_MACROS
00746         std::ostringstream os;
00747         os << "Found one or more certificates issued by: " << issDN->ToString();
00748         #endif
00749         LOG_STRING_DEBUG(os.str().c_str(), thisComponent, 0, this);
00750     }
00751     else
00752     {
00753         #ifndef DISABLE_LOGGING_MACROS
00754         std::ostringstream os;
00755         os << "Failed to find a certificate issued by: " << issDN->ToString();
00756         #endif
00757         LOG_STRING_INFO(os.str().c_str(), thisComponent, 0, this);
00758     }
00759 }
00770 void CPKIFCAPIRepository2::GetCertificateSources(
00772     const CPKIFCertificatePtr& cert, 
00774     CPKIFCertificateSourceList& certs, 
00776     PathBuildingDirection pbd)
00777 {
00778     CPKIFCertificateList certList;
00779     GetCertificates(cert, certList, LOCAL);
00780 
00781     //only collect this as a source if the list is not empty - else just return
00782     if(!certList.empty())
00783     {
00784         CPKIFLocalCertNodePtr lcn(new CPKIFLocalCertNode(pbd));
00785         lcn->SetState(PAS_AVAILABLE);
00786 
00787         CPKIFCertificateList::iterator pos;
00788         CPKIFCertificateList::iterator end = certList.end();
00789         for(pos = certList.begin(); pos != end; ++pos)
00790         {
00791             CPKIFCertificateNodeEntryPtr certNode(new CPKIFCertificateNodeEntry);
00792             certNode->SetCert(*pos);
00793 
00794             ostringstream ostr;
00795             ostr << "CAPI://";
00796             switch(m_impl->m_nSysStoRegLoc)
00797             {
00798             case CERT_SYSTEM_STORE_CURRENT_USER:
00799                 ostr << "CERT_SYSTEM_STORE_CURRENT_USER";
00800                 break;
00801             case CERT_SYSTEM_STORE_LOCAL_MACHINE:
00802                 ostr << "CERT_SYSTEM_STORE_LOCAL_MACHINE";
00803                 break;
00804             default:
00805                 ostr << m_impl->m_nSysStoRegLoc;
00806                 break;
00807             }
00808             ostr << "/" << m_impl->m_szStore << "/" << cert->Issuer()->ToString() << "/" << cert->SerialNumber() << ends;
00809 
00810             std::string capiURI = ostr.str();
00811             certNode->AddSource(capiURI);   
00812             certNode->SetState(PAS_AVAILABLE);
00813 
00814             lcn->AddSource(capiURI);        
00815             lcn->AddCertificate(certNode);
00816         }
00817 
00818         certs.push_back(lcn);
00819     }
00820 }
00821 
00822 void CPKIFCAPIRepository2::FindCertificates(
00824     IPKIFSearchCriteria* searchCriteria,
00826     CPKIFCertificateList& certList,
00828     PKIInfoSource source)
00829 {
00830     LOG_STRING_DEBUG("CPKIFCAPIUserRepository2::FindCertificates", TOOLKIT_SR_CAPIUSERREPOSITORY, 0, this);
00831 
00832     //ignore requests for remote certificates
00833     if(REMOTE == source || NULL == searchCriteria)
00834     {
00835         LOG_STRING_DEBUG("Skipping CPKIFCAPIUserRepository2 - searching REMOTE sources only or NULL search criteria", thisComponent, 0, this);
00836         return;
00837     }
00838 
00839     void* ptrToSearchCriteria = NULL;
00840     DWORD findType = 0;
00841 
00842     //possible structures
00843     PCCERT_CONTEXT cert = NULL;
00844     CERT_NAME_BLOB nameBlob; 
00845     nameBlob.cbData = 0; 
00846     nameBlob.pbData = NULL;
00847 
00848     CERT_ID certID;
00849     certID.IssuerSerialNumber.Issuer.pbData = NULL;
00850     certID.IssuerSerialNumber.SerialNumber.pbData = NULL;
00851 
00852     switch(searchCriteria->GetSearchType())
00853     {
00854     case ALLCERTS:
00855         findType = CERT_FIND_ANY;
00856         break;
00857     case ISSUERNAME:
00858         {
00859             CPKIFNameBasedSearch* nbs = dynamic_cast<CPKIFNameBasedSearch*>(searchCriteria);
00860             StrToName(nbs->GetStringName(), &nameBlob.pbData, &nameBlob.cbData);
00861             if(0 != nameBlob.cbData)
00862             {
00863                 ptrToSearchCriteria = &nameBlob;
00864                 findType = CERT_FIND_ISSUER_NAME;
00865             }
00866             else
00867                 return;
00868         }
00869         break;
00870     case SUBJECTNAME:
00871         {
00872             CPKIFNameBasedSearch* nbs = dynamic_cast<CPKIFNameBasedSearch*>(searchCriteria);
00873             StrToName(nbs->GetStringName(), &nameBlob.pbData, &nameBlob.cbData);
00874             if(0 != nameBlob.cbData)
00875             {
00876                 ptrToSearchCriteria = &nameBlob;
00877                 findType = CERT_FIND_SUBJECT_NAME;
00878             }
00879             else
00880                 return;
00881         }
00882         break;
00883     case ISSUERSERIAL:
00884         {
00885             CPKIFIssuerNameAndSerialNumberBasedSearch* inasnbs = dynamic_cast<CPKIFIssuerNameAndSerialNumberBasedSearch*>(searchCriteria);
00886             CPKIFNamePtr issuerName = inasnbs->GetIssuerName();
00887             certID.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
00888             StrToName(issuerName->ToString(), &certID.IssuerSerialNumber.Issuer.pbData, &certID.IssuerSerialNumber.Issuer.cbData);
00889             const char* sn = inasnbs->GetSerialNumber();
00890 
00891             size_t len = strlen(sn) - 2;
00892             unsigned int iLen = 0;
00893             if(len > boost::numeric::bounds<unsigned int>::highest())
00894             {
00895                 throw CPKIFCacheException(TOOLKIT_SR_CAPIUSERREPOSITORY, COMMON_INVALID_INPUT, "Serial number too big.");
00896             }
00897             else
00898                 iLen = numeric_cast<unsigned int>(len);
00899 
00900             unsigned char* binSN = new unsigned char[iLen];
00901             atob((char*)binSN, (char*)sn+2, &iLen);
00902             ReverseBytes(binSN, iLen);
00903             certID.IssuerSerialNumber.SerialNumber.cbData = iLen;
00904             certID.IssuerSerialNumber.SerialNumber.pbData = binSN;
00905             ptrToSearchCriteria = &certID;
00906             findType = CERT_FIND_CERT_ID;
00907             break;
00908         }
00909     case KEYID:
00910         {
00911             CPKIFKeyIDBasedSearch* kidbs = dynamic_cast<CPKIFKeyIDBasedSearch*>(searchCriteria);
00912             if(!kidbs)
00913                 return;
00914 
00915             CPKIFBufferPtr kid = kidbs->GetKeyID();
00916 
00917             CRYPT_HASH_BLOB chb;
00918             chb.cbData = kid->GetLength();
00919             chb.pbData = (BYTE*)kid->GetBuffer();
00920 
00921             ptrToSearchCriteria = &chb;
00922             findType = CERT_FIND_KEY_IDENTIFIER;
00923             break;
00924         }
00925     default:
00926         return;
00927     };
00928 
00929     do
00930     {
00931         cert = CertFindCertificateInStore(m_impl->m_hSto, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 
00932             0, findType, ptrToSearchCriteria, cert);
00933         if(NULL == cert)
00934             break;
00935 
00936         //create a CCACCert and stuff it into the list
00937         CPKIFCertificatePtr tmpCert(new CPKIFCertificate);
00938         try
00939         {
00940             tmpCert->Decode(cert->pbCertEncoded, cert->cbCertEncoded);
00941 
00942             GottaMatch<CPKIFCertificatePtr> gm;
00943             gm.SetRHS(tmpCert);
00944             if(certList.end() == find_if(certList.begin(), certList.end(), gm))
00945                 certList.push_back(tmpCert);
00946 
00947 //          certList.push_back(tmpCert); //moved this here from below catch block
00948                                         //else non-parsed certs end up in the list
00949         }
00950         catch(CPKIFException&)
00951         {
00952             //EXCEPTION DELETION
00953             //don't fail due to parse errors - log the failure and continue searching
00954             //if nothing is found that actually parses then an error will be generated
00955             //delete e;
00956 
00957             LOG_STRING_ERROR("Failed to parse certificate from CAPI store." , thisComponent, CACHE_PARSE_ERROR, this)
00958         }
00959     }while(NULL != cert);
00960 
00961     //free the memory allocated in call to StrToName
00962     if(NULL != nameBlob.pbData)
00963         PKIFDelete(nameBlob.pbData); //changed to PKIFDelete 12/7/2003
00964     if(NULL != certID.IssuerSerialNumber.Issuer.pbData)
00965         PKIFDelete(certID.IssuerSerialNumber.Issuer.pbData); //changed to PKIFDelete 12/7/2003
00966     if(NULL != certID.IssuerSerialNumber.SerialNumber.pbData)
00967         PKIFDelete(certID.IssuerSerialNumber.SerialNumber.pbData); //changed to PKIFDelete 12/7/2003
00968 }

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