wood burning stoves 2.0*
The moose likes Java in General and the fly likes Programmatically repacking and signing jar, veryfing problem Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "Programmatically repacking and signing jar, veryfing problem" Watch "Programmatically repacking and signing jar, veryfing problem" New topic
Author

Programmatically repacking and signing jar, veryfing problem

Raf Szczypiorski
Ranch Hand

Joined: Aug 21, 2008
Posts: 383
Hi. I wrote simple code to programmatically repack, sign and again pack a jar file. (To those who frown upon signing jars programmatically and including key passes in files / programs, we use this just in our development environments in a ServletContextListener when launch the webapp from Eclipse, so that certain jars are signed. for real deployment we won't do that ;-)).
I repack the jar at first, then I sign it, and then I pack it again. I do this because the jars are later used by Java Web Start, which supports standard jars (repacked signed version), gzipped jars (repacked, signed and gzipped version) and pack.gz jars to further decrease the file size to download (repacked, signed, and then packed and gzipped jars).
So, the problem is that it doesn't work :-) at least, sometimes it does and sometimes it doesn't, which makes it unusable. It works for jconsole from JDK/lib, but not for the sample jar attached to this post.
Here is the code (it requires tools.jar in the classpath as I am using sun.security.tools.JarSigner) (it is not exactly the code I am using, but this is the simples code that shows the problem):

The problem originated from JWS saying that some jars couldn't be verified, and so I did a lot of checking, and it turns out the problem were the signed and then repacked files. So, I wrote this code to debug, and when I run it and then try to verify the jar I get:

jarsigner: java.lang.SecurityException: Invalid signature file digest for Manifest main attributes

So I concentrated on the MANIFEST.MF file on the sample jar attached. I debugged through my code and after each step I checked the manifest. Here are my findings:
1) initial manifest:

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.0
Created-By: 1.5.0_13-b05 (Sun Microsystems Inc.)
Implementation-Title: Test
Implementation-Vendor: Test
Implementation-Version: build.1717
Specification-Title: Test
Specification-Vendor: Test
Specification-Version: Test

2) repacked manifest:

Manifest-Version: 1.0
Implementation-Vendor: Test
Ant-Version: Apache Ant 1.7.0
Implementation-Title: Test
Implementation-Version: build.1717
Specification-Vendor: Test
Specification-Title: Test
Created-By: 1.5.0_13-b05 (Sun Microsystems Inc.)
Specification-Version: Test

As you can see, repacking changed the sequence of the main attributes.
3) repacked and signed manifest:

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.0
Implementation-Vendor: Test
Implementation-Title: Test
Implementation-Version: build.1717
Specification-Vendor: Test
Created-By: 1.5.0_13-b05 (Sun Microsystems Inc.)
Specification-Title: Test
Specification-Version: Test

Name: test/Test.class
SHA1-Digest: PzJU1Pg+2lm7khiVXeh+1xerBQE=

As you can see, signing also mixes the entries, but this is not a big deal. The jar verifies fine at this point.
4) repacked, signed, and then repacked again manifest:

Manifest-Version: 1.0
Implementation-Vendor: Test
Ant-Version: Apache Ant 1.7.0
Implementation-Title: Test
Implementation-Version: build.1717
Specification-Vendor: Test
Specification-Title: Test
Created-By: 1.5.0_13-b05 (Sun Microsystems Inc.)
Specification-Version: Test

Name: test/Test.class
SHA1-Digest: PzJU1Pg+2lm7khiVXeh+1xerBQE=

As you can see, the manifest attributes returned to their sequence after their first repack, which makes the signature file's (TESTTEST.SF in my example) attributes (SHA1-Digest-Manifest-Main-Attributes and SHA1-Digest-Manifest) contain invalid hashes. The hashes were computed from a different manifest, and placed in the signature file, and after repacking, they will be different as the manifest is different, and comparison of the values in the SF file against the computed values that the veryfier makes on the fly will fail. Hence the problem.

(As I mentioned, jconsole.jar works fine but this is only because it has very few manifest main attributes and they do not get reordered while packing. The problem is we use a few third-party jars that actually have quite a few attributes and the problem occurs.)

Now, when I run the same sequence with the pack200, unpack200 and jarsigner tools it works fine. When I checked the manifest after each step, it turns out that pack200/unpack200 sequence does not reorder the manifest main attributes. I thought that maybe the manifest file is "passed" while packing, and added this to my pack and unpack methods:

but it didn't help at all.

What am I doing wrong here? How is the pack200 tandem different than Pack200.Packer/Unpacker classes? What can I do to make this work?

Regards,
Raf

P.S Tested with JDK 1.6.14 and .15
P.S2 Attached the jar as jpg as jars cannot be attached. Please change the name to orig.test.jar.


[oig.test.jpg]

Raf Szczypiorski
Ranch Hand

Joined: Aug 21, 2008
Posts: 383
When I replace the call to pack with a JarInputStream to the one which takes a JarFile, it works! I think this has something to do with this docs bit:

The modification time and deflation hint attributes are not available, for the JAR manifest file and its containing directory.

No this is weird and not really usable...
Could someone please explain what the hint attribute actually does, what the 3 values it takes do (I read in the javadocs about it, also in the tool doc for pack200, but I am still confused about what it actually does).

Regards,
Raf
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: Programmatically repacking and signing jar, veryfing problem
 
Similar Threads
Manifest destiny!
Determine version of a struts.jar
Two questions about applet security
Manifest Version Headers Appearing Out Of Order
Struts version for Weblogic 9.2