EvidenceRecordVerifier.cpp
Go to the documentation of this file.00001
00009
00010 #include "pkif.h"
00011 #include "PKIFAlgorithm.h"
00012 #include "PKIFCryptUtils.h"
00013
00014
00015 #include "PKIFCMS.h"
00016
00017
00018 #include "ArchiveTimestamp.h"
00019 #include "EvidenceRecord.h"
00020 #include "EvidenceRecordVerifier.h"
00021 #include "IPKIFSecuritySuitability.h"
00022
00023
00024 #include "PKIFTSP.h"
00025
00026 #include <stdexcept>
00027 #include <cstring>
00028 #include <iterator>
00029
00030
00031
00032
00034 struct PKIFEvidenceRecordVerifierImpl
00035 {
00036
00037 CPKIFBufferPtr m_orig;
00038 CPKIFParallelHashPtr m_ph;
00039
00040 IPKIFMediatorPtr m_currentMediator;
00041 CPKIFPathSettingsPtr m_currentPS;
00042
00043 IPKIFSecuritySuitabilityPtr m_ssp;
00044
00045 std::vector<CPKIFExMediatorPtr> m_archiveMediators;
00046 std::vector<CPKIFExPathSettingsPtr> m_archivePathSettings;
00047
00048 CPKIFBufferPtr GetHash(PKIFCRYPTO::HASH_ALG ha, IPKIFMediatorPtr& m);
00049
00050 IPKIFMediatorPtr GetMediator(CPKIFTimePtr& toi);
00051 CPKIFPathSettingsPtr GetPathSettings(CPKIFTimePtr& toi);
00052
00053 SeqResultsPtr m_seqResults;
00054 };
00062 IPKIFMediatorPtr PKIFEvidenceRecordVerifierImpl::GetMediator(CPKIFTimePtr& toi)
00063 {
00064 IPKIFMediatorPtr empty;
00065 CPKIFTimePtr highWater;
00066
00067
00068 std::vector<CPKIFExMediatorPtr>::iterator pos;
00069 std::vector<CPKIFExMediatorPtr>::iterator end = m_archiveMediators.end();
00070 for(pos = m_archiveMediators.begin(); pos != end; ++pos)
00071 {
00072 CPKIFTimePtr notBefore = (*pos)->first->notBefore();
00073 CPKIFTimePtr notAfter = (*pos)->first->notAfter();
00074
00075 if(*notBefore <= *toi && *toi <= *notAfter)
00076 return (*pos)->second;
00077
00078 if(!highWater || *highWater < *notAfter)
00079 highWater = notAfter;
00080 }
00081
00082
00083
00084 if(m_archiveMediators.empty())
00085 return m_currentMediator;
00086 else if(highWater && *toi > *highWater)
00087 return m_currentMediator;
00088 else
00089 return empty;
00090 }
00098 CPKIFPathSettingsPtr PKIFEvidenceRecordVerifierImpl::GetPathSettings(CPKIFTimePtr& toi)
00099 {
00100 CPKIFPathSettingsPtr empty;
00101 CPKIFTimePtr highWater;
00102
00103
00104 std::vector<CPKIFExPathSettingsPtr>::iterator pos;
00105 std::vector<CPKIFExPathSettingsPtr>::iterator end = m_archivePathSettings.end();
00106 for(pos = m_archivePathSettings.begin(); pos != end; ++pos)
00107 {
00108 CPKIFTimePtr notBefore = (*pos)->first->notBefore();
00109 CPKIFTimePtr notAfter = (*pos)->first->notAfter();
00110
00111 if(*notBefore <= *toi && *toi <= *notAfter)
00112 return (*pos)->second;
00113
00114 if(!highWater || *highWater < *notAfter)
00115 highWater = notAfter;
00116 }
00117
00118
00119
00120 if(m_archivePathSettings.empty())
00121 return m_currentPS;
00122 else if(*toi > *highWater)
00123 return m_currentPS;
00124 else
00125 return empty;
00126 }
00134 CPKIFBufferPtr PKIFEvidenceRecordVerifierImpl::GetHash(PKIFCRYPTO::HASH_ALG ha, IPKIFMediatorPtr& m)
00135 {
00136 CPKIFBufferPtr emptyBP;
00137
00138 if(m_orig != (CPKIFBuffer*)NULL)
00139 {
00140 if(m != (IPKIFMediator*)NULL)
00141 {
00142 IPKIFCryptoMisc* cm = m->GetMediator<IPKIFCryptoMisc>();
00143 if(cm)
00144 {
00145 IPKIFHashContext* hc = cm->HashInit(ha);
00146 if(hc)
00147 {
00148 CPKIFBufferPtr newBP(new CPKIFBuffer);
00149 unsigned char* hashResult = newBP->AllocateBuffer(ha);
00150 int resultLen = ha;
00151 cm->HashUpdate(hc, (unsigned char*)m_orig->GetBuffer(), m_orig->GetLength());
00152 cm->HashFinal(hc, hashResult, &resultLen);
00153 delete hc;
00154 return newBP;
00155 }
00156 }
00157 }
00158 }
00159 else if(m_ph != (CPKIFParallelHash*)NULL)
00160 {
00161 HashInfo* hi = m_ph->GetHashInfo(ha);
00162 if(NULL != hi)
00163 {
00164 CPKIFBufferPtr newBP(new CPKIFBuffer(hi->m_hashResult, hi->m_hashAlg));
00165 return newBP;
00166 }
00167 }
00168
00169 return emptyBP;
00170 }
00172
00180 CPKIFTimePtr GetTimeFromTimestamp(
00182 CPKIFContentInfoPtr& ci)
00183 {
00184 CPKIFTimePtr emptyTime;
00185
00186
00187 CPKIFTSTInfoPtr tstInfo;
00188
00189 CPKIFSignedData sd;
00190
00191 try
00192 {
00193
00194 CPKIFBufferPtr content = ci->GetContent();
00195 sd.Decode(content);
00196 }
00197 catch(CPKIFException&)
00198 {
00199 return emptyTime;
00200 }
00201
00202 CPKIFEncapsulatedContentInfoPtr ecip = sd.GetEncapsulatedContent();
00203
00204 try
00205 {
00206 CPKIFTSTInfoPtr tmpTstInfo(new CPKIFTSTInfo);
00207
00208
00209 CPKIFBufferPtr content = ecip->GetContent();
00210 tmpTstInfo->Decode(content);
00211
00212 tstInfo = tmpTstInfo;
00213 }
00214 catch(CPKIFException&)
00215 {
00216 return emptyTime;
00217 }
00218
00219 return tstInfo->GetGeneralizedTime();
00220 }
00228 CPKIFAlgorithmIdentifierPtr GetHashAlgorithmFromTimestamp(
00230 CPKIFContentInfoPtr& ci)
00231 {
00232 CPKIFAlgorithmIdentifierPtr emptyHashAlg;
00233
00234
00235 CPKIFTSTInfoPtr tstInfo;
00236
00237 CPKIFSignedData sd;
00238
00239 try
00240 {
00241
00242 CPKIFBufferPtr content = ci->GetContent();
00243 sd.Decode(content);
00244 }
00245 catch(CPKIFException&)
00246 {
00247 return emptyHashAlg;
00248 }
00249
00250 CPKIFEncapsulatedContentInfoPtr ecip = sd.GetEncapsulatedContent();
00251
00252 try
00253 {
00254 CPKIFTSTInfoPtr tmpTstInfo(new CPKIFTSTInfo);
00255
00256
00257 CPKIFBufferPtr content = ecip->GetContent();
00258 tmpTstInfo->Decode(content);
00259
00260 tstInfo = tmpTstInfo;
00261 }
00262 catch(CPKIFException&)
00263 {
00264 return emptyHashAlg;
00265 }
00266
00267
00268 CPKIFMessageImprintPtr mi = tstInfo->GetMessageImprint();
00269 if(!mi)
00270 return emptyHashAlg;
00271
00272
00273 return mi->GetHashAlgorithm();
00274 }
00275
00286 CPKIFBufferPtr HashBuffer(
00288 CPKIFAlgorithm* ha,
00290 CPKIFBufferPtr& bp,
00292 IPKIFMediatorPtr& m)
00293 {
00294 CPKIFBufferPtr rv;
00295 IPKIFCryptoMisc* cm = NULL;
00296
00297
00298 if(m)
00299 cm = m->GetMediator<IPKIFCryptoMisc>();
00300
00301
00302 if(!cm)
00303 cm = GetPlatformCryptoMisc();
00304
00305
00306 if(!cm)
00307 return rv;
00308
00309
00310 CPKIFBufferPtr tmpBP(new CPKIFBuffer);
00311 IPKIFHashContext* h = NULL;
00312
00313 try
00314 {
00315
00316 h = cm->HashInit(ha->HashAlg());
00317
00318 cm->HashUpdate(h, (unsigned char*)bp->GetBuffer(), bp->GetLength());
00319
00320 int outBufLen = ha->DigestSize();
00321 unsigned char* outBuf = tmpBP->AllocateBuffer(outBufLen);
00322
00323 cm->HashFinal(h, outBuf, &outBufLen);
00324
00325 delete h; h = NULL;
00326 }
00327 catch(CPKIFException&)
00328 {
00329 if(h) delete h;
00330 }
00331 catch(...)
00332 {
00333 if(h) delete h;
00334 }
00335
00336 rv = tmpBP;
00337 return rv;
00338 }
00339
00340
00341
00342
00350 CPKIFEvidenceRecordVerifier::CPKIFEvidenceRecordVerifier(void) : m_impl(new PKIFEvidenceRecordVerifierImpl)
00351 {
00352 }
00360 CPKIFEvidenceRecordVerifier::~CPKIFEvidenceRecordVerifier(void)
00361 {
00362 if(m_impl)
00363 delete m_impl;
00364 }
00372 void CPKIFEvidenceRecordVerifier::SetCurrentMediator(
00374 IPKIFMediatorPtr& currentMediator)
00375 {
00376 m_impl->m_currentMediator = currentMediator;
00377 }
00385 IPKIFMediatorPtr CPKIFEvidenceRecordVerifier::GetCurrentMediator()
00386 {
00387 return m_impl->m_currentMediator;
00388 }
00396 void CPKIFEvidenceRecordVerifier::SetCurrentPathSettings(CPKIFPathSettingsPtr& currentPS)
00397 {
00398 m_impl->m_currentPS = currentPS;
00399 }
00407 CPKIFPathSettingsPtr CPKIFEvidenceRecordVerifier::GetCurrentPathSettings()
00408 {
00409 return m_impl->m_currentPS;
00410 }
00418 IPKIFMediatorPtr CPKIFEvidenceRecordVerifier::GetArchiveMediator(CPKIFTimePtr& t)
00419 {
00420 std::vector<CPKIFExMediatorPtr>::iterator pos;
00421 std::vector<CPKIFExMediatorPtr>::iterator end = m_impl->m_archiveMediators.end();
00422 for(pos = m_impl->m_archiveMediators.begin(); pos != end; ++pos)
00423 {
00424 CPKIFTimePtr notBefore = (*pos)->first->notBefore();
00425 CPKIFTimePtr notAfter = (*pos)->first->notAfter();
00426 if(*t > *notBefore && *t < *notAfter)
00427 return (*pos)->second;
00428 }
00429
00430 IPKIFMediatorPtr empty;
00431 return empty;
00432 }
00440 void CPKIFEvidenceRecordVerifier::AddArchiveMediator(CPKIFExMediatorPtr& archiveMediator)
00441 {
00442 m_impl->m_archiveMediators.push_back(archiveMediator);
00443 }
00451 void CPKIFEvidenceRecordVerifier::GetArchiveMediators(
00453 std::vector<CPKIFExMediatorPtr>& v) const
00454 {
00455 v.clear();
00456 copy(m_impl->m_archiveMediators.begin(),m_impl->m_archiveMediators.end(),back_inserter(v));
00457 }
00465 CPKIFPathSettingsPtr CPKIFEvidenceRecordVerifier::GetArchivePathSettings(CPKIFTimePtr& t)
00466 {
00467 std::vector<CPKIFExPathSettingsPtr>::iterator pos;
00468 std::vector<CPKIFExPathSettingsPtr>::iterator end = m_impl->m_archivePathSettings.end();
00469 for(pos = m_impl->m_archivePathSettings.begin(); pos != end; ++pos)
00470 {
00471 CPKIFTimePtr notBefore = (*pos)->first->notBefore();
00472 CPKIFTimePtr notAfter = (*pos)->first->notAfter();
00473 if(*t > *notBefore && *t < *notAfter)
00474 return (*pos)->second;
00475 }
00476
00477 CPKIFPathSettingsPtr empty;
00478 return empty;
00479 }
00487 void CPKIFEvidenceRecordVerifier::AddArchivePathSettings(
00489 CPKIFExPathSettingsPtr& ps)
00490 {
00491 m_impl->m_archivePathSettings.push_back(ps);
00492 }
00500 void CPKIFEvidenceRecordVerifier::GetArchivePathSettings(
00502 std::vector<CPKIFExPathSettingsPtr>& v) const
00503 {
00504 v.clear();
00505 copy(m_impl->m_archivePathSettings.begin(),m_impl->m_archivePathSettings.end(),back_inserter(v));
00506 }
00514 void CPKIFEvidenceRecordVerifier::SetDataComplete(CPKIFBufferPtr& origData)
00515 {
00516 m_impl->m_orig = origData;
00517 }
00525 void CPKIFEvidenceRecordVerifier::SetDataHashSet(CPKIFParallelHashPtr& ph)
00526 {
00527 m_impl->m_ph = ph;
00528 }
00536 CPKIFBufferPtr CPKIFEvidenceRecordVerifier::GetHash(PKIFCRYPTO::HASH_ALG ha, IPKIFMediatorPtr& m)
00537 {
00538 return m_impl->GetHash(ha, m);
00539 }
00547 void CPKIFEvidenceRecordVerifier::SetSecuritySuitabilityPolicy(const IPKIFSecuritySuitabilityPtr& ssp)
00548 {
00549 m_impl->m_ssp = ssp;
00550 }
00558 IPKIFSecuritySuitabilityPtr CPKIFEvidenceRecordVerifier::GetSecuritySuitabilityPolicy() const
00559 {
00560 return m_impl->m_ssp;
00561 }
00562
00579 SeqResultsPtr CPKIFEvidenceRecordVerifier::Verify(CPKIFEvidenceRecordPtr& er)
00580 {
00581
00582
00583 IPKIFMediatorPtr activeMediator = m_impl->m_currentMediator;
00584 CPKIFPathSettingsPtr activePathSettings = m_impl->m_currentPS;
00585 CPKIFTimePtr timeOfInterest = CPKIFTime::CurrentTime();
00586
00587
00588 if(!er)
00589 {
00590 }
00591
00592
00593 if(1 != er->GetVersion())
00594 {
00595 }
00596
00597
00598
00599
00600
00601
00602 CPKIFArchiveTimestampSequencePtr seq = er->GetArchiveTimestampSequence();
00603 SeqResultsPtr seqResults(new SeqResults);
00604
00605 CPKIFArchiveTimestampSequence::reverse_iterator rSeqPos = seq->rbegin();
00606 CPKIFArchiveTimestampSequence::reverse_iterator rSeqEnd = seq->rend();
00607 while(rSeqPos != rSeqEnd)
00608 {
00609 CPKIFArchiveTimestampChainPtr chain = (*rSeqPos);
00610
00611 ChainResultsPtr cr(new ChainResults);
00612 seqResults->push_back(cr);
00613
00614 CPKIFArchiveTimestampChain::reverse_iterator rChainPos = chain->rbegin();
00615 CPKIFArchiveTimestampChain::reverse_iterator rChainEnd = chain->rend();
00616 while(rChainPos != rChainEnd)
00617 {
00618 CPKIFArchiveTimestampPtr curAts = (*rChainPos);
00619 CPKIFContentInfoPtr curTimestamp = curAts->GetTimestamp();
00620
00621 CPKIFAlgorithmIdentifierPtr curHashAlgId = GetHashAlgorithmFromTimestamp(curTimestamp);
00622 CPKIFAlgorithm* pHa = CPKIFAlgorithm::GetAlg(curHashAlgId->oid());
00623 PKIFCRYPTO::HASH_ALG curHashAlg = pHa->HashAlg();
00624
00625 if(m_impl->m_ssp)
00626 {
00627 if(!m_impl->m_ssp->IsAlgorithmSuitable(curHashAlgId))
00628 {
00629 throw std::runtime_error("Unsuitable hash algorithm in timestamp.");
00630 }
00631 }
00632
00633 CPKIFTimestampVerifierPtr tv(new CPKIFTimestampVerifier);
00634
00635 ++rChainPos;
00636 if(rChainPos == rChainEnd)
00637 {
00638 ++rSeqPos;
00639 if(rSeqPos == rSeqEnd)
00640 {
00641
00642 CPKIFBufferPtr hashOfData = GetHash(curHashAlg, activeMediator);
00643 tv->SetDataHash(hashOfData, curHashAlg);
00644 }
00645 else
00646 {
00647
00648
00649 chain = *rSeqPos;
00650
00651 CPKIFBufferPtr hashOfData = GetHash(curHashAlg, activeMediator);
00652 CPKIFBufferPtr hashOfChain = CalculateHashOfArchiveTimestampChain(chain, activeMediator, curHashAlg);
00653
00654 CPKIFBufferPtr tmpBuf(new CPKIFBuffer);
00655 unsigned char* pTmpBuf = tmpBuf->AllocateBuffer(hashOfData->GetLength() + hashOfChain->GetLength());
00656 memcpy(pTmpBuf, hashOfData->GetBuffer(), hashOfData->GetLength());
00657 memcpy(pTmpBuf+hashOfData->GetLength(),hashOfChain->GetBuffer(), hashOfChain->GetLength());
00658
00659 tv->SetDataComplete(tmpBuf);
00660 }
00661 }
00662 else
00663 {
00664
00665
00666 CPKIFArchiveTimestampPtr prevAts = *rChainPos;
00667
00668
00669 CPKIFContentInfoPtr ci = prevAts->GetTimestamp();
00670
00671 CPKIFBufferPtr encodedTimestamp = ci->Encode();
00672 tv->SetDataComplete(encodedTimestamp);
00673 }
00674
00675 tv->SetComparisonTime(timeOfInterest);
00676 tv->SetMediator(activeMediator);
00677 tv->SetPathSettings(activePathSettings);
00678 tv->Verify(curTimestamp);
00679
00680 cr->push_back(tv);
00681
00682 timeOfInterest = GetTimeFromTimestamp(curTimestamp);
00683 activeMediator = m_impl->GetMediator(timeOfInterest);
00684 activePathSettings = m_impl->GetPathSettings(timeOfInterest);
00685 }
00686 }
00687
00688 return seqResults;
00689 }