[webmasters] Re: [xmlsec] Big patch to xmlsec in recent OpenOffice.org sources

Chandler Peng Chuandong.Peng at sun.com
Sat Feb 5 22:43:11 PST 2005


Aleksey Sanin wrote:

> Thanks, Chandler and Andrew!
>
> I'l review these files during next week. But will you mind to re-send
> them to xmlsec at aleksey.com mailing list, please? There are more folks
> who can help me with review.
>
OK , no problem :-)

> Thanks!
> Aleksey
>
> Chandler Peng wrote:
>
>> Andrew ,
>> I have created a new diff file with "diff -uN" on xmlsec_1.2.6. This 
>> diff file only include the difference on the source and the related 
>> makefile . Our new source file need add to xmlsec is in the xmlsec.zip .
>>
>> Chandler Peng..
>>
>>
>> Andrew Fan wrote:
>>
>>> Hi Aleksey,
>>>
>>> I have to say sorry to you and all of others about the mail thread. 
>>> The e-mailed are filtered into aother folder in my email, and I have 
>>> not read it for a very long time. So sorry.
>>>
>>> But I never forgot to contribute the patches back into the main 
>>> track from the very beginning. And now, it seems that I have got the 
>>> permission from my bosses. :-)  Michael Mi and Chandler Peng will 
>>> work on the integration, I will help them during the integrating 
>>> process.
>>>
>>> About the patch, why is it so big? what had happened at the patch? I 
>>> try to illustrate it in some very simple words.
>>> 1. I only made some changes over nss and ms crypto enginers;
>>> 2. For ms crypto enginer, I did some changes over keystore mainly, 
>>> the patch is quite smalll;
>>> 3. For nss enginer, the patch shows a big difference about how to 
>>> find keys and personal certificates from key store and certificate 
>>> store.
>>>
>>> Detailed infomation, I'll try to explain during the integration.
>>>
>>> Thanks & Regards,
>>> Andrew Fan
>>>
>>> Chandler, would you please create a new diff according with "diff 
>>> -uN". Thanks.
>>>
>>> Aleksey Sanin wrote:
>>>
>>>> Andrew,
>>>>
>>>> I would appreciate if you can generate a new "diff -uN" patch against
>>>> the current xmlsec CVS trunk because it is pretty hard to read the
>>>> patch at
>>>>
>>>> http://external.openoffice.org/source/browse/external/libxmlsec/xmlsec1-1.2.4.patch 
>>>>
>>>>
>>>> Plus I have some problems applying the current patch (mainly with new
>>>> files you've added).
>>>>
>>>> Also it is a pretty big patch and I would really appreciate if you
>>>> can write up some comments about it (something like "the change on
>>>> lines AAA-BBB, file CCC, lines DDD-EEE, file FFF, ... fixes bug
>>>> ZZZ" will do).
>>>>
>>>> Thanks,
>>>> Aleksey
>>>>
>>>> Malte Timmermann wrote:
>>>>
>>>>> Andrew,
>>>>>
>>>>> can you please work with Aleksey to get all your changes into xmlsec?
>>>>>
>>>>> Would be great if we could get rid of our patch :)
>>>>>
>>>>> Malte.
>>>>>
>>>
>>

-------------- next part --------------
cvs diff -uN (in directory D:\My_work\SRC680\o_libxmlsec)
? xmlsec/include/xmlsec/mscrypto/akmngr.h
? xmlsec/include/xmlsec/nss/akmngr.h
? xmlsec/include/xmlsec/nss/ciphers.h
? xmlsec/include/xmlsec/nss/tokens.h
? xmlsec/src/mscrypto/akmngr.c
? xmlsec/src/nss/akmngr.c
? xmlsec/src/nss/keytrans.c
? xmlsec/src/nss/keywrapers.c
? xmlsec/src/nss/tokens.c
cvs server: Diffing xmlsec
cvs server: Diffing xmlsec/apps
cvs server: Diffing xmlsec/docs
cvs server: Diffing xmlsec/docs/api
cvs server: Diffing xmlsec/docs/api/chapters
cvs server: Diffing xmlsec/docs/api/images
cvs server: Diffing xmlsec/docs/api/sgml
cvs server: Diffing xmlsec/docs/api/sgml/gnutls
cvs server: Diffing xmlsec/docs/api/sgml/mscrypto
cvs server: Diffing xmlsec/docs/api/sgml/nss
cvs server: Diffing xmlsec/docs/api/sgml/openssl
cvs server: Diffing xmlsec/docs/api/tmpl
cvs server: Diffing xmlsec/docs/api/tmpl/gnutls
cvs server: Diffing xmlsec/docs/api/tmpl/mscrypto
cvs server: Diffing xmlsec/docs/api/tmpl/nss
cvs server: Diffing xmlsec/docs/api/tmpl/openssl
cvs server: Diffing xmlsec/docs/api-0.0.x
cvs server: Diffing xmlsec/docs/api-0.0.x/examples
cvs server: Diffing xmlsec/docs/api-0.0.x/examples/dsig1
cvs server: Diffing xmlsec/docs/api-0.0.x/examples/dsig2
cvs server: Diffing xmlsec/docs/api-0.0.x/examples/dsig3
cvs server: Diffing xmlsec/docs/api-0.0.x/examples/dsig4
cvs server: Diffing xmlsec/docs/api-0.0.x/examples/dsig5
cvs server: Diffing xmlsec/docs/api-0.0.x/examples/enc1
cvs server: Diffing xmlsec/docs/api-0.0.x/examples/enc2
cvs server: Diffing xmlsec/docs/api-0.0.x/sgml
cvs server: Diffing xmlsec/docs/api-0.0.x/tmpl
cvs server: Diffing xmlsec/docs/extra
cvs server: Diffing xmlsec/docs/images
cvs server: Diffing xmlsec/docs/tests
cvs server: Diffing xmlsec/docs/tests/aleksey-xmldsig-01
cvs server: Diffing xmlsec/docs/tests/keys-certs
cvs server: Diffing xmlsec/docs/tests/merlin-exc-c14n-one
cvs server: Diffing xmlsec/docs/tests/merlin-xmldsig-twenty-three
cvs server: Diffing xmlsec/docs/tests/merlin-xmldsig-twenty-three/certs
cvs server: Diffing xmlsec/docs/tests/merlin-xmlenc-five
cvs server: Diffing xmlsec/examples
cvs server: Diffing xmlsec/include
cvs server: Diffing xmlsec/include/xmlsec
cvs server: Diffing xmlsec/include/xmlsec/gnutls
cvs server: Diffing xmlsec/include/xmlsec/mscrypto
Index: xmlsec/include/xmlsec/mscrypto/x509.h
===================================================================
RCS file: /cvs/gnome/xmlsec/include/xmlsec/mscrypto/x509.h,v
retrieving revision 1.3
diff -u -r1.3 x509.h
--- xmlsec/include/xmlsec/mscrypto/x509.h	26 Sep 2003 06:12:46 -0000	1.3
+++ xmlsec/include/xmlsec/mscrypto/x509.h	6 Feb 2005 03:53:15 -0000
@@ -77,6 +77,21 @@
 										 PCCERT_CONTEXT cert,
 										 xmlSecKeyDataType type);
 
+XMLSEC_CRYPTO_EXPORT int		xmlSecMSCryptoX509StoreAdoptKeyStore (
+										xmlSecKeyDataStorePtr store,
+										HCERTSTORE keyStore
+								) ;
+
+XMLSEC_CRYPTO_EXPORT int		xmlSecMSCryptoX509StoreAdoptTrustedStore (
+										xmlSecKeyDataStorePtr store,
+										HCERTSTORE trustedStore
+								) ;
+
+XMLSEC_CRYPTO_EXPORT int		xmlSecMSCryptoX509StoreAdoptUntrustedStore (
+										xmlSecKeyDataStorePtr store,
+										HCERTSTORE untrustedStore
+								) ;
+
 
 #endif /* XMLSEC_NO_X509 */
 
cvs server: Diffing xmlsec/include/xmlsec/nss
Index: xmlsec/include/xmlsec/nss/Makefile.am
===================================================================
RCS file: /cvs/gnome/xmlsec/include/xmlsec/nss/Makefile.am,v
retrieving revision 1.5
diff -u -r1.5 Makefile.am
--- xmlsec/include/xmlsec/nss/Makefile.am	30 Jul 2003 02:46:35 -0000	1.5
+++ xmlsec/include/xmlsec/nss/Makefile.am	6 Feb 2005 03:53:16 -0000
@@ -3,6 +3,7 @@
 xmlsecnssincdir = $(includedir)/xmlsec1/xmlsec/nss
 
 xmlsecnssinc_HEADERS = \
+akmngr.h \
 app.h \
 crypto.h \
 symbols.h \
@@ -10,6 +11,8 @@
 keysstore.h \
 pkikeys.h \
 x509.h \
+tokens.h \
+ciphers.h \
 $(NULL)
 
 install-exec-hook:
Index: xmlsec/include/xmlsec/nss/app.h
===================================================================
RCS file: /cvs/gnome/xmlsec/include/xmlsec/nss/app.h,v
retrieving revision 1.16
diff -u -r1.16 app.h
--- xmlsec/include/xmlsec/nss/app.h	12 Jan 2004 21:06:14 -0000	1.16
+++ xmlsec/include/xmlsec/nss/app.h	6 Feb 2005 03:53:16 -0000
@@ -22,6 +22,9 @@
 #include <xmlsec/keysmngr.h>
 #include <xmlsec/transforms.h>
 
+#include <xmlsec/nss/tokens.h>
+#include <xmlsec/nss/akmngr.h>
+
 /**
  * Init/shutdown
  */
@@ -34,6 +37,8 @@
 XMLSEC_CRYPTO_EXPORT int		xmlSecNssAppDefaultKeysMngrInit	(xmlSecKeysMngrPtr mngr);
 XMLSEC_CRYPTO_EXPORT int 		xmlSecNssAppDefaultKeysMngrAdoptKey(xmlSecKeysMngrPtr mngr,
 									    xmlSecKeyPtr key);
+XMLSEC_CRYPTO_EXPORT int 		xmlSecNssAppDefaultKeysMngrAdoptKeySlot(xmlSecKeysMngrPtr mngr,
+									    xmlSecNssKeySlotPtr keySlot);
 XMLSEC_CRYPTO_EXPORT int 		xmlSecNssAppDefaultKeysMngrLoad	(xmlSecKeysMngrPtr mngr,
 									 const char* uri);
 XMLSEC_CRYPTO_EXPORT int 		xmlSecNssAppDefaultKeysMngrSave	(xmlSecKeysMngrPtr mngr,
Index: xmlsec/include/xmlsec/nss/crypto.h
===================================================================
RCS file: /cvs/gnome/xmlsec/include/xmlsec/nss/crypto.h,v
retrieving revision 1.19
diff -u -r1.19 crypto.h
--- xmlsec/include/xmlsec/nss/crypto.h	12 Jan 2004 21:06:14 -0000	1.19
+++ xmlsec/include/xmlsec/nss/crypto.h	6 Feb 2005 03:53:16 -0000
@@ -264,6 +264,15 @@
         xmlSecNssTransformRsaPkcs1GetKlass()
 XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecNssTransformRsaPkcs1GetKlass(void);
 
+/**
+ * xmlSecNssTransformRsaOaepId:
+ * 
+ * The RSA OAEP key transport transform klass.
+ */
+#define xmlSecNssTransformRsaOaepId \
+        xmlSecNssTransformRsaOaepGetKlass()
+XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecNssTransformRsaOaepGetKlass(void);
+
 #endif /* XMLSEC_NO_RSA */
 
 
Index: xmlsec/include/xmlsec/nss/keysstore.h
===================================================================
RCS file: /cvs/gnome/xmlsec/include/xmlsec/nss/keysstore.h,v
retrieving revision 1.2
diff -u -r1.2 keysstore.h
--- xmlsec/include/xmlsec/nss/keysstore.h	30 Jul 2003 02:46:35 -0000	1.2
+++ xmlsec/include/xmlsec/nss/keysstore.h	6 Feb 2005 03:53:16 -0000
@@ -16,6 +16,8 @@
 #endif /* __cplusplus */ 
 
 #include <xmlsec/xmlsec.h>
+#include <xmlsec/keysmngr.h>
+#include <xmlsec/nss/tokens.h>
 
 /****************************************************************************
  *
@@ -31,6 +33,8 @@
 XMLSEC_CRYPTO_EXPORT xmlSecKeyStoreId	xmlSecNssKeysStoreGetKlass	(void);
 XMLSEC_CRYPTO_EXPORT int		xmlSecNssKeysStoreAdoptKey	(xmlSecKeyStorePtr store,
 									 xmlSecKeyPtr key);
+XMLSEC_CRYPTO_EXPORT int		xmlSecNssKeysStoreAdoptKeySlot(xmlSecKeyStorePtr store,
+									 xmlSecNssKeySlotPtr keySlot);
 XMLSEC_CRYPTO_EXPORT int		xmlSecNssKeysStoreLoad 	(xmlSecKeyStorePtr store,
 								 const char *uri,
 								 xmlSecKeysMngrPtr keysMngr);
cvs server: Diffing xmlsec/include/xmlsec/openssl
cvs server: Diffing xmlsec/include/xmlsec/private
cvs server: Diffing xmlsec/include/xmlsec/skeleton
cvs server: Diffing xmlsec/man
cvs server: Diffing xmlsec/scripts
cvs server: Diffing xmlsec/src
Index: xmlsec/src/bn.c
===================================================================
RCS file: /cvs/gnome/xmlsec/src/bn.c,v
retrieving revision 1.12
diff -u -r1.12 bn.c
--- xmlsec/src/bn.c	21 Jun 2004 18:33:27 -0000	1.12
+++ xmlsec/src/bn.c	6 Feb 2005 03:53:16 -0000
@@ -175,6 +175,11 @@
     int nn;
     int ret;
 
+	/*
+	 * mmi : added for adding prefix 00
+	 */
+	xmlSecByte* data;
+
     xmlSecAssert2(bn != NULL, -1);
     xmlSecAssert2(str != NULL, -1);
     xmlSecAssert2(base > 1, -1);
@@ -192,7 +197,10 @@
      * because each byte is represented by 2 chars. If needed, 
      * buffer size would be increased by Mul/Add functions.
      */
-    ret = xmlSecBufferSetMaxSize(bn, xmlSecBufferGetSize(bn) + len / 2 + 1);
+	/*
+	 * mmi:add one byte to hold the 00 prefix
+	 */
+    ret = xmlSecBufferSetMaxSize(bn, xmlSecBufferGetSize(bn) + len / 2 + 2);
     if(ret < 0) {
 	xmlSecError(XMLSEC_ERRORS_HERE,
 		    NULL,
@@ -239,6 +247,25 @@
 			"base=%d", base);
 	    return (-1);
 	}	
+
+    }
+
+	/*
+	 * mmi : check whether need to add 00 prefix
+	 */
+	data = xmlSecBufferGetData(bn);
+	if (data[0]>127)
+	{
+	    ch = 0;
+        ret = xmlSecBufferPrepend(bn, &ch, 1);
+		if(ret < 0) {
+            xmlSecError(XMLSEC_ERRORS_HERE,
+				NULL,
+				"xmlSecBufferPrepend",
+				XMLSEC_ERRORS_R_XMLSEC_FAILED,
+				"base=%d", base);
+			return (-1);
+		}
     }
 
     return(0);
Index: xmlsec/src/dl.c
===================================================================
RCS file: /cvs/gnome/xmlsec/src/dl.c,v
retrieving revision 1.9
diff -u -r1.9 dl.c
--- xmlsec/src/dl.c	29 Oct 2003 15:57:20 -0000	1.9
+++ xmlsec/src/dl.c	6 Feb 2005 03:53:17 -0000
@@ -329,6 +329,10 @@
 xmlSecCryptoDLInit(void) {
     int ret;
     
+    /* use xmlMalloc/xmlFree */
+    xmlsec_lt_dlmalloc	= xmlSecCryptoDLMalloc;
+    xmlsec_lt_dlfree	= xmlSecCryptoDLFree;
+
     ret = xmlSecPtrListInitialize(&gXmlSecCryptoDLLibraries, xmlSecCryptoDLLibrariesListGetKlass());
     if(ret < 0) {
 	xmlSecError(XMLSEC_ERRORS_HERE,
@@ -350,9 +354,6 @@
     }
     /* TODO: LTDL_SET_PRELOADED_SYMBOLS(); */
     
-    /* use xmlMalloc/xmlFree */
-    xmlsec_lt_dlmalloc	= xmlSecCryptoDLMalloc;
-    xmlsec_lt_dlfree	= xmlSecCryptoDLFree;
     return(0);
 }
 
cvs server: Diffing xmlsec/src/gnutls
cvs server: Diffing xmlsec/src/mscrypto
Index: xmlsec/src/mscrypto/certkeys.c
===================================================================
RCS file: /cvs/gnome/xmlsec/src/mscrypto/certkeys.c,v
retrieving revision 1.5
diff -u -r1.5 certkeys.c
--- xmlsec/src/mscrypto/certkeys.c	17 Mar 2004 05:06:43 -0000	1.5
+++ xmlsec/src/mscrypto/certkeys.c	6 Feb 2005 03:53:18 -0000
@@ -41,6 +41,7 @@
  * a public key from xml document is provided, we need HCRYPTKEY.... The focus
  * now is however directed to certificates.  Wouter
  */
+/** replaced by a wrapper style for WINNT 4.0
 struct _xmlSecMSCryptoKeyDataCtx {
     HCRYPTPROV		hProv;
     BOOL		fCallerFreeProv;
@@ -51,6 +52,124 @@
     HCRYPTKEY		hKey;
     xmlSecKeyDataType	type;
 };	    
+*/
+/*-
+ * A wrapper of HCRYPTKEY, a reference countor is introduced, the function is
+ * the same as CryptDuplicateKey. Because the CryptDuplicateKey is not support
+ * by WINNT 4.0, the wrapper will enable the library work on WINNT 4.0
+ */
+struct _mscrypt_key {
+	HCRYPTKEY hKey ;
+	int	refcnt ;
+} ;
+
+/*-
+ * A wrapper of HCRYPTPROV, a reference countor is introduced, the function is
+ * the same as CryptContextAddRef. Because the CryptContextAddRef is not support
+ * by WINNT 4.0, the wrapper will enable the library work on WINNT 4.0
+ */
+struct _mscrypt_prov {
+	HCRYPTPROV hProv ;
+    BOOL freeprov ;
+	int	refcnt ;
+} ;
+
+struct _xmlSecMSCryptoKeyDataCtx {
+	struct _mscrypt_prov*	p_prov ;
+    LPCTSTR		providerName;
+    DWORD		providerType;
+    PCCERT_CONTEXT	pCert;
+    DWORD		dwKeySpec;
+	struct _mscrypt_key* p_key ;
+    xmlSecKeyDataType	type;
+};	    
+
+struct _mscrypt_key* mscrypt_create_key( HCRYPTKEY key ) {
+	struct _mscrypt_key* pkey ;
+
+	pkey = ( struct _mscrypt_key* )xmlMalloc( sizeof( struct _mscrypt_key ) ) ;
+	if( pkey == NULL ) {
+		xmlSecError( XMLSEC_ERRORS_HERE,
+			"mscrypt_create_key" ,
+			NULL ,
+			XMLSEC_ERRORS_R_MALLOC_FAILED ,
+			XMLSEC_ERRORS_NO_MESSAGE
+		) ;
+	}
+
+	pkey->hKey = key ;
+	pkey->refcnt = 1 ;
+
+	return pkey ;
+}
+
+struct _mscrypt_key* mscrypt_acquire_key( struct _mscrypt_key* key ) {
+	if( key )
+		key->refcnt ++ ;
+
+	return key ;
+}
+
+int mscrypt_release_key( struct _mscrypt_key* key ) {
+	if( key ) {
+		key->refcnt -- ;
+		if( !key->refcnt ) {
+			if( key->hKey ) {
+				CryptDestroyKey( key->hKey ) ;
+				key->hKey = 0 ;
+			}
+			xmlFree( key ) ;
+		} else {
+			return key->refcnt ;
+		}
+	}
+
+	return 0 ;
+}
+
+struct _mscrypt_prov* mscrypt_create_prov( HCRYPTPROV prov, BOOL callerFree ) {
+	struct _mscrypt_prov* pprov ;
+
+	pprov = ( struct _mscrypt_prov* )xmlMalloc( sizeof( struct _mscrypt_prov ) ) ;
+	if( pprov == NULL ) {
+		xmlSecError( XMLSEC_ERRORS_HERE,
+			"mscrypt_create_prov" ,
+			NULL ,
+			XMLSEC_ERRORS_R_MALLOC_FAILED ,
+			XMLSEC_ERRORS_NO_MESSAGE
+		) ;
+	}
+
+	pprov->hProv = prov ;
+	pprov->freeprov = callerFree ;
+	pprov->refcnt = 1 ;
+
+	return pprov ;
+}
+
+struct _mscrypt_prov* mscrypt_acquire_prov( struct _mscrypt_prov* prov ) {
+	if( prov )
+		prov->refcnt ++ ;
+
+	return prov ;
+}
+
+int mscrypt_release_prov( struct _mscrypt_prov* prov ) {
+	if( prov ) {
+		prov->refcnt -- ;
+		if( !prov->refcnt ) {
+			if( prov->hProv && prov->freeprov ) {
+				CryptReleaseContext( prov->hProv, 0 ) ;
+				prov->hProv = 0 ;
+			}
+			xmlFree( prov ) ;
+		} else {
+			return prov->refcnt ;
+		}
+	}
+
+	return 0 ;
+}
 
 /******************************************************************************
  *
@@ -88,24 +207,20 @@
     ctx = xmlSecMSCryptoKeyDataGetCtx(data);
     xmlSecAssert2(ctx != NULL, -1);
 
-    if (ctx->hKey != 0) {
-	CryptDestroyKey(ctx->hKey);
-	ctx->hKey = 0;
-    }
+	if( ctx->p_key != 0 ) {
+		mscrypt_release_key( ctx->p_key ) ;
+	}
+	ctx->p_key = mscrypt_create_key( 0 ) ;
 
     if(ctx->pCert != NULL) {
 	CertFreeCertificateContext(ctx->pCert);
 	ctx->pCert = NULL;
     }
 
-    if ((ctx->hProv != 0) && (ctx->fCallerFreeProv)) {
-	CryptReleaseContext(ctx->hProv, 0);
-	ctx->hProv = 0;
-	ctx->fCallerFreeProv = FALSE;
-    } else {
-	ctx->hProv = 0;
-	ctx->fCallerFreeProv = FALSE;
-    }
+	if( ( ctx->p_prov ) ) {
+		mscrypt_release_prov( ctx->p_prov ) ;
+	}
+	ctx->p_prov = mscrypt_create_prov( 0, FALSE ) ;
 
     ctx->type = type;
 
@@ -116,9 +231,9 @@
         if (!CryptAcquireCertificatePrivateKey(pCert, 
 					       CRYPT_ACQUIRE_USE_PROV_INFO_FLAG, 
 					       NULL, 
-					       &(ctx->hProv), 
+					       &(ctx->p_prov->hProv), 
 					       &(ctx->dwKeySpec), 
-					       &(ctx->fCallerFreeProv))) {
+					       &(ctx->p_prov->freeprov))) {
 	    xmlSecError(XMLSEC_ERRORS_HERE,
 			NULL,
 			"CryptAcquireCertificatePrivateKey",
@@ -127,9 +242,9 @@
 	    return(-1);
 	}
     } else if((type & xmlSecKeyDataTypePublic) != 0){
-	if (!CryptAcquireContext(&(ctx->hProv), 
+		if (!CryptAcquireContext(&(ctx->p_prov->hProv), 
 				 NULL, 
-				 ctx->providerName, 
+				 NULL, 	/*AF: replaces "ctx->providerName" with "NULL" */
 				 ctx->providerType, 
 				 CRYPT_VERIFYCONTEXT)) {
 	    xmlSecError(XMLSEC_ERRORS_HERE,
@@ -140,7 +255,19 @@
 	    return(-1);
 	}
 	ctx->dwKeySpec = 0;
-	ctx->fCallerFreeProv = TRUE;
+		ctx->p_prov->freeprov = TRUE;
+
+		if( !CryptImportPublicKeyInfo( ctx->p_prov->hProv, 
+				X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 
+				&(pCert->pCertInfo->SubjectPublicKeyInfo), 
+				&(ctx->p_key->hKey) ) ) {
+		    xmlSecError(XMLSEC_ERRORS_HERE,
+				NULL,
+				"CryptImportPublicKeyInfo",
+				XMLSEC_ERRORS_R_CRYPTO_FAILED,
+				XMLSEC_ERRORS_NO_MESSAGE);
+		    return(-1);
+		}
     } else {
 	xmlSecError(XMLSEC_ERRORS_HERE,
 		    NULL,
@@ -149,25 +276,6 @@
 		    "Unsupported keytype");
 	return(-1);
     }
-
-    /* CryptImportPublicKeyInfo is only needed when a real key handle
-     * is needed. The key handle is needed for de/encrypting and for
-     * verifying of a signature, *not* for signing. We could call
-     * CryptImportPublicKeyInfo in xmlSecMSCryptoKeyDataGetKey instead
-     * so no unnessecary calls to CryptImportPublicKeyInfo are being
-     * made. WK
-     */
-    if(!CryptImportPublicKeyInfo(ctx->hProv, 
-	X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 
-	&(pCert->pCertInfo->SubjectPublicKeyInfo), 
-	&(ctx->hKey))) {
-	    xmlSecError(XMLSEC_ERRORS_HERE,
-			NULL,
-			"CryptImportPublicKeyInfo",
-			XMLSEC_ERRORS_R_CRYPTO_FAILED,
-			XMLSEC_ERRORS_NO_MESSAGE);
-	    return(-1);
-    }
     ctx->pCert = pCert;
 
     return(0);
@@ -190,29 +298,26 @@
     ctx = xmlSecMSCryptoKeyDataGetCtx(data);
     xmlSecAssert2(ctx != NULL, -1);
 
-    if(ctx->hKey != 0) {
-	CryptDestroyKey(ctx->hKey);
-	ctx->hKey = 0;
-    }
+	if( ctx->p_key != 0 ) {
+		mscrypt_release_key( ctx->p_key ) ;
+		ctx->p_key = NULL ;
+	}
 
     if(ctx->pCert != NULL) {
 	CertFreeCertificateContext(ctx->pCert);
 	ctx->pCert = NULL;
     }
     
-    if((ctx->hProv != 0) && ctx->fCallerFreeProv) {
-	CryptReleaseContext(ctx->hProv, 0);
-	ctx->hProv = 0;
-	ctx->fCallerFreeProv = FALSE;
-    } else {
-	ctx->hProv = 0;
-	ctx->fCallerFreeProv = FALSE;
-    }
+	if( ( ctx->p_prov ) ) {
+		mscrypt_release_prov( ctx->p_prov ) ;
+		ctx->p_prov = NULL ;
+	} else {
+		ctx->p_prov = NULL ;
+	}
 
-    ctx->hProv		 = hProv;
-    ctx->fCallerFreeProv = fCallerFreeProv;
+    ctx->p_prov		 = mscrypt_create_prov( hProv, FALSE ) ;
     ctx->dwKeySpec	 = dwKeySpec;
-    ctx->hKey		 = hKey;
+    ctx->p_key		 = mscrypt_create_key( hKey ) ;
     ctx->type		 = type;
 
     return(0);
@@ -238,7 +343,7 @@
     ctx = xmlSecMSCryptoKeyDataGetCtx(data);
     xmlSecAssert2(ctx != NULL, 0);
  
-    return(ctx->hKey);
+    return( ctx->p_key ? ctx->p_key->hKey : 0 );
 }
 
 /**
@@ -273,7 +378,7 @@
     ctx = xmlSecMSCryptoKeyDataGetCtx(data);
     xmlSecAssert2(ctx != NULL, 0);
 
-    return(ctx->hProv);
+    return( ctx->p_prov ? ctx->p_prov->hProv : 0 );
 }
 
 DWORD
@@ -318,23 +423,34 @@
 	}
     } 
 
-    if (ctxSrc->hKey != 0) {
-	if (!CryptDuplicateKey(ctxSrc->hKey, NULL, 0, &(ctxDst->hKey))) {
+    if( ctxSrc->p_key ) {
+		if( ctxDst->p_key )
+			mscrypt_release_key( ctxDst->p_key ) ;
+
+		ctxDst->p_key = mscrypt_acquire_key( ctxSrc->p_key ) ;
+		if( !ctxDst->p_key ) {
 	    xmlSecError(XMLSEC_ERRORS_HERE,
 			xmlSecErrorsSafeString(xmlSecKeyDataGetName(dst)),
-			"CryptDuplicateKey",
+				"mscrypt_acquire_key",
 			XMLSEC_ERRORS_R_CRYPTO_FAILED,
 			XMLSEC_ERRORS_NO_MESSAGE);
 	    return(-1);
 	}
     }
-    if(ctxSrc->hProv != 0) {
-	CryptContextAddRef(ctxSrc->hProv, NULL, 0);
-	ctxDst->hProv		= ctxSrc->hProv;
-	ctxDst->fCallerFreeProv = TRUE;
-    } else {
-        ctxDst->hProv		= 0;
-	ctxDst->fCallerFreeProv = FALSE;
+
+    if( ctxSrc->p_prov ) {
+		if( ctxDst->p_prov )
+			mscrypt_release_prov( ctxDst->p_prov ) ;
+
+		ctxDst->p_prov = mscrypt_acquire_prov( ctxSrc->p_prov ) ;
+		if( !ctxDst->p_prov ) {
+		    xmlSecError(XMLSEC_ERRORS_HERE,
+				xmlSecErrorsSafeString(xmlSecKeyDataGetName(dst)),
+				"mscrypt_acquire_prov",
+				XMLSEC_ERRORS_R_CRYPTO_FAILED,
+				XMLSEC_ERRORS_NO_MESSAGE);
+		    return(-1);
+		}
     }
     
     ctxDst->dwKeySpec	    = ctxSrc->dwKeySpec;
@@ -355,16 +471,16 @@
     ctx = xmlSecMSCryptoKeyDataGetCtx(data);
     xmlSecAssert(ctx != NULL);
     
-    if (ctx->hKey != 0) {
-	CryptDestroyKey(ctx->hKey);
+    if( ctx->p_key ) {
+		mscrypt_release_key( ctx->p_key ) ;
     }
 
     if(ctx->pCert != NULL) {
 	CertFreeCertificateContext(ctx->pCert);
     }
 
-    if ((ctx->hProv != 0) && ctx->fCallerFreeProv) {
-	CryptReleaseContext(ctx->hProv, 0);
+    if( ctx->p_prov ) {
+		mscrypt_release_prov( ctx->p_prov ) ;
     }
 
     memset(ctx, 0, sizeof(xmlSecMSCryptoKeyDataCtx));
@@ -384,14 +500,14 @@
         xmlSecAssert2(ctx->pCert->pCertInfo != NULL, 0);
 	return (CertGetPublicKeyLength(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 
 		&(ctx->pCert->pCertInfo->SubjectPublicKeyInfo)));
-    } else if (ctx->hKey != 0) {
+    } else if (ctx->p_key != 0 && ctx->p_key->hKey != 0 ) {
         DWORD length = 0;
 	DWORD lenlen = sizeof(DWORD);
 	
-	if (!CryptGetKeyParam(ctx->hKey, KP_KEYLEN, (BYTE *)&length, &lenlen, 0)) {
+	if (!CryptGetKeyParam(ctx->p_key->hKey, KP_KEYLEN, (BYTE *)&length, &lenlen, 0)) {
 	    xmlSecError(XMLSEC_ERRORS_HERE,
 			NULL,
-			"CertDuplicateCertificateContext",
+			"CryptGetKeyParam",
 			XMLSEC_ERRORS_R_CRYPTO_FAILED,
 			XMLSEC_ERRORS_NO_MESSAGE);
 	    return(0);
@@ -938,9 +1054,10 @@
 
     ctx = xmlSecMSCryptoKeyDataGetCtx(xmlSecKeyGetValue(key));
     xmlSecAssert2(ctx != NULL, -1);
-    xmlSecAssert2(ctx->hKey != 0, -1);
+    xmlSecAssert2(ctx->p_key != 0, -1);
+    xmlSecAssert2(ctx->p_key->hKey != 0, -1);
 
-    if (!CryptExportKey(ctx->hKey, 0, PUBLICKEYBLOB, 0, NULL, &dwBlobLen)) {
+    if (!CryptExportKey(ctx->p_key->hKey, 0, PUBLICKEYBLOB, 0, NULL, &dwBlobLen)) {
 	xmlSecError(XMLSEC_ERRORS_HERE,
 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
 		    "CryptExportKey",
@@ -960,7 +1077,7 @@
     }
 
     blob = xmlSecBufferGetData(&buf);
-    if (!CryptExportKey(ctx->hKey, 0, PUBLICKEYBLOB, 0, blob, &dwBlobLen)) {
+    if (!CryptExportKey(ctx->p_key->hKey, 0, PUBLICKEYBLOB, 0, blob, &dwBlobLen)) {
 	xmlSecError(XMLSEC_ERRORS_HERE,
 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
 		    "CryptExportKey",
@@ -1797,9 +1914,10 @@
 
     ctx = xmlSecMSCryptoKeyDataGetCtx(xmlSecKeyGetValue(key));
     xmlSecAssert2(ctx != NULL, -1);
-    xmlSecAssert2(ctx->hKey != 0, -1);
+    xmlSecAssert2(ctx->p_key != 0, -1);
+    xmlSecAssert2(ctx->p_key->hKey != 0, -1);
     
-    if (!CryptExportKey(ctx->hKey, 0, PUBLICKEYBLOB, 0, NULL, &dwBlobLen)) {
+    if (!CryptExportKey(ctx->p_key->hKey, 0, PUBLICKEYBLOB, 0, NULL, &dwBlobLen)) {
 	xmlSecError(XMLSEC_ERRORS_HERE,
 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
 		    "CryptExportKey",
@@ -1819,7 +1937,7 @@
     }
 
     blob = xmlSecBufferGetData(&buf);
-    if (!CryptExportKey(ctx->hKey, 0, PUBLICKEYBLOB, 0, blob, &dwBlobLen)) {
+    if (!CryptExportKey(ctx->p_key->hKey, 0, PUBLICKEYBLOB, 0, blob, &dwBlobLen)) {
 	xmlSecError(XMLSEC_ERRORS_HERE,
 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
 		    "CryptExportKey",
@@ -2010,7 +2128,6 @@
     HCRYPTKEY hKey = 0;
     DWORD dwKeySpec;
     DWORD dwSize;
-    int res = -1;
     int ret;
 
     xmlSecAssert2(xmlSecKeyDataIsValid(data), xmlSecKeyDataTypeUnknown);
@@ -2048,7 +2165,9 @@
 		    "CryptGenKey",
 		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
 		    XMLSEC_ERRORS_NO_MESSAGE);
-	goto done;
+    	if (hProv != 0)
+			CryptReleaseContext(hProv, 0);
+		return -1 ;
     }
 
     ret = xmlSecMSCryptoKeyDataAdoptKey(data, hProv, TRUE, hKey, dwKeySpec, 
@@ -2059,24 +2178,17 @@
 		    "xmlSecMSCryptoKeyDataAdoptKey",
 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
 		    XMLSEC_ERRORS_NO_MESSAGE);
-	goto done;
+	    if( hKey != 0 )
+			CryptDestroyKey( hKey ) ;
+    	if( hProv != 0 )
+			CryptReleaseContext( hProv, 0 ) ;
+
+		return -1 ;
     }
     hProv = 0;
     hKey = 0;
 
-    /* success */
-    res = 0;
-
-done:
-    if (hProv != 0) {
-	CryptReleaseContext(ctx->hProv, 0);
-    }
-
-    if (hKey != 0) {
-	CryptDestroyKey(hKey);
-    }
-
-    return(res);
+    return 0 ;
 }
 
 static xmlSecKeyDataType
Index: xmlsec/src/mscrypto/x509.c
===================================================================
RCS file: /cvs/gnome/xmlsec/src/mscrypto/x509.c,v
retrieving revision 1.2
diff -u -r1.2 x509.c
--- xmlsec/src/mscrypto/x509.c	26 Sep 2003 00:58:13 -0000	1.2
+++ xmlsec/src/mscrypto/x509.c	6 Feb 2005 03:53:19 -0000
@@ -1572,6 +1572,7 @@
 					     xmlSecKeyInfoCtxPtr keyInfoCtx) {
     xmlSecMSCryptoX509DataCtxPtr ctx;
     xmlSecKeyDataStorePtr x509Store;
+	PCCERT_CONTEXT pCert ;
     int ret;
     
     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), -1);
@@ -1610,6 +1611,9 @@
 		return(-1);
 	    }
 
+		/*-
+		 * Get Public key from cert, which does not always work for sign action.
+         *
 	    keyValue = xmlSecMSCryptoX509CertGetKey(ctx->keyCert);
 	    if(keyValue == NULL) {
 		xmlSecError(XMLSEC_ERRORS_HERE,
@@ -1619,6 +1623,51 @@
 			    XMLSEC_ERRORS_NO_MESSAGE);
 		return(-1);
 	    }
+		*/
+
+		/*-
+		 * I'll search key according to KeyReq.
+		 */
+		pCert = CertDuplicateCertificateContext( ctx->keyCert ) ;
+		if( pCert == NULL ) {
+			xmlSecError( XMLSEC_ERRORS_HERE,
+		    	xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+				"CertDuplicateCertificateContext",
+				XMLSEC_ERRORS_R_CRYPTO_FAILED,
+				XMLSEC_ERRORS_NO_MESSAGE);
+
+			return(-1);
+		}
+
+		if( ( keyInfoCtx->keyReq.keyType & xmlSecKeyDataTypePrivate ) == xmlSecKeyDataTypePrivate ) {
+			keyValue = xmlSecMSCryptoCertAdopt( pCert, xmlSecKeyDataTypePrivate ) ;
+			if(keyValue == NULL) {
+				xmlSecError(XMLSEC_ERRORS_HERE,
+						xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+						"xmlSecMSCryptoCertAdopt",
+						XMLSEC_ERRORS_R_XMLSEC_FAILED,
+						XMLSEC_ERRORS_NO_MESSAGE);
+
+				CertFreeCertificateContext( pCert ) ;
+				return(-1);
+			}
+			pCert = NULL ;
+		} else if( ( keyInfoCtx->keyReq.keyType & xmlSecKeyDataTypePublic ) == xmlSecKeyDataTypePublic ) {
+			keyValue = xmlSecMSCryptoCertAdopt( pCert, xmlSecKeyDataTypePublic ) ;
+			if(keyValue == NULL) {
+				xmlSecError(XMLSEC_ERRORS_HERE,
+						xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+						"xmlSecMSCryptoCertAdopt",
+						XMLSEC_ERRORS_R_XMLSEC_FAILED,
+						XMLSEC_ERRORS_NO_MESSAGE);
+
+				CertFreeCertificateContext( pCert ) ;
+				return(-1);
+			}
+			pCert = NULL ;
+		}
+
+
 
 	    /* verify that the key matches our expectations */
 	    if(xmlSecKeyReqMatchKeyValue(&(keyInfoCtx->keyReq), keyValue) != 1) {
Index: xmlsec/src/mscrypto/x509vfy.c
===================================================================
RCS file: /cvs/gnome/xmlsec/src/mscrypto/x509vfy.c,v
retrieving revision 1.3
diff -u -r1.3 x509vfy.c
--- xmlsec/src/mscrypto/x509vfy.c	27 Sep 2003 03:12:22 -0000	1.3
+++ xmlsec/src/mscrypto/x509vfy.c	6 Feb 2005 03:53:20 -0000
@@ -125,6 +125,7 @@
 				xmlChar *issuerName, xmlChar *issuerSerial,
 				xmlChar *ski, xmlSecKeyInfoCtx* keyInfoCtx) {
     xmlSecMSCryptoX509StoreCtxPtr ctx;
+	PCCERT_CONTEXT pCert ;
     
     xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecMSCryptoX509StoreId), NULL);
     xmlSecAssert2(keyInfoCtx != NULL, NULL);
@@ -132,10 +133,17 @@
     ctx = xmlSecMSCryptoX509StoreGetCtx(store);
     xmlSecAssert2(ctx != NULL, NULL);
     xmlSecAssert2(ctx->untrusted != NULL, NULL);
+    xmlSecAssert2(ctx->trusted != NULL, NULL);
 
-    return(xmlSecMSCryptoX509FindCert(ctx->untrusted, subjectName, issuerName, issuerSerial, ski));
-}
+	pCert = NULL ;
+	if( ctx->untrusted != NULL )
+		pCert = xmlSecMSCryptoX509FindCert( ctx->untrusted, subjectName, issuerName, issuerSerial, ski ) ;
+
+	if( ctx->trusted != NULL && pCert == NULL )
+		pCert = xmlSecMSCryptoX509FindCert( ctx->trusted, subjectName, issuerName, issuerSerial, ski ) ;
 
+    return( pCert ) ;
+}
 
 static void 
 xmlSecMSCryptoUnixTimeToFileTime(time_t t, LPFILETIME pft) {
@@ -252,17 +260,22 @@
 }
 
 static BOOL
-xmlSecMSCryptoX509StoreConstructCertsChain(xmlSecKeyDataStorePtr store, PCCERT_CONTEXT cert, HCERTSTORE certs, 
-			      xmlSecKeyInfoCtx* keyInfoCtx) {
+xmlSecMSCryptoX509StoreConstructCertsChain(
+	xmlSecKeyDataStorePtr store ,
+	PCCERT_CONTEXT cert ,
+	HCERTSTORE certStore , 
+	xmlSecKeyInfoCtx* keyInfoCtx
+) {
     xmlSecMSCryptoX509StoreCtxPtr ctx;
     PCCERT_CONTEXT issuerCert = NULL;
     FILETIME fTime;
     DWORD flags;
+    BOOL selfSigned ;
     
     xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecMSCryptoX509StoreId), FALSE);
     xmlSecAssert2(cert != NULL, FALSE);
     xmlSecAssert2(cert->pCertInfo != NULL, FALSE);
-    xmlSecAssert2(certs != NULL, FALSE);
+    xmlSecAssert2(certStore != NULL, FALSE);
     xmlSecAssert2(keyInfoCtx != NULL, FALSE);
 
     ctx = xmlSecMSCryptoX509StoreGetCtx(store);
@@ -283,18 +296,38 @@
 	return(FALSE);
     }
 
-    if (!xmlSecMSCryptoCheckRevocation(certs, cert)) {
+    if (!xmlSecMSCryptoCheckRevocation(certStore, cert)) {
 	return(FALSE);
     }
 
+    /*-
+	 * Firstly try to find the cert in the trusted cert store. We will trust
+	 * the certificate in the trusted store.
+	 */
+    issuerCert = CertFindCertificateInStore(ctx->trusted, 
+			    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
+			    0,
+			    CERT_FIND_SUBJECT_NAME,
+			    &(cert->pCertInfo->Subject),
+			    NULL);
+    if( issuerCert != NULL ) {
+		/* We have found the trusted cert, so return true */
+		CertFreeCertificateContext( issuerCert ) ;
+		return( TRUE ) ;
+    }
+
+	/* Check whether the certificate is self signed certificate */
+	selfSigned = CertCompareCertificateName( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, &(cert->pCertInfo->Subject), &(cert->pCertInfo->Issuer) ) ;
+
     /* try the untrusted certs in the chain */
-    issuerCert = CertFindCertificateInStore(certs, 
+	if( !selfSigned ) {
+	    issuerCert = CertFindCertificateInStore(certStore, 
 			    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
 			    0,
 			    CERT_FIND_SUBJECT_NAME,
 			    &(cert->pCertInfo->Issuer),
 			    NULL);
-    if(issuerCert == cert) {
+	    if( issuerCert != NULL && CertCompareCertificate( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, cert->pCertInfo, issuerCert->pCertInfo ) ) {
 	/* self signed cert, forget it */
 	CertFreeCertificateContext(issuerCert);
     } else if(issuerCert != NULL) {
@@ -304,23 +337,26 @@
 	    CertFreeCertificateContext(issuerCert);
 	    return(FALSE);
         }
-	if(!xmlSecMSCryptoX509StoreConstructCertsChain(store, issuerCert, certs, keyInfoCtx)) {
+			if(!xmlSecMSCryptoX509StoreConstructCertsChain(store, issuerCert, certStore, keyInfoCtx)) {
 	    xmlSecMSCryptoX509StoreCertError(store, issuerCert, flags);
 	    CertFreeCertificateContext(issuerCert);
 	    return(FALSE);
 	}
+
 	CertFreeCertificateContext(issuerCert);
 	return(TRUE);
     }
+	}
 
     /* try the untrusted certs in the store */
+	if( !selfSigned ) {
     issuerCert = CertFindCertificateInStore(ctx->untrusted, 
 			    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
 			    0,
 			    CERT_FIND_SUBJECT_NAME,
 			    &(cert->pCertInfo->Issuer),
 			    NULL);
-    if(issuerCert == cert) {
+	    if( issuerCert != NULL && CertCompareCertificate( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, cert->pCertInfo, issuerCert->pCertInfo ) ) {
 	/* self signed cert, forget it */
 	CertFreeCertificateContext(issuerCert);
     } else if(issuerCert != NULL) {
@@ -330,12 +366,14 @@
 	    CertFreeCertificateContext(issuerCert);
 	    return(FALSE);
         }
-	if(!xmlSecMSCryptoX509StoreConstructCertsChain(store, issuerCert, certs, keyInfoCtx)) {
+			if(!xmlSecMSCryptoX509StoreConstructCertsChain(store, issuerCert, certStore, keyInfoCtx)) {
 	    CertFreeCertificateContext(issuerCert);
 	    return(FALSE);
 	}
+
 	CertFreeCertificateContext(issuerCert);
 	return(TRUE);
+	    }
     }
 
     /* try to find issuer cert in the trusted cert in the store */
@@ -379,25 +417,46 @@
     xmlSecAssert2(certs != NULL, NULL);
     xmlSecAssert2(keyInfoCtx != NULL, NULL);
 
-    while((cert = CertEnumCertificatesInStore(certs, cert)) != NULL){
+    while( ( cert = CertEnumCertificatesInStore( certs, cert ) ) != NULL ) {
 	PCCERT_CONTEXT nextCert = NULL;
+		unsigned char selected ;
     
-	xmlSecAssert2(cert->pCertInfo != NULL, NULL);
+		xmlSecAssert2( cert->pCertInfo != NULL, NULL ) ;
 
 	/* if cert is the issuer of any other cert in the list, then it is 
-	* to be skipped */
+		 * to be skipped except that the cert list only have one self-signed
+		 * certificate.
+		 */
+		for( selected = 0, nextCert = NULL ; ; ) {
 	nextCert = CertFindCertificateInStore(certs,
 				X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
 				0,
 				CERT_FIND_ISSUER_NAME,
 				&(cert->pCertInfo->Subject),
-				NULL);
-	if(nextCert != NULL) {
-	    CertFreeCertificateContext(nextCert);
+				nextCert ) ;
+			if( nextCert != NULL ) {
+				if( CertCompareCertificate( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, cert->pCertInfo, nextCert->pCertInfo ) ) {
+					selected = 1 ;
+					continue ;
+				} else {
+					selected = 0 ;
+					break ;
+				}
+			} else {
+				selected = 1 ;
+				break ;
+			}
+		}
+
+		if( nextCert != NULL )
+			CertFreeCertificateContext( nextCert ) ;
+
+		if( !selected ) {
 	    continue;
 	}
-	if(xmlSecMSCryptoX509StoreConstructCertsChain(store, cert, certs, keyInfoCtx)) {
-	    return(cert);
+
+		if( xmlSecMSCryptoX509StoreConstructCertsChain( store, cert, certs, keyInfoCtx ) ) {
+		    return( cert ) ;
 	}
     }
 
@@ -458,9 +517,126 @@
     return(0);
 }
 
+int	
+xmlSecMSCryptoX509StoreAdoptKeyStore (
+	xmlSecKeyDataStorePtr store,
+	HCERTSTORE keyStore
+) {
+    xmlSecMSCryptoX509StoreCtxPtr ctx;
+    int ret;
+
+    xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecMSCryptoX509StoreId), -1);
+    xmlSecAssert2( keyStore != NULL, -1);
+
+    ctx = xmlSecMSCryptoX509StoreGetCtx(store);
+    xmlSecAssert2(ctx != NULL, -1);
+    xmlSecAssert2(ctx->trusted != NULL, -1);
+
+	if( !CertAddStoreToCollection ( ctx->trusted , keyStore , CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG , 2 ) ) {
+		xmlSecError(XMLSEC_ERRORS_HERE,
+		    xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+		    "CertAddStoreToCollection",
+		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
+		    XMLSEC_ERRORS_NO_MESSAGE);
+		return(-1);
+	}
+
+	{
+		PCCERT_CONTEXT ptCert ;
+
+		ptCert = NULL ;
+		while( 1 ) {
+			ptCert = CertEnumCertificatesInStore( ctx->trusted, ptCert ) ;
+			if( ptCert == NULL )
+				break ;
+		}
+	}
+
+    return(0);
+}
+
+int
+xmlSecMSCryptoX509StoreAdoptTrustedStore (
+	xmlSecKeyDataStorePtr store,
+	HCERTSTORE trustedStore
+) {
+    xmlSecMSCryptoX509StoreCtxPtr ctx;
+    int ret;
+
+    xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecMSCryptoX509StoreId), -1);
+    xmlSecAssert2( trustedStore != NULL, -1);
+
+    ctx = xmlSecMSCryptoX509StoreGetCtx(store);
+    xmlSecAssert2(ctx != NULL, -1);
+    xmlSecAssert2(ctx->trusted != NULL, -1);
+
+	if( !CertAddStoreToCollection ( ctx->trusted , trustedStore , CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG , 3 ) ) {
+		xmlSecError(XMLSEC_ERRORS_HERE,
+		    xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+		    "CertAddStoreToCollection",
+		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
+		    XMLSEC_ERRORS_NO_MESSAGE);
+		return(-1);
+	}
+
+	{
+		PCCERT_CONTEXT ptCert ;
+
+		ptCert = NULL ;
+		while( 1 ) {
+			ptCert = CertEnumCertificatesInStore( ctx->trusted, ptCert ) ;
+			if( ptCert == NULL )
+				break ;
+		}
+	}
+
+    return(0);
+}
+
+int
+xmlSecMSCryptoX509StoreAdoptUntrustedStore (
+	xmlSecKeyDataStorePtr store,
+	HCERTSTORE untrustedStore
+) {
+    xmlSecMSCryptoX509StoreCtxPtr ctx;
+    int ret;
+
+    xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecMSCryptoX509StoreId), -1);
+    xmlSecAssert2( untrustedStore != NULL, -1);
+
+    ctx = xmlSecMSCryptoX509StoreGetCtx(store);
+    xmlSecAssert2(ctx != NULL, -1);
+    xmlSecAssert2(ctx->untrusted != NULL, -1);
+
+	if( !CertAddStoreToCollection ( ctx->untrusted , untrustedStore , CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG , 2 ) ) {
+		xmlSecError(XMLSEC_ERRORS_HERE,
+		    xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+		    "CertAddStoreToCollection",
+		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
+		    XMLSEC_ERRORS_NO_MESSAGE);
+		return(-1);
+	}
+
+	{
+		PCCERT_CONTEXT ptCert ;
+
+		ptCert = NULL ;
+		while( 1 ) {
+			ptCert = CertEnumCertificatesInStore( ctx->untrusted, ptCert ) ;
+			if( ptCert == NULL )
+				break ;
+		}
+	}
+
+	return(0);
+}
+
 static int
 xmlSecMSCryptoX509StoreInitialize(xmlSecKeyDataStorePtr store) {
     xmlSecMSCryptoX509StoreCtxPtr ctx;
+	HCERTSTORE hTrustedMemStore ;
+	HCERTSTORE hUntrustedMemStore ;
+
     xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecMSCryptoX509StoreId), -1);
 
     ctx = xmlSecMSCryptoX509StoreGetCtx(store);
@@ -468,11 +644,11 @@
 
     memset(ctx, 0, sizeof(xmlSecMSCryptoX509StoreCtx));
 
-    /* create trusted certs store */
-    ctx->trusted = CertOpenStore(CERT_STORE_PROV_MEMORY,
-			       X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
+    /* create trusted certs store collection */
+    ctx->trusted = CertOpenStore(CERT_STORE_PROV_COLLECTION,
+			       0,
+			       NULL,
 			       0,
-			       CERT_STORE_CREATE_NEW_FLAG,
 			       NULL);
     if(ctx->trusted == NULL) {
 	xmlSecError(XMLSEC_ERRORS_HERE,
@@ -484,20 +660,88 @@
     }
 
     /* create trusted certs store */
-    ctx->untrusted = CertOpenStore(CERT_STORE_PROV_MEMORY,
+    hTrustedMemStore = CertOpenStore(CERT_STORE_PROV_MEMORY,
 			       X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
 			       0,
 			       CERT_STORE_CREATE_NEW_FLAG,
 			       NULL);
+    if(hTrustedMemStore == NULL) {
+	xmlSecError(XMLSEC_ERRORS_HERE,
+		    xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+		    "CertOpenStore",
+		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
+		    XMLSEC_ERRORS_NO_MESSAGE);
+	CertCloseStore(ctx->trusted, CERT_CLOSE_STORE_FORCE_FLAG);
+	ctx->trusted = NULL ;
+	return(-1);
+    }
+
+	/* add the memory trusted certs store to trusted certs store collection */
+	if( !CertAddStoreToCollection( ctx->trusted, hTrustedMemStore, CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 1 ) ) {
+	xmlSecError(XMLSEC_ERRORS_HERE,
+		    xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+		    "CertAddStoreToCollection",
+		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
+		    XMLSEC_ERRORS_NO_MESSAGE);
+	CertCloseStore(ctx->trusted, CERT_CLOSE_STORE_FORCE_FLAG);
+	CertCloseStore(hTrustedMemStore, CERT_CLOSE_STORE_CHECK_FLAG);
+	ctx->trusted = NULL ;
+	return(-1);
+	}
+	CertCloseStore(hTrustedMemStore, CERT_CLOSE_STORE_CHECK_FLAG);
+
+    /* create untrusted certs store collection */
+    ctx->untrusted = CertOpenStore(CERT_STORE_PROV_COLLECTION,
+			       0,
+			       NULL,
+			       0,
+			       NULL);
     if(ctx->untrusted == NULL) {
 	xmlSecError(XMLSEC_ERRORS_HERE,
 		    xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
 		    "CertOpenStore",
 		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
 		    XMLSEC_ERRORS_NO_MESSAGE);
+	CertCloseStore(ctx->trusted, CERT_CLOSE_STORE_FORCE_FLAG);
+	ctx->trusted = NULL ;
+	return(-1);
+	}
+
+    /* create untrusted certs store */
+    hUntrustedMemStore = CertOpenStore(CERT_STORE_PROV_MEMORY,
+			       X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
+			       0,
+			       CERT_STORE_CREATE_NEW_FLAG,
+			       NULL);
+    if(hUntrustedMemStore == NULL) {
+	xmlSecError(XMLSEC_ERRORS_HERE,
+		    xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+		    "CertOpenStore",
+		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
+		    XMLSEC_ERRORS_NO_MESSAGE);
+	CertCloseStore(ctx->trusted, CERT_CLOSE_STORE_FORCE_FLAG);
+	CertCloseStore(ctx->untrusted, CERT_CLOSE_STORE_FORCE_FLAG);
+	ctx->trusted = NULL ;
+	ctx->untrusted = NULL ;
 	return(-1);
     }
 
+	/* add the memory trusted certs store to untrusted certs store collection */
+	if( !CertAddStoreToCollection( ctx->untrusted, hUntrustedMemStore, CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 1 ) ) {
+	xmlSecError(XMLSEC_ERRORS_HERE,
+		    xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+		    "CertAddStoreToCollection",
+		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
+		    XMLSEC_ERRORS_NO_MESSAGE);
+	CertCloseStore(ctx->untrusted, CERT_CLOSE_STORE_FORCE_FLAG);
+	CertCloseStore(ctx->trusted, CERT_CLOSE_STORE_FORCE_FLAG);
+	CertCloseStore(hUntrustedMemStore, CERT_CLOSE_STORE_CHECK_FLAG);
+	ctx->trusted = NULL ;
+	ctx->untrusted = NULL ;
+	return(-1);
+	}
+	CertCloseStore(hUntrustedMemStore, CERT_CLOSE_STORE_CHECK_FLAG);
+
     return(0);    
 }
 
@@ -544,7 +788,7 @@
 
 	cName = xmlSecMSCryptoCertStrToName(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
 					   subjectName,
-					   CERT_OID_NAME_STR | CERT_NAME_STR_REVERSE_FLAG,
+					   CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG,
 					   &cNameLen);
 	if(cName == NULL) {
 	    xmlSecError(XMLSEC_ERRORS_HERE,
@@ -567,6 +811,7 @@
 
     if((pCert == NULL) && (NULL != issuerName) && (NULL != issuerSerial)) {
 	xmlSecBn issuerSerialBn;	
+	CERT_INFO certInfo ;
 	CERT_NAME_BLOB cnb;
         BYTE *cName = NULL; 
 	DWORD cNameLen = 0;	
@@ -592,10 +837,16 @@
 	    return(NULL);
 	}
 
+	/*
 	cName = xmlSecMSCryptoCertStrToName(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
 					   issuerName,
 					   CERT_OID_NAME_STR | CERT_NAME_STR_REVERSE_FLAG,
 					   &cNameLen);
+	*/
+	cName = xmlSecMSCryptoCertStrToName(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
+					   issuerName,
+					   CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG,
+					   &cNameLen);
 	if(cName == NULL) {
 	    xmlSecError(XMLSEC_ERRORS_HERE,
 			NULL,
@@ -608,26 +859,34 @@
 
 	cnb.pbData = cName;
 	cnb.cbData = cNameLen;
-	while((pCert = CertFindCertificateInStore(store, 
-						  PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
-						  0,
-						  CERT_FIND_ISSUER_NAME,
-						  &cnb,
-						  pCert)) != NULL) {
-	    
-	    /* I have no clue why at a sudden a swap is needed to 
-	     * convert from lsb... This code is purely based upon 
-	     * trial and error :( WK
-	     */
-	    if((pCert->pCertInfo != NULL) && 
-	       (pCert->pCertInfo->SerialNumber.pbData != NULL) && 
-	       (pCert->pCertInfo->SerialNumber.cbData > 0) && 
-	       (0 == xmlSecBnCompareReverse(&issuerSerialBn, pCert->pCertInfo->SerialNumber.pbData, 
-				     pCert->pCertInfo->SerialNumber.cbData))) {
-		
-		break;
-	    }
+
+	certInfo.Issuer.cbData = cnb.cbData ;
+	certInfo.Issuer.pbData = cnb.pbData ;
+
+	/*-
+	 * I have no words for MS rubbish.
+	 */
+	if( xmlSecBnReverse( &issuerSerialBn ) < 0 ) {
+	    xmlSecError(XMLSEC_ERRORS_HERE,
+			NULL,
+			"xmlSecBnReverse",
+			XMLSEC_ERRORS_R_XMLSEC_FAILED,
+			XMLSEC_ERRORS_NO_MESSAGE);
+	    xmlSecBnFinalize(&issuerSerialBn);
+	    return (NULL);
 	}
+	certInfo.SerialNumber.cbData = xmlSecBnGetSize( &issuerSerialBn ) ;
+	certInfo.SerialNumber.pbData = xmlSecBnGetData( &issuerSerialBn ) ;
+
+	pCert = CertFindCertificateInStore(
+		store,
+		X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
+		0,
+		CERT_FIND_SUBJECT_CERT,
+		&certInfo,
+		NULL
+	) ;
+
 	xmlFree(cName);
 	xmlSecBnFinalize(&issuerSerialBn);
     }
cvs server: Diffing xmlsec/src/nss
Index: xmlsec/src/nss/Makefile.am
===================================================================
RCS file: /cvs/gnome/xmlsec/src/nss/Makefile.am,v
retrieving revision 1.17
diff -u -r1.17 Makefile.am
--- xmlsec/src/nss/Makefile.am	16 Sep 2003 09:43:03 -0000	1.17
+++ xmlsec/src/nss/Makefile.am	6 Feb 2005 03:53:20 -0000
@@ -20,21 +20,22 @@
 	$(NULL)
 
 libxmlsec1_nss_la_SOURCES =\
+	akmngr.c \
 	app.c \
 	bignum.c \
 	ciphers.c \
 	crypto.c \
 	digests.c \
 	hmac.c \
+	keysstore.c \
+	keytrans.c \
+	keywrapers.c \
 	pkikeys.c \
 	signatures.c \
 	symkeys.c \
+	tokens.c \
 	x509.c \
 	x509vfy.c \
-	keysstore.c \
-	kt_rsa.c \
-	kw_des.c \
-	kw_aes.c \
 	$(NULL)
 
 libxmlsec1_nss_la_LIBADD = \
Index: xmlsec/src/nss/ciphers.c
===================================================================
RCS file: /cvs/gnome/xmlsec/src/nss/ciphers.c,v
retrieving revision 1.19
diff -u -r1.19 ciphers.c
--- xmlsec/src/nss/ciphers.c	26 Sep 2003 00:58:15 -0000	1.19
+++ xmlsec/src/nss/ciphers.c	6 Feb 2005 03:53:20 -0000
@@ -9,830 +9,951 @@
  */
 #include "globals.h"
 
+#include <stdlib.h>
 #include <string.h>
 
-#include <nspr.h>
 #include <nss.h>
-#include <secoid.h>
 #include <pk11func.h>
 
 #include <xmlsec/xmlsec.h>
+#include <xmlsec/xmltree.h>
+#include <xmlsec/base64.h>
 #include <xmlsec/keys.h>
+#include <xmlsec/keyinfo.h>
 #include <xmlsec/transforms.h>
 #include <xmlsec/errors.h>
 
 #include <xmlsec/nss/crypto.h>
+#include <xmlsec/nss/ciphers.h>
 
-#define XMLSEC_NSS_MAX_KEY_SIZE		32
-#define XMLSEC_NSS_MAX_IV_SIZE		32
-#define XMLSEC_NSS_MAX_BLOCK_SIZE	32
-
-/**************************************************************************
- *
- * Internal Nss Block cipher CTX
+/**
+ * Internal Nss Block Cipher Context
  *
- *****************************************************************************/
-typedef struct _xmlSecNssBlockCipherCtx		xmlSecNssBlockCipherCtx,
-							*xmlSecNssBlockCipherCtxPtr;
+ * This context is designed for repositing a block cipher for transform
+ */
+typedef struct _xmlSecNssBlockCipherCtx		xmlSecNssBlockCipherCtx ;
+typedef struct _xmlSecNssBlockCipherCtx*	xmlSecNssBlockCipherCtxPtr ;
+
 struct _xmlSecNssBlockCipherCtx {
-    CK_MECHANISM_TYPE	cipher;
-    PK11Context*	cipherCtx;
-    xmlSecKeyDataId	keyId;
-    int			keyInitialized;
-    int			ctxInitialized;
-    xmlSecByte		key[XMLSEC_NSS_MAX_KEY_SIZE];
-    xmlSecSize		keySize;
-    xmlSecByte		iv[XMLSEC_NSS_MAX_IV_SIZE];
-    xmlSecSize		ivSize;
-};
-static int 	xmlSecNssBlockCipherCtxInit		(xmlSecNssBlockCipherCtxPtr ctx,
-							 xmlSecBufferPtr in,
-							 xmlSecBufferPtr out,
-							 int encrypt,
-							 const xmlChar* cipherName,
-							 xmlSecTransformCtxPtr transformCtx);
-static int 	xmlSecNssBlockCipherCtxUpdate	(xmlSecNssBlockCipherCtxPtr ctx,
-							 xmlSecBufferPtr in,
-							 xmlSecBufferPtr out,
-							 int encrypt,
-							 const xmlChar* cipherName,
-							 xmlSecTransformCtxPtr transformCtx);
-static int 	xmlSecNssBlockCipherCtxFinal		(xmlSecNssBlockCipherCtxPtr ctx,
-							 xmlSecBufferPtr in,
-							 xmlSecBufferPtr out,
-							 int encrypt,
-							 const xmlChar* cipherName,
-							 xmlSecTransformCtxPtr transformCtx);
-static int 
-xmlSecNssBlockCipherCtxInit(xmlSecNssBlockCipherCtxPtr ctx,
-				xmlSecBufferPtr in, xmlSecBufferPtr out,
-				int encrypt,
-				const xmlChar* cipherName,
-				xmlSecTransformCtxPtr transformCtx) {
-    SECItem keyItem;
-    SECItem ivItem;
-    PK11SlotInfo* slot;
-    PK11SymKey* symKey;
-    int ivLen;
-    SECStatus rv;
-    int ret;
-
-    xmlSecAssert2(ctx != NULL, -1);
-    xmlSecAssert2(ctx->cipher != 0, -1);
-    xmlSecAssert2(ctx->cipherCtx == NULL, -1);
-    xmlSecAssert2(ctx->keyInitialized != 0, -1);
-    xmlSecAssert2(ctx->ctxInitialized == 0, -1);
-    xmlSecAssert2(in != NULL, -1);
-    xmlSecAssert2(out != NULL, -1);
-    xmlSecAssert2(transformCtx != NULL, -1);
-
-    ivLen = PK11_GetIVLength(ctx->cipher);
-    xmlSecAssert2(ivLen > 0, -1);
-    xmlSecAssert2((xmlSecSize)ivLen <= sizeof(ctx->iv), -1);
-    
-    if(encrypt) {
-        /* generate random iv */
-        rv = PK11_GenerateRandom(ctx->iv, ivLen);
-	if(rv != SECSuccess) {
-	    xmlSecError(XMLSEC_ERRORS_HERE,
-			xmlSecErrorsSafeString(cipherName),
-			"PK11_GenerateRandom",
-			XMLSEC_ERRORS_R_CRYPTO_FAILED,
-			"size=%d", ivLen);
-	    return(-1);    
-	}
-	
-	/* write iv to the output */
-	ret = xmlSecBufferAppend(out, ctx->iv, ivLen);
-	if(ret < 0) {
-	    xmlSecError(XMLSEC_ERRORS_HERE, 
-			xmlSecErrorsSafeString(cipherName),
-			"xmlSecBufferAppend",
-			XMLSEC_ERRORS_R_XMLSEC_FAILED,
-			"size=%d", ivLen);
-	    return(-1);
-	}
-	
-    } else {
-	/* if we don't have enough data, exit and hope that 
-	 * we'll have iv next time */
-	if(xmlSecBufferGetSize(in) < (xmlSecSize)ivLen) {
-	    return(0);
-	}
-	
-	/* copy iv to our buffer*/
-	xmlSecAssert2(xmlSecBufferGetData(in) != NULL, -1);
-	memcpy(ctx->iv, xmlSecBufferGetData(in), ivLen);
-	
-	/* and remove from input */
-	ret = xmlSecBufferRemoveHead(in, ivLen);
-	if(ret < 0) {
-	    xmlSecError(XMLSEC_ERRORS_HERE, 
-			xmlSecErrorsSafeString(cipherName),
-			"xmlSecBufferRemoveHead",
-			XMLSEC_ERRORS_R_XMLSEC_FAILED,
-			"size=%d", ivLen);
-	    return(-1);
+	CK_MECHANISM_TYPE		cipher ;
+	PK11SymKey*				symkey ;
+	PK11Context*			cipherCtx ;
+	xmlSecKeyDataId			keyId ;
+} ;
+
+#define xmlSecNssBlockCipherSize	\
+	( sizeof( xmlSecTransform ) + sizeof( xmlSecNssBlockCipherCtx ) )
+
+#define xmlSecNssBlockCipherGetCtx( transform ) \
+	( ( xmlSecNssBlockCipherCtxPtr )( ( ( xmlSecByte* )( transform ) ) + sizeof( xmlSecTransform ) ) )
+
+static int
+xmlSecNssBlockCipherCheckId(
+	xmlSecTransformPtr transform
+) {
+	#ifndef XMLSEC_NO_DES
+	if( xmlSecTransformCheckId( transform, xmlSecNssTransformDes3CbcId ) ) {
+		return 1 ;
 	}
-    }
+	#endif /* XMLSEC_NO_DES */
 
-    memset(&keyItem, 0, sizeof(keyItem));
-    keyItem.data = ctx->key;
-    keyItem.len  = ctx->keySize; 
-    memset(&ivItem, 0, sizeof(ivItem));
-    ivItem.data = ctx->iv;
-    ivItem.len  = ctx->ivSize; 
-
-    slot = PK11_GetBestSlot(ctx->cipher, NULL);
-    if(slot == NULL) {
-	xmlSecError(XMLSEC_ERRORS_HERE, 
-		    xmlSecErrorsSafeString(cipherName),
-		    "PK11_GetBestSlot",
-		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-		    XMLSEC_ERRORS_NO_MESSAGE);
-	return(-1);
-    }
-	
-    symKey = PK11_ImportSymKey(slot, ctx->cipher, PK11_OriginDerive, 
-			       CKA_SIGN, &keyItem, NULL);
-    if(symKey == NULL) {
-	xmlSecError(XMLSEC_ERRORS_HERE, 
-		    xmlSecErrorsSafeString(cipherName),
-		    "PK11_ImportSymKey",
-		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-		    XMLSEC_ERRORS_NO_MESSAGE);
-        PK11_FreeSlot(slot);
-	return(-1);
-    }
+	#ifndef XMLSEC_NO_AES
+	if( xmlSecTransformCheckId( transform, xmlSecNssTransformAes128CbcId ) ||
+		xmlSecTransformCheckId( transform, xmlSecNssTransformAes192CbcId ) ||
+		xmlSecTransformCheckId( transform, xmlSecNssTransformAes256CbcId ) ) {
 
-    ctx->cipherCtx = PK11_CreateContextBySymKey(ctx->cipher, 
-			(encrypt) ? CKA_ENCRYPT : CKA_DECRYPT, 
-			symKey, &ivItem);
-    if(ctx->cipherCtx == NULL) {
-	xmlSecError(XMLSEC_ERRORS_HERE, 
-		    xmlSecErrorsSafeString(cipherName),
-		    "PK11_CreateContextBySymKey",
-		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-		    XMLSEC_ERRORS_NO_MESSAGE);
-	PK11_FreeSymKey(symKey);
-        PK11_FreeSlot(slot);
-	return(-1);
+		return 1 ;
     }
-
-    ctx->ctxInitialized = 1;
-    PK11_FreeSymKey(symKey);
-    PK11_FreeSlot(slot);
-    return(0);
+	#endif /* XMLSEC_NO_AES */
+    
+    return 0 ;
 }
 
-static int 
-xmlSecNssBlockCipherCtxUpdate(xmlSecNssBlockCipherCtxPtr ctx,
-				  xmlSecBufferPtr in, xmlSecBufferPtr out,
-				  int encrypt,
-				  const xmlChar* cipherName,
-				  xmlSecTransformCtxPtr transformCtx) {
-    xmlSecSize inSize, inBlocks, outSize;
-    int blockLen;
-    int outLen = 0;
-    xmlSecByte* outBuf;
-    SECStatus rv;
-    int ret;
-    
-    xmlSecAssert2(ctx != NULL, -1);
-    xmlSecAssert2(ctx->cipher != 0, -1);
-    xmlSecAssert2(ctx->cipherCtx != NULL, -1);
-    xmlSecAssert2(ctx->ctxInitialized != 0, -1);
-    xmlSecAssert2(in != NULL, -1);
-    xmlSecAssert2(out != NULL, -1);
-    xmlSecAssert2(transformCtx != NULL, -1);
+static int
+xmlSecNssBlockCipherFetchCtx(
+	xmlSecNssBlockCipherCtxPtr		context ,
+	xmlSecTransformId				id
+) {
+	xmlSecAssert2( context != NULL, -1 ) ;
+
+	#ifndef XMLSEC_NO_DES
+	if( id == xmlSecNssTransformDes3CbcId ) {
+		context->cipher = CKM_DES3_CBC ;
+		context->keyId = xmlSecNssKeyDataDesId ;
+	} else
+	#endif		/* XMLSEC_NO_DES */
+
+	#ifndef XMLSEC_NO_AES
+	if( id == xmlSecNssTransformAes128CbcId ) {
+		context->cipher = CKM_AES_CBC ;
+		context->keyId = xmlSecNssKeyDataAesId ;
+	} else
+	if( id == xmlSecNssTransformAes192CbcId ) {
+		context->cipher = CKM_AES_CBC ;
+		context->keyId = xmlSecNssKeyDataAesId ;
+	} else
+	if( id == xmlSecNssTransformAes256CbcId ) {
+		context->cipher = CKM_AES_CBC ;
+		context->keyId = xmlSecNssKeyDataAesId ;
+	} else
+	#endif		/* XMLSEC_NO_AES */
+
+	if( 1 ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+		    NULL ,
+		    NULL ,
+		    XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+		    XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return -1 ;    
+	}
 
-    blockLen = PK11_GetBlockSize(ctx->cipher, NULL);
-    xmlSecAssert2(blockLen > 0, -1);
+	return 0 ;
+}
 
-    inSize = xmlSecBufferGetSize(in);
-    outSize = xmlSecBufferGetSize(out);
-    
-    if(inSize < (xmlSecSize)blockLen) {
-	return(0);
-    }
+/**
+ * xmlSecTransformInitializeMethod:
+ * @transform:			the pointer to transform object.
+ *
+ * The transform specific initialization method.
+ *
+ * Returns 0 on success or a negative value otherwise.
+ */
+static int
+xmlSecNssBlockCipherInitialize(
+	xmlSecTransformPtr transform
+) {
+	xmlSecNssBlockCipherCtxPtr context = NULL ;
+
+	xmlSecAssert2( xmlSecNssBlockCipherCheckId( transform ), -1 ) ;
+	xmlSecAssert2( xmlSecTransformCheckSize( transform, xmlSecNssBlockCipherSize ), -1 ) ;
+
+	context = xmlSecNssBlockCipherGetCtx( transform ) ;
+	if( context == NULL ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+		    xmlSecErrorsSafeString( xmlSecTransformGetName( transform ) ) ,
+		    "xmlSecNssBlockCipherGetCtx" ,
+		    XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+		    XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return -1 ;    
+	}
+
+	if( xmlSecNssBlockCipherFetchCtx( context , transform->id ) < 0 ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+		    xmlSecErrorsSafeString( xmlSecTransformGetName( transform ) ) ,
+		    "xmlSecNssBlockCipherFetchCtx" ,
+		    XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+		    XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return -1 ;    
+	}
 
-    if(encrypt) {
-        inBlocks = inSize / ((xmlSecSize)blockLen);
-    } else {
-	/* we want to have the last block in the input buffer 
-	 * for padding check */
-        inBlocks = (inSize - 1) / ((xmlSecSize)blockLen);
-    }
-    inSize = inBlocks * ((xmlSecSize)blockLen);
+	context->symkey = NULL ;
+	context->cipherCtx = NULL ;
 
-    /* we write out the input size plus may be one block */
-    ret = xmlSecBufferSetMaxSize(out, outSize + inSize + blockLen);
-    if(ret < 0) {
-	xmlSecError(XMLSEC_ERRORS_HERE, 
-		    xmlSecErrorsSafeString(cipherName),
-		    "xmlSecBufferSetMaxSize",
-		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-		    "size=%d", outSize + inSize + blockLen);
-	return(-1);
-    }
-    outBuf = xmlSecBufferGetData(out) + outSize;
-    
-    rv = PK11_CipherOp(ctx->cipherCtx, outBuf, &outLen, inSize + blockLen,
-			xmlSecBufferGetData(in), inSize);
-    if(rv != SECSuccess) {
-	xmlSecError(XMLSEC_ERRORS_HERE, 
-		    xmlSecErrorsSafeString(cipherName),
-		    "PK11_CipherOp",
-		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-		    XMLSEC_ERRORS_NO_MESSAGE);
-	return(-1);
-    }
-    xmlSecAssert2((xmlSecSize)outLen == inSize, -1);
-    
-    /* set correct output buffer size */
-    ret = xmlSecBufferSetSize(out, outSize + outLen);
-    if(ret < 0) {
-	xmlSecError(XMLSEC_ERRORS_HERE, 
-		    xmlSecErrorsSafeString(cipherName),
-		    "xmlSecBufferSetSize",
-		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-		    "size=%d", outSize + outLen);
-	return(-1);
-    }
-        
-    /* remove the processed block from input */
-    ret = xmlSecBufferRemoveHead(in, inSize);
-    if(ret < 0) {
-	xmlSecError(XMLSEC_ERRORS_HERE, 
-		    xmlSecErrorsSafeString(cipherName),
-		    "xmlSecBufferRemoveHead",
-		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-		    "size=%d", inSize);
-	return(-1);
-    }
-    return(0);
+	return 0 ;
 }
 
-static int 
-xmlSecNssBlockCipherCtxFinal(xmlSecNssBlockCipherCtxPtr ctx,
-				 xmlSecBufferPtr in,
-				 xmlSecBufferPtr out,
-				 int encrypt,
-				 const xmlChar* cipherName,
-				 xmlSecTransformCtxPtr transformCtx) {
-    xmlSecSize inSize, outSize;
-    int blockLen, outLen = 0;
-    xmlSecByte* inBuf;
-    xmlSecByte* outBuf;
-    SECStatus rv;
-    int ret;
-    
-    xmlSecAssert2(ctx != NULL, -1);
-    xmlSecAssert2(ctx->cipher != 0, -1);
-    xmlSecAssert2(ctx->cipherCtx != NULL, -1);
-    xmlSecAssert2(ctx->ctxInitialized != 0, -1);
-    xmlSecAssert2(in != NULL, -1);
-    xmlSecAssert2(out != NULL, -1);
-    xmlSecAssert2(transformCtx != NULL, -1);
-
-    blockLen = PK11_GetBlockSize(ctx->cipher, NULL);
-    xmlSecAssert2(blockLen > 0, -1);
+/**
+ * xmlSecTransformFinalizeMethod:
+ * @transform:			the pointer to transform object.
+ *
+ * The transform specific destroy method.
+ */
+static void 
+xmlSecNssBlockCipherFinalize(
+	xmlSecTransformPtr transform
+) {
+	xmlSecNssBlockCipherCtxPtr context = NULL ;
 
-    inSize = xmlSecBufferGetSize(in);
-    outSize = xmlSecBufferGetSize(out);
+	xmlSecAssert( xmlSecNssBlockCipherCheckId( transform ) ) ;
+	xmlSecAssert( xmlSecTransformCheckSize( transform, xmlSecNssBlockCipherSize ) ) ;
 
-    if(encrypt != 0) {
-        xmlSecAssert2(inSize < (xmlSecSize)blockLen, -1);        
-    
-	/* create padding */
-        ret = xmlSecBufferSetMaxSize(in, blockLen);
-	if(ret < 0) {
-	    xmlSecError(XMLSEC_ERRORS_HERE, 
-			xmlSecErrorsSafeString(cipherName),
-			"xmlSecBufferSetMaxSize",
-			XMLSEC_ERRORS_R_XMLSEC_FAILED,
-			"size=%d", blockLen);
-	    return(-1);
-	}
-	inBuf = xmlSecBufferGetData(in);
-
-        /* generate random padding */
-	if((xmlSecSize)blockLen > (inSize + 1)) {
-	    rv = PK11_GenerateRandom(inBuf + inSize, blockLen - inSize - 1);
-	    if(rv != SECSuccess) {
-		xmlSecError(XMLSEC_ERRORS_HERE,
-			    xmlSecErrorsSafeString(cipherName),
-			    "PK11_GenerateRandom",
-			    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-			    "size=%d", blockLen - inSize - 1); 
-		return(-1);    
-	    }
-	}
-	inBuf[blockLen - 1] = blockLen - inSize;
-	inSize = blockLen;
-    } else {
-	if(inSize != (xmlSecSize)blockLen) {
-	    xmlSecError(XMLSEC_ERRORS_HERE, 
-			xmlSecErrorsSafeString(cipherName),
-			NULL,
-			XMLSEC_ERRORS_R_INVALID_DATA,
-			"data=%d;block=%d", inSize, blockLen);
-	    return(-1);
+	context = xmlSecNssBlockCipherGetCtx( transform ) ;
+	if( context == NULL ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+		    xmlSecErrorsSafeString( xmlSecTransformGetName( transform ) ) ,
+		    "xmlSecNssBlockCipherGetCtx" ,
+		    XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+		    XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return ;    
 	}
-    }
-    
-    /* process last block */
-    ret = xmlSecBufferSetMaxSize(out, outSize + 2 * blockLen);
-    if(ret < 0) {
-	xmlSecError(XMLSEC_ERRORS_HERE, 
-		    xmlSecErrorsSafeString(cipherName),
-		    "xmlSecBufferSetMaxSize",
-		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-		    "size=%d", outSize + 2 * blockLen);
-	return(-1);
-    }
-    outBuf = xmlSecBufferGetData(out) + outSize;
 
-    rv = PK11_CipherOp(ctx->cipherCtx, outBuf, &outLen, 2 * blockLen,
-			xmlSecBufferGetData(in), inSize);
-    if(rv != SECSuccess) {
-	xmlSecError(XMLSEC_ERRORS_HERE, 
-		    xmlSecErrorsSafeString(cipherName),
-		    "PK11_CipherOp",
-		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-		    XMLSEC_ERRORS_NO_MESSAGE);
-	return(-1);
-    }
-    xmlSecAssert2((xmlSecSize)outLen == inSize, -1);
-    
-    if(encrypt == 0) {
-	/* check padding */
-	if(outLen < outBuf[blockLen - 1]) {
-	    xmlSecError(XMLSEC_ERRORS_HERE,
-			xmlSecErrorsSafeString(cipherName),
-			NULL,
-			XMLSEC_ERRORS_R_INVALID_DATA,
-			"padding=%d;buffer=%d",
-			outBuf[blockLen - 1], outLen);
-	    return(-1);	
-	}
-	outLen -= outBuf[blockLen - 1];
-    } 
-
-    /* set correct output buffer size */
-    ret = xmlSecBufferSetSize(out, outSize + outLen);
-    if(ret < 0) {
-	xmlSecError(XMLSEC_ERRORS_HERE, 
-		    xmlSecErrorsSafeString(cipherName),
-		    "xmlSecBufferSetSize",
-		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-		    "size=%d", outSize + outLen);
-	return(-1);
-    }
+	if( context->cipherCtx != NULL ) {
+		PK11_DestroyContext( context->cipherCtx, PR_TRUE ) ;
+		context->cipherCtx = NULL ;
+	}
 
-    /* remove the processed block from input */
-    ret = xmlSecBufferRemoveHead(in, inSize);
-    if(ret < 0) {
-	xmlSecError(XMLSEC_ERRORS_HERE, 
-		    xmlSecErrorsSafeString(cipherName),
-		    "xmlSecBufferRemoveHead",
-		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-		    "size=%d", inSize);
-	return(-1);
-    }
+	if( context->symkey != NULL ) {
+		PK11_FreeSymKey( context->symkey ) ;
+		context->symkey = NULL ;
+	}
 
-    return(0);
+	context->cipher = CKM_INVALID_MECHANISM ;
+	context->keyId = NULL ;
 }
 
-
-/******************************************************************************
- *
- * EVP Block Cipher transforms
+/**
+ * xmlSecTransformSetKeyRequirementsMethod:
+ * @transform:			the pointer to transform object.
+ * @keyReq:				the pointer to key requirements structure.
  *
- * xmlSecNssBlockCipherCtx block is located after xmlSecTransform structure
+ * Transform specific method to set transform's key requirements.
  * 
- *****************************************************************************/
-#define xmlSecNssBlockCipherSize	\
-    (sizeof(xmlSecTransform) + sizeof(xmlSecNssBlockCipherCtx))
-#define xmlSecNssBlockCipherGetCtx(transform) \
-    ((xmlSecNssBlockCipherCtxPtr)(((xmlSecByte*)(transform)) + sizeof(xmlSecTransform)))
-
-static int	xmlSecNssBlockCipherInitialize	(xmlSecTransformPtr transform);
-static void	xmlSecNssBlockCipherFinalize		(xmlSecTransformPtr transform);
-static int  	xmlSecNssBlockCipherSetKeyReq	(xmlSecTransformPtr transform, 
-							 xmlSecKeyReqPtr keyReq);
-static int	xmlSecNssBlockCipherSetKey		(xmlSecTransformPtr transform,
-							 xmlSecKeyPtr key);
-static int	xmlSecNssBlockCipherExecute		(xmlSecTransformPtr transform,
-							 int last,
-							 xmlSecTransformCtxPtr transformCtx);
-static int	xmlSecNssBlockCipherCheckId		(xmlSecTransformPtr transform);
-							 
+ * Returns 0 on success or a negative value otherwise.
+ */
+static int  
+xmlSecNssBlockCipherSetKeyReq(
+	xmlSecTransformPtr transform ,
+	xmlSecKeyReqPtr keyReq
+) {
+	xmlSecNssBlockCipherCtxPtr context = NULL ;
+	xmlSecSize cipherSize = 0 ;
+
+	xmlSecAssert2( xmlSecNssBlockCipherCheckId( transform ), -1 ) ;
+	xmlSecAssert2( xmlSecTransformCheckSize( transform, xmlSecNssBlockCipherSize ), -1 ) ;
+	xmlSecAssert2( keyReq != NULL , -1 ) ;
+	xmlSecAssert2( ( transform->operation == xmlSecTransformOperationEncrypt ) || ( transform->operation == xmlSecTransformOperationDecrypt ), -1 ) ;
+
+	context = xmlSecNssBlockCipherGetCtx( transform ) ;
+	if( context == NULL ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+		    xmlSecErrorsSafeString( xmlSecTransformGetName( transform ) ) ,
+		    "xmlSecNssBlockCipherGetCtx" ,
+		    XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+		    XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return -1 ;    
+	}
+
+	keyReq->keyId = context->keyId ;
+	keyReq->keyType = xmlSecKeyDataTypeSymmetric ;
+
+	if( transform->operation == xmlSecTransformOperationEncrypt ) {
+		keyReq->keyUsage = xmlSecKeyUsageEncrypt ;
+	} else {
+		keyReq->keyUsage = xmlSecKeyUsageDecrypt ;
+	}
+
+	/*
+	if( context->symkey != NULL )
+		cipherSize = PK11_GetKeyLength( context->symkey ) ; 
 
+	keyReq->keyBitsSize = cipherSize * 8 ;
+	*/
 
+	return 0 ;
+}
+
+/**
+ * xmlSecTransformSetKeyMethod:
+ * @transform:			the pointer to transform object.
+ * @key: 				the pointer to key.
+ *
+ * The transform specific method to set the key for use.
+ * 
+ * Returns 0 on success or a negative value otherwise.
+ */
 static int
-xmlSecNssBlockCipherCheckId(xmlSecTransformPtr transform) {
-#ifndef XMLSEC_NO_DES
-    if(xmlSecTransformCheckId(transform, xmlSecNssTransformDes3CbcId)) {
-	return(1);
-    }
-#endif /* XMLSEC_NO_DES */
+xmlSecNssBlockCipherSetKey(
+	xmlSecTransformPtr transform ,
+	xmlSecKeyPtr key
+) {
+	xmlSecNssBlockCipherCtxPtr context = NULL ;
+	xmlSecKeyDataPtr	keyData = NULL ;
+	PK11SymKey*			symkey = NULL ;
+	CK_ATTRIBUTE_TYPE	operation ;
+	int					ivLen ;
+
+	xmlSecAssert2( xmlSecNssBlockCipherCheckId( transform ), -1 ) ;
+	xmlSecAssert2( xmlSecTransformCheckSize( transform, xmlSecNssBlockCipherSize ), -1 ) ;
+	xmlSecAssert2( key != NULL , -1 ) ;
+    xmlSecAssert2( ( transform->operation == xmlSecTransformOperationEncrypt ) || ( transform->operation == xmlSecTransformOperationDecrypt ), -1 ) ;
+
+	context = xmlSecNssBlockCipherGetCtx( transform ) ;
+	if( context == NULL || context->keyId == NULL || context->symkey != NULL ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+		    xmlSecErrorsSafeString( xmlSecTransformGetName( transform ) ) ,
+		    "xmlSecNssBlockCipherGetCtx" ,
+		    XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+		    XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return -1 ;    
+	}
+	xmlSecAssert2( xmlSecKeyCheckId( key, context->keyId ), -1 ) ;
+
+	keyData = xmlSecKeyGetValue( key ) ;
+	if( keyData == NULL ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+		    xmlSecErrorsSafeString( xmlSecKeyGetName( key ) ) ,
+		    "xmlSecKeyGetValue" ,
+		    XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+		    XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return -1 ;    
+	}
+
+	if( ( symkey = xmlSecNssSymKeyDataGetKey( keyData ) ) == NULL ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+		    xmlSecErrorsSafeString( xmlSecKeyDataGetName( keyData ) ) ,
+		    "xmlSecNssSymKeyDataGetKey" ,
+		    XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+		    XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return -1 ;    
+	}
 
-#ifndef XMLSEC_NO_AES
-    if(xmlSecTransformCheckId(transform, xmlSecNssTransformAes128CbcId) ||
-       xmlSecTransformCheckId(transform, xmlSecNssTransformAes192CbcId) ||
-       xmlSecTransformCheckId(transform, xmlSecNssTransformAes256CbcId)) {
-       
-       return(1);
-    }
-#endif /* XMLSEC_NO_AES */
-    
-    return(0);
+	context->symkey = symkey ;
+
+	return 0 ;
 }
 
+/**
+ * Block cipher transform init
+ */
 static int 
-xmlSecNssBlockCipherInitialize(xmlSecTransformPtr transform) {
-    xmlSecNssBlockCipherCtxPtr ctx;
-    
-    xmlSecAssert2(xmlSecNssBlockCipherCheckId(transform), -1);
-    xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecNssBlockCipherSize), -1);
+xmlSecNssBlockCipherCtxInit(
+	xmlSecNssBlockCipherCtxPtr	ctx ,
+	xmlSecBufferPtr 			in ,
+	xmlSecBufferPtr 			out ,
+	int 						encrypt ,
+	const xmlChar* 				cipherName ,
+	xmlSecTransformCtxPtr 		transformCtx
+) {
+	SECItem				ivItem ;
+	SECItem*			secParam = NULL ;
+	xmlSecBufferPtr		ivBuf = NULL ;
+	int					ivLen ;
+
+	xmlSecAssert2( ctx != NULL , -1 ) ;
+	xmlSecAssert2( ctx->cipher != CKM_INVALID_MECHANISM , -1 ) ;
+	xmlSecAssert2( ctx->symkey != NULL , -1 ) ;
+	xmlSecAssert2( ctx->cipherCtx == NULL , -1 ) ;
+	xmlSecAssert2( ctx->keyId != NULL , -1 ) ;
+	xmlSecAssert2( in != NULL , -1 ) ;
+	xmlSecAssert2( out != NULL , -1 ) ;
+	xmlSecAssert2( transformCtx != NULL , -1 ) ;
+
+	ivLen = PK11_GetIVLength( ctx->cipher ) ;
+	if( ivLen < 0 ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+			NULL ,
+			"PK11_GetIVLength" ,
+			XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+			XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return -1 ;    
+	}
+
+	if( ( ivBuf = xmlSecBufferCreate( ivLen ) ) == NULL ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+			NULL ,
+			"xmlSecBufferCreate" ,
+			XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+			XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return -1 ;    
+	}
+
+	if( encrypt ) {
+		if( PK11_GenerateRandom( ivBuf->data , ivLen ) != SECSuccess ) {
+			xmlSecError( XMLSEC_ERRORS_HERE ,
+				xmlSecErrorsSafeString( cipherName ) ,
+				"PK11_GenerateRandom" ,
+				XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+				XMLSEC_ERRORS_NO_MESSAGE ) ;
+			xmlSecBufferDestroy( ivBuf ) ;
+			return -1 ;    
+		}
+		if( xmlSecBufferSetSize( ivBuf , ivLen ) < 0 ) {
+			xmlSecError( XMLSEC_ERRORS_HERE ,
+				NULL ,
+				"xmlSecBufferSetSize" ,
+				XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+				XMLSEC_ERRORS_NO_MESSAGE ) ;
+			xmlSecBufferDestroy( ivBuf ) ;
+			return -1 ;    
+		}
+
+		if( xmlSecBufferAppend( out , ivBuf->data , ivLen ) < 0 ) {
+			xmlSecError( XMLSEC_ERRORS_HERE ,
+				xmlSecErrorsSafeString( cipherName ) ,
+				"xmlSecBufferAppend" ,
+				XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+				XMLSEC_ERRORS_NO_MESSAGE ) ;
+			xmlSecBufferDestroy( ivBuf ) ;
+			return -1 ;    
+		}
+	} else {
+		if( xmlSecBufferSetData( ivBuf , in->data , ivLen ) < 0 ) {
+			xmlSecError( XMLSEC_ERRORS_HERE ,
+				xmlSecErrorsSafeString( cipherName ) ,
+				"xmlSecBufferSetData" ,
+				XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+				XMLSEC_ERRORS_NO_MESSAGE ) ;
+			xmlSecBufferDestroy( ivBuf ) ;
+			return -1 ;    
+		}
+
+		if( xmlSecBufferRemoveHead( in , ivLen ) < 0 ) {
+			xmlSecError( XMLSEC_ERRORS_HERE ,
+				xmlSecErrorsSafeString( cipherName ) ,
+				"xmlSecBufferRemoveHead" ,
+				XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+				XMLSEC_ERRORS_NO_MESSAGE ) ;
+			xmlSecBufferDestroy( ivBuf ) ;
+			return -1 ;    
+		}
+	}
+
+	ivItem.data = xmlSecBufferGetData( ivBuf ) ;
+	ivItem.len = xmlSecBufferGetSize( ivBuf ) ;
+	if( ( secParam = PK11_ParamFromIV( ctx->cipher , &ivItem ) ) == NULL ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+			xmlSecErrorsSafeString( cipherName ) ,
+			"PK11_ParamFromIV" ,
+			XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+			XMLSEC_ERRORS_NO_MESSAGE ) ;
+		xmlSecBufferDestroy( ivBuf ) ;
+		return -1 ;    
+	}
+
+	ctx->cipherCtx = PK11_CreateContextBySymKey( ctx->cipher , encrypt ? CKA_ENCRYPT : CKA_DECRYPT , ctx->symkey , secParam ) ;
+	if( ctx->cipherCtx == NULL ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+			xmlSecErrorsSafeString( cipherName ) ,
+			"xmlSecBufferRemoveHead" ,
+			XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+			XMLSEC_ERRORS_NO_MESSAGE ) ;
+		SECITEM_FreeItem( secParam , PR_TRUE ) ;
+		xmlSecBufferDestroy( ivBuf ) ;
+		return -1 ;    
+	}
 
-    ctx = xmlSecNssBlockCipherGetCtx(transform);
-    xmlSecAssert2(ctx != NULL, -1);
-    
-    memset(ctx, 0, sizeof(xmlSecNssBlockCipherCtx));
+	SECITEM_FreeItem( secParam , PR_TRUE ) ;
+	xmlSecBufferDestroy( ivBuf ) ;
 
-#ifndef XMLSEC_NO_DES
-    if(transform->id == xmlSecNssTransformDes3CbcId) {
-	ctx->cipher 	= CKM_DES3_CBC;
-	ctx->keyId 	= xmlSecNssKeyDataDesId;
-	ctx->keySize	= 24;
-    } else 
-#endif /* XMLSEC_NO_DES */
-
-#ifndef XMLSEC_NO_AES
-    if(transform->id == xmlSecNssTransformAes128CbcId) {
-	ctx->cipher 	= CKM_AES_CBC;	
-	ctx->keyId 	= xmlSecNssKeyDataAesId;
-	ctx->keySize	= 16;
-    } else if(transform->id == xmlSecNssTransformAes192CbcId) {
-	ctx->cipher 	= CKM_AES_CBC;	
-	ctx->keyId 	= xmlSecNssKeyDataAesId;
-	ctx->keySize	= 24;
-    } else if(transform->id == xmlSecNssTransformAes256CbcId) {
-	ctx->cipher 	= CKM_AES_CBC;	
-	ctx->keyId 	= xmlSecNssKeyDataAesId;
-	ctx->keySize	= 32;
-    } else 
-#endif /* XMLSEC_NO_AES */
-
-    if(1) {
-	xmlSecError(XMLSEC_ERRORS_HERE, 
-		    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
-		    NULL,
-		    XMLSEC_ERRORS_R_INVALID_TRANSFORM,
-		    XMLSEC_ERRORS_NO_MESSAGE);
-	return(-1);
-    }        
-    
-    return(0);
+	return 0 ;
 }
 
-static void 
-xmlSecNssBlockCipherFinalize(xmlSecTransformPtr transform) {
-    xmlSecNssBlockCipherCtxPtr ctx;
+/**
+ * Block cipher transform update
+ */
+static int 
+xmlSecNssBlockCipherCtxUpdate(
+	xmlSecNssBlockCipherCtxPtr	ctx ,
+	xmlSecBufferPtr 			in ,
+	xmlSecBufferPtr 			out ,
+	int 						encrypt ,
+	const xmlChar* 				cipherName ,
+	xmlSecTransformCtxPtr 		transformCtx
+) {
+	xmlSecSize			inSize ;
+	xmlSecSize			outSize ;
+	xmlSecSize			inBlocks ;
+	int					blockSize ;
+	int					outLen ;
+	xmlSecByte*			outBuf ;
+
+	xmlSecAssert2( ctx != NULL , -1 ) ;
+	xmlSecAssert2( ctx->cipher != CKM_INVALID_MECHANISM , -1 ) ;
+	xmlSecAssert2( ctx->symkey != NULL , -1 ) ;
+	xmlSecAssert2( ctx->cipherCtx != NULL , -1 ) ;
+	xmlSecAssert2( ctx->keyId != NULL , -1 ) ;
+	xmlSecAssert2( in != NULL , -1 ) ;
+	xmlSecAssert2( out != NULL , -1 ) ;
+	xmlSecAssert2( transformCtx != NULL , -1 ) ;
+
+	if( ( blockSize = PK11_GetBlockSize( ctx->cipher , NULL ) ) < 0 ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+			xmlSecErrorsSafeString( cipherName ) ,
+			"PK11_GetBlockSize" ,
+			XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+			XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return -1 ;    
+	}
+
+	inSize = xmlSecBufferGetSize( in ) ;
+	outSize = xmlSecBufferGetSize( out ) ;
+
+	inBlocks = ( encrypt != 0 ? inSize : ( inSize - 1 ) ) / blockSize ;
+	inSize = inBlocks * blockSize ;
+
+	if( inSize < blockSize ) {
+		return 0 ;
+	}
+
+	if( xmlSecBufferSetMaxSize( out , outSize + inSize + blockSize ) < 0 ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+			xmlSecErrorsSafeString( cipherName ) ,
+			"xmlSecBufferSetMaxSize" ,
+			XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+			XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return -1 ;    
+	}
+	outBuf = xmlSecBufferGetData( out ) + outSize ;
+
+	if( PK11_CipherOp( ctx->cipherCtx , outBuf , &outLen , inSize + blockSize , xmlSecBufferGetData( in ) , inSize ) != SECSuccess ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+			xmlSecErrorsSafeString( cipherName ) ,
+			"PK11_CipherOp" ,
+			XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+			XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return -1 ;    
+	}
+
+	if( xmlSecBufferSetSize( out , outSize + outLen ) < 0 ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+			xmlSecErrorsSafeString( cipherName ) ,
+			"xmlSecBufferSetSize" ,
+			XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+			XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return -1 ;    
+	}
+
+	if( xmlSecBufferRemoveHead( in , inSize ) < 0 ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+			xmlSecErrorsSafeString( cipherName ) ,
+			"xmlSecBufferRemoveHead" ,
+			XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+			XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return -1 ;    
+	}
 
-    xmlSecAssert(xmlSecNssBlockCipherCheckId(transform));
-    xmlSecAssert(xmlSecTransformCheckSize(transform, xmlSecNssBlockCipherSize));
+	return 0 ;
+}
 
-    ctx = xmlSecNssBlockCipherGetCtx(transform);
-    xmlSecAssert(ctx != NULL);
+/**
+ * Block cipher transform final
+ */
+static int 
+xmlSecNssBlockCipherCtxFinal(
+	xmlSecNssBlockCipherCtxPtr	ctx ,
+	xmlSecBufferPtr 			in ,
+	xmlSecBufferPtr 			out ,
+	int 						encrypt ,
+	const xmlChar* 				cipherName ,
+	xmlSecTransformCtxPtr 		transformCtx
+) {
+	xmlSecSize			inSize ;
+	xmlSecSize			outSize ;
+	int					blockSize ;
+	int					outLen ;
+	xmlSecByte*			inBuf ;
+	xmlSecByte*			outBuf ;
+
+	xmlSecAssert2( ctx != NULL , -1 ) ;
+	xmlSecAssert2( ctx->cipher != CKM_INVALID_MECHANISM , -1 ) ;
+	xmlSecAssert2( ctx->symkey != NULL , -1 ) ;
+	xmlSecAssert2( ctx->cipherCtx != NULL , -1 ) ;
+	xmlSecAssert2( ctx->keyId != NULL , -1 ) ;
+	xmlSecAssert2( in != NULL , -1 ) ;
+	xmlSecAssert2( out != NULL , -1 ) ;
+	xmlSecAssert2( transformCtx != NULL , -1 ) ;
+
+	if( ( blockSize = PK11_GetBlockSize( ctx->cipher , NULL ) ) < 0 ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+			xmlSecErrorsSafeString( cipherName ) ,
+			"PK11_GetBlockSize" ,
+			XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+			XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return -1 ;    
+	}
+
+	inSize = xmlSecBufferGetSize( in ) ;
+	outSize = xmlSecBufferGetSize( out ) ;
+
+	/******************************************************************/
+	if( encrypt != 0 ) {
+		xmlSecAssert2( inSize < blockSize, -1 ) ;
+
+		/* create padding */
+		if( xmlSecBufferSetMaxSize( in , blockSize ) < 0 ) {
+			xmlSecError( XMLSEC_ERRORS_HERE ,
+				xmlSecErrorsSafeString( cipherName ) ,
+				"xmlSecBufferSetMaxSize" ,
+				XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+				XMLSEC_ERRORS_NO_MESSAGE ) ;
+			return -1 ;    
+		}
+		inBuf = xmlSecBufferGetData( in ) ;
+
+		/* generate random */
+		if( blockSize > ( inSize + 1 ) ) {
+			if( PK11_GenerateRandom( inBuf + inSize, blockSize - inSize - 1 ) != SECSuccess ) {
+				xmlSecError( XMLSEC_ERRORS_HERE ,
+					xmlSecErrorsSafeString( cipherName ) ,
+					"PK11_GenerateRandom" ,
+					XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+					XMLSEC_ERRORS_NO_MESSAGE ) ;
+				return -1 ;    
+			}
+		}
+
+		inBuf[blockSize-1] = blockSize - inSize ;
+		inSize = blockSize ;
+	} else {
+		if( inSize != blockSize ) {
+			xmlSecError( XMLSEC_ERRORS_HERE ,
+				xmlSecErrorsSafeString( cipherName ) ,
+				NULL ,
+				XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+				XMLSEC_ERRORS_NO_MESSAGE ) ;
+			return -1 ;    
+		}
+	}
+
+	/* process the last block */
+	if( xmlSecBufferSetMaxSize( out , outSize + inSize + blockSize ) < 0 ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+			xmlSecErrorsSafeString( cipherName ) ,
+			"xmlSecBufferSetMaxSize" ,
+			XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+			XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return -1 ;    
+	}
+	outBuf = xmlSecBufferGetData( out ) + outSize ;
+
+	if( PK11_CipherOp( ctx->cipherCtx , outBuf , &outLen , inSize + blockSize , xmlSecBufferGetData( in ) , inSize ) != SECSuccess ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+			xmlSecErrorsSafeString( cipherName ) ,
+			"PK11_CipherOp" ,
+			XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+			XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return -1 ;    
+	}
+
+	if( encrypt == 0 ) {
+		/* check padding */
+		if( outLen < outBuf[blockSize-1] ) {
+			xmlSecError( XMLSEC_ERRORS_HERE ,
+				xmlSecErrorsSafeString( cipherName ) ,
+				NULL ,
+				XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+				XMLSEC_ERRORS_NO_MESSAGE ) ;
+			return -1 ;    
+		}
+
+		outLen -= outBuf[blockSize-1] ;
+	}
+	/******************************************************************/
+
+	/******************************************************************
+	if( xmlSecBufferSetMaxSize( out , outSize + blockSize ) < 0 ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+			xmlSecErrorsSafeString( cipherName ) ,
+			"xmlSecBufferSetMaxSize" ,
+			XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+			XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return -1 ;    
+	}
+
+	outBuf = xmlSecBufferGetData( out ) + outSize ;
+
+	if( PK11_DigestFinal( ctx->cipherCtx , outBuf , &outLen , blockSize ) != SECSuccess ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+			xmlSecErrorsSafeString( cipherName ) ,
+			"PK11_DigestFinal" ,
+			XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+			XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return -1 ;    
+	}
+	******************************************************************/
+
+	if( xmlSecBufferSetSize( out , outSize + outLen ) < 0 ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+			xmlSecErrorsSafeString( cipherName ) ,
+			"xmlSecBufferSetSize" ,
+			XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+			XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return -1 ;    
+	}
+
+	if( xmlSecBufferRemoveHead( in , inSize ) < 0 ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+			xmlSecErrorsSafeString( cipherName ) ,
+			"xmlSecBufferRemoveHead" ,
+			XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+			XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return -1 ;    
+	}
+
+//	PK11_Finalize( ctx->cipherCtx ) ;
+	PK11_DestroyContext( ctx->cipherCtx , PR_TRUE ) ;
+	ctx->cipherCtx = NULL ;
 
-    if(ctx->cipherCtx != NULL) {
-        PK11_DestroyContext(ctx->cipherCtx, PR_TRUE);
-    }
-    
-    memset(ctx, 0, sizeof(xmlSecNssBlockCipherCtx));
+	return 0 ;
 }
 
-static int  
-xmlSecNssBlockCipherSetKeyReq(xmlSecTransformPtr transform,  xmlSecKeyReqPtr keyReq) {
-    xmlSecNssBlockCipherCtxPtr ctx;
 
-    xmlSecAssert2(xmlSecNssBlockCipherCheckId(transform), -1);
-    xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1);
-    xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecNssBlockCipherSize), -1);
-    xmlSecAssert2(keyReq != NULL, -1);
-
-    ctx = xmlSecNssBlockCipherGetCtx(transform);
-    xmlSecAssert2(ctx != NULL, -1);
-    xmlSecAssert2(ctx->keyId != NULL, -1);
-
-    keyReq->keyId 	= ctx->keyId;
-    keyReq->keyType 	= xmlSecKeyDataTypeSymmetric;
-    if(transform->operation == xmlSecTransformOperationEncrypt) {
-	keyReq->keyUsage = xmlSecKeyUsageEncrypt;
-    } else {
-	keyReq->keyUsage = xmlSecKeyUsageDecrypt;
-    }
-    keyReq->keyBitsSize = 8 * ctx->keySize;
-    return(0);
-}
 
+/**
+ * xmlSecTransformExecuteMethod:
+ * @transform:			the pointer to transform object.
+ * @last:			the flag: if set to 1 then it's the last data chunk.
+ * @transformCtx:		the pointer to transform context object.
+ *
+ * Transform specific method to process a chunk of data.
+ *
+ * Returns 0 on success or a negative value otherwise.
+ */
 static int
-xmlSecNssBlockCipherSetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key) {
-    xmlSecNssBlockCipherCtxPtr ctx;
-    xmlSecBufferPtr buffer;
-    
-    xmlSecAssert2(xmlSecNssBlockCipherCheckId(transform), -1);
-    xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1);
-    xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecNssBlockCipherSize), -1);
-    xmlSecAssert2(key != NULL, -1);
-
-    ctx = xmlSecNssBlockCipherGetCtx(transform);
-    xmlSecAssert2(ctx != NULL, -1);
-    xmlSecAssert2(ctx->cipher != 0, -1);
-    xmlSecAssert2(ctx->keyInitialized == 0, -1);
-    xmlSecAssert2(ctx->keyId != NULL, -1);
-    xmlSecAssert2(xmlSecKeyCheckId(key, ctx->keyId), -1);
-
-    xmlSecAssert2(ctx->keySize > 0, -1);
-    xmlSecAssert2(ctx->keySize <= sizeof(ctx->key), -1);
-
-    buffer = xmlSecKeyDataBinaryValueGetBuffer(xmlSecKeyGetValue(key));
-    xmlSecAssert2(buffer != NULL, -1);
-
-    if(xmlSecBufferGetSize(buffer) < ctx->keySize) {
-	xmlSecError(XMLSEC_ERRORS_HERE,
-		    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
-		    NULL,
-		    XMLSEC_ERRORS_R_INVALID_KEY_DATA_SIZE,
-		    "keySize=%d;expected=%d",
-		    xmlSecBufferGetSize(buffer), ctx->keySize);
-	return(-1);
-    }
-    
-    xmlSecAssert2(xmlSecBufferGetData(buffer) != NULL, -1);
-    memcpy(ctx->key, xmlSecBufferGetData(buffer), ctx->keySize);
-    
-    ctx->keyInitialized = 1;
-    return(0);
+xmlSecNssBlockCipherExecute(
+	xmlSecTransformPtr transform ,
+	int last ,
+	xmlSecTransformCtxPtr transformCtx
+) {
+	xmlSecNssBlockCipherCtxPtr 	context = NULL ;
+	xmlSecBufferPtr				inBuf = NULL ;
+	xmlSecBufferPtr				outBuf = NULL ;
+	const xmlChar*				cipherName ;
+	int							operation ;
+	int							rtv ;
+
+	xmlSecAssert2( xmlSecNssBlockCipherCheckId( transform ), -1 ) ;
+	xmlSecAssert2( xmlSecTransformCheckSize( transform, xmlSecNssBlockCipherSize ), -1 ) ;
+    xmlSecAssert2( ( transform->operation == xmlSecTransformOperationEncrypt ) || ( transform->operation == xmlSecTransformOperationDecrypt ), -1 ) ;
+	xmlSecAssert2( transformCtx != NULL , -1 ) ;
+
+	context = xmlSecNssBlockCipherGetCtx( transform ) ;
+	if( context == NULL ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+		    xmlSecErrorsSafeString( xmlSecTransformGetName( transform ) ) ,
+		    "xmlSecNssBlockCipherGetCtx" ,
+		    XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+		    XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return -1 ;    
+	}
+
+	inBuf = &( transform->inBuf ) ;
+	outBuf = &( transform->outBuf ) ;
+
+	if( transform->status == xmlSecTransformStatusNone ) {
+		transform->status = xmlSecTransformStatusWorking ;
+	}
+
+	operation = ( transform->operation == xmlSecTransformOperationEncrypt ) ? 1 : 0 ;
+	cipherName = xmlSecTransformGetName( transform ) ;
+
+	if( transform->status == xmlSecTransformStatusWorking ) {
+		if( context->cipherCtx == NULL ) {
+			rtv = xmlSecNssBlockCipherCtxInit( context, inBuf , outBuf , operation , cipherName , transformCtx ) ;
+			if( rtv < 0 ) {
+				xmlSecError( XMLSEC_ERRORS_HERE , 
+					xmlSecErrorsSafeString( xmlSecTransformGetName( transform ) ) ,
+					"xmlSecNssBlockCipherCtxInit" ,
+					XMLSEC_ERRORS_R_INVALID_STATUS ,
+					XMLSEC_ERRORS_NO_MESSAGE ) ;
+				return -1 ;
+			}
+		}
+
+		if( context->cipherCtx == NULL && last != 0 ) {
+			xmlSecError( XMLSEC_ERRORS_HERE , 
+				xmlSecErrorsSafeString( xmlSecTransformGetName( transform ) ) ,
+				NULL ,
+				XMLSEC_ERRORS_R_INVALID_STATUS ,
+				"No enough data to intialize transform" ) ;
+			return -1 ;
+		}
+
+		if( context->cipherCtx != NULL ) {
+			rtv = xmlSecNssBlockCipherCtxUpdate( context, inBuf , outBuf , operation , cipherName , transformCtx ) ;
+			if( rtv < 0 ) {
+				xmlSecError( XMLSEC_ERRORS_HERE , 
+					xmlSecErrorsSafeString( xmlSecTransformGetName( transform ) ) ,
+					"xmlSecNssBlockCipherCtxUpdate" ,
+					XMLSEC_ERRORS_R_INVALID_STATUS ,
+					XMLSEC_ERRORS_NO_MESSAGE ) ;
+				return -1 ;
+			}
+		}
+		
+		if( last ) {
+			rtv = xmlSecNssBlockCipherCtxFinal( context, inBuf , outBuf , operation , cipherName , transformCtx ) ;
+			if( rtv < 0 ) {
+				xmlSecError( XMLSEC_ERRORS_HERE , 
+					xmlSecErrorsSafeString( xmlSecTransformGetName( transform ) ) ,
+					"xmlSecNssBlockCipherCtxFinal" ,
+					XMLSEC_ERRORS_R_INVALID_STATUS ,
+					XMLSEC_ERRORS_NO_MESSAGE ) ;
+				return -1 ;
+			}
+			transform->status = xmlSecTransformStatusFinished ;
+		}
+	} else if( transform->status == xmlSecTransformStatusFinished ) {
+		if( xmlSecBufferGetSize( inBuf ) != 0 ) {
+			xmlSecError( XMLSEC_ERRORS_HERE , 
+				xmlSecErrorsSafeString( xmlSecTransformGetName( transform ) ) ,
+				NULL ,
+				XMLSEC_ERRORS_R_INVALID_STATUS ,
+				"status=%d", transform->status ) ;
+			return -1 ;
+		}
+	} else {
+		xmlSecError( XMLSEC_ERRORS_HERE , 
+			xmlSecErrorsSafeString( xmlSecTransformGetName( transform ) ) ,
+			NULL ,
+			XMLSEC_ERRORS_R_INVALID_STATUS ,
+			"status=%d", transform->status ) ;
+		return -1 ;
+	}
+
+	return 0 ;
 }
 
-static int 
-xmlSecNssBlockCipherExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) {
-    xmlSecNssBlockCipherCtxPtr ctx;
-    xmlSecBufferPtr in, out;
-    int ret;
-    
-    xmlSecAssert2(xmlSecNssBlockCipherCheckId(transform), -1);
-    xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1);
-    xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecNssBlockCipherSize), -1);
-    xmlSecAssert2(transformCtx != NULL, -1);
+static xmlSecTransformKlass xmlSecNssAes128CbcKlass = {
+	sizeof( xmlSecTransformKlass ) ,
+	xmlSecNssBlockCipherSize ,
 
-    in = &(transform->inBuf);
-    out = &(transform->outBuf);
+	xmlSecNameAes128Cbc ,
+	xmlSecHrefAes128Cbc ,
+	xmlSecTransformUsageEncryptionMethod ,
+
+	xmlSecNssBlockCipherInitialize ,
+	xmlSecNssBlockCipherFinalize ,
+	NULL ,
+	NULL ,
+
+	xmlSecNssBlockCipherSetKeyReq ,
+	xmlSecNssBlockCipherSetKey ,
+	NULL ,
+	xmlSecTransformDefaultGetDataType ,
+
+	xmlSecTransformDefaultPushBin ,
+	xmlSecTransformDefaultPopBin ,
+	NULL ,
+	NULL ,
+	xmlSecNssBlockCipherExecute ,
+
+	NULL ,
+	NULL
+} ;
 
-    ctx = xmlSecNssBlockCipherGetCtx(transform);
-    xmlSecAssert2(ctx != NULL, -1);
 
-    if(transform->status == xmlSecTransformStatusNone) {
-	transform->status = xmlSecTransformStatusWorking;
-    }
+static xmlSecTransformKlass xmlSecNssAes192CbcKlass = {
+	sizeof( xmlSecTransformKlass ) ,
+	xmlSecNssBlockCipherSize ,
 
-    if(transform->status == xmlSecTransformStatusWorking) {
-	if(ctx->ctxInitialized == 0) {
-	    ret = xmlSecNssBlockCipherCtxInit(ctx, in, out, 
-			(transform->operation == xmlSecTransformOperationEncrypt) ? 1 : 0,
-			xmlSecTransformGetName(transform), transformCtx);
-	    if(ret < 0) {
-		xmlSecError(XMLSEC_ERRORS_HERE, 
-			    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
-			    "xmlSecNssBlockCipherCtxInit",
-			    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-			    XMLSEC_ERRORS_NO_MESSAGE);
-		return(-1);
-	    }
-	}
-	if((ctx->ctxInitialized == 0) && (last != 0)) {
-	    xmlSecError(XMLSEC_ERRORS_HERE, 
-			xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
-			NULL,
-			XMLSEC_ERRORS_R_INVALID_DATA,
-			"not enough data to initialize transform");
-	    return(-1);
-	}
-
-	if(ctx->ctxInitialized != 0) {
-	    ret = xmlSecNssBlockCipherCtxUpdate(ctx, in, out, 
-			(transform->operation == xmlSecTransformOperationEncrypt) ? 1 : 0,
-			xmlSecTransformGetName(transform), transformCtx);
-	    if(ret < 0) {
-		xmlSecError(XMLSEC_ERRORS_HERE, 
-			    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
-			    "xmlSecNssBlockCipherCtxUpdate",
-			    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-			    XMLSEC_ERRORS_NO_MESSAGE);
-		return(-1);
-	    }
-	}
-	
-	if(last) {
-	    ret = xmlSecNssBlockCipherCtxFinal(ctx, in, out, 
-			(transform->operation == xmlSecTransformOperationEncrypt) ? 1 : 0,
-			xmlSecTransformGetName(transform), transformCtx);
-	    if(ret < 0) {
-		xmlSecError(XMLSEC_ERRORS_HERE, 
-			    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
-			    "xmlSecNssBlockCipherCtxFinal",
-			    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-			    XMLSEC_ERRORS_NO_MESSAGE);
-		return(-1);
-	    }
-	    transform->status = xmlSecTransformStatusFinished;
-	} 
-    } else if(transform->status == xmlSecTransformStatusFinished) {
-	/* the only way we can get here is if there is no input */
-	xmlSecAssert2(xmlSecBufferGetSize(in) == 0, -1);
-    } else if(transform->status == xmlSecTransformStatusNone) {
-	/* the only way we can get here is if there is no enough data in the input */
-	xmlSecAssert2(last == 0, -1);
-    } else {
-	xmlSecError(XMLSEC_ERRORS_HERE, 
-		    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
-		    NULL,
-		    XMLSEC_ERRORS_R_INVALID_STATUS,
-		    "status=%d", transform->status);
-	return(-1);
-    }
-    
-    return(0);
-}
+	xmlSecNameAes192Cbc ,
+	xmlSecHrefAes192Cbc ,
+	xmlSecTransformUsageEncryptionMethod ,
+
+	xmlSecNssBlockCipherInitialize ,
+	xmlSecNssBlockCipherFinalize ,
+	NULL ,
+	NULL ,
+
+	xmlSecNssBlockCipherSetKeyReq ,
+	xmlSecNssBlockCipherSetKey ,
+	NULL ,
+	xmlSecTransformDefaultGetDataType ,
+
+	xmlSecTransformDefaultPushBin ,
+	xmlSecTransformDefaultPopBin ,
+	NULL ,
+	NULL ,
+	xmlSecNssBlockCipherExecute ,
+
+	NULL ,
+	NULL
+} ;
 
 
-#ifndef XMLSEC_NO_AES
-/*********************************************************************
- *
- * AES CBC cipher transforms
- *
- ********************************************************************/
-static xmlSecTransformKlass xmlSecNssAes128CbcKlass = {
-    /* klass/object sizes */
-    sizeof(xmlSecTransformKlass),		/* xmlSecSize klassSize */
-    xmlSecNssBlockCipherSize,		/* xmlSecSize objSize */
-
-    xmlSecNameAes128Cbc,			/* const xmlChar* name; */
-    xmlSecHrefAes128Cbc,			/* const xmlChar* href; */
-    xmlSecTransformUsageEncryptionMethod,	/* xmlSecAlgorithmUsage usage; */
-
-    xmlSecNssBlockCipherInitialize, 		/* xmlSecTransformInitializeMethod initialize; */
-    xmlSecNssBlockCipherFinalize,		/* xmlSecTransformFinalizeMethod finalize; */
-    NULL,					/* xmlSecTransformNodeReadMethod readNode; */
-    NULL,					/* xmlSecTransformNodeWriteMethod writeNode; */
-    xmlSecNssBlockCipherSetKeyReq,		/* xmlSecTransformSetKeyMethod setKeyReq; */
-    xmlSecNssBlockCipherSetKey,		/* xmlSecTransformSetKeyMethod setKey; */
-    NULL,					/* xmlSecTransformValidateMethod validate; */
-    xmlSecTransformDefaultGetDataType,		/* xmlSecTransformGetDataTypeMethod getDataType; */
-    xmlSecTransformDefaultPushBin,		/* xmlSecTransformPushBinMethod pushBin; */
-    xmlSecTransformDefaultPopBin,		/* xmlSecTransformPopBinMethod popBin; */
-    NULL,					/* xmlSecTransformPushXmlMethod pushXml; */
-    NULL,					/* xmlSecTransformPopXmlMethod popXml; */
-    xmlSecNssBlockCipherExecute,		/* xmlSecTransformExecuteMethod execute; */
-
-    NULL,					/* void* reserved0; */
-    NULL,					/* void* reserved1; */
-};
+static xmlSecTransformKlass xmlSecNssAes256CbcKlass = {
+	sizeof( xmlSecTransformKlass ) ,
+	xmlSecNssBlockCipherSize ,
 
-/**
- * xmlSecNssTransformAes128CbcGetKlass:
- * 
- * AES 128 CBC encryption transform klass.
- * 
- * Returns pointer to AES 128 CBC encryption transform.
- */ 
-xmlSecTransformId 
-xmlSecNssTransformAes128CbcGetKlass(void) {
-    return(&xmlSecNssAes128CbcKlass);
-}
+	xmlSecNameAes256Cbc ,
+	xmlSecHrefAes256Cbc ,
+	xmlSecTransformUsageEncryptionMethod ,
+
+	xmlSecNssBlockCipherInitialize ,
+	xmlSecNssBlockCipherFinalize ,
+	NULL ,
+	NULL ,
+
+	xmlSecNssBlockCipherSetKeyReq ,
+	xmlSecNssBlockCipherSetKey ,
+	NULL ,
+	xmlSecTransformDefaultGetDataType ,
+
+	xmlSecTransformDefaultPushBin ,
+	xmlSecTransformDefaultPopBin ,
+	NULL ,
+	NULL ,
+	xmlSecNssBlockCipherExecute ,
+
+	NULL ,
+	NULL
+} ;
 
-static xmlSecTransformKlass xmlSecNssAes192CbcKlass = {
-    /* klass/object sizes */
-    sizeof(xmlSecTransformKlass),		/* xmlSecSize klassSize */
-    xmlSecNssBlockCipherSize,		/* xmlSecSize objSize */
-
-    xmlSecNameAes192Cbc,			/* const xmlChar* name; */
-    xmlSecHrefAes192Cbc,			/* const xmlChar* href; */
-    xmlSecTransformUsageEncryptionMethod,	/* xmlSecAlgorithmUsage usage; */
-
-    xmlSecNssBlockCipherInitialize, 		/* xmlSecTransformInitializeMethod initialize; */
-    xmlSecNssBlockCipherFinalize,		/* xmlSecTransformFinalizeMethod finalize; */
-    NULL,					/* xmlSecTransformNodeReadMethod readNode; */
-    NULL,					/* xmlSecTransformNodeWriteMethod writeNode; */
-    xmlSecNssBlockCipherSetKeyReq,		/* xmlSecTransformSetKeyMethod setKeyReq; */
-    xmlSecNssBlockCipherSetKey,		/* xmlSecTransformSetKeyMethod setKey; */
-    NULL,					/* xmlSecTransformValidateMethod validate; */
-    xmlSecTransformDefaultGetDataType,		/* xmlSecTransformGetDataTypeMethod getDataType; */
-    xmlSecTransformDefaultPushBin,		/* xmlSecTransformPushBinMethod pushBin; */
-    xmlSecTransformDefaultPopBin,		/* xmlSecTransformPopBinMethod popBin; */
-    NULL,					/* xmlSecTransformPushXmlMethod pushXml; */
-    NULL,					/* xmlSecTransformPopXmlMethod popXml; */
-    xmlSecNssBlockCipherExecute,		/* xmlSecTransformExecuteMethod execute; */
-    
-    NULL,					/* void* reserved0; */
-    NULL,					/* void* reserved1; */
-};
+static xmlSecTransformKlass xmlSecNssDes3CbcKlass = {
+	sizeof( xmlSecTransformKlass ) ,
+	xmlSecNssBlockCipherSize ,
+
+	xmlSecNameDes3Cbc ,
+	xmlSecHrefDes3Cbc ,
+	xmlSecTransformUsageEncryptionMethod ,
+
+	xmlSecNssBlockCipherInitialize ,
+	xmlSecNssBlockCipherFinalize ,
+	NULL ,
+	NULL ,
+
+	xmlSecNssBlockCipherSetKeyReq ,
+	xmlSecNssBlockCipherSetKey ,
+	NULL ,
+	xmlSecTransformDefaultGetDataType ,
+
+	xmlSecTransformDefaultPushBin ,
+	xmlSecTransformDefaultPopBin ,
+	NULL ,
+	NULL ,
+	xmlSecNssBlockCipherExecute ,
+
+	NULL ,
+	NULL
+} ;
 
 /**
- * xmlSecNssTransformAes192CbcGetKlass:
- * 
- * AES 192 CBC encryption transform klass.
- * 
- * Returns pointer to AES 192 CBC encryption transform.
- */ 
-xmlSecTransformId 
-xmlSecNssTransformAes192CbcGetKlass(void) {
-    return(&xmlSecNssAes192CbcKlass);
+ * xmlSecNssTransformAes128CbcGetKlass
+ *
+ * Get the AES128_CBC transform klass
+ *
+ * Return AES128_CBC transform klass
+ */
+xmlSecTransformId
+xmlSecNssTransformAes128CbcGetKlass( void ) {
+	return ( &xmlSecNssAes128CbcKlass ) ;
 }
 
-static xmlSecTransformKlass xmlSecNssAes256CbcKlass = {
-    /* klass/object sizes */
-    sizeof(xmlSecTransformKlass),		/* xmlSecSize klassSize */
-    xmlSecNssBlockCipherSize,		/* xmlSecSize objSize */
-
-    xmlSecNameAes256Cbc,			/* const xmlChar* name; */
-    xmlSecHrefAes256Cbc,			/* const xmlChar* href; */
-    xmlSecTransformUsageEncryptionMethod,	/* xmlSecAlgorithmUsage usage; */
-
-    xmlSecNssBlockCipherInitialize, 		/* xmlSecTransformInitializeMethod initialize; */
-    xmlSecNssBlockCipherFinalize,		/* xmlSecTransformFinalizeMethod finalize; */
-    NULL,					/* xmlSecTransformNodeReadMethod readNode; */
-    NULL,					/* xmlSecTransformNodeWriteMethod writeNode; */
-    xmlSecNssBlockCipherSetKeyReq,		/* xmlSecTransformSetKeyMethod setKeyReq; */
-    xmlSecNssBlockCipherSetKey,		/* xmlSecTransformSetKeyMethod setKey; */
-    NULL,					/* xmlSecTransformValidateMethod validate; */
-    xmlSecTransformDefaultGetDataType,		/* xmlSecTransformGetDataTypeMethod getDataType; */
-    xmlSecTransformDefaultPushBin,		/* xmlSecTransformPushBinMethod pushBin; */
-    xmlSecTransformDefaultPopBin,		/* xmlSecTransformPopBinMethod popBin; */
-    NULL,					/* xmlSecTransformPushXmlMethod pushXml; */
-    NULL,					/* xmlSecTransformPopXmlMethod popXml; */
-    xmlSecNssBlockCipherExecute,		/* xmlSecTransformExecuteMethod execute; */
-    
-    NULL,					/* void* reserved0; */
-    NULL,					/* void* reserved1; */
-};
-
 /**
- * xmlSecNssTransformAes256CbcGetKlass:
- * 
- * AES 256 CBC encryption transform klass.
- * 
- * Returns pointer to AES 256 CBC encryption transform.
- */ 
-xmlSecTransformId 
-xmlSecNssTransformAes256CbcGetKlass(void) {
-    return(&xmlSecNssAes256CbcKlass);
+ * xmlSecNssTransformAes192CbcGetKlass
+ *
+ * Get the AES192_CBC transform klass
+ *
+ * Return AES192_CBC transform klass
+ */
+xmlSecTransformId
+xmlSecNssTransformAes192CbcGetKlass( void ) {
+	return ( &xmlSecNssAes192CbcKlass ) ;
 }
 
-#endif /* XMLSEC_NO_AES */
-
-#ifndef XMLSEC_NO_DES
-static xmlSecTransformKlass xmlSecNssDes3CbcKlass = {
-    /* klass/object sizes */
-    sizeof(xmlSecTransformKlass),		/* xmlSecSize klassSize */
-    xmlSecNssBlockCipherSize,		/* xmlSecSize objSize */
-
-    xmlSecNameDes3Cbc,				/* const xmlChar* name; */
-    xmlSecHrefDes3Cbc, 				/* const xmlChar* href; */
-    xmlSecTransformUsageEncryptionMethod,	/* xmlSecAlgorithmUsage usage; */
-
-    xmlSecNssBlockCipherInitialize, 		/* xmlSecTransformInitializeMethod initialize; */
-    xmlSecNssBlockCipherFinalize,		/* xmlSecTransformFinalizeMethod finalize; */
-    NULL,					/* xmlSecTransformNodeReadMethod readNode; */
-    NULL,					/* xmlSecTransformNodeWriteMethod writeNode; */
-    xmlSecNssBlockCipherSetKeyReq,		/* xmlSecTransformSetKeyMethod setKeyReq; */
-    xmlSecNssBlockCipherSetKey,		/* xmlSecTransformSetKeyMethod setKey; */
-    NULL,					/* xmlSecTransformValidateMethod validate; */
-    xmlSecTransformDefaultGetDataType,		/* xmlSecTransformGetDataTypeMethod getDataType; */
-    xmlSecTransformDefaultPushBin,		/* xmlSecTransformPushBinMethod pushBin; */
-    xmlSecTransformDefaultPopBin,		/* xmlSecTransformPopBinMethod popBin; */
-    NULL,					/* xmlSecTransformPushXmlMethod pushXml; */
-    NULL,					/* xmlSecTransformPopXmlMethod popXml; */
-    xmlSecNssBlockCipherExecute,		/* xmlSecTransformExecuteMethod execute; */
-    
-    NULL,					/* void* reserved0; */
-    NULL,					/* void* reserved1; */
-};
+/**
+ * xmlSecNssTransformAes256CbcGetKlass
+ *
+ * Get the AES256_CBC transform klass
+ *
+ * Return AES256_CBC transform klass
+ */
+xmlSecTransformId
+xmlSecNssTransformAes256CbcGetKlass( void ) {
+	return ( &xmlSecNssAes256CbcKlass ) ;
+}
 
-/** 
- * xmlSecNssTransformDes3CbcGetKlass:
+/**
+ * xmlSecNssTransformDes3CbcGetKlass
  *
- * Triple DES CBC encryption transform klass.
- * 
- * Returns pointer to Triple DES encryption transform.
+ * Get the DES3_CBC transform klass
+ *
+ * Return DES3_CBC transform klass
  */
-xmlSecTransformId 
-xmlSecNssTransformDes3CbcGetKlass(void) {
-    return(&xmlSecNssDes3CbcKlass);
+xmlSecTransformId
+xmlSecNssTransformDes3CbcGetKlass( void ) {
+	return ( &xmlSecNssDes3CbcKlass ) ;
 }
-#endif /* XMLSEC_NO_DES */
+
 
Index: xmlsec/src/nss/crypto.c
===================================================================
RCS file: /cvs/gnome/xmlsec/src/nss/crypto.c,v
retrieving revision 1.27
diff -u -r1.27 crypto.c
--- xmlsec/src/nss/crypto.c	29 Oct 2003 15:57:25 -0000	1.27
+++ xmlsec/src/nss/crypto.c	6 Feb 2005 03:53:20 -0000
@@ -130,23 +130,23 @@
     /**
      * High level routines form xmlsec command line utility
      */ 
-    gXmlSecNssFunctions->cryptoAppInit 			= xmlSecNssAppInit;
-    gXmlSecNssFunctions->cryptoAppShutdown 		= xmlSecNssAppShutdown;
-    gXmlSecNssFunctions->cryptoAppDefaultKeysMngrInit 	= xmlSecNssAppDefaultKeysMngrInit;
-    gXmlSecNssFunctions->cryptoAppDefaultKeysMngrAdoptKey 	= xmlSecNssAppDefaultKeysMngrAdoptKey;
-    gXmlSecNssFunctions->cryptoAppDefaultKeysMngrLoad 	= xmlSecNssAppDefaultKeysMngrLoad;
-    gXmlSecNssFunctions->cryptoAppDefaultKeysMngrSave 	= xmlSecNssAppDefaultKeysMngrSave;
+    gXmlSecNssFunctions->cryptoAppInit 			= NULL ;
+    gXmlSecNssFunctions->cryptoAppShutdown 		= NULL ;
+    gXmlSecNssFunctions->cryptoAppDefaultKeysMngrInit 	= NULL ;
+    gXmlSecNssFunctions->cryptoAppDefaultKeysMngrAdoptKey 	= NULL ;
+    gXmlSecNssFunctions->cryptoAppDefaultKeysMngrLoad 	= NULL ;
+    gXmlSecNssFunctions->cryptoAppDefaultKeysMngrSave 	= NULL ;
 #ifndef XMLSEC_NO_X509
-    gXmlSecNssFunctions->cryptoAppKeysMngrCertLoad 	= xmlSecNssAppKeysMngrCertLoad;
-    gXmlSecNssFunctions->cryptoAppKeysMngrCertLoadMemory= xmlSecNssAppKeysMngrCertLoadMemory;
-    gXmlSecNssFunctions->cryptoAppPkcs12Load  		= xmlSecNssAppPkcs12Load; 
-    gXmlSecNssFunctions->cryptoAppPkcs12LoadMemory	= xmlSecNssAppPkcs12LoadMemory; 
-    gXmlSecNssFunctions->cryptoAppKeyCertLoad 		= xmlSecNssAppKeyCertLoad;
-    gXmlSecNssFunctions->cryptoAppKeyCertLoadMemory	= xmlSecNssAppKeyCertLoadMemory;
+    gXmlSecNssFunctions->cryptoAppKeysMngrCertLoad 	= NULL ;
+    gXmlSecNssFunctions->cryptoAppKeysMngrCertLoadMemory= NULL ;
+    gXmlSecNssFunctions->cryptoAppPkcs12Load  		= NULL ; 
+    gXmlSecNssFunctions->cryptoAppPkcs12LoadMemory	= NULL ; 
+    gXmlSecNssFunctions->cryptoAppKeyCertLoad 		= NULL ;
+    gXmlSecNssFunctions->cryptoAppKeyCertLoadMemory	= NULL ;
 #endif /* XMLSEC_NO_X509 */
-    gXmlSecNssFunctions->cryptoAppKeyLoad 		= xmlSecNssAppKeyLoad; 
-    gXmlSecNssFunctions->cryptoAppKeyLoadMemory		= xmlSecNssAppKeyLoadMemory; 
-    gXmlSecNssFunctions->cryptoAppDefaultPwdCallback	= (void*)xmlSecNssAppGetDefaultPwdCallback;
+    gXmlSecNssFunctions->cryptoAppKeyLoad 		= NULL ; 
+    gXmlSecNssFunctions->cryptoAppKeyLoadMemory		= NULL ; 
+    gXmlSecNssFunctions->cryptoAppDefaultPwdCallback	= (void*)NULL ;
 
     return(gXmlSecNssFunctions);
 }
Index: xmlsec/src/nss/digests.c
===================================================================
RCS file: /cvs/gnome/xmlsec/src/nss/digests.c,v
retrieving revision 1.18
diff -u -r1.18 digests.c
--- xmlsec/src/nss/digests.c	26 Sep 2003 00:58:15 -0000	1.18
+++ xmlsec/src/nss/digests.c	6 Feb 2005 03:53:20 -0000
@@ -21,7 +21,6 @@
 #include <xmlsec/transforms.h>
 #include <xmlsec/errors.h>
 
-#include <xmlsec/nss/app.h>
 #include <xmlsec/nss/crypto.h>
 
 #define XMLSEC_NSS_MAX_DIGEST_SIZE		32
@@ -107,7 +106,7 @@
 		    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
 		    "SECOID_FindOIDByTag",
 		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-		    XMLSEC_ERRORS_NO_MESSAGE);
+		    "error code=%d", PORT_GetError());
 	return(-1);
     }
     
@@ -117,7 +116,7 @@
 		    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
 		    "PK11_CreateDigestContext",
 		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-		    XMLSEC_ERRORS_NO_MESSAGE);
+		    "error code=%d", PORT_GetError());
 	return(-1);
     }
 	
@@ -208,7 +207,7 @@
 			xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
 			"PK11_DigestBegin",
 			XMLSEC_ERRORS_R_CRYPTO_FAILED,
-			XMLSEC_ERRORS_NO_MESSAGE);
+			"error code=%d", PORT_GetError());
 	    return(-1);
 	}
 	transform->status = xmlSecTransformStatusWorking;
@@ -225,7 +224,7 @@
 			    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
 			    "PK11_DigestOp",
 			    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-			    XMLSEC_ERRORS_NO_MESSAGE);
+			    "error code=%d", PORT_GetError());
 		return(-1);
 	    }
 	    
@@ -246,7 +245,7 @@
 			    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
 			    "PK11_DigestFinal",
 			    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-			    XMLSEC_ERRORS_NO_MESSAGE);
+			    "error code=%d", PORT_GetError());
 		return(-1);
 	    }
 	    xmlSecAssert2(ctx->dgstSize > 0, -1);
Index: xmlsec/src/nss/hmac.c
===================================================================
RCS file: /cvs/gnome/xmlsec/src/nss/hmac.c,v
retrieving revision 1.21
diff -u -r1.21 hmac.c
--- xmlsec/src/nss/hmac.c	26 Sep 2003 00:58:15 -0000	1.21
+++ xmlsec/src/nss/hmac.c	6 Feb 2005 03:53:21 -0000
@@ -23,8 +23,8 @@
 #include <xmlsec/transforms.h>
 #include <xmlsec/errors.h>
 
-#include <xmlsec/nss/app.h>
 #include <xmlsec/nss/crypto.h>
+#include <xmlsec/nss/tokens.h>
 
 #define XMLSEC_NSS_MAX_HMAC_SIZE		128
 
@@ -241,13 +241,13 @@
     keyItem.data = xmlSecBufferGetData(buffer);
     keyItem.len  = xmlSecBufferGetSize(buffer); 
 
-    slot = PK11_GetBestSlot(ctx->digestType, NULL);
+    slot = xmlSecNssSlotGet(ctx->digestType);
     if(slot == NULL) {
 	xmlSecError(XMLSEC_ERRORS_HERE, 
 		    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
-		    "PK11_GetBestSlot",
+		    "xmlSecNssSlotGet",
 		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-		    XMLSEC_ERRORS_NO_MESSAGE);
+		    "error code=%d", PORT_GetError());
 	return(-1);
     }
 	
@@ -258,7 +258,7 @@
 		    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
 		    "PK11_ImportSymKey",
 		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-		    XMLSEC_ERRORS_NO_MESSAGE);
+		    "error code=%d", PORT_GetError());
         PK11_FreeSlot(slot);
 	return(-1);
     }
@@ -269,7 +269,7 @@
 		    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
 		    "PK11_CreateContextBySymKey",
 		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-		    XMLSEC_ERRORS_NO_MESSAGE);
+		    "error code=%d", PORT_GetError());
 	PK11_FreeSymKey(symKey);
         PK11_FreeSlot(slot);
 	return(-1);
@@ -368,7 +368,7 @@
 			xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
 			"PK11_DigestBegin",
 			XMLSEC_ERRORS_R_CRYPTO_FAILED,
-			XMLSEC_ERRORS_NO_MESSAGE);
+			"error code=%d", PORT_GetError());
 	    return(-1);
 	}
 	transform->status = xmlSecTransformStatusWorking;
@@ -385,7 +385,7 @@
 			    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
 			    "PK11_DigestOp",
 			    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-			    XMLSEC_ERRORS_NO_MESSAGE);
+			    "error code=%d", PORT_GetError());
 		return(-1);
 	    }
 	    
@@ -408,7 +408,7 @@
 			    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
 			    "PK11_DigestFinal",
 			    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-			    XMLSEC_ERRORS_NO_MESSAGE);
+			    "error code=%d", PORT_GetError());
 		return(-1);
 	    }
 	    xmlSecAssert2(dgstSize > 0, -1);
Index: xmlsec/src/nss/keysstore.c
===================================================================
RCS file: /cvs/gnome/xmlsec/src/nss/keysstore.c,v
retrieving revision 1.3
diff -u -r1.3 keysstore.c
--- xmlsec/src/nss/keysstore.c	26 Sep 2003 00:58:15 -0000	1.3
+++ xmlsec/src/nss/keysstore.c	6 Feb 2005 03:53:21 -0000
@@ -16,104 +16,511 @@
  * 
  * Copyright (c) 2003 America Online, Inc.  All rights reserved.
  */
+/**
+ * NSS key store uses a key list and a slot list as the key repository. NSS slot
+ * list is a backup repository for the finding keys. If a key is not found from
+ * the key list, the NSS slot list is looked up.
+ *
+ * Any key in the key list will not save to pkcs11 slot. When a store to called
+ * to adopt a key, the key is resident in the key list; While a store to called
+ * to set a is resident in the key list; While a store to called to set a slot 
+ * list, which means that the keys in the listed slot can be used for xml sign-
+ * nature or encryption.
+ *
+ * Then, a user can adjust slot list to effect the crypto behaviors of xmlSec.
+ *
+ * The framework will decrease the user interfaces to administrate xmlSec crypto
+ * engine. He can only focus on NSS layer functions. For examples, after the
+ * user set up a slot list handler to the keys store, he do not need to do any
+ * other work atop xmlSec interfaces, his action on the slot list handler, such
+ * as add a token to, delete a token from the list, will directly effect the key
+ * store behaviors.
+ *
+ * For example, a scenariio:
+ * 0. Create a slot list;( NSS interfaces )
+ * 1. Create a keys store;( xmlSec interfaces )
+ * 2. Set slot list with the keys store;( xmlSec Interfaces )
+ * 3. Add a slot to the slot list;( NSS interfaces )
+ * 4. Perform xml signature; ( xmlSec Interfaces )
+ * 5. Deleter a slot from the slot list;( NSS interfaces )
+ * 6. Perform xml encryption; ( xmlSec Interfaces )
+ * 7. Perform xml signature;( xmlSec Interfaces )
+ * 8. Destroy the keys store;( xmlSec Interfaces )
+ * 8. Destroy the slot list.( NSS Interfaces )
+ */
 #include "globals.h"
-
-#include <stdlib.h>
 #include <string.h>
 
-#include <nss.h> 
-#include <cert.h> 
-#include <pk11func.h> 
-#include <keyhi.h> 
+#include <nss.h>
+#include <pk11func.h>
+#include <prinit.h>
+#include <keyhi.h>
 
-#include <libxml/tree.h> 
 
 #include <xmlsec/xmlsec.h>
-#include <xmlsec/buffer.h>
-#include <xmlsec/base64.h>
-#include <xmlsec/errors.h>
-#include <xmlsec/xmltree.h>
-
+#include <xmlsec/keys.h>
 #include <xmlsec/keysmngr.h>
+#include <xmlsec/transforms.h>
+#include <xmlsec/xmltree.h>
+#include <xmlsec/errors.h>
 
 #include <xmlsec/nss/crypto.h>
 #include <xmlsec/nss/keysstore.h>
-#include <xmlsec/nss/x509.h>
+#include <xmlsec/nss/tokens.h>
+#include <xmlsec/nss/ciphers.h>
 #include <xmlsec/nss/pkikeys.h>
 
-/****************************************************************************
+/**
+ * Internal NSS key store context
  *
- * Nss Keys Store. Uses Simple Keys Store under the hood
- * 
- * Simple Keys Store ptr is located after xmlSecKeyStore
+ * This context is located after xmlSecKeyStore
+ */
+typedef struct _xmlSecNssKeysStoreCtx	xmlSecNssKeysStoreCtx ;
+typedef struct _xmlSecNssKeysStoreCtx*	xmlSecNssKeysStoreCtxPtr ;
+
+struct _xmlSecNssKeysStoreCtx {
+	xmlSecPtrListPtr		keyList ;
+	xmlSecPtrListPtr		slotList ;
+} ;
+
+#define xmlSecNssKeysStoreSize	\
+	( sizeof( xmlSecKeyStore ) + sizeof( xmlSecNssKeysStoreCtx ) )
+
+#define xmlSecNssKeysStoreGetCtx( data ) \
+	( ( xmlSecNssKeysStoreCtxPtr )( ( ( xmlSecByte* )( data ) ) + sizeof( xmlSecKeyStore ) ) )
+
+int xmlSecNssKeysStoreAdoptKeySlot(
+	xmlSecKeyStorePtr		store ,
+	xmlSecNssKeySlotPtr		keySlot
+) {
+	xmlSecNssKeysStoreCtxPtr context = NULL ;
+
+	xmlSecAssert2( xmlSecKeyStoreCheckId( store , xmlSecNssKeysStoreId ) , -1 ) ;
+	xmlSecAssert2( xmlSecKeyStoreCheckSize( store , xmlSecNssKeysStoreSize ) , -1 ) ;
+
+	context = xmlSecNssKeysStoreGetCtx( store ) ;
+	if( context == NULL ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+			xmlSecErrorsSafeString( xmlSecKeyStoreGetName( store ) ) ,
+			"xmlSecNssKeysStoreGetCtx" ,
+			XMLSEC_ERRORS_R_XMLSEC_FAILED ,
+			XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return -1 ;
+	}
+
+	if( context->slotList == NULL ) {
+		if( ( context->slotList = xmlSecPtrListCreate( xmlSecNssKeySlotListId ) ) == NULL ) {
+			xmlSecError( XMLSEC_ERRORS_HERE ,
+				xmlSecErrorsSafeString( xmlSecKeyStoreGetName( store ) ) ,
+				"xmlSecPtrListCreate" ,
+				XMLSEC_ERRORS_R_XMLSEC_FAILED ,
+				XMLSEC_ERRORS_NO_MESSAGE ) ;
+			return -1 ;
+		}
+	}
+
+	if( !xmlSecPtrListCheckId( context->slotList , xmlSecNssKeySlotListId ) ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+			xmlSecErrorsSafeString( xmlSecKeyStoreGetName( store ) ) ,
+			"xmlSecPtrListCheckId" ,
+			XMLSEC_ERRORS_R_XMLSEC_FAILED ,
+			XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return -1 ;
+	}
+
+	if( xmlSecPtrListAdd( context->slotList , keySlot ) < 0 ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+			xmlSecErrorsSafeString( xmlSecKeyStoreGetName( store ) ) ,
+			"xmlSecPtrListAdd" ,
+			XMLSEC_ERRORS_R_XMLSEC_FAILED ,
+			XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return -1 ;
+	}
+
+	return 0 ;
+}
+
+int xmlSecNssKeysStoreAdoptKey(
+	xmlSecKeyStorePtr	store ,
+	xmlSecKeyPtr		key
+) {
+	xmlSecNssKeysStoreCtxPtr context = NULL ;
+
+	xmlSecAssert2( xmlSecKeyStoreCheckId( store , xmlSecNssKeysStoreId ) , -1 ) ;
+	xmlSecAssert2( xmlSecKeyStoreCheckSize( store , xmlSecNssKeysStoreSize ) , -1 ) ;
+
+	context = xmlSecNssKeysStoreGetCtx( store ) ;
+	if( context == NULL ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+			xmlSecErrorsSafeString( xmlSecKeyStoreGetName( store ) ) ,
+			"xmlSecNssKeysStoreGetCtx" ,
+			XMLSEC_ERRORS_R_XMLSEC_FAILED ,
+			XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return -1 ;
+	}
+
+	if( context->keyList == NULL ) {
+		if( ( context->keyList = xmlSecPtrListCreate( xmlSecKeyPtrListId ) ) == NULL ) {
+			xmlSecError( XMLSEC_ERRORS_HERE ,
+				xmlSecErrorsSafeString( xmlSecKeyStoreGetName( store ) ) ,
+				"xmlSecPtrListCreate" ,
+				XMLSEC_ERRORS_R_XMLSEC_FAILED ,
+				XMLSEC_ERRORS_NO_MESSAGE ) ;
+			return -1 ;
+		}
+	}
+
+	if( !xmlSecPtrListCheckId( context->keyList , xmlSecKeyPtrListId ) ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+			xmlSecErrorsSafeString( xmlSecKeyStoreGetName( store ) ) ,
+			"xmlSecPtrListCheckId" ,
+			XMLSEC_ERRORS_R_XMLSEC_FAILED ,
+			XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return -1 ;
+	}
+
+	if( xmlSecPtrListAdd( context->keyList , key ) < 0 ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+			xmlSecErrorsSafeString( xmlSecKeyStoreGetName( store ) ) ,
+			"xmlSecPtrListAdd" ,
+			XMLSEC_ERRORS_R_XMLSEC_FAILED ,
+			XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return -1 ;
+	}
+
+	return 0 ;
+}
+
+/** 
+ * xmlSecKeyStoreInitializeMethod:
+ * @store: 		the store.
+ *
+ * Keys store specific initialization method.
  *
- ***************************************************************************/
-#define xmlSecNssKeysStoreSize \
-	(sizeof(xmlSecKeyStore) + sizeof(xmlSecKeyStorePtr))
-
-#define xmlSecNssKeysStoreGetSS(store) \
-    ((xmlSecKeyStoreCheckSize((store), xmlSecNssKeysStoreSize)) ? \
-     (xmlSecKeyStorePtr*)(((xmlSecByte*)(store)) + sizeof(xmlSecKeyStore)) : \
-     (xmlSecKeyStorePtr*)NULL)
-
-static int			xmlSecNssKeysStoreInitialize	(xmlSecKeyStorePtr store);
-static void			xmlSecNssKeysStoreFinalize	(xmlSecKeyStorePtr store);
-static xmlSecKeyPtr 		xmlSecNssKeysStoreFindKey	(xmlSecKeyStorePtr store, 
-								 const xmlChar* name, 
-								 xmlSecKeyInfoCtxPtr keyInfoCtx);
+ * Returns 0 on success or a negative value if an error occurs.
+ */
+static int
+xmlSecNssKeysStoreInitialize(
+	xmlSecKeyStorePtr store
+) {
+	xmlSecNssKeysStoreCtxPtr context = NULL ;
+
+	xmlSecAssert2( xmlSecKeyStoreCheckId( store , xmlSecNssKeysStoreId ) , -1 ) ;
+	xmlSecAssert2( xmlSecKeyStoreCheckSize( store , xmlSecNssKeysStoreSize ) , -1 ) ;
+
+	context = xmlSecNssKeysStoreGetCtx( store ) ;
+	if( context == NULL ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+			xmlSecErrorsSafeString( xmlSecKeyStoreGetName( store ) ) ,
+			"xmlSecNssKeysStoreGetCtx" ,
+			XMLSEC_ERRORS_R_XMLSEC_FAILED ,
+			XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return -1 ;
+	}
 
-static xmlSecKeyStoreKlass xmlSecNssKeysStoreKlass = {
-    sizeof(xmlSecKeyStoreKlass),
-    xmlSecNssKeysStoreSize,
+	context->keyList = NULL ;
+	context->slotList = NULL ;
 
-    /* data */
-    BAD_CAST "NSS-keys-store",		/* const xmlChar* name; */ 
-        
-    /* constructors/destructor */
-    xmlSecNssKeysStoreInitialize,	/* xmlSecKeyStoreInitializeMethod initialize; */
-    xmlSecNssKeysStoreFinalize,		/* xmlSecKeyStoreFinalizeMethod finalize; */
-    xmlSecNssKeysStoreFindKey,		/* xmlSecKeyStoreFindKeyMethod findKey; */
-
-    /* reserved for the future */
-    NULL,				/* void* reserved0; */
-    NULL,				/* void* reserved1; */
-};
+	return 0 ;
+}
 
-/**
- * xmlSecNssKeysStoreGetKlass:
- * 
- * The Nss list based keys store klass.
+/** 
+ * xmlSecKeyStoreFinalizeMethod:
+ * @store: 		the store.
  *
- * Returns Nss list based keys store klass.
+ * Keys store specific finalization (destroy) method.
  */
-xmlSecKeyStoreId 
-xmlSecNssKeysStoreGetKlass(void) {
-    return(&xmlSecNssKeysStoreKlass);
+void
+xmlSecNssKeysStoreFinalize(
+	xmlSecKeyStorePtr store
+) {
+	xmlSecNssKeysStoreCtxPtr context = NULL ;
+
+	xmlSecAssert( xmlSecKeyStoreCheckId( store , xmlSecNssKeysStoreId ) ) ;
+	xmlSecAssert( xmlSecKeyStoreCheckSize( store , xmlSecNssKeysStoreSize ) ) ;
+
+	context = xmlSecNssKeysStoreGetCtx( store ) ;
+	if( context == NULL ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+			xmlSecErrorsSafeString( xmlSecKeyStoreGetName( store ) ) ,
+			"xmlSecNssKeysStoreGetCtx" ,
+			XMLSEC_ERRORS_R_XMLSEC_FAILED ,
+			XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return ;
+	}
+
+	if( context->keyList != NULL ) {
+		xmlSecPtrListDestroy( context->keyList ) ;
+		context->keyList = NULL ;
+	}
+
+	if( context->slotList != NULL ) {
+		xmlSecPtrListDestroy( context->slotList ) ;
+		context->slotList = NULL ;
+	}
 }
 
-/**
- * xmlSecNssKeysStoreAdoptKey:
- * @store:		the pointer to Nss keys store.
- * @key:		the pointer to key.
- * 
- * Adds @key to the @store. 
+xmlSecKeyPtr
+xmlSecNssKeysStoreFindKeyFromSlot(
+	PK11SlotInfo* slot,
+	const xmlChar* name,
+	xmlSecKeyInfoCtxPtr keyInfoCtx
+) {
+	xmlSecKeyPtr		key = NULL ;
+	xmlSecKeyDataPtr	data = NULL ;
+	int					length ;
+
+	xmlSecAssert2( slot != NULL , NULL ) ;
+	xmlSecAssert2( name != NULL , NULL ) ;
+	xmlSecAssert2( keyInfoCtx != NULL , NULL ) ;
+
+	if( ( keyInfoCtx->keyReq.keyType & xmlSecKeyDataTypeSymmetric ) == xmlSecKeyDataTypeSymmetric ) {
+		PK11SymKey*			symKey ;
+		PK11SymKey*			curKey ;
+
+		/* Find symmetric key from the slot by name */
+		symKey = PK11_ListFixedKeysInSlot( slot , ( char* )name , NULL ) ;
+		for( curKey = symKey ; curKey != NULL ; curKey = PK11_GetNextSymKey( curKey ) ) {
+			/* Check the key request */
+			length = PK11_GetKeyLength( curKey ) ;
+			length *= 8 ;
+			if( ( keyInfoCtx->keyReq.keyBitsSize > 0 ) &&
+				( length > 0 ) &&
+				( length < keyInfoCtx->keyReq.keyBitsSize ) )
+				continue ;
+
+			/* We find a eligible key */
+			data = xmlSecNssSymKeyDataKeyAdopt( curKey ) ;
+			if( data == NULL ) {
+				/* Do nothing */
+			}
+			break ;
+		}
+
+		/* Destroy the sym key list */
+		for( curKey = symKey ; curKey != NULL ; ) {
+			symKey = curKey ;
+			curKey = PK11_GetNextSymKey( symKey ) ;
+			PK11_FreeSymKey( symKey ) ;
+		}
+	} else if( ( keyInfoCtx->keyReq.keyType & xmlSecKeyDataTypePublic ) == xmlSecKeyDataTypePublic ) {
+		SECKEYPublicKeyList*		pubKeyList ;
+		SECKEYPublicKey*			pubKey ;
+		SECKEYPublicKeyListNode*	curPub ;
+
+		/* Find asymmetric key from the slot by name */
+		pubKeyList = PK11_ListPublicKeysInSlot( slot , ( char* )name ) ;
+		pubKey = NULL ;
+		curPub = PUBKEY_LIST_HEAD(pubKeyList);
+		for( ; !PUBKEY_LIST_END(curPub, pubKeyList) ; curPub = PUBKEY_LIST_NEXT( curPub ) ) {
+			/* Check the key request */
+			length = SECKEY_PublicKeyStrength( curPub->key ) ;
+			length *= 8 ;
+			if( ( keyInfoCtx->keyReq.keyBitsSize > 0 ) &&
+				( length > 0 ) &&
+				( length < keyInfoCtx->keyReq.keyBitsSize ) )
+				continue ;
+
+			/* We find a eligible key */
+			pubKey = curPub->key ;
+			break ;
+		}
+
+		if( pubKey != NULL ) {
+			data = xmlSecNssPKIAdoptKey( NULL, pubKey ) ;
+			if( data == NULL ) {
+				/* Do nothing */
+			}
+		}
+
+		/* Destroy the public key list */
+		SECKEY_DestroyPublicKeyList( pubKeyList ) ;
+	} else if( ( keyInfoCtx->keyReq.keyType & xmlSecKeyDataTypePrivate ) == xmlSecKeyDataTypePrivate ) {
+		SECKEYPrivateKeyList*		priKeyList = NULL ;
+		SECKEYPrivateKey*			priKey = NULL ;
+		SECKEYPrivateKeyListNode*	curPri ;
+
+		/* Find asymmetric key from the slot by name */
+		priKeyList = PK11_ListPrivKeysInSlot( slot , ( char* )name , NULL ) ;
+		priKey = NULL ;
+		curPri = PRIVKEY_LIST_HEAD(priKeyList);
+		for( ; !PRIVKEY_LIST_END(curPri, priKeyList) ; curPri = PRIVKEY_LIST_NEXT( curPri ) ) {
+			/* Check the key request */
+			length = PK11_SignatureLen( curPri->key ) ;
+			length *= 8 ;
+			if( ( keyInfoCtx->keyReq.keyBitsSize > 0 ) &&
+				( length > 0 ) &&
+				( length < keyInfoCtx->keyReq.keyBitsSize ) )
+				continue ;
+
+			/* We find a eligible key */
+			priKey = curPri->key ;
+			break ;
+		}
+
+		if( priKey != NULL ) {
+			data = xmlSecNssPKIAdoptKey( priKey, NULL ) ;
+			if( data == NULL ) {
+				/* Do nothing */
+			}
+		}
+
+		/* Destroy the private key list */
+		SECKEY_DestroyPrivateKeyList( priKeyList ) ;
+	}
+
+	/* If we have gotten the key value */
+	if( data != NULL ) {
+		if( ( key = xmlSecKeyCreate() ) == NULL ) {
+			xmlSecError( XMLSEC_ERRORS_HERE ,
+				NULL ,
+				"xmlSecKeyCreate" ,
+				XMLSEC_ERRORS_R_XMLSEC_FAILED ,
+				XMLSEC_ERRORS_NO_MESSAGE ) ;
+
+			xmlSecKeyDataDestroy( data ) ;
+			return NULL ;
+		}
+
+		if( xmlSecKeySetValue( key , data ) < 0 ) {
+			xmlSecError( XMLSEC_ERRORS_HERE ,
+				NULL ,
+				"xmlSecKeySetValue" ,
+				XMLSEC_ERRORS_R_XMLSEC_FAILED ,
+				XMLSEC_ERRORS_NO_MESSAGE ) ;
+
+			xmlSecKeyDestroy( key ) ;
+			xmlSecKeyDataDestroy( data ) ;
+			return NULL ;
+		}
+	}
+
+	return(key);
+}
+
+/** 
+ * xmlSecKeyStoreFindKeyMethod:
+ * @store: 		the store.
+ * @name:		the desired key name.
+ * @keyInfoCtx: 	the pointer to key info context.
  *
- * Returns 0 on success or a negative value if an error occurs.
+ * Keys store specific find method. The caller is responsible for destroying 
+ * the returned key using #xmlSecKeyDestroy method.
+ *
+ * Returns the pointer to a key or NULL if key is not found or an error occurs.
  */
-int 
-xmlSecNssKeysStoreAdoptKey(xmlSecKeyStorePtr store, xmlSecKeyPtr key) {
-    xmlSecKeyStorePtr *ss;
-    
-    xmlSecAssert2(xmlSecKeyStoreCheckId(store, xmlSecNssKeysStoreId), -1);
-    xmlSecAssert2((key != NULL), -1);
+static xmlSecKeyPtr
+xmlSecNssKeysStoreFindKey(
+	xmlSecKeyStorePtr store ,
+	const xmlChar* name ,
+	xmlSecKeyInfoCtxPtr keyInfoCtx
+) {
+	xmlSecNssKeysStoreCtxPtr context = NULL ;
+	xmlSecKeyPtr	key = NULL ;
+	xmlSecNssKeySlotPtr	keySlot = NULL ;
+	xmlSecSize		pos ;
+	xmlSecSize		size ;
+
+	xmlSecAssert2( xmlSecKeyStoreCheckId( store , xmlSecNssKeysStoreId ) , NULL ) ;
+	xmlSecAssert2( xmlSecKeyStoreCheckSize( store , xmlSecNssKeysStoreSize ) , NULL ) ;
+	xmlSecAssert2( keyInfoCtx != NULL , NULL ) ;
+
+	context = xmlSecNssKeysStoreGetCtx( store ) ;
+	if( context == NULL ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+			xmlSecErrorsSafeString( xmlSecKeyStoreGetName( store ) ) ,
+			"xmlSecNssKeysStoreGetCtx" ,
+			XMLSEC_ERRORS_R_XMLSEC_FAILED ,
+			XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return NULL ;
+	}
+
+	/*-
+	 * Look for key at keyList at first.
+	 */
+	if( context->keyList != NULL ) {
+		size = xmlSecPtrListGetSize( context->keyList ) ;
+		for( pos = 0 ; pos < size ; pos ++ ) {
+			key = ( xmlSecKeyPtr )xmlSecPtrListGetItem( context->keyList , pos ) ;
+			if( key != NULL && xmlSecKeyMatch( key , name , &( keyInfoCtx->keyReq ) ) ) {
+				return xmlSecKeyDuplicate( key ) ;
+			}
+		}
+	}
+
+	/*-
+	 * Find the key from slotList
+	 */
+	if( context->slotList != NULL ) {
+		PK11SlotInfo*			slot = NULL ;
+
+		size = xmlSecPtrListGetSize( context->slotList ) ;
+		for( pos = 0 ; pos < size ; pos ++ ) {
+			keySlot = ( xmlSecNssKeySlotPtr )xmlSecPtrListGetItem( context->slotList , pos ) ;
+			slot = xmlSecNssKeySlotGetSlot( keySlot ) ;
+			if( slot == NULL ) {
+				continue ;
+			} else {
+				key = xmlSecNssKeysStoreFindKeyFromSlot( slot, name, keyInfoCtx ) ;
+				if( key == NULL ) {
+					continue ;
+				} else {
+					return( key ) ;
+				}
+			}
+		}
+	}
+
+	/*-
+	 * Create a session key if we can not find the key from keyList and slotList
+	 */
+	if( ( keyInfoCtx->keyReq.keyType & xmlSecKeyDataTypeSession ) == xmlSecKeyDataTypeSession ) {
+		key = xmlSecKeyGenerate( keyInfoCtx->keyReq.keyId , keyInfoCtx->keyReq.keyBitsSize , xmlSecKeyDataTypeSession ) ;
+		if( key == NULL ) {
+			xmlSecError( XMLSEC_ERRORS_HERE ,
+				xmlSecErrorsSafeString( xmlSecKeyStoreGetName( store ) ) ,
+				"xmlSecKeySetValue" ,
+				XMLSEC_ERRORS_R_XMLSEC_FAILED ,
+				XMLSEC_ERRORS_NO_MESSAGE ) ;
+			return NULL ;
+		}
+
+		return key ;
+	}
+
+	/**
+	 * We have no way to find the key any more.
+	 */
+	return NULL ;
+}
 
-    ss = xmlSecNssKeysStoreGetSS(store);
-    xmlSecAssert2(((ss != NULL