[xmlsec] Re: GOST support in xmlsec

Dmitry Belyavsky beldmit at cryptocom.ru
Thu Feb 9 01:39:11 PST 2006


Greetings!

On Wed, 8 Feb 2006, Aleksey Sanin wrote:

> > > 2) I noticed that there are a couple files with Cryptocom name
> > > in them. Is your company OK with releasing these files under MIT
> > > license (same as all other xmlsec sources)? Can you explicitly
> > > state these in the files, please?
> >
> > Is there a standard form of such a disclaimer? Our company is OK with
> > releasing them under MIT license.
> >
> > I've found only 2 files mentioning our company, and not all the
> > identifiers from them are necessary.
>
> Thanks! Can you put a standard xmlsec header in these files, please?
> For example, AOL donated a lot of code to xmlsec-nss implementation
> (take a look at the files in src/nss folder).

Fixed.

> > > 3) What does user need to actually use these new GOST algorithms?
> > > Is it a part of standard Windows distribution? OpenSSL distribution?
> >
> > The user should install a CSP providing the algorithms to use these
> > algorithms. There are at least 3 commercial products providing the
> > algorithms.
> >
> > Unfortunately other crypto libraries don't support the GOST algorithms.
> > Though we have a huge patch to OpenSSL providing them.
>
> OK, it would be good to document these somewhere in the code.

I think it would be better to mention it somewhere in documentation. But
I don't understand where. I'm ready to write smth about it.

> > > 4) I noticed few "FIXME" comments in the code. Is it real? How much
> > > more work is there?
> >
> > Oh, sorry. They can be completely removed.
>
> :) Great!
>
> I am waiting for another patch with these changes :)

The patch is attached.
What are your release plans?

-- 
SY, Dmitry Belyavsky (ICQ UIN 11116575)
-------------- next part --------------
Index: include/xmlsec/app.h
===================================================================
RCS file: /cvs/xmlsec/include/xmlsec/app.h,v
retrieving revision 1.1.1.1
diff -u -w -r1.1.1.1 app.h
--- include/xmlsec/app.h	6 Dec 2005 09:29:17 -0000	1.1.1.1
+++ include/xmlsec/app.h	9 Feb 2006 09:31:07 -0000
@@ -66,6 +66,13 @@
 #define xmlSecKeyDataDsaId			xmlSecKeyDataDsaGetKlass()
 XMLSEC_EXPORT xmlSecKeyDataId			xmlSecKeyDataDsaGetKlass	(void);		
 /** 
+ * xmlSecKeyDataGost2001Id:
+ * 
+ * The GOST2001 key klass.
+ */
+#define xmlSecKeyDataGost2001Id			xmlSecKeyDataGost2001GetKlass()
+XMLSEC_EXPORT xmlSecKeyDataId			xmlSecKeyDataGost2001GetKlass	(void);		
+/** 
  * xmlSecKeyDataHmacId:
  * 
  * The DHMAC key klass.
@@ -177,6 +184,14 @@
 XMLSEC_EXPORT xmlSecTransformId			xmlSecTransformDsaSha1GetKlass	(void);	
 
 /**
+ * xmlSecTransformGost2001GostR3411_94Id:
+ * 
+ * The GOST2001-GOSTR3411_94 signature transform klass.
+ */
+#define xmlSecTransformGost2001GostR3411_94Id		xmlSecTransformGost2001GostR3411_94GetKlass()
+XMLSEC_EXPORT xmlSecTransformId			xmlSecTransformGost2001GostR3411_94GetKlass	(void);	
+
+/**
  * xmlSecTransformHmacMd5Id:
  * 
  * The HMAC with MD5 signature transform klass.
@@ -303,6 +318,13 @@
  */
 #define xmlSecTransformRsaOaepId		xmlSecTransformRsaOaepGetKlass()
 XMLSEC_EXPORT xmlSecTransformId			xmlSecTransformRsaOaepGetKlass	(void);	
+/**
+ * xmlSecTransformGostR3411_94Id:
+ * 
+ * The GOSTR3411_94 digest transform klass.
+ */
+#define xmlSecTransformGostR3411_94Id			xmlSecTransformGostR3411_94GetKlass()
+XMLSEC_EXPORT xmlSecTransformId			xmlSecTransformGostR3411_94GetKlass	(void);
 /**
  * xmlSecTransformSha1Id:
  * 
Index: include/xmlsec/private.h
===================================================================
RCS file: /cvs/xmlsec/include/xmlsec/private.h,v
retrieving revision 1.1.1.1
retrieving revision 1.6
diff -u -w -r1.1.1.1 -r1.6
--- include/xmlsec/private.h	6 Dec 2005 09:29:17 -0000	1.1.1.1
+++ include/xmlsec/private.h	13 Dec 2005 14:31:46 -0000	1.6
@@ -403,6 +403,7 @@
     xmlSecCryptoKeyDataGetKlassMethod		 keyDataAesGetKlass;
     xmlSecCryptoKeyDataGetKlassMethod		 keyDataDesGetKlass;
     xmlSecCryptoKeyDataGetKlassMethod		 keyDataDsaGetKlass;
+    xmlSecCryptoKeyDataGetKlassMethod		 keyDataGost2001GetKlass;
     xmlSecCryptoKeyDataGetKlassMethod		 keyDataHmacGetKlass;
     xmlSecCryptoKeyDataGetKlassMethod		 keyDataRsaGetKlass;
     xmlSecCryptoKeyDataGetKlassMethod		 keyDataX509GetKlass;
@@ -425,6 +426,7 @@
     xmlSecCryptoTransformGetKlassMethod		 transformDes3CbcGetKlass;
     xmlSecCryptoTransformGetKlassMethod		 transformKWDes3GetKlass;
     xmlSecCryptoTransformGetKlassMethod		 transformDsaSha1GetKlass;
+    xmlSecCryptoTransformGetKlassMethod		 transformGost2001GostR3411_94GetKlass;
     xmlSecCryptoTransformGetKlassMethod		 transformHmacMd5GetKlass;
     xmlSecCryptoTransformGetKlassMethod		 transformHmacRipemd160GetKlass;
     xmlSecCryptoTransformGetKlassMethod		 transformHmacSha1GetKlass;
@@ -443,6 +445,7 @@
     xmlSecCryptoTransformGetKlassMethod		 transformRsaSha512GetKlass;
     xmlSecCryptoTransformGetKlassMethod		 transformRsaPkcs1GetKlass;
     xmlSecCryptoTransformGetKlassMethod		 transformRsaOaepGetKlass;
+    xmlSecCryptoTransformGetKlassMethod		 transformGostR3411_94GetKlass;
     xmlSecCryptoTransformGetKlassMethod		 transformSha1GetKlass;
     xmlSecCryptoTransformGetKlassMethod		 transformSha224GetKlass;
     xmlSecCryptoTransformGetKlassMethod		 transformSha256GetKlass;
Index: include/xmlsec/strings.h
===================================================================
RCS file: /cvs/xmlsec/include/xmlsec/strings.h,v
retrieving revision 1.1.1.1
retrieving revision 1.5
diff -u -w -r1.1.1.1 -r1.5
--- include/xmlsec/strings.h	6 Dec 2005 09:29:17 -0000	1.1.1.1
+++ include/xmlsec/strings.h	13 Dec 2005 14:31:46 -0000	1.5
@@ -314,6 +314,18 @@
 
 /*************************************************************************
  *
+ * GOST2001 strings
+ *
+ ************************************************************************/
+XMLSEC_EXPORT_VAR const xmlChar xmlSecNameGOST2001KeyValue[];
+XMLSEC_EXPORT_VAR const xmlChar xmlSecNodeGOST2001KeyValue[];
+XMLSEC_EXPORT_VAR const xmlChar xmlSecHrefGOST2001KeyValue[];
+
+XMLSEC_EXPORT_VAR const xmlChar xmlSecNameGost2001GostR3411_94[];
+XMLSEC_EXPORT_VAR const xmlChar xmlSecHrefGost2001GostR3411_94[];
+
+/*************************************************************************
+ *
  * EncryptedKey
  *
  ************************************************************************/
@@ -448,6 +460,14 @@
 XMLSEC_EXPORT_VAR const xmlChar xmlSecNameRsaOaep[];
 XMLSEC_EXPORT_VAR const xmlChar xmlSecHrefRsaOaep[];
 XMLSEC_EXPORT_VAR const xmlChar xmlSecNodeRsaOAEPparams[];
+
+/*************************************************************************
+ *
+ * GOSTR3411_94 strings
+ *
+ ************************************************************************/
+XMLSEC_EXPORT_VAR const xmlChar xmlSecNameGostR3411_94[];
+XMLSEC_EXPORT_VAR const xmlChar xmlSecHrefGostR3411_94[];
 
 /*************************************************************************
  *
Index: include/xmlsec/templates.h
===================================================================
RCS file: /cvs/xmlsec/include/xmlsec/templates.h,v
retrieving revision 1.1.1.1
retrieving revision 1.3
diff -u -w -r1.1.1.1 -r1.3
--- include/xmlsec/templates.h	6 Dec 2005 09:29:17 -0000	1.1.1.1
+++ include/xmlsec/templates.h	15 Dec 2005 16:56:03 -0000	1.3
@@ -117,6 +117,8 @@
  *
  **********************************************************************/ 
 XMLSEC_EXPORT xmlNodePtr xmlSecTmplX509DataAddIssuerSerial	(xmlNodePtr x509DataNode);
+XMLSEC_EXPORT xmlNodePtr xmlSecTmplX509IssuerSerialAddIssuerName(xmlNodePtr x509IssuerSerialNode, const xmlChar* issuerName);
+XMLSEC_EXPORT xmlNodePtr xmlSecTmplX509IssuerSerialAddSerialNumber(xmlNodePtr x509IssuerSerialNode, const xmlChar* serial);
 XMLSEC_EXPORT xmlNodePtr xmlSecTmplX509DataAddSubjectName	(xmlNodePtr x509DataNode);
 XMLSEC_EXPORT xmlNodePtr xmlSecTmplX509DataAddSKI		(xmlNodePtr x509DataNode);
 XMLSEC_EXPORT xmlNodePtr xmlSecTmplX509DataAddCertificate	(xmlNodePtr x509DataNode);
Index: include/xmlsec/mscrypto/crypto.h
===================================================================
RCS file: /cvs/xmlsec/include/xmlsec/mscrypto/crypto.h,v
retrieving revision 1.1.1.1
retrieving revision 1.5
diff -u -w -r1.1.1.1 -r1.5
--- include/xmlsec/mscrypto/crypto.h	6 Dec 2005 09:29:17 -0000	1.1.1.1
+++ include/xmlsec/mscrypto/crypto.h	13 Dec 2005 14:31:46 -0000	1.5
@@ -80,6 +80,33 @@
 
 /********************************************************************
  *
+ * GOST2001 transform
+ *
+ *******************************************************************/
+#ifndef XMLSEC_NO_GOST
+
+/**
+ * xmlSecMSCryptoKeyDataGost2001Id:
+ * 
+ * The GOST2001 key klass.
+ */
+#define xmlSecMSCryptoKeyDataGost2001Id \
+	xmlSecMSCryptoKeyDataGost2001GetKlass()
+XMLSEC_CRYPTO_EXPORT xmlSecKeyDataId 	xmlSecMSCryptoKeyDataGost2001GetKlass	(void);
+
+/**
+ * xmlSecMSCryptoTransformGost2001GostR3411_94Id:
+ * 
+ * The GOST2001 GOSTR3411_94 signature transform klass.
+ */
+#define xmlSecMSCryptoTransformGost2001GostR3411_94Id \
+	xmlSecMSCryptoTransformGost2001GostR3411_94GetKlass()
+XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecMSCryptoTransformGost2001GostR3411_94GetKlass(void);
+
+#endif /* XMLSEC_NO_GOST */
+
+/********************************************************************
+ *
  * RSA transforms
  *
  *******************************************************************/
@@ -142,6 +169,23 @@
 	xmlSecMSCryptoTransformSha1GetKlass()
 XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecMSCryptoTransformSha1GetKlass(void);
 #endif /* XMLSEC_NO_SHA1 */
+
+/********************************************************************
+ *
+ * GOSTR3411_94 transform
+ *
+ *******************************************************************/
+#ifndef XMLSEC_NO_GOST
+
+/**
+ * xmlSecMSCryptoTransformGostR3411_94Id:
+ * 
+ * The GOSTR3411_94 digest transform klass.
+ */
+#define xmlSecMSCryptoTransformGostR3411_94Id \
+	xmlSecMSCryptoTransformGostR3411_94GetKlass()
+XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecMSCryptoTransformGostR3411_94GetKlass(void);
+#endif /* XMLSEC_NO_GOST */
 
 /********************************************************************
  *
Index: include/xmlsec/mscrypto/symbols.h
===================================================================
RCS file: /cvs/xmlsec/include/xmlsec/mscrypto/symbols.h,v
retrieving revision 1.1.1.1
retrieving revision 1.6
diff -u -w -r1.1.1.1 -r1.6
--- include/xmlsec/mscrypto/symbols.h	6 Dec 2005 09:29:17 -0000	1.1.1.1
+++ include/xmlsec/mscrypto/symbols.h	13 Dec 2005 14:31:46 -0000	1.6
@@ -36,6 +36,7 @@
 #define xmlSecKeyDataAesId			xmlSecMSCryptoKeyDataAesId
 #define xmlSecKeyDataDesId			xmlSecMSCryptoKeyDataDesId
 #define xmlSecKeyDataDsaId			xmlSecMSCryptoKeyDataDsaId
+#define xmlSecKeyDataGost2001Id			xmlSecMSCryptoKeyDataGost2001Id
 #define xmlSecKeyDataHmacId			xmlSecMSCryptoKeyDataHmacId
 #define xmlSecKeyDataRsaId			xmlSecMSCryptoKeyDataRsaId
 #define xmlSecKeyDataX509Id			xmlSecMSCryptoKeyDataX509Id
@@ -58,6 +59,7 @@
 #define xmlSecTransformDes3CbcId		xmlSecMSCryptoTransformDes3CbcId
 #define xmlSecTransformKWDes3Id			xmlSecMSCryptoTransformKWDes3Id
 #define xmlSecTransformDsaSha1Id		xmlSecMSCryptoTransformDsaSha1Id
+#define xmlSecTransformGost2001GostR3411_94Id		xmlSecMSCryptoTransformGost2001GostR3411_94Id
 #define xmlSecTransformHmacMd5Id		xmlSecMSCryptoTransformHmacMd5Id
 #define xmlSecTransformHmacRipemd160Id		xmlSecMSCryptoTransformHmacRipemd160Id
 #define xmlSecTransformHmacSha1Id		xmlSecMSCryptoTransformHmacSha1Id
@@ -66,6 +68,7 @@
 #define xmlSecTransformRsaPkcs1Id		xmlSecMSCryptoTransformRsaPkcs1Id
 #define xmlSecTransformRsaOaepId		xmlSecMSCryptoTransformRsaOaepId
 #define xmlSecTransformSha1Id			xmlSecMSCryptoTransformSha1Id
+#define xmlSecTransformGostR3411_94Id			xmlSecMSCryptoTransformGostR3411_94Id
 
 /**
  * High level routines form xmlsec command line utility
Index: src/app.c
===================================================================
RCS file: /cvs/xmlsec/src/app.c,v
retrieving revision 1.1.1.1
retrieving revision 1.5
diff -u -w -r1.1.1.1 -r1.5
--- src/app.c	6 Dec 2005 09:29:16 -0000	1.1.1.1
+++ src/app.c	13 Dec 2005 14:31:46 -0000	1.5
@@ -174,6 +174,29 @@
 }
 
 /** 
+ * xmlSecKeyDataGost2001GetKlass:
+ * 
+ * The GOST2001 key data klass.
+ *
+ * Returns GOST2001 key data klass or NULL if an error occurs
+ * (xmlsec-crypto library is not loaded or the GOST2001 key data
+ * klass is not implemented).
+ */
+xmlSecKeyDataId	
+xmlSecKeyDataGost2001GetKlass(void) {
+    if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->keyDataGost2001GetKlass == NULL)) {
+	xmlSecError(XMLSEC_ERRORS_HERE,
+		    NULL,
+		    "keyDataGost2001Id",
+		    XMLSEC_ERRORS_R_NOT_IMPLEMENTED,
+		    XMLSEC_ERRORS_NO_MESSAGE);
+        return(xmlSecKeyDataIdUnknown);
+    }
+    
+    return(xmlSecCryptoDLGetFunctions()->keyDataGost2001GetKlass());
+}
+
+/** 
  * xmlSecKeyDataHmacGetKlass:
  * 
  * The HMAC key data klass.
@@ -506,6 +529,29 @@
 }
 
 /** 
+ * xmlSecTransformGost2001GostR3411_94GetKlass:
+ * 
+ * The GOST2001-GOSTR3411_94 signature transform klass.
+ *
+ * Returns GOST2001-GOSTR3411_94 signature transform klass or NULL if an error
+ * occurs (the xmlsec-crypto library is not loaded or this transform is not
+ * implemented).
+ */
+xmlSecTransformId 
+xmlSecTransformGost2001GostR3411_94GetKlass(void) {	
+    if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->transformGost2001GostR3411_94GetKlass == NULL)) {
+	xmlSecError(XMLSEC_ERRORS_HERE,
+		    NULL,
+		    "transformGost2001GostR3411_94Id",
+		    XMLSEC_ERRORS_R_NOT_IMPLEMENTED,
+		    XMLSEC_ERRORS_NO_MESSAGE);
+        return(xmlSecTransformIdUnknown);
+    }
+    
+    return(xmlSecCryptoDLGetFunctions()->transformGost2001GostR3411_94GetKlass());
+}
+
+/** 
  * xmlSecTransformHmacMd5GetKlass:
  *
  * The HMAC-MD5 transform klass.
@@ -918,6 +964,30 @@
     
     return(xmlSecCryptoDLGetFunctions()->transformRsaOaepGetKlass());
 }
+
+/** 
+ * xmlSecTransformGostR3411_94GetKlass:
+ *
+ * GOSTR3411_94 digest transform klass.
+ *
+ * Returns pointer to GOSTR3411_94 digest transform klass or NULL if an error
+ * occurs (the xmlsec-crypto library is not loaded or this transform is not
+ * implemented).
+ */
+xmlSecTransformId 
+xmlSecTransformGostR3411_94GetKlass(void) {
+    if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->transformGostR3411_94GetKlass == NULL)) {
+	xmlSecError(XMLSEC_ERRORS_HERE,
+		    NULL,
+		    "transformGostR3411_94Id",
+		    XMLSEC_ERRORS_R_NOT_IMPLEMENTED,
+		    XMLSEC_ERRORS_NO_MESSAGE);
+        return(xmlSecTransformIdUnknown);
+    }
+    
+    return(xmlSecCryptoDLGetFunctions()->transformGostR3411_94GetKlass());
+}
+
 
 /** 
  * xmlSecTransformSha1GetKlass:
Index: src/dl.c
===================================================================
RCS file: /cvs/xmlsec/src/dl.c,v
retrieving revision 1.1.1.1
retrieving revision 1.5
diff -u -w -r1.1.1.1 -r1.5
--- src/dl.c	6 Dec 2005 09:29:16 -0000	1.1.1.1
+++ src/dl.c	13 Dec 2005 14:31:46 -0000	1.5
@@ -587,6 +587,14 @@
 		    XMLSEC_ERRORS_NO_MESSAGE);
 	return(-1);
     }
+    if((functions->keyDataGost2001GetKlass != NULL) && (xmlSecKeyDataIdsRegister(functions->keyDataGost2001GetKlass()) < 0)) {
+	xmlSecError(XMLSEC_ERRORS_HERE,
+		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(functions->keyDataGost2001GetKlass())),
+		    "xmlSecKeyDataIdsRegister",
+		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
+		    XMLSEC_ERRORS_NO_MESSAGE);
+	return(-1);
+    }
     if((functions->keyDataHmacGetKlass != NULL) && (xmlSecKeyDataIdsRegister(functions->keyDataHmacGetKlass()) < 0)) {
 	xmlSecError(XMLSEC_ERRORS_HERE,
 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(functions->keyDataHmacGetKlass())),
@@ -696,6 +704,15 @@
 	return(-1);
     }    
 
+    if((functions->transformGost2001GostR3411_94GetKlass != NULL) && xmlSecTransformIdsRegister(functions->transformGost2001GostR3411_94GetKlass()) < 0) {
+	xmlSecError(XMLSEC_ERRORS_HERE,
+		    xmlSecErrorsSafeString(xmlSecTransformKlassGetName(functions->transformGost2001GostR3411_94GetKlass())),
+		    "xmlSecTransformIdsRegister",
+		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
+		    XMLSEC_ERRORS_NO_MESSAGE);
+	return(-1);
+    }    
+
     if((functions->transformDsaSha1GetKlass != NULL) && xmlSecTransformIdsRegister(functions->transformDsaSha1GetKlass()) < 0) {
 	xmlSecError(XMLSEC_ERRORS_HERE,
 		    xmlSecErrorsSafeString(xmlSecTransformKlassGetName(functions->transformDsaSha1GetKlass())),
@@ -861,6 +878,15 @@
     if((functions->transformRsaOaepGetKlass != NULL) && xmlSecTransformIdsRegister(functions->transformRsaOaepGetKlass()) < 0) {
 	xmlSecError(XMLSEC_ERRORS_HERE,
 		    xmlSecErrorsSafeString(xmlSecTransformKlassGetName(functions->transformRsaOaepGetKlass())),
+		    "xmlSecTransformIdsRegister",
+		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
+		    XMLSEC_ERRORS_NO_MESSAGE);
+	return(-1);
+    }    
+
+    if((functions->transformGostR3411_94GetKlass != NULL) && xmlSecTransformIdsRegister(functions->transformGostR3411_94GetKlass()) < 0) {
+	xmlSecError(XMLSEC_ERRORS_HERE,
+		    xmlSecErrorsSafeString(xmlSecTransformKlassGetName(functions->transformGostR3411_94GetKlass())),
 		    "xmlSecTransformIdsRegister",
 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
 		    XMLSEC_ERRORS_NO_MESSAGE);
Index: src/strings.c
===================================================================
RCS file: /cvs/xmlsec/src/strings.c,v
retrieving revision 1.1.1.1
diff -u -w -r1.1.1.1 strings.c
--- src/strings.c	6 Dec 2005 09:29:16 -0000	1.1.1.1
+++ src/strings.c	9 Feb 2006 09:31:07 -0000
@@ -285,6 +285,18 @@
 
 /*************************************************************************
  *
+ * GOST2001 strings
+ *
+ ************************************************************************/
+const xmlChar xmlSecNameGOST2001KeyValue[]		= "gost2001";
+const xmlChar xmlSecNodeGOST2001KeyValue[]		= "GOST3410-2001-KeyValue";
+const xmlChar xmlSecHrefGOST2001KeyValue[]		= "http://www.w3.org/2000/09/xmldsig#GOST2001KeyValue";
+
+const xmlChar xmlSecNameGost2001GostR3411_94[]		= "gostr34102001-gostr3411";
+const xmlChar xmlSecHrefGost2001GostR3411_94[]		= "http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411";
+
+/*************************************************************************
+ *
  * DSA strings
  *
  ************************************************************************/
@@ -438,6 +450,14 @@
 const xmlChar xmlSecNameRsaOaep[]		= "rsa-oaep-mgf1p";
 const xmlChar xmlSecHrefRsaOaep[]		= "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p";
 const xmlChar xmlSecNodeRsaOAEPparams[]		= "OAEPparams";
+
+/*************************************************************************
+ *
+ * GOSTR3411_94 strings
+ *
+ ************************************************************************/
+const xmlChar xmlSecNameGostR3411_94[]			= "gostr3411";
+const xmlChar xmlSecHrefGostR3411_94[]			= "http://www.w3.org/2001/04/xmldsig-more#gostr3411";
 
 /*************************************************************************
  *
Index: src/templates.c
===================================================================
RCS file: /cvs/xmlsec/src/templates.c,v
retrieving revision 1.1.1.1
retrieving revision 1.3
diff -u -w -r1.1.1.1 -r1.3
--- src/templates.c	6 Dec 2005 09:29:16 -0000	1.1.1.1
+++ src/templates.c	15 Dec 2005 16:56:04 -0000	1.3
@@ -1451,6 +1451,92 @@
 }
 
 /**
+ * xmlSecTmplX509IssuerSerialAddIssuerName:
+ * @x509IssuerSerialNode: 	the pointer to <dsig:X509IssuerSerial/> node.
+ * @issuerName:		the issuer name (optional).	
+ *
+ * Adds <dsig:X509IssuerName/> node to the <dsig:X509IssuerSerial/> node @x509IssuerSerialNode.
+ *
+ * Returns the pointer to the newly created <dsig:X509IssuerName/> node or
+ * NULL if an error occurs.
+ */
+xmlNodePtr
+xmlSecTmplX509IssuerSerialAddIssuerName(xmlNodePtr x509IssuerSerialNode, const xmlChar* issuerName) {
+	xmlNodePtr res;
+	
+	xmlSecAssert2(x509IssuerSerialNode != NULL, NULL);
+	
+  if(xmlSecFindChild(x509IssuerSerialNode, xmlSecNodeX509IssuerName,
+				xmlSecDSigNs) != NULL) {
+	xmlSecError(XMLSEC_ERRORS_HERE,
+		    NULL,
+		    xmlSecErrorsSafeString(xmlSecNodeX509IssuerName),
+		    XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,
+		    XMLSEC_ERRORS_NO_MESSAGE);
+	return(NULL);
+	}
+
+	res = xmlSecAddChild(x509IssuerSerialNode, xmlSecNodeX509IssuerName, xmlSecDSigNs);
+    if(res == NULL) {
+	xmlSecError(XMLSEC_ERRORS_HERE,
+		    NULL,
+		    "xmlSecAddChild",
+		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
+		    "node=%s",
+		    xmlSecErrorsSafeString(xmlSecNodeX509IssuerName));
+	return(NULL);	
+    }
+
+		if (issuerName != NULL) {
+			xmlNodeSetContent(res, issuerName);
+		}
+		return(res);
+}
+
+/**
+ * xmlSecTmplX509IssuerSerialAddIssuerName:
+ * @x509IssuerSerialNode: 	the pointer to <dsig:X509IssuerSerial/> node.
+ * @serial:		the serial number (optional).	
+ *
+ * Adds <dsig:X509SerialNumber/> node to the <dsig:X509IssuerSerial/> node @x509IssuerSerialNode.
+ *
+ * Returns the pointer to the newly created <dsig:X509SerialNumber/> node or
+ * NULL if an error occurs.
+ */
+xmlNodePtr
+xmlSecTmplX509IssuerSerialAddSerialNumber(xmlNodePtr x509IssuerSerialNode, const xmlChar* serial) {
+	xmlNodePtr res;
+
+	xmlSecAssert2(x509IssuerSerialNode != NULL, NULL);
+
+	if(xmlSecFindChild(x509IssuerSerialNode, xmlSecNodeX509SerialNumber,
+				xmlSecDSigNs) != NULL) {
+		xmlSecError(XMLSEC_ERRORS_HERE,
+				NULL,
+				xmlSecErrorsSafeString(xmlSecNodeX509SerialNumber),
+				XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,
+				XMLSEC_ERRORS_NO_MESSAGE);
+		return(NULL);
+	}
+
+	res = xmlSecAddChild(x509IssuerSerialNode, xmlSecNodeX509SerialNumber, xmlSecDSigNs);
+	if(res == NULL) {
+		xmlSecError(XMLSEC_ERRORS_HERE,
+				NULL,
+				"xmlSecAddChild",
+				XMLSEC_ERRORS_R_XMLSEC_FAILED,
+				"node=%s",
+				xmlSecErrorsSafeString(xmlSecNodeX509SerialNumber));
+		return(NULL);	
+	}
+
+	if (serial != NULL) {
+		xmlNodeSetContent(res, serial);
+	}
+	return(res);
+}
+
+/**
  * xmlSecTmplX509DataAddSubjectName:
  * @x509DataNode: 	the pointer to <dsig:X509Data/> node.
  * 
Index: src/transforms.c
===================================================================
RCS file: /cvs/xmlsec/src/transforms.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -w -r1.1.1.1 -r1.2
--- src/transforms.c	6 Dec 2005 09:29:16 -0000	1.1.1.1
+++ src/transforms.c	16 Dec 2005 13:18:32 -0000	1.2
@@ -1510,7 +1510,7 @@
     if(id == xmlSecTransformIdUnknown) {
 	xmlSecError(XMLSEC_ERRORS_HERE,
 		    NULL,
-		    "xmlSecTransformIdsListFindByHref",
+		    "xmlSecTransformIdListFindByHref",
 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
 		    "href=%s", 
 		    xmlSecErrorsSafeString(href));
Index: src/mscrypto/certkeys.c
===================================================================
RCS file: /cvs/xmlsec/src/mscrypto/certkeys.c,v
retrieving revision 1.1.1.1
diff -u -w -r1.1.1.1 certkeys.c
--- src/mscrypto/certkeys.c	6 Dec 2005 09:29:17 -0000	1.1.1.1
+++ src/mscrypto/certkeys.c	9 Feb 2006 09:31:08 -0000
@@ -13,6 +13,10 @@
 
 #include <windows.h>
 #include <wincrypt.h>
+#ifndef XMLSEC_NO_GOST
+#include "csp_oid.h"
+#include "csp_calg.h"
+#endif
 
 #include <xmlsec/xmlsec.h>
 #include <xmlsec/xmltree.h>
@@ -24,6 +28,7 @@
 
 #include <xmlsec/mscrypto/certkeys.h>
 #include <xmlsec/mscrypto/crypto.h>
+#include <xmlsec/mscrypto/x509.h>
 
 #define XMLSEC_CONTAINER_NAME "xmlsec-key-container"
 
@@ -427,7 +432,7 @@
         BOOL fCallerFreeProv = FALSE;
 
         if (!CryptAcquireCertificatePrivateKey(pCert, 
-					       CRYPT_ACQUIRE_USE_PROV_INFO_FLAG, 
+						CRYPT_ACQUIRE_COMPARE_KEY_FLAG, 
 					       NULL, 
 					       &hProv, 
 					       &(ctx->dwKeySpec), 
@@ -796,6 +801,20 @@
     }
 #endif /* XMLSEC_NO_DSA */	
 
+#ifndef XMLSEC_NO_GOST
+    if (!strcmp(pCert->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId,  szOID_MAGPRO_PUBKEY_SIGN_R3410_2001_CP) || !strcmp(pCert->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId,  szOID_MAGPRO_PUBKEY_SIGN_R3410_2001)) {
+	data = xmlSecKeyDataCreate(xmlSecMSCryptoKeyDataGost2001Id);
+	if(data == NULL) {
+		xmlSecError(XMLSEC_ERRORS_HERE,
+	    		    NULL,
+			    "xmlSecKeyDataCreate",
+			    XMLSEC_ERRORS_R_XMLSEC_FAILED,
+			    "xmlSecMSCryptoKeyDataGost2001Id");
+		return(NULL);	    
+	}
+    }
+#endif /* XMLSEC_NO_GOST*/	
+
     if (NULL == data) {
     	xmlSecError(XMLSEC_ERRORS_HERE,
 		    NULL,
@@ -2408,3 +2427,223 @@
 #endif /* XMLSEC_NO_DSA */
 
 
+#ifndef XMLSEC_NO_GOST
+/**************************************************************************
+ *
+ * GOST2001 xml key representation processing. Contain errors.
+ *
+ *************************************************************************/
+static int		xmlSecMSCryptoKeyDataGost2001Initialize(xmlSecKeyDataPtr data);
+static int		xmlSecMSCryptoKeyDataGost2001Duplicate(xmlSecKeyDataPtr dst,
+							 xmlSecKeyDataPtr src);
+static void		xmlSecMSCryptoKeyDataGost2001Finalize(xmlSecKeyDataPtr data);
+static int		xmlSecMSCryptoKeyDataGost2001XmlRead	(xmlSecKeyDataId id,
+							 xmlSecKeyPtr key,
+							 xmlNodePtr node,
+							 xmlSecKeyInfoCtxPtr keyInfoCtx);
+static int		xmlSecMSCryptoKeyDataGost2001XmlWrite(xmlSecKeyDataId id,
+							 xmlSecKeyPtr key,
+							 xmlNodePtr node,
+							 xmlSecKeyInfoCtxPtr keyInfoCtx);
+static int		xmlSecMSCryptoKeyDataGost2001Generate(xmlSecKeyDataPtr data,
+							 xmlSecSize sizeBits,
+							 xmlSecKeyDataType type);
+
+static xmlSecKeyDataType xmlSecMSCryptoKeyDataGost2001GetType(xmlSecKeyDataPtr data);
+static xmlSecSize	 xmlSecMSCryptoKeyDataGost2001GetSize(xmlSecKeyDataPtr data);
+static void		 xmlSecMSCryptoKeyDataGost2001DebugDump(xmlSecKeyDataPtr data,
+							 FILE* output);
+static void		xmlSecMSCryptoKeyDataGost2001DebugXmlDump(xmlSecKeyDataPtr data,
+							 FILE* output);
+
+static xmlSecKeyDataKlass xmlSecMSCryptoKeyDataGost2001Klass = {
+    sizeof(xmlSecKeyDataKlass),
+    xmlSecMSCryptoKeyDataSize,
+
+    /* data */
+    xmlSecNameGOST2001KeyValue,
+    xmlSecKeyDataUsageKeyValueNode | xmlSecKeyDataUsageRetrievalMethodNodeXml, 
+					/* xmlSecKeyDataUsage usage; */
+    /*xmlSecHrefGOST2001KeyValue*/NULL,		/* const xmlChar* href; */
+    /*xmlSecNodeGOST2001KeyValue*/NULL,		/* const xmlChar* dataNodeName; */
+    xmlSecDSigNs,			/* const xmlChar* dataNodeNs; */
+    
+    /* constructors/destructor */
+    xmlSecMSCryptoKeyDataGost2001Initialize,	/* xmlSecKeyDataInitializeMethod initialize; */
+    xmlSecMSCryptoKeyDataGost2001Duplicate,	/* xmlSecKeyDataDuplicateMethod duplicate; */
+    xmlSecMSCryptoKeyDataGost2001Finalize,	/* xmlSecKeyDataFinalizeMethod finalize; */
+    NULL, /* xmlSecMSCryptoKeyDataGost2001Generate,*/	/* xmlSecKeyDataGenerateMethod generate; */
+    
+    /* get info */
+    xmlSecMSCryptoKeyDataGost2001GetType, 	/* xmlSecKeyDataGetTypeMethod getType; */
+    xmlSecMSCryptoKeyDataGost2001GetSize,	/* xmlSecKeyDataGetSizeMethod getSize; */
+    NULL,				/* xmlSecKeyDataGetIdentifier getIdentifier; */    
+
+    /* read/write */
+    NULL,	/* xmlSecKeyDataXmlReadMethod xmlRead; */
+    NULL,	/* xmlSecKeyDataXmlWriteMethod xmlWrite; */
+    NULL,				/* xmlSecKeyDataBinReadMethod binRead; */
+    NULL,				/* xmlSecKeyDataBinWriteMethod binWrite; */
+
+    /* debug */
+    xmlSecMSCryptoKeyDataGost2001DebugDump,	/* xmlSecKeyDataDebugDumpMethod debugDump; */
+    xmlSecMSCryptoKeyDataGost2001DebugXmlDump,/* xmlSecKeyDataDebugDumpMethod debugXmlDump; */
+
+    /* reserved for the future */
+    NULL,				/* void* reserved0; */
+    NULL,				/* void* reserved1; */
+};
+
+/**
+ * xmlSecMSCryptoKeyDataGost2001GetKlass:
+ * 
+ * The GOST2001 key data klass.
+ *
+ * Returns pointer to GOST2001 key data klass.
+ */
+xmlSecKeyDataId 
+xmlSecMSCryptoKeyDataGost2001GetKlass(void) {
+    return(&xmlSecMSCryptoKeyDataGost2001Klass);
+}
+
+
+static int
+xmlSecMSCryptoKeyDataGost2001Initialize(xmlSecKeyDataPtr data) {
+    xmlSecMSCryptoKeyDataCtxPtr ctx;
+
+    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataGost2001Id), xmlSecKeyDataTypeUnknown);
+
+    xmlSecMSCryptoKeyDataInitialize(data);
+
+    ctx = xmlSecMSCryptoKeyDataGetCtx(data);
+    xmlSecAssert2(ctx != NULL, -1);
+
+    ctx->providerName = "MagPro CSP";
+    ctx->providerType = PROV_MAGPRO_GOST;
+    
+    return(0);
+}
+
+static int
+xmlSecMSCryptoKeyDataGost2001Duplicate(xmlSecKeyDataPtr dst, xmlSecKeyDataPtr src) {
+    xmlSecAssert2(xmlSecKeyDataCheckId(dst, xmlSecMSCryptoKeyDataGost2001Id), -1);
+    xmlSecAssert2(xmlSecKeyDataCheckId(src, xmlSecMSCryptoKeyDataGost2001Id), -1);
+
+    return(xmlSecMSCryptoKeyDataDuplicate(dst, src));
+}
+
+static void
+xmlSecMSCryptoKeyDataGost2001Finalize(xmlSecKeyDataPtr data) {
+    xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataGost2001Id));
+    
+    xmlSecMSCryptoKeyDataFinalize(data);
+}
+
+#if 0
+static int
+xmlSecMSCryptoKeyDataGost2001Generate(xmlSecKeyDataPtr data, xmlSecSize sizeBits, xmlSecKeyDataType type ATTRIBUTE_UNUSED) {
+    xmlSecMSCryptoKeyDataCtxPtr ctx;
+    HCRYPTPROV hProv = 0; 
+    HCRYPTKEY hKey = 0;
+    DWORD dwKeySpec;
+    DWORD dwSize;
+    int res = -1;
+    int ret;
+
+    xmlSecAssert2(xmlSecKeyDataIsValid(data), xmlSecKeyDataTypeUnknown);
+    xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecMSCryptoKeyDataSize), xmlSecKeyDataTypeUnknown);
+    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataGost2001Id), -1);
+    xmlSecAssert2(sizeBits > 0, -1);
+
+    ctx = xmlSecMSCryptoKeyDataGetCtx(data);
+
+    if(!CryptAcquireContext(&hProv, XMLSEC_CONTAINER_NAME, ctx->providerName, ctx->providerType, 0)) {
+	    if (NTE_BAD_KEYSET == GetLastError()) {
+	        if(!CryptAcquireContext(&hProv, XMLSEC_CONTAINER_NAME, ctx->providerName, ctx->providerType, CRYPT_NEWKEYSET)) {
+		        xmlSecError(XMLSEC_ERRORS_HERE,
+			            xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+			            "CryptAcquireContext",
+			            XMLSEC_ERRORS_R_CRYPTO_FAILED,
+			            XMLSEC_ERRORS_NO_MESSAGE);
+		        return(-1);
+	        }
+	    } else {
+	        xmlSecError(XMLSEC_ERRORS_HERE,
+			    xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+			    "CryptAcquireContext",
+			    XMLSEC_ERRORS_R_CRYPTO_FAILED,
+			    XMLSEC_ERRORS_NO_MESSAGE);
+	        return(-1);
+	    }
+    }
+
+    dwKeySpec = AT_SIGNATURE;
+    dwSize = ((sizeBits << 16) | CRYPT_EXPORTABLE);
+    if (!CryptGenKey(hProv, CALG_DSS_SIGN, dwSize, &hKey)) {
+	    xmlSecError(XMLSEC_ERRORS_HERE,
+		        xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+		        "CryptGenKey",
+		        XMLSEC_ERRORS_R_CRYPTO_FAILED,
+		        XMLSEC_ERRORS_NO_MESSAGE);
+	    goto done;
+    }
+
+    ret = xmlSecMSCryptoKeyDataAdoptKey(data, hProv, TRUE, hKey, dwKeySpec, 
+	xmlSecKeyDataTypePublic | xmlSecKeyDataTypePrivate);
+    if(ret < 0) {
+	    xmlSecError(XMLSEC_ERRORS_HERE,
+		        xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+		        "xmlSecMSCryptoKeyDataAdoptKey",
+		        XMLSEC_ERRORS_R_XMLSEC_FAILED,
+		        XMLSEC_ERRORS_NO_MESSAGE);
+	    goto done;
+    }
+    hProv = 0;
+    hKey = 0;
+
+    /* success */
+    res = 0;
+
+done:
+    if (hProv != 0) {
+    	CryptReleaseContext(hProv, 0);
+    }
+
+    if (hKey != 0) {
+	    CryptDestroyKey(hKey);
+    }
+
+    return(res);
+}
+#endif
+static xmlSecKeyDataType
+xmlSecMSCryptoKeyDataGost2001GetType(xmlSecKeyDataPtr data) {
+    return(xmlSecMSCryptoKeyDataGetType(data));
+}
+
+static xmlSecSize 
+xmlSecMSCryptoKeyDataGost2001GetSize(xmlSecKeyDataPtr data) {
+    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataGost2001Id), 0);
+
+    return xmlSecMSCryptoKeyDataGetSize(data);
+}
+
+static void 
+xmlSecMSCryptoKeyDataGost2001DebugDump(xmlSecKeyDataPtr data, FILE* output) {
+    xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataGost2001Id));
+    xmlSecAssert(output != NULL);
+    
+    fprintf(output, "=== dsa key: size = %d\n", 
+	    xmlSecMSCryptoKeyDataGost2001GetSize(data));
+}
+
+static void
+xmlSecMSCryptoKeyDataGost2001DebugXmlDump(xmlSecKeyDataPtr data, FILE* output) {
+    xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataGost2001Id));
+    xmlSecAssert(output != NULL);
+        
+    fprintf(output, "<GOST2001KeyValue size=\"%d\" />\n", 
+	    xmlSecMSCryptoKeyDataGost2001GetSize(data));
+}
+
+#endif /* XMLSEC_NO_GOST*/
Index: src/mscrypto/crypto.c
===================================================================
RCS file: /cvs/xmlsec/src/mscrypto/crypto.c,v
retrieving revision 1.1.1.1
diff -u -w -r1.1.1.1 crypto.c
--- src/mscrypto/crypto.c	6 Dec 2005 09:29:16 -0000	1.1.1.1
+++ src/mscrypto/crypto.c	9 Feb 2006 09:31:08 -0000
@@ -69,6 +69,10 @@
     gXmlSecMSCryptoFunctions->keyDataDsaGetKlass 		= xmlSecMSCryptoKeyDataDsaGetKlass;
 #endif /* XMLSEC_NO_DSA */
 
+#ifndef XMLSEC_NO_GOST
+    gXmlSecMSCryptoFunctions->keyDataGost2001GetKlass 		= xmlSecMSCryptoKeyDataGost2001GetKlass;
+#endif /* XMLSEC_NO_GOST*/
+
 #ifndef XMLSEC_NO_X509
     gXmlSecMSCryptoFunctions->keyDataX509GetKlass 		= xmlSecMSCryptoKeyDataX509GetKlass;
     gXmlSecMSCryptoFunctions->keyDataRawX509CertGetKlass	= xmlSecMSCryptoKeyDataRawX509CertGetKlass;
@@ -103,10 +107,18 @@
     gXmlSecMSCryptoFunctions->transformDsaSha1GetKlass 		= xmlSecMSCryptoTransformDsaSha1GetKlass;
 #endif /* XMLSEC_NO_DSA */
 
+#ifndef XMLSEC_NO_GOST
+    gXmlSecMSCryptoFunctions->transformGost2001GostR3411_94GetKlass 		= xmlSecMSCryptoTransformGost2001GostR3411_94GetKlass;
+#endif /* XMLSEC_NO_GOST */
+
 #ifndef XMLSEC_NO_SHA1    
     gXmlSecMSCryptoFunctions->transformSha1GetKlass 		= xmlSecMSCryptoTransformSha1GetKlass;
 #endif /* XMLSEC_NO_SHA1 */
 
+#ifndef XMLSEC_NO_GOST    
+    gXmlSecMSCryptoFunctions->transformGostR3411_94GetKlass 		= xmlSecMSCryptoTransformGostR3411_94GetKlass;
+#endif /* XMLSEC_NO_GOST */
+
     /**
      * High level routines form xmlsec command line utility
      */ 
Index: src/mscrypto/csp_calg.h
===================================================================
RCS file: src/mscrypto/csp_calg.h
diff -N src/mscrypto/csp_calg.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/mscrypto/csp_calg.h	9 Feb 2006 09:31:08 -0000
@@ -0,0 +1,92 @@
+/** 
+ * XMLSec library
+ *
+ * This is free software; see Copyright file in the source
+ * distribution for preciese wording.
+ * 
+ * Copyright (C) 2005-2006 Aleksey Sanin <aleksey at aleksey.com>
+ * Copyright (c) 2005-2006 Cryptocom LTD (http://www.cryptocom.ru).  
+ * All rights reserved.
+ */
+#ifndef CRYPTOCOM_CSP_CALG_H
+#define CRYPTOCOM_CSP_CALG_H
+
+#define ALG_TYPE_GR3410 (7 << 9)
+
+#define ALG_SID_MAGPRO_R3410_94			64
+#define ALG_SID_MAGPRO_R3410_94_EPHEM	65
+#define ALG_SID_MAGPRO_R3410_2001		66
+#define ALG_SID_MAGPRO_R3410_2001_EPHEM	67
+#define ALG_SID_MAGPRO_28147_89			68
+#define ALG_SID_GR3411					30
+#define ALG_SID_G28147					30
+
+#define ALG_SID_GR3410					30
+#define ALG_SID_DH_EX_SF				30
+#define ALG_SID_DH_EX_EPHEM				31
+#define ALG_SID_PRO_AGREEDKEY_DH		33
+#define ALG_SID_PRO_SIMMETRYKEY			34
+#define ALG_SID_GR3410EL				35
+#define ALG_SID_DH_EL_SF				36
+#define ALG_SID_DH_EL_EPHEM				37
+
+/*! \defgroup CALG_MAGPRO CALG_MAGPRO 
+ *  \brief The description of CALG_MAGPRO
+ *
+ * @{ 
+ */
+
+
+#define CALG_MAGPRO_SIGN_R3410_94       (ALG_CLASS_SIGNATURE | ALG_TYPE_GR3410 | ALG_SID_MAGPRO_R3410_94)
+
+#define CALG_MAGPRO_SIGN_R3410_2001     (ALG_CLASS_SIGNATURE | ALG_TYPE_GR3410 | ALG_SID_MAGPRO_R3410_2001)
+
+#define CALG_MAGPRO_DH_R3410_94         (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | ALG_SID_MAGPRO_R3410_94)
+
+#define CALG_MAGPRO_DH_R3410_2001       (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | ALG_SID_MAGPRO_R3410_2001)
+
+#define CALG_MAGPRO_DH_R3410_94_EPHEM   (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | ALG_SID_MAGPRO_R3410_94_EPHEM)
+
+#define CALG_MAGPRO_DH_R3410_2001_EPHEM (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | ALG_SID_MAGPRO_R3410_2001_EPHEM)
+
+#define CALG_MAGPRO_HASH_R3411_94       (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_GR3411)
+
+#define CALG_MAGPRO_HASH_28147_89       (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MAGPRO_28147_89)
+
+#define CALG_MAGPRO_ENCR_28147_89       (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_G28147)
+
+#define CALG_GR3410						(ALG_CLASS_SIGNATURE | ALG_TYPE_GR3410 | ALG_SID_GR3410)
+
+#define CALG_GR3410EL					(ALG_CLASS_SIGNATURE | ALG_TYPE_GR3410 | ALG_SID_GR3410EL)
+
+#define CALG_DH_EX_SF					(ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | ALG_SID_DH_EX_SF)
+
+#define CALG_DH_EX_EPHEM				(ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | ALG_SID_DH_EX_EPHEM)
+
+#define CALG_DH_EL_SF					(ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | ALG_SID_DH_EL_SF)
+
+#define CALG_DH_EL_EPHEM				(ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | ALG_SID_DH_EL_EPHEM)
+
+/*! @} */
+/*! \defgroup PROV_TYPE PROV_TYPE 
+ *  \brief The description of PROV_MAGPRO_GOST
+ *
+ * @{ 
+ */
+
+
+#define PROV_MAGPRO_GOST 501
+
+/*! @} */
+/*! \defgroup PP_MAGPRO PP_MAGPRO 
+ *
+ * @{ 
+ */
+
+#define PP_RNGTYPE			201
+#define PP_RNGSHARED		202
+#define PP_SETUP_UI			203
+
+/*! @} */
+
+#endif //CRYPTOCOM_CSP_CALG_H
Index: src/mscrypto/csp_oid.h
===================================================================
RCS file: src/mscrypto/csp_oid.h
diff -N src/mscrypto/csp_oid.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/mscrypto/csp_oid.h	9 Feb 2006 09:31:08 -0000
@@ -0,0 +1,115 @@
+/** 
+ * XMLSec library
+ *
+ * This is free software; see Copyright file in the source
+ * distribution for preciese wording.
+ * 
+ * Copyright (C) 2005-2006 Aleksey Sanin <aleksey at aleksey.com>
+ * Copyright (c) 2005-2006 Cryptocom LTD (http://www.cryptocom.ru).  
+ * All rights reserved.
+ */
+#ifndef CRYPTOCOM_OIDS_csp_H
+#define CRYPTOCOM_OIDS_csp_H
+/* Autogenerated from master.oid by oid2h.tcl */
+
+/*! \defgroup szOID_MAGPRO szOID_MAGPRO 
+ *  \brief The OIDs supported by MagPro CSP
+ *
+ * @{ 
+ */
+
+/*! GOST 34.10-94 Diffie-Hellman algorithm Cryptocom LTD */
+#define szOID_MAGPRO_DH_R3410_94 "1.2.643.2.9.1.3.1"
+
+/*! GOST 34.10-2001 Diffie-Hellman algorithm Cryptocom LTD */
+#define szOID_MAGPRO_DH_R3410_2001 "1.2.643.2.9.1.3.2"
+
+/*  */
+#define szOID_MAGPRO_DH_R3410_94_EPHEM "1.2.643.2.9.1.3.1"
+
+/*  */
+#define szOID_MAGPRO_DH_R3410_2001_EPHEM "1.2.643.2.9.1.3.2"
+
+/*! GOST 34.10/11-94 digital signature algorithm Cryptocom LTD with digest */
+#define szOID_MAGPRO_SIGN_R3410_94 "1.2.643.2.9.1.3.3"
+
+/*! GOST 34.10-2001 digital signature algorithm with digest */
+#define szOID_MAGPRO_SIGN_R3410_2001 "1.2.643.2.9.1.3.4"
+
+/*! GOST 28147-89 MAC algorithm Cryptocom LTD */
+#define szOID_MAGPRO_HASH_28147_89 "1.2.643.2.9.1.4.1"
+
+#define szOID_MAGPRO_PUBKEY_DH_R3410_94 "1.2.643.2.9.1.5.1"
+
+#define szOID_MAGPRO_PUBKEY_DH_R3410_2001 "1.2.643.2.9.1.5.2"
+
+/*! GOST 34.10/11-94 digital signature algorithm Cryptocom LTD */
+#define szOID_MAGPRO_PUBKEY_SIGN_R3410_94 "1.2.643.2.9.1.5.3"
+
+/*! GOST 34.10-2001 digital signature algorithm */
+#define szOID_MAGPRO_PUBKEY_SIGN_R3410_2001 "1.2.643.2.9.1.5.4"
+
+/*! GOST 28147-89 encryption parameters */
+#define szOID_MAGPRO_PARAM_ENCR_28147_89 "1.2.643.2.9.1.6.1"
+
+/*! GOST 34.10-2001 public key parameters */
+#define szOID_MAGPRO_PARAM_PK_CC_01 "1.2.643.2.9.1.8.1"
+
+/*! GOST 28147-89 symmetric cipher Cryptocom LTD */
+#define szOID_MAGPRO_ENCR_28147_89 "1.2.643.2.2.21"
+
+/*! GOST 34.10-2001 digital signature algorithm CryptoPro LTD */
+#define szOID_MAGPRO_SIGN_R3410_2001_CP "1.2.643.2.2.3"
+
+/*! GOST 34.10/11-94 digital signature algorithm CryptoPro LTD */
+#define szOID_MAGPRO_SIGN_R3410_94_CP "1.2.643.2.2.4"
+
+/*! GOST 34.11-94 digest algorithm Cryptocom LTD */
+#define szOID_MAGPRO_HASH_R3411_94 "1.2.643.2.2.9"
+
+/*! GOST 34.10-2001 digital signature algorithm CryptoPro LTD public key */
+#define szOID_MAGPRO_PUBKEY_SIGN_R3410_2001_CP "1.2.643.2.2.19"
+
+/*! GOST 34.10/11-94 digital signature algorithm CryptoPro LTD public key */
+#define szOID_MAGPRO_PUBKEY_SIGN_R3410_94_CP "1.2.643.2.2.20"
+
+/*! GostR3411-94-CryptoProParamSet */
+#define szOID_MAGPRO_PARAM_HASH_3411_94 "1.2.643.2.2.30.1"
+
+/*! GostR3410-94-CryptoPro-A-ParamSet */
+#define szOID_MAGPRO_PARAM_PK_CC_94 "1.2.643.2.2.32.2"
+
+
+#define szOID_CP_PARAM_R3411_94_DEF "1.2.643.2.2.30.1"	
+#define szOID_CP_PARAM_R3411_94_1	"1.2.643.2.2.30.2"
+#define szOID_CP_PARAM_R3411_94_2	"1.2.643.2.2.30.3"
+#define szOID_CP_PARAM_R3411_94_3	"1.2.643.2.2.30.4"
+
+#define szOID_CP_PARAM_28147_89_DEF "1.2.643.2.2.31.1"	
+#define szOID_CP_PARAM_28147_89_1	"1.2.643.2.2.31.2"	
+#define szOID_CP_PARAM_28147_89_2	"1.2.643.2.2.31.3" 	
+#define szOID_CP_PARAM_28147_89_3	"1.2.643.2.2.31.4"	
+#define szOID_CP_PARAM_28147_89_4	"1.2.643.2.2.31.5"
+#define szOID_CP_PARAM_28147_89_5	"1.2.643.2.2.31.6"
+#define szOID_CP_PARAM_28147_89_6	"1.2.643.2.2.31.7"
+
+/* OID for Signature 1024*/
+#define szOID_CP_PARAM_PK_R3410_94_DEF  "1.2.643.2.2.32.2" 	/*VerbaO*/
+#define szOID_CP_PARAM_PK_R3410_94_S1   "1.2.643.2.2.32.3" 
+#define szOID_CP_PARAM_PK_R3410_94_S2   "1.2.643.2.2.32.4" 
+#define szOID_CP_PARAM_PK_R3410_94_S3   "1.2.643.2.2.32.5" 
+/* OID for DH 1024*/
+#define szOID_CP_PARAM_PK_R3410_94_E1   "1.2.643.2.2.33.1" 
+#define szOID_CP_PARAM_PK_R3410_94_E2   "1.2.643.2.2.33.2" 
+#define szOID_CP_PARAM_PK_R3410_94_E3   "1.2.643.2.2.33.3" 
+
+#define szOID_CP_PARAM_PK_R3410_2001_DEF "1.2.643.2.2.35.1"	
+#define szOID_CP_PARAM_PK_R3410_2001_S0	 "1.2.643.2.2.35.2"	
+#define szOID_CP_PARAM_PK_R3410_2001_S1	 "1.2.643.2.2.35.3"	
+#define szOID_CP_PARAM_PK_R3410_2001_E0	 "1.2.643.2.2.36.0"	
+#define szOID_CP_PARAM_PK_R3410_2001_E1	 "1.2.643.2.2.36.1"	
+
+
+/*! @} */
+
+#endif
Index: src/mscrypto/digests.c
===================================================================
RCS file: /cvs/xmlsec/src/mscrypto/digests.c,v
retrieving revision 1.1.1.1
retrieving revision 1.7
diff -u -w -r1.1.1.1 -r1.7
--- src/mscrypto/digests.c	6 Dec 2005 09:29:17 -0000	1.1.1.1
+++ src/mscrypto/digests.c	27 Dec 2005 10:18:04 -0000	1.7
@@ -11,6 +11,9 @@
 #include <string.h>
 #include <windows.h>
 #include <wincrypt.h>
+#ifndef XMLSEC_NO_GOST
+#include "csp_calg.h"
+#endif
 
 #include <xmlsec/xmlsec.h>
 #include <xmlsec/keys.h>
@@ -63,6 +66,12 @@
     }
 #endif /* XMLSEC_NO_SHA1 */    
     
+#ifndef XMLSEC_NO_GOST
+    if(xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformGostR3411_94Id)) {
+	return(1);
+    }
+#endif /* XMLSEC_NO_GOST*/    
+    
     return(0);
 }
 
@@ -85,6 +94,24 @@
     } else 
 #endif /* XMLSEC_NO_SHA1 */    
 
+#ifndef XMLSEC_NO_GOST
+    if(xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformGostR3411_94Id)) {
+		ctx->alg_id = CALG_MAGPRO_HASH_R3411_94;
+
+    /* TODO: Check what provider is best suited here.... */
+    if (!CryptAcquireContext(&ctx->provider, NULL, 0, PROV_MAGPRO_GOST, CRYPT_VERIFYCONTEXT)) {
+	xmlSecError(XMLSEC_ERRORS_HERE, 
+		    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+		    NULL,
+		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
+		    XMLSEC_ERRORS_NO_MESSAGE);
+	return(-1);
+    }
+
+    return(0);
+    } else 
+#endif /* XMLSEC_NO_GOST*/    
+
     {
 	xmlSecError(XMLSEC_ERRORS_HERE, 
 		    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
@@ -335,4 +362,48 @@
     return(&xmlSecMSCryptoSha1Klass);
 }
 #endif /* XMLSEC_NO_SHA1 */
+
+#ifndef XMLSEC_NO_GOST
+/******************************************************************************
+ *
+ * GOSTR3411_94
+ *
+ *****************************************************************************/
+static xmlSecTransformKlass xmlSecMSCryptoGostR3411_94Klass = {
+    /* klass/object sizes */
+    sizeof(xmlSecTransformKlass),		/* size_t klassSize */
+    xmlSecMSCryptoDigestSize,			/* size_t objSize */
+
+    xmlSecNameGostR3411_94,				/* const xmlChar* name; */
+    xmlSecHrefGostR3411_94, 				/* const xmlChar* href; */
+    xmlSecTransformUsageDigestMethod,		/* xmlSecTransformUsage usage; */
+    xmlSecMSCryptoDigestInitialize,		/* xmlSecTransformInitializeMethod initialize; */
+    xmlSecMSCryptoDigestFinalize,		/* xmlSecTransformFinalizeMethod finalize; */
+    NULL,					/* xmlSecTransformNodeReadMethod readNode; */
+    NULL,					/* xmlSecTransformNodeWriteMethod writeNode; */
+    NULL,					/* xmlSecTransformSetKeyReqMethod setKeyReq; */
+    NULL,					/* xmlSecTransformSetKeyMethod setKey; */
+    xmlSecMSCryptoDigestVerify,			/* xmlSecTransformVerifyMethod verify; */
+    xmlSecTransformDefaultGetDataType,		/* xmlSecTransformGetDataTypeMethod getDataType; */
+    xmlSecTransformDefaultPushBin,		/* xmlSecTransformPushBinMethod pushBin; */
+    xmlSecTransformDefaultPopBin,		/* xmlSecTransformPopBinMethod popBin; */
+    NULL,					/* xmlSecTransformPushXmlMethod pushXml; */
+    NULL,					/* xmlSecTransformPopXmlMethod popXml; */
+    xmlSecMSCryptoDigestExecute,		/* xmlSecTransformExecuteMethod execute; */    
+    NULL,					/* void* reserved0; */
+    NULL,					/* void* reserved1; */
+};
+
+/** 
+ * xmlSecMSCryptoTransformGostR3411_94GetKlass:
+ *
+ * GOSTR3411_94 digest transform klass.
+ *
+ * Returns pointer to GOSTR3411_94 digest transform klass.
+ */
+xmlSecTransformId 
+xmlSecMSCryptoTransformGostR3411_94GetKlass(void) {
+    return(&xmlSecMSCryptoGostR3411_94Klass);
+}
+#endif /* XMLSEC_NO_GOST*/
 
Index: src/mscrypto/signatures.c
===================================================================
RCS file: /cvs/xmlsec/src/mscrypto/signatures.c,v
retrieving revision 1.1.1.1
diff -u -w -r1.1.1.1 signatures.c
--- src/mscrypto/signatures.c	6 Dec 2005 09:29:16 -0000	1.1.1.1
+++ src/mscrypto/signatures.c	9 Feb 2006 09:31:08 -0000
@@ -13,6 +13,9 @@
 
 #include <windows.h>
 #include <wincrypt.h>
+#ifndef XMLSEC_NO_GOST
+#include "csp_calg.h"
+#endif
 
 #include <xmlsec/xmlsec.h>
 #include <xmlsec/keys.h>
@@ -22,6 +25,7 @@
 #include <xmlsec/mscrypto/crypto.h>
 #include <xmlsec/mscrypto/symbols.h>
 #include <xmlsec/mscrypto/certkeys.h>
+#include <xmlsec/mscrypto/x509.h>
 
 /**************************************************************************
  *
@@ -74,6 +78,12 @@
     }
 #endif /* XMLSEC_NO_DSA */
 
+#ifndef XMLSEC_NO_GOST
+    if(xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformGost2001GostR3411_94Id)) {
+	return(1);
+    }
+#endif /* XMLSEC_NO_GOST*/
+
 #ifndef XMLSEC_NO_RSA
     if(xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformRsaSha1Id)) {
 	return(1);
@@ -101,6 +111,13 @@
     } else 
 #endif /* XMLSEC_NO_RSA */
 
+#ifndef XMLSEC_NO_GOST
+    if(xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformGost2001GostR3411_94Id)) {
+	ctx->digestAlgId    = CALG_MAGPRO_HASH_R3411_94;
+	ctx->keyId	    = xmlSecMSCryptoKeyDataGost2001Id;
+    } else 
+#endif /* XMLSEC_NO_GOST*/
+
 #ifndef XMLSEC_NO_DSA
     if(xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformDsaSha1Id)) {
 	ctx->digestAlgId    = CALG_SHA1;
@@ -243,6 +260,12 @@
     	    *l-- = *j++;
 	    *m-- = *k++;
 	}
+    } else if (xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformGost2001GostR3411_94Id)) {
+	j = (BYTE *)data;
+	l = tmpBuf + dataSize - 1;
+	while (l >= tmpBuf) {
+	    *l-- = *j++;
+	}
     } else if (xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformRsaSha1Id)) {
 	j = (BYTE *)data;
 	l = tmpBuf + dataSize - 1;
@@ -439,6 +462,13 @@
 		    *m-- = *i++;
 		    *n-- = *j++;
 		}
+    } else if (xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformGost2001GostR3411_94Id)) {
+		i = tmpBuf;
+		j = outBuf + dwSigLen - 1;
+
+		while (j >= outBuf) {
+		    *j-- = *i++;
+		}
 	    } else if (xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformRsaSha1Id)) {
 		i = tmpBuf;
 		j = outBuf + dwSigLen - 1;
@@ -571,4 +601,52 @@
 }
 
 #endif /* XMLSEC_NO_DSA */
+
+#ifndef XMLSEC_NO_GOST
+/****************************************************************************
+ *
+ * GOST2001-GOSTR3411_94 signature transform
+ *
+ ***************************************************************************/
+
+static xmlSecTransformKlass xmlSecMSCryptoGost2001GostR3411_94Klass = {
+    /* klass/object sizes */
+    sizeof(xmlSecTransformKlass),		/* xmlSecSize klassSize */
+    xmlSecMSCryptoSignatureSize,	        /* xmlSecSize objSize */
+
+    xmlSecNameGost2001GostR3411_94,				/* const xmlChar* name; */
+    xmlSecHrefGost2001GostR3411_94, 				/* const xmlChar* href; */
+    xmlSecTransformUsageSignatureMethod,	/* xmlSecTransformUsage usage; */
+    
+    xmlSecMSCryptoSignatureInitialize,	        /* xmlSecTransformInitializeMethod initialize; */
+    xmlSecMSCryptoSignatureFinalize,		/* xmlSecTransformFinalizeMethod finalize; */
+    NULL,					/* xmlSecTransformNodeReadMethod readNode; */
+    NULL,					/* xmlSecTransformNodeWriteMethod writeNode; */
+    xmlSecMSCryptoSignatureSetKeyReq,		/* xmlSecTransformSetKeyReqMethod setKeyReq; */
+    xmlSecMSCryptoSignatureSetKey,		/* xmlSecTransformSetKeyMethod setKey; */
+    xmlSecMSCryptoSignatureVerify,		/* xmlSecTransformVerifyMethod verify; */
+    xmlSecTransformDefaultGetDataType,		/* xmlSecTransformGetDataTypeMethod getDataType; */
+    xmlSecTransformDefaultPushBin,		/* xmlSecTransformPushBinMethod pushBin; */
+    xmlSecTransformDefaultPopBin,		/* xmlSecTransformPopBinMethod popBin; */
+    NULL,					/* xmlSecTransformPushXmlMethod pushXml; */
+    NULL,					/* xmlSecTransformPopXmlMethod popXml; */
+    xmlSecMSCryptoSignatureExecute,		/* xmlSecTransformExecuteMethod execute; */
+    
+    NULL,					/* void* reserved0; */
+    NULL,					/* void* reserved1; */
+};
+
+/**
+ * xmlSecMSCryptoTransformGost2001GostR3411_94GetKlass:
+ * 
+ * The GOST2001-GOSTR3411_94 signature transform klass.
+ *
+ * Returns GOST2001-GOSTR3411_94 signature transform klass.
+ */
+xmlSecTransformId 
+xmlSecMSCryptoTransformGost2001GostR3411_94GetKlass(void) {
+    return(&xmlSecMSCryptoGost2001GostR3411_94Klass);
+}
+
+#endif /* XMLSEC_NO_GOST*/
 
Index: src/mscrypto/x509vfy.c
===================================================================
RCS file: /cvs/xmlsec/src/mscrypto/x509vfy.c,v
retrieving revision 1.1.1.1
retrieving revision 1.8
diff -u -w -r1.1.1.1 -r1.8
--- src/mscrypto/x509vfy.c	6 Dec 2005 09:29:16 -0000	1.1.1.1
+++ src/mscrypto/x509vfy.c	13 Jan 2006 18:50:48 -0000	1.8
@@ -261,34 +261,118 @@
     xmlFree(subject);
 }
 
+/**
+ @cert: the certificate we check
+ @pfTime: pointer to FILETIME that we are interested in
+ @store_untrusted: untrusted certificates added via API
+ @store_doc: untrusted certificates/CRLs extracted from a document
+ */
 static BOOL
-xmlSecMSCryptoX509StoreConstructCertsChain(xmlSecKeyDataStorePtr store, PCCERT_CONTEXT cert, HCERTSTORE certs, 
-			      xmlSecKeyInfoCtx* keyInfoCtx) {
-    xmlSecMSCryptoX509StoreCtxPtr ctx;
-    PCCERT_CONTEXT issuerCert = NULL;
-    FILETIME fTime;
-    DWORD flags;
+xmlSecBuildChainUsingWinapi (PCCERT_CONTEXT cert, LPFILETIME pfTime,
+		HCERTSTORE store_untrusted, HCERTSTORE store_doc)
+{
+	PCCERT_CHAIN_CONTEXT     pChainContext = NULL;
+	CERT_CHAIN_PARA          chainPara;
+	BOOL rc = FALSE;
+	HCERTSTORE store_add = NULL;
+
+	/* Initialize data structures. */
+
+	memset(&chainPara, 0, sizeof(CERT_CHAIN_PARA));
+	chainPara.cbSize = sizeof(CERT_CHAIN_PARA);
+
+	/* Create additional store for CertGetCertificateChain() */
+	store_add = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0, 0, NULL);
+	if (!store_add) {
+		xmlSecError(XMLSEC_ERRORS_HERE,
+					"chain additional collection store",
+					"CertOpenStore",
+					XMLSEC_ERRORS_R_CRYPTO_FAILED,
+					XMLSEC_ERRORS_NO_MESSAGE);
+		goto end;
+	}
+	if (!CertAddStoreToCollection(store_add, store_doc, 0, 0)) {
+		xmlSecError(XMLSEC_ERRORS_HERE,
+					"adding document store",
+					"CertAddStoreToCollection",
+					XMLSEC_ERRORS_R_CRYPTO_FAILED,
+					XMLSEC_ERRORS_NO_MESSAGE);
+		goto end;
+	}
+	if (!CertAddStoreToCollection(store_add, store_untrusted, 0, 0)) {
+		xmlSecError(XMLSEC_ERRORS_HERE,
+					"adding untrusted store",
+					"CertAddStoreToCollection",
+					XMLSEC_ERRORS_R_CRYPTO_FAILED,
+					XMLSEC_ERRORS_NO_MESSAGE);
+		goto end;
+	}
     
-    xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecMSCryptoX509StoreId), FALSE);
-    xmlSecAssert2(cert != NULL, FALSE);
-    xmlSecAssert2(cert->pCertInfo != NULL, FALSE);
-    xmlSecAssert2(certs != NULL, FALSE);
-    xmlSecAssert2(keyInfoCtx != NULL, FALSE);
+	/* Build a chain using CertGetCertificateChain
+	 and the certificate retrieved. */
+	if(!CertGetCertificateChain(
+				NULL,                  /* use the default chain engine */
+				cert,
+				pfTime,
+				store_add,
+				&chainPara,
+				CERT_CHAIN_REVOCATION_CHECK_CHAIN,
+				NULL,
+				&pChainContext))
+	{
+    	xmlSecError(XMLSEC_ERRORS_HERE,
+		    "building certificate chain, checking root",
+		    "CertGetCertificateChain",
+		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
+		    XMLSEC_ERRORS_NO_MESSAGE);
+		goto end;
+	}
+	if (pChainContext->TrustStatus.dwErrorStatus == CERT_TRUST_REVOCATION_STATUS_UNKNOWN) {
+		CertFreeCertificateChain(pChainContext); pChainContext = NULL;
+		if(!CertGetCertificateChain(
+			   NULL,                  /* use the default chain engine */
+			   cert,
+			   pfTime,
+			   store_add,
+			   &chainPara,
+			   CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT,
+			   NULL,
+			   &pChainContext))
+		{
+			xmlSecError(XMLSEC_ERRORS_HERE,
+						"building certificate chain, excluding root",
+						"CertGetCertificateChain",
+						XMLSEC_ERRORS_R_CRYPTO_FAILED,
+						XMLSEC_ERRORS_NO_MESSAGE);
+			goto end;
+		}
+	}
 
-    ctx = xmlSecMSCryptoX509StoreGetCtx(store);
-    xmlSecAssert2(ctx != NULL, FALSE);
-    xmlSecAssert2(ctx->trusted != NULL, FALSE);
-    xmlSecAssert2(ctx->untrusted != NULL, FALSE);
+	if (pChainContext->TrustStatus.dwErrorStatus == CERT_TRUST_NO_ERROR)
+		rc = TRUE;
 
-    if(keyInfoCtx->certsVerificationTime > 0) {
-	    /* convert the time to FILETIME */
-    	xmlSecMSCryptoUnixTimeToFileTime(keyInfoCtx->certsVerificationTime, &fTime);
-    } else {
-	    /* Defaults to current time */
-	    GetSystemTimeAsFileTime(&fTime);
+end:
+	if (pChainContext) CertFreeCertificateChain(pChainContext);
+	if (store_add) CertCloseStore(store_add, 0);
+	return (rc);
     }
 
-    if (!xmlSecMSCrypoVerifyCertTime(cert, &fTime)) {
+/**
+ @cert: the certificate we check
+ @pfTime: pointer to FILETIME that we are interested in
+ @store_trusted: trusted certificates added via API
+ @store_untrusted: untrusted certificates added via API
+ @certs: untrusted certificates/CRLs extracted from a document
+ @store: pointer to store klass passed to error functions
+ */
+static BOOL
+xmlSecMSCryptoBuildCertChainManually (PCCERT_CONTEXT cert, LPFILETIME pfTime,
+	HCERTSTORE store_trusted, HCERTSTORE store_untrusted, HCERTSTORE certs,
+	xmlSecKeyDataStorePtr store) {
+	PCCERT_CONTEXT issuerCert = NULL;
+    DWORD flags;
+
+    if (!xmlSecMSCrypoVerifyCertTime(cert, pfTime)) {
     	xmlSecMSCryptoX509StoreCertError(store, cert, CERT_STORE_TIME_VALIDITY_FLAG);
 	    return(FALSE);
     }
@@ -301,7 +385,7 @@
      * Try to find the cert in the trusted cert store. We will trust

      * the certificate in the trusted store.

 	 */

-    issuerCert = CertFindCertificateInStore(ctx->trusted, 

+    issuerCert = CertFindCertificateInStore(store_trusted, 
 			    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,

 			    0,

 			    CERT_FIND_SUBJECT_NAME,

@@ -309,6 +393,8 @@
 			    NULL);

     if( issuerCert != NULL) {

 		/* We have found the trusted cert, so return true */

+	    /* todo: do we want to verify the trusted cert's revocation? we must,
+		 * I think */
 		CertFreeCertificateContext( issuerCert ) ;

 		return( TRUE ) ;

     }

@@ -319,7 +405,7 @@
     }

 
     /* try to find issuer cert in the trusted cert in the store */
-    issuerCert = CertFindCertificateInStore(ctx->trusted, 
+    issuerCert = CertFindCertificateInStore(store_trusted, 
 			    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
 			    0,
 			    CERT_FIND_SUBJECT_NAME,
@@ -332,7 +418,8 @@
 	        CertFreeCertificateContext(issuerCert);
 	        return(FALSE);
         }
-	    /* todo: do we want to verify the trusted cert? */
+	    /* todo: do we want to verify the trusted cert? we must check
+		 * revocation, I think */
 	    CertFreeCertificateContext(issuerCert);
 	    return(TRUE);
     }
@@ -351,7 +438,7 @@
 	        CertFreeCertificateContext(issuerCert);
 	        return(FALSE);
         }
-    	if(!xmlSecMSCryptoX509StoreConstructCertsChain(store, issuerCert, certs, keyInfoCtx)) {
+    	if(!xmlSecMSCryptoBuildCertChainManually(cert, pfTime, store_trusted, store_untrusted, certs, store)) {
 	        xmlSecMSCryptoX509StoreCertError(store, issuerCert, flags);
 	        CertFreeCertificateContext(issuerCert);
 	        return(FALSE);
@@ -361,7 +448,7 @@
     }
 
     /* try the untrusted certs in the store */
-    issuerCert = CertFindCertificateInStore(ctx->untrusted, 
+    issuerCert = CertFindCertificateInStore(store_untrusted, 
 			    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
 			    0,
 			    CERT_FIND_SUBJECT_NAME,
@@ -374,7 +461,7 @@
 	        CertFreeCertificateContext(issuerCert);
 	        return(FALSE);
         }
-	    if(!xmlSecMSCryptoX509StoreConstructCertsChain(store, issuerCert, certs, keyInfoCtx)) {
+    	if(!xmlSecMSCryptoBuildCertChainManually(cert, pfTime, store_trusted, store_untrusted, certs, store)) {
 	        CertFreeCertificateContext(issuerCert);
 	        return(FALSE);
 	    }
@@ -385,6 +472,44 @@
     return(FALSE);
 }
 
+static BOOL
+xmlSecMSCryptoX509StoreConstructCertsChain(xmlSecKeyDataStorePtr store, PCCERT_CONTEXT cert, HCERTSTORE certs, 
+			      xmlSecKeyInfoCtx* keyInfoCtx) {
+    xmlSecMSCryptoX509StoreCtxPtr ctx;
+    PCCERT_CONTEXT tempCert = NULL;
+    FILETIME fTime;
+    
+    xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecMSCryptoX509StoreId), FALSE);
+    xmlSecAssert2(cert != NULL, FALSE);
+    xmlSecAssert2(cert->pCertInfo != NULL, FALSE);
+    xmlSecAssert2(certs != NULL, FALSE);
+    xmlSecAssert2(keyInfoCtx != NULL, FALSE);
+
+    ctx = xmlSecMSCryptoX509StoreGetCtx(store);
+    xmlSecAssert2(ctx != NULL, FALSE);
+    xmlSecAssert2(ctx->trusted != NULL, FALSE);
+    xmlSecAssert2(ctx->untrusted != NULL, FALSE);
+
+    if(keyInfoCtx->certsVerificationTime > 0) {
+	    /* convert the time to FILETIME */
+    	xmlSecMSCryptoUnixTimeToFileTime(keyInfoCtx->certsVerificationTime, &fTime);
+    } else {
+	    /* Defaults to current time */
+	    GetSystemTimeAsFileTime(&fTime);
+    }
+
+	tempCert = CertEnumCertificatesInStore(ctx->trusted, NULL);
+	if (tempCert) {
+		/* If ctx->trusted has any certificated, we trust the user for
+		 * all the information about certificates... */
+		CertFreeCertificateContext(tempCert);
+		return xmlSecMSCryptoBuildCertChainManually(cert, &fTime, ctx->trusted, ctx->untrusted, certs, store);
+	} else {
+		/* ... otherwise we trust the system for trusted root certificates. */
+		return xmlSecBuildChainUsingWinapi(cert, &fTime, ctx->untrusted, certs);
+	}
+}
+
 /**
  * xmlSecMSCryptoX509StoreVerify:
  * @store:		the pointer to X509 certificate context store klass.
Index: src/skeleton/crypto.c
===================================================================
RCS file: /cvs/xmlsec/src/skeleton/crypto.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -w -r1.1.1.1 -r1.2
--- src/skeleton/crypto.c	6 Dec 2005 09:29:17 -0000	1.1.1.1
+++ src/skeleton/crypto.c	11 Jan 2006 13:30:24 -0000	1.2
@@ -64,6 +64,10 @@
     gXmlSecSkeletonFunctions->keyDataDsaGetKlass 	= xmlSecSkeletonKeyDataDsaGetKlass;
 #endif /* XMLSEC_NO_DSA */    
 
+#ifndef XMLSEC_NO_GOST
+    gXmlSecSkeletonFunctions->keyDataGost2001GetKlass 	= xmlSecSkeletonKeyDataGost2001GetKlass;
+#endif /* XMLSEC_NO_GOST */    
+
 #ifndef XMLSEC_NO_HMAC  
     gXmlSecSkeletonFunctions->keyDataHmacGetKlass 	= xmlSecSkeletonKeyDataHmacGetKlass;
 #endif /* XMLSEC_NO_HMAC */    
@@ -105,6 +109,10 @@
     gXmlSecSkeletonFunctions->transformDsaSha1GetKlass 		= xmlSecSkeletonTransformDsaSha1GetKlass;
 #endif /* XMLSEC_NO_DSA */
 
+#ifndef XMLSEC_NO_GOST
+    gXmlSecSkeletonFunctions->transformGost2001GostR3411_94GetKlass 		= xmlSecSkeletonTransformGost2001GostR3411_94GetKlass;
+#endif /* XMLSEC_GOST */
+
 #ifndef XMLSEC_NO_HMAC
     gXmlSecSkeletonFunctions->transformHmacSha1GetKlass 	= xmlSecSkeletonTransformHmacSha1GetKlass;
     gXmlSecSkeletonFunctions->transformHmacRipemd160GetKlass 	= xmlSecSkeletonTransformHmacRipemd160GetKlass;
@@ -124,6 +132,10 @@
 #ifndef XMLSEC_NO_SHA1    
     gXmlSecSkeletonFunctions->transformSha1GetKlass 		= xmlSecSkeletonTransformSha1GetKlass;
 #endif /* XMLSEC_NO_SHA1 */
+
+#ifndef XMLSEC_NO_GOST    
+    gXmlSecSkeletonFunctions->transformGostR3411_94GetKlass 		= xmlSecSkeletonTransformGostR3411_94GetKlass;
+#endif /* XMLSEC_NO_GOST */
 
     /**
      * High level routines form xmlsec command line utility


More information about the xmlsec mailing list