PKIFCAPIUserRepository2.cpp

Go to the documentation of this file.
00001 
00010 #include "CAPIUtils.h" //added here 7/29/2004
00011 #include "PKIFCAPIUserRepository2.h"
00012 #include "ToolkitUtils.h"
00013 #include "PKIFCacheErrors.h"
00014 #include "PKIFCacheException.h"
00015 
00016 #include "Certificate.h"
00017 #include "GottaMatch.h"
00018 #include "Name.h"
00019 #include "Buffer.h"
00020 #include "KeyIDBasedSearch.h"
00021 #include "NameBasedSearch.h"
00022 #include "IssuerNameAndSerialNumberBasedSearch.h"
00023 
00024 #include "boost/numeric/conversion/cast.hpp"
00025 #include "boost/numeric/conversion/bounds.hpp"
00026 #include "boost/limits.hpp"
00027 
00028 using boost::numeric_cast;
00029 using boost::bad_numeric_cast;
00030 
00031 #include <atlbase.h>
00032 #include <sstream>
00033 
00035 struct CPKIFCAPIUserRepository2Impl
00036 {
00037     HCERTSTORE m_hSto;
00038     int m_nSysStoRegLoc;
00039     char* m_szStore;
00040 };
00042 
00060 CPKIFCAPIUserRepository2::CPKIFCAPIUserRepository2(
00062     int sysStoRegLoc,
00064     const char* store)
00065     : m_impl(new CPKIFCAPIUserRepository2Impl), IPKIFCAPISource(sysStoRegLoc, store)
00066 {
00067     LOG_STRING_DEBUG("CPKIFCAPIUserRepository2::CPKIFCAPIUserRepository2(void)", TOOLKIT_SR_CAPIUSERREPOSITORY, 0, this);
00068 
00069     m_impl->m_hSto = NULL;
00070 
00071     m_impl->m_nSysStoRegLoc = sysStoRegLoc;
00072 
00073     m_impl->m_szStore = NULL;
00074     size_t len = 0;
00075     if(store)
00076     {
00077         len = strlen(store);
00078         m_impl->m_szStore = new char[len + 1];
00079 
00080         //reviewed 4/24
00081         strcpy(m_impl->m_szStore, store);
00082     }
00083 }
00091 CPKIFCAPIUserRepository2::~CPKIFCAPIUserRepository2(void)
00092 {
00093     LOG_STRING_DEBUG("CPKIFCAPIUserRepository2::~CPKIFCAPIUserRepository2(void)", TOOLKIT_SR_CAPIUSERREPOSITORY, 0, this);
00094 
00095     if(m_impl->m_szStore)
00096         delete[] m_impl->m_szStore;
00097 
00098     if(NULL != m_impl->m_hSto)
00099     {
00100         CertCloseStore(m_impl->m_hSto, 0); m_impl->m_hSto = NULL;
00101     }
00102     delete m_impl;
00103     m_impl = NULL;
00104 }
00116 void CPKIFCAPIUserRepository2::Initialize(void)
00117 {
00118     LOG_STRING_DEBUG("CPKIFCAPIUserRepository2::Initialize(void)", TOOLKIT_SR_CAPIUSERREPOSITORY, 0, this);
00119 
00120     if(NULL != m_impl->m_hSto)
00121     {
00122         LOG_STRING_WARN("Skipping initialization - CPKIFCAPIUserRepository2 instance already initialized", TOOLKIT_SR_CAPIREPOSITORY, COMMON_ALREADY_INITIALIZED, this);
00123         return; //already initialized - just log it, return and don't bother with exception
00124     }
00125 
00126     USES_CONVERSION;
00127     m_impl->m_hSto =  CertOpenStore(CERT_STORE_PROV_SYSTEM, X509_ASN_ENCODING, NULL, 
00128                                 CERT_STORE_OPEN_EXISTING_FLAG | m_impl->m_nSysStoRegLoc , T2OLE(m_impl->m_szStore));
00129     if(NULL == m_impl->m_hSto)
00130     {
00131         std::ostringstream os;
00132         os << "CertOpenStore failed: " << GetLastError();
00133         RAISE_CACHE_EXCEPTION(os.str().c_str(), thisComponent, CACHE_CERT_STORE_OPEN_FAILED, this)
00134     }
00135 }
00150 void CPKIFCAPIUserRepository2::FindCertificates(
00152     IPKIFSearchCriteria* searchCriteria,
00154     CPKIFCertificateList& certList,
00156     PKIInfoSource source)
00157 {
00158     LOG_STRING_DEBUG("CPKIFCAPIUserRepository2::FindCertificates", TOOLKIT_SR_CAPIUSERREPOSITORY, 0, this);
00159 
00160     //ignore requests for remote certificates
00161     if(REMOTE == source || NULL == searchCriteria)
00162     {
00163         LOG_STRING_DEBUG("Skipping CPKIFCAPIUserRepository2 - searching REMOTE sources only or NULL search criteria", thisComponent, 0, this);
00164         return;
00165     }
00166 
00167     void* ptrToSearchCriteria = NULL;
00168     DWORD findType = 0;
00169 
00170     //possible structures
00171     PCCERT_CONTEXT cert = NULL;
00172     CERT_NAME_BLOB nameBlob; 
00173     nameBlob.cbData = 0; 
00174     nameBlob.pbData = NULL;
00175 
00176     CERT_ID certID;
00177     certID.IssuerSerialNumber.Issuer.pbData = NULL;
00178     certID.IssuerSerialNumber.SerialNumber.pbData = NULL;
00179 
00180     switch(searchCriteria->GetSearchType())
00181     {
00182     case ALLCERTS:
00183         findType = CERT_FIND_ANY;
00184         break;
00185     case ISSUERNAME:
00186         {
00187             CPKIFNameBasedSearch* nbs = dynamic_cast<CPKIFNameBasedSearch*>(searchCriteria);
00188             StrToName(nbs->GetStringName(), &nameBlob.pbData, &nameBlob.cbData);
00189             if(0 != nameBlob.cbData)
00190             {
00191                 ptrToSearchCriteria = &nameBlob;
00192                 findType = CERT_FIND_ISSUER_NAME;
00193             }
00194             else
00195                 return;
00196         }
00197         break;
00198     case SUBJECTNAME:
00199         {
00200             CPKIFNameBasedSearch* nbs = dynamic_cast<CPKIFNameBasedSearch*>(searchCriteria);
00201             StrToName(nbs->GetStringName(), &nameBlob.pbData, &nameBlob.cbData);
00202             if(0 != nameBlob.cbData)
00203             {
00204                 ptrToSearchCriteria = &nameBlob;
00205                 findType = CERT_FIND_SUBJECT_NAME;
00206             }
00207             else
00208                 return;
00209         }
00210         break;
00211     case ISSUERSERIAL:
00212         {
00213             CPKIFIssuerNameAndSerialNumberBasedSearch* inasnbs = dynamic_cast<CPKIFIssuerNameAndSerialNumberBasedSearch*>(searchCriteria);
00214             CPKIFNamePtr issuerName = inasnbs->GetIssuerName();
00215             certID.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
00216             StrToName(issuerName->ToString(), &certID.IssuerSerialNumber.Issuer.pbData, &certID.IssuerSerialNumber.Issuer.cbData);
00217             const char* sn = inasnbs->GetSerialNumber();
00218 
00219             size_t len = strlen(sn) - 2;
00220             unsigned int iLen = 0;
00221             if(len > boost::numeric::bounds<unsigned int>::highest())
00222             {
00223                 throw CPKIFCacheException(TOOLKIT_SR_CAPIUSERREPOSITORY, COMMON_INVALID_INPUT, "Serial number too big.");
00224             }
00225             else
00226                 iLen = numeric_cast<unsigned int>(len);
00227 
00228             unsigned char* binSN = new unsigned char[iLen];
00229             atob((char*)binSN, (char*)sn+2, &iLen);
00230             ReverseBytes(binSN, iLen);
00231             certID.IssuerSerialNumber.SerialNumber.cbData = iLen;
00232             certID.IssuerSerialNumber.SerialNumber.pbData = binSN;
00233             ptrToSearchCriteria = &certID;
00234             findType = CERT_FIND_CERT_ID;
00235             break;
00236         }
00237     case KEYID:
00238         {
00239             CPKIFKeyIDBasedSearch* kidbs = dynamic_cast<CPKIFKeyIDBasedSearch*>(searchCriteria);
00240             if(!kidbs)
00241                 return;
00242 
00243             CPKIFBufferPtr kid = kidbs->GetKeyID();
00244 
00245             CRYPT_HASH_BLOB chb;
00246             chb.cbData = kid->GetLength();
00247             chb.pbData = (BYTE*)kid->GetBuffer();
00248 
00249             ptrToSearchCriteria = &chb;
00250             findType = CERT_FIND_KEY_IDENTIFIER;
00251             break;
00252         }
00253     default:
00254         return;
00255     };
00256 
00257     do
00258     {
00259         cert = CertFindCertificateInStore(m_impl->m_hSto, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 
00260             0, findType, ptrToSearchCriteria, cert);
00261         if(NULL == cert)
00262             break;
00263 
00264         //create a CCACCert and stuff it into the list
00265         CPKIFCertificatePtr tmpCert(new CPKIFCertificate);
00266         try
00267         {
00268             tmpCert->Decode(cert->pbCertEncoded, cert->cbCertEncoded);
00269 
00270             GottaMatch<CPKIFCertificatePtr> gm;
00271             gm.SetRHS(tmpCert);
00272             if(certList.end() == find_if(certList.begin(), certList.end(), gm))
00273                 certList.push_back(tmpCert);
00274 
00275 //          certList.push_back(tmpCert); //moved this here from below catch block
00276                                         //else non-parsed certs end up in the list
00277         }
00278         catch(CPKIFException&)
00279         {
00280             //EXCEPTION DELETION
00281             //don't fail due to parse errors - log the failure and continue searching
00282             //if nothing is found that actually parses then an error will be generated
00283             //delete e;
00284 
00285             LOG_STRING_ERROR("Failed to parse certificate from CAPI store." , thisComponent, CACHE_PARSE_ERROR, this)
00286         }
00287     }while(NULL != cert);
00288 
00289     //free the memory allocated in call to StrToName
00290     if(NULL != nameBlob.pbData)
00291         PKIFDelete(nameBlob.pbData); //changed to PKIFDelete 12/7/2003
00292     if(NULL != certID.IssuerSerialNumber.Issuer.pbData)
00293         PKIFDelete(certID.IssuerSerialNumber.Issuer.pbData); //changed to PKIFDelete 12/7/2003
00294     if(NULL != certID.IssuerSerialNumber.SerialNumber.pbData)
00295         PKIFDelete(certID.IssuerSerialNumber.SerialNumber.pbData); //changed to PKIFDelete 12/7/2003
00296 }

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