Bug#905332: debdiff

Ferenc Wágner wferi at niif.hu
Fri Aug 3 10:59:08 BST 2018


The proposed source debdiff for stretch-security:

diff -Nru xml-security-c-1.7.3/debian/changelog xml-security-c-1.7.3/debian/changelog
--- xml-security-c-1.7.3/debian/changelog	2016-11-08 21:52:45.000000000 +0100
+++ xml-security-c-1.7.3/debian/changelog	2018-08-03 11:32:52.000000000 +0200
@@ -1,3 +1,19 @@
+xml-security-c (1.7.3-4+deb9u1) stretch-security; urgency=high
+
+  * [c16e40f] New patch: Default KeyInfo resolver doesn't check for empty
+    element content.
+    The Apache Santuario XML Security for C++ library contained a
+    number of code paths at risk of dereferencing null pointers when
+    processing various kinds of malformed KeyInfo hints typically found
+    in signed or encrypted XML. The usual effect is a crash, and in the
+    case of the Shibboleth SP software, a crash in the shibd daemon.
+    Upstream bug:
+      https://issues.apache.org/jira/projects/SANTUARIO/issues/SANTUARIO-491
+    CVE: not assigned yet
+    Thanks to Scott Cantor (Closes: #905332)
+
+ -- Ferenc Wágner <wferi at debian.org>  Fri, 03 Aug 2018 11:32:52 +0200
+
 xml-security-c (1.7.3-4) unstable; urgency=medium
 
   [ Etienne Dysli Metref ]
diff -Nru xml-security-c-1.7.3/debian/gbp.conf xml-security-c-1.7.3/debian/gbp.conf
--- xml-security-c-1.7.3/debian/gbp.conf	2016-11-08 21:30:39.000000000 +0100
+++ xml-security-c-1.7.3/debian/gbp.conf	2018-08-02 11:57:00.000000000 +0200
@@ -1,9 +1,11 @@
-[import-orig]
+[DEFAULT]
+debian-branch = stretch
 pristine-tar = True
 
 [dch]
 multimaint-merge = True
 id-length = 7
+full = True
 
 [pq]
 patch-numbers = False
diff -Nru xml-security-c-1.7.3/debian/patches/Default-KeyInfo-resolver-doesn-t-check-for-empty-element-.patch xml-security-c-1.7.3/debian/patches/Default-KeyInfo-resolver-doesn-t-check-for-empty-element-.patch
--- xml-security-c-1.7.3/debian/patches/Default-KeyInfo-resolver-doesn-t-check-for-empty-element-.patch	1970-01-01 01:00:00.000000000 +0100
+++ xml-security-c-1.7.3/debian/patches/Default-KeyInfo-resolver-doesn-t-check-for-empty-element-.patch	2018-08-03 11:25:06.000000000 +0200
@@ -0,0 +1,215 @@
+From: Scott Cantor <scantor at apache.org>
+Date: Wed, 1 Aug 2018 13:02:21 +0000
+Subject: Default KeyInfo resolver doesn't check for empty element content
+
+The Apache Santuario XML Security for C++ library contained a
+number of code paths at risk of dereferencing null pointers when
+processing various kinds of malformed KeyInfo hints typically found
+in signed or encrypted XML. The usual effect is a crash, and in the
+case of the Shibboleth SP software, a crash in the shibd daemon.
+
+This is a combination of two upstream commits with some unrelated
+whitespace changes removed.  Quite much of it is still indentation
+change because of the added conditionals.  Best viewed with tabstop=4,
+for example with 'LESS=Rx4 git show --ignore-space-changes'.
+
+Thanks: Scott Cantor
+Upstream bug:
+  https://issues.apache.org/jira/projects/SANTUARIO/issues/SANTUARIO-491
+CVE: not assigned yet
+Closes: #905332
+---
+ xsec/dsig/DSIGKeyInfoValue.hpp          |   8 +--
+ xsec/enc/XSECKeyInfoResolverDefault.cpp | 108 +++++++++++++++++++-------------
+ 2 files changed, 69 insertions(+), 47 deletions(-)
+
+diff --git a/xsec/dsig/DSIGKeyInfoValue.hpp b/xsec/dsig/DSIGKeyInfoValue.hpp
+index f652679..d6da5d5 100644
+--- a/xsec/dsig/DSIGKeyInfoValue.hpp
++++ b/xsec/dsig/DSIGKeyInfoValue.hpp
+@@ -117,7 +117,7 @@ public:
+ 	 * @returns a pointer to the DSA P string value.
+ 	 */
+ 
+-	const XMLCh * getDSAP(void) const {return mp_PTextNode->getNodeValue();}
++	const XMLCh * getDSAP() const {return mp_PTextNode ? mp_PTextNode->getNodeValue() : NULL;}
+ 
+ 	/**
+ 	 * \brief Get Q value
+@@ -125,7 +125,7 @@ public:
+ 	 * @returns a pointer to the DSA Q string value.
+ 	 */
+ 
+-	const XMLCh * getDSAQ(void) const {return mp_QTextNode->getNodeValue();}
++	const XMLCh * getDSAQ() const {return mp_QTextNode ? mp_QTextNode->getNodeValue() : NULL;}
+ 
+ 	/**
+ 	 * \brief Get G value
+@@ -133,7 +133,7 @@ public:
+ 	 * @returns a pointer to the DSA G string value.
+ 	 */
+ 
+-	const XMLCh * getDSAG(void) const {return mp_GTextNode->getNodeValue();}
++	const XMLCh * getDSAG() const {return mp_GTextNode ? mp_GTextNode->getNodeValue() : NULL;}
+ 
+ 	/**
+ 	 * \brief Get Y value
+@@ -141,7 +141,7 @@ public:
+ 	 * @returns a pointer to the DSA Y string value.
+ 	 */
+ 
+-	const XMLCh * getDSAY(void) const {return mp_YTextNode->getNodeValue();}
++	const XMLCh * getDSAY() const {return mp_YTextNode ? mp_YTextNode->getNodeValue() : NULL;}
+ 
+ 	/**
+ 	 * \brief Get Modulus
+diff --git a/xsec/enc/XSECKeyInfoResolverDefault.cpp b/xsec/enc/XSECKeyInfoResolverDefault.cpp
+index 52cdfe3..c4c81cb 100644
+--- a/xsec/enc/XSECKeyInfoResolverDefault.cpp
++++ b/xsec/enc/XSECKeyInfoResolverDefault.cpp
+@@ -79,13 +79,11 @@ XSECCryptoKey * XSECKeyInfoResolverDefault::resolveKey(DSIGKeyInfoList * lst) {
+ 		case (DSIGKeyInfo::KEYINFO_X509) :
+ 		{
+ 			ret = NULL;
+-			const XMLCh * x509Str;
+-			XSECCryptoX509 * x509 = XSECPlatformUtils::g_cryptoProvider->X509();
+-			Janitor<XSECCryptoX509> j_x509(x509);
+-
+-			x509Str = ((DSIGKeyInfoX509 *) lst->item(i))->getCertificateItem(0);
++			const XMLCh* x509Str = ((const DSIGKeyInfoX509 *) lst->item(i))->getCertificateItem(0);
+ 			
+-			if (x509Str != 0) {
++			if (x509Str) {
++	            XSECCryptoX509 * x509 = XSECPlatformUtils::g_cryptoProvider->X509();
++	            Janitor<XSECCryptoX509> j_x509(x509);
+ 
+ 				// The crypto interface classes work UTF-8
+ 				safeBuffer transX509;
+@@ -104,66 +102,90 @@ XSECCryptoKey * XSECKeyInfoResolverDefault::resolveKey(DSIGKeyInfoList * lst) {
+ 		case (DSIGKeyInfo::KEYINFO_VALUE_DSA) :
+ 		{
+ 
+-			XSECCryptoKeyDSA * dsa = XSECPlatformUtils::g_cryptoProvider->keyDSA();
+-			Janitor<XSECCryptoKeyDSA> j_dsa(dsa);
+-
+-			safeBuffer value;
+-
+-			value << (*mp_formatter << ((DSIGKeyInfoValue *) lst->item(i))->getDSAP());
+-			dsa->loadPBase64BigNums(value.rawCharBuffer(), (unsigned int) strlen(value.rawCharBuffer()));
+-			value << (*mp_formatter << ((DSIGKeyInfoValue *) lst->item(i))->getDSAQ());
+-			dsa->loadQBase64BigNums(value.rawCharBuffer(), (unsigned int) strlen(value.rawCharBuffer()));
+-			value << (*mp_formatter << ((DSIGKeyInfoValue *) lst->item(i))->getDSAG());
+-			dsa->loadGBase64BigNums(value.rawCharBuffer(), (unsigned int) strlen(value.rawCharBuffer()));
+-			value << (*mp_formatter << ((DSIGKeyInfoValue *) lst->item(i))->getDSAY());
+-			dsa->loadYBase64BigNums(value.rawCharBuffer(), (unsigned int) strlen(value.rawCharBuffer()));
+-
+-			j_dsa.release();
+-			return dsa;
++			const DSIGKeyInfoValue* dsaval = (const DSIGKeyInfoValue *) lst->item(i);
++			if (dsaval->getDSAP() || dsaval->getDSAQ() || dsaval->getDSAG() || dsaval->getDSAY()) {
++
++	            XSECCryptoKeyDSA * dsa = XSECPlatformUtils::g_cryptoProvider->keyDSA();
++	            Janitor<XSECCryptoKeyDSA> j_dsa(dsa);
++
++                safeBuffer value;
++
++                if (dsaval->getDSAP()) {
++                    value << (*mp_formatter << dsaval->getDSAP());
++                    dsa->loadPBase64BigNums(value.rawCharBuffer(), (unsigned int) strlen(value.rawCharBuffer()));
++                }
++                if (dsaval->getDSAQ()) {
++                    value << (*mp_formatter << dsaval->getDSAQ());
++                    dsa->loadQBase64BigNums(value.rawCharBuffer(), (unsigned int) strlen(value.rawCharBuffer()));
++                }
++                if (dsaval->getDSAG()) {
++                    value << (*mp_formatter << dsaval->getDSAG());
++                    dsa->loadGBase64BigNums(value.rawCharBuffer(), (unsigned int) strlen(value.rawCharBuffer()));
++                }
++                if (dsaval->getDSAY()) {
++                    value << (*mp_formatter << dsaval->getDSAY());
++                    dsa->loadYBase64BigNums(value.rawCharBuffer(), (unsigned int) strlen(value.rawCharBuffer()));
++                }
++
++                j_dsa.release();
++                return dsa;
++			}
+ 		}
+ 			break;
+ 
+ 		case (DSIGKeyInfo::KEYINFO_VALUE_RSA) :
+ 		{
++		    const DSIGKeyInfoValue* rsaval = (const DSIGKeyInfoValue *) lst->item(i);
++		    if (rsaval->getRSAModulus() && rsaval->getRSAExponent()) {
+ 
+-			XSECCryptoKeyRSA * rsa = XSECPlatformUtils::g_cryptoProvider->keyRSA();
+-			Janitor<XSECCryptoKeyRSA> j_rsa(rsa);
++                XSECCryptoKeyRSA* rsa = XSECPlatformUtils::g_cryptoProvider->keyRSA();
++                Janitor<XSECCryptoKeyRSA> j_rsa(rsa);
+ 
+-			safeBuffer value;
++                safeBuffer value;
+ 
+-			value << (*mp_formatter << ((DSIGKeyInfoValue *) lst->item(i))->getRSAModulus());
+-			rsa->loadPublicModulusBase64BigNums(value.rawCharBuffer(), (unsigned int) strlen(value.rawCharBuffer()));
+-			value << (*mp_formatter << ((DSIGKeyInfoValue *) lst->item(i))->getRSAExponent());
+-			rsa->loadPublicExponentBase64BigNums(value.rawCharBuffer(), (unsigned int) strlen(value.rawCharBuffer()));
++                value << (*mp_formatter << rsaval->getRSAModulus());
++                rsa->loadPublicModulusBase64BigNums(value.rawCharBuffer(), (unsigned int) strlen(value.rawCharBuffer()));
++                value << (*mp_formatter << rsaval->getRSAExponent());
++                rsa->loadPublicExponentBase64BigNums(value.rawCharBuffer(), (unsigned int) strlen(value.rawCharBuffer()));
+ 
+-			j_rsa.release();
+-			return rsa;
++                j_rsa.release();
++                return rsa;
++		    }
+ 
+ 		}
+             break;
+ 
+         case (DSIGKeyInfo::KEYINFO_VALUE_EC) :
+         {
++            const DSIGKeyInfoValue* ecval = (const DSIGKeyInfoValue *) lst->item(i);
++            if (ecval->getECPublicKey() && ecval->getECNamedCurve()) {
+ 
+-            XSECCryptoKeyEC* ec = XSECPlatformUtils::g_cryptoProvider->keyEC();
+-            Janitor<XSECCryptoKeyEC> j_ec(ec);
++                XSECCryptoKeyEC* ec = XSECPlatformUtils::g_cryptoProvider->keyEC();
++                Janitor<XSECCryptoKeyEC> j_ec(ec);
+ 
+-            safeBuffer value;
+-			value << (*mp_formatter << ((DSIGKeyInfoValue *) lst->item(i))->getECPublicKey());
+-            XSECAutoPtrChar curve(((DSIGKeyInfoValue *) lst->item(i))->getECNamedCurve());
+-            if (curve.get()) {
+-                ec->loadPublicKeyBase64(curve.get(), value.rawCharBuffer(), (unsigned int) strlen(value.rawCharBuffer()));
+-                j_ec.release();
+-                return ec;
++                safeBuffer value;
++
++                value << (*mp_formatter << ecval->getECPublicKey());
++                XSECAutoPtrChar curve(ecval->getECNamedCurve());
++                if (curve.get()) {
++                    ec->loadPublicKeyBase64(curve.get(), value.rawCharBuffer(), (unsigned int) strlen(value.rawCharBuffer()));
++                    j_ec.release();
++                    return ec;
++                }
+             }
+         }
+             break;
+ 
+         case (DSIGKeyInfo::KEYINFO_DERENCODED) :
+         {
+-            safeBuffer value;
+-			value << (*mp_formatter << ((DSIGKeyInfoDEREncoded *) lst->item(i))->getData());
+-            return XSECPlatformUtils::g_cryptoProvider->keyDER(value.rawCharBuffer(), (unsigned int)strlen(value.rawCharBuffer()), true);
++            const DSIGKeyInfoDEREncoded* derval = (const DSIGKeyInfoDEREncoded *) lst->item(i);
++            if (derval->getData()) {
++
++                safeBuffer value;
++
++                value << (*mp_formatter << derval->getData());
++                return XSECPlatformUtils::g_cryptoProvider->keyDER(value.rawCharBuffer(), (unsigned int)strlen(value.rawCharBuffer()), true);
++            }
+         }
+             break;
+ 
diff -Nru xml-security-c-1.7.3/debian/patches/series xml-security-c-1.7.3/debian/patches/series
--- xml-security-c-1.7.3/debian/patches/series	2016-11-08 21:30:39.000000000 +0100
+++ xml-security-c-1.7.3/debian/patches/series	2018-08-03 11:32:47.000000000 +0200
@@ -21,3 +21,4 @@
 Use-pkg-config-for-Xerces-OpenSSL-and-NSS-and-provid.patch
 We-do-not-use-pthreads-threadtest.cpp-is-Windows-onl.patch
 Only-add-found-packages-to-the-pkg-config-dependenci.patch
+Default-KeyInfo-resolver-doesn-t-check-for-empty-element-.patch

I tested the resulting package, it fixed the bug and didn't cause any
breakage for me.

There is a header file change affecting inline function bodies, but
according to codesearch.debian.net those functions aren't used outside
of xml-security-c, so there's no need to rebuild anything in the archive
after this update.  The DSA should probably include a corresponding
warning, though.

Dear Security Team, please let me know how to proceed.  (Do you need the
Cc, or was the security tag enough to get you in the loop?)
And jessie is handled by the LTS team now, isn't it?
-- 
Regards,
Feri



More information about the Pkg-shibboleth-devel mailing list