Signed the assemblies. #3

Closed
wants to merge 1 commit into
from

Conversation

Projects
None yet
8 participants

Created a new sn key and signed the assembly. Please message me and i'll send you the password or regenerate the SN. What ever is easier

@cedricbrasey cedricbrasey Signed Assembly
Created a new sn key and signed the assembly
7047f7c
Contributor

Haacked commented Dec 14, 2012

Why this change?

Ninject.mvc is signed and has webactivator as a dependency. I could of built my own version of activator but thought it might be better to have a signed version in repo instead.

Sent from my Windows Phone


From: Phil Haack
Sent: 14/12/2012 16:41
To: davidebbo/WebActivator
Cc: Cedric Brasey
Subject: Re: [WebActivator] Signed the assemblies. (#3)

Why this change?


Reply to this email directly or view it on GitHub:
#3 (comment)

]-----------------------------------------------[
This e-mail and any attached files are confidential and may also be legally privileged.
They are intended solely for the intended addressee. If you are not the addressee
please e-mail it back to the sender and then immediately, permanently delete it. Do
not read, print, re-transmit, store or act in reliance on it. This e-mail may be monitored
by Planet Side Limited in accordance with current regulations. This footnote also
confirms that this e-mail message has been swept for the presence of computer viruses
currently known to Planet Side Limited. However, the recipient is responsible for virus-checking
before opening this message and any attachment. Unless expressly stated to the contrary,
any views expressed in this message are those of the individual sender and may not
necessarily reflect the views of Planet Side Limited.

http://www.planet-side.co.uk

Contributor

Haacked commented Dec 14, 2012

/cc @davidebbo I thought the official WebActivator package was signed.

Haacked closed this Dec 14, 2012

Haacked reopened this Dec 14, 2012

Contributor

Haacked commented Dec 14, 2012

Whoops, I almost merged that on accident. :)

Owner

davidebbo commented Dec 14, 2012

This came up before, and then triggered the gigantic forum discussion. But in the end, it was never signed.

Not sure we really want to re-open this can of worm. Lots of people are using WebActivator, so I wouldn't want to do this lightly.

To summarize, signing makes it more difficult to use assemblies A and B in your project if they are built against different versions of WebActivator. NuGet tries to solve that using binding redirects, but that doesn't work in all cases.

Contributor

Haacked commented Dec 14, 2012

Yeah, i think the real solution is the improved handling of strong naming in NuGet. We've talked about having NuGet have the ability to auto-sign assemblies in a package if that's the only way it can work (aka the target project is signed).

Owner

davidebbo commented Dec 14, 2012

Indeed we have. Many times! And this WebActivator specific thread is probably not the place to discuss this. :)

OTOH, I do wonder how much actual harm would happen is WebActivator was signed, since it is only used in Web projects, and binding redirects tend to work pretty well there.

Typical case where binding redirects don't work is unit tests. Since it runs under its own exe (e.g. xunit.exe), the binding redirect doesn't affect it. However, I don't think anyone would ever expect WebActivator logic to execute in the context of unit tests, so that might be a non-issue here.

I hadn't realised that this was such a heated debate and to be honest i just don't get wht this is such an issue, but that just me. So does this mean that there will or won't be an offical signed WebActivator version?

Owner

davidebbo commented Dec 17, 2012

One potential approach is to sign it and use a version that never changes, to avoid some of the issues. So basically it'll always have assembly version 1.0 (the Win32 version can move up as it's not used for resolution). Apparently, JSON.net does something similar.

Let me get more feedback on this idea first.

Owner

davidebbo commented Dec 17, 2012

It’s actually a pretty tough situation. If the latest version becomes signed, then it will in fact break the world because of all the existing packages that use the unsigned version.

Seems the only way out is:

  • Create a new NuGet package with a different name, different assembly name and different namespace. i.e. Use WebActivator.Signed throughout. This is necessary to avoid conflicts when both are used.
  • Unpublish the unsigned WebActivator to stop new apps from using it.

Then many apps will end up using both packages side by side, which will probably work, but is an ugly situation.

Maybe someone will come up with a better plan...

Contributor

Haacked commented Dec 17, 2012

Why does that break everybody if the latest becomes signed?

Owner

davidebbo commented Dec 17, 2012

Scenario:

  • Package A uses unsigned WebActivator (as is the case for lots of packages today)
  • Package B uses signed WebActivator (as most new package would if we switch)
  • You write an app that uses A and B, and things blow up, because NuGet will move up to the newer (signed) version, and A.dll won't be able to bind to it.

It won't be a super common situation at first, but give it a few months for new packages to start using signed WebActivator, and things will blow up all over the place.

Root of the problem is that you can't have binding redirects that redirect from simple name to strongly named assembly. Binding redirect is only to move up version for a given signature.

Contributor

Haacked commented Dec 17, 2012

Ah, but I assume Package A's reference to WebActivator (since it's not strongly named) will be a simple by name reference and will thus use signed WebActivator just fine.

In other words, I didn't think you need binding redirects for a non-sn assembly. I guess I've never tried it with a non-SN -> SN assembly.

Owner

davidebbo commented Dec 17, 2012

We should double check, but I'm pretty sure it won't bind.

Owner

davidebbo commented Dec 17, 2012

I just tried it to be sure and confirmed that it does not work:

Unhandled Exception: System.IO.FileLoadException: Could not load file or assembly 'ClassLibraryBindTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

So unless there is a trick to make it bind (other than AssemblyResolve event which is a non-starter), then we're out of luck here.

Contributor

Haacked commented Dec 17, 2012

bummer.

This might be highly contravercial and i do appologise for that but...

Has anyone considered maybe enforcing a strongname policy instead? It will obviously involve a quantity of short term pain but, i believe in the long run it will pay divideneds.

 Phil Haack notifications@github.com , 17/12/2012 10:32 PM:

bummer.

           —
           Reply to this email directly or view it on GitHub.                            

]-----------------------------------------------[
This e-mail and any attached files are confidential and may also be legally privileged.
They are intended solely for the intended addressee. If you are not the addressee
please e-mail it back to the sender and then immediately, permanently delete it. Do
not read, print, re-transmit, store or act in reliance on it. This e-mail may be monitored
by Planet Side Limited in accordance with current regulations. This footnote also
confirms that this e-mail message has been swept for the presence of computer viruses
currently known to Planet Side Limited. However, the recipient is responsible for virus-checking
before opening this message and any attachment. Unless expressly stated to the contrary,
any views expressed in this message are those of the individual sender and may not
necessarily reflect the views of Planet Side Limited.

http://www.planet-side.co.uk

Right, you can't "binding redirect" to something which doesn't have the same fundamental identity (and signed vs. non-signed changes the fundamental identity).

Owner

davidebbo commented Dec 18, 2012

@cedricbrasey Can you clarify what you mean by 'enforcing a strongname policy'? Related to WebActivator, NuGet, or .NET in general?

But note that more and more people are trying to move away from strong naming, so it indeed would likely not be a popular proposal :)

Hi David

Personally I would like to see all assemblies deployed with strong names (NuGet, CodePlex, Git, etc) and for binding redirects to be banned.

Deep breath... [Pause for initial backlash]

I don’t say this lightly and I believe that I have a good case. So please be patient with me as I explain my thinking.

My current client and pretty much all my previous clients (I’m a freelance developer in the UK) have an enforced strong name required policy. Now work that I do is 50% GAC deployed and 50% web and for the GAC work we don’t have a choice but to strong name. So out of habit, everything I produce is strong named.

My latest project is, thankfully, a greenfield development and I get to play with all sorts of cool things!!! MVC, Ninject, EF, .net4.5 and more importantly some proper design work. So we are now able to leverage some of the excellent work that the communities have done with regards to tools, methodologies, pattern implementations, utility assemblies, etc.

Now because of the rules that my client has regards to strong naming I’ve come to an impasse with Ninject (I’m only picking on Ninject as this was the first assembly that highlighted the issue). Ninject uses WebActivator (Not referenced in code, but used in templates). Not an issue if you don’t sign your assembly, but I big issue if you do as Ninject is strong named but WebActivator isn’t. Not really WebActivator’s or Ninject’s problem.

What options are available to me?

  1. Get the current version of WebActivator from GitHub, sign it, build it, replace the current 1.5.2 version with my ‘updated’ version. Hope it never changes and make sure that this kludge is documented so that in 2 years’ time the next developer can do the ‘right’ thing.

  2. Un-sign my project and never get it deployed because it breaks IT Security policy for .net deployments.

  3. Develop my own version of WebActivator. Rip the code, or do my own version, etc. Why should I since someone has already done the hard work but you get what I’m driving at.

Isn’t anyone worried here with option 1 or 3, Option 2 BTW is a non goer as I do actually need to deploy this project?

Option 3, couple of issues here. Firstly it’s not very ethical as you are basically ‘borrowing’ someone’s hard graft. Secondly what about bug fixes, support etc?

Option 1 scares the cr@p out of me. What we are basically doing here is rebuilding someone else’s code and passing it of as their work. There would be nothing to stop someone from deploying a package with a ‘new’ WebActivator 1.5.2 that did something terrible to the server or to client data…

With strong named assemblies you can be confident that the referenced assembly used from your project is what you expect and not a rebuild, or worse, a forgery.

And binding redirects, well that’s a rant for another day I think. :)

Cedric 

Owner

davidebbo commented Dec 20, 2012

This is probably not the right place to discuss the general signing vs not signing issue, but we can certainly discuss it relating to WebActivator.

First, I'd like to understand the scenario better. Since that is the root of the issue, why is it a rule that you have to strong name your assembly? Note that even NuGet packages that are signed are often done with non-secret keys. i.e. they're signed for convenience, but that provides no security whatsoever. So it seems like a pretty arbitrary rule which may have been set by people who don't have full understanding of the security implications (I know you don't always control what clients say...).

Note that in the OSS world, what you may view as unethical is actually perfectly acceptable, and very much part of how things work. There is absolutely nothing wrong with taking the code and redistributing it as long as it doesn't violate the license (which is very permissive!).

Note that you would not be able to put your package on NuGet and call it WebActivator, so it would have to be a different name.

As far as getting updates and fixes, git solves that pretty nicely. All you have to do is fork the repo, and later pull changes to get updates.

I'm not saying this is a great approach, but it is certainly more feasible than you make it sound.

That being said, I could conceivable own a spin off package called WebActivator.Signed, but I am a bit worried about user confusion.

Ok, I get the subtleties. I recommend introducing StrongWebActivator or SignedWebActivator or WebActivatorEx, whatever. Maybe add some functional improvements to make it more enticing. Packages should be encouraged to use it, but they can still use basic WebActivator. The hope is that over time the use of WebActivator will drop to zero.

The thing is, shipping code should be strongly named. Code Analysis will tell you to do so. And I've seen first-hand the downside of not doing so... crashing code on certain users' machines. The diagnosis came when the team signed their assemblies... and then the CLR's loader told them that the images were corrupt (on these certain machines, for whatever reason). There are no doubt other benefits as well. See Microsoft's documentation about why assemblies should be signed.

Nice to hear the thoughts of a likeminded developer!

mahara commented Feb 5, 2013

On the subtleties, I wonder why it has be to have a new name. Why not just using a new (major) version? Users still can choose to install legacy (unsigned) versions, if needed. And as a user, I wonder why I would be confused if it made that way.

Owner

davidebbo commented Feb 5, 2013

Most of the arguments in favor of signing can be refuted, and for the most part have been in this forum thread. But that can be a religious debate, and this is not the place for it (that thread is).

The only reason I see to sign to sign WebActivator is to unblock those who are forced to use signing, as long as it can be done with minimal impact to those who are not.

So anyway, let's keep this thread focused on how we can achieve this, rather on further arguments about whether strong naming is good/bad, as we'll just have to agree to disagree on that point :)

@mahara: I think things would blow up if it was just a new version, per my previews comment. Does that make sense?

So unfortunately, I don't think we can avoid renaming the Package, the assembly and the namespace for things to go smoothly.

But then the problem is that it will be hard to make anyone use the new package. One thing that might work is to have a new version of WebActivator (say 2.0) that does nothing other than depend on the new package. This way, people who just install WebActivator in a new project would effectively get the new one. But I need to convince myself that this is indeed not a breaking change, as this can be pretty subtle, and it's easy to overlook scenarios.

As for the new name, @Andrew-Webb's ideas are possible options. Any other ideas? Naming is hard :)

WebActivator2

WebActivatorForEveryone

SublimeWebActivator

WebActivator2013

Owner

davidebbo commented Feb 7, 2013

A couple other things we didn't cover:

  • The private key would be committed to the repo, since we're not doing this for any 'security' reasons. We want to make sure that anyone can build it.
  • We would keep the assembly version fixed (e.g at 1.0), to avoid binding redirect hell. The goal here is not to GAC it so Side by Side is not a scenario.

mahara commented Feb 7, 2013

@davidebbo: I'm not sure I understand correctly the scenario you presented. Are you saying that an app (probably you meant "an unsigned app") can reference both unsigned and signed WebActivator assemblies? That kinda new to me.
In my apps, I sign my apps so that I can't use any unsigned assemblies; only signed ones. Probably, most apps would be unsigned.

Owner

davidebbo commented Feb 7, 2013

@mahara: the app wouldn't directly reference both, but would end up doing it indirectly by referencing A and B, and that would blow up. That's why the name can't stay the same. And yes, this only applies to unsigned apps, which is most of them out there.

mahara commented Feb 7, 2013

OK. So now suppose this new WebActivator package, named WebActivatorEx (or whatever), created. Would it be required to have its "WebActivator" namespace changed or not in case when applied to that scenario?

Owner

davidebbo commented Feb 7, 2013

Namespace needs to change too.

nberardi commented Feb 7, 2013

@cedricbrasey I would venture to say that even though web activator isn't as popular as JSON.NET it is popular enough to where strong naming would cause major issues for many referencing projects when the version changes and they didn't specifically point to a specific version in their references http://coderjournal.com/2012/04/json-net-strong-naming-and-nuget-woes/

The issue isn't so much the strong naming, it is that when the version changes it has a ripple effect that breaks every referencing project, except for the authors that were the most anal about setting an exact reference version.

What really disappoints me about these posts asking for strong naming, is that the poster always thinks that causing major disruptions in the NuGet ecosystem is some how easier than them downloading the source and strong naming it them self.

I do think that NuGet needs to be a little more smart about strong named assemblies though. And make separate folders in the lib for strong names. "net45s" for example. Also the ability to search for only strong named assemblies on the site would be a nice thing for people like @cedricbrasey. That way everything is still up to the package publisher and people that have to support companies that are strong-name happy can just search for strong-named assemblies.

mahara commented Feb 7, 2013

@nberardi
I don't think there's really any disadvantage for a framework library assembly being signed; the same with .NET Framework library assemblies, and other framework libraries I used in my signed apps. Both unsigned and signed apps would still be able to consume them. However, when a framework library weren't signed, any signed apps wouldn't be able to consume at all, and that really matters. And I consider WebActivator, JSON.NET, or any other libraries in NuGet as framework libraries.
So positioning is important here: a framework library, or just a (sample) app, that not need to be signed.

nberardi commented Feb 7, 2013

@mahara what happens if you have the following relation in NuGet package A references signed assembly in package B. signed assembly in package B is updated and the version changes, but package A is not updated?

Hint: package A no longer works, because package B was signed. So package A has to be recompiled and published before it will work again.

Am I missing something here but isn't JSON.net signed? The point that I'm trying to make is that if I write an application that uses version 4.5 of JSON.net (only for example here) I expect and demand that my application only work with this versioned dependency. As this is what was tested and signed off by QA. What I don't want is for another application to decided that what I actually want is version 4.6... 9 times out of 10 there is a good reason why I've bound to a specific version (functionality, bug fix, etc).

I did a little checking and looking at the top 30 packages (ordered by downloads) in nuget:-
19 packages deploy binaries
11 packages deploy javascript/transforms

out of the 19 packages
18 are assemblies (i.e. project referenced items)
1 is a tool

out of the 18 assemblies
16 are strong named.
2 are not strong named.

Even nuget.core is signed...

Why not have nuget enforce a strong name policy and then use the GAC for assembly storage? After all wasn't that the point behind it's creation? My wish is that WebActivator gets bumped to v2.0.0.0 and signed.

@nberardi

Wasn't the GAC created to resolve this (amongst other issues) scenario?

mahara commented Feb 7, 2013

@nberardi
Surely, it would matter. And it would also be debatable over choosing whether to use file version or assembly version. Let's say, for the sake of this discussion, I'd choose not to update it just for the sake of being up-to-date, and not a necessity.
But try looking at this issue from a larger perspective. Put it this way to make it easier: What would happen if I didn't sign my critical LOB app assemblies, and thus they were altered deliberately, and caused a serious security breach for the whole system.
Now tell me, given these two choices: What would really matter here?

nberardi commented Feb 7, 2013

@cedricbrasey JSON.NET is doing that now but they just started last year after they created a horrible mess in JSON.NET that still hasn't been cleaned up. They fixed the mess by using semVer, which basically means that with each release they don't change the version number of the assembly, so that they aren't constantly breaking all referencing projects. See my blog post that I referenced for more information about what was going on then.

Secondly the GAC was created in a different world almost 13 years ago. Where most applications were installed on a desktop, and there was no such thing as a global package service for sharing of packages like NuGet. I think you have to take a deep dive on how version numbers effect signed packages and then combine that with the knowledge of how NuGet references packages. Because signing assemblies isn't bad, but when combined with the reference system in NuGet it becomes a whole different beast that you guys are failing to see.

nberardi commented Feb 7, 2013

@mahara lets not play what if games, because you probably store your signing key with your source like most other users and most open source projects as @davidebbo alluded to earlier, so all that somebody would have to do is modify your code set the same version number as you are using in production and the breach would occur anyways.

Hell I could do this with JSON.NET, copy it to your LOB app, and suddenly be copying out all your web service calls and proprietary information going back and forth. Strong naming is not a security mechanism, it has never been and never will be, and using it as such just leads to false assumptions like the one you are making about your LOB app.

@cedricbrasey Another application wouldn't affect which version of a library you get. But you might use two different third party libraries that were compiled against two different versions of (for example) Json.NET. NuGet's versioning policy does as well as you can do I think. See this series of blog posts: http://blog.davidebbo.com/2011/01/nuget-versioning-part-1-taking-on-dll.html

mahara commented Feb 7, 2013

@nberardi
LOL... you started the "what-if" game, and then ended it yourself... :D
Yes, I've read @davidebbo concern over where to store the signing key. My next question would then be: Where do MS store their signing key for the whole .NET Framework assemblies? Do they ever distribute it publicly ([assembly: AssemblyKeyFile(@"f:\dd\tools\devdiv\EcmaPublicKey.snk")])? And then back to your question: Is there any reason to store the signing key you mentioned for public access?

To certain degrees, yes, I agree that strong naming is not a security mechanism. Especially, when the should-not-be-disclosed signing key made available to public for access. What can I say? :)

Perhaps, MS should completely remove the following guideline page as it's misleading and/or inaccurate, don't you think so?
CA2210: Assemblies should have valid strong names (http://msdn.microsoft.com/en-us/library/ms182127.aspx)
Visual Studio 2012
...

Rule Description

This rule retrieves and verifies the strong name of an assembly. A violation occurs if any of the following are true:
• The assembly does not have a strong name.
• The assembly was altered after signing.
• The assembly is delay-signed.
• The assembly was incorrectly signed, or signing failed.
• The assembly requires registry settings to pass verification. For example, the Strong Name tool (Sn.exe) was used to skip verification for the assembly.

The strong name protects clients from unknowingly loading an assembly that has been tampered with. Assemblies without strong names should not be deployed outside very limited scenarios. If you share or distribute assemblies that are not correctly signed, the assembly can be tampered with, the common language runtime might not load the assembly, or the user might have to disable verification on his or her computer. An assembly without a strong name has from the following drawbacks:
• Its origins cannot be verified.
• The common language runtime cannot warn users if the contents of the assembly have been altered.
• It cannot be loaded into the global assembly cache.

Note that to load and analyze a delay-signed assembly, you must disable verification for the assembly.
...

nberardi commented Feb 7, 2013

@mahara No reason to remove CA2210, because it is not on by default. Choose "Microsoft Managed Recommend Rules" and see if you find CA2210. It isn't there.

CA2210: Assemblies should have valid strong names (http://msdn.microsoft.com/en-us/library/ms182127.aspx)

If only there were a way to tell stupid & pointless FxCop rules to fuck off... :-p

Owner

davidebbo commented Feb 7, 2013

I put the current proposal on https://github.com/davidebbo/WebActivator/wiki/Signing-WebActivator, so we have a basis of discussion.

mahara commented Feb 8, 2013

@nberardi
Nah, I was just kidding about the idea. I put a bit of sarcasm in there... :D
Certainly, the rule is created for reasons explained there. If there's any argument against it, then such arguments should be directed directly to the rule maker a.k.a. MS.

mahara commented Feb 8, 2013

@davidebbo
Great! Thanks for the detailed proposal. It makes this (and the other one) discussion getting closer to an executable decision.
I'm fine with WebActivatorEx for the name. Seems like "Ex" suffix is a standard protocol in MS world... :D

Owner

davidebbo commented Feb 9, 2013

I pushed a signed WebActivatorEx package to NuGet: http://nuget.org/packages/WebActivatorEx/. Can you please give it a try?

Let's call it experimental at this point, as I need more feedback about it being what we really want before starting to advertise it for general use. Thanks!

I can't do anything until Monday. But consider it first on my to do list.

Thanks for going this.

Thank you @davidebbo - it works for me (tested in VS Express 2012 for Web).

Will you be naming it "WebActivatorEx" in NuGet (currently it appears as a second "WebActivator")?

Will you be changing the NuGet description of the original WebActivator to point people to the new version?

Thanks again for: your open-mindedness, your accommodation of us strong-namers, and for your work.

Owner

davidebbo commented Feb 10, 2013

The package is named WebActivatorEx, but I made the display name be WebActivator. Once we get more confidence that this will all work without breaking people transitioning, the plan is to unlist the old one so only the new one shows up.

Owner

davidebbo commented Apr 7, 2013

Closing this since assembly is now signed.

davidebbo closed this Apr 7, 2013

mahara commented Apr 7, 2013

@davidebbo: Thanks for this!

Bringer128 referenced this pull request in dvsekhvalnov/jose-jwt Nov 28, 2014

Closed

Strong naming #5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment