New tests.
[mono.git] / mcs / class / corlib / System.Security.Cryptography / RSACryptoServiceProvider.cs
index e4ee976b17e058cf91d27aa40c3f73f17d4bd9af..ef607bc5fd28b0274dfcca13685009223baf6f17 100644 (file)
@@ -7,11 +7,7 @@
 //
 // (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 Novell, Inc (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
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-using System;
+#if !MOONLIGHT
+
 using System.IO;
+using System.Runtime.InteropServices;
 
-using Mono.Math;
 using Mono.Security.Cryptography;
 
 namespace System.Security.Cryptography {
 
-       public sealed class RSACryptoServiceProvider : RSA {
-       
+       [ComVisible (true)]
+       public sealed class RSACryptoServiceProvider : RSA, ICspAsymmetricAlgorithm {
                private const int PROV_RSA_FULL = 1;    // from WinCrypt.h
 
                private KeyPairPersistence store;
@@ -99,7 +96,7 @@ namespace System.Security.Cryptography {
                        persistKey = (p != null);
                        if (p == null) {
                                p = new CspParameters (PROV_RSA_FULL);
-#if ! NET_1_0
+#if NET_1_1
                                if (useMachineKeyStore)
                                        p.Flags |= CspProviderFlags.UseMachineKeyStore;
 #endif
@@ -116,7 +113,7 @@ namespace System.Security.Cryptography {
                        }
                }
 
-#if ! NET_1_0
+#if NET_1_1
                private static bool useMachineKeyStore = false;
 
                public static bool UseMachineKeyStore {
@@ -153,12 +150,8 @@ namespace System.Security.Cryptography {
                        }
                }
 
-#if (NET_1_0 || NET_1_1)
-               internal
-#else
-               public 
-#endif
-               bool PublicOnly {
+               [ComVisible (false)]
+               public bool PublicOnly {
                        get { return rsa.PublicOnly; }
                }
        
@@ -189,6 +182,9 @@ namespace System.Security.Cryptography {
                // Using this method to decrypt data IS dangerous (and very slow).
                public override byte[] DecryptValue (byte[] rgb) 
                {
+                       if (!rsa.IsCrtPossible)
+                               throw new CryptographicException ("Incomplete private key - missing CRT.");
+
                        return rsa.DecryptValue (rgb);
                }
        
@@ -294,10 +290,9 @@ namespace System.Security.Cryptography {
                {
                        if (rgbHash == null)
                                throw new ArgumentNullException ("rgbHash");
-                       if (str == null)
-                               throw new CryptographicException (Locale.GetText ("No OID specified"));
-       
-                       HashAlgorithm hash = HashAlgorithm.Create (GetHashNameFromOID (str));
+                       // Fx 2.0 defaults to the SHA-1
+                       string hashName = (str == null) ? "SHA1" : GetHashNameFromOID (str);
+                       HashAlgorithm hash = HashAlgorithm.Create (hashName);
                        return PKCS1.Sign_v15 (this, hash, rgbHash);
                }
 
@@ -305,10 +300,8 @@ namespace System.Security.Cryptography {
                // HashAlgorithm descendant
                public bool VerifyData (byte[] buffer, object halg, byte[] signature) 
                {
-#if NET_1_1
                        if (buffer == null)
                                throw new ArgumentNullException ("buffer");
-#endif
                        if (signature == null)
                                throw new ArgumentNullException ("signature");
 
@@ -327,8 +320,9 @@ namespace System.Security.Cryptography {
                                throw new ArgumentNullException ("rgbHash");
                        if (rgbSignature == null)
                                throw new ArgumentNullException ("rgbSignature");
-       
-                       HashAlgorithm hash = HashAlgorithm.Create (GetHashNameFromOID (str));
+                       // Fx 2.0 defaults to the SHA-1
+                       string hashName = (str == null) ? "SHA1" : GetHashNameFromOID (str);
+                       HashAlgorithm hash = HashAlgorithm.Create (hashName);
                        return PKCS1.Verify_v15 (this, hash, rgbHash, rgbSignature);
                }
        
@@ -359,5 +353,58 @@ namespace System.Security.Cryptography {
                                persisted = true;
                        }
                }
+               // ICspAsymmetricAlgorithm
+
+               [MonoTODO ("Always return null")]
+               // FIXME: 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);
+
+                       // ALGID (bytes 4-7) - default is KEYX
+                       // 00 24 00 00 (for CALG_RSA_SIGN)
+                       // 00 A4 00 00 (for CALG_RSA_KEYX)
+                       blob [5] = 0xA4;
+                       return blob;
+               }
+
+               [ComVisible (false)]
+               public void ImportCspBlob (byte[] keyBlob)
+               {
+                       if (keyBlob == null)
+                               throw new ArgumentNullException ("keyBlob");
+
+                       RSA rsa = CryptoConvert.FromCapiKeyBlob (keyBlob);
+                       if (rsa is RSACryptoServiceProvider) {
+                               // default (if no change are present in machine.config)
+                               RSAParameters rsap = rsa.ExportParameters (!(rsa as RSACryptoServiceProvider).PublicOnly);
+                               ImportParameters (rsap);
+                       } else {
+                               // we can't know from RSA if the private key is available
+                               try {
+                                       // so we try it...
+                                       RSAParameters rsap = rsa.ExportParameters (true);
+                                       ImportParameters (rsap);
+                               }
+                               catch {
+                                       // and fall back
+                                       RSAParameters rsap = rsa.ExportParameters (false);
+                                       ImportParameters (rsap);
+                               }
+                       }
+               }
        }
 }
+
+#endif
+