# HG changeset patch # User asotona # Date 1582896919 -3600 # Fri Feb 28 14:35:19 2020 +0100 # Node ID 9ee1f6a86c3317fc55995900721a028bec25c8be # Parent 27e301f90b3a21e5822980978bf77f965b4e3de4 8230117: remove dead code from jar tool Summary: The class files sun.tools.jar.Manifest and sun.tools.jar.SignatureFile are removed Reviewed-by: lancea Contributed-by: asotona diff -r 27e301f90b3a -r 9ee1f6a86c33 src/jdk.jartool/share/classes/sun/tools/jar/Manifest.java --- a/src/jdk.jartool/share/classes/sun/tools/jar/Manifest.java Fri Feb 28 09:53:18 2020 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,257 +0,0 @@ -/* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.tools.jar; - -import java.io.*; -import java.util.*; -import java.security.*; - -import sun.net.www.MessageHeader; -import java.util.Base64; - -/** - * This is OBSOLETE. DO NOT USE THIS. Use java.util.jar.Manifest - * instead. It has to stay here because some apps (namely HJ and HJV) - * call directly into it. - * - * @author David Brown - * @author Benjamin Renaud - */ - -public class Manifest { - - /* list of headers that all pertain to a particular - * file in the archive - */ - private Vector entries = new Vector<>(); - private byte[] tmpbuf = new byte[512]; - /* a hashtable of entries, for fast lookup */ - private Hashtable tableEntries = new Hashtable<>(); - - static final String[] hashes = {"SHA"}; - - static final boolean debug = false; - static final String VERSION = "1.0"; - static final void debug(String s) { - if (debug) - System.out.println("man> " + s); - } - - public Manifest() {} - - public Manifest(byte[] bytes) throws IOException { - this(new ByteArrayInputStream(bytes), false); - } - - public Manifest(InputStream is) throws IOException { - this(is, true); - } - - /** - * Parse a manifest from a stream, optionally computing hashes - * for the files. - */ - public Manifest(InputStream is, boolean compute) throws IOException { - if (!is.markSupported()) { - is = new BufferedInputStream(is); - } - /* do not rely on available() here! */ - while (true) { - is.mark(1); - if (is.read() == -1) { // EOF - break; - } - is.reset(); - MessageHeader m = new MessageHeader(is); - if (compute) { - doHashes(m); - } - addEntry(m); - } - } - - /* recursively generate manifests from directory tree */ - public Manifest(String[] files) throws IOException { - MessageHeader globals = new MessageHeader(); - globals.add("Manifest-Version", VERSION); - String jdkVersion = System.getProperty("java.version"); - globals.add("Created-By", "Manifest JDK "+jdkVersion); - addEntry(globals); - addFiles(null, files); - } - - public void addEntry(MessageHeader entry) { - entries.addElement(entry); - String name = entry.findValue("Name"); - debug("addEntry for name: "+name); - if (name != null) { - tableEntries.put(name, entry); - } - } - - public MessageHeader getEntry(String name) { - return tableEntries.get(name); - } - - public MessageHeader entryAt(int i) { - return entries.elementAt(i); - } - - public Enumeration entries() { - return entries.elements(); - } - - public void addFiles(File dir, String[] files) throws IOException { - if (files == null) - return; - for (int i = 0; i < files.length; i++) { - File file; - if (dir == null) { - file = new File(files[i]); - } else { - file = new File(dir, files[i]); - } - if (file.isDirectory()) { - addFiles(file, file.list()); - } else { - addFile(file); - } - } - } - - /** - * File names are represented internally using "/"; - * they are converted to the local format for anything else - */ - - private final String stdToLocal(String name) { - return name.replace('/', java.io.File.separatorChar); - } - - private final String localToStd(String name) { - name = name.replace(java.io.File.separatorChar, '/'); - if (name.startsWith("./")) - name = name.substring(2); - else if (name.startsWith("/")) - name = name.substring(1); - return name; - } - - public void addFile(File f) throws IOException { - String stdName = localToStd(f.getPath()); - if (tableEntries.get(stdName) == null) { - MessageHeader mh = new MessageHeader(); - mh.add("Name", stdName); - addEntry(mh); - } - } - - public void doHashes(MessageHeader mh) throws IOException { - // If unnamed or is a directory return immediately - String name = mh.findValue("Name"); - if (name == null || name.endsWith("/")) { - return; - } - - - /* compute hashes, write over any other "Hash-Algorithms" (?) */ - for (int j = 0; j < hashes.length; ++j) { - InputStream is = new FileInputStream(stdToLocal(name)); - try { - MessageDigest dig = MessageDigest.getInstance(hashes[j]); - - int len; - while ((len = is.read(tmpbuf, 0, tmpbuf.length)) != -1) { - dig.update(tmpbuf, 0, len); - } - mh.set(hashes[j] + "-Digest", Base64.getMimeEncoder().encodeToString(dig.digest())); - } catch (NoSuchAlgorithmException e) { - throw new JarException("Digest algorithm " + hashes[j] + - " not available."); - } finally { - is.close(); - } - } - } - - /* Add a manifest file at current position in a stream - */ - public void stream(OutputStream os) throws IOException { - - PrintStream ps; - if (os instanceof PrintStream) { - ps = (PrintStream) os; - } else { - ps = new PrintStream(os); - } - - /* the first header in the file should be the global one. - * It should say "Manifest-Version: x.x"; if not add it - */ - MessageHeader globals = entries.elementAt(0); - - if (globals.findValue("Manifest-Version") == null) { - /* Assume this is a user-defined manifest. If it has a Name: <..> - * field, then it is not global, in which case we just add our own - * global Manifest-version: - * If the first MessageHeader has no Name: <..>, we assume it - * is a global header and so prepend Manifest to it. - */ - String jdkVersion = System.getProperty("java.version"); - - if (globals.findValue("Name") == null) { - globals.prepend("Manifest-Version", VERSION); - globals.add("Created-By", "Manifest JDK "+jdkVersion); - } else { - ps.print("Manifest-Version: "+VERSION+"\r\n"+ - "Created-By: "+jdkVersion+"\r\n\r\n"); - } - ps.flush(); - } - - globals.print(ps); - - for (int i = 1; i < entries.size(); ++i) { - MessageHeader mh = entries.elementAt(i); - mh.print(ps); - } - } - - public static boolean isManifestName(String name) { - - // remove leading / - if (name.charAt(0) == '/') { - name = name.substring(1, name.length()); - } - // case insensitive - name = name.toUpperCase(); - - if (name.equals("META-INF/MANIFEST.MF")) { - return true; - } - return false; - } -} diff -r 27e301f90b3a -r 9ee1f6a86c33 src/jdk.jartool/share/classes/sun/tools/jar/SignatureFile.java --- a/src/jdk.jartool/share/classes/sun/tools/jar/SignatureFile.java Fri Feb 28 09:53:18 2020 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,360 +0,0 @@ -/* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.tools.jar; - -import java.io.*; -import java.util.*; -import java.security.*; - -import sun.net.www.MessageHeader; -import java.util.Base64; - - -import sun.security.pkcs.*; -import sun.security.x509.AlgorithmId; - -/** - *

A signature file as defined in the Manifest and Signature Format. It has - * essentially the same structure as a Manifest file in that it is a - * set of RFC 822 headers (sections). The first section contains meta - * data relevant to the entire file (i.e "Signature-Version:1.0") and - * each subsequent section contains data relevant to specific entries: - * entry sections. - * - *

Each entry section contains the name of an entry (which must - * have a counterpart in the manifest). Like the manifest it contains - * a hash, the hash of the manifest section corresponding to the - * name. Since the manifest entry contains the hash of the data, this - * is equivalent to a signature of the data, plus the attributes of - * the manifest entry. - * - *

This signature file format deal with PKCS7 encoded DSA signature - * block. It should be straightforward to extent to support other - * algorithms. - * - * @author David Brown - * @author Benjamin Renaud */ - -public class SignatureFile { - - /* Are we debugging? */ - static final boolean debug = false; - - /* list of headers that all pertain to a particular file in the - * archive */ - private Vector entries = new Vector<>(); - - /* Right now we only support SHA hashes */ - static final String[] hashes = {"SHA"}; - - static final void debug(String s) { - if (debug) - System.out.println("sig> " + s); - } - - /* - * The manifest we're working with. */ - private Manifest manifest; - - /* - * The file name for the file. This is the raw name, i.e. the - * extention-less 8 character name (such as MYSIGN) which wil be - * used to build the signature filename (MYSIGN.SF) and the block - * filename (MYSIGN.DSA) */ - private String rawName; - - /* The digital signature block corresponding to this signature - * file. */ - private PKCS7 signatureBlock; - - - /** - * Private constructor which takes a name a given signature - * file. The name must be extension-less and less or equal to 8 - * character in length. */ - private SignatureFile(String name) throws JarException { - - entries = new Vector<>(); - - if (name != null) { - if (name.length() > 8 || name.indexOf('.') != -1) { - throw new JarException("invalid file name"); - } - rawName = name.toUpperCase(Locale.ENGLISH); - } - } - - /** - * Private constructor which takes a name a given signature file - * and a new file predicate. If it is a new file, a main header - * will be added. */ - private SignatureFile(String name, boolean newFile) - throws JarException { - - this(name); - - if (newFile) { - MessageHeader globals = new MessageHeader(); - globals.set("Signature-Version", "1.0"); - entries.addElement(globals); - } - } - - /** - * Constructs a new Signature file corresponding to a given - * Manifest. All entries in the manifest are signed. - * - * @param manifest the manifest to use. - * - * @param name for this signature file. This should - * be less than 8 characters, and without a suffix (i.e. - * without a period in it. - * - * @exception JarException if an invalid name is passed in. - */ - public SignatureFile(Manifest manifest, String name) - throws JarException { - - this(name, true); - - this.manifest = manifest; - Enumeration enum_ = manifest.entries(); - while (enum_.hasMoreElements()) { - MessageHeader mh = enum_.nextElement(); - String entryName = mh.findValue("Name"); - if (entryName != null) { - add(entryName); - } - } - } - - /** - * Constructs a new Signature file corresponding to a given - * Manifest. Specific entries in the manifest are signed. - * - * @param manifest the manifest to use. - * - * @param entries the entries to sign. - * - * @param filename for this signature file. This should - * be less than 8 characters, and without a suffix (i.e. - * without a period in it. - * - * @exception JarException if an invalid name is passed in. - */ - public SignatureFile(Manifest manifest, String[] entries, - String filename) - throws JarException { - this(filename, true); - this.manifest = manifest; - add(entries); - } - - /** - * Construct a Signature file from an input stream. - * - * @exception IOException if an invalid name is passed in or if a - * stream exception occurs. - */ - public SignatureFile(InputStream is, String filename) - throws IOException { - this(filename); - while (is.available() > 0) { - MessageHeader m = new MessageHeader(is); - entries.addElement(m); - } - } - - /** - * Construct a Signature file from an input stream. - * - * @exception IOException if an invalid name is passed in or if a - * stream exception occurs. - */ - public SignatureFile(InputStream is) throws IOException { - this(is, null); - } - - public SignatureFile(byte[] bytes) throws IOException { - this(new ByteArrayInputStream(bytes)); - } - - /** - * Returns the name of the signature file, ending with a ".SF" - * suffix */ - public String getName() { - return "META-INF/" + rawName + ".SF"; - } - - /** - * Returns the name of the block file, ending with a block suffix - * such as ".DSA". */ - public String getBlockName() { - String suffix = "DSA"; - if (signatureBlock != null) { - SignerInfo info = signatureBlock.getSignerInfos()[0]; - suffix = info.getDigestEncryptionAlgorithmId().getName(); - String temp = AlgorithmId.getEncAlgFromSigAlg(suffix); - if (temp != null) suffix = temp; - } - return "META-INF/" + rawName + "." + suffix; - } - - /** - * Returns the signature block associated with this file. - */ - public PKCS7 getBlock() { - return signatureBlock; - } - - /** - * Sets the signature block associated with this file. - */ - public void setBlock(PKCS7 block) { - this.signatureBlock = block; - } - - /** - * Add a set of entries from the current manifest. - */ - public void add(String[] entries) throws JarException { - for (int i = 0; i < entries.length; i++) { - add (entries[i]); - } - } - - /** - * Add a specific entry from the current manifest. - */ - public void add(String entry) throws JarException { - MessageHeader mh = manifest.getEntry(entry); - if (mh == null) { - throw new JarException("entry " + entry + " not in manifest"); - } - MessageHeader smh; - try { - smh = computeEntry(mh); - } catch (IOException e) { - throw new JarException(e.getMessage()); - } - entries.addElement(smh); - } - - /** - * Get the entry corresponding to a given name. Returns null if - *the entry does not exist. - */ - public MessageHeader getEntry(String name) { - Enumeration enum_ = entries(); - while(enum_.hasMoreElements()) { - MessageHeader mh = enum_.nextElement(); - if (name.equals(mh.findValue("Name"))) { - return mh; - } - } - return null; - } - - /** - * Returns the n-th entry. The global header is a entry 0. */ - public MessageHeader entryAt(int n) { - return entries.elementAt(n); - } - - /** - * Returns an enumeration of the entries. - */ - public Enumeration entries() { - return entries.elements(); - } - - /** - * Given a manifest entry, computes the signature entry for this - * manifest entry. - */ - private MessageHeader computeEntry(MessageHeader mh) throws IOException { - MessageHeader smh = new MessageHeader(); - - String name = mh.findValue("Name"); - if (name == null) { - return null; - } - smh.set("Name", name); - - try { - for (int i = 0; i < hashes.length; ++i) { - MessageDigest dig = getDigest(hashes[i]); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - PrintStream ps = new PrintStream(baos); - mh.print(ps); - byte[] headerBytes = baos.toByteArray(); - byte[] digest = dig.digest(headerBytes); - smh.set(hashes[i] + "-Digest", Base64.getMimeEncoder().encodeToString(digest)); - } - return smh; - } catch (NoSuchAlgorithmException e) { - throw new JarException(e.getMessage()); - } - } - - private Hashtable digests = new Hashtable<>(); - - private MessageDigest getDigest(String algorithm) - throws NoSuchAlgorithmException { - MessageDigest dig = digests.get(algorithm); - if (dig == null) { - dig = MessageDigest.getInstance(algorithm); - digests.put(algorithm, dig); - } - dig.reset(); - return dig; - } - - - /** - * Add a signature file at current position in a stream - */ - public void stream(OutputStream os) throws IOException { - - /* the first header in the file should be the global one. - * It should say "SignatureFile-Version: x.x"; barf if not - */ - MessageHeader globals = entries.elementAt(0); - if (globals.findValue("Signature-Version") == null) { - throw new JarException("Signature file requires " + - "Signature-Version: 1.0 in 1st header"); - } - - PrintStream ps = new PrintStream(os); - globals.print(ps); - - for (int i = 1; i < entries.size(); ++i) { - MessageHeader mh = entries.elementAt(i); - mh.print(ps); - } - } -}