EvidenceRecord.cpp

Go to the documentation of this file.
00001 
00009 //#include "StdAfx.h"
00010 
00011 //PKIFERS includes
00012 #include "EvidenceRecord.h"
00013 #include "IPKIFCryptoInfo.h"
00014 #include "ERSException.h"
00015 #include "ArchiveTimestamp.h"
00016 
00017 //PKIF includes
00018 #include "AlgorithmIdentifier.h"
00019 #include "ASN1Helper.h"
00020 #include "ToolkitUtils.h"
00021 #include "OID.h"
00022 #include "PKIFMessageErrors.h"
00023 #include "PKIFException.h"
00024 #include "GottaMatch.h"
00025 
00026 
00027 //PKIFCMS includes
00028 #include "PKIFCMS.h"
00029 
00030 //Objective includes
00031 #include "ERS.h"
00032 #include "PKIX1Explicit88.h"
00033 
00034 //*****************************************************************************
00035 //  Memory Helper and Impl
00036 //*****************************************************************************
00038 
00043 class PKIFERSMemoryHelper 
00044 {
00045 public:
00046     // Constructor and Destructor
00047     PKIFERSMemoryHelper();
00048     virtual ~PKIFERSMemoryHelper();
00049 
00050     EvidenceRecord* pERS;
00051 };
00059 PKIFERSMemoryHelper::PKIFERSMemoryHelper()
00060 {
00061     pERS = NULL;
00062 }
00070 PKIFERSMemoryHelper::~PKIFERSMemoryHelper()
00071 {
00072     if(pERS)
00073     {
00074         //clean up digest algorithms
00075         DListNode* cur = pERS->digestAlgorithms.head, *tmp = NULL;
00076         while(NULL != cur)
00077         {
00078             CACX509V3AlgorithmIdentifier* tmpDA = (CACX509V3AlgorithmIdentifier*)cur->data;
00079             delete tmpDA;
00080 
00081             tmp = cur->next;
00082             delete cur;
00083             cur = tmp;
00084         }
00085         
00086         cur = pERS->archiveTimeStampSequence.head;
00087         while(NULL != cur)
00088         {
00089             ArchiveTimeStampChain* tmpChain = (ArchiveTimeStampChain*)cur->data;
00090 
00091             DListNode* cur2 = tmpChain->head, *tmp2 = NULL;
00092             while(NULL != cur2)
00093             {
00094                 ArchiveTimeStamp* tmpATS = (ArchiveTimeStamp*)cur2->data;
00095                 delete tmpATS;
00096 
00097                 tmp2 = cur2->next;
00098                 delete cur2;
00099                 cur2 = tmp2;
00100             }
00101 
00102             delete tmpChain;
00103 
00104             tmp = cur->next;
00105             delete cur;
00106             cur = tmp;
00107         }
00108 
00109         delete pERS;
00110     }
00111 }
00112 
00113 struct CPKIFEvidenceRecordImpl 
00114 {
00115     //default constructor
00116     CPKIFEvidenceRecordImpl();
00117 
00118     //initialization (or re-initialization) function
00119     void ClearContent();
00120 
00121     //generate or destroy m_evidenceRecord member
00122     void MakeEvidenceRecord();
00123     void FreeEvidenceRecord();
00124 
00125     //member to maintain state when calling Set functions
00126     void CallingAllGets();
00127 
00128     CPKIFEvidenceRecord* m_parent;
00129 
00130     int m_version;
00131 //  CPKIFAlgorithmIdentifierListPtr m_digestAlgorithms;
00132     CPKIFArchiveTimestampSequencePtr m_archiveTimestampSequence;
00133     CPKIFASNWrapper<EvidenceRecord>* m_evidenceRecord;
00134     CPKIFBufferPtr m_decodeBuf;
00135 };
00143 CPKIFEvidenceRecordImpl::CPKIFEvidenceRecordImpl()
00144 {
00145     //ClearContent frees evidence records, so initialize that here
00146     m_evidenceRecord = NULL;
00147 
00148     //everything else is initialized inside ClearContent
00149     ClearContent();
00150 }
00158 void CPKIFEvidenceRecordImpl::CallingAllGets()
00159 {
00160     if(!m_parent) return;
00161 
00162     m_parent->GetArchiveTimestampSequence();
00163     m_parent->GetDigestAlgorithms();
00164     m_parent->GetVersion();
00165 }
00166 
00176 void CPKIFEvidenceRecordImpl::ClearContent()
00177 {
00178     m_version = PKIFERSv1;
00179 
00180     //CPKIFAlgorithmIdentifierListPtr emptyAlgs;
00181     //m_digestAlgorithms = emptyAlgs;
00182 
00183     CPKIFArchiveTimestampSequencePtr emptyATS; 
00184     m_archiveTimestampSequence = emptyATS;
00185 
00186     CPKIFBufferPtr emptyBuf;
00187     m_decodeBuf = emptyBuf;
00188 
00189     FreeEvidenceRecord();
00190 }
00191 
00199 void CPKIFEvidenceRecordImpl::MakeEvidenceRecord()
00200 {
00201     LOG_STRING_DEBUG("CPKIFEvidenceRecordImpl::MakeEvidenceRecord()", TOOLKIT_ERS_ASN, 0, this);
00202 
00203     FreeEvidenceRecord();
00204     m_evidenceRecord = new CPKIFASNWrapper<EvidenceRecord>( BEREncEvidenceRecord, BERDecEvidenceRecord );
00205 }
00206 
00214 void CPKIFEvidenceRecordImpl::FreeEvidenceRecord()
00215 {
00216     LOG_STRING_DEBUG("CPKIFEvidenceRecordImpl::FreeEvidenceRecord()", TOOLKIT_ERS_ASN, 0, this);
00217     if(NULL != m_evidenceRecord)
00218         delete m_evidenceRecord;
00219     m_evidenceRecord = NULL;
00220 }
00221 
00223 
00224 //*****************************************************************************
00225 //  CPKIFEvidenceRecord implementation
00226 //*****************************************************************************
00236 CPKIFEvidenceRecord::CPKIFEvidenceRecord(void) : m_impl (new CPKIFEvidenceRecordImpl())
00237 {
00238     m_impl->m_parent = this;
00239 }
00247 CPKIFEvidenceRecord::~CPKIFEvidenceRecord(void)
00248 {
00249     if(m_impl)
00250     {
00251         m_impl->FreeEvidenceRecord();   
00252         delete m_impl;
00253     }
00254 }
00255 
00263 int CPKIFEvidenceRecord::GetVersion() const
00264 {
00265     if(NULL != m_impl->m_evidenceRecord && NULL != (*m_impl->m_evidenceRecord).data() && 
00266         m_impl->m_version != (*m_impl->m_evidenceRecord)->version)
00267     {
00268         LOG_STRING_DEBUG("CPKIFEvidenceRecord::GetVersion()", TOOLKIT_ERS_ASN, 0, this);
00269 
00270         CPKIFEvidenceRecord* nonConst = const_cast<CPKIFEvidenceRecord*>(this);
00271         nonConst->m_impl->m_version = (*m_impl->m_evidenceRecord)->version;
00272     }
00273 
00274     return m_impl->m_version;
00275 }
00276 
00290 CPKIFAlgorithmIdentifierListPtr CPKIFEvidenceRecord::GetDigestAlgorithms() const
00291 {
00292 //The commented out code below could be used if the list included in an evidence record by its creator is of 
00293 //interest.  Since the list is simply a convenience, the archive timestamps are parsed upon decoding and the 
00294 //list could be augmented when the archive timestamp  sequence is updated, the list is always calculated from 
00295 //the archive timestamp sequence.  
00296 /*
00297     if(m_impl->m_digestAlgorithms == (CPKIFAlgorithmIdentifierList*)NULL && NULL != m_impl->m_evidenceRecord && 
00298         NULL != (*m_impl->m_evidenceRecord).data())
00299     {
00300         LOG_STRING_DEBUG("CPKIFEvidenceRecord::GetDigestAlgorithms()", TOOLKIT_ERS_ASN, 0, this);
00301 
00302         CPKIFEvidenceRecord* nonConst = const_cast<CPKIFEvidenceRecord*>(this);
00303         CPKIFAlgorithmIdentifierListPtr newAlgList(new CPKIFAlgorithmIdentifierList);
00304         nonConst->m_impl->m_digestAlgorithms = newAlgList;
00305 
00306         DListNode* iter = (*m_impl->m_evidenceRecord)->digestAlgorithms.head;
00307         while(NULL != iter)
00308         {
00309             CACX509V3AlgorithmIdentifier* curAlg = (CACX509V3AlgorithmIdentifier*)iter->data;
00310 
00311             CPKIFOIDPtr algOID(new CPKIFOID(curAlg->algorithm.subid, curAlg->algorithm.numids));
00312             CPKIFBufferPtr paramBuf;
00313             if(curAlg->m.parametersPresent)
00314             {
00315                 paramBuf = CPKIFBufferPtr(new CPKIFBuffer(curAlg->parameters.data, curAlg->parameters.numocts));
00316             }
00317 
00318             CPKIFAlgorithmIdentifierPtr newAlg(new CPKIFAlgorithmIdentifier(algOID, paramBuf));
00319             newAlgList->push_back(newAlg);
00320 
00321             iter = iter->next;
00322         }
00323     }
00324 
00325     return m_impl->m_digestAlgorithms;
00326 */
00327     CPKIFAlgorithmIdentifierListPtr rv(new CPKIFAlgorithmIdentifierList);
00328     if(!m_impl || !m_impl->m_archiveTimestampSequence)
00329         return rv;
00330 
00331     CPKIFArchiveTimestampSequence::iterator seqPos;
00332     CPKIFArchiveTimestampSequence::iterator seqEnd = m_impl->m_archiveTimestampSequence->end();
00333     for(seqPos = m_impl->m_archiveTimestampSequence->begin(); seqPos != seqEnd; ++seqPos)
00334     {
00335         CPKIFArchiveTimestampChain::iterator chainPos;
00336         CPKIFArchiveTimestampChain::iterator chainEnd = (*seqPos)->end();
00337         for(chainPos = (*seqPos)->begin(); chainPos != chainEnd; ++chainPos)
00338         {
00339             CPKIFAlgorithmIdentifierPtr algId = (*chainPos)->GetEffectiveDigestAlgorithm();
00340             CPKIFAlgorithmIdentifierPtr algIdCopy(new CPKIFAlgorithmIdentifier(*algId));
00341             GottaMatch<CPKIFAlgorithmIdentifierPtr> gm;
00342             gm.SetRHS(algIdCopy);
00343             if(rv->end() == find_if(rv->begin(), rv->end(), gm))
00344                 rv->push_back(algIdCopy);
00345         }
00346     }
00347 
00348     return rv;
00349 }
00357 CPKIFArchiveTimestampSequencePtr CPKIFEvidenceRecord::GetArchiveTimestampSequence() const
00358 {
00359     if(m_impl->m_archiveTimestampSequence == (CPKIFArchiveTimestampSequencePtr*)NULL && 
00360         NULL != m_impl->m_evidenceRecord && NULL != (*m_impl->m_evidenceRecord).data())
00361     {
00362         LOG_STRING_DEBUG("CPKIFEvidenceRecord::GetArchiveTimestampSequence()", TOOLKIT_ERS_ASN, 0, this);
00363 
00364         CPKIFEvidenceRecord* nonConst = const_cast<CPKIFEvidenceRecord*>(this);
00365         CPKIFArchiveTimestampSequencePtr newATSSeq(new CPKIFArchiveTimestampSequence);
00366         nonConst->m_impl->m_archiveTimestampSequence = newATSSeq;
00367 
00368         DListNode* iter = (*m_impl->m_evidenceRecord)->archiveTimeStampSequence.head;
00369         while(NULL != iter)
00370         {
00371             CPKIFArchiveTimestampChainPtr newChain(new CPKIFArchiveTimestampChain);
00372 
00373             ArchiveTimeStampChain* curAlg = (ArchiveTimeStampChain*)iter->data;
00374             DListNode* atsIter = curAlg->head;
00375             while(NULL != atsIter)
00376             {
00377                 ArchiveTimeStamp* ats = (ArchiveTimeStamp*)atsIter->data;
00378 
00379                 CACASNWRAPPER_CREATE(ArchiveTimeStamp, tmpPDU);
00380                 ASN1OpenType* data1 = tmpPDU.Encode(ats);
00381 
00382                 CPKIFBufferPtr tmpBP(new CPKIFBuffer(data1->data, data1->numocts));
00383                 delete data1;
00384 
00385                 CPKIFArchiveTimestampPtr newATS(new CPKIFArchiveTimestamp);
00386                 newATS->Decode(tmpBP);
00387                 newChain->push_back(newATS);
00388 
00389                 atsIter = atsIter->next;
00390             }
00391 
00392             newATSSeq->push_back(newChain);         
00393 
00394             iter = iter->next;
00395         }
00396     }
00397 
00398     return m_impl->m_archiveTimestampSequence;
00399 }
00407 CPKIFBufferPtr CPKIFEvidenceRecord::Encode() const
00408 {
00409     m_impl->CallingAllGets();
00410     if(!m_impl || !m_impl->m_archiveTimestampSequence || 0 == m_impl->m_archiveTimestampSequence->size())
00411         throw CPKIFException(TOOLKIT_ERS_ASN, COMMON_INVALID_INPUT);
00412 
00413     //create a new EvidenceRecord struct and hand it to a memory handler instance
00414     PKIFERSMemoryHelper ers;
00415     ers.pERS = new EvidenceRecord();
00416     memset(ers.pERS, 0, sizeof(EvidenceRecord));
00417 
00418     CPKIFAlgorithmIdentifierListPtr digAlgs = GetDigestAlgorithms();
00419 
00420     DListNode* cur = NULL;
00421     CPKIFAlgorithmIdentifierList::iterator pos; 
00422     CPKIFAlgorithmIdentifierList::iterator end = digAlgs->end();
00423     for(pos = digAlgs->begin(); pos != end; ++pos)
00424     {
00425         CPKIFAlgorithmIdentifierPtr digestAlg = (*pos);
00426 
00427         if(NULL == cur)
00428         {
00429             NEW_NODE(cur)
00430         }
00431         else
00432         {
00433             NEW_NEXT_AND_ADVANCE(cur)
00434         }
00435 
00436         //build list in Objective structure (throw bad_alloc - memory helper in caller will clean
00437         //up any previously allocated memory)
00438         CACX509V3AlgorithmIdentifier* tmpDA = new CACX509V3AlgorithmIdentifier;
00439 
00440         tmpDA->m.parametersPresent = 1;
00441         tmpDA->parameters.data = g_nullParams;
00442         tmpDA->parameters.numocts = 2;
00443         CPKIFStringPtr str(new std::string(digestAlg->oid()->ToString())); 
00444         ASN1OBJID* tmpOid = ConvertStringToASN1OBJID(str);
00445 
00446         CopyOID(&tmpDA->algorithm, tmpOid);
00447 
00448         if( NULL != tmpOid)
00449             delete tmpOid;
00450 
00451         cur->data = (void*)tmpDA;
00452 
00453         SET_HEAD_TAIL_INCREMENT(ers.pERS->digestAlgorithms, cur)
00454     }
00455 
00456     CPKIFBufferList bpLifeExtender;
00457     DListNode* seqCur = NULL;
00458     CPKIFArchiveTimestampSequence::iterator seqPos;
00459     CPKIFArchiveTimestampSequence::iterator seqEnd = m_impl->m_archiveTimestampSequence->end();
00460     for(seqPos = m_impl->m_archiveTimestampSequence->begin(); seqPos != seqEnd; ++seqPos)
00461     {
00462         if(NULL == seqCur)
00463         {
00464             NEW_NODE(seqCur)
00465         }
00466         else
00467         {
00468             NEW_NEXT_AND_ADVANCE(seqCur)
00469         }
00470 
00471         ArchiveTimeStampChain* newChain = new ArchiveTimeStampChain;
00472         memset(newChain, 0, sizeof(ArchiveTimeStampChain));
00473         seqCur->data = newChain;
00474 
00475         DListNode* chainCur = NULL;
00476         CPKIFArchiveTimestampChain::iterator chainPos;
00477         CPKIFArchiveTimestampChain::iterator chainEnd = (*seqPos)->end();
00478         for(chainPos = (*seqPos)->begin(); chainPos != chainEnd; ++chainPos)
00479         {
00480             if(NULL == chainCur)
00481             {
00482                 NEW_NODE(chainCur)
00483             }
00484             else
00485             {
00486                 NEW_NEXT_AND_ADVANCE(chainCur)
00487             }
00488 
00489             //build list in Objective structure (throw bad_alloc - memory helper in caller will clean
00490             //up any previously allocated memory)
00491             ArchiveTimeStamp* tmpATS = new ArchiveTimeStamp;
00492             memset(tmpATS, 0, sizeof(ArchiveTimeStamp));
00493 
00494             CPKIFContentInfoPtr ci = (*chainPos)->GetTimestamp();
00495             CPKIFBufferPtr encodedTimestamp = ci->GetContent();
00496             bpLifeExtender.push_back(encodedTimestamp);
00497 
00498             tmpATS->timeStamp.content.data = encodedTimestamp->GetBuffer();
00499             tmpATS->timeStamp.content.numocts = encodedTimestamp->GetLength();
00500 
00501             CPKIFOIDPtr timestampType = ci->GetContentType();
00502 
00503             CPKIFStringPtr str(new std::string(timestampType->ToString())); 
00504             ASN1OBJID* tmpOid = ConvertStringToASN1OBJID(str);
00505             CopyOID(&tmpATS->timeStamp.contentType, tmpOid);
00506 
00507             if( NULL != tmpOid)
00508                 delete tmpOid;
00509 
00510             chainCur->data = (void*)tmpATS;
00511 
00512             SET_HEAD_TAIL_INCREMENT((*newChain), chainCur)
00513         }
00514         SET_HEAD_TAIL_INCREMENT(ers.pERS->archiveTimeStampSequence, seqCur)
00515     }
00516 
00517     CACASNWRAPPER_CREATE(EvidenceRecord, objPDU);
00518     ASN1OpenType* data1 = NULL;
00519     
00520     try
00521     {
00522         data1 = objPDU.Encode(ers.pERS);
00523     }
00524     catch(...)
00525     {
00526         //we must remove pre-existing signer infos from the list in the memory helper before cleanup
00527         //re-throw any exception
00528         throw;
00529     }
00530 
00531     CPKIFBufferPtr tmp;
00532     try
00533     {
00534         //copy the buffer info a buffer ptr to be returned to the caller
00535         CPKIFBufferPtr tmpTmp(new CPKIFBuffer((unsigned char*)data1->data, data1->numocts));
00536         tmp = tmpTmp;
00537         delete data1; data1 = NULL;
00538     }
00539     catch(std::bad_alloc& ba)
00540     {
00541         if(data1)
00542             delete data1;
00543         throw ba;
00544     }
00545 
00546     //immediately after encoding - decode the message and remove all members
00547     //to keep the object in a suitable state
00548     //XXX-DEFER should the state be maintained in this clear and decode fashion
00549     //      or should another means be implemented (possibly storage of the
00550     //      encoded buffer with state-related macros at the beginning of every 
00551     //      function to trigger decodes as necessary)
00552 
00553     CPKIFEvidenceRecord* nonConst = const_cast<CPKIFEvidenceRecord*>(this);
00554     nonConst->Decode(tmp);
00555     m_impl->CallingAllGets();
00556 
00557     return tmp;
00558 }
00559 
00570 void CPKIFEvidenceRecord::Decode(
00572     CPKIFBufferPtr& msg)
00573 {
00574     LOG_STRING_DEBUG("CPKIFEvidenceRecord::Decode(CPKIFBufferPtr& msg)", TOOLKIT_ERS_ASN, 0, this);
00575 
00576     m_impl->ClearContent();
00577 
00578     //if the input is empty - fail now
00579     if(msg == (CPKIFBuffer*)NULL || 0 == msg->GetLength())
00580     {
00581         throw CPKIFERSException(TOOLKIT_ERS_ASN, COMMON_INVALID_INPUT);
00582     }
00583 
00584     m_impl->MakeEvidenceRecord(); 
00585 
00586     try
00587     {
00588         //otherwise try to parse it into the m_impl->m_tsr member
00589         (*m_impl->m_evidenceRecord).Decode(msg->GetBuffer(), msg->GetLength());
00590 
00591         m_impl->m_decodeBuf = msg;
00592     }
00593     catch(CPKIFException&)
00594     {
00595         throw CPKIFERSException(TOOLKIT_ERS_ASN, MSG_DECODE_FAILED);
00596     }
00597 }
00598 
00613 void CPKIFEvidenceRecord::SetArchiveTimestampSequence(CPKIFArchiveTimestampSequencePtr& ats)
00614 {
00615     m_impl->m_archiveTimestampSequence = ats;
00616 }

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