EnvelopedData.cpp

Go to the documentation of this file.
00001 
00009 #include "EnvelopedData.h"
00010 #include "private/PrivatePKIFCMSUtils.h"
00011 
00012 #include "Attribute.h"
00013 #include "Buffer.h"
00014 #include "EncryptedContentInfo.h"
00015 #include "OID.h"
00016 #include "AlgorithmIdentifier.h"
00017 #include "KEKRecipInfoDetails.h"
00018 //#include "KARIDetails.h"
00019 #include "RecipientInfo.h"
00020 #include "SubjectKeyIdentifier.h"
00021 #include "SubjectPublicKeyInfo.h"
00022 #include "Name.h"
00023 #include "KeyUsage.h"
00024 #include "Certificate.h"
00025 #include "CRL.h"
00026 
00027 #include "PKIFFuncStorage.h"
00028 #include "ToolkitUtils.h"
00029 #include "PKIFMessageException.h"
00030 #include "PKIFCMSMessageMemoryHelper.h"
00031 #include "ASN1Helper.h"
00032 #include "PKIFBase64.h"
00033 
00034 #include "IPKIFDefaultKeyManagement.h"
00035 #include "IPKIFCryptoKeyIDOperations.h"
00036 #include "IPKIFPathBuild.h"
00037 #include "IPKIFPathValidate.h"
00038 #include "IPKIFCryptoRawOperations.h"
00039 #include "IPKIFCryptoMisc.h"
00040 #include "PKIFAlgorithm.h"
00041 #include "IPKIFCryptoKeyAgree.h"
00042 
00043 #include "PKIFCMSAttributeMediator2.h"
00044 
00045 #include "CryptographicMessageSyntax2004.h"
00046 
00047 #include <iterator>
00048 
00050 struct CPKIFEnvelopedDataImpl
00051 {
00052     
00053 
00054     CPKIFEnvelopedData *m_parent;
00062     CPKIFEnvelopedDataImpl () 
00063     {
00064         m_parent = NULL;
00065     }
00073     CPKIFEnvelopedDataImpl (CPKIFEnvelopedData  *p) 
00074     {
00075         m_parent = p;
00076     }
00077 
00078     CPKIFEnvelopedData::CMSVersion m_version;
00079     CPKIFCertificateList m_certificates;    //originator certs
00080     CPKIFCRLList m_crls;                    //originator crls
00081     CPKIFRecipientInfoList m_recipientInfos;
00082 
00083     CPKIFCertificateList m_recipients;
00084     CPKIFEncryptedContentInfoPtr m_dataToEncrypt;
00085 
00086     CPKIFAttributeList m_unprotectedAttributes;
00087 
00088     CPKIFBufferPtr m_decodeBuf; //added 10/20/03
00089 
00090     CPKIFPathSettingsPtr m_settings;
00091 
00092     CPKIFASNWrapper<CACCMSEnvelopedData>* m_envelopedData;
00093     PKIFCRYPTO::SYMKEY_ALG m_alg;
00094     PKIFCRYPTO::SYMKEY_MODE m_mode;
00095 
00096     CPKIFKEKRecipInfoDetailsList m_keks;
00097     //CPKIFKARIDetailsList m_karis;
00098 
00099     IPKIFMediatorPtr m_med;
00100 
00101     CPKIFCredentialPtr m_cred;
00102 
00103     //functions called by encode
00104     void PrepareEncryptedContent(CACCMSEnvelopedData* pEnvelopedData, unsigned char** keyData, int* keyDataLen);
00105     void PrepareRecipientInfos(CACCMSEnvelopedData* pEnvelopedData, unsigned char* keyData, int keyDataLen);
00106     void PrepareOriginatorInfo(CACCMSEnvelopedData* pEnvelopedData);
00107 
00108     //function called by decode
00109     void populateUnsignedAttributesVector(const CACCMSUnsignedAttributes& ua);
00110 
00111     //functions called by PrepareOriginatorInfo
00112     void AddCerts(CACCMSEnvelopedData* pEnvelopedData);
00113     void AddCRLs(CACCMSEnvelopedData* pEnvelopedData);
00114 
00115     void RemoveRecipInfos(CACCMSEnvelopedData* envelopedData);
00116 
00117     void MakeEnvelopedData();
00118     void FreeEnvelopedData();
00119 };
00121 
00122 
00123 //*****************************************************************************
00124 //  utility functions (implemented in CACCMSUtils.cpp)
00125 //*****************************************************************************
00126 
00127 
00128 //*****************************************************************************
00129 //  constructors, destructors, makzenfriez
00130 //*****************************************************************************
00144 CPKIFEnvelopedData::CPKIFEnvelopedData()
00145     :m_impl (new CPKIFEnvelopedDataImpl)
00146 {
00147     LOG_STRING_DEBUG("CPKIFEnvelopedData::CPKIFEnvelopedData()", TOOLKIT_CRYPTO_MISC, 0, this);
00148     m_impl->m_parent = this;
00149     m_impl->m_version = CMSv0;
00150     m_impl->m_alg = PKIFCRYPTO::TDES;
00151     m_impl->m_mode = PKIFCRYPTO::CBC;
00152 
00153     m_impl->m_envelopedData = NULL;
00154     m_impl->MakeEnvelopedData();
00155 
00156     SetContentType(g_envelopedData);
00157 }
00165 CPKIFEnvelopedData::~CPKIFEnvelopedData()
00166 {
00167     LOG_STRING_DEBUG("CPKIFEnvelopedData::~CPKIFEnvelopedData()", TOOLKIT_CRYPTO_MISC, 0, this);
00168 
00169     m_impl->FreeEnvelopedData();
00170 
00171     //added 10/7/2003
00172     //RemoveMediatorAssociations();
00173 
00174     delete m_impl;
00175     m_impl = NULL;
00176 }
00177 
00185 void CPKIFEnvelopedData::SetMediator(
00187     IPKIFMediatorPtr& m)
00188 {
00189     m_impl->m_med = m;
00190 }
00198 IPKIFMediatorPtr CPKIFEnvelopedData::GetMediator()
00199 {
00200     return m_impl->m_med;
00201 }
00202 
00211 void CPKIFEnvelopedDataImpl::MakeEnvelopedData()
00212 {
00213     LOG_STRING_DEBUG("CPKIFEnvelopedData::MakeEnvelopedData()", TOOLKIT_CRYPTO_MISC, 0, this);
00214 
00215     FreeEnvelopedData();
00216 
00217     //throw bad_alloc (this function is invoked from the constructor and ClearContent)
00218     m_envelopedData = new CPKIFASNWrapper<CACCMSEnvelopedData>( BEREncCACCMSEnvelopedData, BERDecCACCMSEnvelopedData );
00219 }
00227 void CPKIFEnvelopedDataImpl::FreeEnvelopedData()
00228 {
00229     LOG_STRING_DEBUG("CPKIFEnvelopedData::FreeEnvelopedData()", TOOLKIT_CRYPTO_MISC, 0, this);
00230 
00231     if(NULL != m_envelopedData)
00232         delete m_envelopedData;
00233     m_envelopedData = NULL;
00234 
00235     CPKIFBufferPtr emptyBP;
00236     m_decodeBuf = emptyBP;
00237 }
00238 
00239 //*****************************************************************************
00240 //  field manipulation functions
00241 //*****************************************************************************
00249 void CPKIFEnvelopedData::SetAlgorithmAndMode(
00252     PKIFCRYPTO::SYMKEY_ALG alg,
00255     PKIFCRYPTO::SYMKEY_MODE mode)
00256 {
00257     m_impl->m_alg = alg;
00258     m_impl->m_mode = mode;
00259 }
00267 PKIFCRYPTO::SYMKEY_ALG CPKIFEnvelopedData::GetAlgorithm() const
00268 {
00269     return m_impl->m_alg;
00270 }
00278 PKIFCRYPTO::SYMKEY_MODE CPKIFEnvelopedData::GetMode() const
00279 {
00280     return m_impl->m_mode;
00281 }
00282 
00283 //version (required)
00304 CPKIFEnvelopedData::CMSVersion CPKIFEnvelopedData::GetVersion() const
00305 {
00306     return m_impl->m_version;
00307 }
00320 void CPKIFEnvelopedData::SetDataToEncrypt(
00322     CPKIFEncryptedContentInfoPtr& buf)
00323 {
00324     LOG_STRING_DEBUG("CPKIFEnvelopedData::SetDataToEncrypt(CPKIFEncryptedContentInfoPtr& buf)", TOOLKIT_CRYPTO_MISC, 0, this);
00325 
00326     //This function can be used to set the data to encrypt to NULL.  It cannot
00327     //be used to set an incomplete data to encrypt structure.
00328     if(buf != (CPKIFEncryptedContentInfo*)NULL)
00329     {
00330         //this object MUST feature a content type oid and some content.
00331         //the alg id will be prepared automatically based on the key material.
00332         CPKIFOIDPtr tmpOID = buf->GetOID();
00333         CPKIFBufferPtr tmpBuf = buf->GetContent();
00334         if(tmpOID == (CPKIFOID*)NULL || tmpBuf == (CPKIFBuffer*)NULL)
00335             throw CPKIFMessageException(thisComponent, COMMON_INVALID_INPUT);
00336     }
00337 
00338     m_impl->m_dataToEncrypt = buf;
00339 }
00350 void CPKIFEnvelopedData::AddUnprotectedAttribute(
00353     CPKIFAttributePtr& attr)
00354 {
00355     LOG_STRING_DEBUG("CPKIFEnvelopedData::AddUnprotectedAttribute(CPKIFAttributePtr& attr)", TOOLKIT_CRYPTO_MISC, 0, this);
00356 
00357     //accept no NULLs
00358     if(attr == (CPKIFAttribute*)NULL)
00359         throw CPKIFMessageException(thisComponent, COMMON_INVALID_INPUT);
00360 
00361     //If we're adding following a call to decode, then we should first read the attributes
00362     //that were decoded prior to pushing the new attribute into the list.
00363     if(m_impl->m_unprotectedAttributes.empty())
00364     {
00365         CPKIFAttributeList ual;
00366         GetUnprotectedAttributes(ual);
00367     }
00368 
00369     //Push the new attribute into the list.
00370     m_impl->m_unprotectedAttributes.push_back(attr);
00371 }
00380 void CPKIFEnvelopedData::GetUnprotectedAttributes(
00383     CPKIFAttributeList& ual)
00384 {
00385     LOG_STRING_DEBUG("CPKIFEnvelopedData::GetUnprotectedAttributes(CPKIFAttributeList& ual)", TOOLKIT_CRYPTO_MISC, 0, this);
00386 
00387     ual.clear();
00388 
00389     //If m_unprotectedAttributes is not empty then we've already populated it and need not do so again.
00390     //If it's not empty, then we need to have a decoded object from which attributes will be read.
00391     if(m_impl->m_unprotectedAttributes.empty() && NULL != m_impl->m_envelopedData && NULL != m_impl->m_envelopedData->data() && (*m_impl->m_envelopedData)->m.unprotectedAttrsPresent)
00392         m_impl->populateUnsignedAttributesVector((*m_impl->m_envelopedData)->unprotectedAttrs);
00393 
00394     copy(m_impl->m_unprotectedAttributes.begin(),m_impl->m_unprotectedAttributes.end(), back_inserter(ual));
00395 }
00396 
00404 void CPKIFEnvelopedData::ClearContent()
00405 {
00406     LOG_STRING_DEBUG("CPKIFEnvelopedData::ClearContent(bool removeMediatorAssociations)", TOOLKIT_CRYPTO_MISC, 0, this);
00407 
00408     //free and make
00409     m_impl->FreeEnvelopedData();
00410     m_impl->MakeEnvelopedData();
00411 
00412     //zero the version and reset alg and mode
00413     m_impl->m_version = CMSv0;
00414     m_impl->m_alg = PKIFCRYPTO::TDES;
00415     m_impl->m_mode = PKIFCRYPTO::CBC;
00416 
00417     //clear the lists
00418     m_impl->m_certificates.clear();
00419     m_impl->m_crls.clear();
00420     m_impl->m_recipientInfos.clear();
00421     m_impl->m_recipients.clear();
00422 
00423     m_impl->m_unprotectedAttributes.clear();
00424     m_impl->m_keks.clear();
00425     //m_impl->m_karis.clear();
00426 
00427     //create and assign empty smart pointers
00428     CPKIFEncryptedContentInfoPtr tmp;
00429     m_impl->m_dataToEncrypt = tmp;
00430 
00431     CPKIFPathSettingsPtr tmpSettings;
00432     m_impl->m_settings = tmpSettings;
00433 
00434     IPKIFMediatorPtr tmp2;
00435     m_impl->m_med = tmp2;
00436 
00437 }
00438 
00449 void CPKIFEnvelopedData::AddOriginatorCertificate(
00452     CPKIFCertificatePtr& cert) 
00453 {
00454     LOG_STRING_DEBUG("CPKIFEnvelopedData::AddOriginatorCertificate(CPKIFCertificatePtr& cert)", TOOLKIT_CRYPTO_MISC, 0, this);
00455 
00456     //accept no NULLs
00457     if(cert == (CPKIFCertificate*)NULL)
00458         throw CPKIFMessageException(thisComponent, COMMON_INVALID_INPUT);
00459 
00460     //accept no empty certs
00461     CPKIFBufferPtr encCert = cert->Encoded();
00462     if(encCert == (CPKIFBuffer*)NULL || 0 == encCert->GetLength())
00463         throw CPKIFMessageException(thisComponent, COMMON_INVALID_INPUT);
00464 
00465     //if m_certs is empty - see if there are any from a decode operation
00466     if(m_impl->m_certificates.empty())
00467     {
00468         CPKIFCertificateList certs;
00469         GetOriginatorCertificates(certs);
00470     }
00471 
00472     m_impl->m_certificates.push_back(cert);
00473 }
00482 void CPKIFEnvelopedData::GetOriginatorCertificates(
00485     CPKIFCertificateList& certs)
00486 {
00487     LOG_STRING_DEBUG("CPKIFEnvelopedData::GetOriginatorCertificates(CPKIFCertificateList& certs)", TOOLKIT_CRYPTO_MISC, 0, this);
00488 
00489     //return list containing contents of m_certificates plus certs in m_signedData.
00490     //destroy certs in m_signedData after adding them to m_certificates (don't really
00491     //destroy certs - just change flag so they don't get ignored in the future).
00492 
00493     certs.clear();
00494 
00495     //first, update m_certificates with any certs from m_signedData
00496     if(NULL != m_impl->m_envelopedData && NULL != m_impl->m_envelopedData->data() && (*m_impl->m_envelopedData)->m.originatorInfoPresent && (*m_impl->m_envelopedData)->originatorInfo.m.certsPresent)
00497     {
00498         DListNode* iter = (*m_impl->m_envelopedData)->originatorInfo.certs.head;
00499         while(NULL != iter)
00500         {
00501             CACCMSCertificateChoices* curChoice = (CACCMSCertificateChoices*)iter->data;
00502             if(T_CACCMSCertificateChoices_certificate != curChoice->t)
00503             {
00504                 iter = iter->next;
00505                 continue;
00506             }
00507 
00508             ASN1OpenType* cert = (ASN1OpenType*)curChoice->u.certificate;
00509             
00510             try
00511             {
00512                 CPKIFCertificatePtr newCert(new CPKIFCertificate());
00513                 newCert->Decode(cert->data, cert->numocts);
00514                 m_impl->m_certificates.push_back(newCert);
00515             }
00516             catch(CPKIFException&)
00517             {
00518                 //as with invalid certs in a directory entry, don't fail if we can't 
00519                 //parse a cert - just don't collect it
00520             }
00521             catch(std::bad_alloc& ba)
00522             {
00523                 //empty the list and throw the exception
00524                 m_impl->m_certificates.clear();
00525                 throw ba;
00526             }
00527 
00528             iter = iter->next;
00529         }
00530 
00531         //change the flag on the data so we don't execute this condition again
00532         (*m_impl->m_envelopedData)->originatorInfo.m.certsPresent = 0;
00533     }
00534 
00535     //next, copy the contents of the m_certificates list to the certs list
00536     copy(m_impl->m_certificates.begin(), m_impl->m_certificates.end(), back_inserter(certs));
00537 }
00547 void CPKIFEnvelopedData::AddOriginatorCRL(
00550     CPKIFCRLPtr& crl) 
00551 {
00552     LOG_STRING_DEBUG("CPKIFEnvelopedData::AddOriginatorCRL(CPKIFCRLPtr& crl)", TOOLKIT_CRYPTO_MISC, 0, this);
00553 
00554     //accept no NULLs
00555     if(crl == (CPKIFCRL*)NULL)
00556         throw CPKIFMessageException(thisComponent, COMMON_INVALID_INPUT);
00557 
00558     //accept no empty certs
00559     CPKIFBufferPtr encCRL = crl->Encoded();
00560     if(encCRL == (CPKIFBuffer*)NULL || 0 == encCRL->GetLength())
00561         throw CPKIFMessageException(thisComponent, COMMON_INVALID_INPUT);
00562 
00563     //if m_crls is empty - see if there are any from a decode operation
00564     if(m_impl->m_crls.empty())
00565     {
00566         CPKIFCRLList crls;
00567         GetOriginatorCRLs(crls);
00568     }
00569 
00570     m_impl->m_crls.push_back(crl);
00571 }
00572 
00587 void CPKIFEnvelopedData::SetOriginatorCredential(CPKIFCredentialPtr & cred)
00588 {
00589     m_impl->m_cred = cred;
00590 }
00591 
00599 void CPKIFEnvelopedData::GetOriginatorCRLs(
00602     CPKIFCRLList& crls)
00603 {
00604     LOG_STRING_DEBUG("CPKIFEnvelopedData::GetOriginatorCRLs(CPKIFCRLList& crls)", TOOLKIT_CRYPTO_MISC, 0, this);
00605 
00606     //return list containing contents of m_crls plus crls in m_signedData.
00607     //destroy crls in m_signedData after adding them to m_crls (don't really
00608     //destroy crls - just change flag so they don't get ignored in the future).
00609 
00610     crls.clear();
00611 
00612     //first, update m_crls with any crls from m_signedData
00613     if(NULL != m_impl->m_envelopedData && NULL != m_impl->m_envelopedData->data() && (*m_impl->m_envelopedData)->m.originatorInfoPresent && (*m_impl->m_envelopedData)->originatorInfo.m.crlsPresent)
00614     {
00615         DListNode* iter = (*m_impl->m_envelopedData)->originatorInfo.crls.head;
00616         while(NULL != iter)
00617         {
00618             CACCMSRevocationInfoChoice* curChoice = (CACCMSRevocationInfoChoice*)iter->data;
00619 
00620             if(T_CACCMSRevocationInfoChoice_crl != curChoice->t)
00621             {
00622                 iter = iter->next;
00623                 continue;
00624             }
00625 
00626             ASN1OpenType* crl = (ASN1OpenType*)curChoice->u.crl;
00627             
00628             try
00629             {
00630                 CPKIFCRLPtr newCRL(new CPKIFCRL());
00631                 newCRL->Decode(crl->data, crl->numocts);
00632                 m_impl->m_crls.push_back(newCRL);
00633             }
00634             catch(CPKIFException&)
00635             {
00636                 //as with invalid crls in a directory entry, don't fail if we can't 
00637                 //parse a crl - just don't collect it
00638             }
00639             catch(std::bad_alloc& ba)
00640             {
00641                 //empty the list and throw the exception
00642                 m_impl->m_certificates.clear();
00643                 throw ba;
00644             }
00645     
00646             iter = iter->next;
00647         }
00648 
00649         //change the flag on the data so we don't execute this condition again
00650         (*m_impl->m_envelopedData)->originatorInfo.m.crlsPresent = 0;
00651     }
00652 
00653     //next, copy the contents of the m_crls list to the crls list
00654     copy(m_impl->m_crls.begin(), m_impl->m_crls.end(), back_inserter(crls));
00655 }
00702 void CPKIFEnvelopedData::AddRecipient(
00706     CPKIFCertificatePtr& cert,
00712     CMSPathValidationStatus minStatus) 
00713 {
00714     LOG_STRING_DEBUG("CPKIFEnvelopedData::AddRecipient(CPKIFCertificatePtr& cert, CMSPathValidationStatus minStatus)", TOOLKIT_CRYPTO_MISC, 0, this);
00715 
00716     //NULL and empty checks are performed in the version of AddRecipient that is called below
00717 
00718     //throw bad_allocs
00719     CPKIFCertificatePathPtr path(new CPKIFCertificatePath);
00720     CPKIFPathValidationResultsPtr valResults(new CPKIFPathValidationResults);
00721 
00722     //throw any PKIFExceptions or bad_allocs
00723     AddRecipient(cert, path, valResults, minStatus);
00724 }
00736 void CPKIFEnvelopedData::AddRecipient(
00739     CPKIFKEKRecipInfoDetailsPtr& kek)
00740 {
00741     LOG_STRING_DEBUG("CPKIFEnvelopedData::AddRecipient(CPKIFKEKRecipInfoDetailsPtr& kek)", TOOLKIT_CRYPTO_MISC, 0, this);
00742 
00743     //accept no NULLs
00744     if(kek == (CPKIFKEKRecipInfoDetails*)NULL)
00745         throw CPKIFMessageException(thisComponent, COMMON_INVALID_INPUT);
00746 
00747     m_impl->m_keks.push_back(kek);
00748 }
00749 
00762 //void CPKIFEnvelopedData::AddRecipient(
00763 //  //!A smart poiter to CPKIFKEKRecipInfoDetails object which contains a symmetric key that can be used to
00764 //  //!encrypt the content encryption key.
00765 //  CPKIFKARIDetailsPtr & kari)
00766 //{
00767 //  LOG_STRING_DEBUG("CPKIFEnvelopedData::AddRecipient(CPKIFKARIDetailsPtr& kari)", TOOLKIT_CRYPTO_MISC, 0, this);
00768 //
00769 //  //accept no NULLs
00770 //  if(kari == (CPKIFKARIDetailsPtr*)NULL)
00771 //      throw CPKIFMessageException(thisComponent, COMMON_INVALID_INPUT);
00772 //
00773 //  m_impl->m_karis.push_back(kari);
00774 //}
00775 
00806 void CPKIFEnvelopedData::AddRecipient(
00810     CPKIFCertificatePtr& cert,
00816     CPKIFCertificatePathPtr& path,
00824     CPKIFPathValidationResultsPtr& valResults,
00830     CMSPathValidationStatus minStatus)
00831 {
00832     LOG_STRING_DEBUG("CPKIFEnvelopedData::AddRecipient(CPKIFCertificatePtr& cert, CPKIFCertificatePathPtr& path, CPKIFPathValidationResultsPtr& valResults, CMSPathValidationStatus minStatus)", TOOLKIT_CRYPTO_MISC, 0, this);
00833 
00834     //This function is used to add a recipient, i.e. a certificate that will be used to encrypt the key
00835     //that is used to encrypt the message.
00836 
00837     //added NULL path and results object 2/23/05
00838     CPKIFCertificatePathPtr tmpNULLPath;
00839     CPKIFPathValidationResultsPtr tmpNULLResults;
00840 
00841     //set outbound values to temps, 2/23/05
00842     path = tmpNULLPath;
00843     valResults = tmpNULLResults;
00844 
00845     //if the cert is NULL then we should complain to the application via an exception
00846     if(cert == (CPKIFCertificate*)NULL)
00847         throw CPKIFMessageException(thisComponent, COMMON_INVALID_INPUT, "cert parameter is NULL.");
00848 
00849     //accept no empty certs
00850     CPKIFBufferPtr encCert = cert->Encoded();
00851     if(encCert == (CPKIFBuffer*)NULL || 0 == encCert->GetLength())
00852         throw CPKIFMessageException(thisComponent, COMMON_INVALID_INPUT, "cert parameter is empty");
00853 
00854     //if the caller does not require path validation then simply push the recipient
00855     if(PVS_NOT_VALIDATED == minStatus)
00856     {
00857         m_impl->m_recipients.push_back(cert);
00858         return;
00859     }
00860 
00861     //make sure we have the necessary mediator interfaces (these are the ones we use directly - there
00862     //may be others that are missing in which case the mediator that needs the missing interface will complain)
00863     if(NULL == m_impl->m_med)
00864         throw CPKIFMessageException(thisComponent, COMMON_MEDIATOR_MISSING, "Mediator is not available.");
00865 
00866     IPKIFPathBuild* cBuild = m_impl->m_med->GetMediator<IPKIFPathBuild>();
00867     if(NULL == cBuild)
00868         throw CPKIFMessageException(thisComponent, COMMON_MEDIATOR_MISSING, "IPKIFPathBuild interface is not available.");
00869 
00870     IPKIFPathValidate* cValidate = m_impl->m_med->GetMediator<IPKIFPathValidate>();
00871     if(NULL == cValidate)
00872         throw CPKIFMessageException(thisComponent, COMMON_MEDIATOR_MISSING, "IPKIFPathValidate interface is not available.");
00873 
00874     //determine if the certificate is an encryption cert - if it is not then throw an exception
00875     //(this check is performed as part of the path validation below - but we can fail early if we check now)
00876     CPKIFKeyUsagePtr keyUsage = cert->GetExtension<CPKIFKeyUsage>();
00877     if(keyUsage != (CPKIFKeyUsage*)NULL && !keyUsage->KeyEncipherment())
00878         throw CPKIFMessageException(thisComponent, MSG_INVALID_RECIP, "Recipient certificate is not valid for encryption purposes.");
00879 
00880     //added temporary path and results object 2/15/05
00881     CPKIFCertificatePathPtr tmpPath(new CPKIFCertificatePath);
00882     CPKIFPathValidationResultsPtr tmpResults(new CPKIFPathValidationResults);
00883 
00884     //set outbound values to temps, 2/15/05
00885     path = tmpPath;
00886     valResults = tmpResults;
00887 
00888     //next, we will attempt to build and validate a path to the recipient certificate
00889     tmpPath->SetTarget(cert);
00890     
00891     //if settings have been associated with this object use them, otherwise defer to the default 
00892     //settings (either set on the path processing mediator or defined the default permissive set)
00893     if(m_impl->m_settings != (CPKIFPathSettings*)NULL)
00894         tmpPath->SetPathSettings(m_impl->m_settings);
00895 
00896     //create a functor that checks the key usage bit on the EE cert
00897     //Functor<void, TYPELIST_3(const CPKIFCertificateNodeEntryPtr&, CPKIFPathValidationResults&, CertificateType)> keyUsageEncFunctor(keyUsageChecker_Encryption);
00898     CPKIFFuncStoragePtr keyUsageEncFunctor(new CPKIFFuncStorage(keyUsageChecker_Encryption));
00899 
00900     bool pushRecips = false;
00901     try
00902     {
00903         //added do/while and new breaks 2/15/05
00904         do
00905         {
00906             if(!cBuild->BuildPath(*tmpPath))
00907                 break; //no build, break out and fail
00908 
00909             if(cValidate->ValidatePath(*tmpPath, *tmpResults, keyUsageEncFunctor))
00910             {
00911                 switch(minStatus)
00912                 {
00913                 case PVS_CERT_PATH_VERIFIED:
00914                     if(tmpResults->GetBasicChecksSuccessfullyPerformed() && tmpResults->GetCertSignaturesVerified())
00915                         pushRecips = true;
00916                     break;
00917                 case PVS_REV_STATUS_VERIFIED:
00918                     if(NOT_REVOKED == tmpResults->GetRevocationStatusMostSevere())
00919                         pushRecips = true;
00920                     break;
00921                 }
00922             }
00923         }while(1 && !pushRecips); //loop until no path is found or good path is found
00924     }
00925     catch(CPKIFMessageException& me)
00926     {
00927         throw me;
00928     }
00929     catch(CPKIFException& e)
00930     {
00931         CPKIFMessageException me(thisComponent, MSG_INVALID_RECIP, "Failed to build a valid path to the recipient's certificate.");
00932         me.push_info(e);
00933         throw me;
00934     }
00935 
00936     if(pushRecips)
00937     {
00938         m_impl->m_recipients.push_back(cert);
00939     }
00940     else
00941         throw CPKIFMessageException(thisComponent, MSG_INVALID_RECIP, "Failed to build a valid path to the recipient's certificate.");
00942 }
00951 void CPKIFEnvelopedData::GetRecipientInfos(
00954     CPKIFRecipientInfoList& recipInfos) const
00955 {
00956     LOG_STRING_DEBUG("CPKIFEnvelopedData::GetRecipientInfos(CPKIFRecipientInfoList& recipInfos)", TOOLKIT_CRYPTO_MISC, 0, this);
00957 
00958     recipInfos.clear();
00959 
00960     if(m_impl->m_recipientInfos.empty() && NULL != m_impl->m_envelopedData && NULL != m_impl->m_envelopedData->data())
00961     {
00962         CPKIFEnvelopedData* nonConstED = const_cast<CPKIFEnvelopedData*>(this);
00963 
00964         DListNode* iter = (*m_impl->m_envelopedData)->recipientInfos.head;
00965         while(NULL != iter)
00966         {
00967             CACCMSRecipientInfo* ri = (CACCMSRecipientInfo*)iter->data;
00968             
00969             try
00970             {
00971                 CACASNWRAPPER_CREATE(CACCMSRecipientInfo, InfoWrapper);
00972                 ASN1OpenType *data = InfoWrapper.Encode((CACCMSRecipientInfo*)iter->data);
00973                 CPKIFBufferPtr riBuf(new CPKIFBuffer(data->data, data->numocts));
00974                 delete data;
00975                 
00976                 //do fail if all recipient infos cannot be parsed
00977                 //CPKIFRecipientInfoPtr newCert(new CPKIFRecipientInfo(*ri));
00978                 CPKIFRecipientInfoPtr newCert(new CPKIFRecipientInfo(riBuf));
00979                 nonConstED->m_impl->m_recipientInfos.push_back(newCert);
00980             }
00981             catch(...)
00982             {
00983                 nonConstED->m_impl->m_recipientInfos.clear();
00984                 throw;
00985             }
00986     
00987             iter = iter->next;
00988         }
00989     }
00990 
00991     copy(m_impl->m_recipientInfos.begin(), m_impl->m_recipientInfos.end(), back_inserter(recipInfos));
00992 }
01004 void CPKIFEnvelopedData::SetPathSettings(
01008     CPKIFPathSettingsPtr& settings) 
01009 {
01010     //do accept NULLs - so previously set custom settings can be replaced by defaults
01011     m_impl->m_settings = settings;
01012 }
01013 
01014 //*****************************************************************************
01015 //  encode and decode functions
01016 //*****************************************************************************
01046 CPKIFBufferPtr CPKIFEnvelopedData::Encode()
01047 {
01048     LOG_STRING_DEBUG("CPKIFEnvelopedData::Encode()", TOOLKIT_CRYPTO_MISC, 0, this);
01049 
01050     //All memory allocations in this function are decoration of PKIFCMSMessageMemoryHelper.  If an
01051     //allocation fails we let the caller catch bad_alloc.  The destructor for PKIFCMSMessageMemoryHelper
01052     //will handle all cleanup.
01053 
01054     //create a memory helper object containing an enveloped data structure
01055     PKIFCMSMessageMemoryHelper mhEnvelopedData;
01056     mhEnvelopedData.pEnvelopedData = new CACCMSEnvelopedData;
01057     memset(mhEnvelopedData.pEnvelopedData, 0, sizeof(CACCMSEnvelopedData));
01058 
01059     //initialize this to 0 - it will be updated as necessary by one or more of the following calls
01060     //initialization unecessary thanks to memset above but for clarity...
01061     mhEnvelopedData.pEnvelopedData->version = CACCMSv0;
01062 
01063     //prepare the originator info if present, i.e. certs and crls
01064     m_impl->PrepareOriginatorInfo(mhEnvelopedData.pEnvelopedData);
01065 
01066     //next, encrypt the content.  pass a buffer to receive the key material
01067     //so we can use it below when preparing the recip infos
01068     unsigned char* keyData = NULL;  int keyDataLen = 0;
01069     try
01070     {
01071         //prepare the encrypted content  
01072         if(m_impl->m_dataToEncrypt != (CPKIFEncryptedContentInfo*)NULL && 
01073             (!m_impl->m_recipients.empty() || !m_impl->m_keks.empty() /*|| !m_impl->m_karis.empty()*/))
01074         {
01075             //if data to encrypt is specified then encrypt it using the specified key
01076             //and create the necessary pieces of EncryptedData
01077             m_impl->PrepareEncryptedContent(mhEnvelopedData.pEnvelopedData, &keyData, &keyDataLen);
01078 
01079             //prepare the recipient infos using the key material generated in the call above
01080             m_impl->PrepareRecipientInfos(mhEnvelopedData.pEnvelopedData, keyData, keyDataLen);
01081 
01082             //overwrite then delete the key
01083             memset(keyData, 0, keyDataLen); delete[] keyData; keyData = NULL;
01084         }
01085         else
01086         {
01087             //if data to encrypt is not specified then see if there's a copy of decoded encrypted content
01088             //to use (i.e. we're re-encoding after adding an unprotected attribute to an object for which 
01089             //we may not even possess the decryption key).
01090             if(NULL == m_impl->m_envelopedData || NULL == m_impl->m_envelopedData->data() ||
01091                 0 == (*m_impl->m_envelopedData)->encryptedContentInfo.encryptedContent.numocts)
01092                 throw CPKIFMessageException(thisComponent, COMMON_INVALID_INPUT, "No data to encrypt available.");
01093 
01094             CopyOID(&mhEnvelopedData.pEnvelopedData->encryptedContentInfo.contentType, &(*m_impl->m_envelopedData)->encryptedContentInfo.contentType);
01095             CopyOID(&mhEnvelopedData.pEnvelopedData->encryptedContentInfo.contentEncryptionAlgorithm.algorithm, &(*m_impl->m_envelopedData)->encryptedContentInfo.contentEncryptionAlgorithm.algorithm);
01096             mhEnvelopedData.pEnvelopedData->encryptedContentInfo.contentEncryptionAlgorithm.m.parametersPresent = (*m_impl->m_envelopedData)->encryptedContentInfo.contentEncryptionAlgorithm.m.parametersPresent;
01097             if((*m_impl->m_envelopedData)->encryptedContentInfo.contentEncryptionAlgorithm.m.parametersPresent)
01098             {
01099                 mhEnvelopedData.pEnvelopedData->encryptedContentInfo.contentEncryptionAlgorithm.parameters.data = new unsigned char[(*m_impl->m_envelopedData)->encryptedContentInfo.contentEncryptionAlgorithm.parameters.numocts];
01100                 memcpy((void*)mhEnvelopedData.pEnvelopedData->encryptedContentInfo.contentEncryptionAlgorithm.parameters.data, (*m_impl->m_envelopedData)->encryptedContentInfo.contentEncryptionAlgorithm.parameters.data, (*m_impl->m_envelopedData)->encryptedContentInfo.contentEncryptionAlgorithm.parameters.numocts);
01101                 mhEnvelopedData.pEnvelopedData->encryptedContentInfo.contentEncryptionAlgorithm.parameters.numocts = (*m_impl->m_envelopedData)->encryptedContentInfo.contentEncryptionAlgorithm.parameters.numocts;
01102             }
01103             
01104             mhEnvelopedData.pEnvelopedData->encryptedContentInfo.m.encryptedContentPresent = 1;
01105             mhEnvelopedData.pEnvelopedData->encryptedContentInfo.encryptedContent.data = new unsigned char[(*m_impl->m_envelopedData)->encryptedContentInfo.encryptedContent.numocts];
01106             memcpy((void*)mhEnvelopedData.pEnvelopedData->encryptedContentInfo.encryptedContent.data, (*m_impl->m_envelopedData)->encryptedContentInfo.encryptedContent.data, (*m_impl->m_envelopedData)->encryptedContentInfo.encryptedContent.numocts);
01107             mhEnvelopedData.pEnvelopedData->encryptedContentInfo.encryptedContent.numocts = (*m_impl->m_envelopedData)->encryptedContentInfo.encryptedContent.numocts;
01108 
01109             //prepare the recipient infos using the key material generated in the call above
01110             m_impl->PrepareRecipientInfos(mhEnvelopedData.pEnvelopedData, NULL, 0);
01111         }
01112     }
01113     catch(...)
01114     {
01115         //catch any exception - then clean up the key - then throw the exception
01116         if(keyData)
01117         {
01118             memset(keyData, 0, keyDataLen); delete[] keyData; keyData = NULL;
01119         }
01120         throw;
01121     }
01122     
01123     //make a call to do something we don't yet support
01124     mhEnvelopedData.pEnvelopedData->m.unprotectedAttrsPresent = 0;
01125     {//begin unsigned attribute block
01126 
01127         //get all attributes (either by parsing a decoded object or by accessing a previously constructed list)
01128         CPKIFAttributeList sas;
01129         GetUnprotectedAttributes(sas);
01130 
01131         if(!sas.empty())
01132         {
01133             //create Objective representations of each attribute...
01134             SetupAttributesInObjectiveStructure(sas, mhEnvelopedData.pEnvelopedData->unprotectedAttrs);
01135 
01136             //then set the flag indicating attributes are present and set the version number
01137             mhEnvelopedData.pEnvelopedData->m.unprotectedAttrsPresent = 1;
01138             mhEnvelopedData.pEnvelopedData->version = CACCMSv2;
01139         }
01140     }//end unsigned attribute block
01141 
01142     //prepare an ASN 1 object then produce the encoded result
01143     CACASNWRAPPER_CREATE(CACCMSEnvelopedData, objPDU);
01144     ASN1OpenType* data1 = NULL;
01145         
01146     try
01147     {
01148         data1 = objPDU.Encode(mhEnvelopedData.pEnvelopedData);
01149     }
01150     catch(...)
01151     {
01152         m_impl->RemoveRecipInfos(mhEnvelopedData.pEnvelopedData);
01153         throw;
01154     }
01155 
01156     m_impl->RemoveRecipInfos(mhEnvelopedData.pEnvelopedData);
01157 
01158     try
01159     {
01160         //copy the buffer info a buffer ptr to be returned to the caller
01161         CPKIFBufferPtr tmp(new CPKIFBuffer((unsigned char*)data1->data, data1->numocts));
01162         delete data1; data1 = NULL;
01163         return tmp;
01164     }
01165     catch(std::bad_alloc& ba)
01166     {
01167         if(data1)
01168             delete data1;
01169         throw ba;
01170     }
01171 }
01190 void CPKIFEnvelopedData::Decode(
01193     CPKIFBufferPtr& buf)
01194 {
01195     LOG_STRING_DEBUG("CPKIFEnvelopedData::Decode(CPKIFBufferPtr& buf)", TOOLKIT_CRYPTO_MISC, 0, this);
01196 
01197     //if the input is empty - fail now
01198     if(buf == (CPKIFBuffer*)NULL)
01199         throw CPKIFMessageException(thisComponent, COMMON_INVALID_INPUT);
01200 
01201     try
01202     {
01203         //otherwise attempt to decode the buffer into the member enveloped data structure
01204         (*m_impl->m_envelopedData).Decode(buf->GetBuffer(), buf->GetLength());
01205 
01206         m_impl->m_decodeBuf = buf;
01207 
01208         if(CACCMSv2 == (*m_impl->m_envelopedData)->version)
01209             m_impl->m_version = CPKIFEnvelopedData::CMSv2;
01210         else
01211             m_impl->m_version = CPKIFEnvelopedData::CMSv0;
01212     }
01213     catch(CPKIFException& e)
01214     {
01215         unsigned char * decoded = NULL;
01216         unsigned long decodedLen;
01217         bool b = PEMDecode((char *)buf->GetBuffer(), &decoded, &decodedLen);
01218         if(b)
01219         {
01220             try
01221             {
01222                 (*m_impl->m_envelopedData).InitContext();
01223                 (*m_impl->m_envelopedData).Decode(decoded, decodedLen);
01224 
01225                 CPKIFBufferPtr tmp(new CPKIFBuffer(decoded, decodedLen));
01226                 m_impl->m_decodeBuf = tmp;
01227 
01228                 if(CACCMSv2 == (*m_impl->m_envelopedData)->version)
01229                     m_impl->m_version = CPKIFEnvelopedData::CMSv2;
01230                 else
01231                     m_impl->m_version = CPKIFEnvelopedData::CMSv0;
01232 
01233                 if(NULL != decoded)
01234                     delete decoded;
01235 
01236             }catch(CPKIFException& e)
01237             {
01238                 if(NULL != decoded)
01239                     delete decoded;
01240 
01241                 CPKIFMessageException me(thisComponent, MSG_DECODE_FAILED);
01242                 me.push_info(e);
01243                 //delete e;
01244                 throw me;
01245             }
01246         }
01247         else
01248         {
01249             CPKIFMessageException me(thisComponent, MSG_DECODE_FAILED);
01250             me.push_info(e);
01251             throw me;
01252         }
01253     }
01254 }
01255 
01256 //*****************************************************************************
01257 //  miscellaneous functions
01258 //*****************************************************************************
01279 CPKIFBufferPtr CPKIFEnvelopedData::Decrypt(
01282     CPKIFKEKRecipInfoDetailsPtr& kek)
01283 {
01284     LOG_STRING_DEBUG("CPKIFEnvelopedData::Decrypt(CPKIFKEKRecipInfoDetailsPtr& kek)", TOOLKIT_CRYPTO_MISC, 0, this);
01285 
01286     //*****************************************************************
01287     //  sanity check the inputs
01288     //      - need to have data to decrypt, a kek and an available 
01289     //  IPKIFCryptoRawOperations interface.
01290     //*****************************************************************
01291     IPKIFCryptoRawOperations* cRaw = GetMediator()->GetMediator<IPKIFCryptoRawOperations>();
01292     if(NULL == cRaw)
01293         throw CPKIFMessageException(thisComponent, COMMON_MEDIATOR_MISSING, "IPKIFCryptoRawOperations interface is not available.");
01294 
01295     if(kek == (CPKIFKEKRecipInfoDetails*)NULL)
01296         throw CPKIFMessageException(thisComponent, COMMON_INVALID_INPUT, "No KEK passed to Decrypt function.");
01297 
01298     if(NULL == m_impl->m_envelopedData || NULL == m_impl->m_envelopedData->data())
01299         throw CPKIFMessageException(thisComponent, COMMON_INVALID_INPUT, "No data to decrypt available.");
01300 
01301     //*****************************************************************
01302     //  prepare the decrypted content info output
01303     //*****************************************************************
01304     //decrypt symmetric key
01305     CPKIFKeyMaterialPtr key = GetSymmetricKey(kek, cRaw, &(*m_impl->m_envelopedData)->recipientInfos);
01306     if(key == (CPKIFKeyMaterial*)NULL)
01307         throw CPKIFMessageException(thisComponent, MSG_SYMKEY_DECRYPT_FAILED, "Failed to successfully find and decrypt necessary key material.");
01308 
01309     //having successfully decrypted the key - determine the algorithm and mode
01310     CPKIFAlgorithm * pkifAlg = GetCACSymAlg(&(*m_impl->m_envelopedData)->encryptedContentInfo.contentEncryptionAlgorithm);
01311 
01312     if(!pkifAlg)
01313         throw CPKIFMessageException(thisComponent, COMMON_UNSUPPORTED_ALG, "Unsupported content encryption algorithm.");
01314 
01315     //set the alg and mode on the key material object
01316     key->SetSymmetricKeyAlgorithm(pkifAlg->SymkeyAlg());
01317     key->SetMode(pkifAlg->SymkeyMode());
01318 
01319     //see if we need to crack an IV out of the alg params
01320     if(pkifAlg->NeedsIV())
01321     {
01322         //understanding that we need an IV, see if one is actually present
01323         if(!(*m_impl->m_envelopedData)->encryptedContentInfo.contentEncryptionAlgorithm.m.parametersPresent)
01324         {
01325             throw CPKIFMessageException(thisComponent, MSG_MISSING_PARAMS, "Content encryption mode requires an IV and no IV is present.");
01326         }
01327         else
01328         {
01329             //understanding that we need an IV and that one is present, decode the octet string that contains the IV
01330             OOCTXT ctxt;
01331             initContext (&ctxt);
01332             setBERDecBufPtr(&ctxt, (*m_impl->m_envelopedData)->encryptedContentInfo.contentEncryptionAlgorithm.parameters.data, (*m_impl->m_envelopedData)->encryptedContentInfo.contentEncryptionAlgorithm.parameters.numocts, NULL, NULL);
01333 
01334             unsigned char* iv = NULL;
01335             unsigned int ivLen = (*m_impl->m_envelopedData)->encryptedContentInfo.contentEncryptionAlgorithm.parameters.numocts;
01336 
01337             int stat = decodeDynOctStr (&ctxt, (const OSOCTET* *)&iv, (OSUINT32 *)&ivLen, ASN1EXPL, ivLen);
01338             if (stat != ASN_OK)
01339             {
01340                 //clean up the context
01341                 //freeEncodeBuffer(&ctxt);
01342                 //memFreeAll(&ctxt);
01343                 freeContext(&ctxt);
01344 
01345                 throw CPKIFMessageException(TOOLKIT_MESSAGE_ASN, ASN1_DECODE_ERROR, "Failed to decode IV value");
01346             }
01347 
01348             key->SetIV(iv, ivLen);
01349 
01350             //clean up the context
01351             //freeEncodeBuffer(&ctxt);
01352             //memFreeAll(&ctxt);
01353             freeContext(&ctxt);
01354         }
01355     }
01356 
01357     //allocate a buffer to receive the decrypted content - throw bad_alloc
01358     int nResultLen = (*m_impl->m_envelopedData)->encryptedContentInfo.encryptedContent.numocts;
01359     unsigned char* pResult = new unsigned char[nResultLen];
01360 
01361     try
01362     {
01363         cRaw->Decrypt(*key, (unsigned char*)(*m_impl->m_envelopedData)->encryptedContentInfo.encryptedContent.data, (*m_impl->m_envelopedData)->encryptedContentInfo.encryptedContent.numocts, pResult, &nResultLen);
01364     }
01365     catch(...)
01366     {
01367         //throw any exception - but first clean up pResult
01368         if(pResult)
01369             delete[] pResult;
01370 
01371         throw;
01372     }
01373 
01374     CPKIFBuffer* pTmpBP = NULL;
01375     try
01376     {
01377         pTmpBP = new CPKIFBuffer(true, pResult, nResultLen);
01378     }
01379     catch(std::bad_alloc& ba)
01380     {
01381         if(pResult)
01382             delete[] pResult;
01383 
01384         throw ba;
01385     }
01386 
01387     CPKIFBufferPtr tmpBP(pTmpBP);
01388 
01389     //having decrypted the content, prepare the pieces of an encrypted content info object and
01390     //store the results in m_dataToEncrypt
01391     CPKIFEncryptedContentInfoPtr tmpECIP(new CPKIFEncryptedContentInfo);
01392     CPKIFOIDPtr tmpECIP_OID(new CPKIFOID((*m_impl->m_envelopedData)->encryptedContentInfo.contentType.subid,
01393         (*m_impl->m_envelopedData)->encryptedContentInfo.contentType.numids));
01394     tmpECIP->SetOID(tmpECIP_OID);
01395 
01396         //CPKIFAlgorithmIdentifier creation
01397     CPKIFOIDPtr algOID(new CPKIFOID((*m_impl->m_envelopedData)->encryptedContentInfo.contentEncryptionAlgorithm.algorithm.subid,
01398                         (*m_impl->m_envelopedData)->encryptedContentInfo.contentEncryptionAlgorithm.algorithm.numids));
01399     
01400     CPKIFBufferPtr paramBuf;
01401     if((*m_impl->m_envelopedData)->encryptedContentInfo.contentEncryptionAlgorithm.m.parametersPresent)
01402     {
01403         paramBuf = CPKIFBufferPtr(new CPKIFBuffer((*m_impl->m_envelopedData)->encryptedContentInfo.contentEncryptionAlgorithm.parameters.data,
01404                     (*m_impl->m_envelopedData)->encryptedContentInfo.contentEncryptionAlgorithm.parameters.numocts));
01405     
01406     
01407     }
01408     
01409     CPKIFAlgorithmIdentifierPtr tmpECIP_AlgID(new CPKIFAlgorithmIdentifier(algOID, paramBuf)); 
01410 
01411     //CPKIFAlgorithmIdentifierPtr tmpECIP_AlgID(new CPKIFAlgorithmIdentifier(*((CACX509V3AlgorithmIdentifier*)&(*m_impl->m_envelopedData)->encryptedContentInfo.contentEncryptionAlgorithm)));
01412     tmpECIP->SetAlgorithmIdentifier(tmpECIP_AlgID);
01413 
01414     tmpECIP->SetContent(tmpBP);
01415     m_impl->m_dataToEncrypt = tmpECIP;
01416 
01417     return tmpBP;
01418 }
01452 CPKIFBufferPtr CPKIFEnvelopedData::Decrypt(
01455     CPKIFCredentialPtr& cred)
01456 {
01457     LOG_STRING_DEBUG("CPKIFEnvelopedData::Decrypt(CPKIFCredentialPtr& cred)", TOOLKIT_CRYPTO_MISC, 0, this);
01458 
01459     //*****************************************************************
01460     //  sanity check the inputs
01461     //      - need to have data to decrypt and available 
01462     //  IPKIFCryptoRawOperations and IPKIFCryptoKeyIDOperations interfaces.
01463     //*****************************************************************
01464     if(NULL == m_impl->m_envelopedData || NULL == m_impl->m_envelopedData->data())
01465         throw CPKIFMessageException(thisComponent, COMMON_INVALID_INPUT, "No data to decrypt available.");
01466 
01467 
01468     if(NULL == GetMediator())
01469         throw CPKIFMessageException(thisComponent, COMMON_MEDIATOR_MISSING, "Mediator is not available.");
01470 
01471     IPKIFCryptoKeyIDOperations* cKeyID = GetMediator()->GetMediator<IPKIFCryptoKeyIDOperations>();
01472     if(NULL == cKeyID)
01473         throw CPKIFMessageException(thisComponent, COMMON_MEDIATOR_MISSING, "IPKIFCryptoKeyIDOperations interface is not available.");
01474 
01475     IPKIFCryptoRawOperations* cRaw = GetMediator()->GetMediator<IPKIFCryptoRawOperations>();
01476     if(NULL == cRaw)
01477         throw CPKIFMessageException(thisComponent, COMMON_MEDIATOR_MISSING, "IPKIFCryptoRawOperations interface is not available.");
01478 
01479     IPKIFCryptoKeyAgree* cKeyAgree = GetMediator()->GetMediator<IPKIFCryptoKeyAgree>();
01480 
01481     //*****************************************************************
01482     // if a credential was passed in, it will be used.  if not, then
01483     // an attempt will be made to discover the credential.  
01484     //*****************************************************************
01485     CPKIFCredentialPtr tmpCred = cred;
01486     if(tmpCred == (CPKIFCredential*)NULL)
01487     {
01488         //if no credential was passed in but a default key has been defined, it will be used
01489         IPKIFDefaultKeyManagement* cDefKeys = GetMediator()->GetMediator<IPKIFDefaultKeyManagement>();
01490         if(NULL != cDefKeys)
01491             tmpCred = cDefKeys->GetDefaultKey(PKIFCRYPTO::DECRYPTION);
01492 
01493         if(tmpCred == (CPKIFCredential*)NULL)
01494         {
01495             //if no cred has been passed nor declared as default then we'll look around and see
01496             //if we can find the proper credential
01497             try
01498             {
01499                 tmpCred = AutoDiscoverDecryptionKey(cKeyID, &(*m_impl->m_envelopedData)->recipientInfos);
01500                 if(tmpCred == (CPKIFCredential*)NULL)
01501                     throw CPKIFMessageException(thisComponent, COMMON_INVALID_INPUT, "Failed to automatically discover the decryption key.");
01502             }
01503             catch(CPKIFException& e)
01504             {
01505                 CPKIFMessageException me(thisComponent, COMMON_INVALID_INPUT, "Exception while trying to automatically discover the decryption key.");
01506                 me.push_info(e);
01507                 throw me;
01508             }
01509         }
01510     }
01511 
01512     //*****************************************************************
01513     //  prepare the decrypted content info output
01514     //*****************************************************************
01515     //decrypt symmetric key
01516     CPKIFKeyMaterialPtr key;
01517     if((*m_impl->m_envelopedData)->m.originatorInfoPresent)
01518         key = GetSymmetricKey(tmpCred, cKeyID, &(*m_impl->m_envelopedData)->recipientInfos, cKeyAgree, cRaw, &(*m_impl->m_envelopedData)->originatorInfo);
01519     else
01520         key = GetSymmetricKey(tmpCred, cKeyID, &(*m_impl->m_envelopedData)->recipientInfos, cKeyAgree, cRaw, NULL);
01521     if(key == (CPKIFKeyMaterial*)NULL)
01522         throw CPKIFMessageException(thisComponent, MSG_SYMKEY_DECRYPT_FAILED, "Failed to successfully find and decrypt necessary key material.");
01523 
01524     CPKIFAlgorithm * pkifAlg = GetCACSymAlg(&(*m_impl->m_envelopedData)->encryptedContentInfo.contentEncryptionAlgorithm);
01525     //having successfully decrypted the key - determine the algorithm and mode
01526     if(!pkifAlg)
01527         throw CPKIFMessageException(thisComponent, COMMON_UNSUPPORTED_ALG, "Unsupported content encryption algorithm.");
01528 
01529     //set the alg and mode on the key material object
01530     key->SetSymmetricKeyAlgorithm(pkifAlg->SymkeyAlg());
01531     key->SetMode(pkifAlg->SymkeyMode());
01532 
01533     //see if we need to crack an IV out of the alg params
01534     if(pkifAlg->NeedsIV())
01535     {
01536         //understanding that we need an IV, see if one is actually present
01537         if(!(*m_impl->m_envelopedData)->encryptedContentInfo.contentEncryptionAlgorithm.m.parametersPresent)
01538         {
01539             throw CPKIFMessageException(thisComponent, MSG_MISSING_PARAMS, "Content encryption mode requires an IV and no IV is present.");
01540         }
01541         else
01542         {
01543             //understanding that we need an IV and that one is present, decode the octet string that contains the IV
01544             OOCTXT ctxt;
01545             initContext (&ctxt);
01546             setBERDecBufPtr(&ctxt, (*m_impl->m_envelopedData)->encryptedContentInfo.contentEncryptionAlgorithm.parameters.data, (*m_impl->m_envelopedData)->encryptedContentInfo.contentEncryptionAlgorithm.parameters.numocts, NULL, NULL);
01547 
01548             unsigned char* iv = NULL;
01549             unsigned int ivLen = (*m_impl->m_envelopedData)->encryptedContentInfo.contentEncryptionAlgorithm.parameters.numocts;
01550 
01551             int stat = decodeDynOctStr (&ctxt, (const OSOCTET* *)&iv, (OSUINT32 *)&ivLen, ASN1EXPL, ivLen);
01552             if (stat != ASN_OK)
01553             {
01554                 //clean up the context
01555                 //freeEncodeBuffer(&ctxt);
01556                 //memFreeAll(&ctxt);
01557                 freeContext(&ctxt);
01558 
01559                 throw CPKIFMessageException(TOOLKIT_MESSAGE_ASN, ASN1_DECODE_ERROR, "Failed to decode IV value");
01560             }
01561 
01562             key->SetIV(iv, ivLen);
01563 
01564             //clean up the context
01565             //freeEncodeBuffer(&ctxt);
01566             //memFreeAll(&ctxt);
01567             freeContext(&ctxt);
01568         }
01569     }
01570 
01571     //allocate a buffer to receive the decrypted content - throw bad_alloc
01572     int nResultLen = (*m_impl->m_envelopedData)->encryptedContentInfo.encryptedContent.numocts;
01573     unsigned char* pResult = new unsigned char[nResultLen];
01574 
01575     try
01576     {
01577         cRaw->Decrypt(*key, (unsigned char*)(*m_impl->m_envelopedData)->encryptedContentInfo.encryptedContent.data, (*m_impl->m_envelopedData)->encryptedContentInfo.encryptedContent.numocts, pResult, &nResultLen);
01578     }
01579     catch(...)
01580     {
01581         //throw any exception - but first clean up pResult
01582         if(pResult)
01583             delete[] pResult;
01584 
01585         throw;
01586     }
01587 
01588     CPKIFBuffer* pTmpBP = NULL;
01589     try
01590     {
01591         pTmpBP = new CPKIFBuffer(true, pResult, nResultLen);
01592     }
01593     catch(std::bad_alloc& ba)
01594     {
01595         if(pResult)
01596             delete[] pResult;
01597 
01598         throw ba;
01599     }
01600 
01601     CPKIFBufferPtr tmpBP(pTmpBP);
01602 
01603     //having decrypted the content, prepare the pieces of an encrypted content info object and
01604     //store the results in m_dataToEncrypt
01605     CPKIFEncryptedContentInfoPtr tmpECIP(new CPKIFEncryptedContentInfo);
01606     CPKIFOIDPtr tmpECIP_OID(new CPKIFOID((*m_impl->m_envelopedData)->encryptedContentInfo.contentType.subid,
01607         (*m_impl->m_envelopedData)->encryptedContentInfo.contentType.numids));
01608     tmpECIP->SetOID(tmpECIP_OID);
01609 
01610         //CPKIFAlgorithmIdentifier creation
01611     CPKIFOIDPtr algOID(new CPKIFOID((*m_impl->m_envelopedData)->encryptedContentInfo.contentEncryptionAlgorithm.algorithm.subid,
01612                         (*m_impl->m_envelopedData)->encryptedContentInfo.contentEncryptionAlgorithm.algorithm.numids));
01613     
01614     CPKIFBufferPtr paramBuf;
01615     if((*m_impl->m_envelopedData)->encryptedContentInfo.contentEncryptionAlgorithm.m.parametersPresent)
01616     {
01617         paramBuf = CPKIFBufferPtr(new CPKIFBuffer((*m_impl->m_envelopedData)->encryptedContentInfo.contentEncryptionAlgorithm.parameters.data,
01618                     (*m_impl->m_envelopedData)->encryptedContentInfo.contentEncryptionAlgorithm.parameters.numocts));
01619     
01620     
01621     }
01622     
01623     CPKIFAlgorithmIdentifierPtr tmpECIP_AlgID(new CPKIFAlgorithmIdentifier(algOID, paramBuf)); 
01624     //CPKIFAlgorithmIdentifierPtr tmpECIP_AlgID(new CPKIFAlgorithmIdentifier(*((CACX509V3AlgorithmIdentifier*)&(*m_impl->m_envelopedData)->encryptedContentInfo.contentEncryptionAlgorithm)));
01625     tmpECIP->SetAlgorithmIdentifier(tmpECIP_AlgID);
01626 
01627     tmpECIP->SetContent(tmpBP);
01628     m_impl->m_dataToEncrypt = tmpECIP;
01629 
01630     return tmpBP;
01631 }
01632 
01633 //*****************************************************************************
01634 //  miscellaneous private functions
01635 //*****************************************************************************
01648 void CPKIFEnvelopedDataImpl::PrepareEncryptedContent(
01650     CACCMSEnvelopedData* pEnvelopedData,
01652     unsigned char** keyData, 
01654     int* keyDataLen)
01655 {
01656     LOG_STRING_DEBUG("CPKIFEnvelopedData::PrepareEncryptedContent(CACCMSEnvelopedData* pEnvelopedData, unsigned char** keyData, int* keyDataLen)", TOOLKIT_CRYPTO_MISC, 0, this);
01657 
01658     //*****************************************************************
01659     //  sanity check the inputs
01660     //      - need to have data to decrypt and available 
01661     //  IPKIFCryptoRawOperations and IPKIFCryptoMisc interfaces.
01662     //*****************************************************************
01663     if(NULL == m_med)
01664         throw CPKIFMessageException(m_parent->thisComponent, COMMON_MEDIATOR_MISSING, "Mediator is not available.");
01665 
01666     IPKIFCryptoMisc* cMisc = m_med->GetMediator<IPKIFCryptoMisc>();
01667     if(NULL == cMisc)
01668         throw CPKIFMessageException(m_parent->thisComponent, COMMON_MEDIATOR_MISSING, "IPKIFCryptoMisc interface is not available.");
01669 
01670     if(m_dataToEncrypt == (CPKIFEncryptedContentInfo*)NULL)
01671         throw CPKIFMessageException(m_parent->thisComponent, COMMON_INVALID_INPUT, "No data to encrypt is available.");
01672 
01673     IPKIFCryptoRawOperations* cRaw = m_med->GetMediator<IPKIFCryptoRawOperations>();
01674     if(NULL == cRaw)
01675         throw CPKIFMessageException(m_parent->thisComponent, COMMON_MEDIATOR_MISSING, "IPKIFCryptoRawOperations interface is not available.");
01676 
01677     //*****************************************************************
01678     //  prepare the encrypted content info output
01679     //*****************************************************************
01680     CPKIFStringPtr str(new std::string(m_dataToEncrypt->GetOID()->ToString())); 
01681     ASN1OBJID* tmpOid = ConvertStringToASN1OBJID(str);
01682     CopyOID(&pEnvelopedData->encryptedContentInfo.contentType, tmpOid);
01683     if(tmpOid)
01684         delete tmpOid;
01685     //CopyOID(&pEnvelopedData->encryptedContentInfo.contentType, m_dataToEncrypt->GetOID()->raw());
01686     CPKIFAlgorithm * algInfo = CPKIFAlgorithm::GetAlg(m_alg,m_mode);
01687     CPKIFOIDPtr activeAlg = algInfo->OID();
01688     int keySize = algInfo->KeySize();
01689     int ivSize = algInfo->BlockSize();
01690     bool needIV = algInfo->NeedsIV();
01691     if(!activeAlg) throw CPKIFMessageException(m_parent->thisComponent, COMMON_UNSUPPORTED_ALG);
01692 
01693     CPKIFStringPtr secondStr(new std::string(activeAlg->ToString())); 
01694     ASN1OBJID* secondTmpOid = ConvertStringToASN1OBJID(secondStr);
01695     CopyOID(&pEnvelopedData->encryptedContentInfo.contentEncryptionAlgorithm.algorithm, secondTmpOid);
01696     if(secondTmpOid)
01697         delete secondTmpOid;
01698     //CopyOID(&pEnvelopedData->encryptedContentInfo.contentEncryptionAlgorithm.algorithm, activeAlg->raw());
01699 
01700     //throw bad_alloc (no need to clean this up here - once we hand it off the caller will clean it up)
01701     *keyData = new unsigned char[keySize];
01702     *keyDataLen = keySize;
01703 
01704     //generate a random content encryption key
01705     cMisc->GenRandom(*keyData, keySize);
01706 
01707     //set up a key material object with the key, alg and mode (IV will be added below if necessary)
01708     CPKIFKeyMaterial key;
01709     key.SetSymmetricKey(*keyData, *keyDataLen);
01710     key.SetSymmetricKeyAlgorithm(m_alg);
01711     key.SetMode(m_mode);
01712 
01713     const int maxBlock = (MAXBLOCK/8) + 1;
01714     if(needIV)
01715     {
01716         //generate a random IV
01717         unsigned char iv[maxBlock];
01718         cMisc->GenRandom(iv, ivSize);
01719         key.SetIV(iv, ivSize);
01720 
01721         //encode the IV as an octet string the the content enc alg parameters
01722         pEnvelopedData->encryptedContentInfo.contentEncryptionAlgorithm.m.parametersPresent = 1;
01723         EncodeIVAsOctetString(iv, ivSize, 
01724             (unsigned char**)&pEnvelopedData->encryptedContentInfo.contentEncryptionAlgorithm.parameters.data, 
01725             (int*)&pEnvelopedData->encryptedContentInfo.contentEncryptionAlgorithm.parameters.numocts);
01726     }
01727 
01728     //grab a pointer to the content to be encrypted
01729     CPKIFBufferPtr dataToEnc = m_dataToEncrypt->GetContent();
01730 
01731     //overallocate a buffer (the length will be adjusted down by the call to Encrypt)
01732     pEnvelopedData->encryptedContentInfo.encryptedContent.numocts = dataToEnc->GetLength() + maxBlock;
01733     pEnvelopedData->encryptedContentInfo.encryptedContent.data = new unsigned char[pEnvelopedData->encryptedContentInfo.encryptedContent.numocts];
01734 
01735     cRaw->Encrypt(key, (unsigned char*)dataToEnc->GetBuffer(), dataToEnc->GetLength(), 
01736         (unsigned char*)pEnvelopedData->encryptedContentInfo.encryptedContent.data, (int*)&pEnvelopedData->encryptedContentInfo.encryptedContent.numocts);
01737 
01738     pEnvelopedData->encryptedContentInfo.m.encryptedContentPresent = 1;
01739 }
01747 void CPKIFEnvelopedDataImpl::PrepareOriginatorInfo(
01749     CACCMSEnvelopedData* pEnvelopedData)
01750 {
01751     LOG_STRING_DEBUG("CPKIFEnvelopedData::PrepareOriginatorInfo(CACCMSEnvelopedData* pEnvelopedData)", TOOLKIT_CRYPTO_MISC, 0, this);
01752 
01753     //add any certs or crls that have been associated with this object (possibly zero)
01754     AddCerts(pEnvelopedData);
01755     AddCRLs(pEnvelopedData);
01756 
01757     //added following line 3/30/2004 - else orginator info was not being encoded
01758     pEnvelopedData->m.originatorInfoPresent = pEnvelopedData->originatorInfo.m.certsPresent || pEnvelopedData->originatorInfo.m.crlsPresent;
01759 }
01767 void CPKIFEnvelopedDataImpl::populateUnsignedAttributesVector(
01769     const CACCMSUnsignedAttributes& ua)
01770 {
01771     LOG_STRING_DEBUG("CPKIFEnvelopedData::populateUnsignedAttributesVector(const CACCMSUnsignedAttributes& ua)", TOOLKIT_CRYPTO_MISC, 0, this);
01772 
01773     //if we've already populated the extensions vector then return
01774     if(!m_unprotectedAttributes.empty())
01775         return;
01776 
01777     //if there are no extensions then return
01778     if(0 == ua.count)
01779     {
01780         m_unprotectedAttributes.clear();
01781         return;
01782     }
01783 
01784     //create an extensions mediator using the default extension colleagues and initialize it
01785     CPKIFCMSAttributeMediator2* mediator = CPKIFCMSAttributeMediator2::GetInstance();
01786 
01787     //iterate over the list of extensions and populate the extensions vector
01788     DListNode* cur = ua.head;
01789     for(unsigned int ii = 0; ii < ua.count; ++ii)
01790     {
01791         CACCMSAttribute* attr = (CACCMSAttribute*) cur->data;
01792         CPKIFOIDPtr oid(new CPKIFOID(attr->attrType.subid, attr->attrType.numids));
01793         CPKIFBufferPtr buf(new CPKIFBuffer(attr->attrValues.data, attr->attrValues.numocts));
01794 
01795         m_unprotectedAttributes.push_back(mediator->getAttribute(oid, buf));
01796         cur = cur->next;
01797     }
01798 }
01809 void CPKIFEnvelopedDataImpl::PrepareRecipientInfos(
01811     CACCMSEnvelopedData* pEnvelopedData,
01813     unsigned char* keyData, 
01815     int keyDataLen)
01816 {
01817     LOG_STRING_DEBUG("CPKIFEnvelopedData::PrepareRecipientInfos(CACCMSEnvelopedData* pEnvelopedData, ...", TOOLKIT_CRYPTO_MISC, 0, this);
01818 
01819     //*****************************************************************
01820     //  sanity check the inputs
01821     //      - need to have available IPKIFCryptoRawOperations and 
01822     //  IPKIFCryptoMisc interfaces.
01823     //*****************************************************************
01824     if(NULL == m_med)
01825         throw CPKIFMessageException(m_parent->thisComponent, COMMON_MEDIATOR_MISSING, "Mediator is not available.");
01826 
01827     //This function prepares the recipient info fields, i.e. encrypts the key for each and builds the necessary structure
01828     IPKIFCryptoRawOperations* cRaw = m_med->GetMediator<IPKIFCryptoRawOperations>();
01829     if(NULL == cRaw)
01830         throw CPKIFMessageException(m_parent->thisComponent, COMMON_MEDIATOR_MISSING, "IPKIFCryptoRawOperations interface is not available.");
01831 
01832     //*****************************************************************
01833     //  iterate over the recipient infos
01834     //*****************************************************************
01835     //first, add any signer infos that were present in the decoded message
01836     if(NULL != m_envelopedData && NULL != (*m_envelopedData).data() && (*m_envelopedData)->recipientInfos.count > 0)
01837     {
01838         DListNode* cur = NULL;
01839         DListNode* existing = (*m_envelopedData)->recipientInfos.head;
01840         while(NULL != existing)
01841         {
01842             //throw bad_alloc
01843             if(NULL == cur)
01844             {
01845                 NEW_NODE(cur)
01846             }
01847             else
01848             {
01849                 NEW_NEXT_AND_ADVANCE(cur)
01850             }
01851 
01852             cur->data = existing->data;
01853 
01854             existing = existing->next;
01855 
01856             SET_HEAD_TAIL_INCREMENT(pEnvelopedData->recipientInfos, cur)
01857         }
01858     }
01859 
01860     DListNode* cur = NULL;
01861     CPKIFCertificateList::iterator pos;
01862     CPKIFCertificateList::iterator end = m_recipients.end();
01863     for(pos = m_recipients.begin(); end != pos; ++pos)
01864     {
01865         //create a list entry, set it to point to the recip. info created above...
01866         if(NULL == cur)
01867         {
01868             NEW_NODE(cur)
01869         }
01870         else
01871         {
01872             NEW_NEXT_AND_ADVANCE(cur)
01873         }
01874 
01875         CACCMSRecipientInfo* tmpRI = NULL;
01876 
01877         try
01878         {
01879             tmpRI = new CACCMSRecipientInfo;
01880         
01881             //XXX-DEFER only doing key transport option for now
01882             tmpRI->t = 1;
01883             tmpRI->u.ktri = new CACCMSKeyTransRecipientInfo;
01884         }
01885         catch(std::bad_alloc& ba)
01886         {
01887             if(tmpRI)
01888             {
01889                 if(tmpRI->u.ktri)
01890                     delete tmpRI->u.ktri;
01891                 delete tmpRI;
01892             }
01893 
01894             throw ba;
01895         }
01896 
01897         //set the memory helper protected object to point to tmpRI so
01898         //that failures below this point will not cause leaks
01899         cur->data = (void*)tmpRI;
01900 
01901         //set Objective structures to point to values from various PKIF objects
01902         CPKIFSubjectPublicKeyInfoPtr spki = (*pos)->SubjectPublicKeyInfo();
01903         CPKIFAlgorithmIdentifierPtr spkiAlg = spki->alg();
01904         CPKIFOIDPtr spkiAlgOID = spkiAlg->oid();
01905 
01906         CPKIFStringPtr str(new std::string(spkiAlgOID->ToString())); 
01907         ASN1OBJID* tmpOid = ConvertStringToASN1OBJID(str);
01908         CopyOID(&tmpRI->u.ktri->keyEncryptionAlgorithm.algorithm,tmpOid);
01909         if(tmpOid)
01910             delete tmpOid;
01911         //CopyOID(&tmpRI->u.ktri->keyEncryptionAlgorithm.algorithm,spkiAlgOID->raw());
01912         tmpRI->u.ktri->keyEncryptionAlgorithm.m.parametersPresent = 1;
01913         
01914         //assume RSA with NULL params
01915         tmpRI->u.ktri->keyEncryptionAlgorithm.parameters.data = nullParams;
01916         tmpRI->u.ktri->keyEncryptionAlgorithm.parameters.numocts = 2;
01917 
01918         //XXX-DEFER issDN and serial num for now (version will need changing if SKID is used)
01919         //      if skid is used the pEnvelopedData->version = CACCMSv2;
01920         tmpRI->u.ktri->version = CACCMSv0; 
01921         tmpRI->u.ktri->rid.t = 1;
01922         tmpRI->u.ktri->rid.u.issuerAndSerialNumber = new CACCMSIssuerAndSerialNumber;
01923 
01924         CPKIFNamePtr issuer = (*pos)->Issuer();
01925 
01926         CACASNWRAPPER_CREATE(CACX509V3Name, objPDU);
01927         CACX509V3Name *tmpName = NULL;
01928         CPKIFBufferPtr nameBuf = issuer->rawName();
01929         tmpName = objPDU.Decode(nameBuf->GetBuffer(), nameBuf->GetLength());
01930         CopyName(&tmpRI->u.ktri->rid.u.issuerAndSerialNumber->issuer, *tmpName);
01931         //tmpRI->u.ktri->rid.u.issuerAndSerialNumber->issuer = *tmpName;
01932         //tmpRI->u.ktri->rid.u.issuerAndSerialNumber->issuer = *issuer->rawName();
01933         tmpRI->u.ktri->rid.u.issuerAndSerialNumber->serialNumber = (*pos)->SerialNumber();
01934     
01935         //prepare a key material object with the cert for the current recipient
01936         CPKIFKeyMaterial km;
01937         CPKIFBufferPtr certBuf = (*pos)->Encoded();
01938         km.SetCertificate(certBuf->GetBuffer(), certBuf->GetLength());
01939 
01940         tmpRI->u.ktri->encryptedKey.data = new unsigned char[keyDataLen + 256];
01941 
01942         tmpRI->u.ktri->encryptedKey.numocts = keyDataLen + 256;
01943 
01944         try
01945         {
01946             cRaw->Encrypt(km, keyData, keyDataLen, (unsigned char*)tmpRI->u.ktri->encryptedKey.data, (int*)&tmpRI->u.ktri->encryptedKey.numocts);
01947         }
01948         catch(CPKIFException& e)
01949         {
01950             //XXX-DEFER would we rather create the message for all possible recipients 
01951             //          or fail the entire message? for now fail all
01952             throw e;
01953         }
01954 
01955         SET_HEAD_TAIL_INCREMENT(pEnvelopedData->recipientInfos, cur)
01956     }
01957 
01958     CPKIFKEKRecipInfoDetailsList::iterator kekPos;
01959     CPKIFKEKRecipInfoDetailsList::iterator kekEnd = m_keks.end();
01960     for(kekPos = m_keks.begin(); kekPos != kekEnd; ++kekPos)
01961     {
01962         //continue using the same cur variable so the list is properly formed
01963         if(NULL == cur)
01964         {
01965             NEW_NODE(cur)
01966         }
01967         else
01968         {
01969             NEW_NEXT_AND_ADVANCE(cur)
01970         }
01971 
01972         CACCMSRecipientInfo* tmpRI = NULL;
01973 
01974         try
01975         {
01976             tmpRI = new CACCMSRecipientInfo;
01977             tmpRI->t = T_CACCMSRecipientInfo_kekri;
01978             tmpRI->u.kekri = new CACCMSKEKRecipientInfo;
01979             memset(tmpRI->u.kekri, 0, sizeof(CACCMSKEKRecipientInfo));
01980         }
01981         catch(std::bad_alloc& ba)
01982         {
01983             if(tmpRI)
01984             {
01985                 if(tmpRI->u.kekri)
01986                     delete tmpRI->u.kekri;
01987                 delete tmpRI;
01988             }
01989 
01990             throw ba;
01991         }
01992 
01993         //set the memory helper protected object to point to tmpRI so
01994         //that failures below this point will not cause leaks
01995         cur->data = (void*)tmpRI;
01996 
01997         CPKIFBufferPtr keyID = (*kekPos)->GetKeyIdentifier();
01998         tmpRI->u.kekri->kekid.keyIdentifier.data = keyID->GetBuffer();
01999         tmpRI->u.kekri->kekid.keyIdentifier.numocts = keyID->GetLength();
02000 
02001         //encrypt data
02002         CPKIFOIDPtr activeAlg;
02003         int keySize = 0, ivSize = 0;
02004         bool needIV = false;
02005         CPKIFKeyMaterialPtr curKey = (*kekPos)->GetKEK();
02006         if(PKIFCRYPTO::TDES == curKey->GetSymmetricKeyAlgorithm() && PKIFCRYPTO::CBC == curKey->GetMode())
02007         {
02008             activeAlg = g_tdesCBC;
02009             keySize = 24;
02010             needIV = true;
02011             ivSize = 8;
02012         }
02013         else if(PKIFCRYPTO::DES == curKey->GetSymmetricKeyAlgorithm() && PKIFCRYPTO::CBC == curKey->GetMode())
02014         {
02015             activeAlg = g_desCBC;
02016             keySize = 8;
02017             needIV = true;
02018             ivSize = 8;
02019         }
02020         else if(PKIFCRYPTO::DES == curKey->GetSymmetricKeyAlgorithm() && PKIFCRYPTO::ECB == curKey->GetMode())
02021         {
02022             activeAlg = g_desECB;
02023             keySize = 8;
02024             needIV = false;
02025         }
02026         else if(PKIFCRYPTO::AES == curKey->GetSymmetricKeyAlgorithm() && PKIFCRYPTO::ECB == curKey->GetMode())
02027         {
02028             activeAlg = g_aes128ECB;
02029             keySize = 16;
02030             needIV = false;
02031         }
02032         else if(PKIFCRYPTO::AES == curKey->GetSymmetricKeyAlgorithm() && PKIFCRYPTO::CBC == curKey->GetMode())
02033         {
02034             activeAlg = g_aes128CBC;
02035             keySize = 16;
02036             needIV = true;
02037             ivSize = 16;
02038         }
02039         else if(PKIFCRYPTO::AES128 == curKey->GetSymmetricKeyAlgorithm() && PKIFCRYPTO::ECB == curKey->GetMode())
02040         {
02041             activeAlg = g_aes128ECB;
02042             keySize = 16;
02043             needIV = false;
02044         }
02045         else if(PKIFCRYPTO::AES128 == curKey->GetSymmetricKeyAlgorithm() && PKIFCRYPTO::CBC == curKey->GetMode())
02046         {
02047             activeAlg = g_aes128CBC;
02048             keySize = 16;
02049             needIV = true;
02050             ivSize = 16;
02051         }
02052         else if(PKIFCRYPTO::AES192 == curKey->GetSymmetricKeyAlgorithm() && PKIFCRYPTO::ECB == curKey->GetMode())
02053         {
02054             activeAlg = g_aes192ECB;
02055             keySize = 24;
02056             needIV = false;
02057         }
02058         else if(PKIFCRYPTO::AES192 == curKey->GetSymmetricKeyAlgorithm() && PKIFCRYPTO::CBC == curKey->GetMode())
02059         {
02060             activeAlg = g_aes192CBC;
02061             keySize = 24;
02062             needIV = true;
02063             ivSize = 16;
02064         }
02065         else if(PKIFCRYPTO::AES256 == curKey->GetSymmetricKeyAlgorithm() && PKIFCRYPTO::ECB == curKey->GetMode())
02066         {
02067             activeAlg = g_aes256ECB;
02068             keySize = 32;
02069             needIV = false;
02070         }
02071         else if(PKIFCRYPTO::AES256 == curKey->GetSymmetricKeyAlgorithm() && PKIFCRYPTO::CBC == curKey->GetMode())
02072         {
02073             activeAlg = g_aes256CBC;
02074             keySize = 32;
02075             needIV = true;
02076             ivSize = 16;
02077         }
02078         else
02079             throw CPKIFMessageException(m_parent->thisComponent, COMMON_UNSUPPORTED_ALG);
02080 
02081         CPKIFStringPtr str(new std::string(activeAlg->ToString())); 
02082         ASN1OBJID* tmpOid = ConvertStringToASN1OBJID(str);
02083         CopyOID(&tmpRI->u.kekri->keyEncryptionAlgorithm.algorithm, tmpOid);
02084         if(tmpOid)
02085             delete tmpOid;
02086         //CopyOID(&tmpRI->u.kekri->keyEncryptionAlgorithm.algorithm, activeAlg->raw());
02087 
02088         if(needIV)
02089         {
02090             IPKIFCryptoMisc* cMisc = m_med->GetMediator<IPKIFCryptoMisc>();
02091             if(NULL == cMisc)
02092                 throw CPKIFMessageException(m_parent->thisComponent, COMMON_MEDIATOR_MISSING, "IPKIFCryptoMisc interface is not available.");
02093 
02094             unsigned char iv[MAXBLOCK];
02095             cMisc->GenRandom(iv, ivSize);
02096             curKey->SetIV(iv, ivSize);
02097 
02098             tmpRI->u.kekri->keyEncryptionAlgorithm.m.parametersPresent = 1;
02099 
02100             EncodeIVAsOctetString(iv, ivSize, 
02101                 (unsigned char**)&tmpRI->u.kekri->keyEncryptionAlgorithm.parameters.data, 
02102                 (int*)&tmpRI->u.kekri->keyEncryptionAlgorithm.parameters.numocts);
02103         }
02104 
02105         tmpRI->u.kekri->version = CACCMSv4; //always set to 4 per RFC3369
02106         tmpRI->u.kekri->encryptedKey.data = new unsigned char[keyDataLen + 256];
02107         tmpRI->u.kekri->encryptedKey.numocts = keyDataLen + 256;
02108 
02109         try
02110         {
02111             cRaw->Encrypt(*curKey, keyData, keyDataLen, (unsigned char*)tmpRI->u.kekri->encryptedKey.data, (int*)&tmpRI->u.kekri->encryptedKey.numocts);
02112         }
02113         catch(CPKIFException& e)
02114         {
02115             //XXX-DEFER would we rather create the message for all possible recipients 
02116             //          or fail the entire message? for now fail all
02117             throw e;
02118         }
02119 
02120         SET_HEAD_TAIL_INCREMENT(pEnvelopedData->recipientInfos, cur)
02121     }
02122     
02123     //CPKIFKARIDetailsList::iterator kariPos;
02124     //CPKIFKARIDetailsList::iterator kariEnd = m_karis.end();
02125     //for(kariPos = m_karis.begin(); kariPos != kariEnd; ++kariPos)
02126     //{
02127     //  //continue using the same cur variable so the list is properly formed
02128     //  if(NULL == cur)
02129     //  {
02130     //      NEW_NODE(cur)
02131     //  }
02132     //  else
02133     //  {
02134     //      NEW_NEXT_AND_ADVANCE(cur)
02135     //  }
02136 
02137     //  CACCMSRecipientInfo* tmpRI = NULL;
02138 
02139     //  try
02140     //  {
02141     //      tmpRI = new CACCMSRecipientInfo;
02142     //      tmpRI->t = T_CACCMSRecipientInfo_kari;
02143     //      tmpRI->u.kari = new CACCMSKeyAgreeRecipientInfo;
02144     //      memset(tmpRI->u.kari, 0, sizeof(CACCMSKeyAgreeRecipientInfo));
02145     //  }
02146     //  catch(std::bad_alloc& ba)
02147     //  {
02148     //      if(tmpRI)
02149     //      {
02150     //          if(tmpRI->u.kekri)
02151     //              delete tmpRI->u.kekri;
02152     //          delete tmpRI;
02153     //      }
02154 
02155     //      throw ba;
02156     //  }
02157 
02158     //  //set the memory helper protected object to point to tmpRI so
02159     //  //that failures below this point will not cause leaks
02160     //  cur->data = (void*)tmpRI;
02161     //  (*kariPos)->SetCEK(keyData,keyDataLen);
02162     //  CPKIFBufferPtr encBuf = (*kariPos)->Encoded(m_cred);
02163     //  if(!encBuf) {
02164     //      throw CPKIFMessageException(m_parent->thisComponent,MSG_ENCODE_FAILED);
02165     //  }
02166     //  CACASNWRAPPER_CREATE(CACCMSKeyAgreeRecipientInfo, kariWrapper);
02167     //  CACCMSKeyAgreeRecipientInfo * kariDec = kariWrapper.Decode(encBuf->GetBuffer(), encBuf->GetLength());
02168     //  memcpy(tmpRI->u.kari,kariDec,sizeof(CACCMSKeyAgreeRecipientInfo));
02169     //  SET_HEAD_TAIL_INCREMENT(pEnvelopedData->recipientInfos, cur)
02170     //}
02171 }
02180 void CPKIFEnvelopedDataImpl::AddCerts(
02182     CACCMSEnvelopedData* pEnvelopedData)
02183 {
02184     LOG_STRING_DEBUG("CPKIFEnvelopedData::AddCerts(CACCMSEnvelopedData* pEnvelopedData)", TOOLKIT_CRYPTO_MISC, 0, this);
02185 
02186     //if no certs have been associated with this instance return now
02187     if(m_certificates.empty())
02188         return;
02189 
02190     //else initialize the list and update the version info
02191     pEnvelopedData->originatorInfo.certs.count = 0;
02192     pEnvelopedData->originatorInfo.m.certsPresent = 1;
02193     pEnvelopedData->version = CACCMSv2;
02194 
02195     //This function will put any certs held in the m_certificates member (i.e. those added via the 
02196     //AddCertificate function) into the CACCMSEnvelopedData structure passed in
02197     DListNode* cur = NULL;
02198     CPKIFCertificateList::iterator certPos; 
02199     CPKIFCertificateList::iterator certEnd = m_certificates.end();
02200     for(certPos = m_certificates.begin(); certPos != certEnd; ++certPos)
02201     {
02202         if(NULL == cur)
02203         {
02204             NEW_NODE(cur)
02205         }
02206         else
02207         {
02208             NEW_NEXT_AND_ADVANCE(cur)
02209         }
02210 
02211         //throw bad_alloc - memory will be cleaned by the memory helper object
02212         //into which things have been allocated
02213         CACCMSCertificateChoices* tmpChoice = new CACCMSCertificateChoices;
02214         tmpChoice->t = T_CACCMSCertificateChoices_certificate;
02215         tmpChoice->u.certificate = new ASN1OpenType;
02216         
02217         //certs were screened when added to make sure the encoded buffer existed
02218         tmpChoice->u.certificate->data = (*certPos)->Encoded()->GetBuffer();
02219         tmpChoice->u.certificate->numocts = (*certPos)->Encoded()->GetLength();
02220         
02221         cur->data = tmpChoice;
02222 
02223         SET_HEAD_TAIL_INCREMENT(pEnvelopedData->originatorInfo.certs, cur)
02224     }   
02225 }
02226 
02235 void CPKIFEnvelopedDataImpl::AddCRLs(
02237     CACCMSEnvelopedData* pEnvelopedData)
02238 {
02239     LOG_STRING_DEBUG("CPKIFEnvelopedData::AddCRLs(CACCMSEnvelopedData* pEnvelopedData)", TOOLKIT_CRYPTO_MISC, 0, this);
02240 
02241     //if no crls have been associated with this instance return now
02242     if(m_crls.empty())
02243         return;
02244 
02245     //else initialize the list and update the version info
02246     pEnvelopedData->originatorInfo.crls.count = 0;
02247     pEnvelopedData->originatorInfo.m.crlsPresent = 1;
02248     pEnvelopedData->version = CACCMSv2;
02249 
02250     //This function will put any CRLs held in the m_crls member (i.e. those added via the 
02251     //AddCRL function) into the CACCMSEnvelopedData structure passed in
02252     DListNode* cur = NULL;
02253     CPKIFCRLList::iterator crlPos;  
02254     CPKIFCRLList::iterator crlEnd = m_crls.end();
02255     for(crlPos = m_crls.begin(); crlPos != crlEnd; ++crlPos)
02256     {
02257         if(NULL == cur)
02258         {
02259             NEW_NODE(cur)
02260         }
02261         else
02262         {
02263             NEW_NEXT_AND_ADVANCE(cur)
02264         }
02265 
02266         //throw bad_alloc - memory will be cleaned by the memory helper object
02267         //into which things have been allocated
02268         CACCMSRevocationInfoChoice* revChoice = new CACCMSRevocationInfoChoice;
02269         revChoice->t = T_CACCMSRevocationInfoChoice_crl;
02270         revChoice->u.crl = new ASN1OpenType;
02271 
02272         //crls were screened when added to make sure the encoded buffer existed
02273         revChoice->u.crl->data = (*crlPos)->Encoded()->GetBuffer();
02274         revChoice->u.crl->numocts = (*crlPos)->Encoded()->GetLength();
02275 
02276         cur->data = revChoice;
02277 
02278         SET_HEAD_TAIL_INCREMENT(pEnvelopedData->originatorInfo.crls, cur)
02279     }   
02280 }
02289 void CPKIFEnvelopedDataImpl::RemoveRecipInfos(
02291     CACCMSEnvelopedData* envelopedData)
02292 {
02293     LOG_STRING_DEBUG("CPKIFEnvelopedData::RemoveRecipInfos(CACCMSEnvelopedData* envelopedData)", TOOLKIT_CRYPTO_MISC, 0, this);
02294 
02295     //the purpose of this function is to disassociate previously existing recip info objects from
02296     //newly created recip info objects so we don't end up freeing things twice.  essentially, the
02297     //recip infos from a decoded message are temporarily patched into the recip info list of a
02298     //newly encoded message and must be removed before the memory helper object fires.
02299     if(NULL != m_envelopedData && NULL != (*m_envelopedData).data() && (*m_envelopedData)->recipientInfos.count)
02300     {
02301         //added tmp stuff 11/11/2003
02302         DListNode* cur = envelopedData->recipientInfos.head, *tmp = NULL;
02303         for(unsigned int ii = 0; ii < (*m_envelopedData)->recipientInfos.count && NULL != cur; ++ii, --envelopedData->recipientInfos.count)
02304         {
02305             tmp = cur;
02306             cur = cur->next;
02307             delete tmp;
02308         }
02309         envelopedData->recipientInfos.head = cur;
02310     }
02311 }
02319 void CPKIFEnvelopedData::GetEncodedUnprotectedAttributes (
02321     CPKIFBufferPtr& buf) {
02322   try
02323   {
02324     if (NULL != m_impl->m_envelopedData && NULL != m_impl->m_envelopedData->data() 
02325       && (*m_impl->m_envelopedData)->m.unprotectedAttrsPresent)
02326     {
02327       CACASNWRAPPER_CREATE(CACCMSUnprotectedAttributes, attrWrapper);
02328       ASN1OpenType *data = attrWrapper.Encode (&(*m_impl->m_envelopedData)->unprotectedAttrs);
02329       CPKIFBufferPtr tmp(new CPKIFBuffer(data->data, data->numocts));
02330       buf = tmp;
02331       delete data;
02332       return;
02333     }
02334   } 
02335   catch (...)
02336   {
02337   }
02338 
02339   CPKIFBufferPtr nullExt;
02340   buf = nullExt;
02341 }
02349 void CPKIFEnvelopedData::_GetUnprotectedAttributes(
02351     std::vector<CPKIFAttributePtr> attrVector)
02352 {
02353     CPKIFCMSAttributeMediator2* mediator = CPKIFCMSAttributeMediator2::GetInstance();
02354     this->IPKIFHasAttributes::GetUnprotectedAttributes(mediator, attrVector);
02355 }
02363 void CPKIFEnvelopedData::GetAddedUnprotectedAttributes(
02365     std::vector<CPKIFAttributePtr>& attr)
02366 {
02367   CPKIFAttributeList::iterator pos;
02368   CPKIFAttributeList::iterator end = m_impl->m_unprotectedAttributes.end();
02369   for (pos = m_impl->m_unprotectedAttributes.begin(); pos != end; pos++)
02370   {
02371     attr.push_back (*pos);
02372   }
02373 }
02381 CPKIFEncryptedContentInfoPtr CPKIFEnvelopedData::GetEncryptedData() const
02382 {
02383     if(m_impl->m_dataToEncrypt == (CPKIFEncryptedContentInfo*)NULL)
02384     {
02385         CPKIFEncryptedContentInfoPtr tmpECIP(new CPKIFEncryptedContentInfo());
02386 
02387         //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)
02388         //throw bad_alloc or CPKIFException
02389         CPKIFOIDPtr tmpOID(new CPKIFOID((*m_impl->m_envelopedData)->encryptedContentInfo.contentType.subid, (*m_impl->m_envelopedData)->encryptedContentInfo.contentType.numids));
02390         tmpECIP->SetOID(tmpOID);
02391 
02392         //actual content is optional - add it to the object if it's there...
02393         if((*m_impl->m_envelopedData)->encryptedContentInfo.m.encryptedContentPresent)
02394         {
02395             //throw bad_alloc
02396             CPKIFBufferPtr tmpBuf(new CPKIFBuffer((*m_impl->m_envelopedData)->encryptedContentInfo.encryptedContent.data, (*m_impl->m_envelopedData)->encryptedContentInfo.encryptedContent.numocts));
02397             tmpECIP->SetContent(tmpBuf);
02398         }
02399 
02400         CPKIFOIDPtr tmpContentAlgOID(new CPKIFOID((*m_impl->m_envelopedData)->encryptedContentInfo.contentEncryptionAlgorithm.algorithm.subid, (*m_impl->m_envelopedData)->encryptedContentInfo.contentEncryptionAlgorithm.algorithm.numids));
02401         CPKIFBufferPtr tmpParams;
02402         if((*m_impl->m_envelopedData)->encryptedContentInfo.contentEncryptionAlgorithm.m.parametersPresent)
02403         {
02404             CPKIFBufferPtr newBuf(new CPKIFBuffer((*m_impl->m_envelopedData)->encryptedContentInfo.contentEncryptionAlgorithm.parameters.data, (*m_impl->m_envelopedData)->encryptedContentInfo.contentEncryptionAlgorithm.parameters.numocts));
02405             tmpParams = newBuf;
02406         }
02407         
02408         CPKIFAlgorithmIdentifierPtr contentAlg(new CPKIFAlgorithmIdentifier(tmpContentAlgOID, tmpParams));
02409         tmpECIP->SetAlgorithmIdentifier(contentAlg);
02410 
02411         //save the new ecip
02412         CPKIFEnvelopedData* nonConst = const_cast<CPKIFEnvelopedData*>(this);
02413         nonConst->m_impl->m_dataToEncrypt = tmpECIP;
02414     }
02415 
02416     return m_impl->m_dataToEncrypt;
02417 }

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