ArchiveTimestamp.cpp

Go to the documentation of this file.
00001 
00009 //#include "StdAfx.h"
00010 
00011 //PKIFERS includes
00012 #include "ArchiveTimestamp.h"
00013 #include "EvidenceRecord.h"
00014 #include "ERSException.h"
00015 
00016 //PKIF includes
00017 #include "Buffer.h"
00018 #include "ASN1Helper.h"
00019 #include "ToolkitUtils.h"
00020 #include "OID.h"
00021 #include "IPKIFCryptoMisc.h"
00022 #include "PKIFAlgorithm.h"
00023 
00024 //PKIFCMS includes
00025 #include "ContentInfo.h"
00026 #include "SignedData.h"
00027 #include "EncapsulatedContentInfo.h"
00028 #include "PKIFMessageErrors.h"
00029 
00030 //PKIFTSP includes
00031 #include "TSTInfo.h"
00032 #include "MessageImprint.h"
00033 
00034 //Objective includes
00035 #include "ERS.h"
00036 
00038 
00043 class PKIFArchiveTimestampMemoryHelper 
00044 {
00045 public:
00046     // Constructor and Destructor
00047     PKIFArchiveTimestampMemoryHelper();
00048     virtual ~PKIFArchiveTimestampMemoryHelper();
00049 
00050     ArchiveTimeStamp* pATS;
00051 };
00059 PKIFArchiveTimestampMemoryHelper::PKIFArchiveTimestampMemoryHelper()
00060 {
00061     pATS = NULL;
00062 }
00070 PKIFArchiveTimestampMemoryHelper::~PKIFArchiveTimestampMemoryHelper()
00071 {
00072     if(pATS)
00073         delete pATS;
00074 }
00075 
00076 struct CPKIFArchiveTimestampImpl 
00077 {
00078     CPKIFArchiveTimestampImpl();
00079     void ClearContent();
00080 
00081     CPKIFAlgorithmIdentifierPtr m_digestAlgorithm;
00082     CPKIFPartialHashtreeListPtr m_reducedHashtree;
00083     CPKIFContentInfoPtr m_timestamp;
00084 
00085     ArchiveTimeStampType m_type;
00086 
00087     //member for decoding
00088     CPKIFASNWrapper<ArchiveTimeStamp>* m_ats;
00089 
00090     void MakeArchiveTimeStamp();
00091     void FreeArchiveTimeStamp();
00092 
00093     //member to maintain state when calling Set functions
00094     void CallingAllGets();
00095 
00096     CPKIFArchiveTimestamp* m_parent;
00097     CPKIFBufferPtr m_decodeBuf;
00098 };
00100 
00107 CPKIFArchiveTimestampImpl::CPKIFArchiveTimestampImpl()
00108 {
00109     m_ats = NULL;
00110     ClearContent();
00111 }
00119 void CPKIFArchiveTimestampImpl::CallingAllGets()
00120 {
00121     if(!m_parent) return;
00122 
00123     m_parent->GetDigestAlgorithm();
00124     m_parent->GetReducedHashtree();
00125     m_parent->GetTimestamp();
00126 }
00134 void CPKIFArchiveTimestampImpl::ClearContent()
00135 {
00136     CPKIFAlgorithmIdentifierPtr emptyAlg;
00137     m_digestAlgorithm = emptyAlg;
00138 
00139     CPKIFPartialHashtreeListPtr emptyHashtree;
00140     m_reducedHashtree = emptyHashtree;
00141 
00142     CPKIFContentInfoPtr emptyTimestamp;
00143     m_timestamp = emptyTimestamp;
00144 
00145     CPKIFBufferPtr emptyBuf;
00146     m_decodeBuf = emptyBuf;
00147 
00148     FreeArchiveTimeStamp();
00149 }
00150 
00158 void CPKIFArchiveTimestampImpl::MakeArchiveTimeStamp()
00159 {
00160     LOG_STRING_DEBUG("CPKIFArchiveTimestampImpl::MakeArchiveTimeStamp()", TOOLKIT_ERS_ASN, 0, this);
00161 
00162     FreeArchiveTimeStamp();
00163     m_ats = new CPKIFASNWrapper<ArchiveTimeStamp>( BEREncArchiveTimeStamp, BERDecArchiveTimeStamp );
00164 }
00172 void CPKIFArchiveTimestampImpl::FreeArchiveTimeStamp()
00173 {
00174     LOG_STRING_DEBUG("CPKIFArchiveTimestampImpl::FreeArchiveTimeStamp()", TOOLKIT_ERS_ASN, 0, this);
00175     if(NULL != m_ats)
00176         delete m_ats;
00177     m_ats = NULL;
00178 }
00179 
00181 
00188 CPKIFArchiveTimestamp::CPKIFArchiveTimestamp(void) : m_impl (new CPKIFArchiveTimestampImpl())
00189 {
00190     m_impl->m_parent = this;
00191 }
00199 CPKIFArchiveTimestamp::~CPKIFArchiveTimestamp(void)
00200 {
00201     if(m_impl)
00202     {
00203         m_impl->FreeArchiveTimeStamp(); 
00204         delete m_impl;
00205     }
00206 }
00214 CPKIFAlgorithmIdentifierPtr CPKIFArchiveTimestamp::GetDigestAlgorithm() const
00215 {
00216     if(m_impl->m_digestAlgorithm == (CPKIFAlgorithmIdentifier*)NULL && NULL != m_impl->m_ats && NULL != (*m_impl->m_ats).data() && (*m_impl->m_ats)->m.digestAlgorithmPresent)
00217     {
00218         LOG_STRING_DEBUG("CPKIFArchiveTimestamp::GetDigestAlgorithm()", TOOLKIT_ERS_ASN, 0, this);
00219 
00220         CPKIFArchiveTimestamp* nonConst = const_cast<CPKIFArchiveTimestamp*>(this);
00221 
00222         CACX509V3AlgorithmIdentifier* curAlg = &(*m_impl->m_ats)->digestAlgorithm;
00223 
00224         CPKIFOIDPtr algOID(new CPKIFOID(curAlg->algorithm.subid, curAlg->algorithm.numids));
00225         CPKIFBufferPtr paramBuf;
00226         if(curAlg->m.parametersPresent)
00227         {
00228             paramBuf = CPKIFBufferPtr(new CPKIFBuffer(curAlg->parameters.data, curAlg->parameters.numocts));
00229         }
00230 
00231         CPKIFAlgorithmIdentifierPtr newAlg(new CPKIFAlgorithmIdentifier(algOID, paramBuf));
00232         nonConst->m_impl->m_digestAlgorithm = newAlg;
00233     }
00234 
00235     return m_impl->m_digestAlgorithm;
00236 }
00244 CPKIFPartialHashtreeListPtr CPKIFArchiveTimestamp::GetReducedHashtree() const
00245 {
00246     //XXX***IMPLEMENT ME
00247     return m_impl->m_reducedHashtree;
00248 }
00256 CPKIFContentInfoPtr CPKIFArchiveTimestamp::GetTimestamp() const
00257 {
00258     if(m_impl->m_timestamp == (CPKIFContentInfo*)NULL && NULL != m_impl->m_ats && NULL != (*m_impl->m_ats).data())
00259     {
00260         LOG_STRING_DEBUG("CPKIFArchiveTimestamp::GetTimestamp()", TOOLKIT_ERS_ASN, 0, this);
00261         
00262         CPKIFArchiveTimestamp* nonConst = const_cast<CPKIFArchiveTimestamp*>(this);
00263 
00264         //CACCMSContentInfo* curTimestamp = &(*m_impl->m_ats)->timeStamp;
00265 
00266         CACASNWRAPPER_CREATE(CACCMSContentInfo, tmpPDU);
00267         ASN1OpenType* data1 = tmpPDU.Encode(&(*m_impl->m_ats)->timeStamp);
00268 
00269         CPKIFContentInfoPtr newTimestamp(new CPKIFContentInfo);
00270         newTimestamp->Decode(data1->data, data1->numocts);
00271         delete data1;
00272 
00273         nonConst->m_impl->m_timestamp = newTimestamp;
00274     }
00275 
00276     return m_impl->m_timestamp;
00277 }
00285 void CPKIFArchiveTimestamp::SetDigestAlgorithm(CPKIFAlgorithmIdentifierPtr& hashtree)
00286 {
00287     m_impl->m_digestAlgorithm = hashtree;
00288 }
00296 void CPKIFArchiveTimestamp::SetReducedHashtree(CPKIFPartialHashtreeListPtr& reducedHashtree)
00297 {
00298     m_impl->m_reducedHashtree = reducedHashtree;
00299 }
00307 void CPKIFArchiveTimestamp::SetTimestamp(CPKIFContentInfoPtr& timestamp)
00308 {
00309     m_impl->m_timestamp = timestamp;
00310 }
00311 
00326 CPKIFBufferPtr CPKIFArchiveTimestamp::Encode() const
00327 {
00328     //We may be encoding:
00329     //  - using stuff added since creation of this instance
00330     //  - using stuff from m_ats
00331     //  - using stuff from m_ats plus stuff added since parsing
00332 
00333     if(m_impl->m_digestAlgorithm != (CPKIFAlgorithmIdentifier*)NULL)
00334     {
00335 
00336     }
00337 
00338     if(m_impl->m_reducedHashtree != (CPKIFPartialHashtreeList*)NULL)
00339     {
00340 
00341     }
00342 
00343     CPKIFBufferPtr encodedTimestamp = m_impl->m_timestamp->GetContent();
00344 
00345     PKIFArchiveTimestampMemoryHelper ats;
00346     ats.pATS = new ArchiveTimeStamp();
00347     ats.pATS->timeStamp.content.data = encodedTimestamp->GetBuffer();
00348     ats.pATS->timeStamp.content.numocts = encodedTimestamp->GetLength();
00349 
00350     CPKIFOIDPtr timestampType = m_impl->m_timestamp->GetContentType();
00351 
00352     CPKIFStringPtr str(new std::string(timestampType->ToString())); 
00353     ASN1OBJID* tmpOid = ConvertStringToASN1OBJID(str);
00354     CopyOID(&ats.pATS->timeStamp.contentType, tmpOid);
00355 
00356     CACASNWRAPPER_CREATE(ArchiveTimeStamp, objPDU);
00357     ASN1OpenType* data1 = NULL;
00358     
00359     try
00360     {
00361         data1 = objPDU.Encode(ats.pATS);
00362     }
00363     catch(...)
00364     {
00365         //we must remove pre-existing signer infos from the list in the memory helper before cleanup
00366         //re-throw any exception
00367         throw;
00368     }
00369 
00370     CPKIFBufferPtr tmp;
00371     try
00372     {
00373         //copy the buffer info a buffer ptr to be returned to the caller
00374         CPKIFBufferPtr tmpTmp(new CPKIFBuffer((unsigned char*)data1->data, data1->numocts));
00375         tmp = tmpTmp;
00376         delete data1; data1 = NULL;
00377     }
00378     catch(std::bad_alloc& ba)
00379     {
00380         if(data1)
00381             delete data1;
00382         throw ba;
00383     }
00384 
00385     //immediately after encoding - decode the message and remove all members
00386     //to keep the object in a suitable state
00387     //XXX-DEFER should the state be maintained in this clear and decode fashion
00388     //      or should another means be implemented (possibly storage of the
00389     //      encoded buffer with state-related macros at the beginning of every 
00390     //      function to trigger decodes as necessary)
00391     m_impl->ClearContent();
00392     CPKIFArchiveTimestamp* nonConst = const_cast<CPKIFArchiveTimestamp*>(this);
00393     nonConst->Decode(tmp);
00394     m_impl->CallingAllGets();
00395 
00396     return tmp;
00397 }
00405 void CPKIFArchiveTimestamp::Decode(CPKIFBufferPtr& msg)
00406 {
00407     LOG_STRING_DEBUG("CPKIFArchiveTimestamp::Decode(CPKIFBufferPtr& msg)", TOOLKIT_ERS_ASN, 0, this);
00408 
00409     m_impl->ClearContent();
00410 
00411     //if the input is empty - fail now
00412     if(msg == (CPKIFBuffer*)NULL || 0 == msg->GetLength())
00413     {
00414         throw CPKIFERSException(TOOLKIT_ERS_ASN, COMMON_INVALID_INPUT);
00415     }
00416 
00417     m_impl->MakeArchiveTimeStamp();
00418 
00419     try
00420     {
00421         //otherwise try to parse it into the m_impl->m_tsr member
00422         (*m_impl->m_ats).Decode(msg->GetBuffer(), msg->GetLength());
00423         
00424         m_impl->m_decodeBuf = msg;
00425     }
00426     catch(CPKIFException&)
00427     {
00428         throw CPKIFERSException(TOOLKIT_ERS_ASN, MSG_DECODE_FAILED);
00429     }
00430 }
00445 void CPKIFArchiveTimestamp::SetArchiveTimeStampType(ArchiveTimeStampType atst)
00446 {
00447     m_impl->m_type = atst;
00448 }
00456 ArchiveTimeStampType CPKIFArchiveTimestamp::GetArchiveTimeStampType() const
00457 {
00458     return m_impl->m_type;
00459 }
00467 CPKIFAlgorithmIdentifierPtr CPKIFArchiveTimestamp::GetEffectiveDigestAlgorithm() const
00468 {
00469     CPKIFAlgorithmIdentifierPtr algId = GetDigestAlgorithm();
00470     if(!algId)
00471     {
00472         CPKIFContentInfoPtr ci = GetTimestamp();
00473 
00474         CPKIFSignedData sd;
00475         CPKIFBufferPtr content1 = ci->GetContent();
00476         sd.Decode(content1);
00477 
00478         CPKIFEncapsulatedContentInfoPtr ecip = sd.GetEncapsulatedContent();
00479 
00480         CPKIFTSTInfo tstInfo;
00481         CPKIFBufferPtr content2 = ecip->GetContent();
00482         tstInfo.Decode(content2);
00483 
00484         CPKIFMessageImprintPtr mi = tstInfo.GetMessageImprint();
00485         algId = mi->GetHashAlgorithm();
00486     }
00487 
00488     return algId;
00489 }
00497 CPKIFBufferPtr PKIFERS_API CalculateHashOfTimestamp(
00499     CPKIFContentInfoPtr& timestamp, 
00501     IPKIFMediatorPtr& m, 
00503     PKIFCRYPTO::HASH_ALG ha)
00504 {
00505     CPKIFBufferPtr empty;
00506 
00507     //XXX***IMPLEMENT ME
00508 
00509     return empty;
00510 }
00518 CPKIFBufferPtr PKIFERS_API CalculateHashOfArchiveTimestampChain(
00520     CPKIFArchiveTimestampChainPtr& archiveTimestampChain, 
00522     IPKIFMediatorPtr& m, 
00524     PKIFCRYPTO::HASH_ALG ha)
00525 {
00526     CPKIFBufferPtr rv;
00527 
00528     CPKIFBufferList bpLifeExtender;
00529 
00530     ArchiveTimeStampChain* newChain = new ArchiveTimeStampChain;
00531     memset(newChain, 0, sizeof(ArchiveTimeStampChain));
00532 
00533     DListNode* chainCur = NULL;
00534     CPKIFArchiveTimestampChain::iterator chainPos;
00535     CPKIFArchiveTimestampChain::iterator chainEnd = archiveTimestampChain->end();
00536     for(chainPos = archiveTimestampChain->begin(); chainPos != chainEnd; ++chainPos)
00537     {
00538         if(NULL == chainCur)
00539         {
00540             NEW_NODE(chainCur)
00541         }
00542         else
00543         {
00544             NEW_NEXT_AND_ADVANCE(chainCur)
00545         }
00546 
00547         //build list in Objective structure (throw bad_alloc - memory helper in caller will clean
00548         //up any previously allocated memory)
00549         ArchiveTimeStamp* tmpATS = new ArchiveTimeStamp;
00550         memset(tmpATS, 0, sizeof(ArchiveTimeStamp));
00551 
00552         CPKIFContentInfoPtr ci = (*chainPos)->GetTimestamp();
00553         CPKIFBufferPtr encodedTimestamp = ci->GetContent();
00554         bpLifeExtender.push_back(encodedTimestamp);
00555 
00556         tmpATS->timeStamp.content.data = encodedTimestamp->GetBuffer();
00557         tmpATS->timeStamp.content.numocts = encodedTimestamp->GetLength();
00558 
00559         CPKIFOIDPtr timestampType = ci->GetContentType();
00560 
00561         CPKIFStringPtr str(new std::string(timestampType->ToString())); 
00562         ASN1OBJID* tmpOid = ConvertStringToASN1OBJID(str);
00563         CopyOID(&tmpATS->timeStamp.contentType, tmpOid);
00564 
00565         chainCur->data = (void*)tmpATS;
00566 
00567         SET_HEAD_TAIL_INCREMENT((*newChain), chainCur)
00568     }
00569 
00570     CACASNWRAPPER_CREATE(ArchiveTimeStampChain, objPDU);
00571     ASN1OpenType* data1 = NULL;
00572     
00573     try
00574     {
00575         data1 = objPDU.Encode(newChain);
00576     }
00577     catch(...)
00578     {
00579         //we must remove pre-existing signer infos from the list in the memory helper before cleanup
00580         //re-throw any exception
00581         throw;
00582     }
00583 
00584     CPKIFBufferPtr tmp;
00585     try
00586     {
00587         //copy the buffer info a buffer ptr to be returned to the caller
00588         CPKIFBufferPtr tmpTmp(new CPKIFBuffer((unsigned char*)data1->data, data1->numocts));
00589         tmp = tmpTmp;
00590         delete data1; data1 = NULL;
00591     }
00592     catch(std::bad_alloc& ba)
00593     {
00594         if(data1)
00595             delete data1;
00596         throw ba;
00597     }
00598 
00599     chainCur = newChain->head;
00600     for(int ii = 0; ii < newChain->count; ++ii)
00601     {
00602         delete chainCur->data;
00603         chainCur = chainCur->next;
00604     }
00605     delete newChain;
00606 
00607     IPKIFCryptoMisc* cm = m->GetMediator<IPKIFCryptoMisc>();
00608     IPKIFHashContext* hc = cm->HashInit(ha);
00609     cm->HashUpdate(hc, (unsigned char*)tmp->GetBuffer(), tmp->GetLength());
00610 
00611     CPKIFAlgorithm* haAlg = CPKIFAlgorithm::GetAlg(ha);
00612     int rvLen = haAlg->DigestSize();
00613 
00614     CPKIFBufferPtr tmpBP(new CPKIFBuffer);
00615     unsigned char* rvBuf = tmpBP->AllocateBuffer(rvLen);
00616     cm->HashFinal(hc, rvBuf, &rvLen);
00617     rv = tmpBP;
00618 
00619     return rv;
00620 }

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