Merge pull request #409 from Alkarex/patch-1
[mono.git] / mcs / class / corlib / System.Security.Cryptography / DSACryptoServiceProvider.cs
index 36be2dc0e0a83463de423dda675a1bb8ff6ef852..6c4f84ea3b795ec521ae5decd8106005f137ba53 100644 (file)
@@ -9,23 +9,41 @@
 // (C) 2002
 // Portions (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
 // Portions (C) 2003 Ben Maurer
-// (C) 2004 Novell (http://www.novell.com)
+// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
 //
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if !MOONLIGHT
 
-using System;
 using System.IO;
 using System.Globalization;
+using System.Runtime.InteropServices;
 
 using Mono.Security.Cryptography;
 
 namespace System.Security.Cryptography {
 
-#if NET_1_0
-       public class DSACryptoServiceProvider : DSA {
-#else
-       public sealed class DSACryptoServiceProvider : DSA {
-#endif
-               private const int PROV_DSS = 3;         // from WinCrypt.h
+       [ComVisible (true)]
+       public sealed class DSACryptoServiceProvider : DSA, ICspAsymmetricAlgorithm {
+               private const int PROV_DSS_DH = 13;             // from WinCrypt.h
 
                private KeyPairPersistence store;
                private bool persistKey;
@@ -46,11 +64,20 @@ namespace System.Security.Cryptography {
                // used (or exported). This should save us a lot of time (at
                // least in the unit tests).
 
-               public DSACryptoServiceProvider () : this (1024, null) {}
+               public DSACryptoServiceProvider ()
+                       : this (1024, null)
+               {
+               }
 
-               public DSACryptoServiceProvider (CspParameters parameters) : this (1024, parameters) {}
+               public DSACryptoServiceProvider (CspParameters parameters)
+                       : this (1024, parameters)
+               {
+               }
 
-               public DSACryptoServiceProvider (int dwKeySize) : this (dwKeySize, null) {}
+               public DSACryptoServiceProvider (int dwKeySize)
+                       : this (dwKeySize, null)
+               {
+               }
 
                public DSACryptoServiceProvider (int dwKeySize, CspParameters parameters)
                {
@@ -64,11 +91,9 @@ namespace System.Security.Cryptography {
 
                        persistKey = (parameters != null);
                        if (parameters == null) {
-                               parameters = new CspParameters (PROV_DSS);
-#if ! NET_1_0
+                               parameters = new CspParameters (PROV_DSS_DH);
                                if (useMachineKeyStore)
                                        parameters.Flags |= CspProviderFlags.UseMachineKeyStore;
-#endif
                                store = new KeyPairPersistence (parameters);
                                // no need to load - it cannot exists
                        }
@@ -96,25 +121,13 @@ namespace System.Security.Cryptography {
                        get { return dsa.KeySize; }
                }
 
-               public override KeySizes[] LegalKeySizes {
-                       get { return LegalKeySizesValue; }
-               }
-
                public bool PersistKeyInCsp {
                        get { return persistKey; }
-                       set {
-                               persistKey = value;
-                               if (persistKey)
-                                       OnKeyGenerated (dsa);
-                       }
+                       set { persistKey = value; }
                }
 
-#if (NET_1_0 || NET_1_1)
-               internal
-#else
-               public 
-#endif
-               bool PublicOnly {
+               [ComVisible (false)]
+               public bool PublicOnly {
                        get { return dsa.PublicOnly; }
                }
 
@@ -122,19 +135,19 @@ namespace System.Security.Cryptography {
                        get { return "http://www.w3.org/2000/09/xmldsig#dsa-sha1"; }
                }
 
-#if ! NET_1_0
-               private static bool useMachineKeyStore = false;
+               private static bool useMachineKeyStore;
 
                public static bool UseMachineKeyStore {
                        get { return useMachineKeyStore; }
                        set { useMachineKeyStore = value; }
                }
-#endif
 
                public override DSAParameters ExportParameters (bool includePrivateParameters) 
                {
-                       if ((includePrivateParameters) && (!privateKeyExportable))
-                               throw new CryptographicException ("cannot export private key");
+                       if ((includePrivateParameters) && (!privateKeyExportable)) {
+                               throw new CryptographicException (
+                                       Locale.GetText ("Cannot export private key"));
+                       }
 
                        return dsa.ExportParameters (includePrivateParameters);
                }
@@ -149,16 +162,19 @@ namespace System.Security.Cryptography {
                        return dsa.CreateSignature (rgbHash);
                }
 
-               public byte[] SignData (byte[] data)
+               public byte[] SignData (byte[] buffer)
                {
-                       return dsa.CreateSignature (data);
+                       // right now only SHA1 is supported by FIPS186-2
+                       HashAlgorithm hash = SHA1.Create ();
+                       byte[] toBeSigned = hash.ComputeHash (buffer);
+                       return dsa.CreateSignature (toBeSigned);
                }
 
-               public byte[] SignData (byte[] data, int offset, int count)
+               public byte[] SignData (byte[] buffer, int offset, int count)
                {
                        // right now only SHA1 is supported by FIPS186-2
                        HashAlgorithm hash = SHA1.Create ();
-                       byte[] toBeSigned = hash.ComputeHash (data, offset, count);
+                       byte[] toBeSigned = hash.ComputeHash (buffer, offset, count);
                        return dsa.CreateSignature (toBeSigned);
                }
 
@@ -173,8 +189,11 @@ namespace System.Security.Cryptography {
                public byte[] SignHash (byte[] rgbHash, string str)
                {
                        // right now only SHA1 is supported by FIPS186-2
-                       if (String.Compare (str, "SHA1", true, CultureInfo.InvariantCulture) != 0)
-                               throw new Exception (); // not documented
+                       if (String.Compare (str, "SHA1", true, CultureInfo.InvariantCulture) != 0) {
+                               // not documented
+                               throw new CryptographicException (Locale.GetText ("Only SHA1 is supported."));
+                       }
+
                        return dsa.CreateSignature (rgbHash);
                }
 
@@ -191,8 +210,10 @@ namespace System.Security.Cryptography {
                {
                        if (str == null)
                                str = "SHA1"; // default value
-                       if (str != "SHA1")
-                               throw new CryptographicException ();
+                       if (String.Compare (str, "SHA1", true, CultureInfo.InvariantCulture) != 0) {
+                               throw new CryptographicException (Locale.GetText ("Only SHA1 is supported."));
+                       }
+
                        return dsa.VerifySignature (rgbHash, rgbSignature);
                }
 
@@ -218,7 +239,7 @@ namespace System.Security.Cryptography {
 
                // private stuff
 
-               private void OnKeyGenerated (object sender) 
+               private void OnKeyGenerated (object sender, EventArgs e
                {
                        // the key isn't persisted and we want it persisted
                        if ((persistKey) && (!persisted)) {
@@ -228,5 +249,50 @@ namespace System.Security.Cryptography {
                                persisted = true;
                        }
                }
+               // ICspAsymmetricAlgorithm
+
+               [MonoTODO ("call into KeyPairPersistence to get details")]
+               [ComVisible (false)]
+               public CspKeyContainerInfo CspKeyContainerInfo {
+                       get { return null; }
+               }
+
+               [ComVisible (false)]
+               public byte[] ExportCspBlob (bool includePrivateParameters)
+               {
+                       byte[] blob = null;
+                       if (includePrivateParameters)
+                               blob = CryptoConvert.ToCapiPrivateKeyBlob (this);
+                       else
+                               blob = CryptoConvert.ToCapiPublicKeyBlob (this);
+                       return blob;
+               }
+
+               [ComVisible (false)]
+               public void ImportCspBlob (byte[] keyBlob)
+               {
+                       if (keyBlob == null)
+                               throw new ArgumentNullException ("keyBlob");
+                       DSA dsa = CryptoConvert.FromCapiKeyBlobDSA (keyBlob);
+                       if (dsa is DSACryptoServiceProvider) {
+                               DSAParameters dsap = dsa.ExportParameters (!(dsa as DSACryptoServiceProvider).PublicOnly);
+                               ImportParameters (dsap);
+                       } else {
+                               // we can't know from DSA if the private key is available
+                               try {
+                                       // so we try it...
+                                       DSAParameters dsap = dsa.ExportParameters (true);
+                                       ImportParameters (dsap);
+                               }
+                               catch {
+                                       // and fall back
+                                       DSAParameters dsap = dsa.ExportParameters (false);
+                                       ImportParameters (dsap);
+                               }
+                       }
+               }
        }
 }
+
+#endif
+