New tests.
[mono.git] / mcs / class / corlib / System.Security.Policy / HashMembershipCondition.cs
index 6a7c15780858f51a6a5c6b2daddd82e950fae28f..6918f250f85c6ba3b6e522512d6eface402663fa 100644 (file)
@@ -1,34 +1,68 @@
 //
-// System.Security.Policy.HashMembershipCondition
+// System.Security.Policy.HashMembershipCondition.cs
 //
-// Author(s):
-//  Jackson Harper (Jackson@LatitudeGeo.com)
+// Authors:
+//     Jackson Harper (Jackson@LatitudeGeo.com)
+//     Sebastien Pouliot  <sebastien@ximian.com>
 //
 // (C) 2002 Jackson Harper, All rights reserved
+// 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.Text;
+using System.Collections;
+using System.Globalization;
 using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Runtime.Serialization;
 using System.Security.Cryptography;
 
-namespace System.Security.Policy {
+using Mono.Security.Cryptography;
 
-       public sealed class HashMembershipCondition : IMembershipCondition, 
-               ISecurityEncodable, ISecurityPolicyEncodable {
+namespace System.Security.Policy {
 
-               private static readonly string XmlTag = "IMembershipCondition";
+       [Serializable]
+       [ComVisible (true)]
+       public sealed class HashMembershipCondition : IMembershipCondition, IDeserializationCallback, ISerializable {
+               private readonly int version = 1;
 
                private HashAlgorithm hash_algorithm;
                private byte[] hash_value;
 
-               public HashMembershipCondition (HashAlgorithm hash_algorithm,
-                       byte[] hash_value)
+               // so System.Activator.CreateInstance can create an instance...
+               internal HashMembershipCondition ()
+               {
+               }
+
+               public HashMembershipCondition (HashAlgorithm hashAlg, byte[] value)
                {
-                       if (hash_algorithm == null || hash_value == null)
-                               throw new ArgumentNullException ();
+                       if (hashAlg == null)
+                               throw new ArgumentNullException ("hashAlg");
+                       if (value == null)
+                               throw new ArgumentNullException ("value");
                                
-                       this.hash_algorithm = hash_algorithm;
-                       this.hash_value = hash_value;
+                       this.hash_algorithm = hashAlg;
+                       this.hash_value = (byte[]) value.Clone ();
                }
 
                //
@@ -36,20 +70,28 @@ namespace System.Security.Policy {
                //
                
                public HashAlgorithm HashAlgorithm {
-                       get { return hash_algorithm; }
+                       get {
+                               if (hash_algorithm == null)
+                                       hash_algorithm = new SHA1Managed ();
+                               return hash_algorithm;
+                       }
                        set { 
                                if (value == null)
-                                       throw new ArgumentNullException ();
+                                       throw new ArgumentNullException ("HashAlgorithm");
                                hash_algorithm = value; 
                        }
                }
 
                public byte[] HashValue {
-                       get { return hash_value; }
+                       get {
+                               if (hash_value == null)
+                                       throw new ArgumentException (Locale.GetText ("No HashValue available."));
+                               return (byte[]) hash_value.Clone ();
+                       }
                        set { 
                                if (value == null)
-                                       throw new ArgumentNullException ();
-                               hash_value = value; 
+                                       throw new ArgumentNullException ("HashValue");
+                               hash_value = (byte[]) value.Clone ();
                        } 
                }
 
@@ -60,14 +102,14 @@ namespace System.Security.Policy {
                public bool Check (Evidence evidence)
                {
                        if (evidence == null)
-                               throw new ArgumentNullException ();
+                               return false;
 
-                       // Loop through evidence finding the first Hash object
-                       foreach (object obj in evidence) {
-                               Hash hash = obj as Hash;
+                       IEnumerator e = evidence.GetHostEnumerator ();
+                       while (e.MoveNext ()) {
+                               Hash hash = (e.Current as Hash);
                                if (hash == null)
                                        continue;
-                               if (EqualsHashValue (hash.GenerateHash (hash_algorithm)))
+                               if (Compare (hash_value, hash.GenerateHash (hash_algorithm)))
                                        return true;
                                break;
                        }
@@ -81,96 +123,89 @@ namespace System.Security.Policy {
 
                public override bool Equals (object o)
                {
-                       HashMembershipCondition other;
-                       if (!(o is HashMembershipCondition))
+                       HashMembershipCondition other = (o as HashMembershipCondition);
+                       if (other == null)
                                return false;
 
-                       other = (HashMembershipCondition)o;
-                       
-                       return (other.HashAlgorithm == hash_algorithm &&
-                               other.HashValue == hash_value);
+                       return ((other.HashAlgorithm == hash_algorithm) &&
+                               Compare (hash_value, other.hash_value));
                }
                
-               public SecurityElement ToXml()
+               public SecurityElement ToXml ()
                {
                        return ToXml (null);
                }
 
                public SecurityElement ToXml (PolicyLevel level)
                {
-                       SecurityElement se = new SecurityElement (XmlTag);
-                       Type type = this.GetType ();
-                       string classString = type.FullName + ", " + type.Assembly;
-                       se.AddAttribute ("class", classString);
-                       se.AddAttribute ("version", "1");
-                       se.AddAttribute ("HashValue", Encoding.Default.GetString (hash_value));
+                       SecurityElement se = MembershipConditionHelper.Element (typeof (HashMembershipCondition), version);
+                       se.AddAttribute ("HashValue", CryptoConvert.ToHex (HashValue));
                        se.AddAttribute ("HashAlgorithm", hash_algorithm.GetType ().FullName);
                        return se;
                }
 
-               public void FromXml (SecurityElement element)
+               public void FromXml (SecurityElement e)
                {
-                       FromXml (element, null);
+                       FromXml (e, null);
                }
                
-               public void FromXml (SecurityElement e,
-                       PolicyLevel level)
+               public void FromXml (SecurityElement e, PolicyLevel level)
                {
-                       if (e == null)
-                               throw new ArgumentNullException ();
-                       if (e.Tag != XmlTag)
-                               throw new ArgumentException(
-                                       "e","The Tag of SecurityElement must be " + XmlTag);
+                       MembershipConditionHelper.CheckSecurityElement (e, "e", version, version);
                        
-                       string value = (string)e.Attributes["HashValue"];
-                       string algorithm = (string)e.Attributes["HashAlgorithm"];
+                       hash_value = CryptoConvert.FromHex (e.Attribute ("HashValue"));
 
-                       if (value == null || algorithm == null )
-                               throw new ArgumentException ();
-                       
-                       hash_value = Encoding.Default.GetBytes (value);
-                       hash_algorithm = (HashAlgorithm)Assembly.GetExecutingAssembly ().CreateInstance (algorithm);
-                       
+                       string algorithm = e.Attribute ("HashAlgorithm");
+                       hash_algorithm = (algorithm == null) ? null : HashAlgorithm.Create (algorithm);
                }
 
-               [MonoTODO("This is not right")]
                public override int GetHashCode ()
                {
-                       return hash_value.GetHashCode ();
+                       // note: a Copy must have the same hash code
+                       int code = hash_algorithm.GetType ().GetHashCode ();
+                       if (hash_value != null) {
+                               foreach (byte b in hash_value) {
+                                       code ^= b;
+                               }
+                       }
+                       return code;
                }
                
                public override string ToString ()
                {
-                       StringBuilder builder = new StringBuilder ();
-                       Type alg_type = hash_algorithm.GetType ();
-
-                       builder.Append ("Hash -");
-                       builder.AppendFormat ("{0} {1}", alg_type.FullName, 
-                               alg_type.Assembly);
-                       builder.AppendFormat (" = ",  Encoding.Default.GetString (hash_value));
-
-                       return builder.ToString ();
+                       Type alg_type = this.HashAlgorithm.GetType ();
+                       return String.Format ("Hash - {0} {1} = {2}", alg_type.FullName, 
+                               alg_type.Assembly, CryptoConvert.ToHex (HashValue));
                }
 
                //
                // Private Methods
                //
 
-               private bool EqualsHashValue (byte[] value)
+               private bool Compare (byte[] expected, byte[] actual)
                {
-                       int len;
-
-                       if (value.Length != hash_value.Length)
+                       if (expected.Length != actual.Length)
                                return false;
                        
-                       len = value.Length;
-                       for (int i=0; i<len; i++ ) {
-                               if (value[i] != hash_value[i])
+                       int len = expected.Length;
+                       for (int i = 0; i < len; i++) {
+                               if (expected [i] != actual [i])
                                        return false;
                        }
-
                        return true;
                }
+
+               [MonoTODO ("fx 2.0")]
+               void IDeserializationCallback.OnDeserialization (object sender)
+               {
+               }
+
+               [MonoTODO ("fx 2.0")]
+               void ISerializable.GetObjectData (SerializationInfo info, StreamingContext context) 
+               {
+               }
        }
 }
 
+#endif
+