diff -r 000000000000 -r e35f40988205 xmlsecurityengine/xmlsecwrapper/src/xmlsecwencrypt.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xmlsecurityengine/xmlsecwrapper/src/xmlsecwencrypt.cpp Thu Dec 17 09:29:21 2009 +0200 @@ -0,0 +1,673 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class with methods needed in encryption and decryption process. +* +*/ + +#include + +// XML Engine +#include +#include +#include + +#include +#include +#include + +#include + +// XML Sec +#include "xmlsec_crypto.h" +#include "xmlsec_xmlsec.h" +#include "xmlsec_xmltree.h" +#include "xmlsec_xmlenc.h" +#include "xmlsec_templates.h" +#include "xmlsecwinternalutils.h" + +#include "xmlsecwerrors.h" +#include "xmlsecwdefs.h" +#include "xmlsecwencrypt.h" +#include "xmlsecwkeymanager.h" +#include "xmlsecwtemplate.h" +#include "xmlsecwglobalstate.h" + +const TInt K3DESKeySize = 24; +const TInt KAESKeySize256 = 32; + +namespace Encrypt + { + +// --------------------------------------------------------------------------- +// Reset encryption ctxt +// --------------------------------------------------------------------------- +// +void ResetCtx(xmlSecEncCtxPtr aCtx, CXmlSecKeyManager* aMngr) + { + xmlSecKeyPtr tmpKey = NULL; + if(!aMngr) + { + tmpKey = aCtx->encKey; + aCtx->encKey = NULL; + } + // reset ctx + xmlSecEncCtxReset(aCtx); + if(aMngr) + { + xmlSecEncCtxInitialize(aCtx,aMngr->GetKeyManagerPtr()); + } + + aCtx->encKey = tmpKey; + } + +// --------------------------------------------------------------------------- +// Read key from buffer +// --------------------------------------------------------------------------- +// +xmlSecKeyPtr ReadKeyFromBufferL(const TDesC8& aKeyFile, + const TDesC8& aKeyName, + CXmlSecEncrypt::TXmlSecKeyType aAlgorithm) + { + if(aKeyFile.Length() == 0) + { + User::Leave(KErrWrongParameter); + } + char* name = XmlEngXmlCharFromDes8L(aKeyName); + CleanupStack::PushL(name); + char* tmpName = NULL; + if(aKeyName.Length()) + { + tmpName = name; + } + xmlSecKeyPtr keyPtr = NULL; + // read key and check size + if (aAlgorithm == CXmlSecEncrypt::EAES256) + { + if(aKeyFile.Size() != KAESKeySize256) + { + User::Leave(KErrKey); + } + keyPtr = xmlSecKeyReadMemory(xmlSecKeyDataAesId, aKeyFile.Ptr(), aKeyFile.Size()); + } + else if (aAlgorithm == CXmlSecEncrypt::E3DES) + { + if(aKeyFile.Size() != K3DESKeySize) + { + User::Leave(KErrKey); + } + keyPtr = xmlSecKeyReadMemory(xmlSecKeyDataDesId, aKeyFile.Ptr(), aKeyFile.Size()); + } + XmlEngOOMTestL(); + XmlSecErrorFlagTestL(); + + if(!keyPtr) + { + User::Leave(KErrKey); + } + // set key name + if(xmlSecKeySetName(keyPtr, (const unsigned char*) tmpName) < 0) + { + xmlSecKeyDestroy(keyPtr); + XmlEngOOMTestL(); + XmlSecErrorFlagTestL(); + User::Leave(KErrKey); + } + CleanupStack::PopAndDestroy(name); + return keyPtr; + } + +// --------------------------------------------------------------------------- +// Read key from file +// --------------------------------------------------------------------------- +// +xmlSecKeyPtr ReadKeyFromFileL(const TDesC8& aKeyFile, + const TDesC8& aKeyName, + CXmlSecEncrypt::TXmlSecKeyType aKeyFormat) + { + if(aKeyFile.Length() == 0) + { + User::Leave(KErrWrongParameter); + } + RFs fs; + User::LeaveIfError(fs.Connect()); + CleanupClosePushL(fs); + RFile keyFile; + TInt size; + RBuf keyName; + // read key from file + keyName.CreateL(KMaxFileName); + CleanupClosePushL(keyName); + keyName.Copy(aKeyFile); + User::LeaveIfError(keyFile.Open(fs, keyName, EFileRead | EFileShareReadersOnly)); + CleanupStack::PopAndDestroy(&keyName); + CleanupClosePushL(keyFile); + User::LeaveIfError(keyFile.Size(size)); + HBufC8* key = HBufC8::NewLC(size); + TPtr8 keyPtrD = key->Des(); + User::LeaveIfError(keyFile.Read(keyPtrD, size)); + xmlSecKeyPtr keyPtr = ReadKeyFromBufferL(*key,aKeyName,aKeyFormat); + CleanupStack::PopAndDestroy(key); + CleanupStack::PopAndDestroy(&keyFile); + CleanupStack::PopAndDestroy(&fs); + return keyPtr; + } + + } // namespace Encrypt + +// --------------------------------------------------------------------------- +// Two phase constructor +// --------------------------------------------------------------------------- +// +EXPORT_C CXmlSecEncrypt* CXmlSecEncrypt::NewLC() + { + CXmlSecEncrypt* self = new (ELeave) CXmlSecEncrypt; + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +// --------------------------------------------------------------------------- +// Two phase constructor +// --------------------------------------------------------------------------- +// +EXPORT_C CXmlSecEncrypt* CXmlSecEncrypt::NewL() + { + CXmlSecEncrypt* self = CXmlSecEncrypt::NewLC(); + CleanupStack::Pop(self); + return self; + } + +// --------------------------------------------------------------------------- +// Encrypt data from buffer +// --------------------------------------------------------------------------- +// +EXPORT_C RXmlEngDocument CXmlSecEncrypt::EncryptDataL(const TDesC8& aData) + { + if(!aData.Length()) + { + User::Leave(KErrWrongParameter); + } + if(iTemplate.IsNull()) + { + User::Leave(KErrTemplate); + } + xmlSecEncCtxPtr tmpCtx = ENC_CTX; + + Encrypt::ResetCtx(tmpCtx,NULL); + + xmlNodePtr node = NULL; + // Copy tmpl file + xmlDocPtr result = xmlCopyDoc(INTERNAL_DOCPTR(iTemplate), 1); + if(!result) + { + User::Leave(KErrNoMemory); + } + // find start node + node = xmlSecFindNode(xmlDocGetRootElement(result), xmlSecNodeEncryptedData, xmlSecEncNs); + if(!node) + { + xmlFreeDoc(result); + User::Leave(KErrTemplate); + } + + // encrypt the data + if(xmlSecEncCtxBinaryEncrypt(tmpCtx, node, aData.Ptr(), aData.Length()) < 0) + { + xmlFreeDoc(result); + XmlEngOOMTestL(); + XmlSecErrorFlagTestL(); + User::Leave(KErrEncrypt); + } + RXmlEngDocument doc; + XmlSecGlobalState* gs = XmlSecGetTls(); + doc.OpenL(*gs->iDOMImpl,result); + return doc; + } + +// --------------------------------------------------------------------------- +// Encrypt xml document +// --------------------------------------------------------------------------- +// +EXPORT_C void CXmlSecEncrypt::EncryptXmlDocumentL(RXmlEngDocument& aDocument) + { + if(aDocument.IsNull()) + { + User::Leave(KErrWrongParameter); + } + EncryptXmlNodeL(aDocument.DocumentElement()); + } + +// --------------------------------------------------------------------------- +// Encrypt xml node +// --------------------------------------------------------------------------- +// +EXPORT_C void CXmlSecEncrypt::EncryptXmlNodeL(TXmlEngElement aNode) + { + if(aNode.IsNull()) + { + User::Leave(KErrWrongParameter); + } + if(iTemplate.IsNull()) + { + User::Leave(KErrTemplate); + } + xmlSecEncCtxPtr tmpCtx = ENC_CTX; + + Encrypt::ResetCtx(tmpCtx,NULL); + + xmlNodePtr node = NULL; + // find start node + node = xmlSecFindNode(xmlDocGetRootElement(INTERNAL_DOCPTR(iTemplate)), + xmlSecNodeEncryptedData, xmlSecEncNs); + if(!node) + { + User::Leave(KErrTemplate); + } + + xmlNodePtr result = xmlCopyNode(node, 1); + if(!result) + { + XmlEngOOMTestL(); + User::Leave(KErrNoMemory); + } + // encrypt the data + if(xmlSecEncCtxXmlEncrypt(tmpCtx, result, INTERNAL_NODEPTR(aNode)) < 0) + { + xmlFreeNode( result ); + XmlEngOOMTestL(); + XmlSecErrorFlagTestL(); + User::Leave(KErrEncrypt); + } + } + +// --------------------------------------------------------------------------- +// Encrypt xml node +// --------------------------------------------------------------------------- +// +EXPORT_C void CXmlSecEncrypt::EncryptXmlNodeKeyFromFileL(TXmlEngElement aNode, + RXmlEngDocument& aTemplate, + const TDesC8& aKeyFile, + const TDesC8& aKeyName, + TXmlSecKeyType aKeyFormat) + { + SetKeyFromFileL(aKeyFile,aKeyName,aKeyFormat); + SetTemplateL(aTemplate); + EncryptXmlNodeL(aNode); + } + +// --------------------------------------------------------------------------- +// Encrypt xml document +// --------------------------------------------------------------------------- +// +EXPORT_C void CXmlSecEncrypt::EncryptXmlDocumentKeyFromFileL(RXmlEngDocument& aDoc, + RXmlEngDocument& aTemplate, + const TDesC8& aKeyFile, + const TDesC8& aKeyName, + TXmlSecKeyType aKeyFormat) + { + SetKeyFromFileL(aKeyFile,aKeyName,aKeyFormat); + SetTemplateL(aTemplate); + EncryptXmlDocumentL(aDoc); + } + +// --------------------------------------------------------------------------- +// Encrypt xml node +// --------------------------------------------------------------------------- +// +EXPORT_C void CXmlSecEncrypt::EncryptXmlNodeKeyFromBufferL(TXmlEngElement aNode, + RXmlEngDocument& aTemplate, + const TDesC8& aKey, + const TDesC8& aKeyName, + TXmlSecKeyType aKeyFormat) + { + SetKeyFromBufferL(aKey,aKeyName,aKeyFormat); + SetTemplateL(aTemplate); + EncryptXmlNodeL(aNode); + } + +// --------------------------------------------------------------------------- +// Encrypt xml document +// --------------------------------------------------------------------------- +// +EXPORT_C void CXmlSecEncrypt::EncryptXmlDocumentKeyFromBufferL(RXmlEngDocument& aDoc, + RXmlEngDocument& aTemplate, + const TDesC8& aKey, + const TDesC8& aKeyName, + TXmlSecKeyType aKeyFormat) + { + SetKeyFromBufferL(aKey,aKeyName,aKeyFormat); + SetTemplateL(aTemplate); + EncryptXmlDocumentL(aDoc); + } + +// --------------------------------------------------------------------------- +// Decrypt xml node +// --------------------------------------------------------------------------- +// +EXPORT_C HBufC8* CXmlSecEncrypt::DecryptXmlNodeKeyFromFileL(TXmlEngElement aNode, + const TDesC8& aKeyFile, + const TDesC8& aKeyName, + TXmlSecKeyType aKeyFormat) + { + SetKeyFromFileL(aKeyFile,aKeyName,aKeyFormat); + return DecryptXmlNodeL(aNode); + } + +// --------------------------------------------------------------------------- +// Decrypt xml document +// --------------------------------------------------------------------------- +// +EXPORT_C HBufC8* CXmlSecEncrypt::DecryptXmlDocumentKeyFromFileL(RXmlEngDocument& aDoc, + const TDesC8& aKeyFile, + const TDesC8& aKeyName, + TXmlSecKeyType aKeyFormat) + { + SetKeyFromFileL(aKeyFile,aKeyName,aKeyFormat); + return DecryptXmlDocumentL(aDoc); + } + +// --------------------------------------------------------------------------- +// Decrypt xml node +// --------------------------------------------------------------------------- +// +EXPORT_C HBufC8* CXmlSecEncrypt::DecryptXmlNodeKeyFromBufferL(TXmlEngElement aNode, + const TDesC8& aKey, + const TDesC8& aKeyName, + TXmlSecKeyType aKeyFormat) + { + SetKeyFromBufferL(aKey,aKeyName,aKeyFormat); + return DecryptXmlNodeL(aNode); + } + +// --------------------------------------------------------------------------- +// Decrypt xml document +// --------------------------------------------------------------------------- +// +EXPORT_C HBufC8* CXmlSecEncrypt::DecryptXmlDocumentKeyFromBufferL(RXmlEngDocument& aDoc, + const TDesC8& aKey, + const TDesC8& aKeyName, + TXmlSecKeyType aKeyFormat) + { + SetKeyFromBufferL(aKey,aKeyName,aKeyFormat); + return DecryptXmlDocumentL(aDoc); + } + +// --------------------------------------------------------------------------- +// Decrypt xml node +// --------------------------------------------------------------------------- +// +EXPORT_C HBufC8* CXmlSecEncrypt::DecryptXmlNodeL(TXmlEngElement aNode) + { + if(aNode.IsNull()) + { + User::Leave(KErrWrongParameter); + } + + xmlNodePtr node = NULL; + xmlNodePtr root = INTERNAL_NODEPTR(aNode); + // find start node + node = xmlSecFindNode(root,xmlSecNodeEncryptedData, xmlSecEncNs); + if(!node) + { + User::Leave(KErrWrongParameter); + } + + xmlSecEncCtxPtr tmpCtx = ENC_CTX; + + Encrypt::ResetCtx(tmpCtx,NULL); + // decrypt data + if((xmlSecEncCtxDecrypt(tmpCtx, node) < 0) + || (!tmpCtx->result)) + { + XmlEngOOMTestL(); + XmlSecErrorFlagTestL(); + User::Leave(KErrDecrypt); + } + // if result is data not xml part it is returned as hbufc8* + if(!tmpCtx->resultReplaced) + { + xmlSecByte* result = xmlSecBufferGetData(tmpCtx->result); + if(result) + { + TPtrC8 ptr(result,tmpCtx->result->size); + return ptr.AllocL(); + } + } + return NULL; + } + +// --------------------------------------------------------------------------- +// Decrypt xml document +// --------------------------------------------------------------------------- +// +EXPORT_C HBufC8* CXmlSecEncrypt::DecryptXmlDocumentL(RXmlEngDocument& aDocument) + { + if(aDocument.IsNull()) + { + User::Leave(KErrWrongParameter); + } + return DecryptXmlNodeL(aDocument.DocumentElement()); + } + +// --------------------------------------------------------------------------- +// Set template from file +// --------------------------------------------------------------------------- +// +EXPORT_C void CXmlSecEncrypt::SetTemplateFromFileL(const TDesC8& aTemplate) + { + XmlSecTemplate::SetTemplateFromFileL(iTemplate,aTemplate); + } + +// --------------------------------------------------------------------------- +// Set template from file +// --------------------------------------------------------------------------- +// +EXPORT_C void CXmlSecEncrypt::SetTemplateFromFileL(RFs& aRFs, const TDesC8& aTemplate) + { + XmlSecTemplate::SetTemplateFromFileL(iTemplate,aTemplate,aRFs); + } + +// --------------------------------------------------------------------------- +// Set template from buffer +// --------------------------------------------------------------------------- +// +EXPORT_C void CXmlSecEncrypt::SetTemplateFromBufferL(const TDesC8& aTemplate) + { + XmlSecTemplate::SetTemplateFromBufferL(iTemplate,aTemplate); + } + +// --------------------------------------------------------------------------- +// Set template from DOM tree +// --------------------------------------------------------------------------- +// +EXPORT_C void CXmlSecEncrypt::SetTemplateL(const RXmlEngDocument& aTemplate) + { + XmlSecTemplate::SetTemplateL(iTemplate,aTemplate); + } + +// --------------------------------------------------------------------------- +// Set key info node in template +// --------------------------------------------------------------------------- +// +EXPORT_C void CXmlSecEncrypt::SetKeyInfoL(const TDesC8& aKeyName) + { + XmlSecTemplate::SetKeyInfoL(iTemplate,aKeyName); + } + +// --------------------------------------------------------------------------- +// Set key info node in template +// --------------------------------------------------------------------------- +// +EXPORT_C void CXmlSecEncrypt::SetKeyInfoL(TXmlEngElement aKeyProp) + { + XmlSecTemplate::SetKeyInfoL(iTemplate,aKeyProp); + } + +// --------------------------------------------------------------------------- +// Create encryption template +// --------------------------------------------------------------------------- +// +EXPORT_C const RXmlEngDocument& CXmlSecEncrypt::CreateTemplateL(TXmlSecKeyType aAlgorithm, + TXmlSecDataType aDataType) + { + if(iTemplate.NotNull()) + { + iTemplate.Close(); + } + xmlNodePtr node = NULL; + // create encryption template to encrypt XML file and replace + // its content with encryption result + const xmlChar* mimeType = NULL; + if(aDataType == CXmlSecEncrypt::ENode) + { + mimeType = xmlSecTypeEncElement; + } + else if (aDataType == CXmlSecEncrypt::ENodeContent) + { + mimeType = xmlSecTypeEncContent; + } + + if (aAlgorithm == EAES256) + { + node = xmlSecTmplEncDataCreate(NULL, xmlSecTransformAes256CbcId, + NULL, mimeType, NULL, NULL); + } + else if (aAlgorithm == E3DES) + { + node = xmlSecTmplEncDataCreate(NULL, xmlSecTransformDes3CbcId, + NULL, mimeType, NULL, NULL); + } + if(!node) + { + XmlEngOOMTestL(); + XmlSecErrorFlagTestL(); + User::Leave(KErrTemplate); + } + + // we want to put encrypted data in the node + if(!xmlSecTmplEncDataEnsureCipherValue(node)) + { + xmlFreeNode( node ); + XmlEngOOMTestL(); + XmlSecErrorFlagTestL(); + User::Leave(KErrTemplate); + } + + // add and nodes to put key name in the signed document + xmlNodePtr keyInfo = xmlSecTmplEncDataEnsureKeyInfo(node, NULL); + if(!keyInfo) + { + xmlFreeNode( node ); + XmlEngOOMTestL(); + XmlSecErrorFlagTestL(); + User::Leave(KErrTemplate); + } + + XmlSecGlobalState* gs = XmlSecGetTls(); + CleanupStack::PushL(TCleanupItem(LibxmlNodeCleanup,(TAny*)node)); + iTemplate.OpenL(*gs->iDOMImpl,TXmlEngElement(node)); + CleanupStack::Pop(node); + return iTemplate; + } + +// --------------------------------------------------------------------------- +// Return current encryption template +// --------------------------------------------------------------------------- +// +EXPORT_C const RXmlEngDocument& CXmlSecEncrypt::CurrentTemplate() const + { + return iTemplate; + } + +// --------------------------------------------------------------------------- +// Destroy current encryption template +// --------------------------------------------------------------------------- +// +EXPORT_C void CXmlSecEncrypt::DestroyCurrentTemplate() + { + XmlSecTemplate::DestroyTemplate(iTemplate); + } + +// --------------------------------------------------------------------------- +// Set key from file +// --------------------------------------------------------------------------- +// +EXPORT_C void CXmlSecEncrypt::SetKeyFromFileL(const TDesC8& aKeyFile, + const TDesC8& aKeyName, + TXmlSecKeyType aAlgorithm) + { + xmlSecEncCtxPtr tmp = ENC_CTX; + if(tmp->encKey) + { + xmlSecKeyDestroy(tmp->encKey); + tmp->encKey = NULL; + } + tmp->encKey = Encrypt::ReadKeyFromFileL(aKeyFile,aKeyName,aAlgorithm); + } + +// --------------------------------------------------------------------------- +// Set key from buffer +// --------------------------------------------------------------------------- +// +EXPORT_C void CXmlSecEncrypt::SetKeyFromBufferL(const TDesC8& aKeyFile, + const TDesC8& aKeyName, + TXmlSecKeyType aAlgorithm) + { + xmlSecEncCtxPtr tmp = ENC_CTX; + if(tmp->encKey) + { + xmlSecKeyDestroy(tmp->encKey); + tmp->encKey = NULL; + } + tmp->encKey = Encrypt::ReadKeyFromBufferL(aKeyFile,aKeyName,aAlgorithm); + } + +// --------------------------------------------------------------------------- +// Constructor +// --------------------------------------------------------------------------- +// +CXmlSecEncrypt::CXmlSecEncrypt() + { + iTemplate = RXmlEngDocument(); + } + +// --------------------------------------------------------------------------- +// Second phase constructor +// --------------------------------------------------------------------------- +// +void CXmlSecEncrypt::ConstructL() + { + // create encryption context + iEncCtx = xmlSecEncCtxCreate(NULL); + if(!iEncCtx) + { + User::Leave(KErrNoMemory); + } + } + +// --------------------------------------------------------------------------- +// Destructor +// --------------------------------------------------------------------------- +// +CXmlSecEncrypt::~CXmlSecEncrypt() + { + if(iTemplate.NotNull()) + { + iTemplate.Close(); + } + if(iEncCtx) + { + xmlSecEncCtxDestroy(ENC_CTX); + } + }