00001
00009 #include "CRL.h"
00010 #include "CRLEntry.h"
00011 #include "ASN1Helper.h"
00012 #include "Certificate.h"
00013 #include "Buffer.h"
00014 #include "Name.h"
00015 #include "PKIFTime.h"
00016 #include "AlgorithmIdentifier.h"
00017 #include "ExtensionsMatch.h"
00018 #include "PKIFException.h"
00019 #include "PKIFX509Extensions2.h"
00020 #include "IssuingDistributionPoint.h"
00021 #include "CertificateIssuer.h"
00022 #include "GeneralName.h"
00023 #include "PKIFBase64.h"
00024
00025 #include "PKIFCommonErrors.h"
00026
00027 using namespace std;
00028
00030 struct CPKIFCRLImpl
00031 {
00039 CPKIFCRLImpl ();
00040
00041 void ClearContent();
00042
00043 void populateExtensionsVector();
00044
00045 void PopulateEntryMap();
00046
00047 CPKIFBufferPtr m_rawCRL;
00048 CPKIFASNWrapper<CACX509V3CertificateList> m_signedCRL;
00049 std::vector<CPKIFX509ExtensionPtr> m_exts;
00050 std::vector<pair<CPKIFNamePtr, std::map<std::string, CPKIFCRLEntryPtr> > > m_vector;
00051 CPKIFNamePtr m_issuer;
00052 CPKIFTimePtr m_nextUpdate;
00053 CPKIFTimePtr m_thisUpdate;
00054 CPKIFAlgorithmIdentifierPtr m_sigAlg;
00055 CPKIFCRL * m_this;
00056 };
00057
00058 void CPKIFCRLImpl::PopulateEntryMap()
00059 {
00060 if(!m_vector.empty())
00061 return;
00062
00063 if( m_signedCRL->tbsCertList.m.revokedCertificatesPresent )
00064 {
00065
00066 bool isIndirect = false;
00067 CPKIFIssuingDistributionPointPtr idp = m_this->GetExtension<CPKIFIssuingDistributionPoint>();
00068 if(idp != (CPKIFIssuingDistributionPoint*)NULL)
00069 {
00070 isIndirect = idp->IndirectCRL();
00071 }
00072 CPKIFNamePtr actIssDN;
00073
00074 DListNode* cur = m_signedCRL->tbsCertList.revokedCertificates.head;
00075 CACX509V3RevokedCerts* curData = NULL;
00076 while(NULL != cur)
00077 {
00078 ASN1OpenType * ot = (ASN1OpenType *) cur->data;
00079 CPKIFCRLEntryPtr ce(new CPKIFCRLEntry(CPKIFBufferPtr(new CPKIFBuffer(ot->data,ot->numocts))));
00080
00081 CPKIFCertificateIssuerPtr ci;
00082 ci = ce->GetExtension<CPKIFCertificateIssuer>();
00083 if(ci != (CPKIFCertificateIssuer*)NULL)
00084 {
00085 CPKIFGeneralNameList genNames;
00086 ci->CertificateIssuer(genNames);
00087
00088 CPKIFNamePtr emptyDN;
00089 actIssDN = emptyDN;
00090
00091 CPKIFGeneralNameList::iterator pos;
00092 CPKIFGeneralNameList::iterator end = genNames.end();
00093 for(pos = genNames.begin(); pos != end; ++pos)
00094 {
00095 if((*pos)->GetType() == CPKIFGeneralName::DIRECTORYNAME)
00096 {
00097 actIssDN = (*pos)->directoryName();
00098 }
00099 }
00100
00101 if(actIssDN == (CPKIFName*)NULL)
00102 throw CPKIFException(TOOLKIT_X509_ASN, COMMON_INVALID_INPUT, "A CRL entry contained an unsupported non-DN CertificateIssuer extension.");
00103 }
00104 else
00105 {
00106 if(actIssDN == (CPKIFName*)NULL)
00107 actIssDN = m_this->Issuer();
00108 }
00109
00110 bool found = false;
00111 std::vector<pair<CPKIFNamePtr, std::map<std::string, CPKIFCRLEntryPtr> > >::iterator pos;
00112 std::vector<pair<CPKIFNamePtr, std::map<std::string, CPKIFCRLEntryPtr> > >::iterator end = m_vector.end();
00113 for(pos = m_vector.begin(); pos != end; ++pos)
00114 {
00115
00116 if(*(*pos).first == *actIssDN)
00117 {
00118
00119 (*pos).second.insert( make_pair( string(ce->SerialNumber()), ce ) );
00120 found = true;
00121 }
00122
00123 }
00124 if(!found)
00125 {
00126 std::map<std::string, CPKIFCRLEntryPtr> tmpMap;
00127
00128 tmpMap.insert( make_pair( string(ce->SerialNumber()), ce ) );
00129 m_vector.push_back(make_pair( actIssDN, tmpMap ));
00130 }
00131
00132
00133
00134 cur = cur->next;
00135 }
00136 }
00137 }
00138
00146 CPKIFCRLImpl::CPKIFCRLImpl ():m_signedCRL(BEREncCACX509V3CertificateList, BERDecCACX509V3CertificateList)
00147 {
00148 }
00149
00150
00158 void CPKIFCRLImpl::ClearContent()
00159 {
00160 CPKIFBufferPtr tmpBuf;
00161 m_rawCRL = tmpBuf;
00162
00163 m_exts.clear();
00164
00165 CPKIFNamePtr tmpIss;
00166 m_issuer = tmpIss;
00167 CPKIFTimePtr tmpNext;
00168 m_nextUpdate = tmpNext;
00169 CPKIFTimePtr tmpThis;
00170 m_thisUpdate = tmpThis;
00171 CPKIFAlgorithmIdentifierPtr tmpSig;
00172 m_sigAlg = tmpSig;
00173 }
00174
00175
00188 void CPKIFCRLImpl::populateExtensionsVector()
00189 {
00190 if(NULL == m_signedCRL.data())
00191 throw CPKIFException(TOOLKIT_X509_ASN, COMMON_INVALID_INPUT, "Attempted to read data from a CRL object prior to parsing a CRL.");
00192
00193
00194 if(!m_exts.empty())
00195 return;
00196
00197
00198 if(!m_signedCRL->tbsCertList.m.crlExtensionsPresent)
00199 {
00200 m_exts.clear();
00201 return;
00202 }
00203
00204
00205
00206 CPKIFX509ExtensionMediator2 * mediator = CPKIFX509ExtensionMediator2::GetInstance();
00207 m_this->IPKIFHasExtensions::GetExtensions (mediator, m_exts);
00208 }
00209
00211
00220 void CPKIFCRL::GetExtensionByOID(
00222 const CPKIFOID& oid,
00224 CPKIFX509ExtensionPtr& ref)
00225 {
00226 if(m_impl->m_exts.empty() && m_impl->m_signedCRL->tbsCertList.m.crlExtensionsPresent)
00227 m_impl->populateExtensionsVector();
00228
00229 vector<CPKIFX509ExtensionPtr>::iterator pos;
00230 vector<CPKIFX509ExtensionPtr>::iterator end = m_impl->m_exts.end();
00231 for(pos = m_impl->m_exts.begin(); pos != end; ++pos)
00232 {
00233 if(oid == (*pos)->oid())
00234 {
00235 ref = *pos;
00236 return;
00237 }
00238 }
00239 }
00248 void CPKIFCRL::GetEncodedExtensions (
00250 CPKIFBufferPtr& buf)
00251 {
00252 try
00253 {
00254 if (m_impl->m_signedCRL->tbsCertList.m.crlExtensionsPresent)
00255 {
00256 CACASNWRAPPER_CREATE(CACX509V3Extensions, extsWrapper);
00257 ASN1OpenType *data = extsWrapper.Encode (&m_impl->m_signedCRL->tbsCertList.crlExtensions);
00258 CPKIFBufferPtr tmp(new CPKIFBuffer(data->data, data->numocts));
00259 buf = tmp;
00260 delete data;
00261 return;
00262 }
00263 }
00264 catch (... )
00265 {
00266
00267 }
00268
00269 CPKIFBufferPtr nullExt;
00270 buf = nullExt;
00271 }
00272
00280 CPKIFCRL::CPKIFCRL(void): m_impl (new CPKIFCRLImpl)
00281 {
00282 m_impl->m_this = this;
00283 }
00291 CPKIFCRL::~CPKIFCRL(void)
00292 {
00293 if(m_impl)
00294 {
00295 delete m_impl;
00296 m_impl = 0;
00297 }
00298 }
00299
00300
00308 void CPKIFCRL::Decode(
00310 const unsigned char* cert,
00312 int certLen)
00313 {
00314 try
00315 {
00316 m_impl->ClearContent();
00317 CPKIFBufferPtr tmp(new CPKIFBuffer(cert, certLen));
00318 m_impl->m_rawCRL = tmp;
00319 m_impl->m_signedCRL.Decode(m_impl->m_rawCRL->GetBuffer(), m_impl->m_rawCRL->GetLength());
00320 m_impl->populateExtensionsVector();
00321
00322 }
00323 catch ( CPKIFException& )
00324 {
00325 m_impl->ClearContent();
00326 unsigned char * decoded = NULL;
00327 unsigned long decodedLen;
00328 bool b = PEMDecode_l((char *)cert, certLen, &decoded, &decodedLen);
00329 if(b)
00330 {
00331 try
00332 {
00333 m_impl->ClearContent();
00334 CPKIFBufferPtr tmp2(new CPKIFBuffer(decoded, decodedLen));
00335 m_impl->m_rawCRL = tmp2;
00336 m_impl->m_signedCRL.InitContext();
00337 m_impl->m_signedCRL.Decode(m_impl->m_rawCRL->GetBuffer(), m_impl->m_rawCRL->GetLength());
00338 m_impl->populateExtensionsVector();
00339 if(NULL != decoded)
00340 delete[] decoded;
00341
00342 }catch(...)
00343 {
00344 if(NULL != decoded)
00345 delete[] decoded;
00346 m_impl->ClearContent();
00347 throw;
00348 }
00349 }
00350 else
00351 {
00352 if(NULL != decoded)
00353 delete[] decoded;
00354 m_impl->ClearContent();
00355 throw;
00356 }
00357 }
00358
00359
00360 Version();
00361 }
00362
00373 int CPKIFCRL::Version() const
00374 {
00375 if(NULL == m_impl->m_signedCRL.data())
00376 throw CPKIFException(TOOLKIT_X509_ASN, COMMON_INVALID_INPUT, "Attempted to read data from a CRL object prior to parsing a CRL.");
00377
00378
00379 if(!m_impl->m_signedCRL->tbsCertList.m.versionPresent)
00380 return 1;
00381
00382 switch( m_impl->m_signedCRL->tbsCertList.version )
00383 {
00384 case CACX509V3AFv1:
00385 return 1;
00386 break;
00387 case CACX509V3AFv2:
00388 return 2;
00389 break;
00390 case CACX509V3AFv3:
00391 return 3;
00392 break;
00393 default:
00394 throw CPKIFException(TOOLKIT_ASN, COMMON_UNSUPPORTED_VERSION, "Unsupported CRL version.");
00395 break;
00396 }
00397 }
00407 CPKIFNamePtr CPKIFCRL::Issuer( ) const
00408 {
00409 if(NULL == m_impl->m_signedCRL.data())
00410 throw CPKIFException(TOOLKIT_X509_ASN, COMMON_INVALID_INPUT, "Attempted to read data from a CRL object prior to parsing a CRL.");
00411
00412 if(m_impl->m_issuer == (CPKIFName*)NULL)
00413 {
00414 CACASNWRAPPER_CREATE(CACX509V3Name, objPDU2);
00415 ASN1OpenType* data1 = objPDU2.Encode(&(m_impl->m_signedCRL->tbsCertList.issuer));
00416 CPKIFBufferPtr tmpBuf;
00417 if (data1 != NULL)
00418 {
00419 tmpBuf = CPKIFBufferPtr(new CPKIFBuffer(data1->data, data1->numocts));
00420 delete data1;
00421 }
00422
00423 CPKIFName* tmpName = new CPKIFName(tmpBuf);
00424 CPKIFNamePtr tmpRef(tmpName);
00425
00426 CPKIFCRL* nonConstCert = const_cast<CPKIFCRL*>(this);
00427 nonConstCert->m_impl->m_issuer = tmpRef;
00428 }
00429
00430 return m_impl->m_issuer;
00431 }
00442 CPKIFBufferPtr CPKIFCRL::Encoded() const
00443 {
00444 return m_impl->m_rawCRL;
00445 }
00457 bool CPKIFCRL::CertOnThisCRL(
00459 const CPKIFCertificatePtr& cert,
00461 CPKIFCRLEntryPtr& crlEntry)
00462 {
00463 if(!m_impl->m_signedCRL->tbsCertList.m.revokedCertificatesPresent)
00464 return false;
00465
00466 m_impl->PopulateEntryMap();
00467
00468 const char* serNum = cert->SerialNumber();
00469 CPKIFNamePtr issDN = cert->Issuer();
00470 CPKIFNamePtr actIssDN;
00471
00472
00473 bool isIndirect = false;
00474 CPKIFIssuingDistributionPointPtr idp = GetExtension<CPKIFIssuingDistributionPoint>();
00475 if(idp != (CPKIFIssuingDistributionPoint*)NULL)
00476 {
00477 isIndirect = idp->IndirectCRL();
00478 }
00479 if(!isIndirect)
00480 actIssDN = Issuer();
00481
00482
00483
00484
00485
00486
00487
00488
00489 std::vector<pair<CPKIFNamePtr, std::map<std::string, CPKIFCRLEntryPtr> > >::iterator pos;
00490 std::vector<pair<CPKIFNamePtr, std::map<std::string, CPKIFCRLEntryPtr> > >::iterator end = m_impl->m_vector.end();
00491 for(pos = m_impl->m_vector.begin(); pos != end; ++pos)
00492 {
00493 map<string,CPKIFCRLEntryPtr>::iterator iter = (*pos).second.find(serNum);
00494 if( iter == (*pos).second.end() )
00495 {
00496
00497 continue;
00498 }
00499
00500 CPKIFCRLEntryPtr ce = iter->second;
00501
00502 const char* tmpSNFromEntry = ce->SerialNumber();
00503 if(strlen(serNum) == strlen(tmpSNFromEntry) && 0 == stricmp(serNum, tmpSNFromEntry) && (!isIndirect || *(*pos).first == *issDN))
00504 {
00505 crlEntry = ce;
00506 return true;
00507 }
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00542
00543
00544
00545
00546
00547
00548 }
00549
00550
00551
00552
00553 return false;
00554 }
00562 CPKIFBufferPtr CPKIFCRL::Signature() const
00563 {
00564 CPKIFBufferPtr tmp(new CPKIFBuffer(m_impl->m_signedCRL->signature.data, m_impl->m_signedCRL->signature.numbits/8));
00565 return tmp;
00566 }
00576 CPKIFTimePtr CPKIFCRL::NextUpdate( ) const
00577 {
00578 if(NULL == m_impl->m_signedCRL.data())
00579 throw CPKIFException(TOOLKIT_X509_ASN, COMMON_INVALID_INPUT, "Attempted to read data from a CRL object prior to parsing a CRL.");
00580
00581 if(m_impl->m_nextUpdate == (CPKIFTime*)NULL && m_impl->m_signedCRL->tbsCertList.m.nextUpdatePresent)
00582 {
00583 CPKIFTime* tmpTime = NULL;
00584 if(m_impl->m_signedCRL->tbsCertList.nextUpdate.t == T_CACX509V3Time_utcTime)
00585 {
00586 tmpTime = new CPKIFTime(m_impl->m_signedCRL->tbsCertList.nextUpdate.u.utcTime, UTCTIME);
00587 }
00588 else
00589 {
00590 tmpTime = new CPKIFTime(m_impl->m_signedCRL->tbsCertList.nextUpdate.u.generalTime, GENERALIZEDTIME);
00591 }
00592 CPKIFTimePtr tmpRef(tmpTime);
00593
00594 CPKIFCRL* nonConstCert = const_cast<CPKIFCRL*>(this);
00595 nonConstCert->m_impl->m_nextUpdate = tmpRef;
00596 }
00597
00598 return m_impl->m_nextUpdate;
00599 }
00609 CPKIFTimePtr CPKIFCRL::ThisUpdate( ) const
00610 {
00611 if(NULL == m_impl->m_signedCRL.data())
00612 throw CPKIFException(TOOLKIT_X509_ASN, COMMON_INVALID_INPUT, "Attempted to read data from a CRL object prior to parsing a CRL.");
00613
00614 if(m_impl->m_thisUpdate == (CPKIFTime*)NULL)
00615 {
00616 CPKIFTime* tmpTime = NULL;
00617 if(m_impl->m_signedCRL->tbsCertList.thisUpdate.t == T_CACX509V3Time_utcTime)
00618 {
00619 tmpTime = new CPKIFTime(m_impl->m_signedCRL->tbsCertList.thisUpdate.u.utcTime, UTCTIME);
00620 }
00621 else
00622 {
00623 tmpTime = new CPKIFTime(m_impl->m_signedCRL->tbsCertList.thisUpdate.u.generalTime, GENERALIZEDTIME);
00624 }
00625 CPKIFTimePtr tmpRef(tmpTime);
00626
00627 CPKIFCRL* nonConstCert = const_cast<CPKIFCRL*>(this);
00628 nonConstCert->m_impl->m_thisUpdate = tmpRef;
00629 }
00630
00631 return m_impl->m_thisUpdate;
00632 }
00642 CPKIFAlgorithmIdentifierPtr CPKIFCRL::SignatureAlgorithm( ) const
00643 {
00644 if(NULL == m_impl->m_signedCRL.data())
00645 throw CPKIFException(TOOLKIT_X509_ASN, COMMON_INVALID_INPUT, "Attempted to read data from a CRL object prior to parsing a CRL.");
00646
00647 if(m_impl->m_sigAlg == (CPKIFAlgorithmIdentifier*)NULL)
00648 {
00649
00650 CPKIFOIDPtr algOID(new CPKIFOID(m_impl->m_signedCRL->signatureAlgorithm.algorithm.subid,
00651 m_impl->m_signedCRL->signatureAlgorithm.algorithm.numids));
00652
00653 CPKIFBufferPtr paramBuf;
00654 if(m_impl->m_signedCRL->signatureAlgorithm.m.parametersPresent)
00655 {
00656 paramBuf = CPKIFBufferPtr(new CPKIFBuffer(m_impl->m_signedCRL->signatureAlgorithm.parameters.data,
00657 m_impl->m_signedCRL->signatureAlgorithm.parameters.numocts));
00658
00659 }
00660
00661 CPKIFAlgorithmIdentifierPtr tmpRef(new CPKIFAlgorithmIdentifier(algOID, paramBuf));
00662
00663 CPKIFCRL* nonConstCert = const_cast<CPKIFCRL*>(this);
00664 nonConstCert->m_impl->m_sigAlg = tmpRef;
00665 }
00666
00667 return m_impl->m_sigAlg;
00668 }
00677 bool CPKIFCRL::AreThereAnyUnprocessedCriticalExtensions(
00679 std::vector<CPKIFX509ExtensionPtr>& processedExts)
00680 {
00681
00682
00683
00684
00685
00686
00687 std::vector<CPKIFX509ExtensionPtr>::iterator pos;
00688 std::vector<CPKIFX509ExtensionPtr>::iterator end = m_impl->m_exts.end();
00689 std::vector<CPKIFX509ExtensionPtr>::iterator processedEnd = processedExts.end();
00690 ExtensionsMatch em;
00691 size_t count = processedExts.size();
00692 for(pos = m_impl->m_exts.begin(); pos != end; ++pos)
00693 {
00694 em.SetRHS(*pos);
00695 if((*pos)->isCritical() && processedEnd == find_if(processedExts.begin(), processedExts.end(), em))
00696 return true;
00697 }
00698
00699 return false;
00700 }
00708 bool CPKIFCRL::operator==(const CPKIFCRL& rhs) const
00709 {
00710 return *this->Encoded() == *rhs.Encoded();
00711 }
00712
00713
00721 std::vector<pair<CPKIFNamePtr, std::map<std::string, CPKIFCRLEntryPtr> > > CPKIFCRL::GetCRLEntryMap()
00722 {
00723 return m_impl->m_vector;
00724 }
00725
00733 void CPKIFCRL::PopulateEntryMap()
00734 {
00735 m_impl->PopulateEntryMap();
00736 }