diff options
author | Sebastien Pouliot <sebastien@ximian.com> | 2009-07-14 22:45:19 +0400 |
---|---|---|
committer | Sebastien Pouliot <sebastien@ximian.com> | 2009-07-14 22:45:19 +0400 |
commit | 14846e6f2f0c8e95b3eec525ee9367bcd02fcbd3 (patch) | |
tree | 1515d3be4c0aa7dcda6f644bbe473b9bb8e2da50 /mcs/class/System.Security/System.Security.Cryptography.Xml | |
parent | bbccb6b5ad2d35dc42dcb61e563ec8cf14b5b3dc (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/ChangeLog | 5 | ||||
-rw-r--r-- | mcs/class/System.Security/System.Security.Cryptography.Xml/SignedXml.cs | 31 |
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; |