--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xmlsecurityengine/xmlsecwrapper/src/xmlsecwsign.cpp Thu Dec 17 09:29:21 2009 +0200
@@ -0,0 +1,1037 @@
+/*
+* 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 used in sign and verification process.
+*
+*/
+
+// XML Engine
+#include <libxml2_tree.h>
+#include <libxml2_xmlmemory.h>
+#include <libxml2_parser.h>
+#include <libxml2_globals.h>
+
+#include <xmlengmem.h>
+#include <xmlengxestd.h>
+#include <xmlengutils.h>
+#include <xmlengxestrings.h>
+
+#include <xmlengdom.h>
+
+// XML Sec
+#include "xmlsec_crypto.h"
+#include "xmlsec_xmlsec.h"
+#include "xmlsec_xmltree.h"
+#include "xmlsec_xmldsig.h"
+#include "xmlsec_templates.h"
+#include "xmlsecc_x509.h"
+
+#include "xmlsecwsign.h"
+#include "xmlsecwkeymanager.h"
+#include "xmlsecwerrors.h"
+#include "xmlsecwdefs.h"
+#include "xmlsecwtemplate.h"
+#include "xmlsecwinternalutils.h"
+#include "xmlsecwglobalstate.h"
+
+namespace Sign
+ {
+// ---------------------------------------------------------------------------
+// Reset sign ctx
+// ---------------------------------------------------------------------------
+//
+xmlSecDSigCtxPtr ResetCtxL(xmlSecDSigCtxPtr aCtx, CXmlSecKeyManager* aMngr)
+ {
+ xmlSecKeyPtr tmpKey = NULL;
+ if(!aMngr)
+ {
+ tmpKey = aCtx->signKey;
+ aCtx->signKey = NULL;
+ }
+ // destroy old ctx
+ xmlSecDSigCtxDestroy(aCtx);
+ // create new ctx
+ if(aMngr)
+ {
+ aCtx = xmlSecDSigCtxCreate(aMngr->GetKeyManagerPtr());
+ }
+ else
+ {
+ aCtx = xmlSecDSigCtxCreate(NULL);
+ }
+ // add key if needed
+ if ( !aCtx )
+ {
+ if ( tmpKey )
+ {
+ xmlSecKeyDestroy( tmpKey );
+ }
+ User::Leave( KErrNoMemory );
+ }
+
+ aCtx->signKey = tmpKey;
+ tmpKey = NULL;
+ return aCtx;
+ }
+
+// ---------------------------------------------------------------------------
+// Read key from file
+// ---------------------------------------------------------------------------
+//
+xmlSecKeyPtr ReadKeyFromFileL(const TDesC8& aKeyFile,
+ const TDesC8& aKeyName,
+ CXmlSecSign::TXmlSecKeyType aKeyFormat)
+ {
+ if(aKeyFile.Length() == 0)
+ {
+ User::Leave(KErrWrongParameter);
+ }
+
+ xmlSecKeyPtr keyPtr = NULL;
+ char* file = XmlEngXmlCharFromDes8L(aKeyFile);
+ CleanupStack::PushL(file);
+ char* name = XmlEngXmlCharFromDes8L(aKeyName);
+ CleanupStack::PushL(name);
+ // load key - used method depend key type
+ if (aKeyFormat == CXmlSecSign::ERSAPrivate)
+ {
+ if(aKeyName.Length() == 0)
+ {
+ User::Leave(KErrWrongParameter);
+ }
+ keyPtr = xmlSecCryptoAppKeyLoadWithName(file, xmlSecKeyDataFormatPkcs8Der,
+ name, NULL, NULL, NULL);
+ }
+ else if (aKeyFormat == CXmlSecSign::ERSAPublic)
+ {
+ if(aKeyName.Length() == 0)
+ {
+ User::Leave(KErrWrongParameter);
+ }
+ keyPtr = xmlSecCryptoAppKeyLoadWithName(file, xmlSecKeyDataFormatDer,
+ name, NULL, NULL, NULL);
+ }
+ else if (aKeyFormat == CXmlSecSign::EHMAC)
+ keyPtr = xmlSecKeyReadBinaryFile(xmlSecKeyDataHmacId,file);
+
+ if(!keyPtr)
+ {
+ XmlEngOOMTestL();
+ XmlSecErrorFlagTestL();
+ User::Leave(KErrKey);
+ }
+ const xmlChar* KTmpName = NULL;
+ if(aKeyName.Length())
+ {
+ KTmpName = (xmlChar*) name;
+ }
+ // add key name to key
+ if((aKeyFormat == CXmlSecSign::EHMAC) && (xmlSecKeySetName(keyPtr,KTmpName) < 0))
+ {
+ xmlSecKeyDestroy(keyPtr);
+ XmlEngOOMTestL();
+ XmlSecErrorFlagTestL();
+ User::Leave(KErrKey);
+ }
+
+ CleanupStack::PopAndDestroy(name);
+ CleanupStack::PopAndDestroy(file);
+ return keyPtr;
+ }
+
+// ---------------------------------------------------------------------------
+// Read key from buffer
+// ---------------------------------------------------------------------------
+//
+xmlSecKeyPtr ReadKeyFromBufferL(const TDesC8& aBuffer,
+ const TDesC8& aKeyName,
+ CXmlSecSign::TXmlSecKeyType aKeyFormat)
+ {
+ if(aBuffer.Length() == 0)
+ {
+ User::Leave(KErrWrongParameter);
+ }
+ char* name = XmlEngXmlCharFromDes8L(aKeyName);
+ CleanupStack::PushL(name);
+ xmlSecKeyPtr keyPtr = NULL;
+ // load key - used method depend key type
+ if (aKeyFormat == CXmlSecSign::ERSAPrivate)
+ {
+ if(aKeyName.Length() == 0)
+ {
+ User::Leave(KErrWrongParameter);
+ }
+ keyPtr = xmlSecCryptoAppKeyLoadMemoryWithName(aBuffer.Ptr(), aBuffer.Size(),
+ xmlSecKeyDataFormatPkcs8Der, name, NULL, NULL, NULL);
+ }
+ else if (aKeyFormat == CXmlSecSign::ERSAPublic)
+ {
+ if(aKeyName.Length() == 0)
+ {
+ User::Leave(KErrWrongParameter);
+ }
+ keyPtr = xmlSecCryptoAppKeyLoadMemoryWithName(aBuffer.Ptr(), aBuffer.Size(),
+ xmlSecKeyDataFormatDer, name, NULL, NULL, NULL);
+ }
+ else if (aKeyFormat == CXmlSecSign::EHMAC)
+ keyPtr = xmlSecKeyReadMemory(xmlSecKeyDataHmacId,aBuffer.Ptr(), aBuffer.Size());
+
+ XmlEngOOMTestL();
+ XmlSecErrorFlagTestL();
+ if(!keyPtr)
+ {
+ User::Leave(KErrKey);
+ }
+
+ const xmlChar* KTmpName = NULL;
+ if(aKeyName.Length())
+ {
+ KTmpName = (xmlChar*) name;
+ }
+ // add key name to key
+ if((aKeyFormat == CXmlSecSign::EHMAC) && (xmlSecKeySetName(keyPtr,KTmpName) < 0))
+ {
+ xmlSecKeyDestroy(keyPtr);
+ XmlEngOOMTestL();
+ XmlSecErrorFlagTestL();
+ User::Leave(KErrKey);
+ }
+ CleanupStack::PopAndDestroy(name);
+ return keyPtr;
+ }
+
+// ---------------------------------------------------------------------------
+// Reset template settings
+// ---------------------------------------------------------------------------
+//
+void TemplateCleanup(TAny* aPref)
+ {
+ if(aPref)
+ {
+ delete aPref;
+ xmlSetPrefix(NULL);
+ }
+ xmlSetNewLineFlag(1);
+ }
+
+ }// namespace Sign
+
+// ---------------------------------------------------------------------------
+// Two phase constructor
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CXmlSecSign* CXmlSecSign::NewLC()
+ {
+ CXmlSecSign* self = new (ELeave) CXmlSecSign;
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// Two phase constructor
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CXmlSecSign* CXmlSecSign::NewL()
+ {
+ CXmlSecSign* self = CXmlSecSign::NewLC();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// Sign the xml document
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TXmlEngElement CXmlSecSign::SignXmlDocumentL(RXmlEngDocument& aDocument,
+ TBool aUseCurrentKey)
+ {
+ if(aDocument.IsNull())
+ {
+ User::Leave(KErrWrongParameter);
+ }
+ return SignXmlNodeL(aDocument.DocumentElement(),aUseCurrentKey);
+ }
+
+// ---------------------------------------------------------------------------
+// Sign the xml document
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TXmlEngElement CXmlSecSign::SignXmlDocumentKeyFromFileL(RXmlEngDocument& aDocument,
+ RXmlEngDocument& aTemplate,
+ const TDesC8& aKeyFile,
+ const TDesC8& aKeyName,
+ TXmlSecKeyType aKeyFormat)
+ {
+ SetKeyFromFileL(aKeyFile,aKeyName,aKeyFormat);
+ if(EFalse == iTemplate.IsSameNode(aTemplate))
+ {
+ SetTemplateL(aTemplate);
+ }
+ iSkipTmplLookUp = ETrue; //Set to TRUE indicating to skip searching for Template in document
+ return SignXmlDocumentL(aDocument);
+ }
+
+// ---------------------------------------------------------------------------
+// Sign the xml document
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TXmlEngElement CXmlSecSign::SignXmlDocumentKeyFromFileL(RXmlEngDocument& aDocument,
+ const TDesC8& aKeyFile,
+ const TDesC8& aKeyName,
+ TXmlSecKeyType aKeyFormat)
+ {
+ SetKeyFromFileL(aKeyFile,aKeyName,aKeyFormat);
+ return SignXmlDocumentL(aDocument);
+ }
+
+// ---------------------------------------------------------------------------
+// Sign the xml document
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TXmlEngElement CXmlSecSign::SignXmlDocumentKeyFromBufferL(RXmlEngDocument& aDocument,
+ RXmlEngDocument& aTemplate,
+ const TDesC8& aKey,
+ const TDesC8& aKeyName,
+ TXmlSecKeyType aKeyFormat)
+ {
+ SetKeyFromBufferL(aKey,aKeyName,aKeyFormat);
+ if(EFalse == iTemplate.IsSameNode(aTemplate))
+ {
+ SetTemplateL(aTemplate);
+ }
+ iSkipTmplLookUp = ETrue; //Set to TRUE indicating to skip searching for Template in document
+ return SignXmlDocumentL(aDocument);
+ }
+
+// ---------------------------------------------------------------------------
+// Sign the xml document
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TXmlEngElement CXmlSecSign::SignXmlDocumentKeyFromBufferL(RXmlEngDocument& aDocument,
+ const TDesC8& aKey,
+ const TDesC8& aKeyName,
+ TXmlSecKeyType aKeyFormat)
+ {
+ SetKeyFromBufferL(aKey,aKeyName,aKeyFormat);
+ return SignXmlDocumentL(aDocument);
+ }
+
+
+// ---------------------------------------------------------------------------
+// Sign the xml node
+// ---------------------------------------------------------------------------
+//
+TXmlEngElement CXmlSecSign::SignXmlNodeL(TXmlEngElement aNode, TBool aUseCurrentKey)
+ {
+ TXmlEngElement ele;
+ TBool add = FALSE;
+ xmlSecDSigCtxPtr tmpCtx = SIG_CTX;
+ // Reset ctxt
+ if(aUseCurrentKey)
+ {
+ iSigCtx = NULL;
+ tmpCtx = Sign::ResetCtxL(tmpCtx,NULL);
+ iSigCtx = tmpCtx;
+ }
+ else
+ {
+ if(!iMngr)
+ {
+ iMngr = CXmlSecKeyManager::GetInstanceL();
+ }
+ iSigCtx = NULL;
+ tmpCtx = Sign::ResetCtxL(tmpCtx,iMngr);
+ iSigCtx = tmpCtx;
+ }
+
+ xmlNodePtr node = NULL;
+
+ // skip if there is a template already available which may or may not contain Signature(from document)
+ if(EFalse == iSkipTmplLookUp)
+ {
+ // find <Signature> in aNode
+ node = xmlSecFindNode(xmlDocGetRootElement(INTERNAL_NODEPTR(aNode)->doc),
+ xmlSecNodeSignature, xmlSecDSigNs);
+ }
+ TXmlEngElement sign(node);
+ if(!node)
+ {
+ if(iTemplate.NotNull())
+ {
+ // process template
+ node = xmlSecFindNode(xmlDocGetRootElement(INTERNAL_DOCPTR(iTemplate)),
+ xmlSecNodeSignature, xmlSecDSigNs);
+ if(!node)
+ {
+ User::Leave(KErrTemplate);
+ }
+ node = xmlCopyNode(node, 1);
+ if(!node)
+ {
+ User::Leave(KErrNoMemory);
+ }
+ // add template to document that should be signed
+ sign = TXmlEngElement(node);
+ aNode.AppendChildL(sign);
+ add = TRUE;
+ }
+ }
+
+ // sign the data
+ if(xmlSecDSigCtxSign(tmpCtx, node) < 0)
+ {
+ XmlEngOOMTestL();
+ XmlSecErrorFlagTestL();
+ User::Leave(KErrSign);
+ }
+ if(add)
+ {
+ sign.Unlink();
+ }
+ iSkipTmplLookUp = EFalse; // Reset the Flag
+ return sign;
+ }
+
+// ---------------------------------------------------------------------------
+// Sign the xml nodes
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TXmlEngElement CXmlSecSign::SignXmlNodesL(RArray<TXmlEngElement>& aNodes,
+ TBool aUseCurrentKey)
+ {
+ if(!aNodes.Count())
+ {
+ User::Leave(KErrWrongParameter);
+ }
+ return SignXmlNodeL(aNodes[0].OwnerDocument().DocumentElement(),aUseCurrentKey);
+ }
+
+// ---------------------------------------------------------------------------
+// Verify xml node
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TBool CXmlSecSign::VerifyXmlNodeL(TXmlEngElement aNode,
+ TXmlSecVerificationKeyRepository aKeyRepository)
+ {
+ xmlSecDSigCtxPtr tmpCtx = SIG_CTX;
+
+ // Reset ctxt
+ if( aKeyRepository == EThisObject )
+ {
+ iSigCtx = NULL;
+ tmpCtx = Sign::ResetCtxL(tmpCtx,iMngr);
+ iSigCtx = tmpCtx;
+ }
+ else
+ {
+ if(!iMngr)
+ {
+ iMngr = CXmlSecKeyManager::GetInstanceL();
+ }
+ iSigCtx = NULL;
+ tmpCtx = Sign::ResetCtxL(tmpCtx,iMngr);
+ iSigCtx = tmpCtx;
+ }
+ // should cert store be used
+ if ( aKeyRepository == ECertStore )
+ {
+ xmlSecSetCertStoreFlag();
+ }
+ // verify data
+ if (xmlSecDSigCtxVerify(tmpCtx, INTERNAL_NODEPTR(aNode)) < 0)
+ {
+ if ( aKeyRepository == ECertStore )
+ {
+ xmlSecResetCertStoreFlag();
+ }
+ XmlEngOOMTestL();
+ XmlSecErrorFlagTestL();
+ User::Leave(KErrVerify);
+ }
+ // check result
+ if (tmpCtx->status == xmlSecDSigStatusSucceeded)
+ {
+ if ( aKeyRepository == ECertStore )
+ {
+ xmlSecResetCertStoreFlag();
+ }
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+// ---------------------------------------------------------------------------
+// Verify xml node
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TBool CXmlSecSign::VerifyXmlNodeKeyFromFileL(TXmlEngElement aNode,
+ const TDesC8& aKeyFile,
+ const TDesC8& aKeyName,
+ TXmlSecKeyType aKeyType)
+ {
+ SetKeyFromFileL(aKeyFile,aKeyName,aKeyType);
+ return VerifyXmlNodeL(aNode);
+ }
+
+// ---------------------------------------------------------------------------
+// Verify xml node
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TBool CXmlSecSign::VerifyXmlNodeKeyFromBufferL(TXmlEngElement aNode,
+ const TDesC8& aKey,
+ const TDesC8& aKeyName,
+ TXmlSecKeyType aKeyType)
+ {
+ SetKeyFromBufferL(aKey,aKeyName,aKeyType);
+ return VerifyXmlNodeL(aNode);
+ }
+
+// ---------------------------------------------------------------------------
+// Verify xml document
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TBool CXmlSecSign::VerifyXmlDocumentL(const RXmlEngDocument& aDocument,
+ TXmlSecVerificationKeyRepository aKeyRepository)
+ {
+ xmlNodePtr node = NULL;
+ TXmlEngNode tmpNode = aDocument.DocumentElement();
+ xmlNodePtr root = INTERNAL_NODEPTR(tmpNode);
+ node = xmlSecFindNode(root,xmlSecNodeSignature, xmlSecDSigNs);
+ if(!node)
+ {
+ User::Leave(KErrVerify);
+ }
+ return VerifyXmlNodeL(TXmlEngElement(node),aKeyRepository);
+ }
+
+// ---------------------------------------------------------------------------
+// Verify xml document
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TBool CXmlSecSign::VerifyXmlDocumentKeyFromFileL(const RXmlEngDocument& aDocument,
+ const TDesC8& aKeyFile,
+ const TDesC8& aKeyName,
+ TXmlSecKeyType aKeyType)
+ {
+ SetKeyFromFileL(aKeyFile,aKeyName,aKeyType);
+ return VerifyXmlDocumentL(aDocument);
+ }
+
+// ---------------------------------------------------------------------------
+// Verify xml document
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TBool CXmlSecSign::VerifyXmlDocumentKeyFromBufferL(const RXmlEngDocument& aDocument,
+ const TDesC8& aKey,
+ const TDesC8& aKeyName,
+ TXmlSecKeyType aKeyType)
+ {
+ SetKeyFromBufferL(aKey,aKeyName,aKeyType);
+ return VerifyXmlDocumentL(aDocument);
+ }
+
+// ---------------------------------------------------------------------------
+// Set template from file
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CXmlSecSign::SetTemplateFromFileL(const TDesC8& aTemplate)
+ {
+ XmlSecTemplate::SetTemplateFromFileL(iTemplate,aTemplate);
+ }
+
+// ---------------------------------------------------------------------------
+// Set template from file
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CXmlSecSign::SetTemplateFromFileL(RFs& aRFs, const TDesC8& aTemplate)
+ {
+ XmlSecTemplate::SetTemplateFromFileL(iTemplate,aTemplate,aRFs);
+ }
+
+// ---------------------------------------------------------------------------
+// Set template from buffer
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CXmlSecSign::SetTemplateFromBufferL(const TDesC8& aTemplate)
+ {
+ XmlSecTemplate::SetTemplateFromBufferL(iTemplate,aTemplate);
+ }
+
+// ---------------------------------------------------------------------------
+// Set template from DOM tree
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CXmlSecSign::SetTemplateL(const RXmlEngDocument& aTemplate)
+ {
+ XmlSecTemplate::SetTemplateL(iTemplate,aTemplate);
+ }
+
+// ---------------------------------------------------------------------------
+// Set key info node in template
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CXmlSecSign::SetKeyInfoL(const TDesC8& aKeyName)
+ {
+ XmlSecTemplate::SetKeyInfoL(iTemplate,aKeyName);
+ }
+
+// ---------------------------------------------------------------------------
+// Set key info node in template
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CXmlSecSign::SetKeyInfoL(TXmlEngElement aKeyProp)
+ {
+ XmlSecTemplate::SetKeyInfoL(iTemplate,aKeyProp);
+ }
+
+// ---------------------------------------------------------------------------
+// Create template
+// ---------------------------------------------------------------------------
+//
+EXPORT_C const RXmlEngDocument& CXmlSecSign::CreateTemplateL(TXmlSecKeyType aKeyFormat,
+ RArray<TXmlEngElement>& aNodes,
+ const TDesC8& aId,
+ TBool aX509Cert,
+ TUint aTransform,
+ const TDesC8& aPref,
+ TBool aNewLine)
+ {
+ _LIT8(KSep,":");
+ _LIT8(KPoint,"#");
+ if(iTemplate.NotNull())
+ {
+ iTemplate.Close();
+ }
+
+ if(!aNewLine)
+ {
+ xmlSetNewLineFlag(0);
+ }
+
+ unsigned char* pref = NULL;
+ if(aPref.Length())
+ {
+ pref = (unsigned char*) XmlEngXmlCharFromDes8L(aPref);
+ xmlSetPrefix(pref);
+ }
+ CleanupStack::PushL(TCleanupItem(Sign::TemplateCleanup,(TAny*)pref));
+
+ xmlNodePtr signNode = NULL;
+ xmlNodePtr refNode = NULL;
+ xmlNodePtr keyInfoNode = NULL;
+
+ if((aKeyFormat == ERSAPrivate) || (aKeyFormat == ERSAPublic))
+ {
+ // create signature template for RSA-SHA1 enveloped signature
+ signNode = xmlSecTmplSignatureCreate(NULL, xmlSecTransformExclC14NId,
+ xmlSecTransformRsaSha1Id, NULL);
+ }
+ else if(aKeyFormat == CXmlSecSign::EHMAC)
+ {
+ // create signature template for HMAC-SHA1 enveloped signature
+ signNode = xmlSecTmplSignatureCreate(NULL, xmlSecTransformExclC14NId,
+ xmlSecTransformHmacSha1Id, NULL);
+
+ }
+ if(!signNode)
+ {
+ XmlEngOOMTestL();
+ XmlSecErrorFlagTestL();
+ User::Leave(KErrTemplate);
+ }
+
+ CleanupStack::PushL(TCleanupItem(LibxmlNodeCleanup,(TAny*)signNode));
+
+ TInt nodeCount = aNodes.Count();
+ if(!nodeCount)
+ {
+ // add reference
+ refNode = xmlSecTmplSignatureAddReference(signNode, xmlSecTransformSha1Id,
+ NULL, NULL, NULL);
+ if(!refNode)
+ {
+ //xmlFreeNode( signNode );
+ XmlEngOOMTestL();
+ XmlSecErrorFlagTestL();
+ User::Leave(KErrTemplate);
+ }
+
+ if(KEnvelopedSignature & aTransform)
+ {
+ // add enveloped transform
+ if(!xmlSecTmplReferenceAddTransform(refNode, xmlSecTransformEnvelopedId))
+ {
+ //xmlFreeNode( signNode );
+ XmlEngOOMTestL();
+ XmlSecErrorFlagTestL();
+ User::Leave(KErrTemplate);
+ }
+ }
+ if(KC14N & aTransform)
+ {
+ // add enveloped transform
+ if(!xmlSecTmplReferenceAddTransform(refNode, xmlSecTransformInclC14NId))
+ {
+ //xmlFreeNode( signNode );
+ XmlEngOOMTestL();
+ XmlSecErrorFlagTestL();
+ User::Leave(KErrTemplate);
+ }
+ }
+ else if(KExclusiveC14N & aTransform)
+ {
+ // add enveloped transform
+ if(!xmlSecTmplReferenceAddTransform(refNode, xmlSecTransformExclC14NId))
+ {
+ //xmlFreeNode( signNode );
+ XmlEngOOMTestL();
+ XmlSecErrorFlagTestL();
+ User::Leave(KErrTemplate);
+ }
+ }
+ }
+ else
+ {
+ TPtrC8 nameSpace = KNullDesC8();
+ TPtrC8 uriVal = KNullDesC8();
+ TXmlEngString str;
+ TInt pos = aId.Find(KSep);
+ // check id of element
+ if(pos > 0)
+ {
+ nameSpace.Set(aNodes[0].LookupNamespaceUriL(aId.Left(pos)));
+ if(!nameSpace.Length())
+ {
+ //xmlFreeNode( signNode );
+ if (OOM_FLAG)
+ {
+ XmlEngLeaveOOML();
+ }
+ XmlSecErrorFlagTestL();
+ User::Leave(KErrIdUndefineNS);
+ }
+ }
+ // for all elements with id add reference
+ TXmlEngElement elem;
+ for(TInt i = 0; i < nodeCount; i++)
+ {
+ elem = aNodes[i];
+ uriVal.Set(elem.AttributeValueL(aId.Right(aId.Length() - (pos + 1)),nameSpace));
+ if(uriVal.Length())
+ {
+ str.SetL(KPoint);
+ CleanupClosePushL(str);
+ TXmlEngString str2;
+ str2.SetL(uriVal);
+ CleanupClosePushL(str2);
+ str.AppendL(str2);
+ CleanupStack::PopAndDestroy(&str2);
+ // add reference
+ refNode = xmlSecTmplSignatureAddReference(signNode, xmlSecTransformSha1Id,
+ NULL, (unsigned char*)str.Cstring(), NULL);
+ CleanupStack::PopAndDestroy(&str);
+ if(!refNode)
+ {
+ //xmlFreeNode( signNode );
+ XmlEngOOMTestL();
+ XmlSecErrorFlagTestL();
+ User::Leave(KErrTemplate);
+ }
+
+ if(KEnvelopedSignature & aTransform)
+ {
+ // add enveloped transform
+ if(!xmlSecTmplReferenceAddTransform(refNode, xmlSecTransformEnvelopedId))
+ {
+ //xmlFreeNode( signNode );
+ XmlEngOOMTestL();
+ XmlSecErrorFlagTestL();
+ User::Leave(KErrTemplate);
+ }
+ }
+ if(KC14N & aTransform)
+ {
+ // add enveloped transform
+ if(!xmlSecTmplReferenceAddTransform(refNode, xmlSecTransformInclC14NId))
+ {
+ //xmlFreeNode( signNode );
+ XmlEngOOMTestL();
+ XmlSecErrorFlagTestL();
+ User::Leave(KErrTemplate);
+ }
+ }
+ else if(KExclusiveC14N & aTransform)
+ {
+ // add enveloped transform
+ if(!xmlSecTmplReferenceAddTransform(refNode, xmlSecTransformExclC14NId))
+ {
+ //xmlFreeNode( signNode );
+ XmlEngOOMTestL();
+ XmlSecErrorFlagTestL();
+ User::Leave(KErrTemplate);
+ }
+ }
+ }
+ }
+ }
+
+ // add <dsig:KeyInfo/> and <dsig:X509Data/>
+ keyInfoNode = xmlSecTmplSignatureEnsureKeyInfo(signNode, NULL);
+ if(!keyInfoNode)
+ {
+ //xmlFreeNode( signNode );
+ XmlEngOOMTestL();
+ XmlSecErrorFlagTestL();
+ User::Leave(KErrTemplate);
+ }
+ if(aKeyFormat != CXmlSecSign::EHMAC && aX509Cert)
+ {
+ if(!xmlSecTmplKeyInfoAddX509Data(keyInfoNode))
+ {
+ //xmlFreeNode( signNode );
+ XmlEngOOMTestL();
+ XmlSecErrorFlagTestL();
+ User::Leave(KErrTemplate);
+ }
+ }
+
+ xmlDocPtr doc = xmlNewDoc(NULL);
+ xmlNodePtr tmpNode = xmlAddChild(INTERNAL_NODEPTR(doc), signNode);
+ if(!tmpNode)
+ {
+ xmlFreeDoc(doc);
+ //xmlFreeNode(signNode);
+ User::Leave(KErrNoMemory);
+ }
+ CleanupStack::Pop(signNode);
+ // return created template
+ RXmlEngDocument retDoc;
+ XmlSecGlobalState* gs = XmlSecGetTls();
+ retDoc.OpenL(*gs->iDOMImpl,doc);
+ iTemplate = retDoc;
+ CleanupStack::PopAndDestroy();
+ return iTemplate;
+ }
+
+// ---------------------------------------------------------------------------
+// Create template
+// ---------------------------------------------------------------------------
+//
+EXPORT_C const RXmlEngDocument& CXmlSecSign::CreateTemplateL(TXmlSecKeyType aKeyFormat,
+ TBool aX509Cert,
+ TUint aTransform,
+ const TDesC8& aPref,
+ TBool aNewLine)
+ {
+ RArray<TXmlEngElement> array;
+ CleanupClosePushL(array);
+ CreateTemplateL(aKeyFormat,array,KNullDesC8(),aX509Cert,aTransform,aPref,aNewLine);
+ CleanupStack::PopAndDestroy(&array);
+ return iTemplate;
+ }
+
+// ---------------------------------------------------------------------------
+// Return current encryption template
+// ---------------------------------------------------------------------------
+//
+EXPORT_C const RXmlEngDocument& CXmlSecSign::CurrentTemplate() const
+ {
+ return iTemplate;
+ }
+
+// ---------------------------------------------------------------------------
+// Destroy current encryption template
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CXmlSecSign::DestroyCurrentTemplate()
+ {
+ XmlSecTemplate::DestroyTemplate(iTemplate);
+ }
+
+// ---------------------------------------------------------------------------
+// Read key from buffer and puts it in SymbianKeyStore
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CXmlSecSign::SetKeyFromBufferL(const TDesC8& aBuffer,
+ const TDesC8& aKeyName,
+ TXmlSecKeyType aKeyFormat)
+ {
+ xmlSecDSigCtxPtr tmpCtx = SIG_CTX;
+ if(tmpCtx->signKey)
+ {
+ xmlSecKeyDestroy(tmpCtx->signKey);
+ tmpCtx->signKey = NULL;
+ }
+ tmpCtx->signKey = Sign::ReadKeyFromBufferL(aBuffer,aKeyName,aKeyFormat);
+ }
+
+// ---------------------------------------------------------------------------
+// Read key from file and puts it in SymbianKeyStore
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CXmlSecSign::SetKeyFromFileL(const TDesC8& aKeyFile,
+ const TDesC8& aKeyName,
+ TXmlSecKeyType aKeyFormat)
+ {
+ xmlSecDSigCtxPtr tmpCtx = SIG_CTX;
+ if(tmpCtx->signKey)
+ {
+ xmlSecKeyDestroy(tmpCtx->signKey);
+ tmpCtx->signKey = NULL;
+ }
+ tmpCtx->signKey = Sign::ReadKeyFromFileL(aKeyFile,aKeyName,aKeyFormat);
+ }
+
+// ---------------------------------------------------------------------------
+// Read certificate from file
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CXmlSecSign::SetCertFromFileL(const TDesC8& aCertFile)
+ {
+ xmlSecDSigCtxPtr tmpCtx = SIG_CTX;
+
+ if(!tmpCtx->signKey)
+ {
+ User::Leave(KErrKey);
+ }
+ const TInt length = aCertFile.Length();
+ char* cStringFileName = new char[ length+1 ];
+ if (!cStringFileName)
+ {
+ User::Leave( KErrNoMemory );
+ }
+ // copy cert data
+ memcpy(cStringFileName, (char*) aCertFile.Ptr(), length);
+ cStringFileName[ length ] = NULL;
+ // read cert data, add cert to key
+ if(xmlSecCryptoAppKeyCertLoad(tmpCtx->signKey, cStringFileName, xmlSecKeyDataFormatDer) < 0)
+ {
+ delete[] cStringFileName;
+ XmlEngOOMTestL();
+ XmlSecErrorFlagTestL();
+ User::Leave(KErrCert);
+ }
+ delete[] cStringFileName;
+ }
+
+// ---------------------------------------------------------------------------
+// Read certificate from buffer
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CXmlSecSign::SetCertFromBufferL(const TDesC8& aCert)
+ {
+ xmlSecDSigCtxPtr tmpCtx = SIG_CTX;
+
+ if(!tmpCtx->signKey)
+ {
+ User::Leave(KErrKey);
+ }
+ // add cert data to key
+ if(xmlSecSymbianCryptoAppKeyCertLoadMemory(tmpCtx->signKey,aCert.Ptr(),aCert.Size(),
+ xmlSecKeyDataFormatDer) < 0)
+ {
+ User::Leave(KErrCert);
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Add cert from file to root's cert chain
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CXmlSecSign::AddTrustedCertFromFileL(const TDesC8& aCertFile)
+ {
+ if(!iMngr)
+ {
+ iMngr = CXmlSecKeyManager::GetInstanceL();
+ }
+ const TInt length = aCertFile.Length();
+ char* cStringFileName = new char[ length+1 ];
+ if (!cStringFileName)
+ {
+ User::Leave( KErrNoMemory );
+ }
+ memcpy(cStringFileName, (char*) aCertFile.Ptr(), length);
+ cStringFileName[ length ] = NULL;
+ // load cert data
+ if(xmlSecCryptoAppKeysMngrCertLoad(iMngr->GetKeyManagerPtr(), cStringFileName,
+ xmlSecKeyDataFormatDer, xmlSecKeyDataTypeTrusted) < 0)
+ {
+ delete[] cStringFileName;
+ XmlEngOOMTestL();
+ XmlSecErrorFlagTestL();
+ User::Leave(KErrCert);
+ }
+ delete[] cStringFileName;
+ }
+
+// ---------------------------------------------------------------------------
+// Add cert from buffer to root's cert chain
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CXmlSecSign::AddTrustedCertFromBufferL(const TDesC8& aCert)
+ {
+ if(!iMngr)
+ {
+ iMngr = CXmlSecKeyManager::GetInstanceL();
+ }
+ if(xmlSecCryptoAppKeysMngrCertLoadMemory(iMngr->GetKeyManagerPtr(), aCert.Ptr(),
+ aCert.Size(), xmlSecKeyDataFormatDer, xmlSecKeyDataTypeTrusted) < 0)
+ {
+ XmlEngOOMTestL();
+ XmlSecErrorFlagTestL();
+ User::Leave(KErrCert);
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Constructor
+// ---------------------------------------------------------------------------
+//
+CXmlSecSign::CXmlSecSign()
+ {
+ iTemplate = RXmlEngDocument();
+ iSigCtx = NULL;
+ iSkipTmplLookUp = EFalse; //Initialize the flag to FALSE
+ }
+
+// ---------------------------------------------------------------------------
+// Second phase constructor
+// ---------------------------------------------------------------------------
+//
+void CXmlSecSign::ConstructL()
+ {
+ // create sign context
+ iSigCtx = xmlSecDSigCtxCreate(NULL);
+ if(!iSigCtx)
+ {
+ User::Leave(KErrNoMemory);
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Destructor
+// ---------------------------------------------------------------------------
+//
+CXmlSecSign::~CXmlSecSign()
+ {
+ if(iTemplate.NotNull())
+ {
+ iTemplate.Close();
+ }
+ if(iSigCtx)
+ {
+ xmlSecDSigCtxDestroy(SIG_CTX);
+ }
+ }
+