TimeStampRequest.cpp

Go to the documentation of this file.
00001 
00010 #include "ASN1Helper.h"
00011 #include "AlgorithmIdentifier.h"
00012 #include "Buffer.h"
00013 #include "MessageImprint.h"
00014 #include "OID.h"
00015 
00016 #ifdef WIN32
00017 #include "PKIFCAPIRaw.h"
00018 #endif
00019 
00020 #include "PKIFMessageErrors.h"
00021 #include "PKIFTSP.h"
00022 #include "pkiftsperrors.h"
00023 #include "PKIFX509Extensions2.h"
00024 #include "PKIXTSP.h"
00025 #include "TSPException.h"
00026 #include "TimeStampRequest.h"
00027 #include "ToolkitUtils.h"
00028 #include "IPKIFCryptoMisc.h"
00029 #include "PKIFCryptUtils.h"
00030 #include "X509Extension.h"
00031 #include "private/PKIFTSPMemoryHelper.h"
00032 
00034 
00035 struct CPKIFTimeStampRequestImpl
00036 {
00037     CPKIFTimeStampRequest *m_parent;
00038 
00039     //function to process extensions
00040     void populateExtensionsVector();
00041 
00042     //convenience goo for auto-nonce generation
00043     bool m_bGenerateNonce;
00044     void GenerateNonce() const; //logical const
00045     IPKIFMediator* m_mediator;
00046 
00047     //members for building
00048     int m_version;
00049     CPKIFMessageImprintPtr m_messageImprint;
00050     CPKIFOIDPtr m_policy;
00051     CPKIFStringPtr m_nonce;
00052     bool m_bReqCert;
00053     std::vector<CPKIFX509ExtensionPtr> m_exts;
00054 
00055     //member for decoding
00056     CPKIFASNWrapper<PKIFTSPTimeStampReq>* m_tsr;
00057 
00058     void ClearAllMembers();
00059     void MakeTSR();
00060     void FreeTSR();
00061 
00062     //member to maintain state when calling Set functions
00063     void CallingAllGets();
00064 
00065     CPKIFTimeStampRequest * m_this;
00066 };
00067 
00075 void CPKIFTimeStampRequestImpl::CallingAllGets()
00076 {
00077     LOG_STRING_DEBUG("CPKIFTimeStampRequest::CallingAllGets()", TOOLKIT_TSP_ASN, 0, this);
00078 
00079 
00080     m_parent->GetVersion();
00081     m_parent->GetMessageImprint();
00082     m_parent->GetPolicy();
00083     m_parent->GetNonce();
00084     m_parent->GetReqCert();
00085     populateExtensionsVector();
00086     FreeTSR();
00087 }
00088 
00096 void CPKIFTimeStampRequestImpl::MakeTSR()
00097 {
00098     LOG_STRING_DEBUG("CPKIFTimeStampRequest::MakeTSR()", TOOLKIT_TSP_ASN, 0, this);
00099 
00100     FreeTSR();
00101     m_tsr = new CPKIFASNWrapper<PKIFTSPTimeStampReq>( BEREncPKIFTSPTimeStampReq, BERDecPKIFTSPTimeStampReq );
00102 }
00110 void CPKIFTimeStampRequestImpl::FreeTSR()
00111 {
00112     LOG_STRING_DEBUG("CPKIFTimeStampRequest::FreeTSR()", TOOLKIT_TSP_ASN, 0, this);
00113     if(NULL != m_tsr)
00114         delete m_tsr;
00115     m_tsr = NULL;
00116 }
00117 
00126 void CPKIFTimeStampRequestImpl::ClearAllMembers()
00127 {
00128     LOG_STRING_DEBUG("CPKIFTimeStampRequest::ClearAllMembers()", TOOLKIT_TSP_ASN, 0, this);
00129 
00130     m_version = PKIFTSPv1;
00131     m_bGenerateNonce = false;
00132     m_bReqCert = false;
00133 
00134     m_mediator = NULL;
00135 
00136     CPKIFMessageImprintPtr tmpMI;
00137     m_messageImprint = tmpMI;
00138 
00139     CPKIFOIDPtr tmpOID;
00140     m_policy = tmpOID;
00141     
00142     CPKIFStringPtr tmpStr;
00143     m_nonce = tmpStr;
00144 
00145     FreeTSR();
00146 }
00147 
00155 void CPKIFTimeStampRequestImpl::GenerateNonce() const
00156 {
00157     LOG_STRING_DEBUG("CPKIFTimeStampRequest::GenerateNonce()", TOOLKIT_TSP_ASN, 0, this);
00158 
00159     IPKIFCryptoMisc* iMisc = NULL;
00160     if(NULL != m_mediator)
00161         iMisc = m_mediator->GetMediator<IPKIFCryptoMisc>();
00162 
00163     unsigned char buf[20];
00164     memset(buf, 0, 20); //avoid (unlikely) case of sending random memory to TSA
00165 
00166     if(NULL != iMisc)
00167     {
00168         //if we can get a pointer to an externally provided interface use it
00169         iMisc->GenRandom(buf, 20);
00170     }
00171     else
00172     {
00173         //otherwise create a temp object to generate the nonce
00174  
00175         IPKIFCryptoMisc *raw = GetPlatformCryptoMisc();
00176         raw->GenRandom(buf, 20);
00177                 
00178         //CPKIFCAPIRaw raw;
00179         //raw.GenRandom(buf, 20);
00180     }
00181 
00182     //need to put nonce in Objective format, i.e. ASCII hex preceded by 0x, in a CPKIFStringPtr
00183     std::string* asciiStr = new std::string();
00184     asciiStr->reserve(50);
00185     char* asciiBuf = const_cast<char*>(asciiStr->data());
00186     asciiBuf[0] = '0';
00187     asciiBuf[1] = 'x';
00188 
00189     //added 7/25/2004 - strip leading zeroes
00190     const unsigned char* bufEnd = buf + 20;
00191     unsigned char* bufP = buf;
00192     int nonZeroLen = 20;
00193     while(*bufP == 0x00)
00194     {
00195         ++bufP;
00196         --nonZeroLen;
00197     }
00198 
00199     //added leading zero handling 6/16/2004
00200     if(0x80 & bufP[0])
00201     {
00202         asciiBuf[2] = '0';
00203         btoa((char*)bufP, asciiBuf+3, nonZeroLen);
00204     }
00205     else
00206         btoa((char*)bufP, asciiBuf+2, nonZeroLen);
00207 
00208     CPKIFStringPtr tmpNonce(asciiStr);
00209 
00210     CPKIFTimeStampRequestImpl* nonConst = const_cast<CPKIFTimeStampRequestImpl*>(this);
00211     nonConst->m_nonce = tmpNonce;
00212 }
00213 
00224 void CPKIFTimeStampRequestImpl::populateExtensionsVector()
00225 {
00226     LOG_STRING_DEBUG("CPKIFTimeStampRequest::populateExtensionsVector()", TOOLKIT_TSP_ASN, 0, this);
00227 
00228     if(NULL == m_tsr || NULL == m_tsr->data())
00229         return;
00230 
00231     //if we've already populated the extensions vector then return
00232     if(!m_exts.empty())
00233         return;
00234 
00235     //if there are no extensions then return
00236     if(0 == (*m_tsr)->m.extensionsPresent)
00237     {
00238         m_exts.clear();
00239         return;
00240     }
00241 
00242     // get the one and only extension mediator, with any additions an app might
00243     // have made
00244     CPKIFX509ExtensionMediator2 * mediator = CPKIFX509ExtensionMediator2::GetInstance();
00245 
00246     m_this->IPKIFHasExtensions::GetExtensions (mediator, m_exts);
00247 }
00248 
00250 
00258 void CPKIFTimeStampRequest::GetExtensionByOID(
00260     const CPKIFOID& oid,    
00262     CPKIFX509ExtensionPtr& ref)
00263 {
00264     if(m_impl->m_exts.empty() && 0 != (*m_impl->m_tsr)->m.extensionsPresent)
00265     m_impl->populateExtensionsVector();
00266     
00267     std::vector<CPKIFX509ExtensionPtr>::iterator pos;
00268     std::vector<CPKIFX509ExtensionPtr>::iterator end = m_impl->m_exts.end();
00269     for(pos = m_impl->m_exts.begin(); pos != end; ++pos)
00270     {
00271     if(oid == (*pos)->oid())
00272     {
00273         ref = *pos;
00274         return;
00275     }
00276     }       
00277 }
00278 
00288 CPKIFTimeStampRequest::CPKIFTimeStampRequest()
00289   :m_impl(new CPKIFTimeStampRequestImpl)
00290 {
00291     LOG_STRING_DEBUG("CPKIFTimeStampRequest::CPKIFTimeStampRequest()", TOOLKIT_TSP_ASN, 0, this);
00292 
00293     m_impl->m_parent = this;
00294     m_impl->m_version = PKIFTSPv1;
00295     m_impl->m_bGenerateNonce = false;
00296     m_impl->m_bReqCert = false;
00297 
00298     m_impl->m_tsr = NULL;
00299     m_impl->m_mediator = NULL;
00300 
00301     m_impl->m_this = this;
00302 }
00310 CPKIFTimeStampRequest::~CPKIFTimeStampRequest()
00311 {
00312     LOG_STRING_DEBUG("CPKIFTimeStampRequest::~CPKIFTimeStampRequest()", TOOLKIT_TSP_ASN, 0, this);
00313 
00314     m_impl->FreeTSR();
00315 
00316     if (m_impl) 
00317     {
00318       delete m_impl;
00319     }
00320 }
00321 
00329 int CPKIFTimeStampRequest::GetVersion() const
00330 {
00331     if(NULL != m_impl->m_tsr && NULL != (*m_impl->m_tsr).data() && m_impl->m_version != (*m_impl->m_tsr)->version)
00332     {
00333         LOG_STRING_DEBUG("CPKIFTimeStampRequest::GetVersion()", TOOLKIT_TSP_ASN, 0, this);
00334 
00335         CPKIFTimeStampRequest* nonConst = const_cast<CPKIFTimeStampRequest*>(this);
00336         nonConst->m_impl->m_version = (*m_impl->m_tsr)->version;
00337     }
00338 
00339     return m_impl->m_version;
00340 }
00348 void CPKIFTimeStampRequest::SetMessageImprint(
00351     CPKIFMessageImprintPtr& messageImprint)
00352 {
00353     LOG_STRING_DEBUG("CPKIFTimeStampRequest::SetMessageImprint(CPKIFMessageImprintPtr& messageImprint)", TOOLKIT_TSP_ASN, 0, this);
00354 
00355     //m_impl->CallingAllGets();
00356     m_impl->m_messageImprint = messageImprint;
00357 }
00367 CPKIFMessageImprintPtr CPKIFTimeStampRequest::GetMessageImprint() const
00368 {
00369     //if NULL and the m_impl->m_tsr member is not NULL then we have parsed a message
00370     //and need to return the message imprint from it (otherwise we either haven't
00371     //parsed anything or are building a message and should simply return
00372     //the m_impl->m_messageImprint member)
00373     if(m_impl->m_messageImprint == (CPKIFMessageImprint*)NULL && NULL != m_impl->m_tsr && NULL != (*m_impl->m_tsr).data())
00374     {
00375         LOG_STRING_DEBUG("CPKIFTimeStampRequest::GetMessageImprint()", TOOLKIT_TSP_ASN, 0, this);
00376 
00377         CACASNWRAPPER_CREATE(PKIFTSPMessageImprint, tmiWrapper);
00378         ASN1OpenType *data  = tmiWrapper.Encode(&(*m_impl->m_tsr)->messageImprint);
00379         CPKIFBufferPtr miBuf(new CPKIFBuffer(data->data, data->numocts));
00380 
00381         CPKIFMessageImprint* tmpMI = new CPKIFMessageImprint(miBuf);
00382         //CPKIFMessageImprint* tmpMI = new CPKIFMessageImprint((*m_impl->m_tsr)->messageImprint);
00383         CPKIFMessageImprintPtr tmpRef(tmpMI); 
00384 
00385         CPKIFTimeStampRequest* nonConst = const_cast<CPKIFTimeStampRequest*>(this);
00386         nonConst->m_impl->m_messageImprint = tmpRef;
00387 
00388         if (data)
00389         {
00390           delete data;
00391         }
00392     }
00393 
00394     return m_impl->m_messageImprint;
00395 }
00405 bool CPKIFTimeStampRequest::ExtensionsPresent() const
00406 {
00407     LOG_STRING_DEBUG("CPKIFTimeStampRequest::ExtensionsPresent()", TOOLKIT_TSP_ASN, 0, this);
00408 
00409     if(NULL != m_impl->m_tsr && (*m_impl->m_tsr)->m.extensionsPresent)
00410         return true;
00411     else
00412         return false;
00413 }
00414 
00422 void CPKIFTimeStampRequest::SetPolicy(
00424     CPKIFOIDPtr& policy)
00425 {
00426     LOG_STRING_DEBUG("CPKIFTimeStampRequest::SetPolicy(CPKIFOIDPtr& policy)", TOOLKIT_TSP_ASN, 0, this);
00427 
00428     //m_impl->CallingAllGets();
00429     m_impl->m_policy = policy;
00430 }
00439 CPKIFOIDPtr CPKIFTimeStampRequest::GetPolicy() const
00440 {
00441     //if NULL and the m_impl->m_tsr member is not NULL then we have parsed a message
00442     //and need to return the policy from it (otherwise we either haven't
00443     //parsed anything or are building a message and should simple return
00444     //the m_impl->m_policy member)
00445     if(m_impl->m_policy == (CPKIFOID*)NULL && NULL != m_impl->m_tsr && (*m_impl->m_tsr)->m.reqPolicyPresent)
00446     {
00447         LOG_STRING_DEBUG("CPKIFTimeStampRequest::GetPolicy()", TOOLKIT_TSP_ASN, 0, this);
00448 
00449         CPKIFOID* tmpPolicy = new CPKIFOID((*m_impl->m_tsr)->reqPolicy.subid, (*m_impl->m_tsr)->reqPolicy.numids);
00450         CPKIFOIDPtr tmpRef(tmpPolicy); 
00451 
00452         CPKIFTimeStampRequest* nonConst = const_cast<CPKIFTimeStampRequest*>(this);
00453         nonConst->m_impl->m_policy = tmpRef;
00454     }
00455 
00456     return m_impl->m_policy;
00457 }
00458 
00466 void CPKIFTimeStampRequest::SetNonce(
00469     CPKIFStringPtr& nonce)
00470 {
00471     LOG_STRING_DEBUG("CPKIFTimeStampRequest::SetNonce(CPKIFStringPtr& nonce)", TOOLKIT_TSP_ASN, 0, this);
00472 
00473     //m_impl->CallingAllGets();
00474     m_impl->m_nonce = nonce;
00475 }
00485 const char* CPKIFTimeStampRequest::GetNonce() const
00486 {
00487     //corrected casting of NULL 6/16/2004
00488     if(m_impl->m_nonce == (std::string*)NULL && NULL != m_impl->m_tsr && (*m_impl->m_tsr)->m.noncePresent)
00489     {
00490         LOG_STRING_DEBUG("CPKIFTimeStampRequest::GetNonce()", TOOLKIT_TSP_ASN, 0, this);
00491 
00492         CPKIFStringPtr tmpStr(new std::string((char*)(*m_impl->m_tsr)->nonce));
00493 
00494         CPKIFTimeStampRequest* nonConst = const_cast<CPKIFTimeStampRequest*>(this);
00495         nonConst->m_impl->m_nonce = tmpStr;
00496     }
00497 
00498     if(m_impl->m_nonce == NULL)
00499         return NULL;
00500     else
00501         return m_impl->m_nonce->c_str();
00502 }
00512 void CPKIFTimeStampRequest::SetGenerateNonce(
00514     bool generateNonce, 
00516     IPKIFMediator* m)
00517 {
00518     LOG_STRING_DEBUG("CPKIFTimeStampRequest::SetGenerateNonce(bool generateNonce, IPKIFMediator* m)", TOOLKIT_TSP_ASN, 0, this);
00519 
00520     //m_impl->CallingAllGets();
00521     m_impl->m_bGenerateNonce = generateNonce;
00522     m_impl->m_mediator = m;
00523 }
00531 bool CPKIFTimeStampRequest::GetGenerateNonce() const
00532 {
00533     return m_impl->m_bGenerateNonce;
00534 }
00544 void CPKIFTimeStampRequest::SetReqCert(
00546     bool reqCert)
00547 {
00548     LOG_STRING_DEBUG("CPKIFTimeStampRequest::SetReqCert(bool reqCert)", TOOLKIT_TSP_ASN, 0, this);
00549 
00550     //m_impl->CallingAllGets();
00551     m_impl->m_bReqCert = reqCert;
00552 }
00562 bool CPKIFTimeStampRequest::GetReqCert() const
00563 {
00564     LOG_STRING_DEBUG("CPKIFTimeStampRequest::GetReqCert()", TOOLKIT_TSP_ASN, 0, this);
00565 
00566     CPKIFTimeStampRequest* nonConst = const_cast<CPKIFTimeStampRequest*>(this);
00567     if( NULL != m_impl->m_tsr && 0 != (*m_impl->m_tsr)->certReq)
00568         nonConst->m_impl->m_bReqCert = true;
00569     else
00570         nonConst->m_impl->m_bReqCert = false;
00571     return m_impl->m_bReqCert;
00572 }
00573 
00574 //void CPKIFTimeStampRequest::AddExtension(CPKIFX509ExtensionPtr& ext)
00575 //{
00576 //  CallingAllGets();
00577 //  m_exts.push_back(ext);
00578 //}
00591 CPKIFBufferPtr CPKIFTimeStampRequest::Encode() const
00592 {
00593     LOG_STRING_DEBUG("CPKIFTimeStampRequest::Encode()", TOOLKIT_TSP_ASN, 0, this);
00594 
00595     //Whether the message is being created or regenerated after parsing a previous message
00596     //always create and populate a new request object (use Getxxx functions to access fields).
00597     //throw bad_alloc
00598     PKIFTSPMemoryHelper mhTSPRequest;
00599     mhTSPRequest.pRequest = new PKIFTSPTimeStampReq;
00600     memset(mhTSPRequest.pRequest, 0, sizeof(PKIFTSPTimeStampReq));
00601 
00602     //version - hardcode to 1 for the time being
00603     mhTSPRequest.pRequest->version = PKIFTSPv1;
00604 
00605     //messageImprint
00606     CPKIFMessageImprintPtr mi = GetMessageImprint();
00607     if(mi == (CPKIFMessageImprint*)NULL)
00608     {
00609         throw CPKIFTSPException(TOOLKIT_TSP, TSP_MISSING_REQUIRED_FIELD, "MessageImprint value not specified.");
00610     }
00611     else
00612     {
00613         //hash alg
00614         mhTSPRequest.pRequest->messageImprint.hashAlgorithm.m.parametersPresent = 1;
00615         mhTSPRequest.pRequest->messageImprint.hashAlgorithm.parameters.data = g_nullParams;
00616         mhTSPRequest.pRequest->messageImprint.hashAlgorithm.parameters.numocts = 2;
00617         CPKIFStringPtr str2(new std::string(mi->GetHashAlgorithm()->oid()->ToString()));
00618         ASN1OBJID* tmpOid = ConvertStringToASN1OBJID(str2);
00619 
00620         CopyOID(&mhTSPRequest.pRequest->messageImprint.hashAlgorithm.algorithm, tmpOid);
00621 
00622         if(tmpOid != NULL)
00623             delete tmpOid;
00624         //mhTSPRequest.pRequest->messageImprint.hashAlgorithm.algorithm = *(mi->GetHashAlgorithm()->oid()->raw());
00625 
00626         //hashedMessage
00627         mhTSPRequest.pRequest->messageImprint.hashedMessage.data = mi->GetHashedMessage()->GetBuffer();
00628         mhTSPRequest.pRequest->messageImprint.hashedMessage.numocts = mi->GetHashedMessage()->GetLength();
00629     }
00630 
00631     //reqPolicy
00632     CPKIFOIDPtr policy = GetPolicy();
00633     if(policy != (CPKIFOID*)NULL)
00634     {
00635         CPKIFStringPtr str(new std::string(policy->ToString()));
00636         ASN1OBJID* tmpOid = ConvertStringToASN1OBJID(str);
00637 
00638         CopyOID(&mhTSPRequest.pRequest->reqPolicy, tmpOid);
00639 
00640         if( NULL != tmpOid )
00641             delete tmpOid;
00642 
00643         //mhTSPRequest.pRequest->reqPolicy = *policy->raw();
00644         mhTSPRequest.pRequest->m.reqPolicyPresent = 1;
00645     }
00646 
00647     //nonce
00648     if(m_impl->m_bGenerateNonce)
00649     {
00650         m_impl->GenerateNonce();
00651     }
00652 
00653     const char* nonce = GetNonce();
00654     if(NULL != nonce)
00655     {
00656         mhTSPRequest.pRequest->nonce = (PKIFTSPTSPNonce)nonce;
00657         mhTSPRequest.pRequest->m.noncePresent = 1;
00658     }
00659 
00660     //certReq
00661     if(m_impl->m_bReqCert)
00662     {
00663         //do not set when false (default encoding will not be encoded anyway)
00664         mhTSPRequest.pRequest->certReq = 1;
00665     }
00666 
00667     //extensions
00668     if(!m_impl->m_exts.empty())
00669     {
00670         throw CPKIFTSPException(TOOLKIT_TSP_ASN, COMMON_NOT_IMPLEMENTED, "There is currently no support for including extensions in a CPKIFTimeStampRequest");
00671     }
00672 
00673     CACASNWRAPPER_CREATE(PKIFTSPTimeStampReq, objPDU);
00674     ASN1OpenType* data1 = objPDU.Encode(mhTSPRequest.pRequest);
00675     CPKIFBufferPtr tmp(new CPKIFBuffer(data1->data, data1->numocts));
00676     delete data1;
00677     return tmp;
00678 }
00689 void CPKIFTimeStampRequest::Decode(
00691     CPKIFBufferPtr& msg)
00692 {
00693     LOG_STRING_DEBUG("CPKIFTimeStampRequest::Decode(CPKIFBufferPtr& msg)", TOOLKIT_TSP_ASN, 0, this);
00694 
00695     m_impl->ClearAllMembers();
00696 
00697     //if the input is empty - fail now
00698     if(msg == (CPKIFBuffer*)NULL || 0 == msg->GetLength())
00699     {
00700         throw CPKIFTSPException(TOOLKIT_TSP_ASN, COMMON_INVALID_INPUT);
00701     }
00702 
00703     m_impl->MakeTSR();
00704 
00705     try
00706     {
00707         //otherwise try to parse it into the m_impl->m_tsr member
00708         (*m_impl->m_tsr).Decode(msg->GetBuffer(), msg->GetLength());
00709     }
00710     catch(CPKIFException&)
00711     {
00712         //delete e;
00713         //changed error code 3/2/2004
00714         throw CPKIFTSPException(TOOLKIT_TSP_ASN, MSG_DECODE_FAILED);
00715     }
00716 }
00717 
00725 void CPKIFTimeStampRequest::GetEncodedExtensions (
00727     CPKIFBufferPtr& buf) 
00728 {
00729     try 
00730     {
00731         if ((*m_impl->m_tsr)->m.extensionsPresent)
00732         {
00733             CACASNWRAPPER_CREATE(CACX509V3Extensions, extsWrapper);
00734             ASN1OpenType *data = extsWrapper.Encode (&(*m_impl->m_tsr)->extensions);
00735             CPKIFBufferPtr tmp(new CPKIFBuffer(data->data, data->numocts));
00736             buf = tmp;
00737             delete data;
00738             return;
00739         }
00740     }
00741     catch (... /*CPKIFException& e*/)
00742     {
00743         // How do we want to handle the exception?
00744     }
00745 
00746     CPKIFBufferPtr nullExt;
00747     buf = nullExt;
00748 }

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