00001
00009 #include "PKIFCAPIRepository2.h"
00010 #include "CAPIUtils.h"
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
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
00079 DWORD m_ticksCerts;
00080 DWORD m_ticksCRLs;
00081
00082
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
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
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
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;
00214 }
00215
00216
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
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
00264 CPKIFBufferPtr encName = subDN->Encoded();
00265 nameBlob.pbData = (BYTE*)encName->GetBuffer();
00266 nameBlob.cbData = encName->GetLength();
00267
00268
00269
00270
00271
00272
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
00282 CPKIFCertificatePtr tmpCert(new CPKIFCertificate);
00283 try
00284 {
00285 tmpCert->Decode(cert->pbCertEncoded, cert->cbCertEncoded);
00286 }
00287 catch(CPKIFException& )
00288 {
00289
00290
00291
00292
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
00330 }
00331 pPrevCertContext = CertEnumCertificatesInStore(m_impl->m_hSto, pPrevCertContext);
00332 }
00333 }
00334 catch(...)
00335 {
00336 if(NULL != pPrevCertContext)
00337 {
00338
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
00349
00350
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
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
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
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
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
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
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
00620
00621
00622
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
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
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
00713 CPKIFCertificatePtr tmpCert(new CPKIFCertificate);
00714 try
00715 {
00716 tmpCert->Decode(cert->pbCertEncoded, cert->cbCertEncoded);
00717 }
00718 catch(CPKIFException& )
00719 {
00720
00721
00722
00723
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
00740
00741
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
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
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
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
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
00948
00949 }
00950 catch(CPKIFException&)
00951 {
00952
00953
00954
00955
00956
00957 LOG_STRING_ERROR("Failed to parse certificate from CAPI store." , thisComponent, CACHE_PARSE_ERROR, this)
00958 }
00959 }while(NULL != cert);
00960
00961
00962 if(NULL != nameBlob.pbData)
00963 PKIFDelete(nameBlob.pbData);
00964 if(NULL != certID.IssuerSerialNumber.Issuer.pbData)
00965 PKIFDelete(certID.IssuerSerialNumber.Issuer.pbData);
00966 if(NULL != certID.IssuerSerialNumber.SerialNumber.pbData)
00967 PKIFDelete(certID.IssuerSerialNumber.SerialNumber.pbData);
00968 }