Today’s tip addresses how assemblies using different transparency rules (CLR v2 and CLR v4) interact with each other in the same AppDomain. Remember you can use the SecurityRulesAttribute to specify which level of security rules your assemblies adhere to. The default in .NET 4 is level 2.
There are only two cases here—a level 1 assembly calling a level 2 assembly, and a level 2 assembly calling a level 1 assembly. Let’s take them one at a time.
Level 2 Assembly Calls Level 1 Assembly
Transparency rules are not enforced across assembly boundaries under the level 1 rules, but they are under the level 2 rules. When a level 2 assembly calls a level 1 assembly, transparency violations are not enforced—that is, if level 2 transparent code calls a level 1 critical method in another assembly, the call succeeds.
Level 1 Assembly Calls Level 2 Assembly
You might think that transparency is enforced across the assembly boundary since the roles are now reversed, but the CLR acts a bit more interestingly than that. If partial-trust code from a level 1 assembly tries to call a critical method in a level 2 full-trust assembly, then the call fails. Level 1 assemblies, which use the CLR v2′s transparency semantics, have no way to interpret a public security critical method as it exists in level 2; such a concept didn’t exist back in the second version of the CLR. Because of this, the CLR goes to great lengths to make everything appear as level 1 to the calling assembly. To do this the CLR transforms the method marked SecurityCritical into a LinkDemand for FullTrust. Thus the call to a public critical method from partial trust code fails.
In the CLR v4, methods that were marked with LinkDemands for FullTrust are now marked SecurityCritical, which is a stronger enforcement mechanism because it prevents all partial-trust code and all transparent code from calling it. It is not a stretch to see that the CLR will transform the SecurityCritical annotation back into a LinkDemand for FullTrust to make everything appear as level 1 to the level 1 assembly.
This means that transparent code in a level 1 assembly can call public critical code in a level 2 assembly if the level 1 assembly is fully trusted. The rule states only that partial trust code in a level 1 assembly cannot call fully trusted security critical code in a level 2 assembly.
Furthermore, partial trust code is always security transparent and thus can never call security critical code.