xmlsecurityengine/xmlsecwrapper/src/xmlsecwencrypt.cpp
changeset 0 e35f40988205
child 24 74f0b3eb154c
--- /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 <e32std.h>
+
+// XML Engine
+#include <libxml2_tree.h>
+#include <libxml2_xmlmemory.h>
+#include <libxml2_globals.h>
+
+#include <xmlengmem.h>
+#include <xmlengxestd.h>
+#include <xmlengutils.h>
+
+#include <xmlengdom.h>
+
+// 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 <enc:CipherValue/> node
+    if(!xmlSecTmplEncDataEnsureCipherValue(node)) 
+        {
+        xmlFreeNode( node );
+        XmlEngOOMTestL();
+        XmlSecErrorFlagTestL();
+        User::Leave(KErrTemplate);
+	    }
+
+    // add <dsig:KeyInfo/> and <dsig:KeyName/> 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);
+        }
+    }