00001
00009 #include "CRL.h"
00010 #include "CapiCRL.h"
00011 #include "CRLEntry.h"
00012 #include "ASN1Helper.h"
00013 #include "Certificate.h"
00014 #include "Buffer.h"
00015 #include "Name.h"
00016 #include "PKIFTime.h"
00017 #include "AlgorithmIdentifier.h"
00018 #include "ExtensionsMatch.h"
00019 #include "PKIFException.h"
00020 #include "PKIFX509Extensions2.h"
00021 #include "IssuingDistributionPoint.h"
00022 #include "CertificateIssuer.h"
00023 #include "GeneralName.h"
00024 #include "PKIFBase64.h"
00025 #include <sstream>
00026 #include "PKIFCommonErrors.h"
00027 #include "ToolkitUtils.h"
00028
00029 using namespace std;
00030 using namespace boost;
00031
00033 struct CPKIFCapiCRLImpl
00034 {
00042 CPKIFCapiCRLImpl();
00043
00044
00045 void ClearContent();
00046
00047 void populateExtensionsVector();
00048
00049 CPKIFBufferPtr m_rawCRL;
00050
00051 std::vector<CPKIFX509ExtensionPtr> m_exts;
00052 std::vector<pair<CPKIFNamePtr, std::map<std::string, CPKIFCRLEntryPtr> > > m_vector;
00053 CPKIFNamePtr m_issuer;
00054 CPKIFTimePtr m_nextUpdate;
00055 CPKIFTimePtr m_thisUpdate;
00056 CPKIFAlgorithmIdentifierPtr m_sigAlg;
00057 CPKIFCapiCRL * m_this;
00058
00059 CPKIFBufferPtr m_signature;
00060
00061 PCCRL_CONTEXT m_crl;
00062 };
00063
00071 CPKIFCapiCRLImpl::CPKIFCapiCRLImpl ()
00072 {
00073 m_crl = NULL;
00074 }
00075
00076
00084 void CPKIFCapiCRLImpl::ClearContent()
00085 {
00086 CPKIFBufferPtr tmpBuf;
00087 m_rawCRL = tmpBuf;
00088
00089 m_exts.clear();
00090
00091 CPKIFNamePtr tmpIss;
00092 m_issuer = tmpIss;
00093 CPKIFTimePtr tmpNext;
00094 m_nextUpdate = tmpNext;
00095 CPKIFTimePtr tmpThis;
00096 m_thisUpdate = tmpThis;
00097 CPKIFAlgorithmIdentifierPtr tmpSig;
00098 m_sigAlg = tmpSig;
00099 }
00100
00101
00114 void CPKIFCapiCRLImpl::populateExtensionsVector()
00115 {
00116
00117 if(!m_exts.empty())
00118 return;
00119
00120
00121 if(0 == m_crl->pCrlInfo->cExtension)
00122 {
00123 m_exts.clear();
00124 return;
00125 }
00126
00127
00128
00129 CPKIFX509ExtensionMediator2 * mediator = CPKIFX509ExtensionMediator2::GetInstance();
00130 m_this->IPKIFHasExtensions::GetExtensions (mediator, m_exts);
00131 }
00132
00134
00143 void CPKIFCapiCRL::GetExtensionByOID(
00145 const CPKIFOID& oid,
00147 CPKIFX509ExtensionPtr& ref)
00148 {
00149 if(m_impl->m_exts.empty() && m_impl->m_crl->pCrlInfo->cExtension)
00150 m_impl->populateExtensionsVector();
00151
00152 vector<CPKIFX509ExtensionPtr>::iterator pos;
00153 vector<CPKIFX509ExtensionPtr>::iterator end = m_impl->m_exts.end();
00154 for(pos = m_impl->m_exts.begin(); pos != end; ++pos)
00155 {
00156 if(oid == (*pos)->oid())
00157 {
00158 ref = *pos;
00159 return;
00160 }
00161 }
00162 }
00171 void CPKIFCapiCRL::GetEncodedExtensions (
00173 CPKIFBufferPtr& buf)
00174 {
00175 try
00176 {
00177 HRESULT hr= S_OK;
00178 if(m_impl->m_crl->pCrlInfo->cExtension)
00179 {
00180 _CERT_EXTENSIONS ce;
00181 ce.cExtension = m_impl->m_crl->pCrlInfo->cExtension;
00182 ce.rgExtension = m_impl->m_crl->pCrlInfo->rgExtension;
00183 unsigned char* pvEncoded = NULL;
00184 DWORD pcbEncoded = 0;
00185 CryptEncodeObjectEx(X509_ASN_ENCODING, X509_EXTENSIONS, &ce, 0, NULL, NULL, &pcbEncoded);
00186 pvEncoded = new unsigned char[pcbEncoded];
00187 if(CryptEncodeObjectEx(X509_ASN_ENCODING, X509_EXTENSIONS, &ce, 0, NULL, pvEncoded, &pcbEncoded))
00188 {
00189 CPKIFBufferPtr encodedExtensions(new CPKIFBuffer(pvEncoded, pcbEncoded));
00190 buf = encodedExtensions;
00191 delete[] pvEncoded;
00192 return;
00193 }
00194 else
00195 {
00196 delete[] pvEncoded;
00197 hr = GetLastError();
00198 }
00199 }
00200 }
00201 catch (... )
00202 {
00203
00204 }
00205
00206 CPKIFBufferPtr nullExt;
00207 buf = nullExt;
00208 }
00209
00217 CPKIFCapiCRL::CPKIFCapiCRL(void): m_impl (new CPKIFCapiCRLImpl)
00218 {
00219 m_impl->m_this = this;
00220 }
00228 CPKIFCapiCRL::~CPKIFCapiCRL(void)
00229 {
00230 if(m_impl)
00231 {
00232 if(m_impl->m_crl)
00233 {
00234 CertFreeCRLContext(m_impl->m_crl);
00235 m_impl->m_crl = NULL;
00236 }
00237
00238 delete m_impl;
00239 m_impl = 0;
00240 }
00241 }
00242
00243
00251 void CPKIFCapiCRL::Decode(
00253 const unsigned char* cert,
00255 int certLen)
00256 {
00257 throw std::exception("CPKIFCapiCRL::Decode has not been implemented.");
00258 }
00259
00270 int CPKIFCapiCRL::Version() const
00271 {
00272 switch( m_impl->m_crl->pCrlInfo->dwVersion )
00273 {
00274 case CRL_V1:
00275 return 1;
00276 break;
00277 case CRL_V2:
00278 return 2;
00279 break;
00280 default:
00281 throw CPKIFException(TOOLKIT_ASN, COMMON_UNSUPPORTED_VERSION, "Unsupported CRL version.");
00282 }
00283 }
00293 CPKIFNamePtr CPKIFCapiCRL::Issuer( ) const
00294 {
00295 if(m_impl->m_issuer == (CPKIFName*)NULL)
00296 {
00297 CPKIFBufferPtr tmpBuf;
00298 tmpBuf = CPKIFBufferPtr(new CPKIFBuffer(m_impl->m_crl->pCrlInfo->Issuer.pbData, m_impl->m_crl->pCrlInfo->Issuer.cbData));
00299
00300 CPKIFName* tmpName = new CPKIFName(tmpBuf);
00301 CPKIFNamePtr tmpRef(tmpName);
00302
00303 CPKIFCapiCRL* nonConstCert = const_cast<CPKIFCapiCRL*>(this);
00304 nonConstCert->m_impl->m_issuer = tmpRef;
00305 }
00306
00307 return m_impl->m_issuer;
00308 }
00319 CPKIFBufferPtr CPKIFCapiCRL::Encoded() const
00320 {
00321 if(!m_impl->m_rawCRL)
00322 {
00323 CPKIFBufferPtr tmp(new CPKIFBuffer(m_impl->m_crl->pbCrlEncoded, m_impl->m_crl->cbCrlEncoded));
00324 m_impl->m_rawCRL = tmp;
00325 }
00326 return m_impl->m_rawCRL;
00327 }
00328
00340 bool CPKIFCapiCRL::CertOnThisCRL(
00342 const CPKIFCertificatePtr& cert,
00344 CPKIFCRLEntryPtr& crlEntry)
00345 {
00346 PCCERT_CONTEXT certCtx = NULL;
00347
00348 if(cert == (CPKIFCertificate*)NULL)
00349 {
00350 throw CPKIFException(TOOLKIT_ASN_SUBCOMPONENT, COMMON_INVALID_INPUT, "NULL certificate passed to CertOnThisCRL.");
00351 }
00352
00353 certCtx = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, cert->Encoded()->GetBuffer(), cert->Encoded()->GetLength());
00354 if(NULL == certCtx)
00355 {
00356 std::ostringstream os;
00357 os << "Failed to parse certificate passed to CertOnThisCRL. CertCreateCertificateContext failed: " << GetLastError();
00358 throw CPKIFException(TOOLKIT_ASN_SUBCOMPONENT, COMMON_INVALID_INPUT, os.str().c_str());
00359 }
00360
00361 PCRL_ENTRY pCrlEntry = NULL;
00362 if(CertFindCertificateInCRL(certCtx, m_impl->m_crl, 0, 0, &pCrlEntry))
00363 {
00364 if(pCrlEntry)
00365 {
00366 CPKIFCapiCRLEntryPtr capiCRLEntry(new CPKIFCapiCRLEntry(pCrlEntry));
00367 CPKIFCRLEntryPtr rv = dynamic_pointer_cast<CPKIFCRLEntry, CPKIFCapiCRLEntry>(capiCRLEntry);
00368 crlEntry = rv;
00369 return true;
00370 }
00371 else
00372 return false;
00373 }
00374 else
00375 {
00376 throw std::exception("Failed to search CRL");
00377 }
00378 }
00386 CPKIFBufferPtr CPKIFCapiCRL::Signature() const
00387 {
00388 if(m_impl->m_signature == (CPKIFBuffer*)NULL)
00389 {
00390 CACASNWRAPPER_CREATE(CACX509V3CertificateList, objPDU);
00391 CACX509V3CertificateList* tc = objPDU.Decode(m_impl->m_crl->pbCrlEncoded, m_impl->m_crl->cbCrlEncoded);
00392
00393 CPKIFBufferPtr tmp(new CPKIFBuffer(tc->signature.data, tc->signature.numbits/8));
00394 CPKIFCapiCRL* nonConstCert = const_cast<CPKIFCapiCRL*>(this);
00395 nonConstCert->m_impl->m_signature = tmp;
00396 }
00397 return m_impl->m_signature;
00398 }
00408 CPKIFTimePtr CPKIFCapiCRL::NextUpdate( ) const
00409 {
00410 if(m_impl->m_nextUpdate == (CPKIFTime*)NULL)
00411 {
00412 unsigned char* pvEncoded = NULL;
00413 DWORD pcbEncoded = 0;
00414 CryptEncodeObjectEx(X509_ASN_ENCODING, X509_CHOICE_OF_TIME, &m_impl->m_crl->pCrlInfo->NextUpdate, 0, NULL, NULL, &pcbEncoded);
00415 pvEncoded = new unsigned char[pcbEncoded];
00416 if(CryptEncodeObjectEx(X509_ASN_ENCODING, X509_CHOICE_OF_TIME, &m_impl->m_crl->pCrlInfo->NextUpdate, 0, NULL, pvEncoded, &pcbEncoded))
00417 {
00418 CACASNWRAPPER_CREATE(CACX509V3Time, objPDU);
00419 CACX509V3Time* time = objPDU.Decode(pvEncoded, pcbEncoded);
00420 delete[] pvEncoded;
00421
00422 CPKIFTime* tmpTime = NULL;
00423 if(time->t == T_CACX509V3Time_utcTime)
00424 {
00425 tmpTime = new CPKIFTime(time->u.utcTime, UTCTIME);
00426 }
00427 else
00428 {
00429 tmpTime = new CPKIFTime(time->u.generalTime, GENERALIZEDTIME);
00430 }
00431 CPKIFTimePtr tmpRef(tmpTime);
00432
00433 CPKIFCapiCRL* nonConstCert = const_cast<CPKIFCapiCRL*>(this);
00434 nonConstCert->m_impl->m_nextUpdate = tmpRef;
00435 }
00436 else
00437 {
00438 delete[] pvEncoded;
00439 HRESULT hr = GetLastError();
00440 }
00441 }
00442
00443 return m_impl->m_nextUpdate;
00444 }
00454 CPKIFTimePtr CPKIFCapiCRL::ThisUpdate( ) const
00455 {
00456 if(m_impl->m_thisUpdate == (CPKIFTime*)NULL)
00457 {
00458 unsigned char* pvEncoded = NULL;
00459 DWORD pcbEncoded = 0;
00460 CryptEncodeObjectEx(X509_ASN_ENCODING, X509_CHOICE_OF_TIME, &m_impl->m_crl->pCrlInfo->ThisUpdate, 0, NULL, pvEncoded, &pcbEncoded);
00461 pvEncoded = new unsigned char[pcbEncoded];
00462 if(CryptEncodeObjectEx(X509_ASN_ENCODING, X509_CHOICE_OF_TIME, &m_impl->m_crl->pCrlInfo->ThisUpdate, 0, NULL, pvEncoded, &pcbEncoded))
00463 {
00464 CACASNWRAPPER_CREATE(CACX509V3Time, objPDU);
00465 CACX509V3Time* time = objPDU.Decode(pvEncoded, pcbEncoded);
00466 delete[] pvEncoded;
00467
00468 CPKIFTime* tmpTime = NULL;
00469 if(time->t == T_CACX509V3Time_utcTime)
00470 {
00471 tmpTime = new CPKIFTime(time->u.utcTime, UTCTIME);
00472 }
00473 else
00474 {
00475 tmpTime = new CPKIFTime(time->u.generalTime, GENERALIZEDTIME);
00476 }
00477 CPKIFTimePtr tmpRef(tmpTime);
00478
00479 CPKIFCapiCRL* nonConstCert = const_cast<CPKIFCapiCRL*>(this);
00480 nonConstCert->m_impl->m_thisUpdate = tmpRef;
00481 }
00482 else
00483 {
00484 delete[] pvEncoded;
00485 HRESULT hr = GetLastError();
00486 }
00487 }
00488
00489 return m_impl->m_thisUpdate;
00490 }
00500 CPKIFAlgorithmIdentifierPtr CPKIFCapiCRL::SignatureAlgorithm( ) const
00501 {
00502 if(m_impl->m_sigAlg == (CPKIFAlgorithmIdentifier*)NULL)
00503 {
00504 CPKIFOIDPtr algOID(new CPKIFOID(m_impl->m_crl->pCrlInfo->SignatureAlgorithm.pszObjId));
00505
00506 CPKIFBufferPtr paramBuf;
00507 if(m_impl->m_crl->pCrlInfo->SignatureAlgorithm.Parameters.cbData)
00508 {
00509 paramBuf = CPKIFBufferPtr(new CPKIFBuffer(m_impl->m_crl->pCrlInfo->SignatureAlgorithm.Parameters.pbData,
00510 m_impl->m_crl->pCrlInfo->SignatureAlgorithm.Parameters.cbData));
00511
00512 }
00513
00514 CPKIFAlgorithmIdentifierPtr tmpRef(new CPKIFAlgorithmIdentifier(algOID, paramBuf));
00515
00516 CPKIFCapiCRL* nonConstCert = const_cast<CPKIFCapiCRL*>(this);
00517 nonConstCert->m_impl->m_sigAlg = tmpRef;
00518 }
00519
00520 return m_impl->m_sigAlg;
00521 }
00530 bool CPKIFCapiCRL::AreThereAnyUnprocessedCriticalExtensions(
00532 std::vector<CPKIFX509ExtensionPtr>& processedExts)
00533 {
00534 std::vector<CPKIFX509ExtensionPtr>::iterator pos;
00535 std::vector<CPKIFX509ExtensionPtr>::iterator end = m_impl->m_exts.end();
00536 std::vector<CPKIFX509ExtensionPtr>::iterator processedEnd = processedExts.end();
00537 ExtensionsMatch em;
00538 size_t count = processedExts.size();
00539 for(pos = m_impl->m_exts.begin(); pos != end; ++pos)
00540 {
00541 em.SetRHS(*pos);
00542 if((*pos)->isCritical() && processedEnd == find_if(processedExts.begin(), processedExts.end(), em))
00543 return true;
00544 }
00545
00546 return false;
00547 }
00555 bool CPKIFCapiCRL::operator==(const CPKIFCRL& rhs) const
00556 {
00557 return *this->Encoded() == *rhs.Encoded();
00558 }
00559
00569 void CPKIFCapiCRL::SetCRL(PCCRL_CONTEXT crl)
00570 {
00571 m_impl->m_crl = crl;
00572 }
00573
00574 struct CPKIFCapiCRLEntryImpl
00575 {
00576 CPKIFCapiCRLEntryImpl();
00577
00578 void ClearContent();
00579
00580 void populateExtensionsVector();
00581
00582 CPKIFBufferPtr m_rawCRL;
00583
00584 std::vector<CPKIFX509ExtensionPtr> m_exts;
00585 CPKIFTimePtr m_revocationDate;
00586 CPKIFBufferPtr m_serialNumber;
00587 CPKIFCapiCRLEntry * m_this;
00588 PCRL_ENTRY m_crlEntry;
00589 };
00590
00598 CPKIFCapiCRLEntryImpl::CPKIFCapiCRLEntryImpl()
00599 {
00600 m_this = NULL;
00601 m_crlEntry = NULL;
00602 }
00603
00611 void CPKIFCapiCRLEntryImpl::ClearContent()
00612 {
00613 }
00614
00622 void CPKIFCapiCRLEntryImpl::populateExtensionsVector()
00623 {
00624
00625 if(!m_exts.empty())
00626 return;
00627
00628
00629 if(0 == m_crlEntry->cExtension)
00630 {
00631 m_exts.clear();
00632 return;
00633 }
00634
00635
00636
00637 CPKIFX509ExtensionMediator2 * mediator = CPKIFX509ExtensionMediator2::GetInstance();
00638 m_this->IPKIFHasExtensions::GetExtensions (mediator, m_exts);
00639 }
00640
00648 CPKIFCapiCRLEntry::CPKIFCapiCRLEntry(PCRL_ENTRY crlEntry) : m_impl(new CPKIFCapiCRLEntryImpl)
00649 {
00650 m_impl->m_this = this;
00651 m_impl->m_crlEntry = crlEntry;
00652 }
00653
00661 CPKIFCapiCRLEntry::~CPKIFCapiCRLEntry()
00662 {
00663 }
00664
00672 bool CPKIFCapiCRLEntry::AreThereAnyUnprocessedCriticalExtensions(std::vector<CPKIFX509ExtensionPtr>& processedExts)
00673 {
00674 std::vector<CPKIFX509ExtensionPtr>::iterator pos;
00675 std::vector<CPKIFX509ExtensionPtr>::iterator end = m_impl->m_exts.end();
00676 std::vector<CPKIFX509ExtensionPtr>::iterator processedEnd = processedExts.end();
00677 ExtensionsMatch em;
00678 size_t count = processedExts.size();
00679 for(pos = m_impl->m_exts.begin(); pos != end; ++pos)
00680 {
00681 em.SetRHS(*pos);
00682 if((*pos)->isCritical() && processedEnd == find_if(processedExts.begin(), processedExts.end(), em))
00683 return true;
00684 }
00685
00686 return false;
00687 }
00688
00697 void CPKIFCapiCRLEntry::GetEncodedExtensions (CPKIFBufferPtr& buf)
00698 {
00699 try
00700 {
00701 HRESULT hr= S_OK;
00702 if(m_impl->m_crlEntry->cExtension)
00703 {
00704 _CERT_EXTENSIONS ce;
00705 ce.cExtension = m_impl->m_crlEntry->cExtension;
00706 ce.rgExtension = m_impl->m_crlEntry->rgExtension;
00707 unsigned char* pvEncoded = NULL;
00708 DWORD pcbEncoded = 0;
00709 CryptEncodeObjectEx(X509_ASN_ENCODING, X509_EXTENSIONS, &ce, 0, NULL, NULL, &pcbEncoded);
00710 pvEncoded = new unsigned char[pcbEncoded];
00711 if(CryptEncodeObjectEx(X509_ASN_ENCODING, X509_EXTENSIONS, &ce, 0, NULL, pvEncoded, &pcbEncoded))
00712 {
00713 CPKIFBufferPtr encodedExtensions(new CPKIFBuffer(pvEncoded, pcbEncoded));
00714 buf = encodedExtensions;
00715 delete[] pvEncoded;
00716 return;
00717 }
00718 else
00719 {
00720 delete[] pvEncoded;
00721 hr = GetLastError();
00722 }
00723 }
00724 }
00725 catch (... )
00726 {
00727
00728 }
00729
00730 CPKIFBufferPtr nullExt;
00731 buf = nullExt;
00732 }
00733
00743 void CPKIFCapiCRLEntry::GetExtensionByOID(const CPKIFOID& oid, CPKIFX509ExtensionPtr& ref)
00744 {
00745 if(m_impl->m_exts.empty() && m_impl->m_crlEntry->cExtension)
00746 m_impl->populateExtensionsVector();
00747
00748 vector<CPKIFX509ExtensionPtr>::iterator pos;
00749 vector<CPKIFX509ExtensionPtr>::iterator end = m_impl->m_exts.end();
00750 for(pos = m_impl->m_exts.begin(); pos != end; ++pos)
00751 {
00752 if(oid == (*pos)->oid())
00753 {
00754 ref = *pos;
00755 return;
00756 }
00757 }
00758 }
00759
00769 const char* CPKIFCapiCRLEntry::SerialNumber() const
00770 {
00771 if(m_impl->m_serialNumber == (CPKIFBuffer*)NULL)
00772 {
00773 CPKIFBufferPtr tmp(new CPKIFBuffer);
00774 int len = (m_impl->m_crlEntry->SerialNumber.cbData * 2) + 3;
00775 unsigned char* tmpBuf = tmp->AllocateBuffer(len - 1);
00776 memset(tmpBuf, 0x00, len);
00777 tmpBuf[0] = '0';
00778 tmpBuf[1] = 'x';
00779 btoa((char*)m_impl->m_crlEntry->SerialNumber.pbData, (char*)tmpBuf+2, m_impl->m_crlEntry->SerialNumber.cbData);
00780
00781 CPKIFCapiCRLEntry* nonConst = const_cast<CPKIFCapiCRLEntry*>(this);
00782 nonConst->m_impl->m_serialNumber = tmp;
00783 }
00784 return (char*)m_impl->m_serialNumber->GetBuffer();
00785 }
00786
00795 const CPKIFTimePtr CPKIFCapiCRLEntry::RevocationDate() const
00796 {
00797 if(m_impl->m_revocationDate == (CPKIFTime*)NULL)
00798 {
00799 unsigned char* pvEncoded = NULL;
00800 DWORD pcbEncoded = 0;
00801 CryptEncodeObjectEx(X509_ASN_ENCODING, X509_CHOICE_OF_TIME, &m_impl->m_revocationDate, 0, NULL, pvEncoded, &pcbEncoded);
00802 pvEncoded = new unsigned char[pcbEncoded];
00803 if(CryptEncodeObjectEx(X509_ASN_ENCODING, X509_CHOICE_OF_TIME, &m_impl->m_revocationDate, 0, NULL, pvEncoded, &pcbEncoded))
00804 {
00805 CACASNWRAPPER_CREATE(CACX509V3Time, objPDU);
00806 CACX509V3Time* time = objPDU.Decode(pvEncoded, pcbEncoded);
00807 delete[] pvEncoded;
00808
00809 CPKIFTime* tmpTime = NULL;
00810 if(time->t == T_CACX509V3Time_utcTime)
00811 {
00812 tmpTime = new CPKIFTime(time->u.utcTime, UTCTIME);
00813 }
00814 else
00815 {
00816 tmpTime = new CPKIFTime(time->u.generalTime, GENERALIZEDTIME);
00817 }
00818 CPKIFTimePtr tmpRef(tmpTime);
00819
00820 CPKIFCapiCRLEntry* nonConst = const_cast<CPKIFCapiCRLEntry*>(this);
00821 nonConst->m_impl->m_revocationDate = tmpRef;
00822 }
00823 else
00824 {
00825 delete[] pvEncoded;
00826 HRESULT hr = GetLastError();
00827 }
00828 }
00829
00830 return m_impl->m_revocationDate;
00831 }