Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastien Pouliot <sebastien@ximian.com>2009-07-14 22:45:19 +0400
committerSebastien Pouliot <sebastien@ximian.com>2009-07-14 22:45:19 +0400
commit14846e6f2f0c8e95b3eec525ee9367bcd02fcbd3 (patch)
tree1515d3be4c0aa7dcda6f644bbe473b9bb8e2da50 /mcs/class/System.Security/System.Security.Cryptography.Xml
parentbbccb6b5ad2d35dc42dcb61e563ec8cf14b5b3dc (diff)
Security fix for CVE-2009-0217
svn path=/trunk/mcs/; revision=137886
Diffstat (limited to 'mcs/class/System.Security/System.Security.Cryptography.Xml')
-rw-r--r--mcs/class/System.Security/System.Security.Cryptography.Xml/ChangeLog5
-rw-r--r--mcs/class/System.Security/System.Security.Cryptography.Xml/SignedXml.cs31
2 files changed, 26 insertions, 10 deletions
diff --git a/mcs/class/System.Security/System.Security.Cryptography.Xml/ChangeLog b/mcs/class/System.Security/System.Security.Cryptography.Xml/ChangeLog
index dc649237140..da40b59bdc0 100644
--- a/mcs/class/System.Security/System.Security.Cryptography.Xml/ChangeLog
+++ b/mcs/class/System.Security/System.Security.Cryptography.Xml/ChangeLog
@@ -1,3 +1,8 @@
+2009-07-14 Sebastien Pouliot <sebastien@ximian.com>
+
+ * SignedXml.cs: Fix HMACOutputLength to match XMLDSIG erratum (ref:
+ CVE-2009-0217) and add stricter checks.
+
2009-06-05 Marek Safar <marek.safar@gmail.com>
* *.cs: Fixed NET_2_0 conditional to actually handle Mono.Security
diff --git a/mcs/class/System.Security/System.Security.Cryptography.Xml/SignedXml.cs b/mcs/class/System.Security/System.Security.Cryptography.Xml/SignedXml.cs
index ef2532f01d8..4a3a3e0e911 100644
--- a/mcs/class/System.Security/System.Security.Cryptography.Xml/SignedXml.cs
+++ b/mcs/class/System.Security/System.Security.Cryptography.Xml/SignedXml.cs
@@ -595,17 +595,28 @@ namespace System.Security.Cryptography.Xml {
return false;
byte[] actual = macAlg.ComputeHash (s);
- // HMAC signature may be partial
+ // HMAC signature may be partial and specified by <HMACOutputLength>
if (m_signature.SignedInfo.SignatureLength != null) {
- int length = actual.Length;
- try {
- // SignatureLength is in bits
- length = (Int32.Parse (m_signature.SignedInfo.SignatureLength) >> 3);
- }
- catch {
- }
-
- if (length != actual.Length) {
+ int length = Int32.Parse (m_signature.SignedInfo.SignatureLength);
+ // we only support signatures with a multiple of 8 bits
+ // and the value must match the signature length
+ if ((length & 7) != 0)
+ throw new CryptographicException ("Signature length must be a multiple of 8 bits.");
+
+ // SignatureLength is in bits (and we works on bytes, only in multiple of 8 bits)
+ // and both values must match for a signature to be valid
+ length >>= 3;
+ if (length != m_signature.SignatureValue.Length)
+ throw new CryptographicException ("Invalid signature length.");
+
+ // is the length "big" enough to make the signature meaningful ?
+ // we use a minimum of 80 bits (10 bytes) or half the HMAC normal output length
+ // e.g. HMACMD5 output 128 bits but our minimum is 80 bits (not 64 bits)
+ int minimum = Math.Max (10, actual.Length / 2);
+ if (length < minimum)
+ throw new CryptographicException ("HMAC signature is too small");
+
+ if (length < actual.Length) {
byte[] trunked = new byte [length];
Buffer.BlockCopy (actual, 0, trunked, 0, length);
actual = trunked;