New tests, updates
[mono.git] / mcs / class / corlib / System.Security.Policy / HashMembershipCondition.cs
1 //
2 // System.Security.Policy.HashMembershipCondition.cs
3 //
4 // Authors:
5 //      Jackson Harper (Jackson@LatitudeGeo.com)
6 //      Sebastien Pouliot  <sebastien@ximian.com>
7 //
8 // (C) 2002 Jackson Harper, All rights reserved
9 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30
31 #if !NET_2_1
32
33 using System.Collections;
34 using System.Globalization;
35 using System.Reflection;
36 using System.Runtime.InteropServices;
37 using System.Runtime.Serialization;
38 using System.Security.Cryptography;
39
40 using Mono.Security.Cryptography;
41
42 namespace System.Security.Policy {
43
44         [Serializable]
45 #if NET_2_0
46         [ComVisible (true)]
47         public sealed class HashMembershipCondition : IMembershipCondition, IDeserializationCallback, ISerializable {
48 #else
49         public sealed class HashMembershipCondition : IMembershipCondition {
50 #endif
51                 private readonly int version = 1;
52
53                 private HashAlgorithm hash_algorithm;
54                 private byte[] hash_value;
55
56                 // so System.Activator.CreateInstance can create an instance...
57                 internal HashMembershipCondition ()
58                 {
59                 }
60
61                 public HashMembershipCondition (HashAlgorithm hashAlg, byte[] value)
62                 {
63                         if (hashAlg == null)
64                                 throw new ArgumentNullException ("hashAlg");
65                         if (value == null)
66                                 throw new ArgumentNullException ("value");
67                                 
68                         this.hash_algorithm = hashAlg;
69                         this.hash_value = (byte[]) value.Clone ();
70                 }
71
72                 //
73                 // Public Properties
74                 //
75                 
76                 public HashAlgorithm HashAlgorithm {
77                         get {
78                                 if (hash_algorithm == null)
79                                         hash_algorithm = new SHA1Managed ();
80                                 return hash_algorithm;
81                         }
82                         set { 
83                                 if (value == null)
84                                         throw new ArgumentNullException ("HashAlgorithm");
85                                 hash_algorithm = value; 
86                         }
87                 }
88
89                 public byte[] HashValue {
90                         get {
91                                 if (hash_value == null)
92                                         throw new ArgumentException (Locale.GetText ("No HashValue available."));
93                                 return (byte[]) hash_value.Clone ();
94                         }
95                         set { 
96                                 if (value == null)
97                                         throw new ArgumentNullException ("HashValue");
98                                 hash_value = (byte[]) value.Clone ();
99                         } 
100                 }
101
102                 //
103                 // Public Methods
104                 //
105
106                 public bool Check (Evidence evidence)
107                 {
108                         if (evidence == null)
109                                 return false;
110
111                         IEnumerator e = evidence.GetHostEnumerator ();
112                         while (e.MoveNext ()) {
113                                 Hash hash = (e.Current as Hash);
114                                 if (hash == null)
115                                         continue;
116                                 if (Compare (hash_value, hash.GenerateHash (hash_algorithm)))
117                                         return true;
118                                 break;
119                         }
120                         return false;
121                 }
122
123                 public IMembershipCondition Copy ()
124                 {
125                         return new HashMembershipCondition (hash_algorithm, hash_value);
126                 }
127
128                 public override bool Equals (object o)
129                 {
130                         HashMembershipCondition other = (o as HashMembershipCondition);
131                         if (other == null)
132                                 return false;
133
134                         return ((other.HashAlgorithm == hash_algorithm) &&
135                                 Compare (hash_value, other.hash_value));
136                 }
137                 
138                 public SecurityElement ToXml ()
139                 {
140                         return ToXml (null);
141                 }
142
143                 public SecurityElement ToXml (PolicyLevel level)
144                 {
145                         SecurityElement se = MembershipConditionHelper.Element (typeof (HashMembershipCondition), version);
146                         se.AddAttribute ("HashValue", CryptoConvert.ToHex (HashValue));
147                         se.AddAttribute ("HashAlgorithm", hash_algorithm.GetType ().FullName);
148                         return se;
149                 }
150
151                 public void FromXml (SecurityElement e)
152                 {
153                         FromXml (e, null);
154                 }
155                 
156                 public void FromXml (SecurityElement e, PolicyLevel level)
157                 {
158                         MembershipConditionHelper.CheckSecurityElement (e, "e", version, version);
159                         
160                         hash_value = CryptoConvert.FromHex (e.Attribute ("HashValue"));
161
162                         string algorithm = e.Attribute ("HashAlgorithm");
163                         hash_algorithm = (algorithm == null) ? null : HashAlgorithm.Create (algorithm);
164                 }
165
166                 public override int GetHashCode ()
167                 {
168                         // note: a Copy must have the same hash code
169                         int code = hash_algorithm.GetType ().GetHashCode ();
170                         if (hash_value != null) {
171                                 foreach (byte b in hash_value) {
172                                         code ^= b;
173                                 }
174                         }
175                         return code;
176                 }
177                 
178                 public override string ToString ()
179                 {
180                         Type alg_type = this.HashAlgorithm.GetType ();
181                         return String.Format ("Hash - {0} {1} = {2}", alg_type.FullName, 
182                                 alg_type.Assembly, CryptoConvert.ToHex (HashValue));
183                 }
184
185                 //
186                 // Private Methods
187                 //
188
189                 private bool Compare (byte[] expected, byte[] actual)
190                 {
191                         if (expected.Length != actual.Length)
192                                 return false;
193                         
194                         int len = expected.Length;
195                         for (int i = 0; i < len; i++) {
196                                 if (expected [i] != actual [i])
197                                         return false;
198                         }
199                         return true;
200                 }
201
202 #if NET_2_0
203                 [MonoTODO ("fx 2.0")]
204                 void IDeserializationCallback.OnDeserialization (object sender)
205                 {
206                 }
207
208                 [MonoTODO ("fx 2.0")]
209                 void ISerializable.GetObjectData (SerializationInfo info, StreamingContext context) 
210                 {
211                 }
212 #endif
213         }
214 }
215
216 #endif
217