Update Reference Sources to .NET Framework 4.6.1
[mono.git] / mcs / class / referencesource / mscorlib / system / security / permissions / keycontainerpermission.cs
1 // ==++==
2 // 
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 // 
5 // ==--==
6 // <OWNER>[....]</OWNER>
7 // 
8
9 //
10 //  KeyContainerPermission.cs
11 //
12
13 namespace System.Security.Permissions {
14     using System;
15     using System.Collections;
16     using System.Collections.Generic;
17     using System.Security.Cryptography;
18     using System.Security.Util;
19     using System.Globalization;
20     using System.Diagnostics.Contracts;
21
22 #if !FEATURE_PAL
23
24 [Serializable]
25     [Flags]
26     [System.Runtime.InteropServices.ComVisible(true)]
27     public enum KeyContainerPermissionFlags {
28         NoFlags     = 0x0000,
29
30         Create      = 0x0001,
31         Open        = 0x0002,
32         Delete      = 0x0004,
33
34         Import      = 0x0010,
35         Export      = 0x0020,
36
37         Sign        = 0x0100,
38         Decrypt     = 0x0200,
39
40         ViewAcl     = 0x1000,
41         ChangeAcl   = 0x2000,
42
43         AllFlags    = 0x3337
44     }
45
46     [Serializable]
47     [System.Runtime.InteropServices.ComVisible(true)]
48     public sealed class KeyContainerPermissionAccessEntry {
49         private string m_keyStore;
50         private string m_providerName;
51         private int m_providerType;
52         private string m_keyContainerName;
53         private int m_keySpec;
54         private KeyContainerPermissionFlags m_flags;
55
56         internal KeyContainerPermissionAccessEntry(KeyContainerPermissionAccessEntry accessEntry) : 
57             this (accessEntry.KeyStore, accessEntry.ProviderName, accessEntry.ProviderType, accessEntry.KeyContainerName,
58                   accessEntry.KeySpec, accessEntry.Flags) {
59         }
60
61         public KeyContainerPermissionAccessEntry(string keyContainerName, KeyContainerPermissionFlags flags) : 
62             this (null, null, -1, keyContainerName, -1, flags) {
63         }
64
65         public KeyContainerPermissionAccessEntry(CspParameters parameters, KeyContainerPermissionFlags flags) :
66             this((parameters.Flags & CspProviderFlags.UseMachineKeyStore) == CspProviderFlags.UseMachineKeyStore ? "Machine" : "User",
67                  parameters.ProviderName,
68                  parameters.ProviderType,
69                  parameters.KeyContainerName,
70                  parameters.KeyNumber,
71                  flags) {
72         }
73
74         public KeyContainerPermissionAccessEntry(string keyStore, string providerName, int providerType, 
75                         string keyContainerName, int keySpec, KeyContainerPermissionFlags flags) {
76             m_providerName = (providerName == null ? "*" : providerName);
77             m_providerType = providerType;
78             m_keyContainerName = (keyContainerName == null ? "*" : keyContainerName);
79             m_keySpec = keySpec;
80             KeyStore = keyStore;
81             Flags = flags;
82         }
83
84         public string KeyStore {
85             get {
86                 return m_keyStore;
87             }
88             set {
89                 // Unrestricted entries are invalid; they should not be allowed.
90                 if (IsUnrestrictedEntry(value, this.ProviderName, this.ProviderType, this.KeyContainerName, this.KeySpec))
91                     throw new ArgumentException(Environment.GetResourceString("Arg_InvalidAccessEntry"));
92
93                 if (value == null) {
94                     m_keyStore = "*";
95                 } else {
96                     if (value != "User" && value != "Machine" && value != "*")
97                         throw new ArgumentException(Environment.GetResourceString("Argument_InvalidKeyStore", value), "value");
98                     m_keyStore = value;
99                 }
100             }
101         }
102
103         public string ProviderName {
104             get {
105                 return m_providerName;
106             }
107             set {
108                 // Unrestricted entries are invalid; they should not be allowed.
109                 if (IsUnrestrictedEntry(this.KeyStore, value, this.ProviderType, this.KeyContainerName, this.KeySpec))
110                     throw new ArgumentException(Environment.GetResourceString("Arg_InvalidAccessEntry"));
111
112                 if (value == null)
113                     m_providerName = "*";
114                 else
115                     m_providerName = value;
116             }
117         }
118
119         public int ProviderType {
120             get {
121                 return m_providerType;
122             }
123             set {
124                 // Unrestricted entries are invalid; they should not be allowed.
125                 if (IsUnrestrictedEntry(this.KeyStore, this.ProviderName, value, this.KeyContainerName, this.KeySpec))
126                     throw new ArgumentException(Environment.GetResourceString("Arg_InvalidAccessEntry"));
127
128                 m_providerType = value;
129             }
130         }
131
132         public string KeyContainerName {
133             get {
134                 return m_keyContainerName;
135             }
136             set {
137                 // Unrestricted entries are invalid; they should not be allowed.
138                 if (IsUnrestrictedEntry(this.KeyStore, this.ProviderName, this.ProviderType, value, this.KeySpec))
139                     throw new ArgumentException(Environment.GetResourceString("Arg_InvalidAccessEntry"));
140
141                 if (value == null)
142                     m_keyContainerName = "*";
143                 else
144                     m_keyContainerName = value;
145             }
146         }
147
148         public int KeySpec {
149             get {
150                 return m_keySpec;
151             }
152             set {
153                 // Unrestricted entries are invalid; they should not be allowed.
154                 if (IsUnrestrictedEntry(this.KeyStore, this.ProviderName, this.ProviderType, this.KeyContainerName, value))
155                     throw new ArgumentException(Environment.GetResourceString("Arg_InvalidAccessEntry"));
156
157                 m_keySpec = value;
158             }
159         }
160
161         public KeyContainerPermissionFlags Flags {
162             get {
163                 return m_flags;
164             }
165             set {
166                 KeyContainerPermission.VerifyFlags(value);
167                 m_flags = value;
168             }
169         }
170
171         public override bool Equals (Object o) {
172             KeyContainerPermissionAccessEntry accessEntry = o as KeyContainerPermissionAccessEntry;
173             if (accessEntry == null)
174                 return false;
175
176             if (accessEntry.m_keyStore != m_keyStore) return false;
177             if (accessEntry.m_providerName != m_providerName) return false;
178             if (accessEntry.m_providerType != m_providerType) return false;
179             if (accessEntry.m_keyContainerName != m_keyContainerName) return false;
180             if (accessEntry.m_keySpec != m_keySpec) return false;
181
182             return true;
183         }
184
185         public override int GetHashCode () {
186             int hash = 0;
187
188             hash |= (this.m_keyStore.GetHashCode() & 0x000000FF) << 24;
189             hash |= (this.m_providerName.GetHashCode() & 0x000000FF) << 16;
190             hash |= (this.m_providerType & 0x0000000F) << 12;
191             hash |= (this.m_keyContainerName.GetHashCode() & 0x000000FF) << 4;
192             hash |= (this.m_keySpec & 0x0000000F);
193
194             return hash;
195         }
196
197         internal bool IsSubsetOf (KeyContainerPermissionAccessEntry target) {
198             if (target.m_keyStore != "*" && this.m_keyStore != target.m_keyStore)
199                 return false;
200             if (target.m_providerName != "*" && this.m_providerName != target.m_providerName)
201                 return false;
202             if (target.m_providerType != -1 && this.m_providerType != target.m_providerType)
203                 return false;
204             if (target.m_keyContainerName != "*" && this.m_keyContainerName != target.m_keyContainerName)
205                 return false;
206             if (target.m_keySpec != -1 && this.m_keySpec != target.m_keySpec)
207                 return false;
208
209             return true;
210         }
211
212         internal static bool IsUnrestrictedEntry (string keyStore, string providerName, int providerType, 
213                         string keyContainerName, int keySpec) {
214             if (keyStore != "*" && keyStore != null) return false;
215             if (providerName != "*" && providerName != null) return false;
216             if (providerType != -1) return false;
217             if (keyContainerName != "*" && keyContainerName != null) return false;
218             if (keySpec != -1) return false;
219
220             return true;
221         }
222     }
223
224     [Serializable]
225     [System.Runtime.InteropServices.ComVisible(true)]
226     public sealed class KeyContainerPermissionAccessEntryCollection : ICollection {
227         private ArrayList m_list;
228         private KeyContainerPermissionFlags m_globalFlags;
229
230         private KeyContainerPermissionAccessEntryCollection () {}
231         internal KeyContainerPermissionAccessEntryCollection (KeyContainerPermissionFlags globalFlags) {
232             m_list = new ArrayList();
233             m_globalFlags = globalFlags;
234         }
235
236         public KeyContainerPermissionAccessEntry this[int index] {
237             get {
238                 if (index < 0)
239                     throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumNotStarted"));
240                 if (index >= Count)
241                     throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
242                 Contract.EndContractBlock();
243
244                 return (KeyContainerPermissionAccessEntry)m_list[index];
245             }
246         }
247
248         public int Count {
249             get {
250                 return m_list.Count;
251             }
252         }
253
254         public int Add (KeyContainerPermissionAccessEntry accessEntry) {
255             if (accessEntry == null)
256                 throw new ArgumentNullException("accessEntry");
257             Contract.EndContractBlock();
258
259             int index = m_list.IndexOf(accessEntry);
260             if (index == -1) {
261                 if (accessEntry.Flags != m_globalFlags) {
262                     return m_list.Add(accessEntry);
263                 }
264                 else
265                     return -1;
266             } else {
267                 // We pick up the intersection of the 2 flags. This is the secure choice 
268                 // so we are opting for it.
269                 ((KeyContainerPermissionAccessEntry)m_list[index]).Flags &= accessEntry.Flags;
270                 return index;
271             }
272         }
273
274         public void Clear () {
275             m_list.Clear();
276         }
277
278         public int IndexOf (KeyContainerPermissionAccessEntry accessEntry) {
279             return m_list.IndexOf(accessEntry);
280         }
281
282         public void Remove (KeyContainerPermissionAccessEntry accessEntry) {
283             if (accessEntry == null)
284                 throw new ArgumentNullException("accessEntry");
285             Contract.EndContractBlock();
286             m_list.Remove(accessEntry);
287         }
288
289         public KeyContainerPermissionAccessEntryEnumerator GetEnumerator () {
290             return new KeyContainerPermissionAccessEntryEnumerator(this);
291         }
292
293         /// <internalonly/>
294         IEnumerator IEnumerable.GetEnumerator () {
295             return new KeyContainerPermissionAccessEntryEnumerator(this);
296         }
297
298         /// <internalonly/>
299         void ICollection.CopyTo (Array array, int index) {
300             if (array == null)
301                 throw new ArgumentNullException("array");
302             if (array.Rank != 1)
303                 throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
304             if (index < 0 || index >= array.Length)
305                 throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
306             if (index + this.Count > array.Length)
307                 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
308             Contract.EndContractBlock();
309
310             for (int i=0; i < this.Count; i++) {
311                 array.SetValue(this[i], index);
312                 index++;
313             }
314         }
315
316         public void CopyTo (KeyContainerPermissionAccessEntry[] array, int index) {
317             ((ICollection)this).CopyTo(array, index);
318         }
319
320         public bool IsSynchronized {
321             get {
322                 return false;
323             }
324         }
325
326         public Object SyncRoot {
327             get {
328                 return this;
329             }
330         }
331     }
332
333     [Serializable]
334     [System.Runtime.InteropServices.ComVisible(true)]
335     public sealed class KeyContainerPermissionAccessEntryEnumerator : IEnumerator {
336         private KeyContainerPermissionAccessEntryCollection m_entries;
337         private int m_current;
338
339         private KeyContainerPermissionAccessEntryEnumerator () {}
340         internal KeyContainerPermissionAccessEntryEnumerator (KeyContainerPermissionAccessEntryCollection entries) {
341             m_entries = entries;
342             m_current = -1;
343         }
344
345         public KeyContainerPermissionAccessEntry Current {
346             get {
347                 return m_entries[m_current];
348             }
349         }
350
351         /// <internalonly/>
352         Object IEnumerator.Current {
353             get {
354                 return (Object) m_entries[m_current];
355             }
356         }
357
358         public bool MoveNext() {
359             if (m_current == ((int) m_entries.Count - 1))
360                 return false;
361             m_current++;
362             return true;
363         }
364
365         public void Reset() {
366             m_current = -1;
367         }
368     }
369
370     [Serializable]
371     [System.Runtime.InteropServices.ComVisible(true)]
372     public sealed class KeyContainerPermission : CodeAccessPermission, IUnrestrictedPermission, IBuiltInPermission {
373         private KeyContainerPermissionFlags m_flags;
374         private KeyContainerPermissionAccessEntryCollection m_accessEntries;
375
376         public KeyContainerPermission (PermissionState state) {
377             if (state == PermissionState.Unrestricted)
378                 m_flags = KeyContainerPermissionFlags.AllFlags;
379             else if (state == PermissionState.None)
380                 m_flags = KeyContainerPermissionFlags.NoFlags;
381             else
382                 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidPermissionState"));
383             m_accessEntries = new KeyContainerPermissionAccessEntryCollection(m_flags);
384          }
385
386         public KeyContainerPermission (KeyContainerPermissionFlags flags) {
387             VerifyFlags(flags);
388             m_flags = flags;
389             m_accessEntries = new KeyContainerPermissionAccessEntryCollection(m_flags);
390         }
391
392         public KeyContainerPermission (KeyContainerPermissionFlags flags, KeyContainerPermissionAccessEntry[] accessList) {
393             if (accessList == null) 
394                 throw new ArgumentNullException("accessList");
395             Contract.EndContractBlock();
396
397             VerifyFlags(flags);
398             m_flags = flags;
399             m_accessEntries = new KeyContainerPermissionAccessEntryCollection(m_flags);
400             for (int index = 0; index < accessList.Length; index++) {
401                 m_accessEntries.Add(accessList[index]);
402             }
403         }
404
405         public KeyContainerPermissionFlags Flags {
406             get {
407                 return m_flags;
408             }
409         }
410
411         public KeyContainerPermissionAccessEntryCollection AccessEntries {
412             get {
413                 return m_accessEntries;
414             }
415         }
416
417         public bool IsUnrestricted () {
418             if (m_flags != KeyContainerPermissionFlags.AllFlags)
419                 return false;
420
421             foreach (KeyContainerPermissionAccessEntry accessEntry in AccessEntries) {
422                 if ((accessEntry.Flags & KeyContainerPermissionFlags.AllFlags) != KeyContainerPermissionFlags.AllFlags)
423                     return false;
424             }
425
426             return true;
427         }
428
429         private bool IsEmpty () {
430             if (this.Flags == KeyContainerPermissionFlags.NoFlags) {
431                 foreach (KeyContainerPermissionAccessEntry accessEntry in AccessEntries) {
432                     if (accessEntry.Flags != KeyContainerPermissionFlags.NoFlags)
433                         return false;
434                 }
435                 return true;
436             }
437             return false;
438         }
439
440         //
441         // IPermission implementation
442         //
443
444         public override bool IsSubsetOf (IPermission target) {
445             if (target == null) 
446                 return IsEmpty();
447
448             if (!VerifyType(target))
449                 throw new ArgumentException(Environment.GetResourceString("Argument_WrongType", this.GetType().FullName));
450
451             KeyContainerPermission operand = (KeyContainerPermission) target;
452
453             // since there are containers that are neither in the access list of the source, nor in the 
454             // access list of the target, the source flags must be a subset of the target flags.
455             if ((this.m_flags & operand.m_flags) != this.m_flags)
456                 return false;
457
458             // Any entry in the source should have "applicable" flags in the destination that actually
459             // are less restrictive than the flags in the source.
460
461             foreach (KeyContainerPermissionAccessEntry accessEntry in AccessEntries) {
462                 KeyContainerPermissionFlags targetFlags = GetApplicableFlags(accessEntry, operand);
463                 if ((accessEntry.Flags & targetFlags) != accessEntry.Flags)
464                     return false;
465             }
466
467             // Any entry in the target should have "applicable" flags in the source that actually
468             // are more restrictive than the flags in the target.
469
470             foreach (KeyContainerPermissionAccessEntry accessEntry in operand.AccessEntries) {
471                 KeyContainerPermissionFlags sourceFlags = GetApplicableFlags(accessEntry, this);
472                 if ((sourceFlags & accessEntry.Flags) != sourceFlags)
473                     return false;
474             }
475
476             return true;
477         }
478
479         public override IPermission Intersect (IPermission target) {
480             if (target == null)
481                 return null;
482
483             if (!VerifyType(target))
484                 throw new ArgumentException(Environment.GetResourceString("Argument_WrongType", this.GetType().FullName));
485
486             KeyContainerPermission operand = (KeyContainerPermission) target;
487             if (this.IsEmpty() || operand.IsEmpty())
488                 return null;
489
490             KeyContainerPermissionFlags flags_intersect = operand.m_flags & this.m_flags;
491             KeyContainerPermission cp = new KeyContainerPermission(flags_intersect);
492             foreach (KeyContainerPermissionAccessEntry accessEntry in AccessEntries) {
493                 cp.AddAccessEntryAndIntersect(accessEntry, operand);
494             }
495             foreach (KeyContainerPermissionAccessEntry accessEntry in operand.AccessEntries) {
496                 cp.AddAccessEntryAndIntersect(accessEntry, this);
497             }
498             return cp.IsEmpty() ? null : cp;
499         }
500
501         public override IPermission Union (IPermission target) {
502             if (target == null)
503                 return this.Copy();
504
505             if (!VerifyType(target))
506                 throw new ArgumentException(Environment.GetResourceString("Argument_WrongType", this.GetType().FullName));            
507
508             KeyContainerPermission operand = (KeyContainerPermission) target;    
509             if (this.IsUnrestricted() || operand.IsUnrestricted())
510                 return new KeyContainerPermission(PermissionState.Unrestricted);
511
512             KeyContainerPermissionFlags flags_union = (KeyContainerPermissionFlags) (m_flags | operand.m_flags);
513             KeyContainerPermission cp = new KeyContainerPermission(flags_union);
514             foreach (KeyContainerPermissionAccessEntry accessEntry in AccessEntries) {
515                 cp.AddAccessEntryAndUnion(accessEntry, operand);
516             }
517             foreach (KeyContainerPermissionAccessEntry accessEntry in operand.AccessEntries) {
518                 cp.AddAccessEntryAndUnion(accessEntry, this);
519             }
520             return cp.IsEmpty() ? null : cp;
521         }
522
523         public override IPermission Copy () {
524             if (this.IsEmpty())
525                 return null;
526
527             KeyContainerPermission cp = new KeyContainerPermission((KeyContainerPermissionFlags)m_flags);
528             foreach (KeyContainerPermissionAccessEntry accessEntry in AccessEntries) {
529                 cp.AccessEntries.Add(accessEntry);
530             }
531             return cp;
532         }
533
534 #if FEATURE_CAS_POLICY
535         public override SecurityElement ToXml () {
536             SecurityElement securityElement = CodeAccessPermission.CreatePermissionElement(this, "System.Security.Permissions.KeyContainerPermission");
537             if (!IsUnrestricted()) {
538                 securityElement.AddAttribute("Flags", m_flags.ToString());
539                 if (AccessEntries.Count > 0) {
540                     SecurityElement al = new SecurityElement("AccessList");
541                     foreach (KeyContainerPermissionAccessEntry accessEntry in AccessEntries) {
542                         SecurityElement entryElem = new SecurityElement("AccessEntry");
543                         entryElem.AddAttribute("KeyStore", accessEntry.KeyStore);
544                         entryElem.AddAttribute("ProviderName", accessEntry.ProviderName);
545                         entryElem.AddAttribute("ProviderType", accessEntry.ProviderType.ToString(null, null));
546                         entryElem.AddAttribute("KeyContainerName", accessEntry.KeyContainerName);
547                         entryElem.AddAttribute("KeySpec", accessEntry.KeySpec.ToString(null, null));
548                         entryElem.AddAttribute("Flags", accessEntry.Flags.ToString());
549                         al.AddChild(entryElem);
550                     }
551                     securityElement.AddChild(al);
552                 }
553             } else 
554                 securityElement.AddAttribute("Unrestricted", "true");
555
556             return securityElement;
557         }
558
559         public override void FromXml (SecurityElement securityElement) {
560             CodeAccessPermission.ValidateElement(securityElement, this);
561             if (XMLUtil.IsUnrestricted(securityElement)) {
562                 m_flags = KeyContainerPermissionFlags.AllFlags;
563                 m_accessEntries = new KeyContainerPermissionAccessEntryCollection(m_flags);
564                 return;
565             }
566
567             m_flags = KeyContainerPermissionFlags.NoFlags;
568             string strFlags = securityElement.Attribute("Flags");
569             if (strFlags != null) {
570                 KeyContainerPermissionFlags flags = (KeyContainerPermissionFlags) Enum.Parse(typeof(KeyContainerPermissionFlags), strFlags);
571                 VerifyFlags(flags);
572                 m_flags = flags;
573             }
574             m_accessEntries = new KeyContainerPermissionAccessEntryCollection(m_flags);
575
576             if (securityElement.InternalChildren != null && securityElement.InternalChildren.Count != 0) { 
577                 IEnumerator enumerator = securityElement.Children.GetEnumerator();
578                 while (enumerator.MoveNext()) {
579                     SecurityElement current = (SecurityElement) enumerator.Current;
580                     if (current != null) {
581                         if (String.Equals(current.Tag, "AccessList"))
582                             AddAccessEntries(current);
583                     }
584                 }
585             }
586         }
587 #endif // FEATURE_CAS_POLICY
588
589         /// <internalonly/>
590         int IBuiltInPermission.GetTokenIndex () {
591             return KeyContainerPermission.GetTokenIndex();
592         }
593
594         //
595         // private methods
596         //
597
598         private void AddAccessEntries(SecurityElement securityElement) {
599             if (securityElement.InternalChildren != null && securityElement.InternalChildren.Count != 0) {
600                 IEnumerator elemEnumerator = securityElement.Children.GetEnumerator();
601                 while (elemEnumerator.MoveNext()) {
602                     SecurityElement current = (SecurityElement) elemEnumerator.Current;
603                     if (current != null) {
604                         if (String.Equals(current.Tag, "AccessEntry")) {
605                             int iMax = current.m_lAttributes.Count;
606                             Contract.Assert(iMax % 2 == 0, "Odd number of strings means the attr/value pairs were not added correctly");
607                             string keyStore = null;
608                             string providerName = null;
609                             int providerType = -1;
610                             string keyContainerName = null;
611                             int keySpec = -1;
612                             KeyContainerPermissionFlags flags = KeyContainerPermissionFlags.NoFlags;
613                             for (int i = 0; i < iMax; i += 2) {
614                                 String strAttrName = (String) current.m_lAttributes[i];
615                                 String strAttrValue = (String) current.m_lAttributes[i+1]; 
616                                 if (String.Equals(strAttrName, "KeyStore"))
617                                     keyStore = strAttrValue;
618                                 if (String.Equals(strAttrName, "ProviderName"))
619                                     providerName = strAttrValue;
620                                 else if (String.Equals(strAttrName, "ProviderType"))
621                                     providerType = Convert.ToInt32(strAttrValue, null);
622                                 else if (String.Equals(strAttrName, "KeyContainerName"))
623                                     keyContainerName = strAttrValue;
624                                 else if (String.Equals(strAttrName, "KeySpec"))
625                                     keySpec = Convert.ToInt32(strAttrValue, null);
626                                 else if (String.Equals(strAttrName, "Flags")) {
627                                     flags = (KeyContainerPermissionFlags) Enum.Parse(typeof(KeyContainerPermissionFlags), strAttrValue);
628                                 }
629                             }
630                             KeyContainerPermissionAccessEntry accessEntry = new KeyContainerPermissionAccessEntry(keyStore, providerName, providerType, keyContainerName, keySpec, flags);
631                             AccessEntries.Add(accessEntry);
632                         }
633                     }
634                 }
635             }
636         }
637
638         private void AddAccessEntryAndUnion (KeyContainerPermissionAccessEntry accessEntry, KeyContainerPermission target) {
639             KeyContainerPermissionAccessEntry newAccessEntry = new KeyContainerPermissionAccessEntry(accessEntry);
640             newAccessEntry.Flags |= GetApplicableFlags(accessEntry, target);
641             AccessEntries.Add(newAccessEntry);
642         }
643
644         private void AddAccessEntryAndIntersect (KeyContainerPermissionAccessEntry accessEntry, KeyContainerPermission target) {
645             KeyContainerPermissionAccessEntry newAccessEntry = new KeyContainerPermissionAccessEntry(accessEntry);
646             newAccessEntry.Flags &= GetApplicableFlags(accessEntry, target);
647             AccessEntries.Add(newAccessEntry);
648         }
649
650         //
651         // private/internal static methods.
652         //
653
654         internal static void VerifyFlags (KeyContainerPermissionFlags flags) {
655             if ((flags & ~KeyContainerPermissionFlags.AllFlags) != 0)
656                 throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)flags));
657             Contract.EndContractBlock();
658         }
659
660         private static KeyContainerPermissionFlags GetApplicableFlags (KeyContainerPermissionAccessEntry accessEntry, KeyContainerPermission target) {
661             KeyContainerPermissionFlags flags = KeyContainerPermissionFlags.NoFlags;
662             bool applyDefaultFlags = true;
663
664             // If the entry exists in the target, return the flag of the target entry.
665             int index = target.AccessEntries.IndexOf(accessEntry);
666             if (index != -1) {
667                 flags = ((KeyContainerPermissionAccessEntry)target.AccessEntries[index]).Flags;
668                 return flags;
669             }
670
671             // Intersect the flags in all the target entries that apply to the current access entry, 
672             foreach (KeyContainerPermissionAccessEntry targetAccessEntry in target.AccessEntries) {
673                 if (accessEntry.IsSubsetOf(targetAccessEntry)) {
674                     if (applyDefaultFlags == false) {
675                         flags &= targetAccessEntry.Flags;
676                     } else {
677                         flags = targetAccessEntry.Flags;
678                         applyDefaultFlags = false;
679                     }
680                 }
681             }
682
683             // If no target entry applies to the current entry, the default global flag applies.
684             if (applyDefaultFlags)
685                 flags = target.Flags;
686
687             return flags;
688         }
689
690         private static int GetTokenIndex() {
691             return BuiltInPermissionIndex.KeyContainerPermissionIndex;
692         }
693     }
694
695 #endif // !FEATURE_PAL
696 }