From 2efd05f7efcfe583578a923b2e55776bf9a99ca5 Mon Sep 17 00:00:00 2001 From: Antti Andreimann Date: Fri, 8 Jul 2011 11:29:51 +0300 Subject: [PATCH] Backported a patch to fix CVE-2011-2516 (#719698) --- xml-security-c-1.5.1-CVE-2011-2516.patch | 192 +++++++++++++++++++++++ xml-security-c.spec | 7 +- 2 files changed, 198 insertions(+), 1 deletion(-) create mode 100644 xml-security-c-1.5.1-CVE-2011-2516.patch diff --git a/xml-security-c-1.5.1-CVE-2011-2516.patch b/xml-security-c-1.5.1-CVE-2011-2516.patch new file mode 100644 index 0000000..7ba5d9e --- /dev/null +++ b/xml-security-c-1.5.1-CVE-2011-2516.patch @@ -0,0 +1,192 @@ +diff -up xml-security-c-1.5.1/src/dsig/DSIGAlgorithmHandlerDefault.cpp.orig xml-security-c-1.5.1/src/dsig/DSIGAlgorithmHandlerDefault.cpp +--- xml-security-c-1.5.1/src/dsig/DSIGAlgorithmHandlerDefault.cpp.orig 2009-07-21 17:48:45.000000000 +0300 ++++ xml-security-c-1.5.1/src/dsig/DSIGAlgorithmHandlerDefault.cpp 2011-07-08 10:49:00.000000000 +0300 +@@ -42,6 +42,7 @@ + + XERCES_CPP_NAMESPACE_USE + ++#define MAXB64BUFSIZE 2048 + + // -------------------------------------------------------------------------------- + // Some useful utility functions +@@ -53,10 +54,10 @@ bool compareBase64StringToRaw(const char + unsigned int rawLen, + unsigned int maxCompare = 0) { + // Decode a base64 buffer and then compare the result to a raw buffer +- // Compare at most maxCompare bits (if maxComare > 0) ++ // Compare at most maxCompare bits (if maxCompare > 0) + // Note - whilst the other parameters are bytes, maxCompare is bits + +- unsigned char outputStr[1024]; ++ unsigned char outputStr[MAXB64BUFSIZE]; + unsigned int outputLen = 0; + + XSECCryptoBase64 * b64 = XSECPlatformUtils::g_cryptoProvider->base64(); +@@ -71,8 +72,8 @@ bool compareBase64StringToRaw(const char + Janitor j_b64(b64); + + b64->decodeInit(); +- outputLen = b64->decode((unsigned char *) b64Str, (unsigned int) strlen((char *) b64Str), outputStr, 1024); +- outputLen += b64->decodeFinish(&outputStr[outputLen], 1024 - outputLen); ++ outputLen = b64->decode((unsigned char *) b64Str, (unsigned int) strlen((char *) b64Str), outputStr, MAXB64BUFSIZE); ++ outputLen += b64->decodeFinish(&outputStr[outputLen], MAXB64BUFSIZE - outputLen); + + // Compare + +@@ -144,7 +145,7 @@ void convertRawToBase64String(safeBuffer + // Translate the rawbuffer (at most maxBits or rawLen - whichever is smaller) + // to a base64 string + +- unsigned char b64Str[1024]; ++ unsigned char b64Str[MAXB64BUFSIZE]; + unsigned int outputLen = 0; + + XSECCryptoBase64 * b64 = XSECPlatformUtils::g_cryptoProvider->base64(); +@@ -175,8 +176,8 @@ void convertRawToBase64String(safeBuffer + size = rawLen; + + b64->encodeInit(); +- outputLen = b64->encode((unsigned char *) raw, rawLen, b64Str, 1024); +- outputLen += b64->encodeFinish(&b64Str[outputLen], 1024 - outputLen); ++ outputLen = b64->encode((unsigned char *) raw, rawLen, b64Str, MAXB64BUFSIZE - 1); ++ outputLen += b64->encodeFinish(&b64Str[outputLen], MAXB64BUFSIZE - outputLen - 1); + b64Str[outputLen] = '\0'; + + // Copy out +@@ -380,7 +381,10 @@ unsigned int DSIGAlgorithmHandlerDefault + + // Now check the calculated hash + +- char b64Buf[1024]; ++ // For now, use a fixed length buffer, but expand it, ++ // and detect if the signature size exceeds what we can ++ // handle. ++ char b64Buf[MAXB64BUFSIZE]; + unsigned int b64Len; + safeBuffer b64SB; + +@@ -400,7 +404,7 @@ unsigned int DSIGAlgorithmHandlerDefault + hash, + hashLen, + (char *) b64Buf, +- 1024); ++ MAXB64BUFSIZE); + + if (b64Len <= 0) { + +@@ -408,6 +412,12 @@ unsigned int DSIGAlgorithmHandlerDefault + "Unknown error occured during a DSA Signing operation"); + + } ++ else if (b64Len >= MAXB64BUFSIZE) { ++ ++ throw XSECException(XSECException::AlgorithmMapperError, ++ "DSA Signing operation exceeded size of buffer"); ++ ++ } + + if (b64Buf[b64Len-1] == '\n') + b64Buf[b64Len-1] = '\0'; +@@ -430,7 +440,7 @@ unsigned int DSIGAlgorithmHandlerDefault + hash, + hashLen, + (char *) b64Buf, +- 1024, ++ MAXB64BUFSIZE, + hm); + + if (b64Len <= 0) { +@@ -439,6 +449,12 @@ unsigned int DSIGAlgorithmHandlerDefault + "Unknown error occured during a RSA Signing operation"); + + } ++ else if (b64Len >= MAXB64BUFSIZE) { ++ ++ throw XSECException(XSECException::AlgorithmMapperError, ++ "RSA Signing operation exceeded size of buffer"); ++ ++ } + + // Clean up some "funnies" and make sure the string is NULL terminated + +@@ -471,7 +487,7 @@ unsigned int DSIGAlgorithmHandlerDefault + hashLen, + outputLength); + +- strncpy(b64Buf, (char *) b64SB.rawBuffer(), 1024); ++ strncpy(b64Buf, (char *) b64SB.rawBuffer(), MAXB64BUFSIZE); + break; + + default : +diff -up xml-security-c-1.5.1/src/enc/OpenSSL/OpenSSLCryptoKeyDSA.cpp.orig xml-security-c-1.5.1/src/enc/OpenSSL/OpenSSLCryptoKeyDSA.cpp +--- xml-security-c-1.5.1/src/enc/OpenSSL/OpenSSLCryptoKeyDSA.cpp.orig 2008-12-08 20:52:47.000000000 +0200 ++++ xml-security-c-1.5.1/src/enc/OpenSSL/OpenSSLCryptoKeyDSA.cpp 2011-07-08 11:21:12.000000000 +0300 +@@ -33,6 +33,10 @@ + #include + #include + ++#include ++ ++XSEC_USING_XERCES(ArrayJanitor); ++ + #include + + OpenSSLCryptoKeyDSA::OpenSSLCryptoKeyDSA() : mp_dsaKey(NULL) { +@@ -157,8 +161,9 @@ bool OpenSSLCryptoKeyDSA::verifyBase64Si + "OpenSSL:DSA - Attempt to validate signature with empty key"); + } + +- unsigned char sigVal[512]; + int sigValLen; ++ unsigned char* sigVal = new unsigned char[sigLen + 1]; ++ ArrayJanitor j_sigVal(sigVal); + int err; + + EVP_ENCODE_CTX m_dctx; +@@ -271,10 +276,10 @@ unsigned int OpenSSLCryptoKeyDSA::signBa + + // Now turn the signature into a base64 string + +- unsigned char rawSigBuf[256]; +- unsigned int rawLen; +- +- rawLen = BN_bn2bin(dsa_sig->r, rawSigBuf); ++ unsigned char* rawSigBuf = new unsigned char[(BN_num_bits(dsa_sig->r) + BN_num_bits(dsa_sig->s)) / 8]; ++ ArrayJanitor j_sigbuf(rawSigBuf); ++ ++ unsigned int rawLen = BN_bn2bin(dsa_sig->r, rawSigBuf); + + if (rawLen <= 0) { + +diff -up xml-security-c-1.5.1/src/enc/OpenSSL/OpenSSLCryptoKeyRSA.cpp.orig xml-security-c-1.5.1/src/enc/OpenSSL/OpenSSLCryptoKeyRSA.cpp +--- xml-security-c-1.5.1/src/enc/OpenSSL/OpenSSLCryptoKeyRSA.cpp.orig 2008-12-08 20:52:47.000000000 +0200 ++++ xml-security-c-1.5.1/src/enc/OpenSSL/OpenSSLCryptoKeyRSA.cpp 2011-07-08 10:48:58.000000000 +0300 +@@ -186,21 +186,20 @@ bool OpenSSLCryptoKeyRSA::verifySHA1PKCS + "OpenSSL:RSA - Attempt to validate signature with empty key"); + } + +- unsigned char sigVal[1024]; +- int sigValLen; +- +- EVP_ENCODE_CTX m_dctx; +- int rc; +- +- char * cleanedBase64Signature; ++ char* cleanedBase64Signature; + unsigned int cleanedBase64SignatureLen = 0; + + cleanedBase64Signature = + XSECCryptoBase64::cleanBuffer(base64Signature, sigLen, cleanedBase64SignatureLen); + ArrayJanitor j_cleanedBase64Signature(cleanedBase64Signature); + ++ int sigValLen; ++ unsigned char* sigVal = new unsigned char[sigLen + 1]; ++ ArrayJanitor j_sigVal(sigVal); ++ ++ EVP_ENCODE_CTX m_dctx; + EVP_DecodeInit(&m_dctx); +- rc = EVP_DecodeUpdate(&m_dctx, ++ int rc = EVP_DecodeUpdate(&m_dctx, + sigVal, + &sigValLen, + (unsigned char *) cleanedBase64Signature, diff --git a/xml-security-c.spec b/xml-security-c.spec index 60201bb..91ba7a0 100644 --- a/xml-security-c.spec +++ b/xml-security-c.spec @@ -1,12 +1,13 @@ Name: xml-security-c Version: 1.5.1 -Release: 4%{?dist} +Release: 5%{?dist} Summary: C++ Implementation of W3C security standards for XML Group: System Environment/Libraries License: ASL 2.0 URL: http://santuario.apache.org/c/ Source: http://santuario.apache.org/dist/c-library/%{name}-%{version}.tar.gz +Patch0: xml-security-c-1.5.1-CVE-2011-2516.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: xerces-c-devel xalan-c-devel openssl-devel @@ -36,6 +37,7 @@ XML Digital Signatures. %prep %setup -q +%patch0 -p1 # Remove bogus "-O2" from CXXFLAGS to avoid overriding RPM_OPT_FLAGS. sed -i -e 's/-O2 -DNDEBUG/-DNDEBUG/g' configure @@ -81,6 +83,9 @@ rm -rf $RPM_BUILD_ROOT # %doc CHANGELOG.txt %changelog +* Fri Jul 08 2011 Antti Andreimann - 1.5.1-5 +- Backported a patch to fix CVE-2011-2516 (#719698) + * Mon Feb 07 2011 Fedora Release Engineering - 1.5.1-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild