Some types of evidence are inherent in the structure and content of an assembly, such as the assembly strong name, the hash value of the assembly's content, or the publisher certificate used to sign the assembly. Other types of evidence are determined at runtime, based on characteristics such as the web site or URL from where the assembly is loaded.
The combined set of evidence establishes an identity for the assembly. When the runtime loads an assembly, it compares the assembly's identity with the rules defined in the security policy to determine the permissions to grant to the assembly, called the grant set. The grant set defines the operations that the code contained in the assembly can perform. We discuss permissions in Chapter 7 and security policy in Chapter 8.
Application domains also have an identity based on evidence. As with assemblies, the runtime uses evidence and security policy to determine the application domain's grant set. The grant set of an application domain has an important but indirect effect on the operations and resources accessible to all of the assemblies running in it, which we discuss in Chapter 7.
6.1.1 Sources and Types of Evidence
There are two types of evidence: host evidence and assembly evidence. When the runtime loads an assembly, it instantiates objects to represent each piece of evidence and associates the set of objects with the assembly as host evidence. An assembly can contain additional evidence, embedded at build time. As the runtime loads the assembly, it extracts this additional evidence and associates it with the assembly as assembly evidence.
The purpose of both types of evidence is to give the assembly an identity, which the runtime uses to determine the permissions to grant to it. However, the default behavior of the .NET runtime is to ignore assembly evidence; only through the implementation of CAS extensions can you enable assembly evidence to drive the policy resolution process. We demonstrate how to enable assembly evidence in Section 6.3.
Figure 6-1 shows the key characteristics found in an assembly characteristics and how the runtime uses each to create either host and assembly evidence. The following two sections discuss the nature and purpose of host and assembly evidence in more detail.
Figure 6-1. Sources and destinations of evidence
22.214.171.124 Host evidence
The host, in conjunction with the assembly loader component of the CLR, provides the host evidence for an assembly; the host could be one of the standard .NET runtime hosts (command shell, Internet Explorer, or ASP.NET), a custom runtime host, or a trusted piece of managed code that explicitly loads an assembly at runtime. The assembly loader provides a default set of evidence, but evidence provided by the host takes precedence if it conflicts with the default evidence.
A host's ability to provide and override evidence is extremely powerful; essentially the host can give any identity to an assembly. With this ability, malicious code could manipulate the evidence of the assemblies it loads in order to make the runtime assign them artificially high levels of trust. Therefore, .NET protects the ability to provide host evidence with the ControlEvidence permission an element of the System.Security.Permissions.SecurityPermission permission, which we discuss in Chapter 7.
A class in the System.Security.Policy namespace represents each of the seven standard types of host evidence that the .NET Framework supports. Not every loaded assembly has all types of evidence; an assembly's evidence depends on both its characteristics and the characteristics of the host that loaded it. Table 6-1 lists the standard evidence types. We take a detailed look at each evidence class later in Section 6.2.3.
In addition to the classes listed in Table 6-1, custom hosts and managed code that dynamically load assemblies can provide any type of object as host evidence; but unless you extend the policy resolution mechanism to understand the custom evidence classes, the runtime will ignore them. We demonstrate the creation of custom evidence in Section 6.3.
126.96.36.199 Assembly evidence
The purpose of assembly evidence is to allow you to serialize custom evidence objects and embed them into your assembly at build time. When the runtime loads your assembly, it extracts and deserializes the embedded objects and assigns them to your assembly as assembly evidence.
You are free to use assembly evidence to represent any additional assembly characteristics you require; the example we use later in "Extending the .NET Framework" identifies the programmer who created the assembly.
As we mentioned earlier, the default configuration of the .NET Framework is to ignore assembly evidence. With some customization of CAS, assembly evidence can affect the resolution of code-access permissions in the same way as the standard evidence classes. However, the runtime never grants identity permissions to your assembly based on assembly evidence; only host evidence results in the granting of identity permissions. This does limit the usefulness of assembly evidence, but is necessary to stop malicious code from manipulating CAS and granting itself identity permissions in an attempt to increase its level of trust. We discuss code-access and identity permissions more in Chapter 7.