Sophie

Sophie

distrib > Mandriva > 2009.0 > i586 > by-pkgid > 28c6460f21b27bdcf36b05c7f019a758 > files > 2

xmlsec1-1.2.10-7.2mdv2009.0.src.rpm

From 34b349675af9f72eb822837a8772cc1ead7115c7 Mon Sep 17 00:00:00 2001
From: Aleksey Sanin <aleksey@aleksey.com>
Date: Mon, 15 Jun 2009 17:45:36 +0000
Subject: Fixed HMAC vuln with small values of HMAC length

---
diff --git a/include/xmlsec/gnutls/crypto.h b/include/xmlsec/gnutls/crypto.h
index dd80436..f7fbbad 100644
--- a/include/xmlsec/gnutls/crypto.h
+++ b/include/xmlsec/gnutls/crypto.h
@@ -113,6 +113,10 @@ XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecGnuTLSTransformDes3CbcGetKlass(void
  *
  *******************************************************************/
 #ifndef XMLSEC_NO_HMAC
+
+XMLSEC_CRYPTO_EXPORT int               xmlSecGnuTLSHmacGetMinOutputLength();
+XMLSEC_CRYPTO_EXPORT void              xmlSecGnuTLSHmacSetMinOutputLength(int min_length);
+
 /** 
  * xmlSecGnuTLSKeyDataHmacId:
  * 
diff --git a/include/xmlsec/nss/crypto.h b/include/xmlsec/nss/crypto.h
index f1cd44e..381ee1f 100644
--- a/include/xmlsec/nss/crypto.h
+++ b/include/xmlsec/nss/crypto.h
@@ -191,6 +191,10 @@ XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecNssTransformDsaSha1GetKlass(void);
  *
  *******************************************************************/
 #ifndef XMLSEC_NO_HMAC
+
+XMLSEC_CRYPTO_EXPORT int               xmlSecNssHmacGetMinOutputLength();
+XMLSEC_CRYPTO_EXPORT void              xmlSecNssHmacSetMinOutputLength(int min_length);
+
 /** 
  * xmlSecNssKeyDataHmacId:
  * 
diff --git a/include/xmlsec/openssl/crypto.h b/include/xmlsec/openssl/crypto.h
index 2274e35..3b50b40 100644
--- a/include/xmlsec/openssl/crypto.h
+++ b/include/xmlsec/openssl/crypto.h
@@ -200,6 +200,10 @@ XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecOpenSSLTransformDsaSha1GetKlass(voi
  *
  *******************************************************************/
 #ifndef XMLSEC_NO_HMAC
+
+XMLSEC_CRYPTO_EXPORT int               xmlSecOpenSSLHmacGetMinOutputLength();
+XMLSEC_CRYPTO_EXPORT void              xmlSecOpenSSLHmacSetMinOutputLength(int min_length);
+
 /** 
  * xmlSecOpenSSLKeyDataHmacId:
  * 
diff --git a/src/gnutls/hmac.c b/src/gnutls/hmac.c
index 1119110..5a0940c 100644
--- a/src/gnutls/hmac.c
+++ b/src/gnutls/hmac.c
@@ -23,10 +23,40 @@
 #include <xmlsec/gnutls/app.h>
 #include <xmlsec/gnutls/crypto.h>
 
+#define XMLSEC_GNUTLS_MIN_HMAC_SIZE		64
 #define XMLSEC_GNUTLS_MAX_HMAC_SIZE		128
 
 /**************************************************************************
  *
+ * Configuration
+ *
+ *****************************************************************************/
+static int g_xmlsec_gnutls_hmac_min_length = XMLSEC_GNUTLS_MIN_HMAC_SIZE;
+
+/**
+ * xmlSecGnuTLSHmacGetMinOutputLength: 
+ * 
+ * Returns the min HMAC output length
+ */
+int xmlSecGnuTLSHmacGetMinOutputLength()
+{
+    return g_xmlsec_gnutls_hmac_min_length;
+}
+
+/**
+ * xmlSecGnuTLSHmacSetMinOutputLength: 
+ *
+ * @min_length: the new min length 
+ * 
+ * Sets the min HMAC output length
+ */
+void xmlSecGnuTLSHmacSetMinOutputLength(int min_length)
+{
+    g_xmlsec_gnutls_hmac_min_length = min_length;
+}
+
+/**************************************************************************
+ *
  * Internal GNUTLS HMAC CTX
  *
  *****************************************************************************/
@@ -178,7 +208,20 @@ xmlSecGnuTLSHmacNodeRead(xmlSecTransformPtr transform, xmlNodePtr node, xmlSecTr
 	    ctx->dgstSize = atoi((char*)content);	    
 	    xmlFree(content);
 	}
-	/* todo: error if dgstSize == 0 ?*/
+	
+	/* Ensure that HMAC length is greater than min specified.
+	   Otherwise, an attacker can set this lenght to 0 or very 
+	   small value
+	*/
+	if(ctx->dgstSize < xmlSecGnuTLSHmacGetMinOutputLength()) {
+ 	   xmlSecError(XMLSEC_ERRORS_HERE,
+		    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+		    xmlSecNodeHMACOutputLength,
+		    XMLSEC_ERRORS_R_INVALID_NODE_ATTRIBUTE,
+		    "HMAC output length is too small");
+	   return(-1);
+	}
+
 	cur = xmlSecGetNextElementNode(cur->next);
     }
     
diff --git a/src/nss/hmac.c b/src/nss/hmac.c
index f67ec9d..a7c2018 100644
--- a/src/nss/hmac.c
+++ b/src/nss/hmac.c
@@ -26,10 +26,40 @@
 #include <xmlsec/nss/app.h>
 #include <xmlsec/nss/crypto.h>
 
+#define XMLSEC_NSS_MIN_HMAC_SIZE		64
 #define XMLSEC_NSS_MAX_HMAC_SIZE		128
 
 /**************************************************************************
  *
+ * Configuration
+ *
+ *****************************************************************************/
+static int g_xmlsec_nss_hmac_min_length = XMLSEC_NSS_MIN_HMAC_SIZE;
+
+/**
+ * xmlSecNssHmacGetMinOutputLength: 
+ * 
+ * Returns the min HMAC output length
+ */
+int xmlSecNssHmacGetMinOutputLength()
+{
+    return g_xmlsec_nss_hmac_min_length;
+}
+
+/**
+ * xmlSecNssHmacSetMinOutputLength: 
+ *
+ * @min_length: the new min length 
+ * 
+ * Sets the min HMAC output length
+ */
+void xmlSecNssHmacSetMinOutputLength(int min_length)
+{
+    g_xmlsec_nss_hmac_min_length = min_length;
+}
+
+/**************************************************************************
+ *
  * Internal NSS HMAC CTX
  *
  *****************************************************************************/
@@ -162,7 +192,20 @@ xmlSecNssHmacNodeRead(xmlSecTransformPtr transform, xmlNodePtr node, xmlSecTrans
 	    ctx->dgstSize = atoi((char*)content);	    
 	    xmlFree(content);
 	}
-	/* todo: error if dgstSize == 0 ?*/
+
+	/* Ensure that HMAC length is greater than min specified.
+	   Otherwise, an attacker can set this lenght to 0 or very 
+	   small value
+	*/
+	if(ctx->dgstSize < xmlSecNssHmacGetMinOutputLength()) {
+ 	   xmlSecError(XMLSEC_ERRORS_HERE,
+		    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+		    xmlSecNodeHMACOutputLength,
+		    XMLSEC_ERRORS_R_INVALID_NODE_ATTRIBUTE,
+		    "HMAC output length is too small");
+	   return(-1);
+	}
+
 	cur = xmlSecGetNextElementNode(cur->next);
     }
     
diff --git a/src/openssl/hmac.c b/src/openssl/hmac.c
index 492663b..76fca0e 100644
--- a/src/openssl/hmac.c
+++ b/src/openssl/hmac.c
@@ -32,6 +32,36 @@
 
 #include <xmlsec/openssl/crypto.h>
 
+#define XMLSEC_OPENSSL_MIN_HMAC_SIZE		64
+
+/**************************************************************************
+ *
+ * Configuration
+ *
+ *****************************************************************************/
+static int g_xmlsec_openssl_hmac_min_length = XMLSEC_OPENSSL_MIN_HMAC_SIZE;
+
+/**
+ * xmlSecOpenSSLHmacGetMinOutputLength: 
+ * 
+ * Returns the min HMAC output length
+ */
+int xmlSecOpenSSLHmacGetMinOutputLength()
+{
+    return g_xmlsec_openssl_hmac_min_length;
+}
+
+/**
+ * xmlSecOpenSSLHmacSetMinOutputLength: 
+ *
+ * @min_length: the new min length 
+ * 
+ * Sets the min HMAC output length
+ */
+void xmlSecOpenSSLHmacSetMinOutputLength(int min_length)
+{
+    g_xmlsec_openssl_hmac_min_length = min_length;
+}
 
 /**************************************************************************
  *
@@ -240,7 +270,20 @@ xmlSecOpenSSLHmacNodeRead(xmlSecTransformPtr transform, xmlNodePtr node, xmlSecT
 	    ctx->dgstSize = atoi((char*)content);	    
 	    xmlFree(content);
 	}
-	/* todo: error if dgstSize == 0 ?*/
+
+	/* Ensure that HMAC length is greater than min specified.
+	   Otherwise, an attacker can set this lenght to 0 or very 
+	   small value
+	*/
+	if(ctx->dgstSize < xmlSecOpenSSLHmacGetMinOutputLength()) {
+ 	   xmlSecError(XMLSEC_ERRORS_HERE,
+		    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+		    xmlSecNodeHMACOutputLength,
+		    XMLSEC_ERRORS_R_INVALID_NODE_ATTRIBUTE,
+		    "HMAC output length is too small");
+	   return(-1);
+	}
+
 	cur = xmlSecGetNextElementNode(cur->next);
     }