[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