3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 // <OWNER>Microsoft</OWNER>
10 using System
.Collections
;
11 using System
.Collections
.Generic
;
12 using System
.Diagnostics
.Contracts
;
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
23 /// Base class from which all objects to be used as Evidence must derive
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
38 if (!GetType().IsSerializable
)
40 throw new InvalidOperationException(Environment
.GetResourceString("Policy_EvidenceMustBeSerializable"));
42 #endif // FEATURE_SERIALIZATION
46 /// Since legacy evidence objects would be cloned by being serialized, the default implementation
47 /// of EvidenceBase will do the same.
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
72 /// Interface for types which wrap Whidbey evidence objects for compatibility with v4 evidence rules
74 internal interface ILegacyEvidenceAdapter
76 object EvidenceObject { get; }
77 Type EvidenceType { get; }
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
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()
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.
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.
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()