[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) && (*ss != NULL) && 
-		   (xmlSecKeyStoreCheckId(*ss, xmlSecSimpleKeysStoreId))), -1);
+static xmlSecKeyStoreKlass xmlSecNssKeysStoreKlass = {
+	sizeof( xmlSecKeyStoreKlass ) ,
+	xmlSecNssKeysStoreSize ,
+	BAD_CAST "implicit_nss_keys_store" ,
+	xmlSecNssKeysStoreInitialize ,
+	xmlSecNssKeysStoreFinalize ,
+	xmlSecNssKeysStoreFindKey ,
+	NULL ,
+	NULL
+} ;
 
-    return (xmlSecSimpleKeysStoreAdoptKey(*ss, key));
+/**
+ * xmlSecNssKeysStoreGetKlass:
+ * 
+ * The simple list based keys store klass.
+ *
+ * Returns simple list based keys store klass.
+ */
+xmlSecKeyStoreId 
+xmlSecNssKeysStoreGetKlass( void ) {
+    return &xmlSecNssKeysStoreKlass ;
 }
 
+
+/**************************
+ * Application routines
+ */
 /** 
  * xmlSecNssKeysStoreLoad:
  * @store:		the pointer to Nss keys store.
@@ -125,8 +532,11 @@
  * Returns 0 on success or a negative value if an error occurs.
  */
 int
-xmlSecNssKeysStoreLoad(xmlSecKeyStorePtr store, const char *uri, 
-			    xmlSecKeysMngrPtr keysMngr) {
+xmlSecNssKeysStoreLoad(
+	xmlSecKeyStorePtr store,
+	const char *uri, 
+	xmlSecKeysMngrPtr keysMngr
+) {
     xmlDocPtr doc;
     xmlNodePtr root;
     xmlNodePtr cur;
@@ -252,254 +662,147 @@
  */
 int
 xmlSecNssKeysStoreSave(xmlSecKeyStorePtr store, const char *filename, xmlSecKeyDataType type) {
-    xmlSecKeyStorePtr *ss;
-
-    xmlSecAssert2(xmlSecKeyStoreCheckId(store, xmlSecNssKeysStoreId), -1);
-    xmlSecAssert2((filename != NULL), -1);    
-    
-    ss = xmlSecNssKeysStoreGetSS(store);
-    xmlSecAssert2(((ss != NULL) && (*ss != NULL) && 
-		   (xmlSecKeyStoreCheckId(*ss, xmlSecSimpleKeysStoreId))), -1);
-
-    return (xmlSecSimpleKeysStoreSave(*ss, filename, type));
-}
-
-static int
-xmlSecNssKeysStoreInitialize(xmlSecKeyStorePtr store) {
-    xmlSecKeyStorePtr *ss;
-
-    xmlSecAssert2(xmlSecKeyStoreCheckId(store, xmlSecNssKeysStoreId), -1);
+    xmlSecKeyInfoCtx keyInfoCtx;
+	xmlSecNssKeysStoreCtxPtr context ;
+    xmlSecPtrListPtr list;
+    xmlSecKeyPtr key;
+    xmlSecSize i, keysSize;    
+    xmlDocPtr doc;
+    xmlNodePtr cur;
+    xmlSecKeyDataPtr data;
+    xmlSecPtrListPtr idsList;
+    xmlSecKeyDataId dataId;
+    xmlSecSize idsSize, j;
+    int ret;
 
-    ss = xmlSecNssKeysStoreGetSS(store);
-    xmlSecAssert2((*ss == NULL), -1);
+	xmlSecAssert2( xmlSecKeyStoreCheckId( store , xmlSecNssKeysStoreId ), -1 ) ;
+	xmlSecAssert2( xmlSecKeyStoreCheckSize( store , xmlSecNssKeysStoreSize ), -1 ) ;
+    xmlSecAssert2(filename != NULL, -1);    
+
+	context = xmlSecNssKeysStoreGetCtx( store ) ;
+	xmlSecAssert2( context != NULL, -1 );
+
+    list = context->keyList ;
+	xmlSecAssert2( list != NULL, -1 );
+    xmlSecAssert2(xmlSecPtrListCheckId(list, xmlSecKeyPtrListId), -1);
 
-    *ss = xmlSecKeyStoreCreate(xmlSecSimpleKeysStoreId);
-    if(*ss == NULL) {
-	xmlSecError(XMLSEC_ERRORS_HERE,
+    /* create doc */
+    doc = xmlSecCreateTree(BAD_CAST "Keys", xmlSecNs);
+    if(doc == NULL) {
+		xmlSecError(XMLSEC_ERRORS_HERE,
 		    xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
-		    "xmlSecKeyStoreCreate",
+		    "xmlSecCreateTree",
 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-		    "xmlSecSimpleKeysStoreId");
-	return(-1);
+		    XMLSEC_ERRORS_NO_MESSAGE);
+		return(-1);
     }
-
-    return(0);    
-}
-
-static void
-xmlSecNssKeysStoreFinalize(xmlSecKeyStorePtr store) {
-    xmlSecKeyStorePtr *ss;
     
-    xmlSecAssert(xmlSecKeyStoreCheckId(store, xmlSecNssKeysStoreId));
-    
-    ss = xmlSecNssKeysStoreGetSS(store);
-    xmlSecAssert((ss != NULL) && (*ss != NULL));
-    
-    xmlSecKeyStoreDestroy(*ss);
-}
-
-static xmlSecKeyPtr 
-xmlSecNssKeysStoreFindKey(xmlSecKeyStorePtr store, const xmlChar* name, 
-		          xmlSecKeyInfoCtxPtr keyInfoCtx) {
-    xmlSecKeyStorePtr* ss;
-    xmlSecKeyPtr key = NULL;
-    xmlSecKeyPtr retval = NULL;
-    xmlSecKeyReqPtr keyReq = NULL;
-    CERTCertificate *cert = NULL;
-    SECKEYPublicKey *pubkey = NULL;
-    SECKEYPrivateKey *privkey = NULL;
-    xmlSecKeyDataPtr data = NULL;
-    xmlSecKeyDataPtr x509Data = NULL;
-    int ret;
-
-    xmlSecAssert2(xmlSecKeyStoreCheckId(store, xmlSecNssKeysStoreId), NULL);
-    xmlSecAssert2(keyInfoCtx != NULL, NULL);
-
-    ss = xmlSecNssKeysStoreGetSS(store);
-    xmlSecAssert2(((ss != NULL) && (*ss != NULL)), NULL);
-
-    key = xmlSecKeyStoreFindKey(*ss, name, keyInfoCtx);
-    if (key != NULL) {
-	return (key);
-    }
+    idsList = xmlSecKeyDataIdsGet();	
+    xmlSecAssert2(idsList != NULL, -1);
+	
+    keysSize = xmlSecPtrListGetSize(list);
+    idsSize = xmlSecPtrListGetSize(idsList);
+    for(i = 0; i < keysSize; ++i) {
+	key = (xmlSecKeyPtr)xmlSecPtrListGetItem(list, i);
+	xmlSecAssert2(key != NULL, -1);
+	    
+    cur = xmlSecAddChild(xmlDocGetRootElement(doc), xmlSecNodeKeyInfo, xmlSecDSigNs);
+	if(cur == NULL) {
+	    xmlSecError(XMLSEC_ERRORS_HERE,
+			xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
+			"xmlSecAddChild",
+			XMLSEC_ERRORS_R_XMLSEC_FAILED,
+			"node=%s",
+			xmlSecErrorsSafeString(xmlSecNodeKeyInfo));
+	    xmlFreeDoc(doc); 
+	    return(-1);
+	}
 
-    /* Try to find the key in the NSS DB, and construct an xmlSecKey.
-     * we must have a name to lookup keys in NSS DB.
-     */
-    if (name == NULL) {
-	goto done;
-    }
+	/* special data key name */
+	if(xmlSecKeyGetName(key) != NULL) {
+    	if(xmlSecAddChild(cur, xmlSecNodeKeyName, xmlSecDSigNs) == NULL) {
+			xmlSecError(XMLSEC_ERRORS_HERE,
+			    xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
+			    "xmlSecAddChild",
+			    XMLSEC_ERRORS_R_XMLSEC_FAILED,
+			    "node=%s",
+			    xmlSecErrorsSafeString(xmlSecNodeKeyName));
+			xmlFreeDoc(doc); 
+			return(-1);
+	    }
+	}
+    
+	/* create nodes for other keys data */
+	for(j = 0; j < idsSize; ++j) {
+	    dataId = (xmlSecKeyDataId)xmlSecPtrListGetItem(idsList, j);
+	    xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, -1);
 
-    /* what type of key are we looking for? 
-     * TBD: For now, we'll look only for public/private keys using the
-     * name as a cert nickname. Later on, we can attempt to find
-     * symmetric keys using PK11_FindFixedKey 
-     */
-    keyReq = &(keyInfoCtx->keyReq);
-    if (keyReq->keyType & 
-	(xmlSecKeyDataTypePublic | xmlSecKeyDataTypePrivate)) {
-	cert = CERT_FindCertByNickname (CERT_GetDefaultCertDB(), (char *)name);
-	if (cert == NULL) {
-	    goto done;
-	}
-
-	if (keyReq->keyType & xmlSecKeyDataTypePublic) {
- 	    pubkey = CERT_ExtractPublicKey(cert);
-	    if (pubkey == NULL) {
-		xmlSecError(XMLSEC_ERRORS_HERE,
-			    NULL,
-			    "CERT_ExtractPublicKey",
-			    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-			    XMLSEC_ERRORS_NO_MESSAGE);
-		goto done;
+	    if(dataId->dataNodeName == NULL) {
+			continue;
+	    }
+	    
+	    data = xmlSecKeyGetData(key, dataId);
+	    if(data == NULL) {
+			continue;
 	    }
-	} 
 
-	if (keyReq->keyType & xmlSecKeyDataTypePrivate) { 
- 	    privkey = PK11_FindKeyByAnyCert(cert, NULL);
-	    if (privkey == NULL) {
-		xmlSecError(XMLSEC_ERRORS_HERE,
-			    NULL,
-			    "PK11_FindKeyByAnyCert",
-			    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-			    XMLSEC_ERRORS_NO_MESSAGE);
-		goto done;
+	    if(xmlSecAddChild(cur, dataId->dataNodeName, dataId->dataNodeNs) == NULL) {
+			xmlSecError(XMLSEC_ERRORS_HERE,
+			    xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
+			    "xmlSecAddChild",
+			    XMLSEC_ERRORS_R_XMLSEC_FAILED,
+			    "node=%s", 
+			    xmlSecErrorsSafeString(dataId->dataNodeName));
+			xmlFreeDoc(doc); 
+	        return(-1);
 	    }
 	}
 
-	data = xmlSecNssPKIAdoptKey(privkey, pubkey);
-	if(data == NULL) {
-	    xmlSecError(XMLSEC_ERRORS_HERE,
-			NULL,
-			"xmlSecNssPKIAdoptKey",
-			XMLSEC_ERRORS_R_XMLSEC_FAILED,
-			XMLSEC_ERRORS_NO_MESSAGE);
-	    goto done;
-	}    
-	privkey = NULL;
-	pubkey = NULL;
-
-        key = xmlSecKeyCreate();
-        if (key == NULL) {
+    ret = xmlSecKeyInfoCtxInitialize(&keyInfoCtx, NULL);
+	if(ret < 0) {
 	    xmlSecError(XMLSEC_ERRORS_HERE,
-			NULL,
-			"xmlSecKeyCreate",
+		    	xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
+			"xmlSecKeyInfoCtxInitialize",
 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
 			XMLSEC_ERRORS_NO_MESSAGE);
-	    return (NULL);
-        }
-
-	x509Data = xmlSecKeyDataCreate(xmlSecNssKeyDataX509Id);
-	if(x509Data == NULL) {
-	    xmlSecError(XMLSEC_ERRORS_HERE,
-			NULL,
-			"xmlSecKeyDataCreate",
-			XMLSEC_ERRORS_R_XMLSEC_FAILED,
-			"transform=%s",
-			xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecNssKeyDataX509Id)));
-	    goto done;
-	}
-
-	ret = xmlSecNssKeyDataX509AdoptKeyCert(x509Data, cert);
-	if (ret < 0) {
-	    xmlSecError(XMLSEC_ERRORS_HERE,
-			NULL,
-			"xmlSecNssKeyDataX509AdoptKeyCert",
-			XMLSEC_ERRORS_R_XMLSEC_FAILED,
-			"data=%s",
-			xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
-	    goto done;
-	}
-	cert = CERT_DupCertificate(cert);
-	if (cert == NULL) {
-	    xmlSecError(XMLSEC_ERRORS_HERE,
-			NULL,
-			"CERT_DupCertificate",
-			XMLSEC_ERRORS_R_CRYPTO_FAILED,
-			"data=%s",
-			xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
-	    goto done;
-	}
-
-	ret = xmlSecNssKeyDataX509AdoptCert(x509Data, cert);
-	if (ret < 0) {
-	    xmlSecError(XMLSEC_ERRORS_HERE,
-			NULL,
-			"xmlSecNssKeyDataX509AdoptCert",
-			XMLSEC_ERRORS_R_XMLSEC_FAILED,
-			"data=%s",
-			xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
-	    goto done;
+	    xmlFreeDoc(doc);
+	    return(-1);
 	}
-	cert = NULL;
 
-	ret = xmlSecKeySetValue(key, data);
-	if (ret < 0) {
-	    xmlSecError(XMLSEC_ERRORS_HERE,
-			NULL,
-			"xmlSecKeySetValue",
-			XMLSEC_ERRORS_R_XMLSEC_FAILED,
-			"data=%s", 
-			xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)));
-	    goto done;
-	}
-	data = NULL;
+	keyInfoCtx.mode 		= xmlSecKeyInfoModeWrite;
+    keyInfoCtx.keyReq.keyId		= xmlSecKeyDataIdUnknown;
+	keyInfoCtx.keyReq.keyType	= type;
+	keyInfoCtx.keyReq.keyUsage 	= xmlSecKeyDataUsageAny;
 
-	ret = xmlSecKeyAdoptData(key, x509Data);
-	if (ret < 0) {
+	/* finally write key in the node */
+	ret = xmlSecKeyInfoNodeWrite(cur, key, &keyInfoCtx);
+	if(ret < 0) {
 	    xmlSecError(XMLSEC_ERRORS_HERE,
-			NULL,
-			"xmlSecKeyAdoptData",
+			xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
+			"xmlSecKeyInfoNodeWrite",
 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
-			"data=%s",
-			xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
-	    goto done;
-	}
-	x509Data = NULL;
-
-	retval = key;
-	key = NULL;
-    }
-
-done:
-    if (cert != NULL) {
-	CERT_DestroyCertificate(cert);
-    }
-    if (pubkey != NULL) {
-	SECKEY_DestroyPublicKey(pubkey);
-    }
-    if (privkey != NULL) {
-	SECKEY_DestroyPrivateKey(privkey);
-    }
-    if (data != NULL) {
-	xmlSecKeyDataDestroy(data);
-    }
-    if (x509Data != NULL) {
-	xmlSecKeyDataDestroy(x509Data);
-    }
-    if (key != NULL) {
-	xmlSecKeyDestroy(key);
+			XMLSEC_ERRORS_NO_MESSAGE);
+	    xmlSecKeyInfoCtxFinalize(&keyInfoCtx);
+	    xmlFreeDoc(doc); 
+	    return(-1);
+	}		
+	xmlSecKeyInfoCtxFinalize(&keyInfoCtx);
     }
-
-    /* now that we have a key, make sure it is valid and let the simple
-     * store adopt it */
-    if (retval) {
-	if (xmlSecKeyIsValid(retval)) {
-	    ret = xmlSecSimpleKeysStoreAdoptKey(*ss, retval);
-	    if (ret < 0) {
+    
+    /* now write result */
+    ret = xmlSaveFormatFile(filename, doc, 1);
+    if(ret < 0) {
 		xmlSecError(XMLSEC_ERRORS_HERE,
-			    xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
-			    "xmlSecSimpleKeysStoreAdoptKey",
-			    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-			    XMLSEC_ERRORS_NO_MESSAGE);
-		xmlSecKeyDestroy(retval);
-		retval = NULL;
-	    }
-        } else {
-	    xmlSecKeyDestroy(retval);
-	    retval = NULL;
-	}
-    }
-
-    return (retval);
+		    xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
+		    "xmlSaveFormatFile",
+		    XMLSEC_ERRORS_R_XML_FAILED,
+		    "filename=%s", 
+		    xmlSecErrorsSafeString(filename));
+		xmlFreeDoc(doc); 
+		return(-1);
+    }	   
+    
+    xmlFreeDoc(doc);
+    return(0);
 }
+
Index: xmlsec/src/nss/pkikeys.c
===================================================================
RCS file: /cvs/gnome/xmlsec/src/nss/pkikeys.c,v
retrieving revision 1.4
diff -u -r1.4 pkikeys.c
--- xmlsec/src/nss/pkikeys.c	17 Mar 2004 05:06:45 -0000	1.4
+++ xmlsec/src/nss/pkikeys.c	6 Feb 2005 03:53:22 -0000
@@ -24,6 +24,7 @@
 #include <xmlsec/nss/crypto.h>
 #include <xmlsec/nss/bignum.h>
 #include <xmlsec/nss/pkikeys.h>
+#include <xmlsec/nss/tokens.h>
 
 /**************************************************************************
  *
@@ -115,6 +116,8 @@
                           xmlSecNssPKIKeyDataCtxPtr ctxSrc)
 {
     xmlSecNSSPKIKeyDataCtxFree(ctxDst);
+	ctxDst->privkey = NULL ;
+	ctxDst->pubkey = NULL ;
     if (ctxSrc->privkey != NULL) {
 	ctxDst->privkey = SECKEY_CopyPrivateKey(ctxSrc->privkey);
 	if(ctxDst->privkey == NULL) {
@@ -122,7 +125,7 @@
 			NULL,
 			"SECKEY_CopyPrivateKey",
 			XMLSEC_ERRORS_R_CRYPTO_FAILED,
-			XMLSEC_ERRORS_NO_MESSAGE);
+				"error code=%d", PORT_GetError());
 	    return(-1);
 	}
     }
@@ -134,7 +137,7 @@
 			NULL,
 			"SECKEY_CopyPublicKey",
 			XMLSEC_ERRORS_R_CRYPTO_FAILED,
-			XMLSEC_ERRORS_NO_MESSAGE);
+				"error code=%d", PORT_GetError());
 	    return(-1);
 	}
     }
@@ -147,10 +150,31 @@
                             SECKEYPublicKey  *pubkey)
 {
     xmlSecNssPKIKeyDataCtxPtr ctx;
+	KeyType					pubType = nullKey ;
+	KeyType					priType = nullKey ;
     
     xmlSecAssert2(xmlSecKeyDataIsValid(data), -1);
     xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecNssPKIKeyDataSize), -1);
 
+	if( privkey != NULL ) {
+		priType = SECKEY_GetPrivateKeyType( privkey ) ;
+	}
+
+	if( pubkey != NULL ) {
+		pubType = SECKEY_GetPublicKeyType( pubkey ) ;
+	}
+
+	if( priType != nullKey && pubType != nullKey ) {
+		if( pubType != priType ) {
+			xmlSecError( XMLSEC_ERRORS_HERE ,
+				NULL ,
+				NULL ,
+				XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+				"different type of private and public key" ) ;
+			return -1 ;
+		}
+	}
+
     ctx = xmlSecNssPKIKeyDataGetCtx(data);
     xmlSecAssert2(ctx != NULL, -1);
     
@@ -183,16 +207,30 @@
 {
     xmlSecKeyDataPtr data = NULL;
     int ret;
-    KeyType kt;
-    
-    if (pubkey != NULL) {
-	kt = SECKEY_GetPublicKeyType(pubkey);
-    } else {
-	kt = SECKEY_GetPrivateKeyType(privkey);
-	pubkey = SECKEY_ConvertToPublicKey(privkey);
-    }
+	KeyType					pubType = nullKey ;
+	KeyType					priType = nullKey ;
     
-    switch(kt) {	
+	if( privkey != NULL ) {
+		priType = SECKEY_GetPrivateKeyType( privkey ) ;
+	}
+
+	if( pubkey != NULL ) {
+		pubType = SECKEY_GetPublicKeyType( pubkey ) ;
+	}
+
+	if( priType != nullKey && pubType != nullKey ) {
+		if( pubType != priType ) {
+			xmlSecError( XMLSEC_ERRORS_HERE ,
+				NULL ,
+				NULL ,
+				XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+				"different type of private and public key" ) ;
+			return( NULL ) ;
+		}
+	}
+   
+	pubType = priType != nullKey ? priType : pubType ;
+    switch(pubType) {	
 #ifndef XMLSEC_NO_RSA    
     case rsaKey:
 	data = xmlSecKeyDataCreate(xmlSecNssKeyDataRsaId);
@@ -224,7 +262,7 @@
 		    NULL,
 		    NULL,
 		    XMLSEC_ERRORS_R_INVALID_TYPE,
-		    "PKI key type %d not supported", kt);
+		    "PKI key type %d not supported", pubType);
 	return(NULL);
     }
 
@@ -553,13 +591,13 @@
 	goto done;
     }
 
-    slot = PK11_GetBestSlot(CKM_DSA, NULL);
+    slot = xmlSecNssSlotGet(CKM_DSA);
     if(slot == NULL) {
 	xmlSecError(XMLSEC_ERRORS_HERE,
 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
-		    "PK11_GetBestSlot",
+		    "xmlSecNssSlotGet",
 		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-		    XMLSEC_ERRORS_NO_MESSAGE);
+		    "error code=%d", PORT_GetError());
 	ret = -1;
 	goto done;
     }
@@ -570,7 +608,7 @@
 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
 		    "PORT_NewArena",
 		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-		    XMLSEC_ERRORS_NO_MESSAGE);
+		    "error code=%d", PORT_GetError());
 	ret = -1;
 	goto done;
     }
@@ -582,7 +620,7 @@
 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
 		    "PORT_ArenaZAlloc",
 		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-		    XMLSEC_ERRORS_NO_MESSAGE);
+		    "error code=%d", PORT_GetError());
 	PORT_FreeArena(arena, PR_FALSE);
 	ret = -1;
 	goto done;
@@ -757,14 +795,14 @@
     if (slot != NULL) {
 	PK11_FreeSlot(slot);
     }
-    if (ret != 0) {
+
 	if (pubkey != NULL) {
 	    SECKEY_DestroyPublicKey(pubkey);
 	}
 	if (data != NULL) {
 	    xmlSecKeyDataDestroy(data);
 	}
-    }
+
     return(ret);
 }
 
@@ -783,7 +821,7 @@
 
     ctx = xmlSecNssPKIKeyDataGetCtx(xmlSecKeyGetValue(key));
     xmlSecAssert2(ctx != NULL, -1);
-    xmlSecAssert2(SECKEY_GetPublicKeyType(ctx->pubkey) == dsaKey, -1);
+//    xmlSecAssert2(SECKEY_GetPublicKeyType(ctx->pubkey) == dsaKey, -1);
 
     if(((xmlSecKeyDataTypePublic | xmlSecKeyDataTypePrivate) & keyInfoCtx->keyReq.keyType) == 0) {
 	/* we can have only private key or public key */
@@ -905,7 +943,8 @@
 		    xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
 		    "PK11_PQG_ParamGen",
 		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-		    "size=%d", sizeBits);
+		    "size=%d, error code=%d", sizeBits, PORT_GetError());
+	ret = -1;
 	goto done;
     }
 
@@ -915,11 +954,12 @@
 		    xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
 		    "PK11_PQG_VerifyParams",
 		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-		    "size=%d", sizeBits);
+		    "size=%d, error code=%d", sizeBits, PORT_GetError());
+	ret = -1;
 	goto done;
     }
 
-    slot = PK11_GetBestSlot(CKM_DSA_KEY_PAIR_GEN, NULL);
+    slot = xmlSecNssSlotGet(CKM_DSA_KEY_PAIR_GEN);
     PK11_Authenticate(slot, PR_TRUE, NULL /* default pwd callback */);
     privkey = PK11_GenerateKeyPair(slot, CKM_DSA_KEY_PAIR_GEN, pqgParams,
 				   &pubkey, PR_FALSE, PR_TRUE, NULL);
@@ -929,8 +969,9 @@
 		    xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
 		    "PK11_GenerateKeyPair",
 		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-		    XMLSEC_ERRORS_NO_MESSAGE);
+		    "error code=%d", PORT_GetError());
         
+	ret = -1;
 	goto done;
     }
 
@@ -943,7 +984,8 @@
 		    XMLSEC_ERRORS_NO_MESSAGE);
 	goto done;
     }
-
+	privkey = NULL ;
+	pubkey = NULL ;
     ret = 0;
 
 done:
@@ -956,16 +998,14 @@
     if (pqgVerify != NULL) {
 	PK11_PQG_DestroyVerify(pqgVerify);
     }
-    if (ret == 0) {
-	return (0);
-    }
+
     if (pubkey != NULL) {
 	SECKEY_DestroyPublicKey(pubkey);
     }
     if (privkey != NULL) {
 	SECKEY_DestroyPrivateKey(privkey);
     }
-    return(-1);
+    return(ret);
 }
 
 static xmlSecKeyDataType
@@ -975,10 +1015,10 @@
     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecNssKeyDataDsaId), xmlSecKeyDataTypeUnknown);
     ctx = xmlSecNssPKIKeyDataGetCtx(data);
     xmlSecAssert2(ctx != NULL, -1);
-    xmlSecAssert2(SECKEY_GetPublicKeyType(ctx->pubkey) == dsaKey, -1);
+//    xmlSecAssert2(SECKEY_GetPublicKeyType(ctx->pubkey) == dsaKey, -1);
     if (ctx->privkey != NULL) {
 	return(xmlSecKeyDataTypePrivate | xmlSecKeyDataTypePublic);
-    } else {
+    } else if( ctx->pubkey != NULL ) {
 	return(xmlSecKeyDataTypePublic);
     }
        
@@ -992,7 +1032,7 @@
     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecNssKeyDataDsaId), 0);
     ctx = xmlSecNssPKIKeyDataGetCtx(data);
     xmlSecAssert2(ctx != NULL, -1);
-    xmlSecAssert2(SECKEY_GetPublicKeyType(ctx->pubkey) == dsaKey, -1);
+//    xmlSecAssert2(SECKEY_GetPublicKeyType(ctx->pubkey) == dsaKey, -1);
 
     return(8 * SECKEY_PublicKeyStrength(ctx->pubkey));
 }
@@ -1181,13 +1221,13 @@
 	goto done;
     }
 
-    slot = PK11_GetBestSlot(CKM_RSA_PKCS, NULL);
+    slot = xmlSecNssSlotGet(CKM_RSA_PKCS);
     if(slot == NULL) {
         xmlSecError(XMLSEC_ERRORS_HERE,
                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
-                    "PK11_GetBestSlot",
+                    "xmlSecNssSlotGet",
                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
-                    XMLSEC_ERRORS_NO_MESSAGE);
+                    "error code=%d", PORT_GetError());
         ret = -1;
         goto done;
     }
@@ -1198,7 +1238,7 @@
                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
                     "PORT_NewArena",
                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
-                    XMLSEC_ERRORS_NO_MESSAGE);
+                    "error code=%d", PORT_GetError());
         ret = -1;
         goto done;
     }
@@ -1210,7 +1250,7 @@
                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
                     "PORT_ArenaZAlloc",
                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
-                    XMLSEC_ERRORS_NO_MESSAGE);
+                    "error code=%d", PORT_GetError());
 	PORT_FreeArena(arena, PR_FALSE);
         ret = -1;
         goto done;
@@ -1349,7 +1389,7 @@
 
     ctx = xmlSecNssPKIKeyDataGetCtx(xmlSecKeyGetValue(key));
     xmlSecAssert2(ctx != NULL, -1);
-    xmlSecAssert2(SECKEY_GetPublicKeyType(ctx->pubkey) == rsaKey, -1);
+//    xmlSecAssert2(SECKEY_GetPublicKeyType(ctx->pubkey) == rsaKey, -1);
 
 
     if(((xmlSecKeyDataTypePublic | xmlSecKeyDataTypePrivate) & keyInfoCtx->keyReq.keyType) == 0) {
@@ -1420,7 +1460,7 @@
     params.keySizeInBits = sizeBits;
     params.pe = 65537;
 
-    slot = PK11_GetBestSlot(CKM_RSA_PKCS_KEY_PAIR_GEN, NULL);
+    slot = xmlSecNssSlotGet(CKM_RSA_PKCS_KEY_PAIR_GEN);
     PK11_Authenticate(slot, PR_TRUE, NULL /* default pwd callback */);
     privkey = PK11_GenerateKeyPair(slot, CKM_RSA_PKCS_KEY_PAIR_GEN, &params,
 				   &pubkey, PR_FALSE, PR_TRUE, NULL);
@@ -1430,7 +1470,7 @@
 		    xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
 		    "PK11_GenerateKeyPair",
 		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-		    XMLSEC_ERRORS_NO_MESSAGE);
+		    "error code=%d", PORT_GetError());
         
 	goto done;
     }
@@ -1472,7 +1512,7 @@
     
     ctx = xmlSecNssPKIKeyDataGetCtx(data);
     xmlSecAssert2(ctx != NULL, -1);
-    xmlSecAssert2(SECKEY_GetPublicKeyType(ctx->pubkey) == rsaKey, -1);
+//    xmlSecAssert2(SECKEY_GetPublicKeyType(ctx->pubkey) == rsaKey, -1);
     if (ctx->privkey != NULL) {
 	return(xmlSecKeyDataTypePrivate | xmlSecKeyDataTypePublic);
     } else {
@@ -1490,7 +1530,7 @@
 
     ctx = xmlSecNssPKIKeyDataGetCtx(data);
     xmlSecAssert2(ctx != NULL, -1);
-    xmlSecAssert2(SECKEY_GetPublicKeyType(ctx->pubkey) == rsaKey, -1);
+//    xmlSecAssert2(SECKEY_GetPublicKeyType(ctx->pubkey) == rsaKey, -1);
 
     return(8 * SECKEY_PublicKeyStrength(ctx->pubkey));
 }
Index: xmlsec/src/nss/signatures.c
===================================================================
RCS file: /cvs/gnome/xmlsec/src/nss/signatures.c,v
retrieving revision 1.3
diff -u -r1.3 signatures.c
--- xmlsec/src/nss/signatures.c	26 Sep 2003 00:58:15 -0000	1.3
+++ xmlsec/src/nss/signatures.c	6 Feb 2005 03:53:22 -0000
@@ -199,7 +199,7 @@
 			xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
 			"SGN_NewContext",
 			XMLSEC_ERRORS_R_CRYPTO_FAILED,
-			XMLSEC_ERRORS_NO_MESSAGE);
+			"error code=%d", PORT_GetError());
 	    return(-1);
         }
     } else {
@@ -222,7 +222,7 @@
 			xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
 			"VFY_CreateContext",
 			XMLSEC_ERRORS_R_CRYPTO_FAILED,
-			XMLSEC_ERRORS_NO_MESSAGE);
+			"error code=%d", PORT_GetError());
 	    return(-1);
         }
     }
@@ -282,7 +282,7 @@
 		    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
 		    "VFY_Update, VFY_End",
 		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-		    XMLSEC_ERRORS_NO_MESSAGE);
+		    "error code=%d", PORT_GetError());
 
 	if (PORT_GetError() == SEC_ERROR_PKCS7_BAD_SIGNATURE) {
 	    xmlSecError(XMLSEC_ERRORS_HERE, 
@@ -341,7 +341,7 @@
 			    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
 			    "SGN_Begin",
 			    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-			    XMLSEC_ERRORS_NO_MESSAGE);
+			    "error code=%d", PORT_GetError());
 		return(-1);
 	    }
 	} else {
@@ -351,7 +351,7 @@
 			    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
 			    "VFY_Begin",
 			    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-			    XMLSEC_ERRORS_NO_MESSAGE);
+			    "error code=%d", PORT_GetError());
 		return(-1);
 	    }
 	}
@@ -368,7 +368,7 @@
 			    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
 			    "SGN_Update",
 			    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-			    XMLSEC_ERRORS_NO_MESSAGE);
+			    "error code=%d", PORT_GetError());
 		return(-1);
 	    }
 	} else {
@@ -378,7 +378,7 @@
 			    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
 			    "VFY_Update",
 			    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-			    XMLSEC_ERRORS_NO_MESSAGE);
+			    "error code=%d", PORT_GetError());
 		return(-1);
 	    }
 	}
@@ -404,7 +404,7 @@
 			    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
 			    "SGN_End",
 			    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-			    XMLSEC_ERRORS_NO_MESSAGE);
+			    "error code=%d", PORT_GetError());
 		return(-1);
 	    }
 
Index: xmlsec/src/nss/symkeys.c
===================================================================
RCS file: /cvs/gnome/xmlsec/src/nss/symkeys.c,v
retrieving revision 1.9
diff -u -r1.9 symkeys.c
--- xmlsec/src/nss/symkeys.c	21 Jul 2003 03:12:52 -0000	1.9
+++ xmlsec/src/nss/symkeys.c	6 Feb 2005 03:53:23 -0000
@@ -15,20 +15,42 @@
 #include <stdio.h>
 #include <string.h>
 
+#include <pk11func.h>
+#include <nss.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>
+#include <xmlsec/nss/tokens.h>
 
 /*****************************************************************************
  * 
- * Symmetic (binary) keys - just a wrapper for xmlSecKeyDataBinary
+ * Symmetic (binary) keys - a wrapper over slot information and PK11SymKey
  *
  ****************************************************************************/
+typedef struct _xmlSecNssSymKeyDataCtx      xmlSecNssSymKeyDataCtx ;
+typedef struct _xmlSecNssSymKeyDataCtx*     xmlSecNssSymKeyDataCtxPtr ;
+
+struct _xmlSecNssSymKeyDataCtx {
+    CK_MECHANISM_TYPE       cipher ;    /* the symmetic key mechanism */
+    PK11SlotInfo*           slot ;      /* the key resident slot */
+    PK11SymKey*             symkey ;    /* the symmetic key */
+} ;
+
+#define xmlSecNssSymKeyDataSize \
+    ( sizeof( xmlSecKeyData ) + sizeof( xmlSecNssSymKeyDataCtx ) )
+
+#define xmlSecNssSymKeyDataGetCtx( data ) \
+    ( ( xmlSecNssSymKeyDataCtxPtr )( ( ( xmlSecByte* )( data ) ) + sizeof( xmlSecKeyData ) ) )
+
+
 static int	xmlSecNssSymKeyDataInitialize		(xmlSecKeyDataPtr data);
 static int	xmlSecNssSymKeyDataDuplicate		(xmlSecKeyDataPtr dst,
 							 xmlSecKeyDataPtr src);
@@ -69,105 +91,620 @@
 
 static int
 xmlSecNssSymKeyDataInitialize(xmlSecKeyDataPtr data) {
+    xmlSecNssSymKeyDataCtxPtr ctx;
+
     xmlSecAssert2(xmlSecNssSymKeyDataCheckId(data), -1);
-    
-    return(xmlSecKeyDataBinaryValueInitialize(data));
+    xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecNssSymKeyDataSize), -1);
+
+    ctx = xmlSecNssSymKeyDataGetCtx(data);
+    xmlSecAssert2(ctx != NULL, -1);
+
+    memset( ctx, 0, sizeof(xmlSecNssSymKeyDataCtx));
+
+    /* Set the block cipher mechanism */
+#ifndef XMLSEC_NO_DES
+    if(xmlSecKeyDataCheckId(data, xmlSecNssKeyDataDesId)) {
+        ctx->cipher = CKM_DES3_KEY_GEN;
+    } else
+#endif  /* XMLSEC_NO_DES */
+
+#ifndef XMLSEC_NO_AES
+    if(xmlSecKeyDataCheckId(data, xmlSecNssKeyDataDesId)) {
+        ctx->cipher = CKM_AES_KEY_GEN;
+    } else
+#endif  /* XMLSEC_NO_AES */
+
+    if(1) {
+        xmlSecError( XMLSEC_ERRORS_HERE ,
+            xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+            NULL ,
+            XMLSEC_ERRORS_R_XMLSEC_FAILED ,
+            "Unsupported block cipher" ) ;
+        return(-1) ;
+    }
+
+    return(0);
 }
 
 static int
 xmlSecNssSymKeyDataDuplicate(xmlSecKeyDataPtr dst, xmlSecKeyDataPtr src) {
+    xmlSecNssSymKeyDataCtxPtr ctxDst;
+    xmlSecNssSymKeyDataCtxPtr ctxSrc;
+
     xmlSecAssert2(xmlSecNssSymKeyDataCheckId(dst), -1);
+    xmlSecAssert2(xmlSecKeyDataCheckSize(dst, xmlSecNssSymKeyDataSize), -1);
     xmlSecAssert2(xmlSecNssSymKeyDataCheckId(src), -1);
+    xmlSecAssert2(xmlSecKeyDataCheckSize(src, xmlSecNssSymKeyDataSize), -1);
     xmlSecAssert2(dst->id == src->id, -1);
-        
-    return(xmlSecKeyDataBinaryValueDuplicate(dst, src));
+
+    ctxDst = xmlSecNssSymKeyDataGetCtx(dst);
+    xmlSecAssert2(ctxDst != NULL, -1);
+
+    ctxSrc = xmlSecNssSymKeyDataGetCtx(src);
+    xmlSecAssert2(ctxSrc != NULL, -1);
+
+    ctxDst->cipher = ctxSrc->cipher ;
+
+    if( ctxSrc->slot != NULL ) {
+        if( ctxDst->slot != NULL && ctxDst->slot != ctxSrc->slot ) {
+            PK11_FreeSlot( ctxDst->slot ) ;
+            ctxDst->slot = NULL ;
+        }
+
+        if( ctxDst->slot == NULL && ctxSrc->slot != NULL )
+            ctxDst->slot = PK11_ReferenceSlot( ctxSrc->slot ) ;
+    } else {
+        if( ctxDst->slot != NULL ) {
+            PK11_FreeSlot( ctxDst->slot ) ;
+            ctxDst->slot = NULL ;
+        }
+    }
+
+    if( ctxSrc->symkey != NULL ) {
+        if( ctxDst->symkey != NULL && ctxDst->symkey != ctxSrc->symkey ) {
+            PK11_FreeSymKey( ctxDst->symkey ) ;
+            ctxDst->symkey = NULL ;
+        }
+
+        if( ctxDst->symkey == NULL && ctxSrc->symkey != NULL )
+            ctxDst->symkey = PK11_ReferenceSymKey( ctxSrc->symkey ) ;
+    } else {
+        if( ctxDst->symkey != NULL ) {
+            PK11_FreeSymKey( ctxDst->symkey ) ;
+            ctxDst->symkey = NULL ;
+        }
+    }
+
+    return(0);
 }
 
 static void
 xmlSecNssSymKeyDataFinalize(xmlSecKeyDataPtr data) {
+    xmlSecNssSymKeyDataCtxPtr ctx;
+
     xmlSecAssert(xmlSecNssSymKeyDataCheckId(data));
-    
-    xmlSecKeyDataBinaryValueFinalize(data);
+    xmlSecAssert(xmlSecKeyDataCheckSize(data, xmlSecNssSymKeyDataSize));
+
+    ctx = xmlSecNssSymKeyDataGetCtx(data);
+    xmlSecAssert(ctx != NULL);
+
+    if( ctx->slot != NULL ) {
+        PK11_FreeSlot( ctx->slot ) ;
+        ctx->slot = NULL ;
+    }
+
+    if( ctx->symkey != NULL ) {
+        PK11_FreeSymKey( ctx->symkey ) ;
+        ctx->symkey = NULL ;
+    }
+
+    ctx->cipher = CKM_INVALID_MECHANISM ;
 }
 
 static int
 xmlSecNssSymKeyDataXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
 			       xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
-    xmlSecAssert2(xmlSecNssSymKeyDataKlassCheck(id), -1);
+    PK11SymKey* symKey ;
+    PK11SlotInfo* slot ;
+    xmlSecBufferPtr keyBuf;
+    xmlSecSize len;
+    xmlSecKeyDataPtr data;
+    xmlSecNssSymKeyDataCtxPtr ctx;
+    SECItem keyItem ;
+    int ret;
+    
+    xmlSecAssert2(id != xmlSecKeyDataIdUnknown, -1);
+    xmlSecAssert2(key != NULL, -1);
+    xmlSecAssert2(node != NULL, -1);
+    xmlSecAssert2(keyInfoCtx != NULL, -1);
+
+    /* Create a new KeyData from a id */
+    data = xmlSecKeyDataCreate(id);
+    if(data == NULL ) {
+        xmlSecError(XMLSEC_ERRORS_HERE,
+            xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+            "xmlSecKeyDataCreate",
+            XMLSEC_ERRORS_R_XMLSEC_FAILED,
+            XMLSEC_ERRORS_NO_MESSAGE);
+        return(-1);
+    }
+
+    ctx = xmlSecNssSymKeyDataGetCtx(data);
+    xmlSecAssert2(ctx != NULL, -1);
+
+    /* Create a buffer for raw symmetric key value */
+    if( ( keyBuf = xmlSecBufferCreate( 128 ) ) == NULL ) {
+        xmlSecError( XMLSEC_ERRORS_HERE ,
+            xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+            "xmlSecBufferCreate" ,
+            XMLSEC_ERRORS_R_XMLSEC_FAILED ,
+            XMLSEC_ERRORS_NO_MESSAGE ) ;
+		xmlSecKeyDataDestroy( data ) ;
+        return(-1) ;
+    }
+
+    /* Read the raw key value */
+    if( xmlSecBufferBase64NodeContentRead( keyBuf , node ) < 0 ) {
+        xmlSecError( XMLSEC_ERRORS_HERE ,
+            xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+            xmlSecErrorsSafeString(xmlSecNodeGetName(node)),
+            XMLSEC_ERRORS_R_XMLSEC_FAILED ,
+            XMLSEC_ERRORS_NO_MESSAGE ) ;
+
+        xmlSecBufferDestroy( keyBuf ) ;
+		xmlSecKeyDataDestroy( data ) ;
+        return(-1) ;
+    }
+
+    /* Get slot */
+    slot = xmlSecNssSlotGet(ctx->cipher);
+    if( slot == NULL ) {
+        xmlSecError( XMLSEC_ERRORS_HERE ,
+            xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+            "xmlSecNssSlotGet" ,
+            XMLSEC_ERRORS_R_XMLSEC_FAILED ,
+            XMLSEC_ERRORS_NO_MESSAGE ) ;
+
+        xmlSecBufferDestroy( keyBuf ) ;
+		xmlSecKeyDataDestroy( data ) ;
+        return(-1) ;
+    }
+
+    /* Wrap the raw key value SECItem */
+    keyItem.type = siBuffer ;
+    keyItem.data = xmlSecBufferGetData( keyBuf ) ;
+    keyItem.len = xmlSecBufferGetSize( keyBuf ) ;
+
+    /* Import the raw key into slot temporalily and get the key handler*/
+    symKey = PK11_ImportSymKey(slot, ctx->cipher, PK11_OriginGenerated, CKA_VALUE, &keyItem, NULL ) ;
+    if( symKey == NULL ) {
+        xmlSecError( XMLSEC_ERRORS_HERE ,
+            xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+            "PK11_ImportSymKey" ,
+            XMLSEC_ERRORS_R_XMLSEC_FAILED ,
+            XMLSEC_ERRORS_NO_MESSAGE ) ;
+
+		PK11_FreeSlot( slot ) ;
+        xmlSecBufferDestroy( keyBuf ) ;
+		xmlSecKeyDataDestroy( data ) ;
+        return(-1) ;
+    }
+	PK11_FreeSlot( slot ) ;
+
+    /* raw key material has been copied into symKey, it isn't used any more */
+    xmlSecBufferDestroy( keyBuf ) ;
     
-    return(xmlSecKeyDataBinaryValueXmlRead(id, key, node, keyInfoCtx));
+    /* Adopt the symmetric key into key data */
+    ret = xmlSecNssSymKeyDataAdoptKey(data, symKey);
+    if(ret < 0) {
+        xmlSecError(XMLSEC_ERRORS_HERE,
+            xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+            "xmlSecKeyDataBinaryValueSetBuffer",
+            XMLSEC_ERRORS_R_XMLSEC_FAILED,
+            XMLSEC_ERRORS_NO_MESSAGE);
+        PK11_FreeSymKey( symKey ) ;
+		xmlSecKeyDataDestroy( data ) ;
+        return(-1);
+    }
+    /* symKey has been duplicated into data, it isn't used any more */
+    PK11_FreeSymKey( symKey ) ;
+
+    /* Check value */
+    if(xmlSecKeyReqMatchKeyValue(&(keyInfoCtx->keyReq), data) != 1) {
+        xmlSecError(XMLSEC_ERRORS_HERE,
+            xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+            "xmlSecKeyReqMatchKeyValue",
+            XMLSEC_ERRORS_R_XMLSEC_FAILED,
+            XMLSEC_ERRORS_NO_MESSAGE);
+		xmlSecKeyDataDestroy( data ) ;
+        return(0);
+    }
+    
+    ret = xmlSecKeySetValue(key, data);
+    if(ret < 0) {
+        xmlSecError(XMLSEC_ERRORS_HERE,
+            xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+            "xmlSecKeySetValue",
+            XMLSEC_ERRORS_R_XMLSEC_FAILED,
+            XMLSEC_ERRORS_NO_MESSAGE);
+		xmlSecKeyDataDestroy( data ) ;
+        return(-1);
+    }
+
+    return(0);
 }
 
 static int 
 xmlSecNssSymKeyDataXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
 				    xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
+    PK11SymKey* symKey ;
+
     xmlSecAssert2(xmlSecNssSymKeyDataKlassCheck(id), -1);
+    xmlSecAssert2(key != NULL, -1);
+    xmlSecAssert2(node != NULL, -1);
+    xmlSecAssert2(keyInfoCtx != NULL, -1);
+
+	/* Get symmetric key from "key" */
+    symKey = xmlSecNssSymKeyDataGetKey(xmlSecKeyGetValue(key)); 
+    if( symKey != NULL ) {
+        SECItem* keyItem ;
+		xmlSecBufferPtr keyBuf ;
+
+		/* Extract raw key data from symmetric key */
+		if( PK11_ExtractKeyValue( symKey ) != SECSuccess ) {
+        	xmlSecError(XMLSEC_ERRORS_HERE,
+            	xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+            	"PK11_ExtractKeyValue",
+            	XMLSEC_ERRORS_R_XMLSEC_FAILED,
+            	XMLSEC_ERRORS_NO_MESSAGE);
+			PK11_FreeSymKey( symKey ) ;
+        	return(-1);
+		}
+
+		/* Get raw key data from "symKey" */
+        keyItem = PK11_GetKeyData( symKey ) ;
+	    if(keyItem == NULL) {
+        	xmlSecError(XMLSEC_ERRORS_HERE,
+            	xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+            	"PK11_GetKeyData",
+            	XMLSEC_ERRORS_R_XMLSEC_FAILED,
+            	XMLSEC_ERRORS_NO_MESSAGE);
+			PK11_FreeSymKey( symKey ) ;
+        	return(-1);
+    	}
+
+		/* Create key data buffer with raw kwy material */
+		keyBuf = xmlSecBufferCreate(keyItem->len) ;
+	    if(keyBuf == NULL) {
+        	xmlSecError(XMLSEC_ERRORS_HERE,
+            	xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+            	"xmlSecBufferCreate",
+            	XMLSEC_ERRORS_R_XMLSEC_FAILED,
+            	XMLSEC_ERRORS_NO_MESSAGE);
+			PK11_FreeSymKey( symKey ) ;
+        	return(-1);
+    	}
+
+		xmlSecBufferSetData( keyBuf , keyItem->data , keyItem->len ) ;
+
+		/* Write raw key material into current xml node */
+		if( xmlSecBufferBase64NodeContentWrite( keyBuf, node, XMLSEC_BASE64_LINESIZE ) < 0 ) {
+        	xmlSecError(XMLSEC_ERRORS_HERE,
+            	xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+            	"xmlSecBufferBase64NodeContentWrite",
+            	XMLSEC_ERRORS_R_XMLSEC_FAILED,
+            	XMLSEC_ERRORS_NO_MESSAGE);
+			xmlSecBufferDestroy(keyBuf);
+			PK11_FreeSymKey( symKey ) ;
+        	return(-1);
+		}
+		xmlSecBufferDestroy(keyBuf);
+		PK11_FreeSymKey( symKey ) ;
+    }
     
-    return(xmlSecKeyDataBinaryValueXmlWrite(id, key, node, keyInfoCtx));
+    return 0 ;
 }
 
 static int
 xmlSecNssSymKeyDataBinRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
 				    const xmlSecByte* buf, xmlSecSize bufSize,
 				    xmlSecKeyInfoCtxPtr keyInfoCtx) {
-    xmlSecAssert2(xmlSecNssSymKeyDataKlassCheck(id), -1);
+    PK11SymKey* symKey ;
+    PK11SlotInfo* slot ;
+    xmlSecKeyDataPtr data;
+    xmlSecNssSymKeyDataCtxPtr ctx;
+    SECItem keyItem ;
+    int ret;
     
-    return(xmlSecKeyDataBinaryValueBinRead(id, key, buf, bufSize, keyInfoCtx));
+    xmlSecAssert2(id != xmlSecKeyDataIdUnknown, -1);
+    xmlSecAssert2(key != NULL, -1);
+    xmlSecAssert2(buf != NULL, -1);
+    xmlSecAssert2(bufSize != 0, -1);
+    xmlSecAssert2(keyInfoCtx != NULL, -1);
+
+    /* Create a new KeyData from a id */
+    data = xmlSecKeyDataCreate(id);
+    if(data == NULL ) {
+        xmlSecError(XMLSEC_ERRORS_HERE,
+            xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+            "xmlSecKeyDataCreate",
+            XMLSEC_ERRORS_R_XMLSEC_FAILED,
+            XMLSEC_ERRORS_NO_MESSAGE);
+        return(-1);
+    }
+
+    ctx = xmlSecNssSymKeyDataGetCtx(data);
+    xmlSecAssert2(ctx != NULL, -1);
+
+    /* Get slot */
+    slot = xmlSecNssSlotGet(ctx->cipher);
+    if( slot == NULL ) {
+        xmlSecError( XMLSEC_ERRORS_HERE ,
+            xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+            "xmlSecNssSlotGet" ,
+            XMLSEC_ERRORS_R_XMLSEC_FAILED ,
+            XMLSEC_ERRORS_NO_MESSAGE ) ;
+		xmlSecKeyDataDestroy( data ) ;
+        return(-1) ;
+    }
+
+    /* Wrap the raw key value SECItem */
+    keyItem.type = siBuffer ;
+    keyItem.data = buf ;
+    keyItem.len = bufSize ;
+
+    /* Import the raw key into slot temporalily and get the key handler*/
+    symKey = PK11_ImportSymKey(slot, ctx->cipher, PK11_OriginGenerated, CKA_VALUE, &keyItem, NULL ) ;
+    if( symKey == NULL ) {
+        xmlSecError( XMLSEC_ERRORS_HERE ,
+            xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+            "PK11_ImportSymKey" ,
+            XMLSEC_ERRORS_R_XMLSEC_FAILED ,
+            XMLSEC_ERRORS_NO_MESSAGE ) ;
+		PK11_FreeSlot( slot ) ;
+		xmlSecKeyDataDestroy( data ) ;
+        return(-1) ;
+    }
+
+    /* Adopt the symmetric key into key data */
+    ret = xmlSecNssSymKeyDataAdoptKey(data, symKey);
+    if(ret < 0) {
+        xmlSecError(XMLSEC_ERRORS_HERE,
+            xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+            "xmlSecKeyDataBinaryValueSetBuffer",
+            XMLSEC_ERRORS_R_XMLSEC_FAILED,
+            XMLSEC_ERRORS_NO_MESSAGE ) ;
+        PK11_FreeSymKey( symKey ) ;
+		PK11_FreeSlot( slot ) ;
+		xmlSecKeyDataDestroy( data ) ;
+        return(-1);
+    }
+    /* symKey has been duplicated into data, it isn't used any more */
+    PK11_FreeSymKey( symKey ) ;
+	PK11_FreeSlot( slot ) ;
+
+    /* Check value */
+    if(xmlSecKeyReqMatchKeyValue(&(keyInfoCtx->keyReq), data) != 1) {
+        xmlSecError(XMLSEC_ERRORS_HERE,
+            xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+            "xmlSecKeyReqMatchKeyValue",
+            XMLSEC_ERRORS_R_XMLSEC_FAILED,
+            XMLSEC_ERRORS_NO_MESSAGE);
+		xmlSecKeyDataDestroy( data ) ;
+        return(0);
+    }
+    
+    ret = xmlSecKeySetValue(key, data);
+    if(ret < 0) {
+        xmlSecError(XMLSEC_ERRORS_HERE,
+            xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+            "xmlSecKeySetValue",
+            XMLSEC_ERRORS_R_XMLSEC_FAILED,
+            XMLSEC_ERRORS_NO_MESSAGE);
+		xmlSecKeyDataDestroy( data ) ;
+        return(-1);
+    }
+
+    return(0);
 }
 
 static int
 xmlSecNssSymKeyDataBinWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
 				    xmlSecByte** buf, xmlSecSize* bufSize,
 				    xmlSecKeyInfoCtxPtr keyInfoCtx) {
+    PK11SymKey* symKey ;
+
     xmlSecAssert2(xmlSecNssSymKeyDataKlassCheck(id), -1);
+    xmlSecAssert2(key != NULL, -1);
+    xmlSecAssert2(buf != NULL, -1);
+    xmlSecAssert2(bufSize != 0, -1);
+    xmlSecAssert2(keyInfoCtx != NULL, -1);
+
+	/* Get symmetric key from "key" */
+    symKey = xmlSecNssSymKeyDataGetKey(xmlSecKeyGetValue(key)); 
+    if( symKey != NULL ) {
+        SECItem* keyItem ;
+
+		/* Extract raw key data from symmetric key */
+		if( PK11_ExtractKeyValue( symKey ) != SECSuccess ) {
+        	xmlSecError(XMLSEC_ERRORS_HERE,
+            	xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+            	"PK11_ExtractKeyValue",
+            	XMLSEC_ERRORS_R_XMLSEC_FAILED,
+            	XMLSEC_ERRORS_NO_MESSAGE);
+			PK11_FreeSymKey( symKey ) ;
+        	return(-1);
+		}
+
+		/* Get raw key data from "symKey" */
+        keyItem = PK11_GetKeyData( symKey ) ;
+	    if(keyItem == NULL) {
+        	xmlSecError(XMLSEC_ERRORS_HERE,
+            	xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+            	"PK11_GetKeyData",
+            	XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ 	           	XMLSEC_ERRORS_NO_MESSAGE);
+			PK11_FreeSymKey( symKey ) ;
+        	return(-1);
+    	}
+
+		*bufSize = keyItem->len;
+		*buf = ( xmlSecByte* )xmlMalloc( *bufSize );
+		if( *buf == NULL ) {
+        	xmlSecError(XMLSEC_ERRORS_HERE,
+            	xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+            	NULL,
+            	XMLSEC_ERRORS_R_XMLSEC_FAILED,
+            	XMLSEC_ERRORS_NO_MESSAGE);
+			PK11_FreeSymKey( symKey ) ;
+        	return(-1);
+    	}
+
+		memcpy((*buf), keyItem->data, (*bufSize));
+		PK11_FreeSymKey( symKey ) ;
+    }
     
-    return(xmlSecKeyDataBinaryValueBinWrite(id, key, buf, bufSize, keyInfoCtx));
+    return 0 ;
 }
 
 static int
 xmlSecNssSymKeyDataGenerate(xmlSecKeyDataPtr data, xmlSecSize sizeBits, xmlSecKeyDataType type ATTRIBUTE_UNUSED) {
-    xmlSecBufferPtr buffer;
-
+    PK11SymKey* symkey ;
+    PK11SlotInfo* slot ;
+    xmlSecNssSymKeyDataCtxPtr ctx;
+    int ret;
+    
     xmlSecAssert2(xmlSecNssSymKeyDataCheckId(data), -1);
     xmlSecAssert2(sizeBits > 0, -1);
 
-    buffer = xmlSecKeyDataBinaryValueGetBuffer(data);
-    xmlSecAssert2(buffer != NULL, -1);
-    
-    return(xmlSecNssGenerateRandom(buffer, (sizeBits + 7) / 8));
+    ctx = xmlSecNssSymKeyDataGetCtx(data);
+    xmlSecAssert2(ctx != NULL, -1);
+
+	if( sizeBits % 8 != 0 ) {
+       	xmlSecError(XMLSEC_ERRORS_HERE,
+            xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+            NULL,
+            XMLSEC_ERRORS_R_XMLSEC_FAILED,
+            "Symmetric key size must be octuple");
+        return(-1);
+	}
+
+    /* Get slot */
+    slot = xmlSecNssSlotGet(ctx->cipher);
+    if( slot == NULL ) {
+        xmlSecError( XMLSEC_ERRORS_HERE ,
+            xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+            "xmlSecNssSlotGet" ,
+            XMLSEC_ERRORS_R_XMLSEC_FAILED ,
+            XMLSEC_ERRORS_NO_MESSAGE ) ;
+        return(-1) ;
+    }
+
+	if( PK11_Authenticate( slot, PR_FALSE , NULL ) != SECSuccess ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+		    xmlSecErrorsSafeString( xmlSecKeyDataGetName( data ) ) ,
+		    "PK11_Authenticate" ,
+		    XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+		    XMLSEC_ERRORS_NO_MESSAGE ) ;
+		PK11_FreeSlot( slot ) ;
+		return -1 ;
+	}
+
+	symkey = PK11_KeyGen( slot , ctx->cipher , NULL , sizeBits/8 , NULL ) ;
+	if( symkey == NULL ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+		    xmlSecErrorsSafeString( xmlSecKeyDataGetName( data ) ) ,
+		    "PK11_KeyGen" ,
+		    XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+		    XMLSEC_ERRORS_NO_MESSAGE ) ;
+		PK11_FreeSlot( slot ) ;
+		return -1 ;
+	}
+
+	if( ctx->slot != NULL ) {
+		PK11_FreeSlot( ctx->slot ) ;
+		ctx->slot = NULL ;
+	}
+	ctx->slot = slot ;
+
+	if( ctx->symkey != NULL ) {
+		PK11_FreeSymKey( ctx->symkey ) ;
+		ctx->symkey = NULL ;
+	}
+	ctx->symkey = symkey ;
+
+	return 0 ;
 }
 
 static xmlSecKeyDataType
 xmlSecNssSymKeyDataGetType(xmlSecKeyDataPtr data) {
-    xmlSecBufferPtr buffer;
+	xmlSecNssSymKeyDataCtxPtr context = NULL ;
+	xmlSecKeyDataType type = xmlSecKeyDataTypeUnknown ;
 
     xmlSecAssert2(xmlSecNssSymKeyDataCheckId(data), xmlSecKeyDataTypeUnknown);
+	xmlSecAssert2( xmlSecKeyDataCheckSize( data, xmlSecNssSymKeyDataSize ), xmlSecKeyDataTypeUnknown ) ;
 
-    buffer = xmlSecKeyDataBinaryValueGetBuffer(data);
-    xmlSecAssert2(buffer != NULL, xmlSecKeyDataTypeUnknown);
+	context = xmlSecNssSymKeyDataGetCtx( data ) ;
+	if( context == NULL ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+		    xmlSecErrorsSafeString( xmlSecKeyDataGetName( data ) ) ,
+		    "xmlSecNssSymKeyDataGetCtx" ,
+		    XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+		    XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return xmlSecKeyDataTypeUnknown ;
+	}
+
+	if( context->symkey != NULL ) {
+		type |= xmlSecKeyDataTypeSymmetric ;
+	} else {
+		type |= xmlSecKeyDataTypeUnknown ;
+	}
 
-    return((xmlSecBufferGetSize(buffer) > 0) ? xmlSecKeyDataTypeSymmetric : xmlSecKeyDataTypeUnknown);
+	return type ;
 }
 
 static xmlSecSize 
 xmlSecNssSymKeyDataGetSize(xmlSecKeyDataPtr data) {
+	xmlSecNssSymKeyDataCtxPtr context ;
+	unsigned int	length = 0 ;
+
     xmlSecAssert2(xmlSecNssSymKeyDataCheckId(data), 0);
-    
-    return(xmlSecKeyDataBinaryValueGetSize(data));
+	xmlSecAssert2( xmlSecKeyDataCheckSize( data, xmlSecNssSymKeyDataSize ), 0 ) ;
+
+	context = xmlSecNssSymKeyDataGetCtx( data ) ;
+	if( context == NULL ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+		    xmlSecErrorsSafeString( xmlSecKeyDataGetName( data ) ) ,
+		    "xmlSecNssSymKeyDataGetCtx" ,
+		    XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+		    XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return 0 ;
+	}
+
+	if( context->symkey != NULL ) {
+		length = PK11_GetKeyLength( context->symkey ) ;
+		length *= 8 ;
+	}
+
+	return length ;
 }
 
 static void 
 xmlSecNssSymKeyDataDebugDump(xmlSecKeyDataPtr data, FILE* output) {
     xmlSecAssert(xmlSecNssSymKeyDataCheckId(data));
     
-    xmlSecKeyDataBinaryValueDebugDump(data, output);    
+	/* print only size, everything else is sensitive */
+	fprintf( output , "=== %s: size=%d\n" , data->id->dataNodeName ,
+											xmlSecKeyDataGetSize(data)) ;
 }
 
 static void
 xmlSecNssSymKeyDataDebugXmlDump(xmlSecKeyDataPtr data, FILE* output) {
     xmlSecAssert(xmlSecNssSymKeyDataCheckId(data));
     
-    xmlSecKeyDataBinaryValueDebugXmlDump(data, output);    
+	/* print only size, everything else is sensitive */
+	fprintf( output , "<%s size=\"%d\" />\n" , data->id->dataNodeName ,
+											xmlSecKeyDataGetSize(data)) ;
 }
 
 static int 
@@ -201,7 +738,7 @@
  *************************************************************************/
 static xmlSecKeyDataKlass xmlSecNssKeyDataAesKlass = {
     sizeof(xmlSecKeyDataKlass),
-    xmlSecKeyDataBinarySize,
+    xmlSecNssSymKeyDataSize,
 
     /* data */
     xmlSecNameAESKeyValue,
@@ -282,7 +819,7 @@
  *************************************************************************/
 static xmlSecKeyDataKlass xmlSecNssKeyDataDesKlass = {
     sizeof(xmlSecKeyDataKlass),
-    xmlSecKeyDataBinarySize,
+    xmlSecNssSymKeyDataSize,
 
     /* data */
     xmlSecNameDESKeyValue,
@@ -364,7 +901,7 @@
  *************************************************************************/
 static xmlSecKeyDataKlass xmlSecNssKeyDataHmacKlass = {
     sizeof(xmlSecKeyDataKlass),
-    xmlSecKeyDataBinarySize,
+    xmlSecNssSymKeyDataSize,
 
     /* data */
     xmlSecNameHMACKeyValue,
@@ -435,6 +972,126 @@
     
     return(xmlSecBufferSetData(buffer, buf, bufSize));
 }
+/**
+ * xmlSecNssSymKeyDataAdoptKey:
+ * @data:				the pointer to symmetric key data.
+ * @symkey:				the symmetric key
+ *
+ * Set the value of symmetric key data.
+ *
+ * Returns 0 on success or a negative value if an error occurs.
+ */
+int
+xmlSecNssSymKeyDataAdoptKey(
+	xmlSecKeyDataPtr data ,
+	PK11SymKey* symkey
+) {
+	xmlSecNssSymKeyDataCtxPtr context = NULL ;
+
+	xmlSecAssert2( xmlSecNssSymKeyDataCheckId( data ), -1 ) ;
+	xmlSecAssert2( xmlSecKeyDataCheckSize( data, xmlSecNssSymKeyDataSize ), -1 ) ;
+	xmlSecAssert2( symkey != NULL, -1 ) ;
+
+	context = xmlSecNssSymKeyDataGetCtx( data ) ;
+	xmlSecAssert2(context != NULL, -1);
+
+	context->cipher = PK11_GetMechanism( symkey ) ;
+
+	if( context->slot != NULL ) {
+		PK11_FreeSlot( context->slot ) ;
+		context->slot = NULL ;
+	}
+	context->slot = PK11_GetSlotFromKey( symkey ) ;
+
+	if( context->symkey != NULL ) {
+		PK11_FreeSymKey( context->symkey ) ;
+		context->symkey = NULL ;
+	}
+	context->symkey = PK11_ReferenceSymKey( symkey ) ;
+
+	return 0 ;
+}
+
+xmlSecKeyDataPtr xmlSecNssSymKeyDataKeyAdopt(
+    PK11SymKey*     symKey
+) {
+	xmlSecKeyDataPtr	data = NULL ;
+	CK_MECHANISM_TYPE	mechanism = CKM_INVALID_MECHANISM ;
+
+	xmlSecAssert2( symKey != NULL , NULL ) ;
+
+	mechanism = PK11_GetMechanism( symKey ) ;
+	switch( mechanism ) {
+		case CKM_DES3_KEY_GEN :
+		case CKM_DES3_CBC :
+		case CKM_DES3_MAC :
+			data = xmlSecKeyDataCreate( xmlSecNssKeyDataDesId ) ;
+			if( data == NULL ) {
+				xmlSecError( XMLSEC_ERRORS_HERE ,
+					NULL ,
+					"xmlSecKeyDataCreate" ,
+					XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+					"xmlSecNssKeyDataDesId" ) ;
+				return NULL ;
+			}
+			break ;
+		case CKM_AES_KEY_GEN :
+		case CKM_AES_CBC :
+		case CKM_AES_MAC :
+			data = xmlSecKeyDataCreate( xmlSecNssKeyDataAesId ) ;
+			if( data == NULL ) {
+				xmlSecError( XMLSEC_ERRORS_HERE ,
+					NULL ,
+					"xmlSecKeyDataCreate" ,
+					XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+					"xmlSecNssKeyDataDesId" ) ;
+				return NULL ;
+			}
+			break ;
+		default :
+			xmlSecError( XMLSEC_ERRORS_HERE ,
+				NULL ,
+				NULL ,
+				XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+				"Unsupported mechanism" ) ;
+			return NULL ;
+	}
+
+	if( xmlSecNssSymKeyDataAdoptKey( data , symKey ) < 0 ) {
+		xmlSecError( XMLSEC_ERRORS_HERE ,
+			NULL ,
+			"xmlSecNssSymKeyDataAdoptKey" ,
+			XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+			XMLSEC_ERRORS_NO_MESSAGE ) ;
+
+		xmlSecKeyDataDestroy( data ) ;
+		return NULL ;
+	}
 
+	return data ;
+}
+
+
+PK11SymKey*
+xmlSecNssSymKeyDataGetKey(
+    xmlSecKeyDataPtr data
+) {
+    xmlSecNssSymKeyDataCtxPtr ctx;
+    PK11SymKey* symkey ;
+
+    xmlSecAssert2(xmlSecNssSymKeyDataCheckId(data), NULL);
+    xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecNssSymKeyDataSize), NULL);
+
+    ctx = xmlSecNssSymKeyDataGetCtx(data);
+    xmlSecAssert2(ctx != NULL, NULL);
+
+    if( ctx->symkey != NULL ) {
+        symkey = PK11_ReferenceSymKey( ctx->symkey ) ;
+    } else {
+        symkey = NULL ;
+    }
+
+    return(symkey);
+}
 #endif /* XMLSEC_NO_HMAC */
 
Index: xmlsec/src/nss/x509.c
===================================================================
RCS file: /cvs/gnome/xmlsec/src/nss/x509.c,v
retrieving revision 1.5
diff -u -r1.5 x509.c
--- xmlsec/src/nss/x509.c	26 Sep 2003 03:53:09 -0000	1.5
+++ xmlsec/src/nss/x509.c	6 Feb 2005 03:53:24 -0000
@@ -34,7 +34,6 @@
 #include <xmlsec/keys.h>
 #include <xmlsec/keyinfo.h>
 #include <xmlsec/keysmngr.h>
-#include <xmlsec/x509.h>
 #include <xmlsec/base64.h>
 #include <xmlsec/errors.h>
 
@@ -61,33 +60,18 @@
 static int		xmlSecNssX509CertificateNodeRead	(xmlSecKeyDataPtr data,
 								 xmlNodePtr node,
 								 xmlSecKeyInfoCtxPtr keyInfoCtx);
-static int		xmlSecNssX509CertificateNodeWrite	(CERTCertificate* cert,
-								 xmlNodePtr node,
-								 xmlSecKeyInfoCtxPtr keyInfoCtx);
 static int		xmlSecNssX509SubjectNameNodeRead	(xmlSecKeyDataPtr data,
 								 xmlNodePtr node,
 								 xmlSecKeyInfoCtxPtr keyInfoCtx);
-static int		xmlSecNssX509SubjectNameNodeWrite	(CERTCertificate* cert,
-								 xmlNodePtr node,
-								 xmlSecKeyInfoCtxPtr keyInfoCtx);
 static int		xmlSecNssX509IssuerSerialNodeRead	(xmlSecKeyDataPtr data,
 								 xmlNodePtr node,
 								 xmlSecKeyInfoCtxPtr keyInfoCtx);
-static int		xmlSecNssX509IssuerSerialNodeWrite	(CERTCertificate* cert,
-								 xmlNodePtr node,
-								 xmlSecKeyInfoCtxPtr keyInfoCtx);
 static int		xmlSecNssX509SKINodeRead		(xmlSecKeyDataPtr data,
 								 xmlNodePtr node,
 								 xmlSecKeyInfoCtxPtr keyInfoCtx);
-static int		xmlSecNssX509SKINodeWrite		(CERTCertificate* cert,
-								 xmlNodePtr node,
-								 xmlSecKeyInfoCtxPtr keyInfoCtx);
 static int		xmlSecNssX509CRLNodeRead		(xmlSecKeyDataPtr data,
 								 xmlNodePtr node,
 								 xmlSecKeyInfoCtxPtr keyInfoCtx);
-static int		xmlSecNssX509CRLNodeWrite		(CERTSignedCrl* crl,
-								 xmlNodePtr node,
-								 xmlSecKeyInfoCtxPtr keyInfoCtx);
 static int		xmlSecNssKeyDataX509VerifyAndExtractKey(xmlSecKeyDataPtr data, 
 								xmlSecKeyPtr key,
 								xmlSecKeyInfoCtxPtr keyInfoCtx);
@@ -104,9 +88,6 @@
 								 xmlSecKeyInfoCtxPtr keyInfoCtx);
 static xmlChar*		xmlSecNssX509CrlBase64DerWrite		(CERTSignedCrl* crl, 
 								 int base64LineWrap);
-static xmlChar*		xmlSecNssX509NameWrite			(CERTName* nm);
-static xmlChar*		xmlSecNssASN1IntegerWrite		(SECItem *num);
-static xmlChar*		xmlSecNssX509SKIWrite			(CERTCertificate* cert);
 static void		xmlSecNssX509CertDebugDump		(CERTCertificate* cert, 
 								 FILE* output);
 static void		xmlSecNssX509CertDebugXmlDump		(CERTCertificate* cert, 
@@ -378,7 +359,7 @@
 			xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
 			"CERT_NewCertList",
 			XMLSEC_ERRORS_R_CRYPTO_FAILED,
-			XMLSEC_ERRORS_NO_MESSAGE);
+			"error code=%d", PORT_GetError());
 	    return(-1);	
 	}
     }
@@ -389,7 +370,7 @@
 		    xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
 		    "CERT_AddCertToListTail",
 		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-		    XMLSEC_ERRORS_NO_MESSAGE);
+		    "error code=%d", PORT_GetError());
 	return(-1);	
     }
     ctx->numCerts++;
@@ -588,7 +569,7 @@
 			xmlSecErrorsSafeString(xmlSecKeyDataGetName(dst)),
 			"CERT_DupCertificate",
 			XMLSEC_ERRORS_R_CRYPTO_FAILED,
-			XMLSEC_ERRORS_NO_MESSAGE);
+			"error code=%d", PORT_GetError());
 	    return(-1);
 	}
 	
@@ -627,7 +608,7 @@
                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(dst)),
                         "SEC_DupCrl",
                         XMLSEC_ERRORS_R_CRYPTO_FAILED,
-                        XMLSEC_ERRORS_NO_MESSAGE);
+                        "error code=%d", PORT_GetError());
             return(-1);
         }
 
@@ -652,7 +633,7 @@
 			xmlSecErrorsSafeString(xmlSecKeyDataGetName(dst)),
 			"CERT_DupCertificate",
 			XMLSEC_ERRORS_R_CRYPTO_FAILED,
-			XMLSEC_ERRORS_NO_MESSAGE);
+			"error code=%d", PORT_GetError());
 	    return(-1);
 	}
 	ret = xmlSecNssKeyDataX509AdoptKeyCert(dst, certDst);
@@ -752,30 +733,21 @@
 xmlSecNssKeyDataX509XmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
 				xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
     xmlSecKeyDataPtr data;
+    xmlNodePtr cur;
+    xmlChar* buf;
     CERTCertificate* cert;
     CERTSignedCrl* crl;
     xmlSecSize size, pos;
-    int content = 0;
-    int ret;
     				
     xmlSecAssert2(id == xmlSecNssKeyDataX509Id, -1);
     xmlSecAssert2(key != NULL, -1);
     xmlSecAssert2(node != NULL, -1);
     xmlSecAssert2(keyInfoCtx != NULL, -1);
 
-    content = xmlSecX509DataGetNodeContent (node, 1, keyInfoCtx);
-    if (content < 0) {
-	xmlSecError(XMLSEC_ERRORS_HERE,
-		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
-		    "xmlSecX509DataGetNodeContent",
-		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-		    "content=%d", content);
-	return(-1);
-    } else if(content == 0) {
-	/* by default we are writing certificates and crls */
-	content = XMLSEC_X509DATA_DEFAULT;
+    /* todo: flag in ctx remove all existing content */
+    if(0) {
+        xmlNodeSetContent(node, NULL);
     }
-
     /* get x509 data */
     data = xmlSecKeyGetData(key, id);
     if(data == NULL) {
@@ -795,80 +767,75 @@
 			"pos=%d", pos);
 	    return(-1);
 	}
-
-	if((content & XMLSEC_X509DATA_CERTIFICATE_NODE) != 0) {
-	    ret = xmlSecNssX509CertificateNodeWrite(cert, node, keyInfoCtx);
-	    if(ret < 0) {
-		xmlSecError(XMLSEC_ERRORS_HERE,
-			    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
-			    "xmlSecNssX509CertificateNodeWrite",
-			    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-			    "pos=%d", pos);
-		return(-1);
-	    }
+	
+	/* set base64 lines size from context */
+	buf = xmlSecNssX509CertBase64DerWrite(cert, keyInfoCtx->base64LineSize); 
+	if(buf == NULL) {
+	    xmlSecError(XMLSEC_ERRORS_HERE,
+			xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+			"xmlSecNssX509CertBase64DerWrite",
+			XMLSEC_ERRORS_R_XMLSEC_FAILED,
+			XMLSEC_ERRORS_NO_MESSAGE);
+	    return(-1);
 	}
-
-	if((content & XMLSEC_X509DATA_SUBJECTNAME_NODE) != 0) {
-	    ret = xmlSecNssX509SubjectNameNodeWrite(cert, node, keyInfoCtx);
-	    if(ret < 0) {
-		xmlSecError(XMLSEC_ERRORS_HERE,
-			    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
-			    "xmlSecNssX509SubjectNameNodeWrite",
-			    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-			    "pos=%d", pos);
-		return(-1);
-	    }
+	
+	cur = xmlSecAddChild(node, xmlSecNodeX509Certificate, xmlSecDSigNs);
+	if(cur == NULL) {
+	    xmlSecError(XMLSEC_ERRORS_HERE,
+			xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+			"xmlSecAddChild",
+			XMLSEC_ERRORS_R_XMLSEC_FAILED,
+			"node=%s",
+			xmlSecErrorsSafeString(xmlSecNodeX509Certificate));
+	    xmlFree(buf);
+	    return(-1);	
 	}
+	/* todo: add \n around base64 data - from context */
+	/* todo: add errors check */
+	xmlNodeSetContent(cur, xmlSecStringCR);
+	xmlNodeSetContent(cur, buf);
+	xmlFree(buf);
+    }    
 
-	if((content & XMLSEC_X509DATA_ISSUERSERIAL_NODE) != 0) {
-	    ret = xmlSecNssX509IssuerSerialNodeWrite(cert, node, keyInfoCtx);
-	    if(ret < 0) {
-		xmlSecError(XMLSEC_ERRORS_HERE,
-			    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
-			    "xmlSecNssX509IssuerSerialNodeWrite",
-			    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-			    "pos=%d", pos);
-		return(-1);
-	    }
-	}
+    /* write crls */
+    size = xmlSecNssKeyDataX509GetCrlsSize(data);
+    for(pos = 0; pos < size; ++pos) {
+        crl = xmlSecNssKeyDataX509GetCrl(data, pos);
+        if(crl == NULL) {
+            xmlSecError(XMLSEC_ERRORS_HERE,
+                        xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+                        "xmlSecNssKeyDataX509GetCrl",
+                        XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                        "pos=%d", pos);
+            return(-1);
+        }
 
-	if((content & XMLSEC_X509DATA_SKI_NODE) != 0) {
-	    ret = xmlSecNssX509SKINodeWrite(cert, node, keyInfoCtx);
-	    if(ret < 0) {
-		xmlSecError(XMLSEC_ERRORS_HERE,
-			    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
-			    "xmlSecNssX509SKINodeWrite",
-			    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-			    "pos=%d", pos);
-		return(-1);
-	    }
-	}
-    }    
+        /* set base64 lines size from context */
+        buf = xmlSecNssX509CrlBase64DerWrite(crl, keyInfoCtx->base64LineSize);
+        if(buf == NULL) {
+            xmlSecError(XMLSEC_ERRORS_HERE,
+                        xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+                        "xmlSecNssX509CrlBase64DerWrite",
+                        XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                        XMLSEC_ERRORS_NO_MESSAGE);
+            return(-1);
+        }
 
-    /* write crls if needed */
-    if((content & XMLSEC_X509DATA_CRL_NODE) != 0) {
-	size = xmlSecNssKeyDataX509GetCrlsSize(data);
-	for(pos = 0; pos < size; ++pos) {
-	    crl = xmlSecNssKeyDataX509GetCrl(data, pos);
-	    if(crl == NULL) {
-		xmlSecError(XMLSEC_ERRORS_HERE,
-			    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
-			    "xmlSecNssKeyDataX509GetCrl",
-			    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-			    "pos=%d", pos);
-		return(-1);
-	    }
-	    
-	    ret = xmlSecNssX509CRLNodeWrite(crl, node, keyInfoCtx);
-	    if(ret < 0) {
-		xmlSecError(XMLSEC_ERRORS_HERE,
-			    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
-			    "xmlSecNssX509CRLNodeWrite",
-			    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-			    "pos=%d", pos);
-		return(-1);
-	    }
-	}
+        cur = xmlSecAddChild(node, xmlSecNodeX509CRL, xmlSecDSigNs);
+        if(cur == NULL) {
+            xmlSecError(XMLSEC_ERRORS_HERE,
+                        xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+                        "xmlSecAddChild",
+                        XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                        "new_node=%s",
+                        xmlSecErrorsSafeString(xmlSecNodeX509CRL));
+            xmlFree(buf);
+            return(-1);
+        }
+        /* todo: add \n around base64 data - from context */
+        /* todo: add errors check */
+        xmlNodeSetContent(cur, xmlSecStringCR);
+        xmlNodeSetContent(cur, buf);
     }
 
     return(0);
@@ -1015,19 +982,13 @@
     xmlSecAssert2(keyInfoCtx != NULL, -1);
 
     content = xmlNodeGetContent(node);
-    if((content == NULL) || (xmlSecIsEmptyString(content) == 1)) {
-	if(content != NULL) {
-	    xmlFree(content);
-	}
-	if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_STOP_ON_EMPTY_NODE) != 0) {
-	    xmlSecError(XMLSEC_ERRORS_HERE,
-			xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
-			xmlSecErrorsSafeString(xmlSecNodeGetName(node)),
-			XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,
-			XMLSEC_ERRORS_NO_MESSAGE);
-	    return(-1);
-	}
-	return(0);
+    if(content == NULL){
+	xmlSecError(XMLSEC_ERRORS_HERE,
+		    xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+		    xmlSecErrorsSafeString(xmlSecNodeGetName(node)),
+		    XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,
+		    XMLSEC_ERRORS_NO_MESSAGE);
+	return(-1);
     }
 
     cert = xmlSecNssX509CertBase64DerRead(content);
@@ -1058,46 +1019,6 @@
 }
 
 static int 
-xmlSecNssX509CertificateNodeWrite(CERTCertificate* cert, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
-    xmlChar* buf;
-    xmlNodePtr cur;
-    
-    xmlSecAssert2(cert != NULL, -1);
-    xmlSecAssert2(node != NULL, -1);
-    xmlSecAssert2(keyInfoCtx != NULL, -1);
-    
-    /* set base64 lines size from context */
-    buf = xmlSecNssX509CertBase64DerWrite(cert, keyInfoCtx->base64LineSize); 
-    if(buf == NULL) {
-	xmlSecError(XMLSEC_ERRORS_HERE,
-		    NULL,
-		    "xmlSecNssX509CertBase64DerWrite",
-		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-		    XMLSEC_ERRORS_NO_MESSAGE);
-	return(-1);
-    }
-	
-    cur = xmlSecAddChild(node, xmlSecNodeX509Certificate, xmlSecDSigNs);
-    if(cur == NULL) {
-	xmlSecError(XMLSEC_ERRORS_HERE,
-		    NULL,
-		    "xmlSecAddChild",
-		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-		    "node=%s",
-		    xmlSecErrorsSafeString(xmlSecNodeX509Certificate));
-	xmlFree(buf);
-	return(-1);	
-    }
-
-    /* todo: add \n around base64 data - from context */
-    /* todo: add errors check */
-    xmlNodeSetContent(cur, xmlSecStringCR);
-    xmlNodeSetContent(cur, buf);
-    xmlFree(buf);
-    return(0);
-}
-
-static int		
 xmlSecNssX509SubjectNameNodeRead(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {	
     xmlSecKeyDataStorePtr x509Store;
     xmlChar* subject;
@@ -1120,19 +1041,13 @@
     }
 
     subject = xmlNodeGetContent(node);
-    if((subject == NULL) || (xmlSecIsEmptyString(subject) == 1)) {
-	if(subject != NULL) {
-	    xmlFree(subject);
-	}
-	if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_STOP_ON_EMPTY_NODE) != 0) {
-	    xmlSecError(XMLSEC_ERRORS_HERE,
-		        xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
-			xmlSecErrorsSafeString(xmlSecNodeGetName(node)),
-			XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,
-			XMLSEC_ERRORS_NO_MESSAGE);
-	    return(-1);
-	}
-	return(0);
+    if(subject == NULL) {
+	xmlSecError(XMLSEC_ERRORS_HERE,
+		    xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+		    xmlSecErrorsSafeString(xmlSecNodeGetName(node)),
+		    XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,
+		    XMLSEC_ERRORS_NO_MESSAGE);
+	return(-1);
     }
 
     cert = xmlSecNssX509StoreFindCert(x509Store, subject, NULL, NULL, NULL, keyInfoCtx);
@@ -1168,40 +1083,6 @@
 }
 
 static int
-xmlSecNssX509SubjectNameNodeWrite(CERTCertificate* cert, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx ATTRIBUTE_UNUSED) {
-    xmlChar* buf = NULL;
-    xmlNodePtr cur = NULL;
-
-    xmlSecAssert2(cert != NULL, -1);
-    xmlSecAssert2(node != NULL, -1);
-
-    buf = xmlSecNssX509NameWrite(&(cert->subject));
-    if(buf == NULL) {
-	xmlSecError(XMLSEC_ERRORS_HERE,
-	    NULL,
-	    "xmlSecNssX509NameWrite(&(cert->subject))",
-	    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-	    XMLSEC_ERRORS_NO_MESSAGE);
-	return(-1);
-    }
-
-    cur = xmlSecAddChild(node, xmlSecNodeX509SubjectName, xmlSecDSigNs);
-    if(cur == NULL) {
-	xmlSecError(XMLSEC_ERRORS_HERE,
-	    NULL,
-	    "xmlSecAddChild",
-	    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-	    "node=%s",
-	    xmlSecErrorsSafeString(xmlSecNodeX509SubjectName));
-	xmlFree(buf);
-	return(-1);
-    }
-    xmlNodeSetContent(cur, buf);
-    xmlFree(buf);
-    return(0);
-}
-
-static int 
 xmlSecNssX509IssuerSerialNodeRead(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
     xmlSecKeyDataStorePtr x509Store;
     xmlNodePtr cur;
@@ -1226,21 +1107,9 @@
     }
 
     cur = xmlSecGetNextElementNode(node->children);
-    if(cur == NULL) {
-	if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_STOP_ON_EMPTY_NODE) != 0) {
-	    xmlSecError(XMLSEC_ERRORS_HERE,
-			xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
-			xmlSecErrorsSafeString(xmlSecNodeX509IssuerName),
-			XMLSEC_ERRORS_R_NODE_NOT_FOUND,
-			"node=%s",
-			xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
-	    return(-1);
-	}
-	return(0);
-    }
-    
+
     /* the first is required node X509IssuerName */
-    if(!xmlSecCheckNodeName(cur, xmlSecNodeX509IssuerName, xmlSecDSigNs)) {
+    if((cur == NULL) || !xmlSecCheckNodeName(cur, xmlSecNodeX509IssuerName, xmlSecDSigNs)) {
 	xmlSecError(XMLSEC_ERRORS_HERE,
 		    xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
 		    xmlSecErrorsSafeString(xmlSecNodeX509IssuerName),
@@ -1333,78 +1202,6 @@
 }
 
 static int
-xmlSecNssX509IssuerSerialNodeWrite(CERTCertificate* cert, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx ATTRIBUTE_UNUSED) {
-    xmlNodePtr cur;
-    xmlNodePtr issuerNameNode;
-    xmlNodePtr issuerNumberNode;
-    xmlChar* buf;
-    
-    xmlSecAssert2(cert != NULL, -1);
-    xmlSecAssert2(node != NULL, -1);
-
-    /* create xml nodes */
-    cur = xmlSecAddChild(node, xmlSecNodeX509IssuerSerial, xmlSecDSigNs);
-    if(cur == NULL) {
-	xmlSecError(XMLSEC_ERRORS_HERE,
-		    NULL,
-		    "xmlSecAddChild",
-		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-		    "node=%s",
-		    xmlSecErrorsSafeString(xmlSecNodeX509IssuerSerial));
-	return(-1);
-    }
-
-    issuerNameNode = xmlSecAddChild(cur, xmlSecNodeX509IssuerName, xmlSecDSigNs);
-    if(issuerNameNode == NULL) {
-	xmlSecError(XMLSEC_ERRORS_HERE,
-		    NULL,
-		    "xmlSecAddChild",
-		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-		    "node=%s",
-		    xmlSecErrorsSafeString(xmlSecNodeX509IssuerName));
-	return(-1);
-    }
-
-    issuerNumberNode = xmlSecAddChild(cur, xmlSecNodeX509SerialNumber, xmlSecDSigNs);
-    if(issuerNumberNode == NULL) {
-	xmlSecError(XMLSEC_ERRORS_HERE,
-		    NULL,
-		    "xmlSecAddChild",
-		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-		    "node=%s",
-		    xmlSecErrorsSafeString(xmlSecNodeX509SerialNumber));
-	return(-1);
-    }
-
-    /* write data */
-    buf = xmlSecNssX509NameWrite(&(cert->issuer));
-    if(buf == NULL) {
-	xmlSecError(XMLSEC_ERRORS_HERE,
-		    NULL,
-		    "xmlSecNssX509NameWrite(&(cert->issuer))",
-		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-		    XMLSEC_ERRORS_NO_MESSAGE);
-	return(-1);
-    }
-    xmlNodeSetContent(issuerNameNode, buf);
-    xmlFree(buf);
-
-    buf = xmlSecNssASN1IntegerWrite(&(cert->serialNumber));
-    if(buf == NULL) {
-	xmlSecError(XMLSEC_ERRORS_HERE,
-		    NULL,
-		    "xmlSecNssASN1IntegerWrite(&(cert->serialNumber))",
-		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-		    XMLSEC_ERRORS_NO_MESSAGE);
-	return(-1);
-    }
-    xmlNodeSetContent(issuerNumberNode, buf);
-    xmlFree(buf);
-
-    return(0);
-}
-
-static int 
 xmlSecNssX509SKINodeRead(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
     xmlSecKeyDataStorePtr x509Store;
     xmlChar* ski;
@@ -1427,20 +1224,14 @@
     }
     
     ski = xmlNodeGetContent(node);
-    if((ski == NULL) || (xmlSecIsEmptyString(ski) == 1)) {
-	if(ski != NULL) {
-	    xmlFree(ski);
-	}
-	if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_STOP_ON_EMPTY_NODE) != 0) {
-	    xmlSecError(XMLSEC_ERRORS_HERE,
-			xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
-			xmlSecErrorsSafeString(xmlSecNodeGetName(node)),
-			XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,
-			"node=%s",
-			xmlSecErrorsSafeString(xmlSecNodeX509SKI));
-	    return(-1);
-	}
-	return(0);
+    if(ski == NULL) {
+	xmlSecError(XMLSEC_ERRORS_HERE,
+		    xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+		    xmlSecErrorsSafeString(xmlSecNodeGetName(node)),
+		    XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,
+		    "node=%s",
+		    xmlSecErrorsSafeString(xmlSecNodeX509SKI));
+	return(-1);
     }
 
     cert = xmlSecNssX509StoreFindCert(x509Store, NULL, NULL, NULL, ski, keyInfoCtx);
@@ -1476,41 +1267,6 @@
 }
 
 static int
-xmlSecNssX509SKINodeWrite(CERTCertificate* cert, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx ATTRIBUTE_UNUSED) {
-    xmlChar *buf = NULL;
-    xmlNodePtr cur = NULL;
-
-    xmlSecAssert2(cert != NULL, -1);
-    xmlSecAssert2(node != NULL, -1);
-
-    buf = xmlSecNssX509SKIWrite(cert);
-    if(buf == NULL) {
-	xmlSecError(XMLSEC_ERRORS_HERE,
-		    NULL,
-		    "xmlSecNssX509SKIWrite",
-		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-		    XMLSEC_ERRORS_NO_MESSAGE);
-	return(-1);
-    }
-
-    cur = xmlSecAddChild(node, xmlSecNodeX509SKI, xmlSecDSigNs);
-    if(cur == NULL) {
-	xmlSecError(XMLSEC_ERRORS_HERE,
-		    NULL,
-		    "xmlSecAddChild",
-		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-		    "new_node=%s",
-		    xmlSecErrorsSafeString(xmlSecNodeX509SKI));
-	xmlFree(buf);
-	return(-1);
-    }
-    xmlNodeSetContent(cur, buf);
-    xmlFree(buf);
-
-    return(0);
-}
-
-static int 
 xmlSecNssX509CRLNodeRead(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
     xmlChar *content;
     CERTSignedCrl* crl;
@@ -1520,19 +1276,13 @@
     xmlSecAssert2(keyInfoCtx != NULL, -1);
 
     content = xmlNodeGetContent(node);
-   if((content == NULL) || (xmlSecIsEmptyString(content) == 1)) {
-	if(content != NULL) {
-	    xmlFree(content);
-	}
-	if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_STOP_ON_EMPTY_NODE) != 0) {
-	    xmlSecError(XMLSEC_ERRORS_HERE,
-			xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
-			xmlSecErrorsSafeString(xmlSecNodeGetName(node)),
-			XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,
-			XMLSEC_ERRORS_NO_MESSAGE);
-	    return(-1);
-	}
-	return(0);
+    if(content == NULL){
+	xmlSecError(XMLSEC_ERRORS_HERE,
+		    xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+		    xmlSecErrorsSafeString(xmlSecNodeGetName(node)),
+		    XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,
+		    XMLSEC_ERRORS_NO_MESSAGE);
+	return(-1);
     }
 
     crl = xmlSecNssX509CrlBase64DerRead(content, keyInfoCtx);
@@ -1552,47 +1302,6 @@
 }
 
 static int
-xmlSecNssX509CRLNodeWrite(CERTSignedCrl* crl, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
-    xmlChar* buf = NULL;
-    xmlNodePtr cur = NULL;
-
-    xmlSecAssert2(crl != NULL, -1);
-    xmlSecAssert2(node != NULL, -1);
-    xmlSecAssert2(keyInfoCtx != NULL, -1);
-
-    /* set base64 lines size from context */
-    buf = xmlSecNssX509CrlBase64DerWrite(crl, keyInfoCtx->base64LineSize); 
-    if(buf == NULL) {
-	xmlSecError(XMLSEC_ERRORS_HERE,
-		    NULL,
-		    "xmlSecNssX509CrlBase64DerWrite",
-		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-		    XMLSEC_ERRORS_NO_MESSAGE);
-	return(-1);
-    }
-
-    cur = xmlSecAddChild(node, xmlSecNodeX509CRL, xmlSecDSigNs);
-    if(cur == NULL) {
-	xmlSecError(XMLSEC_ERRORS_HERE,
-		    NULL,
-		    "xmlSecAddChild",
-		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-		    "new_node=%s",
-		    xmlSecErrorsSafeString(xmlSecNodeX509CRL));
-	xmlFree(buf);
-	return(-1);
-    }
-    /* todo: add \n around base64 data - from context */
-    /* todo: add errors check */
-    xmlNodeSetContent(cur, xmlSecStringCR);
-    xmlNodeSetContent(cur, buf);
-    xmlFree(buf);
-
-    return(0);
-}
-
-
-static int
 xmlSecNssKeyDataX509VerifyAndExtractKey(xmlSecKeyDataPtr data, xmlSecKeyPtr key,
 				    xmlSecKeyInfoCtxPtr keyInfoCtx) {
     xmlSecNssX509DataCtxPtr ctx;
@@ -1600,6 +1309,10 @@
     int ret;
     SECStatus status;
     PRTime notBefore, notAfter;
+
+    PK11SlotInfo* slot ;
+    SECKEYPublicKey *pubKey = NULL;
+    SECKEYPrivateKey *priKey = NULL;
     
     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecNssKeyDataX509Id), -1);
     xmlSecAssert2(key != NULL, -1);
@@ -1632,10 +1345,13 @@
 			    xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
 			    "CERT_DupCertificate",
 			    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-			    XMLSEC_ERRORS_NO_MESSAGE);
+			    "error code=%d", PORT_GetError());
 		return(-1);
 	    }
 	
+		/*-
+		 * Get Public key from cert, which does not always work for sign action.
+         *
 	    keyValue = xmlSecNssX509CertGetKey(ctx->keyCert);
 	    if(keyValue == NULL) {
 		xmlSecError(XMLSEC_ERRORS_HERE,
@@ -1645,6 +1361,54 @@
 			    XMLSEC_ERRORS_NO_MESSAGE);
 		return(-1);
 	    }
+		 */
+
+		/*-
+		 * I'll search key according to KeyReq.
+		 */
+        slot = cert->slot ;
+        if( ( keyInfoCtx->keyReq.keyType & xmlSecKeyDataTypePrivate ) == xmlSecKeyDataTypePrivate ) {
+            if( ( priKey = PK11_FindPrivateKeyFromCert( slot , cert , NULL ) ) == NULL ) {
+                xmlSecError( XMLSEC_ERRORS_HERE ,
+                    xmlSecErrorsSafeString( xmlSecKeyDataGetName( data ) ) ,
+                    "PK11_FindPrivateKeyFromCert" ,
+                    XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+                    XMLSEC_ERRORS_NO_MESSAGE ) ;
+                return -1 ;
+            }
+        }
+
+		if( ( keyInfoCtx->keyReq.keyType & xmlSecKeyDataTypePublic ) == xmlSecKeyDataTypePublic ) {
+            if( ( pubKey = CERT_ExtractPublicKey( cert ) ) == NULL ) {
+                xmlSecError( XMLSEC_ERRORS_HERE ,
+                    xmlSecErrorsSafeString( xmlSecKeyDataGetName( data ) ) ,
+                    "CERT_ExtractPublicKey" ,
+                    XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+                    XMLSEC_ERRORS_NO_MESSAGE ) ;
+
+				if( priKey != NULL )
+					SECKEY_DestroyPrivateKey( priKey ) ;
+                return -1 ;
+            }
+        }
+
+        keyValue = xmlSecNssPKIAdoptKey(priKey, pubKey);
+		if( keyValue == NULL ) {
+            xmlSecError( XMLSEC_ERRORS_HERE ,
+                xmlSecErrorsSafeString( xmlSecKeyDataGetName( data ) ) ,
+                "xmlSecNssPKIAdoptKey" ,
+                XMLSEC_ERRORS_R_CRYPTO_FAILED ,
+                XMLSEC_ERRORS_NO_MESSAGE ) ;
+
+			if( priKey != NULL )
+				SECKEY_DestroyPrivateKey( priKey ) ;
+
+			if( pubKey != NULL )
+				SECKEY_DestroyPublicKey( pubKey ) ;
+
+            return -1 ;
+		}
+		/* Modify keyValue get Done */
 	    
 	    /* verify that the key matches our expectations */
 	    if(xmlSecKeyReqMatchKeyValue(&(keyInfoCtx->keyReq), keyValue) != 1) {
@@ -1746,7 +1510,7 @@
 		    NULL,
 		    "CERT_ExtractPublicKey",
 		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-		    XMLSEC_ERRORS_NO_MESSAGE);
+		    "error code=%d", PORT_GetError());
 	return(NULL);
     }    
 
@@ -1804,7 +1568,7 @@
 		    NULL,
 		    "__CERT_NewTempCertificate",
 		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-		    XMLSEC_ERRORS_NO_MESSAGE);
+		    "error code=%d", PORT_GetError());
 	return(NULL);
     }
 
@@ -1827,7 +1591,7 @@
 		    NULL,
 		    "cert->derCert",
 		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-		    XMLSEC_ERRORS_NO_MESSAGE);
+		    "error code=%d", PORT_GetError());
 	return(NULL);
     }
     
@@ -1890,7 +1654,7 @@
                     NULL,
                     "PK11_GetInternalKeySlot",
                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
-                    XMLSEC_ERRORS_NO_MESSAGE);
+                    "error code=%d", PORT_GetError());
 	return NULL;
     }
 
@@ -1905,7 +1669,7 @@
 		    NULL,
 		    "PK11_ImportCRL",
 		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-		    XMLSEC_ERRORS_NO_MESSAGE);
+		    "error code=%d", PORT_GetError());
 	PK11_FreeSlot(slot);
 	return(NULL);
     }
@@ -1929,7 +1693,7 @@
                     NULL,
                     "crl->derCrl",
                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
-                    XMLSEC_ERRORS_NO_MESSAGE);
+                    "error code=%d", PORT_GetError());
         return(NULL);
     }
 
@@ -1945,86 +1709,6 @@
 
     return(res);
 }
-
-static xmlChar*
-xmlSecNssX509NameWrite(CERTName* nm) {
-    xmlChar *res = NULL;
-    char *str;
-
-    xmlSecAssert2(nm != NULL, NULL);
-
-    str = CERT_NameToAscii(nm);
-    if (str == NULL) {
-        xmlSecError(XMLSEC_ERRORS_HERE,
-        	    NULL,
-        	    "CERT_NameToAscii",
-        	    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-        	    XMLSEC_ERRORS_NO_MESSAGE);
-        return(NULL);
-    }
-
-    res = xmlStrdup(BAD_CAST str);
-    if(res == NULL) {
-	xmlSecError(XMLSEC_ERRORS_HERE,
-		    NULL,
-		    "xmlStrdup",
-		    XMLSEC_ERRORS_R_MALLOC_FAILED,
-		    XMLSEC_ERRORS_NO_MESSAGE);
-	PORT_Free(str);
-	return(NULL);
-    }
-    PORT_Free(str);
-    return(res);
-}
-
-static xmlChar*
-xmlSecNssASN1IntegerWrite(SECItem *num) {
-    xmlChar *res = NULL;
-    
-    xmlSecAssert2(num != NULL, NULL);
-
-    /* TODO : to be implemented after 
-     * NSS bug http://bugzilla.mozilla.org/show_bug.cgi?id=212864 is fixed 
-     */
-    return(res);
-}
-
-static xmlChar*
-xmlSecNssX509SKIWrite(CERTCertificate* cert) {
-    xmlChar *res = NULL;
-    SECItem ski;
-    SECStatus rv;
-
-    xmlSecAssert2(cert != NULL, NULL);
-
-    memset(&ski, 0, sizeof(ski));
-
-    rv = CERT_FindSubjectKeyIDExtension(cert, &ski);
-    if (rv != SECSuccess) {
-	xmlSecError(XMLSEC_ERRORS_HERE,
-		    NULL,
-		    "CERT_FindSubjectKeyIDExtension",
-		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-		    XMLSEC_ERRORS_NO_MESSAGE);
-	SECITEM_FreeItem(&ski, PR_FALSE);
-	return(NULL);
-    }
-
-    res = xmlSecBase64Encode(ski.data, ski.len, 0);
-    if(res == NULL) {
-	xmlSecError(XMLSEC_ERRORS_HERE,
-		    NULL,
-		    "xmlSecBase64Encode",
-	    	    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-		    XMLSEC_ERRORS_NO_MESSAGE);
-	SECITEM_FreeItem(&ski, PR_FALSE);
-	return(NULL);
-    }
-    SECITEM_FreeItem(&ski, PR_FALSE);
-    
-    return(res);
-}
-
 
 static void 
 xmlSecNssX509CertDebugDump(CERTCertificate* cert, FILE* output) {
Index: xmlsec/src/nss/x509vfy.c
===================================================================
RCS file: /cvs/gnome/xmlsec/src/nss/x509vfy.c,v
retrieving revision 1.3
diff -u -r1.3 x509vfy.c
--- xmlsec/src/nss/x509vfy.c	26 Sep 2003 00:58:15 -0000	1.3
+++ xmlsec/src/nss/x509vfy.c	6 Feb 2005 03:53:24 -0000
@@ -30,6 +30,7 @@
 #include <xmlsec/keyinfo.h>
 #include <xmlsec/keysmngr.h>
 #include <xmlsec/base64.h>
+#include <xmlsec/bn.h>
 #include <xmlsec/errors.h>
 
 #include <xmlsec/nss/crypto.h>
@@ -61,17 +62,8 @@
  
 static int		xmlSecNssX509StoreInitialize	(xmlSecKeyDataStorePtr store);
 static void		xmlSecNssX509StoreFinalize	(xmlSecKeyDataStorePtr store);
-static int 		xmlSecNssX509NameStringRead	(xmlSecByte **str, 
-							 int *strLen, 
-							 xmlSecByte *res, 
-							 int resLen,
-							 xmlSecByte delim, 
-							 int ingoreTrailingSpaces);
-static xmlSecByte * 	xmlSecNssX509NameRead		(xmlSecByte *str, 
-							 int len);
-
-static void 		xmlSecNssNumToItem(SECItem *it, unsigned long num);
 
+static int 		xmlSecNssIntegerToItem( const xmlChar* integer , SECItem *it ) ;
 
 static xmlSecKeyDataStoreKlass xmlSecNssX509StoreKlass = {
     sizeof(xmlSecKeyDataStoreKlass),
@@ -245,8 +237,9 @@
                         xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
                         NULL,
                         XMLSEC_ERRORS_R_CERT_VERIFY_FAILED,
-                        "cert with subject name %s could not be verified",
-                        cert->subjectName);
+						"cert with subject name %s could not be verified, errcode %d",
+						cert->subjectName,
+			PORT_GetError());
 	    break;
     }
    
@@ -281,7 +274,7 @@
                         xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
                         "CERT_NewCertList",
                         XMLSEC_ERRORS_R_CRYPTO_FAILED,
-                        XMLSEC_ERRORS_NO_MESSAGE);
+						"error code=%d", PORT_GetError());
             return(-1);
         }
     }
@@ -292,7 +285,7 @@
                     xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
                     "CERT_AddCertToListTail",
                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
-                    XMLSEC_ERRORS_NO_MESSAGE);
+					"error code=%d", PORT_GetError());
         return(-1);
     }
 
@@ -342,40 +335,28 @@
 xmlSecNssX509FindCert(xmlChar *subjectName, xmlChar *issuerName, 
 		      xmlChar *issuerSerial, xmlChar *ski) {
     CERTCertificate *cert = NULL;
-    xmlChar         *p = NULL;
     CERTName *name = NULL;
     SECItem *nameitem = NULL;
     PRArenaPool *arena = NULL;
 
     if (subjectName != NULL) {
-	p = xmlSecNssX509NameRead(subjectName, xmlStrlen(subjectName));
-	if (p == NULL) {
-            xmlSecError(XMLSEC_ERRORS_HERE,
-                        NULL,
-                        "xmlSecNssX509NameRead",
-                        XMLSEC_ERRORS_R_XMLSEC_FAILED,
-                        "subject=%s",
-                        xmlSecErrorsSafeString(subjectName));
-	    goto done;
-	}
-
 	arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
 	if (arena == NULL) {
             xmlSecError(XMLSEC_ERRORS_HERE,
                         NULL,
                         "PORT_NewArena",
                         XMLSEC_ERRORS_R_CRYPTO_FAILED,
-                        XMLSEC_ERRORS_NO_MESSAGE);
+						"error code=%d", PORT_GetError());
 	    goto done;
 	}
 
-	name = CERT_AsciiToName((char*)p);
+		name = CERT_AsciiToName((char*)subjectName);
 	if (name == NULL) {
             xmlSecError(XMLSEC_ERRORS_HERE,
                         NULL,
                         "CERT_AsciiToName",
                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
-                        XMLSEC_ERRORS_NO_MESSAGE);
+						"error code=%d", PORT_GetError());
 	    goto done;
 	}
 
@@ -386,7 +367,7 @@
                         NULL,
                         "SEC_ASN1EncodeItem",
                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
-                        XMLSEC_ERRORS_NO_MESSAGE);
+						"error code=%d", PORT_GetError());
 	    goto done;
 	}
 
@@ -397,34 +378,23 @@
     if((issuerName != NULL) && (issuerSerial != NULL)) {
 	CERTIssuerAndSN issuerAndSN;
 
-	p = xmlSecNssX509NameRead(issuerName, xmlStrlen(issuerName));
-	if (p == NULL) {
-            xmlSecError(XMLSEC_ERRORS_HERE,
-                        NULL,
-                        "xmlSecNssX509NameRead",
-                        XMLSEC_ERRORS_R_XMLSEC_FAILED,
-                        "issuer=%s",
-                        xmlSecErrorsSafeString(issuerName));
-	    goto done;
-	}
-
 	arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
 	if (arena == NULL) {
             xmlSecError(XMLSEC_ERRORS_HERE,
                         NULL,
                         "PORT_NewArena",
                         XMLSEC_ERRORS_R_CRYPTO_FAILED,
-                        XMLSEC_ERRORS_NO_MESSAGE);
+						"error code=%d", PORT_GetError());
 	    goto done;
 	}
 
-	name = CERT_AsciiToName((char*)p);
+		name = CERT_AsciiToName((char*)issuerName);
 	if (name == NULL) {
             xmlSecError(XMLSEC_ERRORS_HERE,
                         NULL,
                         "CERT_AsciiToName",
                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
-                        XMLSEC_ERRORS_NO_MESSAGE);
+				"error code=%d", PORT_GetError());
 	    goto done;
 	}
 
@@ -435,7 +405,7 @@
                         NULL,
                         "SEC_ASN1EncodeItem",
                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
-                        XMLSEC_ERRORS_NO_MESSAGE);
+						"error code=%d", PORT_GetError());
 	    goto done;
 	}
 
@@ -445,7 +415,15 @@
 	issuerAndSN.derIssuer.len = nameitem->len;
 
 	/* TBD: serial num can be arbitrarily long */
-	xmlSecNssNumToItem(&issuerAndSN.serialNumber, PORT_Atoi((char *)issuerSerial));
+		if( xmlSecNssIntegerToItem( issuerSerial, &issuerAndSN.serialNumber ) < 0 ) {
+			xmlSecError(XMLSEC_ERRORS_HERE,
+				NULL,
+				"xmlSecNssIntegerToItem",
+				XMLSEC_ERRORS_R_XMLSEC_FAILED,
+				"serial number=%s",
+				xmlSecErrorsSafeString(issuerSerial));
+			goto done;
+		}
 
 	cert = CERT_FindCertByIssuerAndSN(CERT_GetDefaultCertDB(), 
 					  &issuerAndSN);
@@ -476,9 +454,6 @@
     }
 
 done:
-    if (p != NULL) {
-	PORT_Free(p);
-    }
     if (arena != NULL) {
 	PORT_FreeArena(arena, PR_FALSE);
     }
@@ -489,227 +464,84 @@
     return(cert);
 }
 
-/**
- * xmlSecNssX509NameRead:
- */       
-static xmlSecByte *
-xmlSecNssX509NameRead(xmlSecByte *str, int len) {
-    xmlSecByte name[256];
-    xmlSecByte value[256];
-    xmlSecByte *retval = NULL;
-    xmlSecByte *p = NULL;
-    int nameLen, valueLen;
+static int
+xmlSecNssIntegerToItem(
+	const xmlChar* integer ,
+	SECItem *item
+) {
+	xmlSecBn bn ;
+	xmlSecSize i, length ;
+	const xmlSecByte* bnInteger ;
 
-    xmlSecAssert2(str != NULL, NULL);
-    
-    /* return string should be no longer than input string */
-    retval = (xmlSecByte *)PORT_Alloc(len+1);
-    if(retval == NULL) {
-	xmlSecError(XMLSEC_ERRORS_HERE,
-		    NULL,
-		    "PORT_Alloc",
-		    XMLSEC_ERRORS_R_MALLOC_FAILED,
-		    XMLSEC_ERRORS_NO_MESSAGE);
-	return(NULL);
-    }
-    p = retval;
-    
-    while(len > 0) {
-	/* skip spaces after comma or semicolon */
-	while((len > 0) && isspace(*str)) {
-	    ++str; --len;
+	xmlSecAssert2( integer != NULL, -1 ) ;
+	xmlSecAssert2( item != NULL, -1 ) ;
+
+	if( xmlSecBnInitialize( &bn, 0 ) < 0 ) {
+		xmlSecError( XMLSEC_ERRORS_HERE,
+			NULL,
+			"xmlSecBnInitialize",
+			XMLSEC_ERRORS_R_INVALID_DATA,
+			XMLSEC_ERRORS_NO_MESSAGE ) ;
+		return -1 ;	
 	}
 
-	nameLen = xmlSecNssX509NameStringRead(&str, &len, name, sizeof(name), '=', 0);	
-	if(nameLen < 0) {
-	    xmlSecError(XMLSEC_ERRORS_HERE,
+	if( xmlSecBnFromDecString( &bn, integer ) < 0 ) {
+		xmlSecError( XMLSEC_ERRORS_HERE,
 			NULL,
-			"xmlSecNssX509NameStringRead",
-			XMLSEC_ERRORS_R_XMLSEC_FAILED,
-			XMLSEC_ERRORS_NO_MESSAGE);
-	    goto done;
+			"xmlSecBnFromDecString",
+			XMLSEC_ERRORS_R_INVALID_DATA,
+			XMLSEC_ERRORS_NO_MESSAGE ) ;
+
+		xmlSecBnFinalize( &bn ) ;
+		return -1 ;	
 	}
-	memcpy(p, name, nameLen);
-	p+=nameLen;
-	*p++='=';
-	if(len > 0) {
-	    ++str; --len;
-	    if((*str) == '\"') {
-		valueLen = xmlSecNssX509NameStringRead(&str, &len, 
-					value, sizeof(value), '"', 1);	
-		if(valueLen < 0) {
-		    xmlSecError(XMLSEC_ERRORS_HERE,
-				NULL,
-				"xmlSecNssX509NameStringRead",
-				XMLSEC_ERRORS_R_XMLSEC_FAILED,
-				XMLSEC_ERRORS_NO_MESSAGE);
-		    goto done;
-    		}
-		/* skip spaces before comma or semicolon */
-		while((len > 0) && isspace(*str)) {
-		    ++str; --len;
-		}
-		if((len > 0) && ((*str) != ',')) {
-		    xmlSecError(XMLSEC_ERRORS_HERE,
-				NULL,
-				NULL,
-				XMLSEC_ERRORS_R_INVALID_DATA,
-				"comma is expected");
-		    goto done;
-		}
-		if(len > 0) {
-		    ++str; --len;
-		}
-		*p++='\"';
-		memcpy(p, value, valueLen);
-		p+=valueLen;
-		*p++='\"';
-	    } else if((*str) == '#') {
-		/* TODO: read octect values */
-		xmlSecError(XMLSEC_ERRORS_HERE,
-			    NULL,
-			    NULL,
-			    XMLSEC_ERRORS_R_INVALID_DATA,
-			    "reading octect values is not implemented yet");
-		goto done;
-	    } else {
-		valueLen = xmlSecNssX509NameStringRead(&str, &len, 
-					value, sizeof(value), ',', 1);	
-		if(valueLen < 0) {
-		    xmlSecError(XMLSEC_ERRORS_HERE,
-				NULL,
-				"xmlSecNssX509NameStringRead",
-				XMLSEC_ERRORS_R_XMLSEC_FAILED,
-				XMLSEC_ERRORS_NO_MESSAGE);
-		    goto done;
-    		}
-		memcpy(p, value, valueLen);
-		p+=valueLen;
-		if (len > 0)
-		    *p++=',';
-	    } 			
-	} else {
-	    valueLen = 0;
+
+	length = xmlSecBnGetSize( &bn ) ;
+	if( length <= 0 ) {
+		xmlSecError( XMLSEC_ERRORS_HERE,
+			NULL,
+			"xmlSecBnGetSize",
+			XMLSEC_ERRORS_R_INVALID_DATA,
+			XMLSEC_ERRORS_NO_MESSAGE ) ;
+
+		xmlSecBnFinalize( &bn ) ;
+		return -1 ;
 	}
-	if(len > 0) {
-	    ++str; --len;
-	}	
-    }
 
-    *p = 0;
-    return(retval);
-    
-done:
-    PORT_Free(retval);
-    return (NULL);
-}
+	bnInteger = xmlSecBnGetData( &bn ) ;
+	if( bnInteger == NULL ) {
+		xmlSecError( XMLSEC_ERRORS_HERE,
+			NULL,
+			"xmlSecBnGetData",
+			XMLSEC_ERRORS_R_INVALID_DATA,
+			XMLSEC_ERRORS_NO_MESSAGE ) ;
 
+		xmlSecBnFinalize( &bn ) ;
+		return -1 ;
+	}
 
+	item->data = ( unsigned char * )PORT_Alloc( length );
+	if( item->data == NULL ) {
+		xmlSecError( XMLSEC_ERRORS_HERE,
+			NULL,
+			"PORT_Alloc",
+			XMLSEC_ERRORS_R_INVALID_DATA,
+			XMLSEC_ERRORS_NO_MESSAGE ) ;
 
-/**
- * xmlSecNssX509NameStringRead:
- */
-static int 
-xmlSecNssX509NameStringRead(xmlSecByte **str, int *strLen, 
-			    xmlSecByte *res, int resLen,
-			    xmlSecByte delim, int ingoreTrailingSpaces) {
-    xmlSecByte *p, *q, *nonSpace; 
-
-    xmlSecAssert2(str != NULL, -1);
-    xmlSecAssert2(strLen != NULL, -1);
-    xmlSecAssert2(res != NULL, -1);
-    
-    p = (*str);
-    nonSpace = q = res;
-    while(((p - (*str)) < (*strLen)) && ((*p) != delim) && ((q - res) < resLen)) { 
-	if((*p) != '\\') {
-	    if(ingoreTrailingSpaces && !isspace(*p)) {
-		nonSpace = q;	
-	    }
-	    *(q++) = *(p++);
-	} else {
-	    ++p;
-	    nonSpace = q;    
-	    if(xmlSecIsHex((*p))) {
-		if((p - (*str) + 1) >= (*strLen)) {
-		    xmlSecError(XMLSEC_ERRORS_HERE,
-				NULL,
-				NULL,
-				XMLSEC_ERRORS_R_INVALID_DATA,
-				"two hex digits expected");
-	    	    return(-1);
-		}
-		*(q++) = xmlSecGetHex(p[0]) * 16 + xmlSecGetHex(p[1]);
-		p += 2;
-	    } else {
-		if(((++p) - (*str)) >= (*strLen)) {
-		    xmlSecError(XMLSEC_ERRORS_HERE,
-				NULL,
-				NULL,
-				XMLSEC_ERRORS_R_INVALID_DATA,
-				"escaped symbol missed");
-		    return(-1);
-		}
-		*(q++) = *(p++); 
-	    }
-	}	    
-    }
-    if(((p - (*str)) < (*strLen)) && ((*p) != delim)) {
-	xmlSecError(XMLSEC_ERRORS_HERE,
-		    NULL,
-		    NULL,
-		    XMLSEC_ERRORS_R_INVALID_SIZE,
-		    "buffer is too small");
-	return(-1);
-    }
-    (*strLen) -= (p - (*str));
-    (*str) = p;
-    return((ingoreTrailingSpaces) ? nonSpace - res + 1 : q - res);
-}
+		xmlSecBnFinalize( &bn ) ;
+		return -1 ;
+	}
 
-/* code lifted from NSS */
-static void
-xmlSecNssNumToItem(SECItem *it, unsigned long ui)
-{
-    unsigned char bb[5];
-    int len;
-
-    bb[0] = 0;
-    bb[1] = (unsigned char) (ui >> 24);
-    bb[2] = (unsigned char) (ui >> 16);
-    bb[3] = (unsigned char) (ui >> 8);
-    bb[4] = (unsigned char) (ui);
-
-    /*
-    ** Small integers are encoded in a single byte. Larger integers
-    ** require progressively more space.
-    */
-    if (ui > 0x7f) {
-        if (ui > 0x7fff) {
-            if (ui > 0x7fffffL) {
-                if (ui >= 0x80000000L) {
-                    len = 5;
-                } else {
-                    len = 4;
-                }
-            } else {
-                len = 3;
-            }
-        } else {
-            len = 2;
-        }
-    } else {
-        len = 1;
-    }
+	item->len = length;
 
-    it->data = (unsigned char *)PORT_Alloc(len);
-    if (it->data == NULL) {
-        return;
-    }
+	for( i = 0 ; i < length ; i ++ )
+		item->data[i] = *( bnInteger + i ) ;
 
-    it->len = len;
-    PORT_Memcpy(it->data, bb + (sizeof(bb) - len), len);
+	xmlSecBnFinalize( &bn ) ;
+
+	return 0 ;
 }
+
 #endif /* XMLSEC_NO_X509 */
 
 
cvs server: Diffing xmlsec/src/openssl
cvs server: Diffing xmlsec/src/skeleton
cvs server: Diffing xmlsec/tests
cvs server: Diffing xmlsec/tests/01-geuerp-xfilter2
cvs server: Diffing xmlsec/tests/01-phaos-xmlenc-3
cvs server: Diffing xmlsec/tests/aleksey-xkms-01
cvs server: Diffing xmlsec/tests/aleksey-xkms-01/keys
cvs server: Diffing xmlsec/tests/aleksey-xmldsig-01
cvs server: Diffing xmlsec/tests/aleksey-xmlenc-01
cvs server: Diffing xmlsec/tests/keys
cvs server: Diffing xmlsec/tests/keys/demoCA
cvs server: Diffing xmlsec/tests/keys/demoCA/newcerts
cvs server: Diffing xmlsec/tests/keys/demoCA/private
cvs server: Diffing xmlsec/tests/merlin-c14n-three
cvs server: Diffing xmlsec/tests/merlin-exc-c14n-one
cvs server: Diffing xmlsec/tests/merlin-xmldsig-twenty-three
cvs server: Diffing xmlsec/tests/merlin-xmldsig-twenty-three/certs
cvs server: Diffing xmlsec/tests/merlin-xmlenc-five
cvs server: Diffing xmlsec/tests/merlin-xpath-filter2-three
cvs server: Diffing xmlsec/tests/nssdb
cvs server: Diffing xmlsec/tests/phaos-xmldsig-three
cvs server: Diffing xmlsec/tests/phaos-xmldsig-three/certs
cvs server: Diffing xmlsec/win32
Index: xmlsec/win32/Makefile.msvc
===================================================================
RCS file: /cvs/gnome/xmlsec/win32/Makefile.msvc,v
retrieving revision 1.27
diff -u -r1.27 Makefile.msvc
--- xmlsec/win32/Makefile.msvc	9 Jun 2004 14:35:12 -0000	1.27
+++ xmlsec/win32/Makefile.msvc	6 Feb 2005 03:53:27 -0000
@@ -223,6 +223,10 @@
 	$(XMLSEC_OPENSSL_INTDIR_A)\x509vfy.obj 
 
 XMLSEC_NSS_OBJS = \
+	$(XMLSEC_NSS_INTDIR)\akmngr.obj\
+	$(XMLSEC_NSS_INTDIR)\keytrans.obj\
+	$(XMLSEC_NSS_INTDIR)\keywrapers.obj\
+	$(XMLSEC_NSS_INTDIR)\tokens.obj\
 	$(XMLSEC_NSS_INTDIR)\app.obj\
 	$(XMLSEC_NSS_INTDIR)\bignum.obj\
 	$(XMLSEC_NSS_INTDIR)\ciphers.obj \
@@ -235,9 +239,6 @@
 	$(XMLSEC_NSS_INTDIR)\x509.obj\
 	$(XMLSEC_NSS_INTDIR)\x509vfy.obj\
 	$(XMLSEC_NSS_INTDIR)\keysstore.obj\
-	$(XMLSEC_NSS_INTDIR)\kt_rsa.obj\
-	$(XMLSEC_NSS_INTDIR)\kw_des.obj\
-	$(XMLSEC_NSS_INTDIR)\kw_aes.obj\
 	$(XMLSEC_NSS_INTDIR)\strings.obj
 XMLSEC_NSS_OBJS_A = \
 	$(XMLSEC_NSS_INTDIR_A)\app.obj\
@@ -258,6 +259,7 @@
 	$(XMLSEC_NSS_INTDIR_A)\strings.obj
 
 XMLSEC_MSCRYPTO_OBJS = \
+	$(XMLSEC_MSCRYPTO_INTDIR)\akmngr.obj\
 	$(XMLSEC_MSCRYPTO_INTDIR)\app.obj\
 	$(XMLSEC_MSCRYPTO_INTDIR)\crypto.obj \
 	$(XMLSEC_MSCRYPTO_INTDIR)\ciphers.obj \

*****CVS exited normally with code 1*****
-------------- next part --------------
A non-text attachment was scrubbed...
Name: xmlsec.zip
Type: application/octet-stream
Size: 18391 bytes
Desc: not available
Url : http://www.aleksey.com/pipermail/xmlsec/attachments/20050206/7b028c1d/xmlsec-0002.obj


More information about the xmlsec mailing list