Details
-
Type:
New Feature
-
Status:
Closed
-
Priority:
Major
-
Resolution: Fixed
-
Affects Version/s: None
-
Fix Version/s: 1.0-alpha-2
-
Component/s: None
-
Labels:None
Description
There are potential issues when dealing with including such already signed jars in a webstart application.
In particular see:
http://jira.codehaus.org/browse/MOJO-7#action_49160
and the relevant m1 jnlp issues:
http://jira.codehaus.org/browse/MPJNLP-20
http://jira.codehaus.org/browse/MPJNLP-28
According to the feedback I got on the maven user list, I think that, in order to satisfy everybody, we need to:
- handle already signed jars (MPJNLP-28)
- primarily we need the possibility to unsign a jar. That will probably go to jar:unsign.
- optionally avoid signing jars that are already signed.
- optionally clean the Manifest (maven1 jnlp feature, to work around SDK 1.3 issue - See MPJNLP-20)
Did I miss something?
Now how do we present that to the user?
We could:
- assume that every jar will be signed by default
- let the user list the operation to perform, maybe using something like:
<sign>
<dname>...</dname>
...
<unsign>
<dependency>...</dependency>
</unsign>
<skipSignedJars>true<skipSignedJars>
<cleanManifest>true</cleanManifest>
</sign>
Does that look correct?
-
- handleAlreadySignedJars.diff
- 30/Nov/07 5:07 AM
- 9 kB
- Claude Humard
-
- MWEBSTART-1-patch.diff
- 03/Dec/07 7:58 AM
- 8 kB
- Claude Humard
-
- MWEBSTART-1-test.sh
- 28/Dec/06 7:14 PM
- 2 kB
- Jerome Lacoste
Issue Links
- is related to
-
MJAR-26
Need the ability to unsign a jar
-
-
MWEBSTART-14
support component extension mecanism for already signed jars
-
-
MWEBSTART-170
Add a canSign parameter to authorize or forbbid unsigning of already signed jar
-
Activity
With regard to sign properties in settings.xml, I've been pointed by Brett to the fact that one can use profiles under certain conditions (see MNG-860), or properties.
See the user mailing list,
Message-ID: <5a2cf1f60601261222u258228a4s99eba297fcc13753@mail.gmail.com>
(message titled "[RFC] [m2] template mecanism in settings.xml (initialy for plugin sensitive information)" dated 26 Jan 2006 ).
Using profiles with profiles.xml and ~/settings.xml is the solution for the keyfile stuff. See the free m2 book.
Isn't it problematic to unsign already signed jars and sign it with another certificate ?
Consider for example Java Help jar from Sun.
Is it allowed to unsign this jar ?
Until now, I thought the only solution is to use the component extension mechansim outlined here:
http://java.sun.com/j2se/1.5.0/docs/guide/javaws/developersguide/faq.html#213
What do you think ?
The component extension can be hell for your users, as they might have to click through a multitude of certificates to accept.
That's the exactly the one thing that the jnlp spec tries to enforce by having all jars certified by one certificate... the only problem is they won't allow that those jars are also signed by other certificates too.
It's easy to overwrite a signed jar's signature:
First sign it and then remove META-INF/xxx.RSA and SF
Problem is the maven jar plugin won't allow you to sign a jar which is already signed.
A copy from my mail to user list:
I know this very easy way works though:
- Sign them (even if they are signed - the jar plugin currently doesn't allow this)
- Remove the .SF/.RSA file if it's not yours.
The other way around probably works too.
So only thing the webstart plugin should do is:
- If it's already signed by someone else (I would hack this for now to "if it's already signed in the repo" as you don't want to resign already signed files by yourself in target/jnlp)
then first remove .SF/.RSA (and .sf/.rsa) from the Zip file before signing it.
Sounds easy enough right? And in webstart the ANT tasks are already included and it includes a zip and unzip task. But there isn't an Unzip class (there is a zip class) Using Sun's ZipStream's is more boilerplate I presume.
- Sign them (even if they are signed - the jar plugin currently doesn't allow this)
- Remove the .SF/.RSA file if it's not yours. The other way around probably works too.
- If it's already signed by someone else (I would hack this for now to "if it's already signed in the repo" as you don't want to resign already signed files by yourself in target/jnlp) then first remove .SF/.RSA (and .sf/.rsa) from the Zip file before signing it.
My concern is not a technical but a judicial matter.
If unsigning jars (from SUN for example) is legally allowed, then no problem.
If not, there has to be an alternative way.
I'm not a lawyer, so bear with me, if this does not make sense ![]()
I committed a work (r2871) based on a patch from Andrius Šabana. This introduces an unsign jar (that will be moved to the jar plugin later on).
The code is not yet enabled. I want to write some test cases first. If anyone wants to give a hand...
I'd like to help get unsigning functionality in there. I downloaded the plugin from SVN and tried compiling it. When running JarUnsignMojoTest, I get this:
Running org.codehaus.mojo.webstart.JarUnsignMojoTest
[debug] keytool executable=[C:\Program Files (x86)\Java\jre1.6.0\..\bin\keytool.exe]
[debug] mdkirs: false c:\DOCUME~1\KENGEI~1\LOCALS~1\Temp
[debug] Executing: "C:\Program Files (x86)\Java\jre1.6.0\..\bin\keytool.exe" -genkey -dname "CN=CN, OU=OU, L=L, ST=ST, O=O, C=C" -alias test -keypass 123456 -keystore c:\DOCUME~1\KENGEI~1\LOCALS~1\Temp\keystore -storepass 123456
[warn] 'C:\Program' is not recognized as an internal or external command,
[warn] operable program or batch file.
This is a problem in plexus, and is equivalent to http://jira.codehaus.org/browse/MJAR-49.
So moving to plexus-utils 1.1+ does solve the "spaces in executable name" problem. Unfortunately, it requires moving to an alpha version (1.0-alpha-?) of plexus-container-default, which requires maven-embedder 2.1-SNAPSHOT, which requires maven-core 2.1-SNAPSHOT. Because of all of this, I have little hope of the jar unsigning being available before Maven 2.1.
Ken,
> Because of all of this, I have little hope of the jar unsigning being available before Maven 2.1.
You can always install your SDK in a different location ?
E.g. C:\Programs or D:\Java
When I use Windows, I always install my programs under C:\Programs. There are too many problems with spaces in PATH on that platform.
What kind of ETA are we looking at for this enhancement? We're running into this at work and I have been tasked with resolving the issue (lucky me). If it's due to be resolved soon and generally available to us all, then I can probably stall a bit and just wait. However, if it's going to be a while (>3 mos. or so), then I'll need to figure something out on my own or borrow from the suggested implementations. Perhaps I could just deploy a SNAPSHOT of the module into our repository and we could use that (is this turned on yet).
James, Ken,
if you want to help to get this fixed, feel free. I won't work on it until I say something in that issue.
Try to reuse the unsign jar mojo I introduced some time ago. If you have the space in path issue on Windows, install Java in a different place.
I've created a patch to handle already signed jars using the "jnlp-download-servlet"-mojo. The patch is based on the maven-webstart-plugin-1.0-alpha-2 revision 5622.
Basically, the following changes were made:
- added new boolean configuration-property named "unsignAlreadySignedJars" (alias="unsign" default-value="false").
- moved the already implemented method "removeExistingSignatures()" and depending methods/properties from AbstractJnlpMojo to AbstractBaseJnlpMojo, so this method is available to the JnlpDownloadServletMojo as well.
- in AbstractBaseJnlpMojo.signJars(), if unsignAlreadySignedJars is set to true in config, the signature of jars which are already signed, is removed prior to packing and signing with own key.
- fixed issue where subfolders and their content in src/main/jnlp/resource-folder were not copied to working-directory.
- improved removeExistingSignatures()-method: only jars which contain a signature are unsigned. Jars without signature are ignored.
- added new boolean configuration-property named "unsignAlreadySignedJars" (alias="unsign" default-value="false").
- moved the already implemented method "removeExistingSignatures()" and depending methods/properties from AbstractJnlpMojo to AbstractBaseJnlpMojo, so this method is available to the JnlpDownloadServletMojo as well.
- in AbstractBaseJnlpMojo.signJars(), if unsignAlreadySignedJars is set to true in config, the signature of jars which are already signed, is removed prior to packing and signing with own key.
- fixed issue where subfolders and their content in src/main/jnlp/resource-folder were not copied to working-directory.
- improved removeExistingSignatures()-method: only jars which contain a signature are unsigned. Jars without signature are ignored.
Claude,
thanks a lot for your contribution. Some comments:
- fixed issue where subfolders and their content in src/main/jnlp/resource-folder were not copied to working-directory.
Is this the change in src/main/java/org/codehaus/mojo/webstart/JnlpDownloadServletMojo.java ?
This is a separate issue, right ? If so, can you create a new issue in Jira ?
How long did you test this change ?
- fixed issue where subfolders and their content in src/main/jnlp/resource-folder were not copied to working-directory.
Ok, I split up the submitted "handleAlreadySignedJars.diff"-patch into two separate patches:
- Concerning the copy-subfolder-issue, I've created a new issue (
MWEBSTART-59) and submitted a separate patch there. - I've uploaded a new diff-file here (
MWEBSTART-1-patch.diff) which handles only the unsign-issue as described in my previous post. This patch works well without theMWEBSTART-59-patch as long as there are no subfolders within the jnlp-workdirectory.
- Concerning the copy-subfolder-issue, I've created a new issue (
MWEBSTART-59) and submitted a separate patch there. - I've uploaded a new diff-file here (
MWEBSTART-1-patch.diff) which handles only the unsign-issue as described in my previous post. This patch works well without theMWEBSTART-59-patch as long as there are no subfolders within the jnlp-workdirectory.
Thanks for the patch. I also updated the documentation slightly. Don't hesitate to send me a how-to or an example.
PS: try to avoid tabs in the code !
I'm trying to solve this problem - in our case, we want to use Java Help, which requires a jar file signed by Sun. At the moment, we're doing it via the extension mechanism. This works, except for the fact that we have to manually copy the jar file (which is, obviously, a hassle). So can you provide an example of how to get the "unsignAlreadySignedJars" to work?
Havard, I've not used this feature yet.
Basically if you enable the property, the plugin should do everything on its own (identigy the already signed jars, and unsign them).
It would be great to have a integration test for it. If you feel like writing one...
OK, I figured out the answer to my previous questions - here is a sample POM snippet:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>webstart-maven-plugin</artifactId>
<version>1.0-alpha-2-SNAPSHOT</version>
<configuration>
<jnlp>
<mainClass>${ttAppMainClass}</mainClass>
</jnlp>
<sign>
<keystore>${project.basedir}/src/main/jnlp/resources/pdKeystore</keystore>
<storepass>secretPW</storepass>
<alias>signerAlias</alias>
</sign>
<unsignAlreadySignedJars>true</unsignAlreadySignedJars>
<verbose>false</verbose>
</configuration>
</plugin>
</plugins>
</build>
I hope it is not too late to chime in with this but the best way to deal with already signed jars is with the extension element in JNLP. For example, I do this in my app that includes javahelp:
<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0+" codebase="http://localhost:8080/test-app/"
href="testapp.jnlp">
<information>
<title>Test App</title>
<vendor>Test Apps, Inc.</vendor>
<offline-allowed />
</information>
<security>
<all-permissions />
</security>
<resources>
<j2se version="1.4+" max-heap-size="256m" />
<jar href="test-app-1.0-SNAPSHOT.jar" main="true" />
<extension name="Java Help System" href="javahelp.jnlp" />
</resources>
<application-desc
main-class="com.company.testapp.Test" />
</jnlp>
The javahelp.jnlp looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<jnlp spec="1.0+" codebase="$$codebase" href="$$name">
<information>
<title>Javahelp</title>
<vendor>Sun Microsystems, Inc.</vendor>
<offline-allowed/>
</information>
<security>
<all-permissions/>
</security>
<offline-allowed/>
<resources>
<jar href="javahelp-2.0.02.jar" main="true"/>
</resources>
<component-desc/>
</jnlp>
This way test-app-1.0-SNAPSHOT.jar can be signed with a different cert chain than javahelp-2.0.02.jar which comes already signed by our friends at Sun Microsystems. In fact since it is already signed there is no need to sign it.
If you guys could make the webstart plugin detect an already signed JAR and use this extension mechanism instead of trying to unsign/sign it then you would be my heros.
Hope this helps.
Acegi's jar are good test cases (they are signed by Ben Alex in ibiblio).
When unsigning, don't forget to remove META-INF/.SF and META-INF/.RSA (case insensitive)
An option unsignAnyAlreadySigned would be handy, not to have to note every jar to unsign.
Some properties of sign should be able to set in ~/.m2/settings.xml (this should be documented too), such as:
path to keyfile, key type, alias, passphrase, etc. It's probably recommended to talk this over with core developers to formalize this in settings.xml as it might be needed for other use cases too.