verifyjar must use -storepass or jarsigner will not work
authorStefan Bodewig <bodewig@apache.org>
Tue, 20 Mar 2018 11:13:57 +0000 (12:13 +0100)
committerStefan Bodewig <bodewig@apache.org>
Tue, 20 Mar 2018 11:13:57 +0000 (12:13 +0100)
https://bz.apache.org/bugzilla/show_bug.cgi?id=62194

WHATSNEW
manual/Tasks/signjar.html
manual/Tasks/verifyjar.html
src/main/org/apache/tools/ant/taskdefs/VerifyJar.java
src/tests/antunit/taskdefs/signjar-test.xml

index 6dd00fe..1011201 100644 (file)
--- a/WHATSNEW
+++ b/WHATSNEW
@@ -16,6 +16,15 @@ Fixed bugs:
  * Fixed NullPointerException when a mappedresource is used in pathconvert
    Bugzilla Report 62076
 
+ * Added a workaround for a bug in the jarsigner tool to <verifyjar>
+   which requires the -storepass command line argument when verifying
+   signatures using -strict together with a PKCS12 keystore. Unlike
+   when signing the jar it will not prompt for the keystore's password
+   and read it from standard input.
+   This means Ant will now pass the keystore's password on the command
+   line when using <verifyjar>, which poses a security risk you should
+   be aware of.
+   Bugzilla Report 62194
 
 Other changes:
 --------------
index 0f9d778..32315c1 100644 (file)
@@ -66,7 +66,9 @@ and <tt>lazy</tt> is false, the JAR is signed.</li>
   </tr>
   <tr>
     <td valign="top">storepass</td>
-    <td valign="top">password for keystore integrity.</td>
+    <td valign="top">password for keystore integrity. Ant will not use
+    the <code>-storepass</code> command line argument but send the
+    password to jarsigner when it prompts for it.</td>
     <td valign="top" align="center">Yes.</td>
   </tr>
   <tr>
index 4be2788..886075a 100644 (file)
@@ -52,8 +52,12 @@ supported
   </tr>
   <tr>
     <td valign="top">storepass</td>
-    <td valign="top">password for keystore integrity.</td>
-    <td valign="top" align="center">Yes.</td>
+    <td valign="top">password for keystore integrity.
+    Note that
+    jarsigner does not read the password from stdin during
+    verification, so the password must be send via a command line
+    interface and may be visible to other users of the system.</td>
+    <td valign="top" align="center">No.</td>
   </tr>
   <tr>
     <td valign="top">keystore</td>
index a0003c7..4cbbe2a 100644 (file)
@@ -58,6 +58,8 @@ public class VerifyJar extends AbstractJarSignerTask {
     /** Error output if there is a failure to verify the jar. */
     public static final String ERROR_NO_VERIFY = "Failed to verify ";
 
+    private String savedStorePass = null;
+
     /**
      * Ask for certificate information to be printed
      * @param certificates if true print certificates.
@@ -100,6 +102,42 @@ public class VerifyJar extends AbstractJarSignerTask {
     }
 
     /**
+     * @since 1.9.11
+     */
+    @Override
+    protected void beginExecution() {
+        // when using a PKCS12 keystore jarsigner -verify will not
+        // prompt for the keystore password but will only properly
+        // verify the jar with -strict enabled if the -storepass
+        // parameter is used. Note that the documentation of jarsigner
+        // says -storepass was never required with -verify - this is
+        // wrong.
+        //
+        // See https://bz.apache.org/bugzilla/show_bug.cgi?id=62194
+        //
+        // So if strict is true then we hide storepass from the base
+        // implementation and instead add the -storepass command line
+        // argument
+        if (mustHideStorePass()) {
+            savedStorePass = storepass;
+            setStorepass(null);
+        }
+        super.beginExecution();
+    }
+
+    /**
+     * @since 1.9.11
+     */
+    @Override
+    protected void endExecution() {
+        if (savedStorePass != null) {
+            setStorepass(savedStorePass);
+            savedStorePass = null;
+        }
+        super.endExecution();
+    }
+
+    /**
      * verify a JAR.
      * @param jar the jar to verify.
      * @throws BuildException if the file could not be verified
@@ -112,6 +150,10 @@ public class VerifyJar extends AbstractJarSignerTask {
 
         setCommonOptions(cmd);
         bindToKeystore(cmd);
+        if (savedStorePass != null) {
+            addValue(cmd, "-storepass");
+            addValue(cmd, savedStorePass);
+        }
 
         //verify special operations
         addValue(cmd, "-verify");
@@ -151,6 +193,10 @@ public class VerifyJar extends AbstractJarSignerTask {
         }
     }
 
+    private boolean mustHideStorePass() {
+        return strict && storepass != null;
+    }
+
     /**
      * we are not thread safe here. Do not use on multiple threads at the same time.
      */
index 4d998fb..30671cf 100644 (file)
     </au:expectfailure>
   </target>
 
+  <target name="testVerifyJarStrict" depends="basic">
+    <verify-base jar="${signtest.jar}" strict="true"/>
+  </target>
+
+  <target name="testVerifyJarStrictPKCS12" depends="basic-pkcs12"
+          description="https://bz.apache.org/bugzilla/show_bug.cgi?id=62194">
+    <verify-base-pkcs12 jar="${signtest.jar}" strict="true"/>
+  </target>
+
 </project>