By Matthew Lyons
IN THIS CHAPTER
Different Sources of Evidence
Evidence and the Base Class Library
As explained in Chapter 4, "
This chapter will cover:
What evidence is and how it is assigned to code
Different sources of evidence
Evidence classes used in the .NET Framework base class library
Evidence provides the basic building blocks for how code access security can work on .NET Framework code. An example of evidence about code is its SHA1 hash value.
This value is a
For more information on cryptographic hash values, see Chapter 30, "Using Cryptography with the .NET Framework: The Basics."
There are two key points to remember about evidence:
Evidence applies to executing code itself, not the
Evidence is applied to the granularity of assemblies and application domains.
Application domains will be mentioned several times in this book. They are also referred to as app domains.
Evidence is a collection of information that is gathered about
executing code, regardless of who is running it. Figure 5.1 shows
an example of this. Given two users, Alice and Bob, running
assembly X, the security engine (that is, the part of the CLR that
In a way, you can look at different .NET applications as different users, where evidence is the set of credentials for an application. This analogy doesn't work for all pieces of .NET Framework security, but it will help you understand the role of evidence. Evidence is how .NET Framework security differentiates one piece of code from another.
Another important piece of information regarding evidence is
that it only applies to code that is executing. The .NET Framework
will not precompute or cache evidence for code that is not
executing. Evidence is dynamically calculated and applied when code
is running. In fact, some evidence is impossible to know before
code executes. For example, the URL of origin for an executing
So far, I have made the assertion that evidence is applied to running code. However, "running code" is a general concept. To be more specific about this concept, we have to understand the building blocks of a process in the .NET Framework.
In the .NET Framework, app domains are
An assembly is a
In the .NET Framework, an assembly is referenced by using the
class. Assemblies can be loaded
directly from the file system or the Global Assembly Cache.
Assemblies loaded from the global cache are shared across all
applications using the .NET Framework. Assemblies provided by the
.NET Framework SDK will generally be located in the global cache,
while assemblies for individual applications will
Because evidence is not precomputed by the .NET Framework, you cannot know exactly what evidence will be associated with an assembly you write. However, you can examine the evidence associated with an assembly at the time of execution by using the System.Reflection.Assembly.Evidence property. To obtain the evidence of an executing assembly, simply utilize the following code:
System.Security.Policy.Evidence ev = System.Reflection.Assembly. GetExecutingAssembly(). Evidence;
Essentially, application domains provide in-process isolation of executing code. All .NET Framework code must run in some app domain. While it isn't obvious by running a simple "Hello World" application, a default app domain is created for every .NET Framework process. If no other app domains are created, all code runs in the default domain.
The same assembly can be loaded into multiple app domains at the
same time. When this happens, the compiled code in memory can be
shared to reduce the working set. However, static data is not
shared between app domains. If it were shared, this would mean a
breakdown in the isolation that app domains are
App domains use the System.AppDomain class to represent them to managed code. The AppDomain class has an identical property as the Assembly class for handling evidence. To obtain evidence on the current AppDomain , you can use the following code:
System.Security.Policy.Evidence ev = System.AppDomain.CurrentDomain.Evidence;
App domains are particularly
Loading assemblies that you want to unload at a later time. (In fact, the only way to unload an assembly is to unload the app domain containing that assembly.)
Providing fewer rights than provided by default policy to less-trusted assemblies. (App domain policy is discussed in Chapter 8, "Membership Conditions, Code Groups, and Policy Levels: The Brick and Mortar of Security Policy.")
Running several tasks that should be isolated from each other without using multiple processes.