[icedtea-web] RFC: PR822: Applets fail to load if jars have different signers

Deepak Bhole dbhole at redhat.com
Thu Jan 26 11:55:34 PST 2012


Hi,

This patch fixes PR822:
http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=822

It makes it so that applets do not require all jars to have a single
signer (which is not mandated by the spec). After the patch, sites like
the one mentioned in the bug (https://bcee.snet.lu/) now work.

ChangeLog:
2012-01-26  Deepak Bhole <dbhole at redhat.com>

    PR822: Applets fail to load if jars have different signers
    * netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java
    (initializeResources): Ensure that there is a single signer only for Web
    Start applications and not for applets.
    * netx/net/sourceforge/jnlp/tools/JarSigner.java (verifyJar): Ensure that
    a given jar is signed throughout by at least one common certificate.

Okay for 1.2 and HEAD?

Cheers,
Deepak
-------------- next part --------------
diff -r b901442e9ba4 netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java
--- a/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java	Wed Jan 25 16:42:27 2012 +0100
+++ b/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java	Thu Jan 26 14:44:54 2012 -0500
@@ -470,8 +470,15 @@
                                         R("LCInit"), R("LFatalVerification"), R("LFatalVerificationInfo"));
             }
 
-            //Case when at least one jar has some signing
-            if (js.anyJarsSigned() && js.isFullySignedByASingleCert()) {
+            // Case when at least one jar has some signing
+            // For permissions to be given, we need:
+            // 1. Something is signed
+            // 2. This is an applet
+            // 3. OR, if this is NOT an applet, all jars have the same signer
+            if (js.anyJarsSigned() // signed 
+                    && (getJNLPFile().isApplet() // and an applet 
+                            || (!getJNLPFile().isApplet() // OR, NOT an applet 
+                                    && js.isFullySignedByASingleCert()))) { // AND fully signed by a single cert
                 signing = true;
 
                 if (!js.allJarsSigned() &&
diff -r b901442e9ba4 netx/net/sourceforge/jnlp/tools/JarSigner.java
--- a/netx/net/sourceforge/jnlp/tools/JarSigner.java	Wed Jan 25 16:42:27 2012 +0100
+++ b/netx/net/sourceforge/jnlp/tools/JarSigner.java	Thu Jan 26 14:44:54 2012 -0500
@@ -241,6 +241,8 @@
             jarFile = new JarFile(jarName, true);
             Vector<JarEntry> entriesVec = new Vector<JarEntry>();
             byte[] buffer = new byte[8192];
+            int signableEntriesInJar = 0;
+            Hashtable<Certificate, Integer> jarSignCount = new Hashtable<Certificate, Integer>(); 
 
             JarEntry je;
             Enumeration<JarEntry> entries = jarFile.entries();
@@ -281,8 +283,10 @@
 
                     hasUnsignedEntry |= shouldHaveSignature &&  !isSigned;
 
-                    if (shouldHaveSignature)
+                    if (shouldHaveSignature) {
+                        signableEntriesInJar++;
                         totalSignableEntries++;
+                    }
 
                     if (shouldHaveSignature && isSigned) {
                         for (int i = 0; i < signers.length; i++) {
@@ -307,6 +311,11 @@
                                     }
                                 }
                             }
+                            
+                            if (!jarSignCount.containsKey(cert))
+                                jarSignCount.put(cert, 1);
+                            else
+                                jarSignCount.put(cert, jarSignCount.get(cert) + 1);
                         }
                     }
                 } //while e has more elements
@@ -314,6 +323,7 @@
 
                 // Else increment totalEntries by 1 so that unsigned jars with 
                 // no manifests can't sneak in
+                signableEntriesInJar++;
                 totalSignableEntries++;
             }
 
@@ -321,6 +331,20 @@
             if (!anySigned) {
                 return verifyResult.UNSIGNED;
             } else {
+                
+                boolean signedBySingleCert = false;
+                Enumeration<Integer> e = jarSignCount.elements(); 
+                while (e.hasMoreElements()) {
+                    int count = e.nextElement();
+                    if (count == signableEntriesInJar) {
+                        signedBySingleCert = true;
+                        break;
+                    }
+                }
+                
+                if (!signedBySingleCert)
+                    return verifyResult.UNSIGNED;
+
                 anyJarsSigned = true;
 
                 //warnings


More information about the distro-pkg-dev mailing list