summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/Security/Permissions/keycontainerpermission.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/src/System/Security/Permissions/keycontainerpermission.cs')
-rw-r--r--src/mscorlib/src/System/Security/Permissions/keycontainerpermission.cs688
1 files changed, 688 insertions, 0 deletions
diff --git a/src/mscorlib/src/System/Security/Permissions/keycontainerpermission.cs b/src/mscorlib/src/System/Security/Permissions/keycontainerpermission.cs
new file mode 100644
index 0000000000..9691c03da3
--- /dev/null
+++ b/src/mscorlib/src/System/Security/Permissions/keycontainerpermission.cs
@@ -0,0 +1,688 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Security.Permissions {
+ using System;
+ using System.Collections;
+ using System.Collections.Generic;
+#if FEATURE_CRYPTO
+ using System.Security.Cryptography;
+#endif
+ using System.Security.Util;
+ using System.Globalization;
+ using System.Diagnostics.Contracts;
+
+[Serializable]
+ [Flags]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public enum KeyContainerPermissionFlags {
+ NoFlags = 0x0000,
+
+ Create = 0x0001,
+ Open = 0x0002,
+ Delete = 0x0004,
+
+ Import = 0x0010,
+ Export = 0x0020,
+
+ Sign = 0x0100,
+ Decrypt = 0x0200,
+
+ ViewAcl = 0x1000,
+ ChangeAcl = 0x2000,
+
+ AllFlags = 0x3337
+ }
+
+ [Serializable]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class KeyContainerPermissionAccessEntry {
+ private string m_keyStore;
+ private string m_providerName;
+ private int m_providerType;
+ private string m_keyContainerName;
+ private int m_keySpec;
+ private KeyContainerPermissionFlags m_flags;
+
+ internal KeyContainerPermissionAccessEntry(KeyContainerPermissionAccessEntry accessEntry) :
+ this (accessEntry.KeyStore, accessEntry.ProviderName, accessEntry.ProviderType, accessEntry.KeyContainerName,
+ accessEntry.KeySpec, accessEntry.Flags) {
+ }
+
+ public KeyContainerPermissionAccessEntry(string keyContainerName, KeyContainerPermissionFlags flags) :
+ this (null, null, -1, keyContainerName, -1, flags) {
+ }
+
+#if FEATURE_CRYPTO
+ public KeyContainerPermissionAccessEntry(CspParameters parameters, KeyContainerPermissionFlags flags) :
+ this((parameters.Flags & CspProviderFlags.UseMachineKeyStore) == CspProviderFlags.UseMachineKeyStore ? "Machine" : "User",
+ parameters.ProviderName,
+ parameters.ProviderType,
+ parameters.KeyContainerName,
+ parameters.KeyNumber,
+ flags) {
+ }
+#endif
+
+ public KeyContainerPermissionAccessEntry(string keyStore, string providerName, int providerType,
+ string keyContainerName, int keySpec, KeyContainerPermissionFlags flags) {
+ m_providerName = (providerName == null ? "*" : providerName);
+ m_providerType = providerType;
+ m_keyContainerName = (keyContainerName == null ? "*" : keyContainerName);
+ m_keySpec = keySpec;
+ KeyStore = keyStore;
+ Flags = flags;
+ }
+
+ public string KeyStore {
+ get {
+ return m_keyStore;
+ }
+ set {
+ // Unrestricted entries are invalid; they should not be allowed.
+ if (IsUnrestrictedEntry(value, this.ProviderName, this.ProviderType, this.KeyContainerName, this.KeySpec))
+ throw new ArgumentException(Environment.GetResourceString("Arg_InvalidAccessEntry"));
+
+ if (value == null) {
+ m_keyStore = "*";
+ } else {
+ if (value != "User" && value != "Machine" && value != "*")
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidKeyStore", value), "value");
+ m_keyStore = value;
+ }
+ }
+ }
+
+ public string ProviderName {
+ get {
+ return m_providerName;
+ }
+ set {
+ // Unrestricted entries are invalid; they should not be allowed.
+ if (IsUnrestrictedEntry(this.KeyStore, value, this.ProviderType, this.KeyContainerName, this.KeySpec))
+ throw new ArgumentException(Environment.GetResourceString("Arg_InvalidAccessEntry"));
+
+ if (value == null)
+ m_providerName = "*";
+ else
+ m_providerName = value;
+ }
+ }
+
+ public int ProviderType {
+ get {
+ return m_providerType;
+ }
+ set {
+ // Unrestricted entries are invalid; they should not be allowed.
+ if (IsUnrestrictedEntry(this.KeyStore, this.ProviderName, value, this.KeyContainerName, this.KeySpec))
+ throw new ArgumentException(Environment.GetResourceString("Arg_InvalidAccessEntry"));
+
+ m_providerType = value;
+ }
+ }
+
+ public string KeyContainerName {
+ get {
+ return m_keyContainerName;
+ }
+ set {
+ // Unrestricted entries are invalid; they should not be allowed.
+ if (IsUnrestrictedEntry(this.KeyStore, this.ProviderName, this.ProviderType, value, this.KeySpec))
+ throw new ArgumentException(Environment.GetResourceString("Arg_InvalidAccessEntry"));
+
+ if (value == null)
+ m_keyContainerName = "*";
+ else
+ m_keyContainerName = value;
+ }
+ }
+
+ public int KeySpec {
+ get {
+ return m_keySpec;
+ }
+ set {
+ // Unrestricted entries are invalid; they should not be allowed.
+ if (IsUnrestrictedEntry(this.KeyStore, this.ProviderName, this.ProviderType, this.KeyContainerName, value))
+ throw new ArgumentException(Environment.GetResourceString("Arg_InvalidAccessEntry"));
+
+ m_keySpec = value;
+ }
+ }
+
+ public KeyContainerPermissionFlags Flags {
+ get {
+ return m_flags;
+ }
+ set {
+ KeyContainerPermission.VerifyFlags(value);
+ m_flags = value;
+ }
+ }
+
+ public override bool Equals (Object o) {
+ KeyContainerPermissionAccessEntry accessEntry = o as KeyContainerPermissionAccessEntry;
+ if (accessEntry == null)
+ return false;
+
+ if (accessEntry.m_keyStore != m_keyStore) return false;
+ if (accessEntry.m_providerName != m_providerName) return false;
+ if (accessEntry.m_providerType != m_providerType) return false;
+ if (accessEntry.m_keyContainerName != m_keyContainerName) return false;
+ if (accessEntry.m_keySpec != m_keySpec) return false;
+
+ return true;
+ }
+
+ public override int GetHashCode () {
+ int hash = 0;
+
+ hash |= (this.m_keyStore.GetHashCode() & 0x000000FF) << 24;
+ hash |= (this.m_providerName.GetHashCode() & 0x000000FF) << 16;
+ hash |= (this.m_providerType & 0x0000000F) << 12;
+ hash |= (this.m_keyContainerName.GetHashCode() & 0x000000FF) << 4;
+ hash |= (this.m_keySpec & 0x0000000F);
+
+ return hash;
+ }
+
+ internal bool IsSubsetOf (KeyContainerPermissionAccessEntry target) {
+ if (target.m_keyStore != "*" && this.m_keyStore != target.m_keyStore)
+ return false;
+ if (target.m_providerName != "*" && this.m_providerName != target.m_providerName)
+ return false;
+ if (target.m_providerType != -1 && this.m_providerType != target.m_providerType)
+ return false;
+ if (target.m_keyContainerName != "*" && this.m_keyContainerName != target.m_keyContainerName)
+ return false;
+ if (target.m_keySpec != -1 && this.m_keySpec != target.m_keySpec)
+ return false;
+
+ return true;
+ }
+
+ internal static bool IsUnrestrictedEntry (string keyStore, string providerName, int providerType,
+ string keyContainerName, int keySpec) {
+ if (keyStore != "*" && keyStore != null) return false;
+ if (providerName != "*" && providerName != null) return false;
+ if (providerType != -1) return false;
+ if (keyContainerName != "*" && keyContainerName != null) return false;
+ if (keySpec != -1) return false;
+
+ return true;
+ }
+ }
+
+ [Serializable]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class KeyContainerPermissionAccessEntryCollection : ICollection {
+ private ArrayList m_list;
+ private KeyContainerPermissionFlags m_globalFlags;
+
+ private KeyContainerPermissionAccessEntryCollection () {}
+ internal KeyContainerPermissionAccessEntryCollection (KeyContainerPermissionFlags globalFlags) {
+ m_list = new ArrayList();
+ m_globalFlags = globalFlags;
+ }
+
+ public KeyContainerPermissionAccessEntry this[int index] {
+ get {
+ if (index < 0)
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumNotStarted"));
+ if (index >= Count)
+ throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ Contract.EndContractBlock();
+
+ return (KeyContainerPermissionAccessEntry)m_list[index];
+ }
+ }
+
+ public int Count {
+ get {
+ return m_list.Count;
+ }
+ }
+
+ public int Add (KeyContainerPermissionAccessEntry accessEntry) {
+ if (accessEntry == null)
+ throw new ArgumentNullException("accessEntry");
+ Contract.EndContractBlock();
+
+ int index = m_list.IndexOf(accessEntry);
+ if (index == -1) {
+ if (accessEntry.Flags != m_globalFlags) {
+ return m_list.Add(accessEntry);
+ }
+ else
+ return -1;
+ } else {
+ // We pick up the intersection of the 2 flags. This is the secure choice
+ // so we are opting for it.
+ ((KeyContainerPermissionAccessEntry)m_list[index]).Flags &= accessEntry.Flags;
+ return index;
+ }
+ }
+
+ public void Clear () {
+ m_list.Clear();
+ }
+
+ public int IndexOf (KeyContainerPermissionAccessEntry accessEntry) {
+ return m_list.IndexOf(accessEntry);
+ }
+
+ public void Remove (KeyContainerPermissionAccessEntry accessEntry) {
+ if (accessEntry == null)
+ throw new ArgumentNullException("accessEntry");
+ Contract.EndContractBlock();
+ m_list.Remove(accessEntry);
+ }
+
+ public KeyContainerPermissionAccessEntryEnumerator GetEnumerator () {
+ return new KeyContainerPermissionAccessEntryEnumerator(this);
+ }
+
+ /// <internalonly/>
+ IEnumerator IEnumerable.GetEnumerator () {
+ return new KeyContainerPermissionAccessEntryEnumerator(this);
+ }
+
+ /// <internalonly/>
+ void ICollection.CopyTo (Array array, int index) {
+ if (array == null)
+ throw new ArgumentNullException("array");
+ if (array.Rank != 1)
+ throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
+ if (index < 0 || index >= array.Length)
+ throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ if (index + this.Count > array.Length)
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
+ Contract.EndContractBlock();
+
+ for (int i=0; i < this.Count; i++) {
+ array.SetValue(this[i], index);
+ index++;
+ }
+ }
+
+ public void CopyTo (KeyContainerPermissionAccessEntry[] array, int index) {
+ ((ICollection)this).CopyTo(array, index);
+ }
+
+ public bool IsSynchronized {
+ get {
+ return false;
+ }
+ }
+
+ public Object SyncRoot {
+ get {
+ return this;
+ }
+ }
+ }
+
+ [Serializable]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class KeyContainerPermissionAccessEntryEnumerator : IEnumerator {
+ private KeyContainerPermissionAccessEntryCollection m_entries;
+ private int m_current;
+
+ private KeyContainerPermissionAccessEntryEnumerator () {}
+ internal KeyContainerPermissionAccessEntryEnumerator (KeyContainerPermissionAccessEntryCollection entries) {
+ m_entries = entries;
+ m_current = -1;
+ }
+
+ public KeyContainerPermissionAccessEntry Current {
+ get {
+ return m_entries[m_current];
+ }
+ }
+
+ /// <internalonly/>
+ Object IEnumerator.Current {
+ get {
+ return (Object) m_entries[m_current];
+ }
+ }
+
+ public bool MoveNext() {
+ if (m_current == ((int) m_entries.Count - 1))
+ return false;
+ m_current++;
+ return true;
+ }
+
+ public void Reset() {
+ m_current = -1;
+ }
+ }
+
+ [Serializable]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class KeyContainerPermission : CodeAccessPermission, IUnrestrictedPermission, IBuiltInPermission {
+ private KeyContainerPermissionFlags m_flags;
+ private KeyContainerPermissionAccessEntryCollection m_accessEntries;
+
+ public KeyContainerPermission (PermissionState state) {
+ if (state == PermissionState.Unrestricted)
+ m_flags = KeyContainerPermissionFlags.AllFlags;
+ else if (state == PermissionState.None)
+ m_flags = KeyContainerPermissionFlags.NoFlags;
+ else
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidPermissionState"));
+ m_accessEntries = new KeyContainerPermissionAccessEntryCollection(m_flags);
+ }
+
+ public KeyContainerPermission (KeyContainerPermissionFlags flags) {
+ VerifyFlags(flags);
+ m_flags = flags;
+ m_accessEntries = new KeyContainerPermissionAccessEntryCollection(m_flags);
+ }
+
+ public KeyContainerPermission (KeyContainerPermissionFlags flags, KeyContainerPermissionAccessEntry[] accessList) {
+ if (accessList == null)
+ throw new ArgumentNullException("accessList");
+ Contract.EndContractBlock();
+
+ VerifyFlags(flags);
+ m_flags = flags;
+ m_accessEntries = new KeyContainerPermissionAccessEntryCollection(m_flags);
+ for (int index = 0; index < accessList.Length; index++) {
+ m_accessEntries.Add(accessList[index]);
+ }
+ }
+
+ public KeyContainerPermissionFlags Flags {
+ get {
+ return m_flags;
+ }
+ }
+
+ public KeyContainerPermissionAccessEntryCollection AccessEntries {
+ get {
+ return m_accessEntries;
+ }
+ }
+
+ public bool IsUnrestricted () {
+ if (m_flags != KeyContainerPermissionFlags.AllFlags)
+ return false;
+
+ foreach (KeyContainerPermissionAccessEntry accessEntry in AccessEntries) {
+ if ((accessEntry.Flags & KeyContainerPermissionFlags.AllFlags) != KeyContainerPermissionFlags.AllFlags)
+ return false;
+ }
+
+ return true;
+ }
+
+ private bool IsEmpty () {
+ if (this.Flags == KeyContainerPermissionFlags.NoFlags) {
+ foreach (KeyContainerPermissionAccessEntry accessEntry in AccessEntries) {
+ if (accessEntry.Flags != KeyContainerPermissionFlags.NoFlags)
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ //
+ // IPermission implementation
+ //
+
+ public override bool IsSubsetOf (IPermission target) {
+ if (target == null)
+ return IsEmpty();
+
+ if (!VerifyType(target))
+ throw new ArgumentException(Environment.GetResourceString("Argument_WrongType", this.GetType().FullName));
+
+ KeyContainerPermission operand = (KeyContainerPermission) target;
+
+ // since there are containers that are neither in the access list of the source, nor in the
+ // access list of the target, the source flags must be a subset of the target flags.
+ if ((this.m_flags & operand.m_flags) != this.m_flags)
+ return false;
+
+ // Any entry in the source should have "applicable" flags in the destination that actually
+ // are less restrictive than the flags in the source.
+
+ foreach (KeyContainerPermissionAccessEntry accessEntry in AccessEntries) {
+ KeyContainerPermissionFlags targetFlags = GetApplicableFlags(accessEntry, operand);
+ if ((accessEntry.Flags & targetFlags) != accessEntry.Flags)
+ return false;
+ }
+
+ // Any entry in the target should have "applicable" flags in the source that actually
+ // are more restrictive than the flags in the target.
+
+ foreach (KeyContainerPermissionAccessEntry accessEntry in operand.AccessEntries) {
+ KeyContainerPermissionFlags sourceFlags = GetApplicableFlags(accessEntry, this);
+ if ((sourceFlags & accessEntry.Flags) != sourceFlags)
+ return false;
+ }
+
+ return true;
+ }
+
+ public override IPermission Intersect (IPermission target) {
+ if (target == null)
+ return null;
+
+ if (!VerifyType(target))
+ throw new ArgumentException(Environment.GetResourceString("Argument_WrongType", this.GetType().FullName));
+
+ KeyContainerPermission operand = (KeyContainerPermission) target;
+ if (this.IsEmpty() || operand.IsEmpty())
+ return null;
+
+ KeyContainerPermissionFlags flags_intersect = operand.m_flags & this.m_flags;
+ KeyContainerPermission cp = new KeyContainerPermission(flags_intersect);
+ foreach (KeyContainerPermissionAccessEntry accessEntry in AccessEntries) {
+ cp.AddAccessEntryAndIntersect(accessEntry, operand);
+ }
+ foreach (KeyContainerPermissionAccessEntry accessEntry in operand.AccessEntries) {
+ cp.AddAccessEntryAndIntersect(accessEntry, this);
+ }
+ return cp.IsEmpty() ? null : cp;
+ }
+
+ public override IPermission Union (IPermission target) {
+ if (target == null)
+ return this.Copy();
+
+ if (!VerifyType(target))
+ throw new ArgumentException(Environment.GetResourceString("Argument_WrongType", this.GetType().FullName));
+
+ KeyContainerPermission operand = (KeyContainerPermission) target;
+ if (this.IsUnrestricted() || operand.IsUnrestricted())
+ return new KeyContainerPermission(PermissionState.Unrestricted);
+
+ KeyContainerPermissionFlags flags_union = (KeyContainerPermissionFlags) (m_flags | operand.m_flags);
+ KeyContainerPermission cp = new KeyContainerPermission(flags_union);
+ foreach (KeyContainerPermissionAccessEntry accessEntry in AccessEntries) {
+ cp.AddAccessEntryAndUnion(accessEntry, operand);
+ }
+ foreach (KeyContainerPermissionAccessEntry accessEntry in operand.AccessEntries) {
+ cp.AddAccessEntryAndUnion(accessEntry, this);
+ }
+ return cp.IsEmpty() ? null : cp;
+ }
+
+ public override IPermission Copy () {
+ if (this.IsEmpty())
+ return null;
+
+ KeyContainerPermission cp = new KeyContainerPermission((KeyContainerPermissionFlags)m_flags);
+ foreach (KeyContainerPermissionAccessEntry accessEntry in AccessEntries) {
+ cp.AccessEntries.Add(accessEntry);
+ }
+ return cp;
+ }
+
+#if FEATURE_CAS_POLICY
+ public override SecurityElement ToXml () {
+ SecurityElement securityElement = CodeAccessPermission.CreatePermissionElement(this, "System.Security.Permissions.KeyContainerPermission");
+ if (!IsUnrestricted()) {
+ securityElement.AddAttribute("Flags", m_flags.ToString());
+ if (AccessEntries.Count > 0) {
+ SecurityElement al = new SecurityElement("AccessList");
+ foreach (KeyContainerPermissionAccessEntry accessEntry in AccessEntries) {
+ SecurityElement entryElem = new SecurityElement("AccessEntry");
+ entryElem.AddAttribute("KeyStore", accessEntry.KeyStore);
+ entryElem.AddAttribute("ProviderName", accessEntry.ProviderName);
+ entryElem.AddAttribute("ProviderType", accessEntry.ProviderType.ToString(null, null));
+ entryElem.AddAttribute("KeyContainerName", accessEntry.KeyContainerName);
+ entryElem.AddAttribute("KeySpec", accessEntry.KeySpec.ToString(null, null));
+ entryElem.AddAttribute("Flags", accessEntry.Flags.ToString());
+ al.AddChild(entryElem);
+ }
+ securityElement.AddChild(al);
+ }
+ } else
+ securityElement.AddAttribute("Unrestricted", "true");
+
+ return securityElement;
+ }
+
+ public override void FromXml (SecurityElement securityElement) {
+ CodeAccessPermission.ValidateElement(securityElement, this);
+ if (XMLUtil.IsUnrestricted(securityElement)) {
+ m_flags = KeyContainerPermissionFlags.AllFlags;
+ m_accessEntries = new KeyContainerPermissionAccessEntryCollection(m_flags);
+ return;
+ }
+
+ m_flags = KeyContainerPermissionFlags.NoFlags;
+ string strFlags = securityElement.Attribute("Flags");
+ if (strFlags != null) {
+ KeyContainerPermissionFlags flags = (KeyContainerPermissionFlags) Enum.Parse(typeof(KeyContainerPermissionFlags), strFlags);
+ VerifyFlags(flags);
+ m_flags = flags;
+ }
+ m_accessEntries = new KeyContainerPermissionAccessEntryCollection(m_flags);
+
+ if (securityElement.InternalChildren != null && securityElement.InternalChildren.Count != 0) {
+ IEnumerator enumerator = securityElement.Children.GetEnumerator();
+ while (enumerator.MoveNext()) {
+ SecurityElement current = (SecurityElement) enumerator.Current;
+ if (current != null) {
+ if (String.Equals(current.Tag, "AccessList"))
+ AddAccessEntries(current);
+ }
+ }
+ }
+ }
+#endif // FEATURE_CAS_POLICY
+
+ /// <internalonly/>
+ int IBuiltInPermission.GetTokenIndex () {
+ return KeyContainerPermission.GetTokenIndex();
+ }
+
+ //
+ // private methods
+ //
+
+ private void AddAccessEntries(SecurityElement securityElement) {
+ if (securityElement.InternalChildren != null && securityElement.InternalChildren.Count != 0) {
+ IEnumerator elemEnumerator = securityElement.Children.GetEnumerator();
+ while (elemEnumerator.MoveNext()) {
+ SecurityElement current = (SecurityElement) elemEnumerator.Current;
+ if (current != null) {
+ if (String.Equals(current.Tag, "AccessEntry")) {
+ int iMax = current.m_lAttributes.Count;
+ Contract.Assert(iMax % 2 == 0, "Odd number of strings means the attr/value pairs were not added correctly");
+ string keyStore = null;
+ string providerName = null;
+ int providerType = -1;
+ string keyContainerName = null;
+ int keySpec = -1;
+ KeyContainerPermissionFlags flags = KeyContainerPermissionFlags.NoFlags;
+ for (int i = 0; i < iMax; i += 2) {
+ String strAttrName = (String) current.m_lAttributes[i];
+ String strAttrValue = (String) current.m_lAttributes[i+1];
+ if (String.Equals(strAttrName, "KeyStore"))
+ keyStore = strAttrValue;
+ if (String.Equals(strAttrName, "ProviderName"))
+ providerName = strAttrValue;
+ else if (String.Equals(strAttrName, "ProviderType"))
+ providerType = Convert.ToInt32(strAttrValue, null);
+ else if (String.Equals(strAttrName, "KeyContainerName"))
+ keyContainerName = strAttrValue;
+ else if (String.Equals(strAttrName, "KeySpec"))
+ keySpec = Convert.ToInt32(strAttrValue, null);
+ else if (String.Equals(strAttrName, "Flags")) {
+ flags = (KeyContainerPermissionFlags) Enum.Parse(typeof(KeyContainerPermissionFlags), strAttrValue);
+ }
+ }
+ KeyContainerPermissionAccessEntry accessEntry = new KeyContainerPermissionAccessEntry(keyStore, providerName, providerType, keyContainerName, keySpec, flags);
+ AccessEntries.Add(accessEntry);
+ }
+ }
+ }
+ }
+ }
+
+ private void AddAccessEntryAndUnion (KeyContainerPermissionAccessEntry accessEntry, KeyContainerPermission target) {
+ KeyContainerPermissionAccessEntry newAccessEntry = new KeyContainerPermissionAccessEntry(accessEntry);
+ newAccessEntry.Flags |= GetApplicableFlags(accessEntry, target);
+ AccessEntries.Add(newAccessEntry);
+ }
+
+ private void AddAccessEntryAndIntersect (KeyContainerPermissionAccessEntry accessEntry, KeyContainerPermission target) {
+ KeyContainerPermissionAccessEntry newAccessEntry = new KeyContainerPermissionAccessEntry(accessEntry);
+ newAccessEntry.Flags &= GetApplicableFlags(accessEntry, target);
+ AccessEntries.Add(newAccessEntry);
+ }
+
+ //
+ // private/internal static methods.
+ //
+
+ internal static void VerifyFlags (KeyContainerPermissionFlags flags) {
+ if ((flags & ~KeyContainerPermissionFlags.AllFlags) != 0)
+ throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)flags));
+ Contract.EndContractBlock();
+ }
+
+ private static KeyContainerPermissionFlags GetApplicableFlags (KeyContainerPermissionAccessEntry accessEntry, KeyContainerPermission target) {
+ KeyContainerPermissionFlags flags = KeyContainerPermissionFlags.NoFlags;
+ bool applyDefaultFlags = true;
+
+ // If the entry exists in the target, return the flag of the target entry.
+ int index = target.AccessEntries.IndexOf(accessEntry);
+ if (index != -1) {
+ flags = ((KeyContainerPermissionAccessEntry)target.AccessEntries[index]).Flags;
+ return flags;
+ }
+
+ // Intersect the flags in all the target entries that apply to the current access entry,
+ foreach (KeyContainerPermissionAccessEntry targetAccessEntry in target.AccessEntries) {
+ if (accessEntry.IsSubsetOf(targetAccessEntry)) {
+ if (applyDefaultFlags == false) {
+ flags &= targetAccessEntry.Flags;
+ } else {
+ flags = targetAccessEntry.Flags;
+ applyDefaultFlags = false;
+ }
+ }
+ }
+
+ // If no target entry applies to the current entry, the default global flag applies.
+ if (applyDefaultFlags)
+ flags = target.Flags;
+
+ return flags;
+ }
+
+ private static int GetTokenIndex() {
+ return BuiltInPermissionIndex.KeyContainerPermissionIndex;
+ }
+ }
+}