00001
00009 #include "PKIFdll.h"
00010
00011 #include "IPKIFColleague.h"
00012 #include "PKIFCRLDPRetrieval.h"
00013 #include "LDAP_URL_Header.h"
00014
00015 #include "Buffer.h"
00016 #include "GeneralName.h"
00017 #include "AuthorityInfoAccess.h"
00018 #include "SubjectInfoAccess.h"
00019 #include "ToolkitUtils.h"
00020
00021 #include "CRLDistributionPoint.h"
00022 #include "CRLDistributionPoints.h"
00023 #include "DistributionPointName.h"
00024 #include "AccessDescription.h"
00025 #include "IssuerAltName.h"
00026 #include "Certificate.h"
00027 #include "GottaMatch.h"
00028 #include "CRL.h"
00029 #include "PKIFHttpCrlNode.h"
00030 #include "PKIFLdapCrlNode.h"
00031
00032 #include "ASN1Helper.h"
00033 #include "CryptographicMessageSyntax2004.h"
00034
00035
00036 #ifdef _DEBUG_URI_DUMP
00037 #include <fstream>
00038 extern ofstream g_uriLogFile;
00039 #endif
00040
00042 struct CPKIFCRLDPRetrievalImpl
00043 {
00044 CPKIFOIDPtr m_oid;
00045 CPKIFBufferList m_content;
00046 };
00048
00056 CPKIFCRLDPRetrieval::CPKIFCRLDPRetrieval(void)
00057 :m_impl (new CPKIFCRLDPRetrievalImpl)
00058 {
00059 LOG_STRING_DEBUG("CPKIFCRLDPRetrieval::CPKIFCRLDPRetrieval(void)", TOOLKIT_OCSP_CHECKER, 0, this);
00060 }
00068 CPKIFCRLDPRetrieval::~CPKIFCRLDPRetrieval(void)
00069 {
00070 LOG_STRING_DEBUG("CPKIFCRLDPRetrieval::~CPKIFCRLDPRetrieval(void)", TOOLKIT_OCSP_CHECKER, 0, this);
00071
00072 delete m_impl;
00073 m_impl = NULL;
00074 }
00075
00083 void CPKIFCRLDPRetrieval::Initialize(void)
00084 {
00085 }
00086
00094 bool RetrieveCRLGivenHTTPURL(
00096 const char* url,
00098 CPKIFCRLList& crlList)
00099 {
00100 LOG_STRING_DEBUG("RetrieveCRLGivenHTTPURL(const char* url, CPKIFCRLList& crlList)", TOOLKIT_OCSP_CHECKER, 0, NULL);
00101
00102 if(NULL == url || 0 == strlen(url))
00103 return false;
00104
00105 bool allIsWell = false;
00106 try
00107 {
00108
00109 #ifdef _DEBUG_URI_DUMP
00110 if(!g_uriLogFile.is_open())
00111 {
00112 g_uriLogFile.open("_DEBUG_URI_DUMP_URILog.txt", ios::out);
00113 }
00114 DWORD __ticks = GetTickCount();
00115 #endif
00116
00117 CPKIFBufferPtr crlBuf;
00118 GetRequest(url, crlBuf);
00119
00120 #ifdef _DEBUG_URI_DUMP
00121 g_uriLogFile << GetTickCount() - __ticks << " milliseconds elapsed retrieving from " << url << endl;
00122 #endif
00123
00124 if(!crlBuf)
00125 return false;
00126
00127
00128
00129 CPKIFCRLPtr crl(new CPKIFCRL());
00130 try
00131 {
00132 crl->Decode(crlBuf->GetBuffer(), crlBuf->GetLength());
00133
00134 GottaMatch<CPKIFCRLPtr> gm;
00135 gm.SetRHS(crl);
00136 if(crlList.end() == find_if(crlList.begin(), crlList.end(), gm))
00137 crlList.push_back(crl);
00138 allIsWell = true;
00139 }
00140 catch(CPKIFException&)
00141 {
00142
00143
00144 }
00145 }
00146 catch(...)
00147 {
00148 allIsWell = false;
00149 }
00150
00151 return allIsWell;
00152 }
00153
00161 void GetCertsfromP7(
00163 CPKIFBufferPtr& buf,
00165 CPKIFCertificateList& certList)
00166 {
00167
00168 if(buf == (CPKIFBuffer*)NULL)
00169 return;
00170
00171 try
00172 {
00173 CACASNWRAPPER_CREATE(CACCMSContentInfo, contentInfo);
00174 CACASNWRAPPER_CREATE(CACCMSSignedData, signedData);
00175
00176 contentInfo.Decode(buf->GetBuffer(), buf->GetLength());
00177 signedData.Decode(contentInfo->content);
00178
00179 if(!signedData->m.certificatesPresent || 0 >= signedData->certificates.count)
00180 return;
00181
00182 DListNode* iter = signedData->certificates.head;
00183 while(NULL != iter)
00184 {
00185
00186
00187
00188 CACCMSCertificateChoices* curChoice = (CACCMSCertificateChoices*)iter->data;
00189 if(T_CACCMSCertificateChoices_certificate != curChoice->t)
00190 {
00191 iter = iter->next;
00192 continue;
00193 }
00194 ASN1OpenType* cert = (ASN1OpenType*)curChoice->u.certificate;
00195
00196 try
00197 {
00198 CPKIFCertificatePtr newCert(new CPKIFCertificate());
00199 newCert->Decode(cert->data, cert->numocts);
00200 certList.push_back(newCert);
00201 }
00202 catch(CPKIFException&)
00203 {
00204
00205 }
00206 catch(std::bad_alloc& ba)
00207 {
00208
00209 certList.clear();
00210 throw ba;
00211 }
00212
00213 iter = iter->next;
00214 }
00215 }
00216 catch(CPKIFException&)
00217 {
00218
00219 }
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 }
00248
00256 bool CAC_API RetrieveCertGivenHTTPURL(
00258 const char* url,
00260 CPKIFCertificateNodeList& certNodeList)
00261 {
00262 LOG_STRING_DEBUG("RetrieveCertGivenHTTPURL(const char* url, CPKIFCertificateNodeList& certNodeList)", TOOLKIT_OCSP_CHECKER, 0, NULL);
00263
00264 if(NULL == url || 0 == strlen(url))
00265 return false;
00266
00267 bool allIsWell = false;
00268 try
00269 {
00270 #ifdef _DEBUG_URI_DUMP
00271 if(!g_uriLogFile.is_open())
00272 {
00273 g_uriLogFile.open("_DEBUG_URI_DUMP_URILog.txt", ios::out);
00274 }
00275 DWORD __ticks = GetTickCount();
00276 #endif
00277
00278 std::string strUrl = url;
00279 CPKIFBufferPtr certBuf;
00280 GetRequest(url, certBuf);
00281
00282 #ifdef _DEBUG_URI_DUMP
00283 g_uriLogFile << GetTickCount() - __ticks << " milliseconds elapsed retrieving from " << url << endl;
00284 #endif
00285
00286 if(!certBuf || !certBuf->GetBuffer() || 0 >= certBuf->GetLength())
00287 return false;
00288
00289
00290
00291 CPKIFCertificatePtr cert(new CPKIFCertificate());
00292 try
00293 {
00294 cert->Decode(certBuf->GetBuffer(), certBuf->GetLength());
00295
00296 CPKIFCertificateNodeEntryPtr certNode(new CPKIFCertificateNodeEntry(cert));
00297 GottaMatch<CPKIFCertificateNodeEntryPtr> gm;
00298 gm.SetRHS(certNode);
00299 if(certNodeList.end() == find_if(certNodeList.begin(), certNodeList.end(), gm))
00300 {
00301 certNode->AddSource(strUrl);
00302 certNode->SetSource(REMOTE);
00303 certNodeList.push_back(certNode);
00304 }
00305 allIsWell = true;
00306 }
00307 catch(CPKIFException&)
00308 {
00309
00310
00311
00312
00313 CPKIFCertificateList certList;
00314 GetCertsfromP7(certBuf, certList);
00315
00316 CPKIFCertificateList::iterator pos;
00317 CPKIFCertificateList::iterator end = certList.end();
00318 for(pos = certList.begin(); pos != end; ++pos)
00319 {
00320 CPKIFCertificateNodeEntryPtr certNode(new CPKIFCertificateNodeEntry(*pos));
00321 GottaMatch<CPKIFCertificateNodeEntryPtr> gm;
00322 gm.SetRHS(certNode);
00323 if(certNodeList.end() == find_if(certNodeList.begin(), certNodeList.end(), gm))
00324 {
00325 certNode->AddSource(strUrl);
00326 certNode->SetSource(REMOTE);
00327 certNodeList.push_back(certNode);
00328 }
00329 }
00330 }
00331 }
00332 catch(...)
00333 {
00334 allIsWell = false;
00335 }
00336
00337 return allIsWell;
00338 }
00339
00353 void CAC_API GetCertsFromIssuerAltName(
00356 CPKIFCertificate& cert,
00358 CPKIFCertificateNodeList& certNodeList,
00360 PKIInfoSource source,
00362 PathBuildingDirection pbd)
00363 {
00364 LOG_STRING_DEBUG("GetCertsFromIssuerAltName(const CPKIFCertificatePtr& cert, CPKIFCertificateNodeList& certNodeList, PKIInfoSource source)", TOOLKIT_OCSP_CHECKER, 0, NULL);
00365
00366 if(LOCAL == source)
00367 return;
00368
00369
00370
00371 CPKIFCertificateNodeList certsFromIAN;
00372 CPKIFGeneralNameList genNames;
00373
00374 if(PBD_FORWARD == pbd)
00375 {
00376 CPKIFIssuerAltNamePtr ian;
00377 CPKIFAuthorityInfoAccessPtr aia;
00378
00379
00380 try
00381 {
00382 ian = cert.GetExtension<CPKIFIssuerAltName>();
00383 aia = cert.GetExtension<CPKIFAuthorityInfoAccess>();
00384 if(ian == (CPKIFIssuerAltNamePtr*)NULL && aia == (CPKIFAuthorityInfoAccess*)NULL)
00385 return;
00386 }
00387 catch(...)
00388 {
00389
00390 return;
00391 }
00392
00393 if(ian != (CPKIFIssuerAltNamePtr*)NULL)
00394 {
00395 ian->GeneralNames(genNames);
00396 }
00397
00398 if(aia != (CPKIFAuthorityInfoAccess*)NULL)
00399 {
00400 CPKIFAccessDescriptionListPtr adl = aia->GetAccessDescriptions();
00401 CPKIFAccessDescriptionList::iterator aPos;
00402 CPKIFAccessDescriptionList::iterator aEnd = adl->end();
00403 for(aPos = adl->begin(); aPos != aEnd; ++aPos)
00404 {
00405 CPKIFOIDPtr aOID = (*aPos)->AccessMethod();
00406 if(aOID != (CPKIFOID*)NULL && *aOID == *g_aiaCAIssuer)
00407 {
00408 CPKIFGeneralNamePtr aGN = (*aPos)->AccessLocation();
00409 genNames.push_back(aGN);
00410 }
00411 }
00412 }
00413 }
00414 else
00415 {
00416 CPKIFSubjectInfoAccessPtr sia;
00417 try
00418 {
00419 sia = cert.GetExtension<CPKIFSubjectInfoAccess>();
00420 if(sia == (CPKIFSubjectInfoAccess*)NULL)
00421 return;
00422 }
00423 catch(...)
00424 {
00425
00426 return;
00427 }
00428
00429 if(sia != (CPKIFSubjectInfoAccess*)NULL)
00430 {
00431 CPKIFAccessDescriptionListPtr adl = sia->GetAccessDescriptions();
00432 CPKIFAccessDescriptionList::iterator aPos;
00433 CPKIFAccessDescriptionList::iterator aEnd = adl->end();
00434 for(aPos = adl->begin(); aPos != aEnd; ++aPos)
00435 {
00436 CPKIFOIDPtr aOID = (*aPos)->AccessMethod();
00437 if(aOID != (CPKIFOID*)NULL && *aOID == *g_aiaCARepository)
00438 {
00439 CPKIFGeneralNamePtr aGN = (*aPos)->AccessLocation();
00440 genNames.push_back(aGN);
00441 }
00442 }
00443 }
00444 }
00445
00446 CPKIFGeneralNameList::iterator gnPos;
00447 CPKIFGeneralNameList::iterator gnEnd = genNames.end();
00448 for(gnPos = genNames.begin(); gnPos != gnEnd; ++gnPos)
00449 {
00450
00451 const char* url = (*gnPos)->uri();
00452 if(url != NULL)
00453 {
00454 std::string urlStr = url;
00455 if(0 == urlStr.find("ldap"))
00456 {
00457
00458 GetCertfromLDAPURL((char*)url, certsFromIAN, pbd);
00459 }
00460 else if(0 == urlStr.find("http"))
00461 {
00462
00463 RetrieveCertGivenHTTPURL(url, certsFromIAN);
00464 }
00465 }
00466 }
00467
00468 CPKIFCertificateNodeList::iterator pos;
00469 CPKIFCertificateNodeList::iterator end = certsFromIAN.end();
00470 for(pos = certsFromIAN.begin(); pos != end; ++pos)
00471 {
00472 GottaMatch<CPKIFCertificateNodeEntryPtr> gm;
00473 gm.SetRHS(*pos);
00474 if(certNodeList.end() == find_if(certNodeList.begin(), certNodeList.end(), gm))
00475 {
00476 (*pos)->SetSource(REMOTE);
00477 certNodeList.push_back(*pos);
00478 }
00479 }
00480 }
00481
00493 void CPKIFCRLDPRetrieval::GetCRLs(
00495 const CPKIFCertificatePtr& cert,
00497 CPKIFCRLList& crlList,
00499 PKIInfoSource source)
00500 {
00501 LOG_STRING_DEBUG("CPKIFCRLDPRetrieval::GetCRLs(const CPKIFCertificatePtr& cert, CPKIFCRLList& crlList, PKIInfoSource source)", TOOLKIT_OCSP_CHECKER, 0, this);
00502
00503
00504 if(LOCAL == source)
00505 return;
00506
00507
00508 CPKIFCRLDistributionPointsPtr crlDPs = cert->GetExtension<CPKIFCRLDistributionPoints>();
00509 if(crlDPs == (CPKIFCRLDistributionPoints*)NULL)
00510 return;
00511
00512
00513 CPKIFCRLDistributionPointListPtr dps = crlDPs->DPs();
00514 if(dps == (CPKIFCRLDistributionPointList*)NULL)
00515 return;
00516
00517
00518 CPKIFCRLDistributionPointList::iterator pos;
00519 CPKIFCRLDistributionPointList::iterator end = dps->end();
00520 for(pos = dps->begin(); pos != end; ++pos)
00521 {
00522 CPKIFDistributionPointNamePtr dp = (*pos)->DistributionPoint();
00523 if(dp != (CPKIFDistributionPointName*)NULL)
00524 {
00525
00526 CPKIFGeneralNameList gns;
00527 dp->FullName(gns);
00528
00529
00530 CPKIFGeneralNameList::iterator gnPos;
00531 CPKIFGeneralNameList::iterator gnEnd = gns.end();
00532 for(gnPos = gns.begin(); gnPos != gnEnd; ++gnPos)
00533 {
00534
00535 const char* url = (*gnPos)->uri();
00536 if(url != NULL)
00537 {
00538 std::string urlStr = url;
00539 if(0 == urlStr.find("http"))
00540 {
00541
00542 RetrieveCRLGivenHTTPURL(url, crlList);
00543 }
00544 else
00545 {
00546
00547 GetCRLfromLDAPURL(url, crlList);
00548 }
00549 }
00550 }
00551 }
00552
00553
00554 CPKIFGeneralNameList gns;
00555 (*pos)->CRLIssuer(gns);
00556
00557
00558 CPKIFGeneralNameList::iterator gnPos;
00559 CPKIFGeneralNameList::iterator gnEnd = gns.end();
00560 for(gnPos = gns.begin(); gnPos != gnEnd; ++gnPos)
00561 {
00562
00563 const char* url = (*gnPos)->uri();
00564 if(url != NULL)
00565 {
00566 std::string urlStr = url;
00567 if(0 == urlStr.find("http"))
00568 {
00569
00570 RetrieveCRLGivenHTTPURL(url, crlList);
00571 }
00572 else
00573 {
00574
00575 GetCRLfromLDAPURL(url, crlList);
00576 }
00577 }
00578 }
00579
00580 }
00581 }
00590 void CPKIFCRLDPRetrieval::GetCRLSources(
00592 const CPKIFCertificatePtr& cert,
00594 CPKIFCrlSourceList& crlNodeList,
00596 PKIInfoSource source)
00597 {
00598 LOG_STRING_DEBUG("CPKIFCRLDPRetrieval::GetCRLs(const CPKIFCertificatePtr& cert, CPKIFCRLList& crlList, PKIInfoSource source)", TOOLKIT_OCSP_CHECKER, 0, this);
00599
00600
00601 if(LOCAL == source)
00602 return;
00603
00604
00605 CPKIFCRLDistributionPointsPtr crlDPs = cert->GetExtension<CPKIFCRLDistributionPoints>();
00606 if(crlDPs == (CPKIFCRLDistributionPoints*)NULL)
00607 return;
00608
00609
00610 CPKIFCRLDistributionPointListPtr dps = crlDPs->DPs();
00611 if(dps == (CPKIFCRLDistributionPointList*)NULL)
00612 return;
00613
00614
00615 CPKIFCRLDistributionPointList::iterator pos;
00616 CPKIFCRLDistributionPointList::iterator end = dps->end();
00617 for(pos = dps->begin(); pos != end; ++pos)
00618 {
00619 CPKIFDistributionPointNamePtr dp = (*pos)->DistributionPoint();
00620 if(dp != (CPKIFDistributionPointName*)NULL)
00621 {
00622
00623 CPKIFGeneralNameList gns;
00624 dp->FullName(gns);
00625
00626
00627 CPKIFGeneralNameList::iterator gnPos;
00628 CPKIFGeneralNameList::iterator gnEnd = gns.end();
00629 for(gnPos = gns.begin(); gnPos != gnEnd; ++gnPos)
00630 {
00631
00632 const char* url = (*gnPos)->uri();
00633 if(url != NULL)
00634 {
00635 std::string urlStr = url;
00636 if(0 == urlStr.find("http"))
00637 {
00638 if(!UriAlreadyInList(crlNodeList, urlStr))
00639 {
00640 CPKIFHttpCrlNodePtr httpCrlNode(new CPKIFHttpCrlNode);
00641 httpCrlNode->AddSource(urlStr);
00642 crlNodeList.push_back(httpCrlNode);
00643 }
00644 }
00645 else if(0 == urlStr.find("ldap"))
00646 {
00647 if(!UriAlreadyInList(crlNodeList, urlStr))
00648 {
00649 CPKIFLdapCrlNodePtr ldapCrlNode(new CPKIFLdapCrlNode);
00650 ldapCrlNode->AddSource(urlStr);
00651 crlNodeList.push_back(ldapCrlNode);
00652 }
00653 }
00654 }
00655 }
00656 }
00657
00658
00659 CPKIFGeneralNameList gns;
00660 (*pos)->CRLIssuer(gns);
00661
00662
00663 CPKIFGeneralNameList::iterator gnPos;
00664 CPKIFGeneralNameList::iterator gnEnd = gns.end();
00665 for(gnPos = gns.begin(); gnPos != gnEnd; ++gnPos)
00666 {
00667
00668 const char* url = (*gnPos)->uri();
00669 if(url != NULL)
00670 {
00671 std::string urlStr = url;
00672 if(0 == urlStr.find("http"))
00673 {
00674 if(!UriAlreadyInList(crlNodeList, urlStr))
00675 {
00676 CPKIFHttpCrlNodePtr httpCrlNode(new CPKIFHttpCrlNode);
00677 httpCrlNode->AddSource(urlStr);
00678 crlNodeList.push_back(httpCrlNode);
00679 }
00680 }
00681 else if(0 == urlStr.find("ldap"))
00682 {
00683 if(!UriAlreadyInList(crlNodeList, urlStr))
00684 {
00685 CPKIFLdapCrlNodePtr ldapCrlNode(new CPKIFLdapCrlNode);
00686 ldapCrlNode->AddSource(urlStr);
00687 crlNodeList.push_back(ldapCrlNode);
00688 }
00689 }
00690 }
00691 }
00692
00693 }
00694 }