Author: tchemit
Date: Sat Dec 28 14:50:33 2013
New Revision: 1553841

URL: http://svn.apache.org/r1553841
Log:
MSHARED-314 - Unsign jar still have some signatures in the manisfest

Modified:
    
maven/shared/trunk/maven-jarsigner/src/main/java/org/apache/maven/shared/jarsigner/JarSignerUtil.java
    
maven/shared/trunk/maven-jarsigner/src/test/java/org/apache/maven/shared/jarsigner/JarSignerUtilTest.java

Modified: 
maven/shared/trunk/maven-jarsigner/src/main/java/org/apache/maven/shared/jarsigner/JarSignerUtil.java
URL: 
http://svn.apache.org/viewvc/maven/shared/trunk/maven-jarsigner/src/main/java/org/apache/maven/shared/jarsigner/JarSignerUtil.java?rev=1553841&r1=1553840&r2=1553841&view=diff
==============================================================================
--- 
maven/shared/trunk/maven-jarsigner/src/main/java/org/apache/maven/shared/jarsigner/JarSignerUtil.java
 (original)
+++ 
maven/shared/trunk/maven-jarsigner/src/main/java/org/apache/maven/shared/jarsigner/JarSignerUtil.java
 Sat Dec 28 14:50:33 2013
@@ -28,6 +28,9 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.util.Map;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipInputStream;
 import java.util.zip.ZipOutputStream;
@@ -82,7 +85,7 @@ public class JarSignerUtil
      * output JAR to retain as much metadata from the original JAR as possible.
      *
      * @param jarFile The JAR file to unsign, must not be <code>null</code>.
-     * @throws java.io.IOException
+     * @throws IOException
      */
     public static void unsignArchive( File jarFile )
         throws IOException
@@ -107,6 +110,18 @@ public class JarSignerUtil
 
                 zos.putNextEntry( new ZipEntry( ze.getName() ) );
 
+                if ( isManifestFile( ze.getName() ) )
+                {
+
+                    // build a new manifest while removing all digest entries
+                    // see https://jira.codehaus.org/browse/MSHARED-314
+                    Manifest oldManifest = new Manifest( zis );
+                    Manifest newManifest = buildUnsignedManifest( oldManifest 
);
+                    newManifest.write( zos );
+
+                    continue;
+                }
+
                 IOUtil.copy( zis, zos );
             }
 
@@ -122,11 +137,48 @@ public class JarSignerUtil
     }
 
     /**
+     * Build a new manifest from the given one removing any signing 
information inside it.
+     *
+     * This is done by removing any attributes containing some digest 
informations.
+     * If a entry has then no more attributes, then it will not be readd in 
the result manifest.
+     *
+     * @param manifest manifest to clean
+     * @return the build manifest with no digest attributes
+     * @since 1.3
+     */
+    protected static Manifest buildUnsignedManifest( Manifest manifest ) {
+
+        Manifest result = new Manifest( manifest );
+        result.getMainAttributes().clear();
+
+        for ( Map.Entry<String, Attributes> entry : 
manifest.getEntries().entrySet() )
+        {
+            Attributes oldAttributes = entry.getValue();
+            Attributes newAttributes = new Attributes();
+            for ( Map.Entry<Object, Object> objectEntry : 
oldAttributes.entrySet() )
+            {
+                String attributeKey = String.valueOf( objectEntry.getKey() );
+                if ( !attributeKey.contains( "-Digest" ) )
+                {
+                    // can add this attribute
+                    newAttributes.put( objectEntry.getKey(), 
objectEntry.getValue() );
+                }
+            }
+            if ( !newAttributes.isEmpty() )
+            {
+                // can add this entry
+                result.getEntries().put( entry.getKey(), newAttributes );
+            }
+        }
+        return result;
+    }
+
+    /**
      * Scans an archive for existing signatures.
      *
      * @param jarFile The archive to scan, must not be <code>null</code>.
      * @return <code>true</code>, if the archive contains at least one 
signature file; <code>false</code>, if the archive
-     *         does not contain any signature files.
+     * does not contain any signature files.
      * @throws IOException if scanning <code>jarFile</code> fails.
      */
     public static boolean isArchiveSigned( final File jarFile )
@@ -183,7 +235,7 @@ public class JarSignerUtil
      * @param entryName The name of the JAR file entry to check, must not be 
<code>null</code>.
      * @return <code>true</code> if the entry is related to a signature, 
<code>false</code> otherwise.
      */
-    private static boolean isSignatureFile( String entryName )
+    protected static boolean isSignatureFile( String entryName )
     {
         boolean result = false;
         if ( entryName.regionMatches( true, 0, "META-INF", 0, 8 ) )
@@ -212,4 +264,22 @@ public class JarSignerUtil
         }
         return result;
     }
+
+    protected static boolean isManifestFile( String entryName )
+    {
+        boolean result = false;
+        if ( entryName.regionMatches( true, 0, "META-INF", 0, 8 ) )
+        {
+            entryName = entryName.replace( '\\', '/' );
+
+            if ( entryName.indexOf( '/' ) == 8 && entryName.lastIndexOf( '/' ) 
== 8 )
+            {
+                if ( entryName.regionMatches( true, entryName.length() - 11, 
"MANIFEST.MF", 0, 11 ) )
+                {
+                    result = true;
+                }
+            }
+        }
+        return result;
+    }
 }

Modified: 
maven/shared/trunk/maven-jarsigner/src/test/java/org/apache/maven/shared/jarsigner/JarSignerUtilTest.java
URL: 
http://svn.apache.org/viewvc/maven/shared/trunk/maven-jarsigner/src/test/java/org/apache/maven/shared/jarsigner/JarSignerUtilTest.java?rev=1553841&r1=1553840&r2=1553841&view=diff
==============================================================================
--- 
maven/shared/trunk/maven-jarsigner/src/test/java/org/apache/maven/shared/jarsigner/JarSignerUtilTest.java
 (original)
+++ 
maven/shared/trunk/maven-jarsigner/src/test/java/org/apache/maven/shared/jarsigner/JarSignerUtilTest.java
 Sat Dec 28 14:50:33 2013
@@ -23,6 +23,8 @@ import junit.framework.TestCase;
 import org.apache.maven.shared.utils.io.FileUtils;
 
 import java.io.File;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
 
 /**
  * Created on 11/8/13.
@@ -52,9 +54,28 @@ public class JarSignerUtilTest
 
         assertTrue( JarSignerUtil.isArchiveSigned( target ) );
 
+        // check that manifest contains some digest attributes
+        JarFile originalJarFile = new JarFile( file );
+        Manifest originalManifest = originalJarFile.getManifest();
+        originalJarFile.close();
+
+        Manifest originalCleanManifest = JarSignerUtil.buildUnsignedManifest( 
originalManifest );
+        assertFalse( originalManifest.equals( originalCleanManifest ) );
+        assertTrue( originalCleanManifest.equals( 
JarSignerUtil.buildUnsignedManifest( originalCleanManifest ) ) );
+
         JarSignerUtil.unsignArchive( target );
 
         assertFalse( JarSignerUtil.isArchiveSigned( target ) );
 
+        // check that manifest has no digest entry
+        // see https://jira.codehaus.org/browse/MSHARED-314
+        JarFile jarFile = new JarFile( target );
+        Manifest manifest = jarFile.getManifest();
+        jarFile.close();
+        Manifest cleanManifest = JarSignerUtil.buildUnsignedManifest( manifest 
);
+        assertTrue( manifest.equals( cleanManifest ) );
+        assertTrue( manifest.equals( originalCleanManifest ) );
+
+
     }
 }


Reply via email to