| Summary: | Could there be a "prefer signed" option? | ||||||
|---|---|---|---|---|---|---|---|
| Product: | [Eclipse Project] Equinox | Reporter: | David Williams <david_williams> | ||||
| Component: | p2 | Assignee: | P2 Inbox <equinox.p2-inbox> | ||||
| Status: | CLOSED WONTFIX | QA Contact: | |||||
| Severity: | enhancement | ||||||
| Priority: | P3 | CC: | aniefer, john.arthorne, matthew, pascal, thomas, tjwatson | ||||
| Version: | 3.6 | ||||||
| Target Milestone: | --- | ||||||
| Hardware: | PC | ||||||
| OS: | Windows 7 | ||||||
| Whiteboard: | stalebug | ||||||
| Attachments: |
|
||||||
|
Description
David Williams
(In reply to comment #0) > I guess it is debatable, but to me, a signed bundle and an unsigned bundle do > have the "same bits" (same executable code) ... just difference is signing. > It seems unreasonable to me to have to have a new qualifier, just to say you > now have a signed version. Signed versus unsigned bundles do not have the same bits and that fact isn't debatable ;) Executable code is only one possible part of the "bits" that make up a bundle, and since at least the MANIFEST.MF is changed then the contents of the bundle jar are different. So, while it wouldn't be impossible to introduce such an option, it would mean changing the identity of an installable unit to be more than an [id,version] pair, to something like [id,version,signedness]. The notion of an [id,version] pair uniquely identifying an installable unit is a pretty deeply ingrained concept in p2. On the other hand, you could look at signing as part of the delivery mechanism, just as we do with pack.gz. You compile and jar things together. That creates the bits. The way we deliver those bits doesn't affect the id and version. We optionally sign sign and pack them. When installing, we optoinally both unpack and unjar. So we might have at least four forms of the same bits. The folder The signed jar The unsigned jar The jar.pack.gz All of them are represented by the same id and version and we already do prefer one delivery mechanism over another (.jar.pack.gz over .jar). So why not prefer signed over unsigned?
> Signed versus unsigned bundles do not have the same bits and that fact isn't
> debatable ;) Executable code is only one possible part of the "bits" ...
Hmm, I wonder why the qualifier doesn't change, then? :) Plus, I think everyone would agree that conditioning a jar in preparation to be packed (and signed) really can change the bits, so there is another case the qualifier should be incremented?
Or, I guess it could be said we have quantum bundles ... that they don't really exist until observed. And unconditioned, unsigned bundles are never observed. [can you tell, I've been watching the science channel a lot lately] :)
Of course, we all know in reality, not every bundle is always conditioned and signed in every build. Maybe it should be, but ... hard to do, hard to insist on .... another case where p2 expects a level of perfection that's hard to achieve.
I like the "distribution" idea Thomas mentioned. In fact, one could imagine a solution where mirror and install tasks had options that said "fail if bundles are not signed" or "fail if bundles are not conditioned" ... you would need a list of exceptions, since not literally every bundle is intended to be signed or conditioned. That "fail rule" would certainly prevent "bad repos" from being created ... I wonder how long it would take to create one of those? Seems easier just to say "prefered signed" and let the repo be a little bit imperfect at times -- that is, allow incremental improvement.
But ... I agree, there is no obvious and easy (perfect?) solution.
(In reply to comment #2) > On the other hand, you could look at signing as part of the delivery mechanism, > just as we do with pack.gz. You compile and jar things together. That creates > the bits. The way we deliver those bits doesn't affect the id and version. We > optionally sign sign and pack them. When installing, we optionally both unpack > and unjar. So we might have at least four forms of the same bits. > > The folder > The signed jar > The unsigned jar > The jar.pack.gz > > All of them are represented by the same id and version and we already do prefer > one delivery mechanism over another (.jar.pack.gz over .jar). So why not prefer > signed over unsigned? There is an important difference here. There is one unique artifact key (id/version) representing the artifact. There can be multiple representations of that artifact in a repository (jar, pack.gz, etc). Each of those representations includes a description of the transformations that need to happen as it is transferred, so that in all cases you end up with the identical result. That is the key point - it allows different representations in the repository for storage and transport efficiency reasons, but in all cases the end result must be identical. The difference with signed vs. unsigned is that you would not end up with the same result so the different representations are not equivalent. (In reply to comment #3) > > Signed versus unsigned bundles do not have the same bits and that fact isn't > > debatable ;) Executable code is only one possible part of the "bits" ... > > Hmm, I wonder why the qualifier doesn't change, then? :) Plus, I think everyone > would agree that conditioning a jar in preparation to be packed (and signed) > really can change the bits, so there is another case the qualifier should be > incremented? > > Or, I guess it could be said we have quantum bundles ... that they don't really > exist until observed. And unconditioned, unsigned bundles are never observed. > [can you tell, I've been watching the science channel a lot lately] :) They don't really exist until they are "published" into some repository. Of course the bundle undergoes transformation while it is being built, but once it is built and made available to the world, it needs to stay unchanged. Otherwise as you noted originally, if someone has installed it already they have no way to get a different copy of the same id/version again. Your assumption would hold true if the .jar file was normalized in all cases but I think Davids point concerns what should happen if signing occurs in a new delivery once a deliver with unsigned material has been made. Compare that with what happens if a delivery is first made without normalizing and packing and then it's followed by a delivery where packing was made. The pack200 is far more intrusive in that it actually does change the bits in the included .class files. I.e. you have a scenario that with great certainty will yield different representations depending on preferred transportation. You name storage and efficiency as things being separate from the actual identified artifact. But what about integrity? It's still just a transportation concern. What harm could come from favoring that that cannot come from favoring pack200? (In reply to comment #6) > Your assumption would hold true if the .jar file was normalized in all cases > but I think Davids point concerns what should happen if signing occurs in a new > delivery once a deliver with unsigned material has been made. Compare that with > what happens if a delivery is first made without normalizing and packing and > then it's followed by a delivery where packing was made. The pack200 is far > more intrusive in that it actually does change the bits in the included .class > files. I.e. you have a scenario that with great certainty will yield different > representations depending on preferred transportation. If you had two representations for the same artifact, one being a non-normalized jar and the other being pack200.gz, it would be a bug from the p2 design perspective. Different users installing the same artifact key could end up with a different result in their install. This is a bad outcome - installs aren't reproducible and support/serviceability becomes a problem. Imagine asking a user, "you say you have Feature X, version Y installed, but *which* Feature X, version Y do you have? > You name storage and efficiency as things being separate from the actual > identified artifact. But what about integrity? It's still just a > transportation concern. What harm could come from favoring that that > cannot come from favoring pack200? There is no problem with favouring one artifact representation over another as long as the result is the same. Signed jars are not the same as unsigned jars. This isn't only a transportation concern because signed jars can behave quite differently from unsigned jars if you have runtime signature verification enabled. We have mirroring tools for comparing against previous builds. When using a baseline, if a bundle has the same version from the previous build then the artifact is taken from the previous build. (We can also do a "smart" comparison, to help decide if the jar needs to be retagged with a higher version. Signing and conditioning should both show up as differences. Signing because of the signature files added, and conditioning because of changes around the eclipse.inf file). However, I doubt that anyone is using this other than the platform. If everyone always did this comparison against previous builds then it would be a little more explicit that they need to up-version for any changes. (In reply to comment #7) > There is no problem with favouring one artifact representation over another as > long as the result is the same. Signed jars are not the same as unsigned jars. Were is the recommendation that says - if you want to sign a bundle, you better change it's version? > This isn't only a transportation concern because signed jars can behave quite > differently from unsigned jars if you have runtime signature verification > enabled. That can be said about a unpacked versus packed jars too when you have pack200 enabled. Sure, you can put an unpacked jar in the repository as a sibling to cover that, but it doesn't change anything. You would get a more or less identical situation using different artifact descriptors for signed and unsigned. Two use-cases: 1. I use a bundle in my product. The original is found in a Maven repository which makes it cumbersome to deal with from an install perspective. I therefore decide to put it in the repository that I'm publishing. As part of that, I decide to pack the jar, relying on that the pack200 utility will not break my installs. I do thorough tests to verify that everything works as expected. 2. An organization prefer that the employees use an internal repository of blessed things. This repository will only contain signed material. A central function downloads required material from the net, verifies that it is OK, signs it, and adds it to the blessed repository. The whole idea with the repository is to increase quality and security so the repository is rigorously tested. Both use-cases show a scenario where the bits do change. The relevance is that p2 is used merely as a provisioning mechanism and the user makes the most out of it. It's never involved in the build of the artifacts so tweaking versions is not possible (that would indeed break things). I'm not sure I see any problems with that. This issue has come back into my consciousness due to the Foundation's "old" certificate expiring in April, 2012, so many bundles built before then show a warning of expired certificate, and while no known cases of that hurting anything, to get the new signature requires rebuilding, with new qualifier, not merely "resigning" the jar. I am not sure p2 could ever efficiently pick a new jar, if it had "a more recent signature" ... guess it could if part of metadata ... but would be kind of cool to merely resign, and not have to change qualifier, for every bundle, every few years, just to get new signing certificate. (And, yes, yes, I know, different bits ... but ... not associated with executable function :). Just thinking out-loud, I suppose an alternative approach would be a tool, say a "jarsignerupdater" which would resign the jar and add a letter, say, to the qualifier. This would have "trickle" effect that features, etc, should have to be changed, but ... its a good thought experiment, since it shows "nothings really changed" about the bundle, except the qualifier (well, and signature :) I've always been surprised by the expiration of the certificates and their implication on our jars, and thus I'm wondering if we are using them appropriately. Let me explain what I mean: When two countries sign a treaty, the fact that there is the signature of a president and a stamp on the piece of paper is enough to consider the treaty valid. When the president or the stamp of a country change, the treaty does not have to be re-signed. The simple fact that the individuals and their tools (stamps) involved in the signature were authority at the time are sufficient to guarantee that the treaty will be valid forever. Now, if the treaty is the jar and the stamp is the signature created by the certificate, I don't understand why a jar that has been signed with a valid certificate can become invalid or expire. Therefore my question, do we use certificate and signature correctly? Of course adding an option to not complain when invalid signature is encountered would be easier :) I think the difficulty is that there isn't a secure way of determining when a jar was signed. If dates were ignored and the Eclipse certificate was compromised then jars could be signed indefinitely with the compromised certificate. (Certs can also be revoked, but that hasn't been effective for web browsers.) (In reply to comment #13) > I think the difficulty is that there isn't a secure way of determining when a > jar was signed. Yes there is. There is a trusted timestamp authority which provides authenticated timestamps (http://www.ietf.org/rfc/rfc3161.txt). We use this at Eclipse (see bug 263708). Our existing signatures *are* still valid after the certificate expires. I think the jarsigner tool just spits out this information because it might indicate you need to renew your certificate. The message does not mean that the signature is invalid. We're all fine here. John, if the signature are still valid, have we ever looked into changing the signature verification (which I believe equinox own) to detect this case and avoid the complaint? CC'ing tom as he may know. Are we just talking about the warning that appears in David's jar signing report? I believe this is coming from executing the JDK's jarsigner tool. I don't think an Eclipse end-user would ever see this. Given David initial description I thought we were talking about a p2 generated message, but maybe I'm getting that wrong. Created attachment 216323 [details]
screenshot of the pb
(In reply to comment #18) > Created attachment 216323 [details] > screenshot of the pb pb? Problem? I don't see the "not signed" warning in that image. Only the "already installed" grayed out icon? Or are my eyes going out on me? I don't think "signed or not" can be detected until you try and install something. And, expired certificate but valid at time of signature is not treated as "unsigned" (or give warning) with equinox. There might be a "strict" option you could turn on to make it report those, but not that I know of. The "warnings" that people are seeing/talking about are for the straight "jarsigner -verify" reports I create, such as http://build.eclipse.org/juno/simrel/reporeports/reports/verifydiroutput/verified.txt (I should probably right an equinox app to check signatures :) BUT, the reason this came up, was someone suggested, "if you really wanted to get rid of the warnings, you can just sign the jar again, you do not need to rebuild it" and in response I then gave the tired warning of "well, if the bits change in anyway the qualifier should change" or users (or, some adopters, that "pull" bits with p2) won't get the newly signed bundle. And, all that just reminded me of this issue. I still think _requiring_ the qualifier to change, even if just resigned, is sort of impossible to do. Such as, in an ideal case, a company could "resign" our bundles with their own certificates, to stamp them as "these are in same form as when they came from company X product" ... but ... users would never "get" those versions, since qualifier would not have changed (if they already had some installed). And to confirm what John said, yes, besides have a steady source of income :) the security companies do claim that "should have limited life time since the longer a certificate/signature is out there, the higher the chance someone would have stolen the key or cracked the code, so best to renew every now and then". I have seen in my internet searches, there are some programs or settings that can be ran in "strict" mode, that would not accept jars as valid, even if cert was valid at time of signing ... but, I suspect that's mostly for banks using applets, or something. I've never heard of a real use case. The only hint I got of a problem is that you might not be able to resign a code bundle with and additional certificate, if one of its authenticating certs has expired, but a) very hard to find good documentation about this sort of thing, and b) not sure anyone is doing that with our bundles? Ignore comment #18. Wrong bug. (In reply to comment #15) > John, if the signature are still valid, have we ever looked into changing the > signature verification (which I believe equinox own) to detect this case and > avoid the complaint? > CC'ing tom as he may know. I believe this has already been answered, but I will reconfirm. The Foundation uses signs with a TSA and the framework validates it when verifying a signed bundle. This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant. If the bug is still relevant, please remove the "stalebug" whiteboard tag. |