views:

641

answers:

3

I have a server executable that talks to Active Directory to retrieve user information. In addition to AD, this exe allows customers to write their own plugins to talk to custom user directories.

This executable is strongly named.

Is the following a true statement:

In order for a strongly named assembly to load another assembly, the loaded assembly must also be signed with the same key.

The following code returns null, if the assembly is not strongly signed, with no error indicating the assembly was not properly signed. Note, that if I do sign the assembly, I get an instance of IService. Which leads me to believe that loaded assemblies must be strongly signed.

Assembly assembly = Assembly.LoadFrom(path);

foreach (Type t in assembly.GetTypes())
{
    if (t.GetInterface(typeof(IService).FullName) != null)
    {
      return (Activator.CreateInstance(t) as IService);
    }
}

So, does this mean if you have a strongly signed assembly, and support assembly plugins, they must also be signed--plugin writers must sign them with the same key? That doesn't sound right.

Finally, Say I have an assembly that implements the IService interface, but also references an assembly, that references yet another assembly, each signed with a different key. What happens when I try to load? Should they all be signed by the same key?

+2  A: 

If your assembly is strongly typed signed, I think any assembly you load must also be strongly typed signed...but not necessarily signed with the same key.

Justin Niessner
strongly typed, or strongly named?
Alan
Doh...my fingers got ahead of my brain.
Justin Niessner
+2  A: 

The statement is wrong - referenced assemblies must be signed, but not necessarily with the same key.

When you reference a strong-named assembly, you expect to get certain benefits, such as versioning and naming protection. If the strong-named assembly then references an assembly with a simple name, which does not have these benefits, you lose the benefits you would derive from using a strong-named assembly and revert to DLL conflicts. Therefore, strong-named assemblies can only reference other strong-named assemblies.

(Taken from MSDN Library)

Daniel Brückner
+9  A: 

The following statement is correct:

In order for a strongly named assembly to load another assembly, the loaded assembly must also be signed with the same key.

From MSDN:

If the strong-named assembly then references an assembly with a simple name, which does not have these benefits, you lose the benefits you would derive from using a strong-named assembly and revert to DLL conflicts. Therefore, strong-named assemblies can only reference other strong-named assemblies.


Edit: D'oh! Though my answer is true, as P Daddy points out, it's irrelevant!

Using reflection to Load a weakly-named assembly is not the same thing as referencing one, and is not restricted the same way.

I recreated your code (or at least a close approximation), with the following assemblies:

  • Interface.dll (signed, contains IService)

  • Loader.exe (signed, a console app that takes a path, uses your code to load and return the first IService it finds in the assembly specified by that path, then calls an IService method)

  • Plugin.dll (not signed, contains an IService implementation)

Next I added a Plugin.dll reference to Loaded.exe and tried to access its IService implementation, which failed as expected with the following message: "Assembly generation failed -- Referenced assembly 'Plugin' does not have a strong name."

Finally, I ran the console app, passed it the name of the weakly-named Plugin.dll, and it worked just fine.

There seems to be something else afoot. Scott Hanselman has blogged about the vagaries of dynamic assembly loading on several occasions, and he points to Suzanne Cook's blog for authoritative details about the topic.

Jeff Sternal
But does that mean that assemblies loaded at runtime with `Assembly.LoadFrom()` need to be signed, too? I wouldn't think so.
P Daddy
@P Daddy: yikes, talk about missing the forest for the trees. That's a good question - I wouldn't think so either. In fact, if you search on "Assembly.Load Strong Name" you find a bunch of people asking how to enforce the strong name requirement. Now I'm puzzled about the behavior of the code posted above.
Jeff Sternal