Difference between revisions of "JGridstart/Bouncycastle and Java Web start"

From PDP/Grid Wiki
Jump to navigationJump to search
(add JNLP sign note)
(split page)
Line 41: Line 41:
 
Now when the Java Web Start application is run, the user has to accept a warning dialog twice: one for the application itself, and one for the BouncyCastle extension. This is a little troublesome, since the user doesn't care about the extension; if he has just consented to grant the application access why does it ask for it again?
 
Now when the Java Web Start application is run, the user has to accept a warning dialog twice: one for the application itself, and one for the BouncyCastle extension. This is a little troublesome, since the user doesn't care about the extension; if he has just consented to grant the application access why does it ask for it again?
  
There is a workaround for the Sun Java runtime environment that requires a signed JNLP file.
+
The solution to this issue is to sign the BouncyCastle JAR with the same key as the application JAR; the resulting BouncyCastle JAR will be signed twice: <tt>META-INF/BC-KEY.*</tt> gives the security permissions to be used as a cryptography provider, and <tt>META-INF/<MY-KEY>.*</tt> gives the other permissions. Because you use the same key for your application as BouncyCastle, the user only needs to accept it once.
  
==Workaround: one warning dialog only (Sun JRE)==
 
'''Note that this workaround appears to work only for Sun Java, not for OpenJDK.''' The following section describes how to get the best of both worlds.
 
  
The security warning for the BouncyCastle extension (the second warning) can be avoided if one uses a policy file in the application. This policy file explicitely grants access to certain operations, and these operations can be BouncyCastle's as well. So we get the following files
+
If you don't want to sign the BouncyCastle JAR yourself, it is still possible to workaround the issue, please see [[JGridstart/Bouncycastle_and_Java_web_start_workaround|Bouncycastle and Java web start workaround]].
 
 
<tt>app.jnlp</tt> (note the new property tag):
 
<?xml version="1.0" encoding="utf-8"?>
 
<jnlp spec="1.0+" href="app.jnlp" codebase="http://somewhere/">
 
  <information>
 
    <title>App</title>
 
    <vendor>Nikhef</vendor>
 
    <homepage href="http://somewhere/"/>
 
  </information>
 
  <security>
 
    <all-permissions/>
 
  </security>
 
  <resources>
 
    <j2se href="http://java.sun.com/products/autodl/j2se" version="1.3+"/>
 
    <jar href="app.jar"/>
 
    <extension name="BouncyCastle cryptography library" href="bcprov.jnlp"/>
 
    <property name="java.security.policy" value="http://somewhere/bcprov.policy"/>
 
  </resources>
 
  <application-desc main-class="app.Main"/>
 
  </jnlp>
 
 
 
<tt>bcprov.jnlp</tt>, now without any permissions (note the removed security section):
 
  <?xml version="1.0" encoding="UTF-8"?>
 
  <jnlp spec="1.0+" codebase="http://somewhere/" href="bcprov.jnlp">
 
  <information>
 
    <title>bcprov-jdk14</title>
 
    <vendor>Sun Microsystems, Inc.</vendor>
 
    <offline-allowed/>
 
  </information>
 
  <resources>
 
    <jar href="bcprov-jdk14-142.jar"/>
 
  </resources>
 
  <component-desc/>
 
  </jnlp>
 
 
 
and a new <tt>bcprov.policy</tt>, which grants BouncyCastle its access:
 
  grant {
 
  // allow BouncyCastle to register itself
 
  permission java.security.SecurityPermission "Security.insertProvider.BC";
 
  permission java.security.SecurityPermission "putProviderProperty.BC";
 
  // allow access to BouncyCastle properties
 
  permission java.util.PropertyPermission "org.bouncycastle.*","read";
 
  };
 
 
 
Note that <tt>bcprov.policy</tt> is referenced using the full url, it is not located in the application's jar.
 
 
 
Because the property <tt>java.security.policy</tt> is not a safe property, java web start will see the application as unsigned, even if the JAR is signed. So one needs to [http://java.sun.com/javase/technologies/desktop/javawebstart/download-spec.html sign] the JNLP file as well to avoid this warning.
 
 
 
This method avoids a second permission dialog for the BouncyCastle JAR using the Sun Java runtime environment. OpenJDK's runtime environment still requires <tt>all-permissions</tt> in <tt>bcprov.jnlp</tt>'s security section, which triggers the second permission dialog. This is tackled in the next section.
 
 
 
==Full workaround: Sun & OpenJDK==
 
While it is thus possible to avoid the BouncyCastle permission dialog for the Sun JRE, the OpenJDK JRE still requires <tt>all-permissions</tt>. So the Sun Java Web Start application needs to be served a different <tt>bcprov.jnlp</tt> than the OpenJDK Java Web Start application. Luckily, it ''is'' possible to distinguish between the two (altough more an accident that the developers' purpose) by looking at the [[JGridstart/Java_user_agents|HTTP request headers]]: when <tt>UA-Java-Version</tt> exists as a header, it is the Sun JRE; if not, it is the OpenJDK JRE.
 
 
 
With the widely used [http://httpd.apache.org/ Apache web server] it is possible to use its [http://httpd.apache.org/docs/2.2/rewrite/ mod_rewrite] to do this easily. One needs the <tt>app.jnlp</tt> as in the previous section (with the security policy), and the two species of <tt>bcprov.jnlp</tt>. Let's call the first version (with <tt>all-permissions</tt> in the security section) <tt>bcprov.policy</tt>, and the second version (without a security section) <tt>bcprov-sun.jnlp</tt> (don't forget to update its <tt>href</tt> accordingly). Now add the following to your <tt>.htaccess</tt> file:
 
  RewriteEngine On
 
  # you may need a RewriteBase directive here
 
  RewriteCond %{HTTP:UA-Java-Version} !^$
 
  RewriteRule bcprov.jnlp bcprov-sun.jnlp
 
Now the OpenJDK JRE is served the file <tt>bcprov.jnlp</tt> just like without a <tt>.htaccess</tt>, and the Sun JRE is served <tt>bcprov-sun.jnlp</tt> when it requests <tt>bcprov.jnlp</tt>. So all are happy now!
 
 
 
----
 
''I have tested this only with <all-permissions/> in the security section. If you have experiences with <j2ee-permissions/> please notify me and I'll add it here.''
 

Revision as of 10:12, 8 January 2010

BouncyCastle is a cryptographic library for Java that complements and completes the default Java Cryptography Extension. To use it as a provider (e.g. to to access a KeyStore that is supported by BouncyCastle), one has to use the JAR file provided by them because that is signed by Sun (because of law-stuff). When creating a Java Web Start application, the way to do this is by referencing to a bouncycastle JNLP file using the extension tag. For example the file app.jnlp:

<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0+" href="app.jnlp" codebase="http://somewhere/">
  <information>
    <title>App</title>
    <vendor>Nikhef</vendor>
    <homepage href="http://somewhere/"/>
  </information>
  <security>
    <all-permissions/>
  </security>
  <resources>
   <j2se href="http://java.sun.com/products/autodl/j2se" version="1.3+"/>
   <jar href="app.jar"/>
   <extension name="BouncyCastle cryptography library" href="bcprov.jnlp"/>
  </resources>
  <application-desc main-class="app.Main"/>
 </jnlp>

References the file bcprov.jnlp which describes the BouncyCastle extension. This can not be put in the application's JNLP because all JARs in a single JNLP file need to be signed by the same key. The file bcprov.jnlp can contain:

 <?xml version="1.0" encoding="UTF-8"?>
 <jnlp spec="1.0+" codebase="http://somewhere/" href="bcprov.jnlp">
  <information>
   <title>bcprov-jdk14</title>
   <vendor>Sun Microsystems, Inc.</vendor>
   <offline-allowed/>
  </information>
  <security>
    <all-permissions/>
  </security>
  <resources>
   <jar href="bcprov-jdk14-142.jar"/>
  </resources>
  <component-desc/>
 </jnlp>

You see that this file also has the all-permissions tag in the security section. This is to allow the file to register itself as a cryptography provider.

Now when the Java Web Start application is run, the user has to accept a warning dialog twice: one for the application itself, and one for the BouncyCastle extension. This is a little troublesome, since the user doesn't care about the extension; if he has just consented to grant the application access why does it ask for it again?

The solution to this issue is to sign the BouncyCastle JAR with the same key as the application JAR; the resulting BouncyCastle JAR will be signed twice: META-INF/BC-KEY.* gives the security permissions to be used as a cryptography provider, and META-INF/<MY-KEY>.* gives the other permissions. Because you use the same key for your application as BouncyCastle, the user only needs to accept it once.


If you don't want to sign the BouncyCastle JAR yourself, it is still possible to workaround the issue, please see Bouncycastle and Java web start workaround.