2445 lines · 92.7 KB · Java
RawDownload
            s.append('\n');            first = false;        }        try {            CertPath cp = certificateFactory.generateCertPath(certs);            validator.validate(cp, pkixParameters);        } catch (Exception e) {            chainNotValidated = true;            s.append(tab + rb.getString(".CertPath.not.validated.") +                    e.getLocalizedMessage() + "]\n");   // TODO        }        String result = s.toString();        cacheForSignerInfo.put(signer, result);        return result;    }     private void writeEntry(ZipFile zf, ZipOutputStream os, ZipEntry ze)    throws IOException    {        ZipEntry ze2 = new ZipEntry(ze.getName());        ze2.setMethod(ze.getMethod());        ze2.setTime(ze.getTime());        ze2.setComment(ze.getComment());        ze2.setExtra(ze.getExtra());        if (ze.getMethod() == ZipEntry.STORED) {            ze2.setSize(ze.getSize());            ze2.setCrc(ze.getCrc());        }        os.putNextEntry(ze2);        writeBytes(zf, ze, os);    }     /**     * Writes all the bytes for a given entry to the specified output stream.     */    private synchronized void writeBytes        (ZipFile zf, ZipEntry ze, ZipOutputStream os) throws IOException {        int n;         InputStream is = null;        try {            is = zf.getInputStream(ze);            long left = ze.getSize();             while((left > 0) && (n = is.read(buffer, 0, buffer.length)) != -1) {                os.write(buffer, 0, n);                left -= n;            }        } finally {            if (is != null) {                is.close();            }        }    }     void loadKeyStore(String keyStoreName, boolean prompt) {         if (!nullStream && keyStoreName == null) {            keyStoreName = System.getProperty("user.home") + File.separator                + ".keystore";        }         try {            if (providerName == null) {                store = KeyStore.getInstance(storetype);            } else {                store = KeyStore.getInstance(storetype, providerName);            }             // Get pass phrase            // XXX need to disable echo; on UNIX, call getpass(char *prompt)Z            // and on NT call ??            if (token && storepass == null && !protectedPath                    && !KeyStoreUtil.isWindowsKeyStore(storetype)) {                storepass = getPass                        (rb.getString("Enter.Passphrase.for.keystore."));            } else if (!token && storepass == null && prompt) {                storepass = getPass                        (rb.getString("Enter.Passphrase.for.keystore."));            }             if (nullStream) {                store.load(null, storepass);            } else {                keyStoreName = keyStoreName.replace(File.separatorChar, '/');                URL url = null;                try {                    url = new URL(keyStoreName);                } catch (java.net.MalformedURLException e) {                    // try as file                    url = new File(keyStoreName).toURI().toURL();                }                InputStream is = null;                try {                    is = url.openStream();                    store.load(is, storepass);                } finally {                    if (is != null) {                        is.close();                    }                }            }            Set<TrustAnchor> tas = new HashSet<>();            try {                KeyStore caks = KeyTool.getCacertsKeyStore();                if (caks != null) {                    Enumeration<String> aliases = caks.aliases();                    while (aliases.hasMoreElements()) {                        String a = aliases.nextElement();                        try {                            tas.add(new TrustAnchor((X509Certificate)caks.getCertificate(a), null));                        } catch (Exception e2) {                            // ignore, when a SecretkeyEntry does not include a cert                        }                    }                }            } catch (Exception e) {                // Ignore, if cacerts cannot be loaded            }            if (store != null) {                Enumeration<String> aliases = store.aliases();                while (aliases.hasMoreElements()) {                    String a = aliases.nextElement();                    try {                        X509Certificate c = (X509Certificate)store.getCertificate(a);                        // Only add TrustedCertificateEntry and self-signed                        // PrivateKeyEntry                        if (store.isCertificateEntry(a) ||                                c.getSubjectDN().equals(c.getIssuerDN())) {                            tas.add(new TrustAnchor(c, null));                        }                    } catch (Exception e2) {                        // ignore, when a SecretkeyEntry does not include a cert                    }                }            }            certificateFactory = CertificateFactory.getInstance("X.509");            validator = CertPathValidator.getInstance("PKIX");            try {                pkixParameters = new PKIXParameters(tas);                pkixParameters.setRevocationEnabled(false);            } catch (InvalidAlgorithmParameterException ex) {                // Only if tas is empty            }        } catch (IOException ioe) {            throw new RuntimeException(rb.getString("keystore.load.") +                                        ioe.getMessage());        } catch (java.security.cert.CertificateException ce) {            throw new RuntimeException(rb.getString("certificate.exception.") +                                        ce.getMessage());        } catch (NoSuchProviderException pe) {            throw new RuntimeException(rb.getString("keystore.load.") +                                        pe.getMessage());        } catch (NoSuchAlgorithmException nsae) {            throw new RuntimeException(rb.getString("keystore.load.") +                                        nsae.getMessage());        } catch (KeyStoreException kse) {            throw new RuntimeException                (rb.getString("unable.to.instantiate.keystore.class.") +                kse.getMessage());        }    }     X509Certificate getTsaCert(String alias) {         java.security.cert.Certificate cs = null;         try {            cs = store.getCertificate(alias);        } catch (KeyStoreException kse) {            // this never happens, because keystore has been loaded        }        if (cs == null || (!(cs instanceof X509Certificate))) {            MessageFormat form = new MessageFormat(rb.getString                ("Certificate.not.found.for.alias.alias.must.reference.a.valid.KeyStore.entry.containing.an.X.509.public.key.certificate.for.the"));            Object[] source = {alias, alias};            error(form.format(source));        }        return (X509Certificate) cs;    }     /**     * Check if userCert is designed to be a code signer     * @param userCert the certificate to be examined     * @param bad 3 booleans to show if the KeyUsage, ExtendedKeyUsage,     *            NetscapeCertType has codeSigning flag turned on.     *            If null, the class field badKeyUsage, badExtendedKeyUsage,     *            badNetscapeCertType will be set.     */    void checkCertUsage(X509Certificate userCert, boolean[] bad) {         // Can act as a signer?        // 1. if KeyUsage, then [0:digitalSignature] or        //    [1:nonRepudiation] should be true        // 2. if ExtendedKeyUsage, then should contains ANY or CODE_SIGNING        // 3. if NetscapeCertType, then should contains OBJECT_SIGNING        // 1,2,3 must be true         if (bad != null) {            bad[0] = bad[1] = bad[2] = false;        }         boolean[] keyUsage = userCert.getKeyUsage();        if (keyUsage != null) {            keyUsage = Arrays.copyOf(keyUsage, 9);            if (!keyUsage[0] && !keyUsage[1]) {                if (bad != null) {                    bad[0] = true;                    badKeyUsage = true;                }            }        }         try {            List<String> xKeyUsage = userCert.getExtendedKeyUsage();            if (xKeyUsage != null) {                if (!xKeyUsage.contains("2.5.29.37.0") // anyExtendedKeyUsage                        && !xKeyUsage.contains("1.3.6.1.5.5.7.3.3")) {  // codeSigning                    if (bad != null) {                        bad[1] = true;                        badExtendedKeyUsage = true;                    }                }            }        } catch (java.security.cert.CertificateParsingException e) {            // shouldn't happen        }         try {            // OID_NETSCAPE_CERT_TYPE            byte[] netscapeEx = userCert.getExtensionValue                    ("2.16.840.1.113730.1.1");            if (netscapeEx != null) {                DerInputStream in = new DerInputStream(netscapeEx);                byte[] encoded = in.getOctetString();                encoded = new DerValue(encoded).getUnalignedBitString()                        .toByteArray();                 NetscapeCertTypeExtension extn =                        new NetscapeCertTypeExtension(encoded);                 Boolean val = (Boolean)extn.get(                        NetscapeCertTypeExtension.OBJECT_SIGNING);                if (!val) {                    if (bad != null) {                        bad[2] = true;                        badNetscapeCertType = true;                    }                }            }        } catch (IOException e) {            //        }    }     void getAliasInfo(String alias) {         Key key = null;         try {            java.security.cert.Certificate[] cs = null;            if (altCertChain != null) {                try {                    cs = CertificateFactory.getInstance("X.509").                            generateCertificates(new FileInputStream(altCertChain)).                            toArray(new Certificate[0]);                } catch (CertificateException ex) {                    error(rb.getString("Cannot.restore.certchain.from.file.specified"));                } catch (FileNotFoundException ex) {                    error(rb.getString("File.specified.by.certchain.does.not.exist"));                }            } else {                try {                    cs = store.getCertificateChain(alias);                } catch (KeyStoreException kse) {                    // this never happens, because keystore has been loaded                }            }            if (cs == null || cs.length == 0) {                if (altCertChain != null) {                    error(rb.getString                            ("Certificate.chain.not.found.in.the.file.specified."));                } else {                    MessageFormat form = new MessageFormat(rb.getString                        ("Certificate.chain.not.found.for.alias.alias.must.reference.a.valid.KeyStore.key.entry.containing.a.private.key.and"));                    Object[] source = {alias, alias};                    error(form.format(source));                }            }             certChain = new X509Certificate[cs.length];            for (int i=0; i<cs.length; i++) {                if (!(cs[i] instanceof X509Certificate)) {                    error(rb.getString                        ("found.non.X.509.certificate.in.signer.s.chain"));                }                certChain[i] = (X509Certificate)cs[i];            }             // We don't meant to print anything, the next call            // checks validity and keyUsage etc            printCert("", certChain[0], true, 0, true);             try {                CertPath cp = certificateFactory.generateCertPath(Arrays.asList(certChain));                validator.validate(cp, pkixParameters);            } catch (Exception e) {                chainNotValidated = true;            }             try {                if (!token && keypass == null)                    key = store.getKey(alias, storepass);                else                    key = store.getKey(alias, keypass);            } catch (UnrecoverableKeyException e) {                if (token) {                    throw e;                } else if (keypass == null) {                    // Did not work out, so prompt user for key password                    MessageFormat form = new MessageFormat(rb.getString                        ("Enter.key.password.for.alias."));                    Object[] source = {alias};                    keypass = getPass(form.format(source));                    key = store.getKey(alias, keypass);                }            }        } catch (NoSuchAlgorithmException e) {            error(e.getMessage());        } catch (UnrecoverableKeyException e) {            error(rb.getString("unable.to.recover.key.from.keystore"));        } catch (KeyStoreException kse) {            // this never happens, because keystore has been loaded        }         if (!(key instanceof PrivateKey)) {            MessageFormat form = new MessageFormat(rb.getString                ("key.associated.with.alias.not.a.private.key"));            Object[] source = {alias};            error(form.format(source));        } else {            privateKey = (PrivateKey)key;        }    }     void error(String message)    {        System.out.println(rb.getString("jarsigner.")+message);        System.exit(1);    }      void error(String message, Exception e)    {        System.out.println(rb.getString("jarsigner.")+message);        if (debug) {            e.printStackTrace();        }        System.exit(1);    }     char[] getPass(String prompt)    {        System.err.print(prompt);        System.err.flush();        try {            char[] pass = Password.readPassword(System.in);             if (pass == null) {                error(rb.getString("you.must.enter.key.password"));            } else {                return pass;            }        } catch (IOException ioe) {            error(rb.getString("unable.to.read.password.")+ioe.getMessage());        }        // this shouldn't happen        return null;    }     /*     * Reads all the bytes for a given zip entry.     */    private synchronized byte[] getBytes(ZipFile zf,                                         ZipEntry ze) throws IOException {        int n;         InputStream is = null;        try {            is = zf.getInputStream(ze);            baos.reset();            long left = ze.getSize();             while((left > 0) && (n = is.read(buffer, 0, buffer.length)) != -1) {                baos.write(buffer, 0, n);                left -= n;            }        } finally {            if (is != null) {                is.close();            }        }         return baos.toByteArray();    }     /*     * Returns manifest entry from given jar file, or null if given jar file     * does not have a manifest entry.     */    private ZipEntry getManifestFile(ZipFile zf) {        ZipEntry ze = zf.getEntry(JarFile.MANIFEST_NAME);        if (ze == null) {            // Check all entries for matching name            Enumeration<? extends ZipEntry> enum_ = zf.entries();            while (enum_.hasMoreElements() && ze == null) {                ze = enum_.nextElement();                if (!JarFile.MANIFEST_NAME.equalsIgnoreCase                    (ze.getName())) {                    ze = null;                }            }        }        return ze;    }     /*     * Computes the digests of a zip entry, and returns them as an array     * of base64-encoded strings.     */    private synchronized String[] getDigests(ZipEntry ze, ZipFile zf,                                             MessageDigest[] digests,                                             BASE64Encoder encoder)        throws IOException {         int n, i;        InputStream is = null;        try {            is = zf.getInputStream(ze);            long left = ze.getSize();            while((left > 0)                && (n = is.read(buffer, 0, buffer.length)) != -1) {                for (i=0; i<digests.length; i++) {                    digests[i].update(buffer, 0, n);                }                left -= n;            }        } finally {            if (is != null) {                is.close();            }        }         // complete the digests        String[] base64Digests = new String[digests.length];        for (i=0; i<digests.length; i++) {            base64Digests[i] = encoder.encode(digests[i].digest());        }        return base64Digests;    }     /*     * Computes the digests of a zip entry, and returns them as a list of     * attributes     */    private Attributes getDigestAttributes(ZipEntry ze, ZipFile zf,                                           MessageDigest[] digests,                                           BASE64Encoder encoder)        throws IOException {         String[] base64Digests = getDigests(ze, zf, digests, encoder);        Attributes attrs = new Attributes();         for (int i=0; i<digests.length; i++) {            attrs.putValue(digests[i].getAlgorithm()+"-Digest",                           base64Digests[i]);        }        return attrs;    }     /*     * Updates the digest attributes of a manifest entry, by adding or     * replacing digest values.     * A digest value is added if the manifest entry does not contain a digest     * for that particular algorithm.     * A digest value is replaced if it is obsolete.     *     * Returns true if the manifest entry has been changed, and false     * otherwise.     */    private boolean updateDigests(ZipEntry ze, ZipFile zf,                                  MessageDigest[] digests,                                  BASE64Encoder encoder,                                  Manifest mf) throws IOException {        boolean update = false;         Attributes attrs = mf.getAttributes(ze.getName());        String[] base64Digests = getDigests(ze, zf, digests, encoder);         for (int i=0; i<digests.length; i++) {

Lines 1501–2000 of 2445. Previous lines