>I checked this by changing a part of a .sf file, reinserting it into the same
>JAR archive and reading the streamed entries succeeds!
>This is bad, since it means that anyone could simply replace the files, manifest
>and .sf files.
>Note that jarsigner -verify -verbose does report that the signature is broken.
The only thing that is signed is that list of digests, right? How is
someone to create a new manifest with your signature to match the
changes? He would have to sign it with HIS key, and then the user
would be asked to ok. He would see it was not you.
Of course YOU are allowed to change the manifest and resign it.
--
Canadian Mind Products, Roedy Green.
Coaching, problem solving, economical contract programming.
See http://mindprod.com/jgloss/jgloss.html for The Java Glossary.
Michel Gallant - 21 Apr 2004 15:37 GMT
> >I checked this by changing a part of a .sf file, reinserting it into the same
> >JAR archive and reading the streamed entries succeeds!
[quoted text clipped - 6 lines]
> changes? He would have to sign it with HIS key, and then the user
> would be asked to ok. He would see it was not you.
I am not talking about the signed JAR applet infrastructure which DOES seem
to properly check the .rsa file against the .sig file and then verifying this authenciated
file against the recalculated hashes specified in the manifest file.
I am referring to developers who want to manually verify JAR archives. The JAR
and related api imply that the Jar constructor checks the signature (of the .rsa against
the .sig) which is clearly not true, as my test hash shown.
Cheers,
Mitch
Shane Petroff - 21 Apr 2004 20:56 GMT
> I am referring to developers who want to manually verify JAR archives. The JAR
> and related api imply that the Jar constructor checks the signature (of the .rsa against
> the .sig) which is clearly not true, as my test hash shown.
Glad to know I'm not nuts. I did a similar test but figured that I was
misusing something.
--
Shane
Michel Gallant - 21 Apr 2004 23:53 GMT
To clarify, here is a test case showing what I mean (for those who find
this a bit confusing):
Minimal Java code used to programatically load (with verification on) Jar:
http://www.jensign.com/JavaScience/JarVerifIssue/verijar.java
Samples JARs:
test.jar has technically "good" signature (self-signed certificate however)
http://www.jensign.com/JavaScience/JarVerifIssue/test.jar
testbad.jar has one of the entry files (content2.txt) changed and reinserted (but not resigned):
http://www.jensign.com/JavaScience/JarVerifIssue/testbad.jar
testbadsig.jar ONLY changed the .sig file (simply replaced the header line
from Signature-Version: 1.0 to Signature-Version: 1.0a ). No contents
are changed (nor are the hash-entry statements changed.
Since the .rsa file is a PKCS#7 signature over the entire .sig file, this breaks
the signature completely.
http://www.jensign.com/JavaScience/JarVerifIssue/testbadsig.jar
(The above changes were made simply using WinZip ... very handy tool to
look at all files in signed JAR).
The following output using jarsigner.exe tool shows that correct verification status
is reported for all these sample JARs:
------------- jarsigner.exe verification results on good and corrupt JARs ------
jarsigner -verify test.jar
jar verified.
jarsigner -verify testbad.jar
jarsigner: java.lang.SecurityException: SHA1 digest error for contents2.txt
jarsigner -verify testbadsig.jar
jar is unsigned. (signatures missing or not parsable)
----------------------------------------------------------------------------------------
Now, the problem (or lack of understanding) arises when one uses the sample code
verijar.java to load and stream the JAR entries. Reading testbad.jar correctly reports
a bad hash result, but reading testbadsig.jar DOES NOT REPORT ANY PROBLEM, which
seems like a big problem (or serious flaw in the documentation). Evidently the .sig file
is not verified at all:
java verijar testbadsig.jar
Entry META-INF/_F8B7B1C.RSA
Starting to read entry ...
Finished reading entry.
Entry contents1.txt
Starting to read entry with attributes 1
Finished reading entry.
Entry contents2.txt
Starting to read entry with attributes 1
Finished reading entry.
Entry META-INF/_F8B7B1C.SF
Starting to read entry ...
Finished reading entry.
What this means is that to provide complete and proper signed JAR signature verification
(not just hash verification which can always been changed unnoticed) is that JAR loading should
ALWAYS first check the .rsa file against the .sig file and THEN verify the hashed via
.sig through the manifest file to the actual file entries.
So, we need to look at the source code for jarsigner.exe to see when in the process it
invokes the first (.rsa/.sig) signature verification step :-) But I suppose that source is
not public? Next best would be how to use JAR or related public Java api to force
this signature verification (instead of simple and insufficient hash-entry verification).
- Mitch Gallant
www.jensign.com
> > I am referring to developers who want to manually verify JAR archives. The JAR
> > and related api imply that the Jar constructor checks the signature (of the .rsa against
[quoted text clipped - 5 lines]
> --
> Shane
Michel Gallant - 22 Apr 2004 20:25 GMT
To add a bit more to this, one can completely remove the .sig and .rsa files
from the jar and the with verify = true for Jar or JarInputStream constructors,
there are no errors reported on reading any manifest entries.
Therefore, it seems that Jar and JarInputStream initially must try to verify
the .sig/.rsa signature and if that signature fails, then the entry hashes are not
verified at all against hash values in the manifest.mf, nor are any errors returned.
- Mitch Gallant
> To clarify, here is a test case showing what I mean (for those who find
> this a bit confusing):
[quoted text clipped - 79 lines]
> > --
> > Shane