2445 lines · 92.7 KB · Java
RawDownload
/* * Copyright (c) 1997, 2011, 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.security.tools; import java.io.*;import java.util.*;import java.util.zip.*;import java.util.jar.*;import java.math.BigInteger;import java.net.URI;import java.net.URISyntaxException;import java.text.Collator;import java.text.MessageFormat;import java.security.cert.Certificate;import java.security.cert.X509Certificate;import java.security.cert.CertificateException;import java.security.*;import java.lang.reflect.Constructor; import com.sun.jarsigner.ContentSigner;import com.sun.jarsigner.ContentSignerParameters;import java.net.SocketTimeoutException;import java.net.URL;import java.net.URLClassLoader;import java.security.cert.CertPath;import java.security.cert.CertPathValidator;import java.security.cert.CertificateExpiredException;import java.security.cert.CertificateFactory;import java.security.cert.CertificateNotYetValidException;import java.security.cert.PKIXParameters;import java.security.cert.TrustAnchor;import java.util.Map.Entry;import sun.security.x509.*;import sun.security.util.*;import sun.misc.BASE64Encoder;  /** * <p>The jarsigner utility. * * The exit codes for the main method are: * * 0: success * 1: any error that the jar cannot be signed or verified, including: *      keystore loading error *      TSP communciation error *      jarsigner command line error... * otherwise: error codes from -strict * * @author Roland Schemers * @author Jan Luehe */ public class JarSigner {     // for i18n    private static final java.util.ResourceBundle rb =        java.util.ResourceBundle.getBundle        ("sun.security.tools.JarSignerResources");    private static final Collator collator = Collator.getInstance();    static {        // this is for case insensitive string comparisions        collator.setStrength(Collator.PRIMARY);    }     private static final String META_INF = "META-INF/";     // prefix for new signature-related files in META-INF directory    private static final String SIG_PREFIX = META_INF + "SIG-";     private static final Class[] PARAM_STRING = { String.class };     private static final String NONE = "NONE";    private static final String P11KEYSTORE = "PKCS11";     private static final long SIX_MONTHS = 180*24*60*60*1000L; //milliseconds     // Attention:    // This is the entry that get launched by the security tool jarsigner.    public static void main(String args[]) throws Exception {        JarSigner js = new JarSigner();        js.run(args);    }     static final String VERSION = "1.0";     static final int IN_KEYSTORE = 0x01;        // signer is in keystore    static final int IN_SCOPE = 0x02;    static final int NOT_ALIAS = 0x04;          // alias list is NOT empty and                                                // signer is not in alias list    static final int SIGNED_BY_ALIAS = 0x08;    // signer is in alias list     X509Certificate[] certChain;    // signer's cert chain (when composing)    PrivateKey privateKey;          // private key    KeyStore store;                 // the keystore specified by -keystore                                    // or the default keystore, never null     String keystore; // key store file    boolean nullStream = false; // null keystore input stream (NONE)    boolean token = false; // token-based keystore    String jarfile;  // jar files to sign or verify    String alias;    // alias to sign jar with    List<String> ckaliases = new ArrayList<>(); // aliases in -verify    char[] storepass; // keystore password    boolean protectedPath; // protected authentication path    String storetype; // keystore type    String providerName; // provider name    Vector<String> providers = null; // list of providers    // arguments for provider constructors    HashMap<String,String> providerArgs = new HashMap<>();    char[] keypass; // private key password    String sigfile; // name of .SF file    String sigalg; // name of signature algorithm    String digestalg = "SHA-256"; // name of digest algorithm    String signedjar; // output filename    String tsaUrl; // location of the Timestamping Authority    String tsaAlias; // alias for the Timestamping Authority's certificate    String altCertChain; // file to read alternative cert chain from    boolean verify = false; // verify the jar    String verbose = null; // verbose output when signing/verifying    boolean showcerts = false; // show certs when verifying    boolean debug = false; // debug    boolean signManifest = true; // "sign" the whole manifest    boolean externalSF = true; // leave the .SF out of the PKCS7 block    boolean strict = false;  // treat warnings as error     // read zip entry raw bytes    private ByteArrayOutputStream baos = new ByteArrayOutputStream(2048);    private byte[] buffer = new byte[8192];    private ContentSigner signingMechanism = null;    private String altSignerClass = null;    private String altSignerClasspath = null;    private ZipFile zipFile = null;     private boolean hasExpiredCert = false;    private boolean hasExpiringCert = false;    private boolean notYetValidCert = false;    private boolean chainNotValidated = false;    private boolean notSignedByAlias = false;    private boolean aliasNotInStore = false;    private boolean hasUnsignedEntry = false;    private boolean badKeyUsage = false;    private boolean badExtendedKeyUsage = false;    private boolean badNetscapeCertType = false;     CertificateFactory certificateFactory;    CertPathValidator validator;    PKIXParameters pkixParameters;     public void run(String args[]) {        try {            parseArgs(args);             // Try to load and install the specified providers            if (providers != null) {                ClassLoader cl = ClassLoader.getSystemClassLoader();                Enumeration<String> e = providers.elements();                while (e.hasMoreElements()) {                    String provName = e.nextElement();                    Class<?> provClass;                    if (cl != null) {                        provClass = cl.loadClass(provName);                    } else {                        provClass = Class.forName(provName);                    }                     String provArg = providerArgs.get(provName);                    Object obj;                    if (provArg == null) {                        obj = provClass.newInstance();                    } else {                        Constructor<?> c =                                provClass.getConstructor(PARAM_STRING);                        obj = c.newInstance(provArg);                    }                     if (!(obj instanceof Provider)) {                        MessageFormat form = new MessageFormat(rb.getString                            ("provName.not.a.provider"));                        Object[] source = {provName};                        throw new Exception(form.format(source));                    }                    Security.addProvider((Provider)obj);                }            }             if (verify) {                try {                    loadKeyStore(keystore, false);                } catch (Exception e) {                    if ((keystore != null) || (storepass != null)) {                        System.out.println(rb.getString("jarsigner.error.") +                                        e.getMessage());                        System.exit(1);                    }                }                /*              if (debug) {                    SignatureFileVerifier.setDebug(true);                    ManifestEntryVerifier.setDebug(true);                }                */                verifyJar(jarfile);            } else {                loadKeyStore(keystore, true);                getAliasInfo(alias);                 // load the alternative signing mechanism                if (altSignerClass != null) {                    signingMechanism = loadSigningMechanism(altSignerClass,                        altSignerClasspath);                }                signJar(jarfile, alias, args);            }        } catch (Exception e) {            System.out.println(rb.getString("jarsigner.error.") + e);            if (debug) {                e.printStackTrace();            }            System.exit(1);        } finally {            // zero-out private key password            if (keypass != null) {                Arrays.fill(keypass, ' ');                keypass = null;            }            // zero-out keystore password            if (storepass != null) {                Arrays.fill(storepass, ' ');                storepass = null;            }        }         if (strict) {            int exitCode = 0;            if (hasExpiringCert) {                exitCode |= 2;            }            if (chainNotValidated) {                // hasExpiredCert and notYetValidCert included in this case                exitCode |= 4;            }            if (badKeyUsage || badExtendedKeyUsage || badNetscapeCertType) {                exitCode |= 8;            }            if (hasUnsignedEntry) {                exitCode |= 16;            }            if (notSignedByAlias || aliasNotInStore) {                exitCode |= 32;            }            if (exitCode != 0) {                System.exit(exitCode);            }        }    }     /*     * Parse command line arguments.     */    void parseArgs(String args[]) {        /* parse flags */        int n = 0;         if (args.length == 0) fullusage();        for (n=0; n < args.length; n++) {             String flags = args[n];            String modifier = null;            if (flags.charAt(0) == '-') {                int pos = flags.indexOf(':');                if (pos > 0) {                    modifier = flags.substring(pos+1);                    flags = flags.substring(0, pos);                }            }             if (collator.compare(flags, "-keystore") == 0) {                if (++n == args.length) usageNoArg();                keystore = args[n];            } else if (collator.compare(flags, "-storepass") ==0) {                if (++n == args.length) usageNoArg();                storepass = getPass(modifier, args[n]);            } else if (collator.compare(flags, "-storetype") ==0) {                if (++n == args.length) usageNoArg();                storetype = args[n];            } else if (collator.compare(flags, "-providerName") ==0) {                if (++n == args.length) usageNoArg();                providerName = args[n];            } else if ((collator.compare(flags, "-provider") == 0) ||                        (collator.compare(flags, "-providerClass") == 0)) {                if (++n == args.length) usageNoArg();                if (providers == null) {                    providers = new Vector<String>(3);                }                providers.add(args[n]);                 if (args.length > (n+1)) {                    flags = args[n+1];                    if (collator.compare(flags, "-providerArg") == 0) {                        if (args.length == (n+2)) usageNoArg();                        providerArgs.put(args[n], args[n+2]);                        n += 2;                    }                }            } else if (collator.compare(flags, "-protected") ==0) {                protectedPath = true;            } else if (collator.compare(flags, "-certchain") ==0) {                if (++n == args.length) usageNoArg();                altCertChain = args[n];            } else if (collator.compare(flags, "-debug") ==0) {                debug = true;            } else if (collator.compare(flags, "-keypass") ==0) {                if (++n == args.length) usageNoArg();                keypass = getPass(modifier, args[n]);            } else if (collator.compare(flags, "-sigfile") ==0) {                if (++n == args.length) usageNoArg();                sigfile = args[n];            } else if (collator.compare(flags, "-signedjar") ==0) {                if (++n == args.length) usageNoArg();                signedjar = args[n];            } else if (collator.compare(flags, "-tsa") ==0) {                if (++n == args.length) usageNoArg();                tsaUrl = args[n];            } else if (collator.compare(flags, "-tsacert") ==0) {                if (++n == args.length) usageNoArg();                tsaAlias = args[n];            } else if (collator.compare(flags, "-altsigner") ==0) {                if (++n == args.length) usageNoArg();                altSignerClass = args[n];            } else if (collator.compare(flags, "-altsignerpath") ==0) {                if (++n == args.length) usageNoArg();                altSignerClasspath = args[n];            } else if (collator.compare(flags, "-sectionsonly") ==0) {                signManifest = false;            } else if (collator.compare(flags, "-internalsf") ==0) {                externalSF = false;            } else if (collator.compare(flags, "-verify") ==0) {                verify = true;            } else if (collator.compare(flags, "-verbose") ==0) {                verbose = (modifier != null) ? modifier : "all";            } else if (collator.compare(flags, "-sigalg") ==0) {                if (++n == args.length) usageNoArg();                sigalg = args[n];            } else if (collator.compare(flags, "-digestalg") ==0) {                if (++n == args.length) usageNoArg();                digestalg = args[n];            } else if (collator.compare(flags, "-certs") ==0) {                showcerts = true;            } else if (collator.compare(flags, "-strict") ==0) {                strict = true;            } else if (collator.compare(flags, "-h") == 0 ||                        collator.compare(flags, "-help") == 0) {                fullusage();            } else {                if (!flags.startsWith("-")) {                    if (jarfile == null) {                        jarfile = flags;                    } else {                        alias = flags;                        ckaliases.add(alias);                    }                } else {                    System.err.println(                            rb.getString("Illegal.option.") + flags);                    usage();                }            }        }         // -certs must always be specified with -verbose        if (verbose == null) showcerts = false;         if (jarfile == null) {            System.err.println(rb.getString("Please.specify.jarfile.name"));            usage();        }        if (!verify && alias == null) {            System.err.println(rb.getString("Please.specify.alias.name"));            usage();        }        if (!verify && ckaliases.size() > 1) {            System.err.println(rb.getString("Only.one.alias.can.be.specified"));            usage();        }         if (storetype == null) {            storetype = KeyStore.getDefaultType();        }        storetype = KeyStoreUtil.niceStoreTypeName(storetype);         try {            if (signedjar != null && new File(signedjar).getCanonicalPath().equals(                    new File(jarfile).getCanonicalPath())) {                signedjar = null;            }        } catch (IOException ioe) {            // File system error?            // Just ignore it.        }         if (P11KEYSTORE.equalsIgnoreCase(storetype) ||                KeyStoreUtil.isWindowsKeyStore(storetype)) {            token = true;            if (keystore == null) {                keystore = NONE;            }        }         if (NONE.equals(keystore)) {            nullStream = true;        }         if (token && !nullStream) {            System.err.println(MessageFormat.format(rb.getString                (".keystore.must.be.NONE.if.storetype.is.{0}"), storetype));            usage();        }         if (token && keypass != null) {            System.err.println(MessageFormat.format(rb.getString                (".keypass.can.not.be.specified.if.storetype.is.{0}"), storetype));            usage();        }         if (protectedPath) {            if (storepass != null || keypass != null) {                System.err.println(rb.getString                        ("If.protected.is.specified.then.storepass.and.keypass.must.not.be.specified"));                usage();            }        }        if (KeyStoreUtil.isWindowsKeyStore(storetype)) {            if (storepass != null || keypass != null) {                System.err.println(rb.getString                        ("If.keystore.is.not.password.protected.then.storepass.and.keypass.must.not.be.specified"));                usage();            }        }    }     static char[] getPass(String modifier, String arg) {        char[] output = KeyTool.getPassWithModifier(modifier, arg);        if (output != null) return output;        usage();        return null;    // Useless, usage() already exit    }     static void usageNoArg() {        System.out.println(rb.getString("Option.lacks.argument"));        usage();    }     static void usage() {        System.out.println();        System.out.println(rb.getString("Please.type.jarsigner.help.for.usage"));        System.exit(1);    }     static void fullusage() {        System.out.println(rb.getString                ("Usage.jarsigner.options.jar.file.alias"));        System.out.println(rb.getString                (".jarsigner.verify.options.jar.file.alias."));        System.out.println();        System.out.println(rb.getString                (".keystore.url.keystore.location"));        System.out.println();        System.out.println(rb.getString                (".storepass.password.password.for.keystore.integrity"));        System.out.println();        System.out.println(rb.getString                (".storetype.type.keystore.type"));        System.out.println();        System.out.println(rb.getString                (".keypass.password.password.for.private.key.if.different."));        System.out.println();        System.out.println(rb.getString

Lines 1–500 of 2445.