2007-08-17 Sebastien Pouliot <sebastien@ximian.com>
[mono.git] / mcs / class / corlib / System.Security.Cryptography / PasswordDeriveBytes.cs
index ca4b001edf2560170fc483991807fd30221420db..ae1bb1f8b53ff2fa53f90cd715524ef76712dc66 100644 (file)
@@ -5,7 +5,7 @@
 //     Sebastien Pouliot (sebastien@ximian.com)
 //
 // (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
-// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2004-2007 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
@@ -27,8 +27,8 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-using System;
 using System.Globalization;
+using System.Runtime.InteropServices;
 using System.Text;
 
 namespace System.Security.Cryptography {
@@ -39,6 +39,9 @@ namespace System.Security.Cryptography {
 // b.  IETF RFC2898: PKCS #5: Password-Based Cryptography Specification Version 2.0
 //     http://www.rfc-editor.org/rfc/rfc2898.txt
 
+#if NET_2_0
+[ComVisible (true)]
+#endif
 public class PasswordDeriveBytes : DeriveBytes {
 
        private string HashNameValue;
@@ -81,6 +84,36 @@ public class PasswordDeriveBytes : DeriveBytes {
                }
        }
 
+#if NET_2_0
+       public PasswordDeriveBytes (byte[] password, byte[] salt) 
+       {
+               Prepare (password, salt, "SHA1", 100);
+       }
+
+       public PasswordDeriveBytes (byte[] password, byte[] salt, CspParameters cspParams) 
+       {
+               Prepare (password, salt, "SHA1", 100);
+               if (cspParams != null) {
+                       throw new NotSupportedException (
+                               Locale.GetText ("CspParameters not supported by Mono for PasswordDeriveBytes."));
+               }
+       }
+
+       public PasswordDeriveBytes (byte[] password, byte[] salt, string hashName, int iterations) 
+       {
+               Prepare (password, salt, hashName, iterations);
+       }
+
+       public PasswordDeriveBytes (byte[] password, byte[] salt, string hashName, int iterations, CspParameters cspParams) 
+       {
+               Prepare (password, salt, hashName, iterations);
+               if (cspParams != null) {
+                       throw new NotSupportedException (
+                               Locale.GetText ("CspParameters not supported by Mono for PasswordDeriveBytes."));
+               }
+       }
+#endif
+
        ~PasswordDeriveBytes () 
        {
                // zeroize buffer
@@ -92,15 +125,33 @@ public class PasswordDeriveBytes : DeriveBytes {
                Array.Clear (password, 0, password.Length);
        }
 
+#if NET_2_0
        private void Prepare (string strPassword, byte[] rgbSalt, string strHashName, int iterations) 
        {
-#if NET_2_0
                if (strPassword == null)
                        throw new ArgumentNullException ("strPassword");
-               password = Encoding.UTF8.GetBytes (strPassword);
+
+               byte[] pwd = Encoding.UTF8.GetBytes (strPassword);
+               Prepare (pwd, rgbSalt, strHashName, iterations);
+               Array.Clear (pwd, 0, pwd.Length);
+       }
+
+       private void Prepare (byte[] password, byte[] rgbSalt, string strHashName, int iterations)
+       {
+               if (password == null)
+                       throw new ArgumentNullException ("password");
+
+               this.password = (byte[]) password.Clone ();
 
                Salt = rgbSalt;
+
+               HashName = strHashName;
+               IterationCount = iterations;
+               state = 0;
+       }
 #else
+       private void Prepare (string strPassword, byte[] rgbSalt, string strHashName, int iterations)
+       {
                if (strPassword == null)
                        password = null;
                else
@@ -110,12 +161,12 @@ public class PasswordDeriveBytes : DeriveBytes {
                        SaltValue = null;
                else
                        SaltValue = (byte[]) rgbSalt.Clone ();
-#endif
 
                HashName = strHashName;
                IterationCount = iterations;
                state = 0;
        }
+#endif
 
        public string HashName {
                get { return HashNameValue; } 
@@ -177,6 +228,9 @@ public class PasswordDeriveBytes : DeriveBytes {
        }
 
        // note: Key is returned - we can't zeroize it ourselve :-(
+#if NET_2_0
+       [Obsolete ("see Rfc2898DeriveBytes for PKCS#5 v2 support")]
+#endif
        public override byte[] GetBytes (int cb) 
        {
 #if ! NET_2_0
@@ -188,10 +242,10 @@ public class PasswordDeriveBytes : DeriveBytes {
                        throw new IndexOutOfRangeException ("cb");
 
                if (state == 0) {
-                       state = 1;
                        // it's now impossible to change the HashName, Salt
                        // and IterationCount
                        Reset ();
+                       state = 1;
                }
 
                byte[] result = new byte [cb];
@@ -244,7 +298,11 @@ public class PasswordDeriveBytes : DeriveBytes {
 
        public override void Reset () 
        {
+#if NET_2_0
+               state = 0;
+#else
                // note: Reset doesn't change state
+#endif
                position = 0;
                hashnumber = 0;