[SCM] Debian packaging for XML-Security-C branch, squeeze, updated. debian/1.5.1-3+squeeze1-2-g570de2f

Russ Allbery rra at debian.org
Tue Jun 18 05:44:38 UTC 2013


The following commit has been merged in the squeeze branch:
commit 97670d82b1d2dc285f9c930b445b7bebb0788246
Author: Russ Allbery <rra at debian.org>
Date:   Sun Jun 16 21:58:48 2013 -0700

    Apply upstream security patches
    
    * Apply upstream patch to fix a spoofing vulnerability that allows an
      attacker to reuse existing signatures with arbitrary content.
      (CVE-2013-2153)
    * Apply upstream patch to fix a stack overflow in the processing of
      malformed XPointer expressions in the XML Signature Reference
      processing code.  (CVE-2013-2154)
    * Apply upstream patch to fix processing of the output length of an
      HMAC-based XML Signature that could cause a denial of service when
      processing specially chosen input.  (CVE-2013-2155)
    * Apply upstream patch to fix a heap overflow in the processing of the
      PrefixList attribute optionally used in conjunction with Exclusive
      Canonicalization, potentially allowing arbitary code execution.
      (CVE-2013-2156)

diff --git a/debian/changelog b/debian/changelog
index cd3d26a..85b0199 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,21 @@
+xml-security-c (1.5.1-3+squeeze2) oldstable-security; urgency=high
+
+  * Apply upstream patch to fix a spoofing vulnerability that allows an
+    attacker to reuse existing signatures with arbitrary content.
+    (CVE-2013-2153)
+  * Apply upstream patch to fix a stack overflow in the processing of
+    malformed XPointer expressions in the XML Signature Reference
+    processing code.  (CVE-2013-2154)
+  * Apply upstream patch to fix processing of the output length of an
+    HMAC-based XML Signature that could cause a denial of service when
+    processing specially chosen input.  (CVE-2013-2155)
+  * Apply upstream patch to fix a heap overflow in the processing of the
+    PrefixList attribute optionally used in conjunction with Exclusive
+    Canonicalization, potentially allowing arbitary code execution.
+    (CVE-2013-2156)
+
+ -- Russ Allbery <rra at debian.org>  Sun, 16 Jun 2013 22:20:05 -0700
+
 xml-security-c (1.5.1-3+squeeze1) stable-security; urgency=high
 
   * Apply upstream patch to fix buffer overflow when signing or verifying
diff --git a/include/xsec/framework/XSECDefs.hpp b/include/xsec/framework/XSECDefs.hpp
index 9b2d938..78686eb 100644
--- a/include/xsec/framework/XSECDefs.hpp
+++ b/include/xsec/framework/XSECDefs.hpp
@@ -64,6 +64,9 @@
     typedef unsigned int xsecsize_t;
 #endif
 
+// Pending API change, compile in a limit for Xerces SecurityManager entity expansion
+#define XSEC_ENTITY_EXPANSION_LIMIT 1000
+
 
 // --------------------------------------------------------------------------------
 //           Namespace Handling
diff --git a/src/canon/XSECC14n20010315.cpp b/src/canon/XSECC14n20010315.cpp
index 9447686..e1e85e1 100644
--- a/src/canon/XSECC14n20010315.cpp
+++ b/src/canon/XSECC14n20010315.cpp
@@ -236,6 +236,8 @@ void XSECC14n20010315::setExclusive(char * xmlnsList) {
 
 	}
 
+    ArrayJanitor<char> j_nsBuf(nsBuf);
+
 	int i, j;
 
 	i = 0;
@@ -243,21 +245,22 @@ void XSECC14n20010315::setExclusive(char * xmlnsList) {
 	while (xmlnsList[i] != '\0') {
 
 		while (xmlnsList[i] == ' ' ||
-			   xmlnsList[i] == '\0' ||
 			   xmlnsList[i] == '\t' ||
 			   xmlnsList[i] == '\r' ||
-			   xmlnsList[i] == '\n')
+			   xmlnsList[i] == '\n') {
 
 			   ++i;	// Skip white space
+        }
 
 		j = 0;
 		while (!(xmlnsList[i] == ' ' ||
 			   xmlnsList[i] == '\0' ||
 			   xmlnsList[i] == '\t' ||
 			   xmlnsList[i] == '\r' ||
-			   xmlnsList[i] == '\n'))
+			   xmlnsList[i] == '\n')) {
 
 			   nsBuf[j++] = xmlnsList[i++];	// Copy name
+        }
 
 		// Terminate the string
 		nsBuf[j] = '\0';
@@ -277,8 +280,6 @@ void XSECC14n20010315::setExclusive(char * xmlnsList) {
 
 	}
 
-	delete[] nsBuf;
-
 }
 
 
diff --git a/src/dsig/DSIGAlgorithmHandlerDefault.cpp b/src/dsig/DSIGAlgorithmHandlerDefault.cpp
index 7a1fde2..5a886cd 100644
--- a/src/dsig/DSIGAlgorithmHandlerDefault.cpp
+++ b/src/dsig/DSIGAlgorithmHandlerDefault.cpp
@@ -57,6 +57,15 @@ bool compareBase64StringToRaw(const char * b64Str,
 	// Compare at most maxCompare bits (if maxCompare > 0)
 	// Note - whilst the other parameters are bytes, maxCompare is bits
 
+    // The div function below takes signed int, so make sure the value
+    // is safe to cast.
+    if ((int) maxCompare < 0) {
+
+        throw XSECException(XSECException::CryptoProviderError, 
+				"Comparison length was unsafe");
+
+    }
+
 	unsigned char outputStr[MAXB64BUFSIZE];
 	unsigned int outputLen = 0;
 	
@@ -123,7 +132,7 @@ bool compareBase64StringToRaw(const char * b64Str,
 
 	char mask = 0x01;
 	if (maxCompare != 0) {
-	    for (j = 0 ; j < (unsigned int) d.rem; ++i) {
+	    for (j = 0 ; j < (unsigned int) d.rem; ++j) {
 
 		    if ((raw[i] & mask) != (outputStr[i] & mask))
 			    return false;
@@ -477,7 +486,7 @@ unsigned int DSIGAlgorithmHandlerDefault::signToSafeBuffer(
 		// Signature already created, so just translate to base 64 and enter string
 
         // FIX: CVE-2009-0217
-        if (outputLength > 0 && (outputLength < 80 || outputLength < hashLen / 2)) {
+        if (outputLength > 0 && (outputLength > hashLen || outputLength < 80 || outputLength < hashLen / 2)) {
             throw XSECException(XSECException::AlgorithmMapperError,
                 "HMACOutputLength set to unsafe value.");
         }
@@ -584,7 +593,7 @@ bool DSIGAlgorithmHandlerDefault::verifyBase64Signature(
 		// Already done - just compare calculated value with read value
 
         // FIX: CVE-2009-0217
-        if (outputLength > 0 && (outputLength < 80 || outputLength < hashLen / 2)) {
+        if (outputLength > 0 && (outputLength > hashLen || outputLength < 80 || outputLength < hashLen / 2)) {
             throw XSECException(XSECException::AlgorithmMapperError,
                 "HMACOutputLength set to unsafe value.");
         }
diff --git a/src/dsig/DSIGReference.cpp b/src/dsig/DSIGReference.cpp
index 78e43d8..a6cc179 100644
--- a/src/dsig/DSIGReference.cpp
+++ b/src/dsig/DSIGReference.cpp
@@ -488,17 +488,15 @@ TXFMBase * DSIGReference::getURIBaseTXFM(DOMDocument * doc,
 		}
 
 		else if (URI[9] == XERCES_CPP_NAMESPACE_QUALIFIER chOpenParen &&
-			     URI[10] == XERCES_CPP_NAMESPACE_QUALIFIER chLatin_i &&
-				 URI[11] == XERCES_CPP_NAMESPACE_QUALIFIER chLatin_d &&
-				 URI[12] == XERCES_CPP_NAMESPACE_QUALIFIER chOpenParen &&
-				 URI[13] == XERCES_CPP_NAMESPACE_QUALIFIER chSingleQuote) {
+                 URI[10] == XERCES_CPP_NAMESPACE_QUALIFIER chLatin_i &&
+                 URI[11] == XERCES_CPP_NAMESPACE_QUALIFIER chLatin_d &&
+                 URI[12] == XERCES_CPP_NAMESPACE_QUALIFIER chOpenParen &&
+                 URI[13] == XERCES_CPP_NAMESPACE_QUALIFIER chSingleQuote) {
 
 			xsecsize_t len = XMLString::stringLen(&URI[14]);
 
-			XMLCh tmp[512];
-
-			if (len > 511)
-				len = 511;
+			XMLCh* tmp = new XMLCh[len + 1];
+            ArrayJanitor<XMLCh> j_tmp(tmp);
 
 			xsecsize_t j = 14, i = 0;
 
@@ -602,9 +600,14 @@ void DSIGReference::load(void) {
 	// Now check for Transforms
 	tmpElt = mp_referenceNode->getFirstChild();
 
-	while (tmpElt != 0 && (tmpElt->getNodeType() != DOMNode::ELEMENT_NODE))
+	while (tmpElt != 0 && (tmpElt->getNodeType() != DOMNode::ELEMENT_NODE)) {
+        if (tmpElt->getNodeType() == DOMNode::ENTITY_REFERENCE_NODE) {
+            throw XSECException(XSECException::ExpectedDSIGChildNotFound,
+                    "EntityReference nodes in <Reference> are unsupported.");
+        }
 		// Skip text and comments
 		tmpElt = tmpElt->getNextSibling();
+    }
 
 	if (tmpElt == 0) {
 
@@ -623,13 +626,19 @@ void DSIGReference::load(void) {
 
 		// Find next node
 		tmpElt = tmpElt->getNextSibling();
-		while (tmpElt != 0 && (tmpElt->getNodeType() != DOMNode::ELEMENT_NODE))
+		while (tmpElt != 0 && (tmpElt->getNodeType() != DOMNode::ELEMENT_NODE)) {
+            if (tmpElt->getNodeType() == DOMNode::ENTITY_REFERENCE_NODE) {
+                throw XSECException(XSECException::ExpectedDSIGChildNotFound,
+                        "EntityReference nodes in <Reference> are unsupported.");
+            }
 			tmpElt = tmpElt->getNextSibling();
+        }
 
 
 	} /* if tmpElt node type = transforms */
-	else
+	else {
 		mp_transformList = NULL;
+    }
 
 
 	if (tmpElt == NULL || !strEquals(getDSIGLocalName(tmpElt), "DigestMethod")) {
@@ -664,8 +673,14 @@ void DSIGReference::load(void) {
 
 	tmpElt = tmpElt->getNextSibling();
 
-	while (tmpElt != 0 && !(strEquals(getDSIGLocalName(tmpElt), "DigestValue")))
+    while (tmpElt != 0 &&
+            (tmpElt->getNodeType() != DOMNode::ELEMENT_NODE || !strEquals(getDSIGLocalName(tmpElt), "DigestValue"))) {
+        if (tmpElt->getNodeType() == DOMNode::ENTITY_REFERENCE_NODE) {
+            throw XSECException(XSECException::ExpectedDSIGChildNotFound,
+                    "EntityReference nodes in <Reference> are unsupported.");
+        }
 		tmpElt = tmpElt->getNextSibling();
+    }
 
 	if (tmpElt == 0) {
 
@@ -703,8 +718,13 @@ void DSIGReference::load(void) {
 
 			// Find Manifest child
 			manifestNode = manifestNode->getFirstChild();
-			while (manifestNode != 0 && manifestNode->getNodeType() != DOMNode::ELEMENT_NODE)
+			while (manifestNode != 0 && manifestNode->getNodeType() != DOMNode::ELEMENT_NODE) {
+                if (manifestNode->getNodeType() == DOMNode::ENTITY_REFERENCE_NODE) {
+                    throw XSECException(XSECException::ExpectedDSIGChildNotFound,
+                            "EntityReference nodes in <Reference> are unsupported.");
+                }
 				manifestNode = manifestNode->getNextSibling();
+            }
 
 			if (manifestNode == 0 || !strEquals(getDSIGLocalName(manifestNode), "Manifest"))
 				throw XSECException(XSECException::ExpectedDSIGChildNotFound,
@@ -715,8 +735,14 @@ void DSIGReference::load(void) {
 		// Now have the manifest node, find the first reference and load!
 		referenceNode = manifestNode->getFirstChild();
 
-		while (referenceNode != 0 && !strEquals(getDSIGLocalName(referenceNode), "Reference"))
+		while (referenceNode != 0 &&
+                (referenceNode->getNodeType() != DOMNode::ELEMENT_NODE || !strEquals(getDSIGLocalName(referenceNode), "Reference"))) {
+            if (referenceNode->getNodeType() == DOMNode::ENTITY_REFERENCE_NODE) {
+                throw XSECException(XSECException::ExpectedDSIGChildNotFound,
+                        "EntityReference nodes in <Reference> are unsupported.");
+            }
 			referenceNode = referenceNode->getNextSibling();
+        }
 
 		if (referenceNode == 0)
 			throw XSECException(XSECException::ExpectedDSIGChildNotFound,
@@ -769,8 +795,13 @@ DSIGReferenceList *DSIGReference::loadReferenceListFromXML(const XSECEnv * env,
 		// Find next element Node
 		tmpRef = tmpRef->getNextSibling();
 
-		while (tmpRef != 0 && tmpRef->getNodeType() != DOMNode::ELEMENT_NODE)
+		while (tmpRef != 0 && tmpRef->getNodeType() != DOMNode::ELEMENT_NODE) {
+            if (tmpRef->getNodeType() == DOMNode::ENTITY_REFERENCE_NODE) {
+                throw XSECException(XSECException::ExpectedDSIGChildNotFound,
+                        "EntityReference nodes in <Reference> are unsupported.");
+            }
 			tmpRef = tmpRef->getNextSibling();
+        }
 
 	}
 
diff --git a/src/dsig/DSIGSignedInfo.cpp b/src/dsig/DSIGSignedInfo.cpp
index 494cfb8..3e141b3 100644
--- a/src/dsig/DSIGSignedInfo.cpp
+++ b/src/dsig/DSIGSignedInfo.cpp
@@ -284,9 +284,14 @@ void DSIGSignedInfo::load(void) {
 
 	// Check for CanonicalizationMethod
 
-	while (tmpSI != 0 && (tmpSI->getNodeType() != DOMNode::ELEMENT_NODE))
+	while (tmpSI != 0 && (tmpSI->getNodeType() != DOMNode::ELEMENT_NODE)) {
+        if (tmpSI->getNodeType() == DOMNode::ENTITY_REFERENCE_NODE) {
+            throw XSECException(XSECException::ExpectedDSIGChildNotFound,
+                    "EntityReference nodes in <SignedInfo> are unsupported.");
+        }
 		// Skip text and comments
 		tmpSI = tmpSI->getNextSibling();
+    }
 
 	if (tmpSI == 0 || !strEquals(getDSIGLocalName(tmpSI), "CanonicalizationMethod")) {
 
@@ -347,17 +352,23 @@ void DSIGSignedInfo::load(void) {
 
 	}
 
-	else
+	else {
 
 		throw XSECException(XSECException::UnknownCanonicalization);
+    }
 
 	// Now load the SignatureMethod
 
 	tmpSI = tmpSI->getNextSibling();
 
-	while (tmpSI != 0 && (tmpSI->getNodeType() != DOMNode::ELEMENT_NODE))
+	while (tmpSI != 0 && (tmpSI->getNodeType() != DOMNode::ELEMENT_NODE)) {
+        if (tmpSI->getNodeType() == DOMNode::ENTITY_REFERENCE_NODE) {
+            throw XSECException(XSECException::ExpectedDSIGChildNotFound,
+                    "EntityReference nodes in <SignedInfo> are unsupported.");
+        }
 		// Skip text and comments
 		tmpSI = tmpSI->getNextSibling();
+    }
 
 	if (tmpSI == 0 || !strEquals(getDSIGLocalName(tmpSI), "SignatureMethod")) {
 
@@ -391,10 +402,14 @@ void DSIGSignedInfo::load(void) {
 	 * longer know at this point if this is an HMAC, we need to check. */
 
 	DOMNode *tmpSOV = tmpSI->getFirstChild();
-	while (tmpSOV != NULL && 
-		tmpSOV->getNodeType() != DOMNode::ELEMENT_NODE && 
-		!strEquals(getDSIGLocalName(tmpSOV), "HMACOutputLength"))
+	while (tmpSOV != NULL &&
+            (tmpSOV->getNodeType() != DOMNode::ELEMENT_NODE || !strEquals(getDSIGLocalName(tmpSOV), "HMACOutputLength"))) {
+        if (tmpSOV->getNodeType() == DOMNode::ENTITY_REFERENCE_NODE) {
+            throw XSECException(XSECException::ExpectedDSIGChildNotFound,
+                    "EntityReference nodes in <SignedInfo> are unsupported.");
+        }
 		tmpSOV = tmpSOV->getNextSibling();
+    }
 
 	if (tmpSOV != NULL) {
 
@@ -418,9 +433,14 @@ void DSIGSignedInfo::load(void) {
 
 	// Run through the rest of the elements until done
 
-	while (tmpSI != 0 && (tmpSI->getNodeType() != DOMNode::ELEMENT_NODE))
+	while (tmpSI != 0 && (tmpSI->getNodeType() != DOMNode::ELEMENT_NODE)) {
+        if (tmpSI->getNodeType() == DOMNode::ENTITY_REFERENCE_NODE) {
+            throw XSECException(XSECException::ExpectedDSIGChildNotFound,
+                    "EntityReference nodes in <SignedInfo> are unsupported.");
+        }
 		// Skip text and comments
 		tmpSI = tmpSI->getNextSibling();
+    }
 
 	if (tmpSI != NULL) {
 
diff --git a/src/transformers/TXFMParser.cpp b/src/transformers/TXFMParser.cpp
index 3a7ef32..c3cb842 100644
--- a/src/transformers/TXFMParser.cpp
+++ b/src/transformers/TXFMParser.cpp
@@ -111,8 +111,11 @@ void TXFMParser::setInput(TXFMBase *newInput) {
 	XercesDOMParser parser;
 
 	parser.setDoNamespaces(true);
-	parser.setCreateEntityReferenceNodes(true);
-	parser.setDoSchema(true);
+    parser.setLoadExternalDTD(false);
+
+    SecurityManager securityManager;
+    securityManager.setEntityExpansionLimit(XSEC_ENTITY_EXPANSION_LIMIT);
+    parser.setSecurityManager(&securityManager);
 
 	parser.parse(is);
     xsecsize_t errorCount = parser.getErrorCount();
diff --git a/src/transformers/TXFMXSL.cpp b/src/transformers/TXFMXSL.cpp
index 63e8206..89cb45e 100644
--- a/src/transformers/TXFMXSL.cpp
+++ b/src/transformers/TXFMXSL.cpp
@@ -180,8 +180,12 @@ void TXFMXSL::evaluateStyleSheet(const safeBuffer &sbStyleSheet) {
 
 	parser->setDoNamespaces(true);
 	parser->setCreateEntityReferenceNodes(true);
+    parser->setLoadExternalDTD(false);
 	parser->setDoSchema(true);
 
+    SecurityManager securityManager;
+    parser->setSecurityManager(&securityManager);
+
 	// Create an input source
 
 	MemBufInputSource* memIS = new MemBufInputSource ((const XMLByte*) txoh.buffer.rawBuffer(), txoh.offset, "XSECMem");
diff --git a/src/utils/XSECSOAPRequestorSimple.cpp b/src/utils/XSECSOAPRequestorSimple.cpp
index cae2ae6..405a00d 100644
--- a/src/utils/XSECSOAPRequestorSimple.cpp
+++ b/src/utils/XSECSOAPRequestorSimple.cpp
@@ -213,31 +213,31 @@ char * XSECSOAPRequestorSimple::wrapAndSerialise(DOMDocument * request) {
 
 DOMDocument * XSECSOAPRequestorSimple::parseAndUnwrap(const char * buf, unsigned int len) {
 
-	XercesDOMParser * parser = new XercesDOMParser;
-	Janitor<XercesDOMParser> j_parser(parser);
+	XercesDOMParser parser;
+	parser.setDoNamespaces(true);
+    parser.setLoadExternalDTD(false);
 
-	parser->setDoNamespaces(true);
-	parser->setCreateEntityReferenceNodes(true);
-	parser->setDoSchema(true);
+    SecurityManager securityManager;
+    securityManager.setEntityExpansionLimit(XSEC_ENTITY_EXPANSION_LIMIT);
+    parser.setSecurityManager(&securityManager);
 
 	// Create an input source
 
-	MemBufInputSource* memIS = new MemBufInputSource ((const XMLByte*) buf, len, "XSECMem");
-	Janitor<MemBufInputSource> j_memIS(memIS);
+	MemBufInputSource memIS((const XMLByte*) buf, len, "XSECMem");
 
-	parser->parse(*memIS);
-    xsecsize_t errorCount = parser->getErrorCount();
+	parser.parse(memIS);
+    xsecsize_t errorCount = parser.getErrorCount();
     if (errorCount > 0)
 		throw XSECException(XSECException::HTTPURIInputStreamError,
 							"Error parsing response message");
 
 	if (m_envelopeType == ENVELOPE_NONE) {
 
-		return parser->adoptDocument();
+		return parser.adoptDocument();
 
 	}
 
-    DOMDocument * responseDoc = parser->getDocument();
+    DOMDocument * responseDoc = parser.getDocument();
 
 	// Must be a SOAP message of some kind - so lets remove the wrapper.
 	// First create a new document for the Response message
diff --git a/src/xenc/impl/XENCCipherImpl.cpp b/src/xenc/impl/XENCCipherImpl.cpp
index 5db1d63..f1a0e2a 100644
--- a/src/xenc/impl/XENCCipherImpl.cpp
+++ b/src/xenc/impl/XENCCipherImpl.cpp
@@ -303,9 +303,6 @@ DOMDocumentFragment * XENCCipherImpl::deSerialise(safeBuffer &content, DOMNode *
 
 	sbt.sbStrcatIn(&crcb[offset]);
 
-	// Now transform the content to UTF-8
-	//sb.sbXMLChCat8(content.rawCharBuffer());
-
 	// Terminate the string
 
 	sb.sbXMLChIn(DSIGConstants::s_unicodeStrEmpty);
@@ -318,27 +315,26 @@ DOMDocumentFragment * XENCCipherImpl::deSerialise(safeBuffer &content, DOMNode *
 	ArrayJanitor<char> j_trailer(trailer);
 	sbt.sbStrcatIn(trailer);
 
-	// Now we need to parse the document
-
-	XercesDOMParser * parser = new XercesDOMParser;
-	Janitor<XercesDOMParser> j_parser(parser);
-
-	parser->setDoNamespaces(true);
-	parser->setCreateEntityReferenceNodes(true);
-	parser->setDoSchema(false);
-
 	// Create an input source
 
 	xsecsize_t bytes = XMLString::stringLen(sbt.rawCharBuffer());
 	MemBufInputSource* memIS = new MemBufInputSource ((const XMLByte*) sbt.rawBuffer(), bytes, "XSECMem");
 	Janitor<MemBufInputSource> j_memIS(memIS);
 
-	parser->parse(*memIS);
-    xsecsize_t errorCount = parser->getErrorCount();
+	XercesDOMParser parser;
+	parser.setDoNamespaces(true);
+	parser.setLoadExternalDTD(false);
+
+	SecurityManager securityManager;
+	securityManager.setEntityExpansionLimit(XSEC_ENTITY_EXPANSION_LIMIT);
+	parser.setSecurityManager(&securityManager);
+
+	parser.parse(*memIS);
+    xsecsize_t errorCount = parser.getErrorCount();
     if (errorCount > 0)
         throw XSECException(XSECException::CipherError, "Errors occured during de-serialisation of decrypted element content");
 
-    DOMDocument * doc = parser->getDocument();
+    DOMDocument * doc = parser.getDocument();
 
 	// Create a DocumentFragment to hold the children of the parsed doc element
 	DOMDocument *ctxDocument = ctx->getOwnerDocument();

-- 
Debian packaging for XML-Security-C



More information about the Pkg-shibboleth-devel mailing list