Geeks With Blogs
Adrian Hara Working through the .NET maze

Here are two assembly signing gotchas I ran into today:

1. I had two assemblies, A and B, and A had an [InternalsVisibleTo(”B”)] attribute (my concrete scenario, A is the “main” assembly and B a unit tests assembly). Everything is peachy! Then I go and sign them and compile: boom! Compilation fails with the following error message:

“Friend assembly reference 'B' is invalid. Strong-name signed assemblies must specify a public key in their InternalsVisibleTo declarations”

So I go and modify A's InternalsVisibleTo attribute like so: [InternalsVisibleTo(“B, PublicKeyToken=blabla“)]. Compile: same error message.... Wtf? I check out MSDN, and hey, there's even an example:

[assembly:InternalsVisibleToAttribute("AssemblyB, PublicKey=32ab4ba45e0a69a1")]

Just like my code, still no dice. 15 minutes later, after a lot of poking around a little alarm goes off: the example above says “PublicKey“, not “PublicKeyToken“! So I google it and sure enough, the example is plain wrong. As it turns out, it used to be that you needed to specify the token, but somewhere before the release of .NET 2.0 it changed so the full public key has to be included! Fortunately for us, David Kean put together a nice little tool to help the lazy bastard inside us generate the whole attribute declaration: http://davidkean.net/archive/2005/10/06/1183.aspx

2. Just as I thought my problems were gone (are they ever?) I ran into something even more disconcerting. Since now the unit test assemblies would have to be signed (because of the “friend” assembly stuff) all assemblies they depended on would have to be signed as well. And, as you might know, NMock2 is, sadly enough, not signed. I have to admit, before today, I never imagined that signing an assembly for which you don't have the sources wasn't an easy task. So after trying sn.exe, al.exe and not having any luck, I ran into this beautiful tool, called ILMerge. Using it you can sign an assembly .dll in three easy steps:

  • Create a dummy empty assembly, which is signed with your KeyPair.snk
  • ilmerge.exe  DummyAssembly.dll  TheUnsignedBastardAssembly.dll /keyfile:KeyPair.snk /out:TheSignedAssembly.dll
  • (later edit) Actually when writing the line above I forgot to do a reality-check: the name of assembly specified at the “/out:“ switch must be the same as the name of the unsigned assembly you are trying to sign. So the command-line above should really be:
    • ilmerge.exe  DummyAssembly.dll  TheUnsignedBastardAssembly.dll /keyfile:KeyPair.snk /out:TheUnsignedBastardAssembly.dll  (TheUnsignedBastardAssembly.dll being, after executing this, signed :) ). To make things even more complicated, if you use the line above exactly ilmerge.exe will not work, as it will try to overwrite TheUnsignedBastardAssembly while it's got it open. So either: a) move one of the input/output assemblies to another folder or b) rename the input assembly to Foo.dll, just keep the output one's name correct.
  • Enjoy (ok, I actually made this step up)

Very important to note is that the dummy signed assembly must be first in the parameters list for ilmerge, as this is considered the “primary assembly” and it's the one checked for a signature (actually it's resigned after merging).

(note: of course in my case there was another option, getting the sources for NMock2, which I did, but for some reason they were missing a class, so I couldn't build them and anyway, you might not always be so lucky)

Posted on Thursday, October 5, 2006 1:21 PM | Back to top


Comments on this post: Assembly Signing Gotchas

# re: Assembly Signing Gotchas
Requesting Gravatar...
Just to note that the current release of NMock (now the NMock2 namespace) from http://nmock.org is now signed.
Left by Richard Holden on Mar 18, 2008 12:22 AM

Your comment:
 (will show your gravatar)


Copyright © Adrian Hara | Powered by: GeeksWithBlogs.net