1 /* JarSigner.java -- The signing handler of the gjarsigner tool 2 Copyright (C) 2006 Free Software Foundation, Inc. 3 4 This file is part of GNU Classpath. 5 6 GNU Classpath is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 GNU Classpath is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GNU Classpath; see the file COPYING. If not, write to the 18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 02110-1301 USA. 20 21 Linking this library statically or dynamically with other modules is 22 making a combined work based on this library. Thus, the terms and 23 conditions of the GNU General Public License cover the whole 24 combination. 25 26 As a special exception, the copyright holders of this library give you 27 permission to link this library with independent modules to produce an 28 executable, regardless of the license terms of these independent 29 modules, and to copy and distribute the resulting executable under 30 terms of your choice, provided that you also meet, for each linked 31 independent module, the terms and conditions of the license of that 32 module. An independent module is a module which is not derived from 33 or based on this library. If you modify this library, you may extend 34 this exception to your version of the library, but you are not 35 obligated to do so. If you do not wish to do so, delete this 36 exception statement from your version. */ 37 38 39 package gnu.classpath.tools.jarsigner; 40 41 import gnu.classpath.Configuration; 42 import gnu.classpath.SystemProperties; 43 import gnu.java.util.jar.JarUtils; 44 45 import java.io.File; 46 import java.io.FileOutputStream; 47 import java.io.IOException; 48 import java.io.InputStream; 49 import java.util.Enumeration; 50 import java.util.jar.JarEntry; 51 import java.util.jar.JarFile; 52 import java.util.jar.JarOutputStream; 53 import java.util.logging.Logger; 54 55 /** 56 * The JAR signing handler of the <code>gjarsigner</code> tool. 57 */ 58 public class JarSigner 59 { 60 private static final Logger log = Logger.getLogger(JarSigner.class.getName()); 61 /** The owner tool of this handler. */ 62 private Main main; 63 JarSigner(Main main)64 JarSigner(Main main) 65 { 66 super(); 67 68 this.main = main; 69 } 70 start()71 void start() throws Exception 72 { 73 if (Configuration.DEBUG) 74 log.entering(this.getClass().getName(), "start"); //$NON-NLS-1$ 75 JarFile jarFile = new JarFile(main.getJarFileName()); 76 SFHelper sfHelper = new SFHelper(jarFile); 77 78 sfHelper.startSigning(); 79 80 // 1. compute the digests 81 for (Enumeration e = jarFile.entries(); e.hasMoreElements(); ) 82 { 83 JarEntry je = (JarEntry) e.nextElement(); 84 String jeName = je.getName(); 85 if (jeName.equals(JarFile.MANIFEST_NAME) 86 || jeName.endsWith(File.separator)) 87 continue; 88 89 sfHelper.updateEntry(je); 90 if (main.isVerbose()) 91 System.out.println(Messages.getString("JarSigner.1") + jeName); //$NON-NLS-1$ 92 } 93 94 sfHelper.finishSigning(main.isSectionsOnly()); 95 if (main.isVerbose()) 96 System.out.println(Messages.getString("JarSigner.2") + JarFile.MANIFEST_NAME); //$NON-NLS-1$ 97 98 // 2. write jar entries and manifest 99 File signedJarFile = File.createTempFile("gcp-", ".jar"); //$NON-NLS-1$ //$NON-NLS-2$ 100 FileOutputStream fos = new FileOutputStream(signedJarFile); 101 JarOutputStream outSignedJarFile = new JarOutputStream(fos, 102 sfHelper.getManifest()); 103 for (Enumeration e = jarFile.entries(); e.hasMoreElements(); ) 104 { 105 JarEntry je = (JarEntry) e.nextElement(); 106 String jeName = je.getName(); 107 if (jeName.equals(JarFile.MANIFEST_NAME) 108 || jeName.endsWith(File.separator)) 109 continue; 110 111 log.finest("Processing " + jeName); //$NON-NLS-1$ 112 JarEntry newEntry = new JarEntry(jeName); 113 newEntry.setTime(je.getTime()); 114 outSignedJarFile.putNextEntry(newEntry); 115 InputStream jeis = jarFile.getInputStream(je); 116 copyFromTo(jeis, outSignedJarFile); 117 } 118 119 // 3. create the .SF file 120 String signaturesFileName = main.getSigFileName(); 121 String sfFileName = JarUtils.META_INF + signaturesFileName 122 + JarUtils.SF_SUFFIX; 123 if (Configuration.DEBUG) 124 log.fine("Processing " + sfFileName); //$NON-NLS-1$ 125 JarEntry sfEntry = new JarEntry(sfFileName); 126 sfEntry.setTime(System.currentTimeMillis()); 127 outSignedJarFile.putNextEntry(sfEntry); 128 sfHelper.writeSF(outSignedJarFile); 129 if (Configuration.DEBUG) 130 log.fine("Created .SF file"); //$NON-NLS-1$ 131 if (main.isVerbose()) 132 System.out.println(Messages.getString("JarSigner.8") + sfFileName); //$NON-NLS-1$ 133 134 // 4. create the .DSA file 135 String dsaFileName = JarUtils.META_INF + signaturesFileName 136 + JarUtils.DSA_SUFFIX; 137 if (Configuration.DEBUG) 138 log.fine("Processing " + dsaFileName); //$NON-NLS-1$ 139 JarEntry dsaEntry = new JarEntry(dsaFileName); 140 dsaEntry.setTime(System.currentTimeMillis()); 141 outSignedJarFile.putNextEntry(dsaEntry); 142 sfHelper.writeDSA(outSignedJarFile, 143 main.getSignerPrivateKey(), 144 main.getSignerCertificateChain(), 145 main.isInternalSF()); 146 if (Configuration.DEBUG) 147 log.fine("Created .DSA file"); //$NON-NLS-1$ 148 if (main.isVerbose()) 149 System.out.println(Messages.getString("JarSigner.8") + dsaFileName); //$NON-NLS-1$ 150 151 // cleanup 152 outSignedJarFile.close(); 153 fos.close(); 154 signedJarFile.renameTo(new File(main.getSignedJarFileName())); 155 if (Configuration.DEBUG) 156 log.fine("Renamed signed JAR file"); //$NON-NLS-1$ 157 if (main.isVerbose()) 158 System.out.println(SystemProperties.getProperty("line.separator") //$NON-NLS-1$ 159 + Messages.getString("JarSigner.14")); //$NON-NLS-1$ 160 if (Configuration.DEBUG) 161 log.exiting(this.getClass().getName(), "start"); //$NON-NLS-1$ 162 } 163 copyFromTo(InputStream in, JarOutputStream out)164 private void copyFromTo(InputStream in, JarOutputStream out) 165 throws IOException 166 { 167 byte[] buffer = new byte[8192]; 168 int n; 169 while ((n = in.read(buffer)) != -1) 170 if (n > 0) 171 out.write(buffer, 0, n); 172 } 173 } 174