From bd130f3a2cc2c16e45775d63a45130ef4448b3ec Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Tue, 13 Aug 2013 12:09:56 -0400 Subject: [PATCH] [mscorlib] Support OID names in RSACryptoServiceProvider.SignData() Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=13953 MSDN documents that RSACryptoServiceProvider.SignData()'s provider paramter may contain an OID name: http://msdn.microsoft.com/en-us/library/y2wf1b6k.aspx > The halg parameter can accept a String, a HashAlgorithm, or a Type. > The string value can be one of the following: > * The object identifier (OID) friendly name of the hash algorithm to use, > either a name registered in the crypto config file or one in the > Crypto API OID table. > * The OID value. The OID must be one recognized by the Crypto API. > For example, you could use SignData(new byte[5], "1.3.14.3.2.26") or > SignData(new byte[5], "sha1"), or SignData(new byte[5], "SHA1"). Add support for this OID names as the provider. --- .../RSACryptoServiceProvider.cs | 19 +++++++++++++++++- .../RSACryptoServiceProviderTest.cs | 20 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/mcs/class/corlib/System.Security.Cryptography/RSACryptoServiceProvider.cs b/mcs/class/corlib/System.Security.Cryptography/RSACryptoServiceProvider.cs index 03cbfe1a8fb..4cd3779172c 100644 --- a/mcs/class/corlib/System.Security.Cryptography/RSACryptoServiceProvider.cs +++ b/mcs/class/corlib/System.Security.Cryptography/RSACryptoServiceProvider.cs @@ -235,7 +235,7 @@ namespace System.Security.Cryptography { HashAlgorithm hash = null; if (halg is String) - hash = HashAlgorithm.Create ((String)halg); + hash = GetHashFromString ((string) halg); else if (halg is HashAlgorithm) hash = (HashAlgorithm) halg; else if (halg is Type) @@ -243,8 +243,25 @@ namespace System.Security.Cryptography { else throw new ArgumentException ("halg"); + if (hash == null) + throw new ArgumentException ( + "Could not find provider for halg='" + halg + "'.", + "halg"); + return hash; } + + private HashAlgorithm GetHashFromString (string name) + { + HashAlgorithm hash = HashAlgorithm.Create (name); + if (hash != null) + return hash; + try { + return HashAlgorithm.Create (GetHashNameFromOID (name)); + } catch (CryptographicException e) { + throw new ArgumentException (e.Message, "halg", e); + } + } // NOTE: this method can work with ANY configured (OID in machine.config) // HashAlgorithm descendant diff --git a/mcs/class/corlib/Test/System.Security.Cryptography/RSACryptoServiceProviderTest.cs b/mcs/class/corlib/Test/System.Security.Cryptography/RSACryptoServiceProviderTest.cs index 91b39eb832c..01a3f9987f3 100644 --- a/mcs/class/corlib/Test/System.Security.Cryptography/RSACryptoServiceProviderTest.cs +++ b/mcs/class/corlib/Test/System.Security.Cryptography/RSACryptoServiceProviderTest.cs @@ -262,6 +262,26 @@ public class RSACryptoServiceProviderTest { rsa.SignData (data, MD5.Create ()); } + [Test] + [ExpectedException (typeof (ArgumentException))] + public void SignDataWithInvalidOid () + { + byte[] data = new byte [5]; + rsa = new RSACryptoServiceProvider (minKeySize); + + rsa.SignData (data, "1.2.3"); + } + + [Test] + public void SignDataWithOid () + { + string oid = CryptoConfig.MapNameToOID ("SHA256"); + byte[] data = new byte [5]; + rsa = new RSACryptoServiceProvider (minKeySize); + + rsa.SignData (data, oid); + } + [Test] [ExpectedException (typeof (ArgumentNullException))] public void SignHashNullValue () -- 2.25.1