stevel      2005/03/24 09:17:09

  Modified:    src/main/org/apache/tools/ant/taskdefs
                        AbstractJarSignerTask.java VerifyJar.java
               src/etc/testcases/taskdefs signjar.xml
               src/testcases/org/apache/tools/ant/taskdefs SignJarTest.java
  Log:
  Well, a bit of hackery and you can verify that JAR is signed. But there is 
*nothing* to verify that the signature itself is trusted. Essentially 
"jarsigner -verify" is a worthless piece of junk from the security perspective.
  
  Revision  Changes    Path
  1.3       +17 -6     
ant/src/main/org/apache/tools/ant/taskdefs/AbstractJarSignerTask.java
  
  Index: AbstractJarSignerTask.java
  ===================================================================
  RCS file: 
/home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/AbstractJarSignerTask.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- AbstractJarSignerTask.java        24 Mar 2005 15:01:30 -0000      1.2
  +++ AbstractJarSignerTask.java        24 Mar 2005 17:17:09 -0000      1.3
  @@ -203,16 +203,27 @@
        */
       private RedirectorElement createRedirector() {
           RedirectorElement result = new RedirectorElement();
  -        StringBuffer input = new StringBuffer(storepass).append('\n');
  -        if (keypass != null) {
  -            input.append(keypass).append('\n');
  +        if(storepass!=null) {
  +            StringBuffer input = new StringBuffer(storepass).append('\n');
  +            if (keypass != null) {
  +                input.append(keypass).append('\n');
  +            }
  +            result.setInputString(input.toString());
  +            result.setLogInputString(false);
           }
  -        result.setInputString(input.toString());
  -        result.setLogInputString(false);
           return result;
       }
   
       /**
  +     * get the redirector. Non-null between invocations of
  +     * [EMAIL PROTECTED] #beginExecution()} and [EMAIL PROTECTED] 
#endExecution()}
  +     * @return a redirector or null
  +     */
  +    public RedirectorElement getRedirector() {
  +        return redirector;
  +    }
  +
  +    /**
        * these are options common to signing and verifying
        * @param cmd  command to configure
        */
  @@ -224,7 +235,7 @@
           if (verbose) {
               addValue(cmd,"-verbose");
           }
  -        
  +
           //now patch in all system properties
           Vector props=sysProperties.getVariablesVector();
           Enumeration e=props.elements();
  
  
  
  1.2       +82 -1     ant/src/main/org/apache/tools/ant/taskdefs/VerifyJar.java
  
  Index: VerifyJar.java
  ===================================================================
  RCS file: 
/home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/VerifyJar.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- VerifyJar.java    23 Mar 2005 16:51:42 -0000      1.1
  +++ VerifyJar.java    24 Mar 2005 17:17:09 -0000      1.2
  @@ -19,10 +19,15 @@
   
   import org.apache.tools.ant.BuildException;
   import org.apache.tools.ant.DirectoryScanner;
  +import org.apache.tools.ant.filters.ChainableReader;
   import org.apache.tools.ant.types.FileSet;
  +import org.apache.tools.ant.types.RedirectorElement;
  +import org.apache.tools.ant.types.FilterChain;
   
   import java.util.Vector;
   import java.io.File;
  +import java.io.Reader;
  +import java.io.IOException;
   
   /**
    * JAR verification task.
  @@ -39,9 +44,16 @@
       public static final String ERROR_NO_FILE = "Not found :";
   
       /**
  +     * The string we look for in the text to indicate direct verification
  +     */
  +    private static final String VERIFIED_TEXT = "jar verified.";
  +
  +    /**
        * certification flag
        */
       private boolean certificates=false;
  +    private BufferingOutputFilter outputCache = new BufferingOutputFilter();
  +    public static final String ERROR_NO_VERIFY = "Failed to verify ";
   
       /**
        * Ask for certificate information to be printed
  @@ -65,6 +77,13 @@
           }
   
           beginExecution();
  +
  +        //patch the redirector to save output to a file
  +        RedirectorElement redirector = getRedirector();
  +        redirector.setAlwaysLog(true);
  +        FilterChain outputFilterChain = redirector.createOutputFilterChain();
  +        outputFilterChain.add(outputCache);
  +
           try {
               Vector sources = createUnifiedSources();
               for (int i = 0; i < sources.size(); i++) {
  @@ -114,7 +133,69 @@
   
           log("Verifying JAR: " +
                   jar.getAbsolutePath());
  -
  +        outputCache.clear();
           cmd.execute();
  +        String results=outputCache.toString();
  +        if(results.indexOf(VERIFIED_TEXT)<0) {
  +            throw new BuildException(ERROR_NO_VERIFY+jar);
  +        }
  +    }
  +
  +    /**
  +     * we are not thread safe here. Do not use on multiple threads at the 
same time.
  +     */
  +    private class BufferingOutputFilter implements ChainableReader {
  +
  +        private BufferingOutputFilterReader buffer;
  +
  +        public Reader chain(Reader rdr) {
  +            buffer = new BufferingOutputFilterReader(rdr);
  +            return buffer;
  +        }
  +
  +        public String toString() {
  +            return buffer.toString();
  +        }
  +
  +        public void clear() {
  +            if(buffer!=null) {
  +                buffer.clear();
  +            }
  +        }
  +    }
  +
  +    /**
  +     * catch the output of the buffer
  +     */
  +    private class BufferingOutputFilterReader extends Reader {
  +
  +        private Reader next;
  +
  +        private StringBuffer buffer=new StringBuffer();
  +
  +        public BufferingOutputFilterReader(Reader next) {
  +            this.next = next;
  +        }
  +
  +        public int read(char cbuf[], int off, int len) throws IOException {
  +            //hand down
  +            int result=next.read(cbuf,off,len);
  +            //cache
  +            buffer.append(cbuf,off,len);
  +            //return
  +            return result;
  +        }
  +
  +        public void close() throws IOException {
  +            next.close();
  +        }
  +
  +        public String toString() {
  +            return buffer.toString();
  +        }
  +
  +        public void clear() {
  +            buffer=new StringBuffer();
  +        }
       }
   }
  
  
  
  1.11      +8 -0      ant/src/etc/testcases/taskdefs/signjar.xml
  
  Index: signjar.xml
  ===================================================================
  RCS file: /home/cvs/ant/src/etc/testcases/taskdefs/signjar.xml,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- signjar.xml       24 Mar 2005 15:01:30 -0000      1.10
  +++ signjar.xml       24 Mar 2005 17:17:09 -0000      1.11
  @@ -194,10 +194,18 @@
       <verify-base jar="${test.jar}"/>
     </target>
   
  +  <target name="testVerifyJarCertificates" depends="basic">
  +    <verify-base jar="${test.jar}" certificates="true" verbose="true"/>
  +  </target>
  +  
     <target name="testVerifyJarUnsigned" depends="jar">
       <verify-base jar="${test.jar}"/>
     </target>
     
  +  <target name="testVerifyJarNotInKeystore" depends="basic">
  +    <verifyjar jar="${test.jar}" certificates="true" verbose="true"/>
  +  </target>
  +    
     <target name="testVerifyFileset" depends="basic">
       <verify-base >
         <fileset file="${test.jar}" />
  
  
  
  1.15      +10 -3     
ant/src/testcases/org/apache/tools/ant/taskdefs/SignJarTest.java
  
  Index: SignJarTest.java
  ===================================================================
  RCS file: 
/home/cvs/ant/src/testcases/org/apache/tools/ant/taskdefs/SignJarTest.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- SignJarTest.java  24 Mar 2005 15:01:30 -0000      1.14
  +++ SignJarTest.java  24 Mar 2005 17:17:09 -0000      1.15
  @@ -164,9 +164,16 @@
                   AbstractJarSignerTask.ERROR_NO_SOURCE);
       }
   
  -    public void NotestVerifyJarUnsigned() {
  -        expectBuildException("testVerifyJarUnsigned",
  -                "unsigned JAR file");
  +    public void testVerifyJarUnsigned() {
  +        expectBuildExceptionContaining("testVerifyJarUnsigned",
  +                "unsigned JAR file",
  +                VerifyJar.ERROR_NO_VERIFY);
  +    }
  +
  +    public void NotestVerifyJarNotInKeystore() {
  +        expectBuildExceptionContaining("testVerifyJarNotInKeystore",
  +                "signature not in keystore",
  +                VerifyJar.ERROR_NO_VERIFY);
       }
   
       public void testVerifyFileset() {
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to