I'm trying to troubleshoot an issue with signed jars not working under appletviewer. My main goal is to run it outside of the browser, so I tried using appletviewer - if you have other suggestions, let me know.
Here's the context:
- Ubuntu 11.10
Java:
$ java -version java version "1.6.0_26" Java(TM) SE Runtime Environment (build 1.6.0_26-b03) Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02, mixed mode)
Here's the problem:
- I have a jar myjar.jar that contains an applet inside
- It works properly in browser, but not when run under appletviewer
The jar is signed:
$ jarsigner -verify -certs -verbose -keystore /etc/ssl/certs/java/cacerts myjar.jar ... smk <file size> <file date> <file name> X.509, CN=xxx, OU=xxx, OU=xxx, O=xxx, L=xxx, ST=xxx, C=xxx [certificate is valid from m/d/y h:m PM to m/d/y h:m PM] X.509, CN=yyy, OU=yyy, OU=yyy, O=yyy, C=yyy [certificate is valid from m/d/y h:m PM to m/d/y h:m PM] [KeyUsage extension does not support code signing] X.509, OU=zzz, O=zzz, C=zzz (alias1) [certificate is valid from m/d/y h:m PM to m/d/y h:m PM] ... jar verified.
and, though the intermediate signing certificate (yyy above) is not present, the root one (zzz - or alias1) is:
$ keytool -list -v -keystore /etc/ssl/certs/java/cacerts -storepass changeit|grep alias1
alias1, Mmm d, yyyy, trustedCertEntry,
Running this:
$ appletviewer myhtml.html
gives:
Caused by: java.security.AccessControlException: access denied (java.lang.RuntimePermission preferences)
Question set 1:
- Is the assumption that when a root certificate is present, all following intermediate certificates are assumed acceptable for verification purposes? In above case, is it necessary to have yyy in the cacerts file?
- When jar is signed, as myjar.jar is, is it assumed that appletviewer should run with no restrictions?
- Is there a better way to run it to avoid this?
- Why is this working differently in browser than with appletviewer?
Not being sure of above, I tried adding the certificate to another local file, called cacerts2. I can confirm that:
- keytool lists that certificate in cacerts
jarsigner output is now like this:
$ jarsigner -verify -certs -verbose -keystore cacerts2 myjar.jar ... smk <file size> <file date> <file name> X.509, CN=xxx, OU=xxx, OU=xxx, O=xxx, L=xxx, ST=xxx, C=xxx [certificate is valid from m/d/y h:m PM to m/d/y h:m PM] X.509, CN=yyy, OU=yyy, OU=yyy, O=yyy, C=yyy (alias2) [certificate is valid from m/d/y h:m PM to m/d/y h:m PM] [KeyUsage extension does not support code signing] X.509, OU=zzz, O=zzz, C=zzz (alias1) [certificate is valid from m/d/y h:m PM to m/d/y h:m PM] ... jar verified.
Note that now I have the intermediate alias (yyy - or alias2) present in the output and verified both against alias1 and alias2. Running the appletviewer like this:
$ appletviewer -J-Djavax.net.ssl.trustStore=cacerts2 -J-Djavax.net.ssl.trustStorePassword=changeit myhtml.html
still results in the same exception.
Question set 2:
- Is the above the right way to supply the trust store?
- Does the above mean that appletviewer will use it in the same way as jarsigner will when passed -keystore command for its verification purposes?
The third thing I tried is making a policy file like this (this is in mypolicy.policy):
keystore "cacerts2";
// Tried with this and without the next line:
//keystorePasswordURL "cacerts.pass";
// where file cacerts.pass has only "changeit" / "changeit\n" in it (tried both)
// Tried the following three:
grant signedBy "alias1" {
//grant signedBy "alias2" {
//grant {
permission java.lang.RuntimePermission "preferences";
};
and running like this:
$ appletviewer -J-Djava.security.policy=mypolicy.policy myhtml.html
and like this:
$ appletviewer -J-Djavax.net.ssl.trustStore=cacerts2 -J-Djavax.net.ssl.trustStorePassword=changeit -J-Djava.security.policy=mypolicy.policy myhtml.html
Results:
- grant without any signedBy specs worked, so I can confirm the policy is picked up
- grant with either signedBy is failing
Question set 3:
- Is this the correct way to specify policy and signedBy? I find the docs from Oracle incomplete on this topic
- Is policy file even used when jar is signed?
- Any other ideas? :)
Use Java Web Start, which could launch applets free-floating since around the 1.2 days. (Or convert the code to a frame.)
If the main point of this is testing, you might try Appleteer. AFAIR I never got around to implementing a sand-box for it (so even unsigned applet code would behave as if it were trusted).
AppletViewer used to launch applets without a security sand-box, even if they were not signed. Now it is the opposite and has a sand-box, and there is no way to get it to accept signed code as trusted!
IDEs seem to apply a policy file to the viewer, to get it to act however the user configures the IDE.