CRL.cpp

Go to the documentation of this file.
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   //added 2/24/2005
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                     //(*pos).second.insert( make_pair( ce->SerialNumber(), ce ) );
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                 //tmpMap.insert( make_pair( ce->SerialNumber(), ce ) );
00128                 tmpMap.insert( make_pair( string(ce->SerialNumber()), ce ) );
00129                 m_vector.push_back(make_pair( actIssDN, tmpMap ));
00130             }
00131 
00132             //m_crlEntryMap.insert( make_pair( ce->SerialNumber(), ce ) );
00133 
00134             cur = cur->next;
00135         }
00136     }
00137 }
00138 
00146 CPKIFCRLImpl::CPKIFCRLImpl ():m_signedCRL(BEREncCACX509V3CertificateList, BERDecCACX509V3CertificateList)
00147 {
00148 }
00149 
00150 //added 2/24/2005
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     //if we've already populated the extensions vector then return
00194     if(!m_exts.empty())
00195         return;
00196 
00197     //if there are no extensions then return
00198     if(!m_signedCRL->tbsCertList.m.crlExtensionsPresent)
00199     {
00200         m_exts.clear();
00201         return;
00202     }
00203 
00204     // get the one and only extension mediator, with any additions an app might
00205     // have made
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 (... /*CPKIFException& e*/)
00265     {
00266         // How do we want to handle the exception?
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& ) //changed from std::exception 6/4/2004
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     //Added a call to Version() to make sure crl contains an acceptable version
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     //added 5/3/2004
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         //CPKIFName* tmpName = new CPKIFName(m_impl->m_signedCRL->tbsCertList.issuer);
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     //added 8/26/2004
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     //DListNode* cur = m_impl->m_signedCRL->tbsCertList.revokedCertificates.head;
00483     //CACX509V3RevokedCerts* curData = NULL;
00484     //while(NULL != cur)
00485     //{
00486         //ASN1OpenType * ot = (ASN1OpenType *) cur->data;
00487         //CPKIFCRLEntryPtr ce(new CPKIFCRLEntry(CPKIFBufferPtr(new CPKIFBuffer(ot->data,ot->numocts))));
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             //return false;
00497             continue;
00498         }
00499 
00500         CPKIFCRLEntryPtr ce = iter->second;
00501         //reviewed 4/24 - added strlen check
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         //CPKIFCRLEntryPtr ce = iter->second;
00509         //if(isIndirect)
00510         //{
00511         //  CPKIFCertificateIssuerPtr ci;
00512         //  ci = ce->GetExtension<CPKIFCertificateIssuer>();
00513         //  if(ci != (CPKIFCertificateIssuer*)NULL)
00514         //  {
00515         //      CPKIFGeneralNameList genNames;
00516         //      ci->CertificateIssuer(genNames);
00517 
00518         //      CPKIFNamePtr emptyDN;
00519         //      actIssDN = emptyDN;
00520 
00521         //      CPKIFGeneralNameList::iterator pos;
00522         //      CPKIFGeneralNameList::iterator end = genNames.end();
00523         //      for(pos = genNames.begin(); pos != end; ++pos)
00524         //      {
00525         //          if((*pos)->GetType() == CPKIFGeneralName::DIRECTORYNAME)
00526         //          {
00527         //              actIssDN = (*pos)->directoryName();
00528         //          }
00529         //      }
00530 
00531         //      if(actIssDN == (CPKIFName*)NULL)
00532         //          throw CPKIFException(TOOLKIT_X509_ASN, COMMON_INVALID_INPUT, "A CRL entry contained an unsupported non-DN CertificateIssuer extension.");
00533         //  }
00534         //  else
00535         //  {
00536         //      if(actIssDN == (CPKIFName*)NULL)
00537         //          actIssDN = Issuer();
00538         //  }
00539         //}
00540 
00542         //const char* tmpSNFromEntry = ce->SerialNumber();
00543         //if(strlen(serNum) == strlen(tmpSNFromEntry) && 0 == stricmp(serNum, tmpSNFromEntry) && (!isIndirect || *actIssDN == *issDN))
00544         //{
00545         //  crlEntry = ce;
00546         //  return true;
00547         //}
00548     }
00549 
00550     //  cur = cur->next;
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     // XXX TODO: commenting this out for now. it needs to be made true.
00682     /*if(processedExts.size() > m_impl->m_exts.size())
00683     {
00684         throw CPKIFException(TOOLKIT_X509_ASN, COMMON_INVALID_INPUT,
00685             "More extensions were processed than are present in the CRL.");
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 }

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