EncryptedData.cpp

Go to the documentation of this file.
00001 
00009 #include "EncryptedData.h"
00010 
00011 #include "Attribute.h"
00012 #include "Buffer.h"
00013 #include "EncryptedContentInfo.h"
00014 #include "OID.h"
00015 #include "AlgorithmIdentifier.h"
00016 #include "PKIFBase64.h"
00017 #include "PKIFAlgorithm.h"
00018 
00019 #include "ToolkitUtils.h"
00020 #include "PKIFMessageException.h"
00021 #include "PKIFCMSMessageMemoryHelper.h"
00022 #include "ASN1Helper.h"
00023 
00024 #include "IPKIFCryptoRawOperations.h"
00025 #include "IPKIFCryptoMisc.h"
00026 
00027 #include "PKIFCMSAttributeMediator2.h"
00028 
00029 #include "CryptographicMessageSyntax2004.h"
00030 
00031 #include <iterator>
00032 
00033 //EncodeIVAsOctetString is implemented in EnvelopedData.cpp
00034 void EncodeIVAsOctetString(unsigned char* iv, int ivLen, unsigned char** encodedIV, int* encodedIVLen);
00035 
00036 //declare utility function that's defined in CACCMSUtils.h
00037 void SetupAttributesInObjectiveStructure(CPKIFAttributeList& attrs, DList& objAttrs);
00038 
00040 struct CPKIFEncryptedDataImpl
00041 {
00042     
00043     CPKIFEncryptedData *m_parent;
00044 
00052     CPKIFEncryptedDataImpl () 
00053     {
00054         m_parent = NULL;
00055     }
00063     CPKIFEncryptedDataImpl (CPKIFEncryptedData  *p) 
00064     {
00065         m_parent = p;
00066     }
00067 
00068     CPKIFEncryptedData::CMSVersion m_version;
00069     CPKIFEncryptedContentInfoPtr m_dataToEncrypt;
00070     CPKIFAttributeList m_unprotectedAttributes;
00071 
00072     CPKIFKeyMaterialPtr m_key;
00073 
00074     CPKIFBufferPtr m_decodeBuf; //added 10/20/03
00075 
00076     CPKIFASNWrapper<CACCMSEncryptedData>* m_encryptedData;
00077 
00078     //functions called by encode
00079     void PrepareEncryptedContent(CACCMSEncryptedData* pEnvelopedData);
00080 
00081     IPKIFMediatorPtr m_med;
00082 
00083     //function called by decode
00084     void populateUnsignedAttributesVector(const CACCMSUnsignedAttributes& ua);
00085 
00086     void MakeEncryptedData();
00087     void FreeEncryptedData();
00088 };
00090 
00091 
00092 //*****************************************************************************
00093 //  constructors, destructors, makzenfriez
00094 //*****************************************************************************
00103 CPKIFEncryptedData::CPKIFEncryptedData()
00104     :m_impl (new CPKIFEncryptedDataImpl)
00105 {
00106     LOG_STRING_DEBUG("CPKIFEncryptedData::CPKIFEncryptedData()", TOOLKIT_CRYPTO_MISC, 0, this);
00107 
00108     m_impl->m_parent = this;
00109     m_impl->m_version = CMSv0;
00110     m_impl->m_encryptedData = NULL;
00111 
00112     m_impl->MakeEncryptedData();
00113 
00114     SetContentType(g_encryptedData);
00115 }
00123 CPKIFEncryptedData::~CPKIFEncryptedData()
00124 {
00125     LOG_STRING_DEBUG("CPKIFEncryptedData::~CPKIFEncryptedData()", TOOLKIT_CRYPTO_MISC, 0, this);
00126 
00127     m_impl->FreeEncryptedData();
00128     //RemoveMediatorAssociations();
00129         
00130     delete m_impl;
00131     m_impl = NULL;
00132 
00133 }
00134 
00142 void CPKIFEncryptedData::AddMediator(
00144     IPKIFMediatorPtr& m)
00145 {
00146     m_impl->m_med = m;
00147 }
00155 IPKIFMediatorPtr CPKIFEncryptedData::GetMediator()
00156 {
00157     return m_impl->m_med;
00158 }
00166 void CPKIFEncryptedDataImpl::MakeEncryptedData()
00167 {
00168     LOG_STRING_DEBUG("CPKIFEncryptedData::MakeEncryptedData()", TOOLKIT_CRYPTO_MISC, 0, this);
00169 
00170     FreeEncryptedData();
00171 
00172     //throw bad_alloc (this function is invoked from the constructor and ClearContent)
00173     m_encryptedData = new CPKIFASNWrapper<CACCMSEncryptedData>( BEREncCACCMSEncryptedData, BERDecCACCMSEncryptedData );
00174 }
00182 void CPKIFEncryptedDataImpl::FreeEncryptedData()
00183 {
00184     LOG_STRING_DEBUG("CPKIFEncryptedData::FreeEncryptedData()", TOOLKIT_CRYPTO_MISC, 0, this);
00185 
00186     if(NULL != m_encryptedData)
00187         delete m_encryptedData;
00188     m_encryptedData = NULL;
00189 
00190     CPKIFBufferPtr emptyBP;
00191     m_decodeBuf = emptyBP;
00192 }
00193 
00194 //*****************************************************************************
00195 //  field manipulation functions
00196 //*****************************************************************************
00204 void CPKIFEncryptedData::SetKeyMaterial(
00206     CPKIFKeyMaterialPtr& key)
00207 {
00208     m_impl->m_key = key;
00209 }
00226 CPKIFEncryptedData::CMSVersion CPKIFEncryptedData::GetVersion() const
00227 {
00228     return m_impl->m_version;
00229 }
00239 void CPKIFEncryptedData::SetDataToEncrypt(
00241     CPKIFEncryptedContentInfoPtr& buf)
00242 {
00243     LOG_STRING_DEBUG("CPKIFEncryptedData::SetDataToEncrypt(CPKIFEncryptedContentInfoPtr& buf)", TOOLKIT_CRYPTO_MISC, 0, this);
00244 
00245     //This function can be used to set the data to encrypt to NULL.  It cannot
00246     //be used to set an incomplete data to encrypt structure.
00247     if(buf != (CPKIFEncryptedContentInfo*)NULL)
00248     {
00249         //this object MUST feature a content type oid and some content.
00250         //the alg id will be prepared automatically based on the key material.
00251         CPKIFOIDPtr tmpOID = buf->GetOID();
00252         CPKIFBufferPtr tmpBuf = buf->GetContent();
00253         if(tmpOID == (CPKIFOID*)NULL || tmpBuf == (CPKIFBuffer*)NULL)
00254             throw CPKIFMessageException(thisComponent, COMMON_INVALID_INPUT);
00255     }
00256 
00257     m_impl->m_dataToEncrypt = buf;
00258 }
00270 void CPKIFEncryptedData::AddUnprotectedAttribute(
00273     CPKIFAttributePtr& attr)
00274 {
00275     LOG_STRING_DEBUG("CPKIFEncryptedData::AddUnprotectedAttribute(CPKIFAttributePtr& attr)", TOOLKIT_CRYPTO_MISC, 0, this);
00276 
00277     //accept no NULLs
00278     if(attr == (CPKIFAttribute*)NULL)
00279         throw CPKIFMessageException(thisComponent, COMMON_INVALID_INPUT);
00280 
00281     //If we're adding following a call to decode, then we should first read the attributes
00282     //that were decoded prior to pushing the new attribute into the list.
00283     if(m_impl->m_unprotectedAttributes.empty())
00284     {
00285         CPKIFAttributeList ual;
00286         GetUnprotectedAttributes(ual);
00287     }
00288 
00289     //Push the new attribute into the list.
00290     m_impl->m_unprotectedAttributes.push_back(attr);
00291 }
00300 void CPKIFEncryptedData::GetUnprotectedAttributes(
00302     CPKIFAttributeList& ual)
00303 {
00304     LOG_STRING_DEBUG("CPKIFEncryptedData::GetUnprotectedAttributes(CPKIFAttributeList& ual)", TOOLKIT_CRYPTO_MISC, 0, this);
00305 
00306     ual.clear();
00307 
00308     //If m_unprotectedAttributes is not empty then we've already populated it and need not do so again.
00309     //If it's not empty, then we need to have a decoded object from which attributes will be read.
00310     if(m_impl->m_unprotectedAttributes.empty() && NULL != m_impl->m_encryptedData && NULL != m_impl->m_encryptedData->data() && (*m_impl->m_encryptedData)->m.unprotectedAttrsPresent)
00311         m_impl->populateUnsignedAttributesVector((*m_impl->m_encryptedData)->unprotectedAttrs);
00312 
00313     copy(m_impl->m_unprotectedAttributes.begin(),m_impl->m_unprotectedAttributes.end(), back_inserter(ual));
00314 }
00325 void CPKIFEncryptedData::ClearContent(
00328     bool removeMediatorAssociations)
00329 {
00330     LOG_STRING_DEBUG("CPKIFEncryptedData::ClearContent(bool removeMediatorAssociations)", TOOLKIT_CRYPTO_MISC, 0, this);
00331 
00332     //free and make
00333     m_impl->FreeEncryptedData();
00334     m_impl->MakeEncryptedData();
00335 
00336     //zero the version
00337     m_impl->m_version = CMSv0;
00338 
00339     //create and assign empty smart pointers
00340     CPKIFEncryptedContentInfoPtr tmp;
00341     m_impl->m_dataToEncrypt = tmp;
00342 
00343     m_impl->m_unprotectedAttributes.clear();
00344 
00345     CPKIFKeyMaterialPtr emptyKey;
00346     m_impl->m_key = emptyKey;
00347 
00348     IPKIFMediatorPtr tmp2;
00349     m_impl->m_med = tmp2;
00350 
00351     //added 10/17/2003
00352     //if(removeMediatorAssociations)
00353     //  RemoveMediatorAssociations();
00354 }
00355 
00356 //*****************************************************************************
00357 //  encode and decode functions
00358 //*****************************************************************************
00368 CPKIFBufferPtr CPKIFEncryptedData::Encode()
00369 {
00370     LOG_STRING_DEBUG("CPKIFEncryptedData::Encode()", TOOLKIT_CRYPTO_MISC, 0, this);
00371 
00372     //All memory allocations in this function are decoration of PKIFCMSMessageMemoryHelper.  If an
00373     //allocation fails we let the caller catch bad_alloc.  The destructor for PKIFCMSMessageMemoryHelper
00374     //will handle all cleanup.
00375 
00376     //create a memory helper object containing an Encrypted data structure - throw bad_alloc
00377     PKIFCMSMessageMemoryHelper mhEncryptedData;
00378     mhEncryptedData.pEncryptedData = new CACCMSEncryptedData;
00379     memset(mhEncryptedData.pEncryptedData, 0, sizeof(CACCMSEncryptedData));
00380 
00381     //initialize this to 0 - it will be updated as necessary by one or more of the following calls
00382     //initialization unnecessary thanks to memset above but for clarity...
00383     mhEncryptedData.pEncryptedData->version = CACCMSv0;
00384 
00385     //prepare the encrypted content  
00386     if(m_impl->m_dataToEncrypt != (CPKIFEncryptedContentInfo*)NULL)
00387     {
00388         //if data to encrypt is specified then encrypt it using the specified key
00389         //and create the necessary pieces of EncryptedData
00390         m_impl->PrepareEncryptedContent(mhEncryptedData.pEncryptedData);
00391     }
00392     else
00393     {
00394         //if data to encrypt is not specified then see if there's a copy of decoded encrypted content
00395         //to use (i.e. we're re-encoding after adding an unprotected attribute to an object for which 
00396         //we may not even possess the decryption key).
00397         if(NULL == m_impl->m_encryptedData || NULL == m_impl->m_encryptedData->data() ||
00398             0 == (*m_impl->m_encryptedData)->encryptedContentInfo.encryptedContent.numocts)
00399             throw CPKIFMessageException(thisComponent, COMMON_INVALID_INPUT, "No data to encrypt available.");
00400 
00401         CopyOID(&mhEncryptedData.pEncryptedData->encryptedContentInfo.contentType, &(*m_impl->m_encryptedData)->encryptedContentInfo.contentType);
00402         CopyOID(&mhEncryptedData.pEncryptedData->encryptedContentInfo.contentEncryptionAlgorithm.algorithm, &(*m_impl->m_encryptedData)->encryptedContentInfo.contentEncryptionAlgorithm.algorithm);
00403         mhEncryptedData.pEncryptedData->encryptedContentInfo.contentEncryptionAlgorithm.m.parametersPresent = (*m_impl->m_encryptedData)->encryptedContentInfo.contentEncryptionAlgorithm.m.parametersPresent;
00404         if((*m_impl->m_encryptedData)->encryptedContentInfo.contentEncryptionAlgorithm.m.parametersPresent)
00405         {
00406             mhEncryptedData.pEncryptedData->encryptedContentInfo.contentEncryptionAlgorithm.parameters.data = new unsigned char[(*m_impl->m_encryptedData)->encryptedContentInfo.contentEncryptionAlgorithm.parameters.numocts];
00407             memcpy((void*)mhEncryptedData.pEncryptedData->encryptedContentInfo.contentEncryptionAlgorithm.parameters.data, (*m_impl->m_encryptedData)->encryptedContentInfo.contentEncryptionAlgorithm.parameters.data, (*m_impl->m_encryptedData)->encryptedContentInfo.contentEncryptionAlgorithm.parameters.numocts);
00408             mhEncryptedData.pEncryptedData->encryptedContentInfo.contentEncryptionAlgorithm.parameters.numocts = (*m_impl->m_encryptedData)->encryptedContentInfo.contentEncryptionAlgorithm.parameters.numocts;
00409         }
00410         
00411         mhEncryptedData.pEncryptedData->encryptedContentInfo.m.encryptedContentPresent = 1;
00412         mhEncryptedData.pEncryptedData->encryptedContentInfo.encryptedContent.data = new unsigned char[(*m_impl->m_encryptedData)->encryptedContentInfo.encryptedContent.numocts];
00413         memcpy((void*)mhEncryptedData.pEncryptedData->encryptedContentInfo.encryptedContent.data, (*m_impl->m_encryptedData)->encryptedContentInfo.encryptedContent.data, (*m_impl->m_encryptedData)->encryptedContentInfo.encryptedContent.numocts);
00414         mhEncryptedData.pEncryptedData->encryptedContentInfo.encryptedContent.numocts = (*m_impl->m_encryptedData)->encryptedContentInfo.encryptedContent.numocts;
00415     }
00416     
00417     mhEncryptedData.pEncryptedData->m.unprotectedAttrsPresent = 0;
00418     {//begin unsigned attribute block
00419 
00420         //get all attributes (either by parsing a decoded object or by accessing a previously constructed list)
00421         CPKIFAttributeList sas;
00422         GetUnprotectedAttributes(sas);
00423 
00424         if(!sas.empty())
00425         {
00426             //create Objective representations of each attribute...
00427             SetupAttributesInObjectiveStructure(sas, mhEncryptedData.pEncryptedData->unprotectedAttrs);
00428     
00429             //then set the flag indicating attributes are present and set the version number
00430             mhEncryptedData.pEncryptedData->m.unprotectedAttrsPresent = 1;
00431             mhEncryptedData.pEncryptedData->version = CACCMSv2;
00432         }
00433     }//end unsigned attribute block
00434 
00435     //prepare an ASN 1 object then produce the encoded result
00436     CACASNWRAPPER_CREATE(CACCMSEncryptedData, objPDU);
00437     ASN1OpenType* data1 = objPDU.Encode(mhEncryptedData.pEncryptedData);
00438 
00439     try
00440     {
00441         //copy the buffer info a buffer ptr to be returned to the caller
00442         CPKIFBufferPtr tmp(new CPKIFBuffer((unsigned char*)data1->data, data1->numocts));
00443         delete data1; data1 = NULL;
00444         return tmp;
00445     }
00446     catch(std::bad_alloc& ba)
00447     {
00448         if(data1)
00449             delete data1;
00450         throw ba;
00451     }
00452 }
00465 void CPKIFEncryptedData::Decode(
00468     CPKIFBufferPtr& buf)
00469 {
00470     LOG_STRING_DEBUG("CPKIFEncryptedData::Decode(CPKIFBufferPtr& buf)", TOOLKIT_CRYPTO_MISC, 0, this);
00471 
00472     //if the input is empty - fail now
00473     if(buf == (CPKIFBuffer*)NULL)
00474         throw CPKIFMessageException(thisComponent, COMMON_INVALID_INPUT);
00475 
00476     try
00477     {
00478         //otherwise attempt to decode the buffer into the member Encrypted data structure
00479         (*m_impl->m_encryptedData).Decode(buf->GetBuffer(), buf->GetLength());
00480 
00481         m_impl->m_decodeBuf = buf;
00482 
00483         if(CACCMSv2 == (*m_impl->m_encryptedData)->version)
00484             m_impl->m_version = CPKIFEncryptedData::CMSv2;
00485         else
00486             m_impl->m_version = CPKIFEncryptedData::CMSv0;
00487     }
00488     catch(CPKIFException& e)
00489     {
00490         unsigned char * decoded = NULL;
00491         unsigned long decodedLen;
00492         bool b = PEMDecode((char *)buf->GetBuffer(), &decoded, &decodedLen);
00493         if(b)
00494         {
00495             try
00496             {
00497                 (*m_impl->m_encryptedData).InitContext();
00498                 (*m_impl->m_encryptedData).Decode(decoded, decodedLen);
00499 
00500                 CPKIFBufferPtr tmp(new CPKIFBuffer(decoded, decodedLen));
00501                 m_impl->m_decodeBuf = tmp;
00502 
00503                 if(CACCMSv2 == (*m_impl->m_encryptedData)->version)
00504                     m_impl->m_version = CPKIFEncryptedData::CMSv2;
00505                 else
00506                     m_impl->m_version = CPKIFEncryptedData::CMSv0;
00507 
00508                 if(NULL != decoded)
00509                     delete decoded;
00510 
00511             }catch(CPKIFException& e)
00512             {
00513                 if(NULL != decoded)
00514                     delete decoded;
00515 
00516                 CPKIFMessageException me(thisComponent, MSG_DECODE_FAILED);
00517                 me.push_info(e);
00518                 //delete e;
00519                 throw me;
00520             }
00521         }
00522         else
00523         {
00524             if(NULL != decoded)
00525                 delete decoded;
00526             CPKIFMessageException me(thisComponent, MSG_DECODE_FAILED);
00527             me.push_info(e);
00528             throw me;
00529         }
00530     }
00531 }
00532 
00533 //*****************************************************************************
00534 //  miscellaneous functions
00535 //*****************************************************************************
00550 CPKIFBufferPtr CPKIFEncryptedData::Decrypt()
00551 {
00552     LOG_STRING_DEBUG("CPKIFEncryptedData::Decrypt()", TOOLKIT_CRYPTO_MISC, 0, this);
00553 
00554     //*****************************************************************
00555     //  sanity check the inputs
00556     //      - need to have data to decrypt, a key and an available 
00557     //  IPKIFCryptoRawOperations interface.
00558     //*****************************************************************
00559     if(NULL == GetMediator())
00560         throw CPKIFMessageException(thisComponent, COMMON_MEDIATOR_MISSING, "Mediator is not available.");
00561 
00562     IPKIFCryptoRawOperations* cRaw = GetMediator()->GetMediator<IPKIFCryptoRawOperations>();
00563     if(NULL == cRaw)
00564         throw CPKIFMessageException(thisComponent, COMMON_MEDIATOR_MISSING, "IPKIFCryptoRawOperations interface is not available.");
00565 
00566     if(m_impl->m_key == (CPKIFKeyMaterial*)NULL)
00567         throw CPKIFMessageException(thisComponent, COMMON_INVALID_INPUT, "No key material available in CPKIFEncryptedData::Decrypt.  Call SetKeyMaterial before calling Decrypt.");
00568 
00569     if(NULL == m_impl->m_encryptedData || NULL == m_impl->m_encryptedData->data())
00570         throw CPKIFMessageException(thisComponent, COMMON_INVALID_INPUT, "No data to decrypt available.");
00571 
00572     //*****************************************************************
00573     //  prepare the decrypted content info output
00574     //*****************************************************************
00575     //see if we need to crack an IV out of the alg params
00576     if(ModeRequiresIV(m_impl->m_key->GetMode()))
00577     {
00578         //understanding that we need an IV, see if one is actually present
00579         if(!(*m_impl->m_encryptedData)->encryptedContentInfo.contentEncryptionAlgorithm.m.parametersPresent)
00580         {
00581             throw CPKIFMessageException(thisComponent, MSG_MISSING_PARAMS, "Content encryption mode requires an IV and no IV is present in the data to decrypt.");
00582         }
00583         else
00584         {
00585             //understanding that we need an IV and that one is present, decode the octet string that contains the IV
00586             OOCTXT ctxt;
00587             initContext (&ctxt);
00588             setBERDecBufPtr(&ctxt, (*m_impl->m_encryptedData)->encryptedContentInfo.contentEncryptionAlgorithm.parameters.data, (*m_impl->m_encryptedData)->encryptedContentInfo.contentEncryptionAlgorithm.parameters.numocts, NULL, NULL);
00589 
00590             unsigned char* iv = NULL;
00591             unsigned int ivLen = (*m_impl->m_encryptedData)->encryptedContentInfo.contentEncryptionAlgorithm.parameters.numocts;
00592 
00593             int stat = decodeDynOctStr (&ctxt, (const OSOCTET* *)&iv, (OSUINT32 *)&ivLen, ASN1EXPL, ivLen);
00594             if (stat != ASN_OK)
00595             {
00596                 //clean up the context
00597                 //freeEncodeBuffer(&ctxt);
00598                 //memFreeAll(&ctxt);
00599                 freeContext(&ctxt);
00600 
00601                 throw CPKIFMessageException(TOOLKIT_MESSAGE_ASN, ASN1_DECODE_ERROR, "Failed to decode IV value");
00602             }
00603 
00604             m_impl->m_key->SetIV(iv, ivLen);
00605 
00606             //clean up the context
00607             //freeEncodeBuffer(&ctxt);
00608             //memFreeAll(&ctxt);
00609             freeContext(&ctxt);
00610         }
00611     }
00612 
00613     //allocate a buffer to receive the decrypted content - throw bad_alloc
00614     int nResultLen = (*m_impl->m_encryptedData)->encryptedContentInfo.encryptedContent.numocts;
00615     unsigned char* pResult = new unsigned char[nResultLen];
00616 
00617     try
00618     {
00619         cRaw->Decrypt(*m_impl->m_key, (unsigned char*)(*m_impl->m_encryptedData)->encryptedContentInfo.encryptedContent.data, (*m_impl->m_encryptedData)->encryptedContentInfo.encryptedContent.numocts, pResult, &nResultLen);
00620     }
00621     catch(...)
00622     {
00623         //throw any exception - but first clean up pResult
00624         if(pResult)
00625             delete[] pResult;
00626 
00627         throw;
00628     }
00629 
00630     CPKIFBuffer* pTmpBP = NULL;
00631     try
00632     {
00633         pTmpBP = new CPKIFBuffer(true, pResult, nResultLen);
00634     }
00635     catch(std::bad_alloc& ba)
00636     {
00637         if(pResult)
00638             delete[] pResult;
00639 
00640         throw ba;
00641     }
00642 
00643     CPKIFBufferPtr tmpBP(pTmpBP);
00644 
00645     //having decrypted the content, prepare the pieces of an encrypted content info object and
00646     //store the results in m_dataToEncrypt
00647     CPKIFEncryptedContentInfoPtr tmpECIP(new CPKIFEncryptedContentInfo);
00648     CPKIFOIDPtr tmpECIP_OID(new CPKIFOID((*m_impl->m_encryptedData)->encryptedContentInfo.contentType.subid, 
00649                 (*m_impl->m_encryptedData)->encryptedContentInfo.contentType.numids));
00650     tmpECIP->SetOID(tmpECIP_OID);
00651 
00652     //CPKIFAlgorithmIdentifier creation
00653     CPKIFOIDPtr algOID(new CPKIFOID((*m_impl->m_encryptedData)->encryptedContentInfo.contentEncryptionAlgorithm.algorithm.subid,
00654                         (*m_impl->m_encryptedData)->encryptedContentInfo.contentEncryptionAlgorithm.algorithm.numids));
00655     CPKIFBufferPtr paramBuf;
00656     if((*m_impl->m_encryptedData)->encryptedContentInfo.contentEncryptionAlgorithm.m.parametersPresent)
00657     {
00658         paramBuf = CPKIFBufferPtr(new CPKIFBuffer((*m_impl->m_encryptedData)->encryptedContentInfo.contentEncryptionAlgorithm.parameters.data,
00659                     (*m_impl->m_encryptedData)->encryptedContentInfo.contentEncryptionAlgorithm.parameters.numocts));
00660     
00661     
00662     }
00663     
00664     CPKIFAlgorithmIdentifierPtr tmpECIP_AlgID(new CPKIFAlgorithmIdentifier(algOID, paramBuf)); 
00665     //CPKIFAlgorithmIdentifierPtr tmpECIP_AlgID(new CPKIFAlgorithmIdentifier(*((CACX509V3AlgorithmIdentifier*)&(*m_impl->m_encryptedData)->encryptedContentInfo.contentEncryptionAlgorithm)));
00666     tmpECIP->SetAlgorithmIdentifier(tmpECIP_AlgID);
00667 
00668     tmpECIP->SetContent(tmpBP);
00669     m_impl->m_dataToEncrypt = tmpECIP;
00670 
00671     return tmpBP;
00672 }
00673 
00674 //*****************************************************************************
00675 //  miscellaneous functions
00676 //*****************************************************************************
00689 void CPKIFEncryptedDataImpl::PrepareEncryptedContent(
00691     CACCMSEncryptedData* pEncryptedData)
00692 {
00693     LOG_STRING_DEBUG("CPKIFEncryptedData::PrepareEncryptedContent(CACCMSEncryptedData* pEncryptedData)", TOOLKIT_CRYPTO_MISC, 0, this);
00694 
00695     //This function is only called from CPKIFEncryptedData::Encode.  All memory allocated by this
00696     //function is allocated into objects that will be cleaned up automatically if an exception is
00697     //generated.  Thus, no catch statements are necessary here.
00698 
00699     //*****************************************************************
00700     //  sanity check the inputs
00701     //      - need to have data to encrypt, a key, a pointer
00702     //  to outbound structure and an available IPKIFCryptoRawOperations 
00703     //  interface.
00704     //*****************************************************************
00705     if(NULL == pEncryptedData)
00706         throw CPKIFMessageException(m_parent->thisComponent, COMMON_INVALID_INPUT, "");
00707 
00708     if(m_key == (CPKIFKeyMaterial*)NULL)
00709         throw CPKIFMessageException(m_parent->thisComponent, COMMON_INVALID_INPUT, "No key material has been set via a call to SetKeyMaterial.");
00710 
00711     if(m_dataToEncrypt == (CPKIFEncryptedContentInfo*)NULL)
00712         throw CPKIFMessageException(m_parent->thisComponent, COMMON_INVALID_INPUT, "No data to encrypt is available.");
00713 
00714     if(NULL == m_med)
00715         throw CPKIFMessageException(m_parent->thisComponent, COMMON_MEDIATOR_MISSING, "Mediator is not available.");
00716 
00717     IPKIFCryptoRawOperations* cRaw = m_med->GetMediator<IPKIFCryptoRawOperations>();
00718     if(NULL == cRaw)
00719         throw CPKIFMessageException(m_parent->thisComponent, COMMON_MEDIATOR_MISSING, "IPKIFCryptoRawOperations interface is not available.");
00720 
00721     //*****************************************************************
00722     //  prepare the encrypted content info output
00723     //  EncryptedContentInfo ::= SEQUENCE 
00724     //  {
00725     //      contentType ContentType,
00726     //      contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
00727     //      encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL 
00728     //  }
00729     //*****************************************************************
00730     CPKIFStringPtr str(new std::string(m_dataToEncrypt->GetOID()->ToString()));
00731     ASN1OBJID* tmpOid = ConvertStringToASN1OBJID(str);
00732     CopyOID(&pEncryptedData->encryptedContentInfo.contentType, tmpOid);
00733     if(tmpOid)
00734         delete tmpOid;
00735     //CopyOID(&pEncryptedData->encryptedContentInfo.contentType, m_dataToEncrypt->GetOID()->raw());
00736     CPKIFAlgorithm * algInfo = CPKIFAlgorithm::GetAlg(m_key->GetSymmetricKeyAlgorithm()
00737         ,m_key->GetMode());
00738     CPKIFOIDPtr activeAlg = algInfo->OID();
00739     int keySize = algInfo->KeySize();
00740     int ivSize = algInfo->BlockSize();
00741     bool needIV = algInfo->NeedsIV();
00742     if(!activeAlg) throw CPKIFMessageException(m_parent->thisComponent, COMMON_UNSUPPORTED_ALG);
00743     
00744     CPKIFStringPtr secondStr(new std::string(activeAlg->ToString()));
00745     ASN1OBJID* secondTmpOid = ConvertStringToASN1OBJID(secondStr);
00746     CopyOID(&pEncryptedData->encryptedContentInfo.contentEncryptionAlgorithm.algorithm, secondTmpOid);
00747     if(secondTmpOid)
00748         delete secondTmpOid;
00749     //CopyOID(&pEncryptedData->encryptedContentInfo.contentEncryptionAlgorithm.algorithm, activeAlg->raw());
00750 
00751     const int maxBlock = (MAXBLOCK/8) + 1;
00752     if(needIV)
00753     {
00754         //if we need an IV access the IPKIFCryptoMisc interface
00755         IPKIFCryptoMisc* cMisc = m_med->GetMediator<IPKIFCryptoMisc>();
00756         if(NULL == cMisc)
00757             throw CPKIFMessageException(m_parent->thisComponent, COMMON_MEDIATOR_MISSING, "IPKIFCryptoMisc interface is not available.");
00758 
00759         //generate a random IV
00760         unsigned char iv[maxBlock];
00761         cMisc->GenRandom(iv, ivSize);
00762         m_key->SetIV(iv, ivSize);
00763 
00764         //encode the IV as an octet string the the content enc alg parameters
00765         pEncryptedData->encryptedContentInfo.contentEncryptionAlgorithm.m.parametersPresent = 1;
00766         EncodeIVAsOctetString(iv, ivSize, 
00767             (unsigned char**)&pEncryptedData->encryptedContentInfo.contentEncryptionAlgorithm.parameters.data, 
00768             (int*)&pEncryptedData->encryptedContentInfo.contentEncryptionAlgorithm.parameters.numocts);
00769     }
00770 
00771     //grab a pointer to the content to be encrypted
00772     CPKIFBufferPtr dataToEnc = m_dataToEncrypt->GetContent();
00773 
00774     //overallocate a buffer (the length will be adjusted down by the call to Encrypt)
00775     pEncryptedData->encryptedContentInfo.encryptedContent.numocts = dataToEnc->GetLength() + maxBlock;
00776     pEncryptedData->encryptedContentInfo.encryptedContent.data = new unsigned char[pEncryptedData->encryptedContentInfo.encryptedContent.numocts];
00777 
00778     cRaw->Encrypt(*m_key, (unsigned char*)dataToEnc->GetBuffer(), dataToEnc->GetLength(), 
00779         (unsigned char*)pEncryptedData->encryptedContentInfo.encryptedContent.data, (int*)&pEncryptedData->encryptedContentInfo.encryptedContent.numocts);
00780 
00781     pEncryptedData->encryptedContentInfo.m.encryptedContentPresent = 1;
00782 }
00793 void CPKIFEncryptedDataImpl::populateUnsignedAttributesVector(
00795     const CACCMSUnsignedAttributes& ua)
00796 {
00797     LOG_STRING_DEBUG("CPKIFEncryptedData::populateUnsignedAttributesVector", TOOLKIT_CRYPTO_MISC, 0, this);
00798 
00799     //if we've already populated the extensions vector then return
00800     if(!m_unprotectedAttributes.empty())
00801         return;
00802 
00803     //if there are no extensions then return
00804     if(0 == ua.count)
00805     {
00806         m_unprotectedAttributes.clear();
00807         return;
00808     }
00809 
00810     //create an attributes mediator using the default attribute colleagues and initialize it
00811     CPKIFCMSAttributeMediator2* mediator = CPKIFCMSAttributeMediator2::GetInstance();
00812 
00813     //iterate over the list of extensions and populate the extensions vector
00814     DListNode* cur = ua.head;
00815     for(unsigned int ii = 0; ii < ua.count; ++ii)
00816     {
00817         CACCMSAttribute* attr = (CACCMSAttribute*) cur->data;
00818         CPKIFOIDPtr oid(new CPKIFOID(attr->attrType.subid,attr->attrType.numids));
00819         CPKIFBufferPtr buf(new CPKIFBuffer(attr->attrValues.data, attr->attrValues.numocts));
00820 
00821         m_unprotectedAttributes.push_back(mediator->getAttribute(oid, buf));
00822         //m_unprotectedAttributes.push_back(mediator.getAttribute(*((CACCMSAttribute*)cur->data)));
00823         cur = cur->next;
00824     }
00825 }
00826 
00834 void CPKIFEncryptedData::GetEncodedUnprotectedAttributes (
00836     CPKIFBufferPtr& buf) {
00837   try
00838   {
00839     if (NULL != m_impl->m_encryptedData && NULL != m_impl->m_encryptedData->data() 
00840       && (*m_impl->m_encryptedData)->m.unprotectedAttrsPresent)
00841     {
00842       CACASNWRAPPER_CREATE(CACCMSUnprotectedAttributes, attrWrapper);
00843       ASN1OpenType *data = attrWrapper.Encode (&(*m_impl->m_encryptedData)->unprotectedAttrs);
00844       CPKIFBufferPtr tmp(new CPKIFBuffer(data->data, data->numocts));
00845       buf = tmp;
00846       delete data;
00847       return;
00848     }
00849   } 
00850   catch (...)
00851   {
00852   }
00853 
00854   CPKIFBufferPtr nullExt;
00855   buf = nullExt;
00856 }
00864 void CPKIFEncryptedData::_GetUnprotectedAttributes(
00866     std::vector<CPKIFAttributePtr> attrVector)
00867 {
00868     CPKIFCMSAttributeMediator2* mediator = CPKIFCMSAttributeMediator2::GetInstance();
00869     this->IPKIFHasAttributes::GetUnprotectedAttributes(mediator, attrVector);
00870 }
00878 void CPKIFEncryptedData::GetAddedUnprotectedAttributes(
00880     std::vector<CPKIFAttributePtr>& attr)
00881 {
00882   /*std::vector<CPKIFAttributePtr>*/CPKIFAttributeList::iterator pos;
00883   /*std::vector<CPKIFAttributePtr>*/CPKIFAttributeList::iterator end = m_impl->m_unprotectedAttributes.end();
00884   for (pos = m_impl->m_unprotectedAttributes.begin(); pos != end; pos++)
00885   {
00886     attr.push_back (*pos);
00887   }
00888 }
00896 CPKIFEncryptedContentInfoPtr CPKIFEncryptedData::GetEncryptedData() const
00897 {
00898     if(m_impl->m_dataToEncrypt == (CPKIFEncryptedContentInfo*)NULL)
00899     {
00900         CPKIFEncryptedContentInfoPtr tmpECIP(new CPKIFEncryptedContentInfo());
00901 
00902         //content type is required so if we get here then we have one (if there wasn't one we'd've failed in the parser)
00903         //throw bad_alloc or CPKIFException
00904         CPKIFOIDPtr tmpOID(new CPKIFOID((*m_impl->m_encryptedData)->encryptedContentInfo.contentType.subid, (*m_impl->m_encryptedData)->encryptedContentInfo.contentType.numids));
00905         tmpECIP->SetOID(tmpOID);
00906 
00907         //actual content is optional - add it to the object if it's there...
00908         if((*m_impl->m_encryptedData)->encryptedContentInfo.m.encryptedContentPresent)
00909         {
00910             //throw bad_alloc
00911             CPKIFBufferPtr tmpBuf(new CPKIFBuffer((*m_impl->m_encryptedData)->encryptedContentInfo.encryptedContent.data, (*m_impl->m_encryptedData)->encryptedContentInfo.encryptedContent.numocts));
00912             tmpECIP->SetContent(tmpBuf);
00913         }
00914 
00915         CPKIFOIDPtr tmpContentAlgOID(new CPKIFOID((*m_impl->m_encryptedData)->encryptedContentInfo.contentEncryptionAlgorithm.algorithm.subid, (*m_impl->m_encryptedData)->encryptedContentInfo.contentEncryptionAlgorithm.algorithm.numids));
00916         CPKIFBufferPtr tmpParams;
00917         if((*m_impl->m_encryptedData)->encryptedContentInfo.contentEncryptionAlgorithm.m.parametersPresent)
00918         {
00919             CPKIFBufferPtr newBuf(new CPKIFBuffer((*m_impl->m_encryptedData)->encryptedContentInfo.contentEncryptionAlgorithm.parameters.data, (*m_impl->m_encryptedData)->encryptedContentInfo.contentEncryptionAlgorithm.parameters.numocts));
00920             tmpParams = newBuf;
00921         }
00922         
00923         CPKIFAlgorithmIdentifierPtr contentAlg(new CPKIFAlgorithmIdentifier(tmpContentAlgOID, tmpParams));
00924         tmpECIP->SetAlgorithmIdentifier(contentAlg);
00925 
00926         //save the new ecip
00927         CPKIFEncryptedData* nonConst = const_cast<CPKIFEncryptedData*>(this);
00928         nonConst->m_impl->m_dataToEncrypt = tmpECIP;
00929     }
00930 
00931     return m_impl->m_dataToEncrypt;
00932 }

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