<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>.NET Security Blog : SSCLI</title><link>http://blogs.msdn.com/shawnfa/archive/tags/SSCLI/default.aspx</link><description>Tags: SSCLI</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Special Permissions in the SSCLI</title><link>http://blogs.msdn.com/shawnfa/archive/2006/06/06/619126.aspx</link><pubDate>Tue, 06 Jun 2006 19:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:619126</guid><dc:creator>shawnfa</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/619126.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=619126</wfw:commentRss><description>&lt;P&gt;Before digging into a pretty clever optimization that the &lt;A HREF="/shawnfa/archive/2006/03/24/560034.aspx"&gt;SSCLI&lt;/A&gt; makes for certain special permission demands, I want to point out that everything I’m about to cover is an implementation detail. Although this optimization does occur today, we can and will change it for future versions of the CLR (and potentially service packs for the v2.0 version) … the only thing guaranteed about the behavior of a demand is that it throws a SecurityException if the call stack does not meet the required permissions; and does nothing if it does. &lt;/P&gt;
&lt;P&gt;With that being said, the v2.0 CLR has a few special permissions which it can apply a clever optimization to in order to speed up demands. If you’ve got the SSCLI v2 installed, you can see these permission defined in managed code in the PermissionType enumeration (clr\src\bcl\System\Security\CodeAccessSecurityEngine.cs) and mirrored in the VM (clr\src\VM\SecurityPolicy.h). (Look for the set of #defines starting at line 297 with SECURITY_UNMANAGED_CODE). &lt;/P&gt;
&lt;P&gt;There are two categories of these special permissions defined: &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;
&lt;DIV&gt;A flag of a permission (Assert, SkipVerification, UnmanagedCode, etc) &lt;/DIV&gt;
&lt;LI&gt;
&lt;DIV&gt;An unrestricted permission (UI, Environment, Security, etc) &lt;/DIV&gt;&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Each of these is given an integer value in SecurityPolicy.h which matches its value in the PermissionType enumeration. The CLR maps these values into flags by using the corresponding bit of a DWORD to indicate that this permission is the one being talked about. For instance, given: &lt;/P&gt;
&lt;DIV style="BORDER-RIGHT: black thin inset; PADDING-RIGHT: 1em; BORDER-TOP: black thin inset; PADDING-LEFT: 2em; FONT-SIZE: x-small; PADDING-BOTTOM: 1em; MARGIN: 1em 1em 1em 2em; BORDER-LEFT: black thin inset; PADDING-TOP: 1em; BORDER-BOTTOM: black thin inset; FONT-FAMILY: monospace; BACKGROUND-COLOR: lightgrey; WORD-WRAP: break-word"&gt;&lt;SPAN style="COLOR: blue"&gt;#define&lt;/SPAN&gt; UI_PERMISSION 9&lt;/DIV&gt;
&lt;P&gt;We use 1 &amp;lt;&amp;lt; UI_PERMISSION or 0x00000200 as a flag to indicate that we’re referencing unrestricted UI permission. In this way, we can simply logically or together as many of these permissions as is needed to talk about any given set of the special permissions. This does imply a limit of 32 special permissions however -- currently the CLR defines only 18, so there is plenty of room to grow there. One interesting thing to note is that although we do define SECURITY_FULL_TRUST to be bit 7, generally the VM uses 0xFFFFFFFF to refer to the FullTrust special permission bitmask. &lt;/P&gt;
&lt;P&gt;
&lt;H2&gt;Calculating Special Permission Flags &lt;/H2&gt;
&lt;P&gt;When an assembly or an AppDomain is loaded, policy is resolved to get the grant set. The entry point for this resolution is SecurityPolicy::ResolvePolicy (clr\src\VM\SecurityPolicy.cpp), which takes the parameters you would expect such as the evidence and assembly level declarative permission sets. It returns the grant set, and as an out parameter the denied permission set. As an extra out parameter, dwSpecialFlags, is the set of special permission flags which are calculated from the grant and deny set. &lt;/P&gt;
&lt;P&gt;The logic is to return a bitmask that represents everything that was in the grant set and not in the deny set. So if an assembly was being resolved in SecurityPolicy::ResolvePolicy, and its grant set included SkipVerification, UnmanagedCode and unrestricted UIPermission while its deny set included SkipVerification and unrestricted EnvironmentPermission, the output would be: &lt;/P&gt;
&lt;DIV style="BORDER-RIGHT: black thin inset; PADDING-RIGHT: 1em; BORDER-TOP: black thin inset; PADDING-LEFT: 2em; FONT-SIZE: x-small; PADDING-BOTTOM: 1em; MARGIN: 1em 1em 1em 2em; BORDER-LEFT: black thin inset; PADDING-TOP: 1em; BORDER-BOTTOM: black thin inset; FONT-FAMILY: monospace; BACKGROUND-COLOR: lightgrey; WORD-WRAP: break-word"&gt;((1 &amp;lt;&amp;lt; SECURITY_SKIP_VER) | (1 &amp;lt;&amp;lt; SECURITY_UNMANAGED_CODE) | (1 &amp;lt;&amp;lt; UI_PERMISSION) ) &amp;amp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;~( (1 &amp;lt;&amp;lt; SECURITY_SKIP_VER) | (1 &amp;lt;&amp;lt; ENVIRONMENT_PERMISSION) ) = &lt;BR&gt;(0x00000103) &amp;amp; !(0x00000402) = &lt;BR&gt;0x00000103 &amp;amp; 0xFFFFFBFD = &lt;BR&gt;0x00000101 = &lt;BR&gt;(1 &amp;lt;&amp;lt; UI_PERMISSION) | (1 &amp;lt;&amp;lt; SECURITY_UNMANAGED_CODE) &lt;BR&gt;&lt;/DIV&gt;
&lt;P&gt;Which is what we would expect when you take the set (SkipVerification, UnmanagedCode, UIPermission) and remove (SkipVerification, EnvironmentPermission). &lt;/P&gt;
&lt;P&gt;The actual work of resolving policy and calculating these flags is delegated by SecurityPolicy::ResolvePolicy to System.Security.SecurityManager.ResolvePolicy (clr\src\bcl\System\Security\SecurityManager.cs). After ResolvePolicy computes the grant and deny sets, it passes those to SecurityManager.GetSpecialFlags, whose job it is to do the mapping from the permission sets to any appropriate special permission flags. It does this by scanning for any flags on permissions which have their flags represented in the special permissions (currently just SecurityPermission and ReflectionPermission) and saving those flags away. It also does a scan for any permissions which have their unrestricted permissions set as a special flag, saving those as well. &lt;/P&gt;
&lt;P&gt;Once all the permissions which may map to a special flag are found, SecurityManager.MapToSpecialFlags is called to map the flags from SecurityPermission and ReflectionPermission back to an appropriate flag, while the GetSpecialFlags method itself adds bits for any of the other permissions which are unrestricted. &lt;/P&gt;
&lt;P&gt;I mentioned earlier that FullTrust is represented as 0xFFFFFFFF rather than 0x00000080, you can see that mapping in the very first line of SecurityManager.GetSpecialFlags. &lt;/P&gt;
&lt;P&gt;
&lt;H2&gt;Security Descriptors and Special Permissions &lt;/H2&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;The base SecurityDescriptor class (clr\src\VM\SecurityDescriptor.h) defines a protected member, the DWORD m_dwSpecialFlags, which holds the set of special permission flags that apply to the VM object the security descriptor refers to (such as an AppDomain or Assembly). In addition to this set of flags, the ApplicationSecurityDescriptor (clr\src\VM\SecurityDescriptorAppDomain.h) defines a second member to hold these flags -- m_dwDomainWideSpecialFlags. &lt;/P&gt;
&lt;P&gt;The m_dwSpecialFlags member is populated with the result from calling SecurityPolicy::ResolvePolicy on the object being loaded. The extra field in the ApplicationSecurityDescriptor however is kept up to date differently, and allows us to perform an optimization when a demand for one of these special permissions comes in. &lt;/P&gt;
&lt;P&gt;After the AppDomain has had its policy resolved, m_dwDomainWideSpecialFlags is initialized to match the special flags of the AppDomain. (This is done in ApplicationSecurityDescriptor::InitializePLS in clr\src\VM\SecurityDescriptorAppDomain.cpp). This means an AppDomain with no loaded assemblies has an m_dwDomainWideSpecialFlags indicating the special permission grant set of the domain itself. &lt;/P&gt;
&lt;P&gt;As each assembly is loaded into the AppDomain, the AssemblySecurityDescriptor’s m_dwSpecialFlags is initialized while policy is resolved on that assembly. (See AssemblySecurityDescriptor::ResolveWorker in clr\src\VM\SecurityDescriptorAssembly.cpp). The AppDomain then updates the m_dwDomainWideSpecialFlags field with the information from the AssemblySecurityDescriptor in ApplicationSecurityDescriptor::AddNewSecDescToPLS. The domain wide flags are updated by doing a bitwise and between the current domain wide flags and the flags of the assembly’s security descriptor. &lt;/P&gt;
&lt;P&gt;Following this logic along, the domain wide special flags start out as the set of special permissions granted to the AppDomain itself, and then are potentially reduced by each assembly loaded so that at any given point the domain wide special flags are always the set of special permissions which are granted to every assembly in the domain as well as the domain boundary. &lt;/P&gt;
&lt;P&gt;With that setup, if a demand for one of the special permissions is done in the AppDomain, we can check to see if the domain wide flag for that permission is set. If it is, then the CLR can cause the demand to succeed without ever having to do a stack walk, since it knows that for the special permission bit to be set everything in the AppDomain must be granted the given permission. The code which maps the permissions in a demand to a set of special flags is in SecurityStackWalk::GetPermissionSpecialFlags (clr\src\VM\SecurityStackWalk.cpp). &lt;/P&gt;
&lt;P&gt;Obviously this optimization does not work in the face of stack walk modifiers such as Deny or PermitOnly, which can cause the permission set of the call stack to become a subset of the permissions granted to the assemblies in the domain -- and if you look at the code in SecurityStackWalk::HasFlagsOrFullyTrustedIgnoreMode (clr\src\VM\security.inl) this is what the check for pThread-&amp;gt;GetOverridesCount() == 0 is doing. [But as Alton Brown might say, that’s another show.] This is just one more reason that &lt;A HREF="/shawnfa/archive/2006/02/02/523390.aspx"&gt;you really want to avoid using Deny and PermitOnly&lt;/A&gt; in your code if at all possible. &lt;/P&gt;
&lt;P&gt;Also note that this logic works for determining if a demand will pass, however it cannot be used to determine that a demand will fail. For instance, if an AppDomain has assemblies A, B, and C loaded into it, and the AppDomain, assembly A, and assembly B are all granted SkipVerification while assembly C is not, the SECURITY_SKIP_VER bit will be clear on the domain wide flags. However, if a skip verification demand is done while only A and B are on the call stack (or if C is on the stack, but either A or B has done an Assert preventing a stack walk from reaching C), then the demand will still succeed even though the bit is clear. &lt;/P&gt;
&lt;P&gt;The take away from this is not that you should try to only demand special permissions -- again, these were all implementation details subject to change at any point. You should always demand the most appropriate permission for the resource you’re trying to protect. More importantly, it’s interesting to see how the CLR can optimize the performance of some demands, and how operations like Deny and PermitOnly can ruin the optimizations.&lt;/P&gt;
&lt;DIV&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=619126" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/SSCLI/default.aspx">SSCLI</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Under+the+Hood/default.aspx">Under the Hood</category></item><item><title>SSCLI Zone Mappings</title><link>http://blogs.msdn.com/shawnfa/archive/2006/05/16/598173.aspx</link><pubDate>Tue, 16 May 2006 17:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:598173</guid><dc:creator>shawnfa</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/598173.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=598173</wfw:commentRss><description>&lt;P&gt;My&amp;nbsp;&lt;A HREF="/shawnfa/archive/2006/05/15/598150.aspx"&gt;previous post&lt;/A&gt; is begging the question "so what is the SSCLI's zone mapping policy?"&lt;/P&gt;
&lt;P&gt;It's actually quite simple, the source for SecurityPolicy::QuickGetZone in clr\src\vm\securitypolicy.cpp shows that SSCLI maps a URL to:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;NoZone if the URL is NULL&lt;/LI&gt;
&lt;LI&gt;MyComputer if the URL is a file URL&lt;/LI&gt;
&lt;LI&gt;Internet for all other cases&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Which indicates that there is no such thing as LocalIntranet, Trusted or Untrusted zones in SSCLI land.&amp;nbsp; (Although the SecurityZone enumeration still contains those as you can see in clr\src\bcl\system\security\securityzone.cs).&lt;/P&gt;
&lt;P&gt;The check to see if the URL is a file URL is simply done as a call to the &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/shlwapi/path/urlis.asp"&gt;UrlIs API&lt;/A&gt; specifying URLIS_FILEURL.&amp;nbsp; For those non-Win32 platforms, the PAL version of UrlIs can be found in the palrt\src\urlpars.cpp file.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=598173" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/SSCLI/default.aspx">SSCLI</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/CAS/default.aspx">CAS</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Policy/default.aspx">Policy</category></item><item><title>Custom Zones and the CLR</title><link>http://blogs.msdn.com/shawnfa/archive/2006/05/15/598150.aspx</link><pubDate>Mon, 15 May 2006 20:30:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:598150</guid><dc:creator>shawnfa</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/598150.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=598150</wfw:commentRss><description>&lt;P&gt;On the topic of &lt;A HREF="/shawnfa/archive/2006/05/12/596419.aspx"&gt;zones and the CLR&lt;/A&gt; ...&lt;/P&gt;
&lt;P&gt;Windows lets you define custom zones outside of the standard ones that the CLR knows about (see &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/workshop/security/szone/urlzones.asp"&gt;MSDN's topic on Security Zones&lt;/A&gt;&amp;nbsp;for more information).&amp;nbsp; However, because the CLR doesn't know about them, generally any assembly loaded from one of those zones will not get any CAS permissions.&amp;nbsp; This stems from the fact that default policy starts by switching on which zone an assembly is loaded from; since the custom zone won't have a matching ZoneCodeGroup it will end up with Nothing.&lt;/P&gt;
&lt;P&gt;The CLR does provide a registry key to help out in this scenario however.&amp;nbsp; If you set the DWORD HKLM\Software\Microsoft\.NETFramework\&amp;lt;version&amp;gt;\Security\Policy\TreatCustomZonesAsInternetZone to 1, the CLR will give any assembly loaded from a zone it doesn't recognize Internet zone evidence.&lt;/P&gt;
&lt;P&gt;In the SSCLI, the source for this feature lives in clr\src\utilcode\overrides.cpp -- check out the ApplyCustomZoneOverride function.&amp;nbsp; This&amp;nbsp;function takes in a pointer to what the CLR currently thinks the zone is, and if the above registry key is set, switches that value to be Internet.&lt;/P&gt;
&lt;P&gt;An interesting quirk is that this is not actually wired up in the default SSCLI, since it's implementation of zone mapping is much simpler than the standard CLR.&amp;nbsp; If you do want to beef up the zone mapping logic, and potentially wire in a call to ApplyCustomZoneOverride you'll want to check out SecurityPolicy::QuickGetZone in the clr\src\vm\securitypolicy.cpp file.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=598150" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/SSCLI/default.aspx">SSCLI</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/CAS/default.aspx">CAS</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Policy/default.aspx">Policy</category></item><item><title>What Happens When You Fully Sign a Test Signed Assembly</title><link>http://blogs.msdn.com/shawnfa/archive/2006/04/03/567651.aspx</link><pubDate>Tue, 04 Apr 2006 00:44:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:567651</guid><dc:creator>shawnfa</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/567651.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=567651</wfw:commentRss><description>&lt;P&gt;When an assembly is &lt;A HREF="/shawnfa/archive/2005/10/24/484170.aspx"&gt;test signed&lt;/A&gt;, the public key used to verify its signature is different from the public key that makes up part of the assembly identity.&amp;nbsp; So what happens when you take an assembly which is registered as a test signed assembly on your machine and fully sign it?&lt;/P&gt;
&lt;P&gt;The key here (aren't puns fun) is the fully signed bit in the CLR header.&amp;nbsp; An assembly which is fully signed (so not simply named, test signed, or delay signed) has the COMIMAGE_FLAGS_STRONGNAMESIGNED bit set in the Flags field of the IMAGE_COR20_HEADER.&amp;nbsp; (Both can be found in corhdr.h in the Framework SDK)&lt;/P&gt;
&lt;P&gt;If the CLR is verifying a signature, and it sees this bit set, it won't even attempt to check the skip verification or test sign lists.&amp;nbsp; Instead, verification proceeds with the public key embedded in the assembly itself.&amp;nbsp; So the answer to the question is that a fully signed assembly with a entry on the test signed assembly list will work as expected, and verify with the correct public key.&lt;/P&gt;
&lt;P&gt;In the &lt;A HREF="/shawnfa/archive/2006/03/24/560034.aspx"&gt;SSCLI v2&lt;/A&gt;, you can see this behavior in the strong name code located at sscli20\clr\src\VM\strongname.cpp.&amp;nbsp; Specifically, go to the VerifySignature method -- the relevant code starts at line 2498.&amp;nbsp; On 2504 we check to see if the fully signed bit is in place, and if not we check for a test public key on 2506.&amp;nbsp; The magic behind test key signing&amp;nbsp; is essentially on one line of code, line 2514, where we substitute the test public key for the assembly's real public key.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=567651" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/SSCLI/default.aspx">SSCLI</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Under+the+Hood/default.aspx">Under the Hood</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/StrongName/default.aspx">StrongName</category></item><item><title>SSCLI v2</title><link>http://blogs.msdn.com/shawnfa/archive/2006/03/24/560034.aspx</link><pubDate>Fri, 24 Mar 2006 19:18:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:560034</guid><dc:creator>shawnfa</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/560034.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=560034</wfw:commentRss><description>&lt;P&gt;As &lt;A HREF="/jasonz/archive/2006/03/23/559581.aspx"&gt;Jason announces&lt;/A&gt;, v2.0 of the SSCLI is now available for download: &lt;A href="http://msdn.microsoft.com/net/sscli"&gt;&lt;FONT face=Verdana color=#0000cc size=2&gt;http://msdn.microsoft.com/net/sscli&lt;/FONT&gt;&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;In addition to general CLR features like generics that are available in this download, some interesting security points to look at are:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Transparency (sscli20\clr\src\vm\securitytransparentassembly.cpp)&lt;/LI&gt;
&lt;LI&gt;Revamped compressed stack (sscli20\clr\src\vm\newcompressedstack.cpp)&lt;/LI&gt;
&lt;LI&gt;New declarative security metadata format (sscli20\clr\src\vm\securitydeclarative.cpp)&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;And of course our general security perf work is here too.&amp;nbsp; For those interested in how this mscorwks thing works ... time to get downloading :-)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=560034" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/SSCLI/default.aspx">SSCLI</category></item><item><title>Comparing Java and .NET Security</title><link>http://blogs.msdn.com/shawnfa/archive/2005/08/17/452760.aspx</link><pubDate>Wed, 17 Aug 2005 21:34:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:452760</guid><dc:creator>shawnfa</dc:creator><slash:comments>12</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/452760.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=452760</wfw:commentRss><description>&lt;P&gt;It's been a while since I've last seen a &lt;a href="http://blogs.msdn.com/shawnfa/archive/2004/02/18/75722.aspx"&gt;comparison of Java and .NET security&lt;/A&gt;.&amp;nbsp; &lt;A href="http://www.cs.virginia.edu/~nrp3d/"&gt;Nathaneal Paul&lt;/A&gt; and &lt;A href="http://www.cs.virginia.edu/~evans/"&gt;David Evans&lt;/A&gt; from the &lt;A href="http://www.cs.virginia.edu/"&gt;University of Virginia Computer Science Department&lt;/A&gt; recently finished their comparison, &lt;A href="http://www.cs.virginia.edu/~nrp3d/papers/computers_and_security-net-java.pdf"&gt;Comparing Java and .NET Security: Lessons Learned and Missed.&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;In their paper, Nathaneal and David take a bottom up approach to examining the security models of each platform.&amp;nbsp; They start with the opcodes that make up the instruction set of each virtual machine, and examine them both from an instruction set design perspective as well as from a verification perspective.&amp;nbsp; They use the SSCLI to compare verifier implementations between the CLR and Java.&amp;nbsp; From there, they look at the way each platform allows for policy creation and the permissions that each uses.&amp;nbsp; The paper ends with an examination of how each platform uses its policy system, from bootstraping to modifying the stack walk.&lt;/P&gt;
&lt;P&gt;At the beginning of the paper, Nathaneal and David compare the number of reported major security vulnerabilities in the Java VM and the CLR since each had their official 1.0 release in January 1996 and January 2002 respectively.&amp;nbsp; Their data makes for an interesting graph, presented in their paper as Figure 1:&lt;/P&gt;
&lt;P&gt;&lt;IMG alt="Java vs CLR major security vulnerabilities" src="http://shawnmsdn.members.winisp.net/images/JavaVsClrVulnerabilities.png"&gt; &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=452760" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/SSCLI/default.aspx">SSCLI</category></item><item><title>When is ReflectionPermission Needed?</title><link>http://blogs.msdn.com/shawnfa/archive/2005/03/08/389768.aspx</link><pubDate>Tue, 08 Mar 2005 20:31:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:389768</guid><dc:creator>shawnfa</dc:creator><slash:comments>11</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/389768.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=389768</wfw:commentRss><description>&lt;p&gt;Reflection and its interaction with security can sometimes be a bit of a confusing matter.&amp;nbsp; The easiest portion to figure out is the permissions needed to use Reflection.Emit.&amp;nbsp; In order to do anything with the reflection emit feature, you'll need to have ReflectionPermission with the ReflectionEmit flag set.&amp;nbsp; In the default policy, you'll have this permission if you're running on LocalIntranet or MyComputer.&lt;/p&gt; &lt;p&gt;Things get a little more dicey when you start to figure out what permissions you need in order to use standard reflection.&amp;nbsp; The general rule of thumb is that if you could do something with early binding, then you won't need ReflectionPermission in order to use reflection to do the same thing with late binding.&amp;nbsp; So, you could easily create an XmlDocument and load a string into it with the Load method via reflection, even if you didn't have any ReflectionPermission.&amp;nbsp; This makes sense because demanding a permission here really doesn't buy any extra security, since you could have just done these operations directly in your code anyway.&lt;/p&gt; &lt;p&gt;Getting a&amp;nbsp;Type object for a type that is not visible to you, or getting an object to represent a member that is not visible has different behavior between v1.x and v2.0.&amp;nbsp; On v1.x, you'll need ReflectionPermission with the TypeInformation flag.&amp;nbsp; This means if you want to get a Type object for System.AssemblyHandle (which is a type in mscorlib marked as internal), you'll need this permission.&amp;nbsp; You'll also need this permission to get a MethodInfo object for System.Array::GetMedian() even though Array is public,&amp;nbsp;since GetMedian() is a private member.&amp;nbsp; The same holds true of getting a FieldInfo for System.Security.PermissionSet::m_Unrestricted, a private field.&amp;nbsp; Getting a PropertyInfo for the protected property System.Security.Cryptography.HashAlgorithm::HashSize would not require any permissions if you derived from HashAlgorithm, otherwise TypeInformation would be needed there as well.&amp;nbsp; One thing that's interesting to note about this is that if you do not have TypeInformation, and you try to perform one of these protected operations, you won't get a SecurityException.&amp;nbsp; Instead, reflection will just return a null object back to you.&amp;nbsp; In Whidbey the TypeInformation flag has been marked as obsolete, and any code can get at these objects.&lt;/p&gt; &lt;p&gt;The reason this is safe is that once you have the appropriate xxxInfo object, and you want to either invoke it or read its value, you'll need ReflectionPermission with the ReflectionPermissionFlag.MemberAccess flag set.&amp;nbsp; By default, both TypeInformation and MemberAccess are only granted to code running on the local machine.&amp;nbsp; &lt;p&gt;&lt;/p&gt;So, from the discussion above, it would seem that I could easily call System.Reflection.Assembly::GetExecutingAssembly() from partial trust code, since Assembly is a public class, and GetExecutingAssembly() is a public method on that class.&amp;nbsp; However, if I tried to do that, I would end up with a SecurityException. &lt;p&gt;&lt;/p&gt; &lt;p&gt;Why is that?&amp;nbsp; The answer lies deep within the CLR, inside the reflection internals.&amp;nbsp; If you look inside the SSCLI, you can find the code that's responsible for dispatching the late-bound call in COMMember::InvokeMethod_Internal (located in sscli\clr\src\vm\COMMember.cpp, line 1154).&amp;nbsp; Scanning down a bit through that method, there's an interesting comment on line 1231, where the reflection system calls an IsDangerousMethod() function to check to see if it needs to demand additional permissions.&amp;nbsp; If IsDangerousMethod() returns true, then an RM_ATTR_RISK_METHOD flag gets set, which causes COMCodeAccessSecurityEngine::SpecialDemand(REFLECTION_MEMBER_ACCESS) to be called on line 1278.&lt;/p&gt; &lt;p&gt;It seems pretty obvious that this might be our problem, so lets go check out IsDangerousMethod() to see what it considers to be dangerous.&amp;nbsp; This function starts at line 1007 of COMMember.cpp, and the meat of it is between lines 1073 and 1093.&amp;nbsp; Basically, we check the method table of the method in question, and compare it to a method table of several classes.&amp;nbsp; If the method belongs to one of these classes, we consider it dangerous and return true.&amp;nbsp; The&amp;nbsp;list of classes to compare against is initialized on lines 1031 to 1049.&amp;nbsp; The 19 special classes are:&lt;/p&gt; &lt;p&gt; &lt;table border="1"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;System.Activator&lt;/td&gt; &lt;td&gt;System.AppDomain&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;System.RuntimeType&lt;/td&gt; &lt;td&gt;System.Type&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;System.IO.IsolatedStorage.IsolatedStorageFile&lt;/td&gt; &lt;td&gt;System.Reflection.Assembly&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;System.Reflection.ConstructorInfo&lt;/td&gt; &lt;td&gt;System.Reflection.EventInfo&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;System.Reflection.FieldInfo&lt;/td&gt; &lt;td&gt;System.Reflection.MethodBase&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;System.Reflection.PropertyInfo&lt;/td&gt; &lt;td&gt;System.Reflection.RuntimeConstructorInfo&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;System.Reflection.RuntimeEventInfo&lt;/td&gt; &lt;td&gt;System.Reflection.RuntimeFieldInfo&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;System.Reflection.RuntimeMethodInfo&lt;/td&gt; &lt;td&gt;System.Reflection.RuntimePropertyInfo&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;System.Reflection.Emit.AssemblyBuilder&lt;/td&gt; &lt;td&gt;Sytem.Reflection.Emit.MethodRental&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;System.Resources.ResourceManager&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;This table is defined in terms of macros that look like CLASS__APPDOMAIN, which should all be relatively easy to figure out on their own.&amp;nbsp; However, if you'd like to find the source of this definition, you can check clr\src\vm\mscorlib.h, where all of these macros are created.&amp;nbsp; For instance, CLASS__APPDOMIAN is created on line 64 of this file:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DEFINE_CLASS(APP_DOMAIN, System, AppDomain)&lt;/p&gt; &lt;p&gt;If a class belongs to this table, then none of its methods or properties are available through late binding unless the calling code is granted MemberAccess.&amp;nbsp; That's why my partial trust code above couldn't call Assembly::GetExecutingAssembly().&lt;/p&gt; &lt;p&gt;In addition to the 19 classes listed above, Whidbey adds the following four classes to the dangerous list:&lt;/p&gt; &lt;p&gt; &lt;table border="1"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;System.RuntimeFieldHandle&lt;/td&gt; &lt;td&gt;System.RuntimeMethodHandle&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;System.RuntimeTypeHandle&lt;/td&gt; &lt;td&gt;System.Reflection.RuntimeFieldInfo&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt; &lt;p&gt;Another area where reflection and security come together is when the target code is protected with a LinkDemand.&amp;nbsp; The problem with using reflection to invoke a method that contains a LinkDemand is that the reflection code and not your code will ultimately be the method's caller.&amp;nbsp; This means that if the LinkDemand is for a set of CAS permissions (FullTrust for instance), it may be satisfied by the reflection code which lives in mscorlib, even though the demand may not have been satisfied by your code.&amp;nbsp; In order to prevent malicious code from circumventing LinkDemands through the use of reflection,&amp;nbsp;invoking a method&amp;nbsp;through reflection has the effect of turning LinkDemands into full demands.&amp;nbsp; If you don't want the whole stack checked, then you should &lt;A href="http://blogs.msdn.com/shawnfa/archive/2004/08/23/219155.aspx"&gt;Assert the permissions being demanded&lt;/a&gt; before calling the method with reflection, and then RevertAssert those permissions after the method returns.&amp;nbsp; By following that pattern, you can most closely simulate the effect of the LinkDemand.&lt;/p&gt; &lt;p&gt;For instance, if I'm calling System.Security.Cryptography.X509Certificates.X509Certificate::Handle, which has a LinkDemand on its getter for UnmanagedCode, I would use something like this:&lt;/p&gt; &lt;p&gt; &lt;div style="BORDER-RIGHT: black thin inset; PADDING-RIGHT: 1em; BORDER-TOP: black thin inset; PADDING-LEFT: 2em; FONT-SIZE: x-small; PADDING-BOTTOM: 1em; MARGIN: 1em 1em 1em 2em; BORDER-LEFT: black thin inset; PADDING-TOP: 1em; BORDER-BOTTOM: black thin inset; FONT-FAMILY: monospace; BACKGROUND-COLOR: lightgrey; WORD-WRAP: break-word"&gt;IntPtr&amp;nbsp;handleValue&amp;nbsp;=&amp;nbsp;IntPtr.Zero;&lt;br /&gt;&lt;span style="COLOR: blue"&gt;try&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="COLOR: blue"&gt;new&lt;/span&gt;&amp;nbsp;SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;handleValue&amp;nbsp;=&amp;nbsp;(IntPtr)handleProperty.GetValue(cert,&amp;nbsp;&lt;span style="COLOR: blue"&gt;null&lt;/span&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;span style="COLOR: blue"&gt;finally&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CodeAccessPermission.RevertAssert();&lt;br /&gt;}&lt;/div&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;To sum up, when working with reflection, if you keep the following rules in mind, you shouldn't run into any issues:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;If you're using Reflection.Emit, you need ReflectionPermissionFlag.Emit &lt;li&gt;If you're accessing code that you would be able to access anyway, you don't need any permission &lt;li&gt;If you're getting objects describing items you don't have access to, you need ReflectionPermissionFlag.TypeDiscovery &lt;li&gt;If you're invoking objects you don't have access to, you need ReflectionPermissionFlag.MemberAccess &lt;li&gt;There are some special classes unavailable without ReflectionPermissionFlag.MemberAccess &lt;li&gt;All LinkDemands will turn into full Demands&lt;/li&gt;&lt;/ol&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=389768" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/SSCLI/default.aspx">SSCLI</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/CAS/default.aspx">CAS</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Under+the+Hood/default.aspx">Under the Hood</category></item><item><title>Why == and the Equals Method Return Different Results for Floating Point Values</title><link>http://blogs.msdn.com/shawnfa/archive/2004/07/19/187792.aspx</link><pubDate>Mon, 19 Jul 2004 20:21:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:187792</guid><dc:creator>shawnfa</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/187792.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=187792</wfw:commentRss><description>&lt;P&gt;There's a subtle difference between comparing floating point values with the Equals method and comparing them with the == operator.&amp;nbsp; (In all the code I show in this post, I use the Double class, however everything I say also applies to the Single class).&lt;/P&gt;
&lt;P&gt;When the following code is run, it compiles and produces the results you would expect:&lt;/P&gt;
&lt;P&gt;
&lt;DIV class=codeblock&gt;&lt;SPAN class=keyword&gt;double&lt;/SPAN&gt;&amp;nbsp;pi1&amp;nbsp;&lt;SPAN class=operator&gt;=&lt;/SPAN&gt;&amp;nbsp;3.1415926535;&lt;BR&gt;&lt;SPAN class=keyword&gt;double&lt;/SPAN&gt;&amp;nbsp;pi2&amp;nbsp;&lt;SPAN class=operator&gt;=&lt;/SPAN&gt;&amp;nbsp;3.1415926535;&lt;BR&gt;&lt;BR&gt;Console&lt;SPAN class=operator&gt;.&lt;/SPAN&gt;WriteLine&lt;SPAN class=operator&gt;(&lt;/SPAN&gt;&lt;SPAN class=string&gt;"For PI:\n\tDouble.Equals() : {0}\n\tOperator == : {1}"&lt;/SPAN&gt;,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Double&lt;SPAN class=operator&gt;.&lt;/SPAN&gt;Equals&lt;SPAN class=operator&gt;(&lt;/SPAN&gt;pi1,&amp;nbsp;pi2),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pi1&amp;nbsp;&lt;SPAN class=operator&gt;==&lt;/SPAN&gt;&amp;nbsp;pi2);&lt;BR&gt;&lt;/DIV&gt;
&lt;DIV class=codeblock&gt;For PI:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Double.Equals() : True&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Operator == : True&lt;BR&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;Both values of pi compare to be the same regardless of using the Equals method or operator.&amp;nbsp; However, the following code produces a more interesting result:&lt;/P&gt;
&lt;P&gt;
&lt;DIV class=codeblock&gt;&lt;SPAN class=keyword&gt;double&lt;/SPAN&gt;&amp;nbsp;nan1&amp;nbsp;&lt;SPAN class=operator&gt;=&lt;/SPAN&gt;&amp;nbsp;Double&lt;SPAN class=operator&gt;.&lt;/SPAN&gt;NaN;&lt;BR&gt;&lt;SPAN class=keyword&gt;double&lt;/SPAN&gt;&amp;nbsp;nan2&amp;nbsp;&lt;SPAN class=operator&gt;=&lt;/SPAN&gt;&amp;nbsp;Double&lt;SPAN class=operator&gt;.&lt;/SPAN&gt;NaN;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;BR&gt;Console&lt;SPAN class=operator&gt;.&lt;/SPAN&gt;WriteLine&lt;SPAN class=operator&gt;(&lt;/SPAN&gt;&lt;SPAN class=string&gt;"For NaN:\n\tDouble.Equals() : {0}\n\tOperator == : {1}"&lt;/SPAN&gt;,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Double&lt;SPAN class=operator&gt;.&lt;/SPAN&gt;Equals&lt;SPAN class=operator&gt;(&lt;/SPAN&gt;nan1,&amp;nbsp;nan2),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;nan1&amp;nbsp;&lt;SPAN class=operator&gt;==&lt;/SPAN&gt;&amp;nbsp;nan2);&lt;BR&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;When this is run, the results are:&lt;/P&gt;
&lt;P&gt;
&lt;DIV class=codeblock&gt;For NaN:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Double.Equals() : True&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Operator == : False&lt;BR&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;Why would Double.Equals() produce a result of true, while the == operator produces a result of false?&amp;nbsp; Well, to start with, lets check out what a Double is.&amp;nbsp; According to section 7.2 of the &lt;A href="http://msdn.microsoft.com/net/ecma/"&gt;ECMA spec &lt;/A&gt;(&lt;A href="http://download.microsoft.com/download/3/f/b/3fb318cb-f60c-4128-ada8-bbffb791046d/Partition_II_Metadata.zip"&gt;in Partition II&lt;/A&gt;):&lt;/P&gt;
&lt;TABLE border=1&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;B&gt;Class Library Type&lt;/B&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;B&gt;CIL Type&lt;/B&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;B&gt;Description&lt;/B&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Single&lt;/TD&gt;
&lt;TD&gt;float32&lt;/TD&gt;
&lt;TD&gt;IEC 60559:1989 32-bit float&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Double&lt;/TD&gt;
&lt;TD&gt;float64&lt;/TD&gt;
&lt;TD&gt;IEC 60559:1989 64-bit float&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;P&gt;So what's this IEC 60559:1989 stuff?&amp;nbsp; It's a standard for the binary format of floating point types.&amp;nbsp; The &lt;A href="http://download.microsoft.com/download/0/a/c/0acb3585-3f3f-4169-ad61-efc9f0176788/CSharp.zip"&gt;C# Standard &lt;/A&gt;points out in section 3 that this standard is more commonly known in the United States as ANSI/IEEE Standard 754-1985, or the IEEE Standard for Binary Floating-Point Arithmetic.&lt;/P&gt;
&lt;P&gt;According to IEC 60559:1989, two floating point numbers with values of NaN are never equal.&amp;nbsp; However, according to the &lt;A href="http://download.microsoft.com/download/3/c/2/3c26966b-ce53-4d78-9076-5cb8331844f1/TypeLibrary.zip"&gt;specification for the System.Object::Equals method&lt;/A&gt;, it's desirable to override this method to provide value equality semantics.&amp;nbsp; Since System.ValueType provides this functionality through the use of Reflection, the description for Object.Equals specifically says that value types should consider overriding the default ValueType implementation to gain a performance increase.&amp;nbsp; In fact from looking at the &lt;A href="http://dotnet.di.unipi.it/Content/sscli/docs/doxygen/fx/bcl/valuetype_8cs-source.html#l00036"&gt;source of System.ValueType::Equals &lt;/A&gt;(line 36 of clr\src\BCL\System\ValueType.cs in the SSCLI), there's even a comment from the CLR Perf team to the effect of System.ValueType::Equals not being fast.&lt;/P&gt;
&lt;P&gt;So now we have two conflicting ideas of what Equals should mean.&amp;nbsp; Object::Equals says that the BCL value types should override to provide value equality, and IEC 60559 says that NaN does not equal NaN.&amp;nbsp; Partition I of the ECMA spec provides resolution for this conflict by making a note about this specific case in section 8.2.5.2.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&amp;#8220;Note: Although two floating point NaNs are defined by IEC 60559:1989 to always compare as unequal, the contract for System.Object.Equals, requires that overrides must satisfy the requirements for an equivalence operator.&amp;nbsp; Therefore, System.Double.Equals and System.Single.Equals return True when comparing two NaNs, while the equality operator returns False in that case, as required by the standard.&amp;#8221;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;So that's why == and Equals behave differently in the NaN case.&amp;nbsp; There are a lot of issues to remember when dealing with floating point numbers, and this should be another one.&amp;nbsp; Always use Equals() if you want NaN to be equal with other NaNs, and always use the == operator if you want NaNs to behave according to the IEEE floating point specification.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=187792" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/SSCLI/default.aspx">SSCLI</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Under+the+Hood/default.aspx">Under the Hood</category></item><item><title>What's the Deal with the ECMA Key?</title><link>http://blogs.msdn.com/shawnfa/archive/2004/06/09/152097.aspx</link><pubDate>Wed, 09 Jun 2004 23:35:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:152097</guid><dc:creator>shawnfa</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/152097.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=152097</wfw:commentRss><description>&lt;P&gt;The libraries laid out in the &lt;A href="http://msdn.microsoft.com/net/ecma/default.asp"&gt;ECMA spec&lt;/A&gt; are all signed with a public key that looks pretty strange.&amp;nbsp; If you ildasm mscorlib.dll, System.dll, or any of the other framework libraries that are defined in the ECMA specs (see partition IV: Library&amp;nbsp;&amp;nbsp;if you're interested in which libraries these are), you'll notice a peculiar looking public key:&lt;/P&gt;
&lt;P&gt;
&lt;DIV class=codeblock&gt;.publickey = (00 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 )&lt;/DIV&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;That looks very strange, and not at all like a strong key.&amp;nbsp; This key is called the Standard Public Key (sometimes referred to as the ECMA public key), and has a public key token of b77a5c561934e089.&amp;nbsp; If you have the SSCLI installed,&amp;nbsp; you'll see this key defined as the &amp;#8220;neutral key&amp;#8221; in the file sscli\clr\src\dlls\mscorsn\strongname.cpp. (lines 107 and 109).&lt;/P&gt;
&lt;P&gt;By looking at the format of public key blobs, defined in strongname.h (line 38 in sscli\clr\src\inc\strongname.h in the SSCLI, line 28 of &amp;lt;SDK root&amp;gt;\inc\strongname.h in the .NET Framework 1.1 SDK), you'll see it's defined as follows:&lt;/P&gt;
&lt;P&gt;
&lt;DIV class=codeblock&gt;&lt;SPAN class=comment&gt;// Public key blob binary format.&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN class=keyword&gt;typedef struct&lt;/SPAN&gt; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&lt;SPAN class=keyword&gt;unsigned int&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;SigAlgID;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN class=comment&gt;// (ALG_ID) signature algorithm used to create the signature&lt;/SPAN&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&lt;SPAN class=keyword&gt;unsigned int&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;HashAlgID;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN class=comment&gt;// (ALG_ID) hash algorithm used to create the signature&lt;/SPAN&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;ULONG&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cbPublicKey;&amp;nbsp;&amp;nbsp;&lt;SPAN class=comment&gt;// length of the key in bytes&lt;/SPAN&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;BYTE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;PublicKey[1];&amp;nbsp;&lt;SPAN class=comment&gt;// variable length byte array containing the key value in format output by CryptoAPI&lt;/SPAN&gt;&lt;BR&gt;} PublicKeyBlob;&lt;BR&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;So, the standard public key actually has 0 for both algorithm IDs, a length of 4 bytes, and all of those bytes are set to 0.&amp;nbsp; This means that the standard public key is actually a 16 bit key of all zeros.&lt;/P&gt;
&lt;P&gt;The mechanism behind this key is actually pretty clever.&amp;nbsp; Since the ECMA spec lays out the specifications for how any implementation of the CLI should work, it can't say that everyone must sign with the Microsoft key.&amp;nbsp; If it did that, then Microsoft would either have to sign anyone's assemblies who decided to implement the CLI, or we'd have to make our private key available to the general public, creating a huge security hole.&amp;nbsp; However, since strong names of referenced assemblies are burned into assemblies at compile time, there needs to be some way for compiler to refer to the standard libraries without forcing a specific implementation of the CLI onto the users of the assembly.&lt;/P&gt;
&lt;P&gt;Enter the standard public key.&amp;nbsp; Assemblies that specify this key as their public key aren't actually signed by a corresponding private key.&amp;nbsp; Instead, CLI implantations see this key, and substitute in their own keypair.&amp;nbsp; For instance, when the SSCLI sees the standard public key, it knows that this means the assemblies have been signed with the key found in sscli\clr\src\dlls\mscorsn\thekey.h and sscli\clr\bin\finalpublickey.snk.&lt;/P&gt;
&lt;P&gt;Allowing CLI implementors to swap the actual key that the standard public key represents frees them up to be able to run code that was compiled against another vendor's CLI implementation.&amp;nbsp; Also, since each VM implementation will translate the standard public key into only their private keypair, this prevents assemblies signed by creators of CLI implementations from verifying on different CLI implementations.&amp;nbsp; For instance, the Mono mscorlib won't pass signature verification on the CLR.&lt;/P&gt;&lt;/FONT&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=152097" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/SSCLI/default.aspx">SSCLI</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Cryptography/default.aspx">Cryptography</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Under+the+Hood/default.aspx">Under the Hood</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/StrongName/default.aspx">StrongName</category></item><item><title>Same Site Socket Permission</title><link>http://blogs.msdn.com/shawnfa/archive/2004/03/10/87548.aspx</link><pubDate>Wed, 10 Mar 2004 22:09:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:87548</guid><dc:creator>shawnfa</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/87548.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=87548</wfw:commentRss><description>&lt;P&gt;Fairly frequently, people will want to know how to get same site socket permissions,&amp;nbsp;in the same way that they can get same site web permission today. Unfortunately, the answer is that with the security objects shipped with the framework, there is no way to accomplish this.&lt;/P&gt;
&lt;P&gt;In order to figure out what coding must be done to get same site socket permissions, first lets look at how same site web permissions are granted. Instead of being a flag on the web permission itself, same site web permission is actually created in the NetCodeGroup. The SSCLI source for this code group can be found here: &lt;A href="http://dotnet.di.unipi.it/Content/sscli/docs/doxygen/fx/bcl/netcodegroup_8cs-source.html"&gt;http://dotnet.di.unipi.it/Content/sscli/docs/doxygen/fx/bcl/netcodegroup_8cs-source.html&lt;/A&gt;. This code group, instead of having a static permission set associated with it, creates a dynamic permission set when it is evaluated. If its membership condition is matched, the Resolve method of the code group will scan the evidence for a Url or Site object. If it finds one of these (giving preference to Url), it will generate a WebPermission with access back to that Url. (You can see this by looking at the Resolve method, the interesting part is between lines 82 and 104).&lt;/P&gt;
&lt;P&gt;In order to create same site socket access, something very similar would have to be done. However, careful inspection of the NetCodeGroup.cs source file shows that this work is already done for you! The implementation details of generating the dynamic permissions are encapsulated in the CalculatePolicy method (&lt;A href="http://dotnet.di.unipi.it/Content/sscli/docs/doxygen/fx/bcl/netcodegroup_8cs-source.html#l00284"&gt;line 284&lt;/A&gt;). Interestingly enough, on&lt;A href="http://dotnet.di.unipi.it/Content/sscli/docs/doxygen/fx/bcl/netcodegroup_8cs-source.html#l00289"&gt; line 289&lt;/A&gt;, a security element named socketPerm is initialized to null, and then ignored for the rest of the method. So it looks like all that needs to be done is to write a method that will create the socket permissions for you. The NetCodeGroup has this method written already as well. Specifically, there's a CreateSocketPermission method on &lt;A href="http://dotnet.di.unipi.it/Content/sscli/docs/doxygen/fx/bcl/netcodegroup_8cs-source.html#l00225"&gt;line 225 &lt;/A&gt;that does the job for you.&lt;/P&gt;
&lt;P&gt;So, in order to modify the NetCodeGroup to create same site socket permissions, all that needs to be done is to change line 289 from: &lt;/P&gt;
&lt;DIV class=codeblock&gt;SecurityElement socketPerm = &lt;SPAN class=keyword&gt;null&lt;/SPAN&gt;;&lt;/DIV&gt;
&lt;P&gt;to&lt;/P&gt;
&lt;DIV class=codeblock&gt;SecurityElement socketPerm = CreateSocketPermission(host, scheme); &lt;/DIV&gt;
&lt;P&gt;And there you go, a NetCodeGroup that will grant both same site web and same site socket permissions.&lt;/P&gt;
&lt;HR&gt;

&lt;P&gt;If you're looking for the NetCodeGroup.cs file in the &lt;A href="http://msdn.microsoft.com/net/sscli"&gt;SSCLI&lt;/A&gt; distribution, it unpacks to the clr\src\bcl\system\security\policy directory.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=87548" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/SSCLI/default.aspx">SSCLI</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/CAS/default.aspx">CAS</category></item><item><title>More Details on Portable Crypto Operations</title><link>http://blogs.msdn.com/shawnfa/archive/2004/03/09/86923.aspx</link><pubDate>Wed, 10 Mar 2004 00:33:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:86923</guid><dc:creator>shawnfa</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/86923.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=86923</wfw:commentRss><description>&lt;P&gt;Yesterday I &lt;A href="http://blogs.msdn.com/shawnfa/archive/2004/03/08/86233.aspx#FeedBack"&gt;posted&lt;/A&gt;&amp;nbsp;about detecting which CSP provided algorithms were available on your copy of Windows, and upgrading IE to get a newer CSP that supported more algorithms.&amp;nbsp; &lt;A href="http://pages.infinit.net/ctech/poupou.html"&gt;Sebastien Pouliot&lt;/A&gt;&amp;nbsp;provied some nice followup information on using pure managed classes instead of the *CryptoServiceProvider implementations to help solve the portability problem.&lt;/P&gt;
&lt;P&gt;Sebastian works with &lt;A href="http://www.go-mono.com"&gt;Mono&lt;/A&gt;, and points out that all of their algorithms are pure managed, and can be used on any platform (even the ones named *CryptoServiceProvider, the names are just for compatibility).&amp;nbsp; Microsoft also provides several managed classes, notably RijndaelManaged for AES symmetric encryption, and SHA1Managed for hashing, so using the Microsoft framework is also an option here.&amp;nbsp; For updates on the status of Crypto in Mono, you can check out &lt;A href="http://www.go-mono.com/crypto.html" target=_new&gt;&lt;FONT color=#223355&gt;http://www.go-mono.com/crypto.html&lt;/FONT&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;What follows is part of Sebastian's response to yesterday's post (note Fx1.2 is Whidbey, v2.0 of the Framework):&lt;/P&gt;
&lt;P&gt;
&lt;HR id=null&gt;
&lt;/P&gt;
&lt;P&gt;Actually all Fx cryptographic algorithms are supported, including the new one in Fx1.2 - and them some... &lt;BR&gt;&lt;BR&gt;The mscorlib.dll assembly contains the following algorithms. &lt;BR&gt;- DSACryptoServiceProvider * &lt;BR&gt;- RSACryptoServiceProvider *, ** &lt;BR&gt;- DESCryptoServiceProvider * &lt;BR&gt;- RC2CryptoServiceProvider * &lt;BR&gt;- RijndaelManaged &lt;BR&gt;- RIPEMD160Managed *** &lt;BR&gt;- SHA1CryptoServiceProvider *, **** &lt;BR&gt;- SHA1Managed **** &lt;BR&gt;- SHA256Managed &lt;BR&gt;- SHA284Managed &lt;BR&gt;- SHA512Managed &lt;BR&gt;- TripleDESCryptoServiceProvider * &lt;BR&gt;and all HMAC (SHA1, MD5, RIPEMD160, SHA256, SHA384, SHA512) &lt;BR&gt;&lt;BR&gt;* For compatibility we had to keep the &amp;lt;algo&amp;gt;CryptoServiceProvider names but the implementations are fully managed. &lt;BR&gt;** Support both PKCS1 and OAEP padding. &lt;BR&gt;*** To support upcoming Fx 1.2 &lt;BR&gt;**** They are actually the same implementation. &lt;BR&gt;&lt;BR&gt;&lt;BR&gt;Mono.Security.dll assembly also have some additional algorithms* &lt;BR&gt;- RSAManaged &lt;BR&gt;- DHManaged &lt;BR&gt;- ARC4Managed ** &lt;BR&gt;- MD2Managed *** &lt;BR&gt;- MD4Managed *** &lt;BR&gt;which were required for other "internal" pieces like NTLM authentication and SSL/TLS (both available as managed implementation inside the same assembly). &lt;BR&gt;&lt;BR&gt;* Note the absence of DSAManaged from this assembly! Sadly the DSA abstract class has an internal constructor making it impossible to inherit from it outside mscorlib. I hope this get corrected in Fx 1.2. &lt;BR&gt;** Compatible with RSA RC4 stream cipher. &lt;BR&gt;*** MD2Managed and MDManaged are present but we STRONGLY discourage their use in new applications. Their presence was required to support older X.509 certificates (signed using a MD2 hash) and to support NTLM authentication (which use MD4). &lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&amp;gt; Also, how easy would it be to get the Mono algorithms to compile using the Microsoft toolset and distribute them with an application? Would I need just a .cs file or two, or are there a slew of dependencies to worry about? &lt;BR&gt;&lt;BR&gt;Using Mono.Security.dll on Windows should be very easy (i.e. it shouldn't require any change or I missed my target ;-). &lt;BR&gt;&lt;BR&gt;Other algorithms (corlib) may have dependencies on BigInteger (DSA, RSA) and other internal classes from Mono.* namespaces. However they do not depend on some Mono's internal (with the notable exception of the RNGCryptoServiceProvider class) so it's only a matter to include the right files. Some people ported the corlib's source for the Compact Framework without too much problems (few changes were required because many overloaded methods are missing in CF). &lt;BR&gt;&lt;BR&gt;The licensing is also very friendly as Mono class library use the MIT X.11 license (&lt;A href="http://www.opensource.org/licenses/mit-license.php" target=_new&gt;&lt;FONT color=#223355&gt;http://www.opensource.org/licenses/mit-license.php&lt;/FONT&gt;&lt;/A&gt;). Finally anyone can follow the current status of Mono's cryptography by bookmarking this page: &lt;A href="http://www.go-mono.com/crypto.html" target=_new&gt;&lt;FONT color=#223355&gt;http://www.go-mono.com/crypto.html&lt;/FONT&gt;&lt;/A&gt; &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=86923" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/SSCLI/default.aspx">SSCLI</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Cryptography/default.aspx">Cryptography</category></item><item><title>How Exceptions Work in Rotor (and the CLR)</title><link>http://blogs.msdn.com/shawnfa/archive/2004/03/05/84980.aspx</link><pubDate>Sat, 06 Mar 2004 02:30:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:84980</guid><dc:creator>shawnfa</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/84980.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=84980</wfw:commentRss><description>Joel Pobar has a nice &lt;A href="http://blogs.msdn.com/joelpob/archive/2004/03/05/84738.aspx"&gt;post&lt;/A&gt; with Jan Kotas' explanation of how exceptions work in Rotor (and by extension, the CLR).&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=84980" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/SSCLI/default.aspx">SSCLI</category></item><item><title>Moving</title><link>http://blogs.msdn.com/shawnfa/archive/2003/12/09/57033.aspx</link><pubDate>Wed, 10 Dec 2003 03:29:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:57033</guid><dc:creator>shawnfa</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/57033.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=57033</wfw:commentRss><description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;
    The GotDotNet blogs are being frozen, so I'll be moving my blog over to the ASP.Net
    site.&amp;#160; You can find the new location at &lt;a href="http://blogs.msdn.com/shawnfa"&gt;http://blogs.msdn.com/shawnfa&lt;/a&gt;
&lt;/body&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=57033" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/ClickOnce/default.aspx">ClickOnce</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/SSCLI/default.aspx">SSCLI</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Cryptography/default.aspx">Cryptography</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/XML/default.aspx">XML</category></item><item><title>Custom Security Object Samples</title><link>http://blogs.msdn.com/shawnfa/archive/2003/11/10/57029.aspx</link><pubDate>Tue, 11 Nov 2003 00:46:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:57029</guid><dc:creator>shawnfa</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/57029.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=57029</wfw:commentRss><description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;
    &lt;p&gt;
        Currently, there are no samples on MSDN for creating custom security objects.&amp;#160;
        However, the SSCLI ships with implementations for all of the built in security objects
        that shipped with the .Net framework 1.0.&amp;#160; This source can be used as a sample
        to help along with custom security object creation.&amp;#160; The Universita Di Pisa has
        posted the source code for the SSCLI on their website, so you don't even have to download
        the package to view it.&amp;#160; Here are some links that may be useful: 
    &lt;/p&gt;
    &lt;ul&gt;
        &lt;li&gt;
            &lt;a href="http://msdn.microsoft.com/net/sscli"&gt;SSCLI home page&lt;/a&gt; 
        &lt;/li&gt;
        &lt;li&gt;
            &lt;a href="http://dotnet.di.unipi.it/"&gt;Online SSCLI source browser&lt;/a&gt; 
        &lt;/li&gt;
        &lt;li&gt;
            &lt;a href="http://dotnet.di.unipi.it/Content/sscli/docs/doxygen/fx/bcl/allmembershipcondition_8cs-source.html"&gt;AllMembershipCondition.cs &lt;/a&gt;(A
            simple membership condition) 
        &lt;/li&gt;
        &lt;li&gt;
            &lt;a href="http://dotnet.di.unipi.it/Content/sscli/docs/doxygen/fx/bcl/strongnamemembershipcondition_8cs-source.html"&gt;StrongNameMembershipCondition.cs &lt;/a&gt;(A
            more complete membership condition) 
        &lt;/li&gt;
        &lt;li&gt;
            &lt;a href="http://dotnet.di.unipi.it/Content/sscli/docs/doxygen/fx/bcl/unioncodegroup_8cs-source.html"&gt;UnionCodeGroup.cs&lt;/a&gt;&amp;#160;(A
            sample code group) 
        &lt;/li&gt;
        &lt;li&gt;
            &lt;a href="http://dotnet.di.unipi.it/Content/sscli/docs/doxygen/fx/bcl/fileiopermission_8cs-source.html"&gt;FileIOPermission.cs&lt;/a&gt;&amp;#160;(A
            permission that works on a list of strings) 
        &lt;/li&gt;
        &lt;li&gt;
            &lt;a href="http://dotnet.di.unipi.it/Content/sscli/docs/doxygen/fx/bcl/securitypermission_8cs-source.html"&gt;SecurityPermission.cs&lt;/a&gt;&amp;#160;(A
            permission that works on a set of flags) 
        &lt;/li&gt;
    &lt;/ul&gt;
    &lt;p&gt;
        &lt;strong&gt;Update &lt;em&gt;(11/14/03)&lt;/em&gt;: &lt;/strong&gt;Eugene has just posted a sample of creating
        a custom permission: &lt;a href="http://blogs.gotdotnet.com/eugenebo/PermaLink.aspx/069af686-c063-4ce4-9cac-6b8d5234918e"&gt;http://blogs.gotdotnet.com/eugenebo/PermaLink.aspx/069af686-c063-4ce4-9cac-6b8d5234918e&lt;/a&gt;
    &lt;/p&gt;
&lt;/body&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=57029" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/SSCLI/default.aspx">SSCLI</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/CAS/default.aspx">CAS</category></item></channel></rss>