Updates referencesource to .NET 4.7
[mono-project.git] / mcs / class / referencesource / mscorlib / system / security / policy / evidencebase.cs
blob30a8fbee73529c07aa8852b042e17665ce580e97
1 // ==++==
2 //
3 // Copyright (c) Microsoft Corporation. All rights reserved.
4 //
5 // ==--==
6 // <OWNER>Microsoft</OWNER>
7 //
9 using System;
10 using System.Collections;
11 using System.Collections.Generic;
12 using System.Diagnostics.Contracts;
13 using System.IO;
14 using System.Runtime.InteropServices;
15 #if FEATURE_SERIALIZATION
16 using System.Runtime.Serialization.Formatters.Binary;
17 #endif // FEATURE_SERIALIZATION
18 using System.Security.Permissions;
20 namespace System.Security.Policy
22 /// <summary>
23 /// Base class from which all objects to be used as Evidence must derive
24 /// </summary>
25 [ComVisible(true)]
26 [Serializable]
27 #pragma warning disable 618
28 [PermissionSet(SecurityAction.InheritanceDemand, Unrestricted = true)]
29 #pragma warning restore 618
30 public abstract class EvidenceBase
32 protected EvidenceBase()
34 #if FEATURE_SERIALIZATION
35 // All objects to be used as evidence must be serializable. Make sure that any derived types
36 // are marked serializable to enforce this, since the attribute does not inherit down to derived
37 // classes.
38 if (!GetType().IsSerializable)
40 throw new InvalidOperationException(Environment.GetResourceString("Policy_EvidenceMustBeSerializable"));
42 #endif // FEATURE_SERIALIZATION
45 /// <remarks>
46 /// Since legacy evidence objects would be cloned by being serialized, the default implementation
47 /// of EvidenceBase will do the same.
48 /// </remarks>
49 #pragma warning disable 618
50 [SecurityPermission(SecurityAction.Assert, SerializationFormatter = true)]
51 [PermissionSet(SecurityAction.InheritanceDemand, Unrestricted = true)]
52 #pragma warning restore 618
53 [SecuritySafeCritical]
54 public virtual EvidenceBase Clone()
56 #if FEATURE_SERIALIZATION
57 using (MemoryStream memoryStream = new MemoryStream())
59 BinaryFormatter formatter = new BinaryFormatter();
60 formatter.Serialize(memoryStream, this);
62 memoryStream.Position = 0;
63 return formatter.Deserialize(memoryStream) as EvidenceBase;
65 #else // !FEATURE_SERIALIZATION
66 throw new NotImplementedException();
67 #endif // FEATURE_SERIALIZATION
71 /// <summary>
72 /// Interface for types which wrap Whidbey evidence objects for compatibility with v4 evidence rules
73 /// </summary>
74 internal interface ILegacyEvidenceAdapter
76 object EvidenceObject { get; }
77 Type EvidenceType { get; }
80 /// <summary>
81 /// Wrapper class to hold legacy evidence objects which do not derive from EvidenceBase, and allow
82 /// them to be held in the Evidence collection which expects to maintain lists of EvidenceBase only
83 /// </summary>
84 [Serializable]
85 internal sealed class LegacyEvidenceWrapper : EvidenceBase, ILegacyEvidenceAdapter
87 private object m_legacyEvidence;
89 internal LegacyEvidenceWrapper(object legacyEvidence)
91 Contract.Assert(legacyEvidence != null);
92 Contract.Assert(legacyEvidence.GetType() != typeof(EvidenceBase), "Attempt to wrap an EvidenceBase in a LegacyEvidenceWrapper");
93 Contract.Assert(legacyEvidence.GetType().IsSerializable, "legacyEvidence.GetType().IsSerializable");
95 m_legacyEvidence = legacyEvidence;
98 public object EvidenceObject
100 get { return m_legacyEvidence; }
103 public Type EvidenceType
105 get { return m_legacyEvidence.GetType(); }
108 public override bool Equals(object obj)
110 return m_legacyEvidence.Equals(obj);
113 public override int GetHashCode()
115 return m_legacyEvidence.GetHashCode();
118 #pragma warning disable 618
119 [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
120 #pragma warning restore 618
121 [SecuritySafeCritical]
122 public override EvidenceBase Clone()
124 return base.Clone();
128 /// <summary>
129 /// Pre-v4 versions of the runtime allow multiple pieces of evidence that all have the same type.
130 /// This type wraps those evidence objects into a single type of list, allowing legacy code to continue
131 /// to work with the Evidence collection that does not expect multiple evidences of the same type.
132 ///
133 /// This may not be limited to LegacyEvidenceWrappers, since it's valid for legacy code to add multiple
134 /// objects of built-in evidence to an Evidence collection. The built-in evidence now derives from
135 /// EvienceObject, so when the legacy code runs on v4, it may end up attempting to add multiple
136 /// Hash evidences for intsance.
137 /// </summary>
138 [Serializable]
139 internal sealed class LegacyEvidenceList : EvidenceBase, IEnumerable<EvidenceBase>, ILegacyEvidenceAdapter
141 private List<EvidenceBase> m_legacyEvidenceList = new List<EvidenceBase>();
143 public object EvidenceObject
147 // We'll choose the first item in the list to represent us if we're forced to return only
148 // one object. This can occur if multiple pieces of evidence are added via the legacy APIs,
149 // and then the new APIs are used to retrieve that evidence.
150 return m_legacyEvidenceList.Count > 0 ? m_legacyEvidenceList[0] : null;
154 public Type EvidenceType
158 Contract.Assert(m_legacyEvidenceList.Count > 0, "No items in LegacyEvidenceList, cannot tell what type they are");
160 ILegacyEvidenceAdapter adapter = m_legacyEvidenceList[0] as ILegacyEvidenceAdapter;
161 return adapter == null ? m_legacyEvidenceList[0].GetType() : adapter.EvidenceType;
165 public void Add(EvidenceBase evidence)
167 Contract.Assert(evidence != null);
168 Contract.Assert(m_legacyEvidenceList.Count == 0 || EvidenceType == evidence.GetType() || (evidence is LegacyEvidenceWrapper && (evidence as LegacyEvidenceWrapper).EvidenceType == EvidenceType),
169 "LegacyEvidenceList must be homogeonous");
170 Contract.Assert(evidence.GetType() != typeof(LegacyEvidenceList),
171 "Attempt to add a legacy evidence list to another legacy evidence list");
173 m_legacyEvidenceList.Add(evidence);
176 public IEnumerator<EvidenceBase> GetEnumerator()
178 return m_legacyEvidenceList.GetEnumerator();
181 IEnumerator System.Collections.IEnumerable.GetEnumerator()
183 return m_legacyEvidenceList.GetEnumerator();
186 #pragma warning disable 618
187 [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
188 #pragma warning restore 618
189 [SecuritySafeCritical]
190 public override EvidenceBase Clone()
192 return base.Clone();