4217 lines · 166.7 KB · Java
RawDownload
                             (keyPass != null) ? keyPass : storePass,                             new Certificate[] { newCert } );         if (verbose) {            System.err.println(rb.getString("New.certificate.self.signed."));            System.err.print(newCert.toString());            System.err.println();        }    }     /**     * Processes a certificate reply from a certificate authority.     *     * <p>Builds a certificate chain on top of the certificate reply,     * using trusted certificates from the keystore. The chain is complete     * after a self-signed certificate has been encountered. The self-signed     * certificate is considered a root certificate authority, and is stored     * at the end of the chain.     *     * <p>The newly generated chain replaces the old chain associated with the     * key entry.     *     * @return true if the certificate reply was installed, otherwise false.     */    private boolean installReply(String alias, InputStream in)        throws Exception    {        if (alias == null) {            alias = keyAlias;        }         Pair<Key,char[]> objs = recoverKey(alias, storePass, keyPass);        PrivateKey privKey = (PrivateKey)objs.fst;        if (keyPass == null) {            keyPass = objs.snd;        }         Certificate userCert = keyStore.getCertificate(alias);        if (userCert == null) {            MessageFormat form = new MessageFormat                (rb.getString("alias.has.no.public.key.certificate."));            Object[] source = {alias};            throw new Exception(form.format(source));        }         // Read the certificates in the reply        Collection<? extends Certificate> c = cf.generateCertificates(in);        if (c.isEmpty()) {            throw new Exception(rb.getString("Reply.has.no.certificates"));        }        Certificate[] replyCerts = c.toArray(new Certificate[c.size()]);        Certificate[] newChain;        if (replyCerts.length == 1) {            // single-cert reply            newChain = establishCertChain(userCert, replyCerts[0]);        } else {            // cert-chain reply (e.g., PKCS#7)            newChain = validateReply(alias, userCert, replyCerts);        }         // Now store the newly established chain in the keystore. The new        // chain replaces the old one.        if (newChain != null) {            keyStore.setKeyEntry(alias, privKey,                                 (keyPass != null) ? keyPass : storePass,                                 newChain);            return true;        } else {            return false;        }    }     /**     * Imports a certificate and adds it to the list of trusted certificates.     *     * @return true if the certificate was added, otherwise false.     */    private boolean addTrustedCert(String alias, InputStream in)        throws Exception    {        if (alias == null) {            throw new Exception(rb.getString("Must.specify.alias"));        }        if (keyStore.containsAlias(alias)) {            MessageFormat form = new MessageFormat(rb.getString                ("Certificate.not.imported.alias.alias.already.exists"));            Object[] source = {alias};            throw new Exception(form.format(source));        }         // Read the certificate        X509Certificate cert = null;        try {            cert = (X509Certificate)cf.generateCertificate(in);        } catch (ClassCastException cce) {            throw new Exception(rb.getString("Input.not.an.X.509.certificate"));        } catch (CertificateException ce) {            throw new Exception(rb.getString("Input.not.an.X.509.certificate"));        }         // if certificate is self-signed, make sure it verifies        boolean selfSigned = false;        if (isSelfSigned(cert)) {            cert.verify(cert.getPublicKey());            selfSigned = true;        }         if (noprompt) {            keyStore.setCertificateEntry(alias, cert);            return true;        }         // check if cert already exists in keystore        String reply = null;        String trustalias = keyStore.getCertificateAlias(cert);        if (trustalias != null) {            MessageFormat form = new MessageFormat(rb.getString                ("Certificate.already.exists.in.keystore.under.alias.trustalias."));            Object[] source = {trustalias};            System.err.println(form.format(source));            reply = getYesNoReply                (rb.getString("Do.you.still.want.to.add.it.no."));        } else if (selfSigned) {            if (trustcacerts && (caks != null) &&                    ((trustalias=caks.getCertificateAlias(cert)) != null)) {                MessageFormat form = new MessageFormat(rb.getString                        ("Certificate.already.exists.in.system.wide.CA.keystore.under.alias.trustalias."));                Object[] source = {trustalias};                System.err.println(form.format(source));                reply = getYesNoReply                        (rb.getString("Do.you.still.want.to.add.it.to.your.own.keystore.no."));            }            if (trustalias == null) {                // Print the cert and ask user if they really want to add                // it to their keystore                printX509Cert(cert, System.out);                reply = getYesNoReply                        (rb.getString("Trust.this.certificate.no."));            }        }        if (reply != null) {            if ("YES".equals(reply)) {                keyStore.setCertificateEntry(alias, cert);                return true;            } else {                return false;            }        }         // Try to establish trust chain        try {            Certificate[] chain = establishCertChain(null, cert);            if (chain != null) {                keyStore.setCertificateEntry(alias, cert);                return true;            }        } catch (Exception e) {            // Print the cert and ask user if they really want to add it to            // their keystore            printX509Cert(cert, System.out);            reply = getYesNoReply                (rb.getString("Trust.this.certificate.no."));            if ("YES".equals(reply)) {                keyStore.setCertificateEntry(alias, cert);                return true;            } else {                return false;            }        }         return false;    }     /**     * Prompts user for new password. New password must be different from     * old one.     *     * @param prompt the message that gets prompted on the screen     * @param oldPasswd the current (i.e., old) password     */    private char[] getNewPasswd(String prompt, char[] oldPasswd)        throws Exception    {        char[] entered = null;        char[] reentered = null;         for (int count = 0; count < 3; count++) {            MessageFormat form = new MessageFormat                (rb.getString("New.prompt."));            Object[] source = {prompt};            System.err.print(form.format(source));            entered = Password.readPassword(System.in);            passwords.add(entered);            if (entered == null || entered.length < 6) {                System.err.println(rb.getString                    ("Password.is.too.short.must.be.at.least.6.characters"));            } else if (Arrays.equals(entered, oldPasswd)) {                System.err.println(rb.getString("Passwords.must.differ"));            } else {                form = new MessageFormat                        (rb.getString("Re.enter.new.prompt."));                Object[] src = {prompt};                System.err.print(form.format(src));                reentered = Password.readPassword(System.in);                passwords.add(reentered);                if (!Arrays.equals(entered, reentered)) {                    System.err.println                        (rb.getString("They.don.t.match.Try.again"));                } else {                    Arrays.fill(reentered, ' ');                    return entered;                }            }            if (entered != null) {                Arrays.fill(entered, ' ');                entered = null;            }            if (reentered != null) {                Arrays.fill(reentered, ' ');                reentered = null;            }        }        throw new Exception(rb.getString("Too.many.failures.try.later"));    }     /**     * Prompts user for alias name.     * @param prompt the {0} of "Enter {0} alias name:  " in prompt line     * @returns the string entered by the user, without the \n at the end     */    private String getAlias(String prompt) throws Exception {        if (prompt != null) {            MessageFormat form = new MessageFormat                (rb.getString("Enter.prompt.alias.name."));            Object[] source = {prompt};            System.err.print(form.format(source));        } else {            System.err.print(rb.getString("Enter.alias.name."));        }        return (new BufferedReader(new InputStreamReader(                                        System.in))).readLine();    }     /**     * Prompts user for an input string from the command line (System.in)     * @prompt the prompt string printed     * @returns the string entered by the user, without the \n at the end     */    private String inputStringFromStdin(String prompt) throws Exception {        System.err.print(prompt);        return (new BufferedReader(new InputStreamReader(                                        System.in))).readLine();    }     /**     * Prompts user for key password. User may select to choose the same     * password (<code>otherKeyPass</code>) as for <code>otherAlias</code>.     */    private char[] getKeyPasswd(String alias, String otherAlias,                                char[] otherKeyPass)        throws Exception    {        int count = 0;        char[] keyPass = null;         do {            if (otherKeyPass != null) {                MessageFormat form = new MessageFormat(rb.getString                        ("Enter.key.password.for.alias."));                Object[] source = {alias};                System.err.println(form.format(source));                 form = new MessageFormat(rb.getString                        (".RETURN.if.same.as.for.otherAlias."));                Object[] src = {otherAlias};                System.err.print(form.format(src));            } else {                MessageFormat form = new MessageFormat(rb.getString                        ("Enter.key.password.for.alias."));                Object[] source = {alias};                System.err.print(form.format(source));            }            System.err.flush();            keyPass = Password.readPassword(System.in);            passwords.add(keyPass);            if (keyPass == null) {                keyPass = otherKeyPass;            }            count++;        } while ((keyPass == null) && count < 3);         if (keyPass == null) {            throw new Exception(rb.getString("Too.many.failures.try.later"));        }         return keyPass;    }     /**     * Prints a certificate in a human readable format.     */    private void printX509Cert(X509Certificate cert, PrintStream out)        throws Exception    {        /*        out.println("Owner: "                    + cert.getSubjectDN().toString()                    + "\n"                    + "Issuer: "                    + cert.getIssuerDN().toString()                    + "\n"                    + "Serial number: " + cert.getSerialNumber().toString(16)                    + "\n"                    + "Valid from: " + cert.getNotBefore().toString()                    + " until: " + cert.getNotAfter().toString()                    + "\n"                    + "Certificate fingerprints:\n"                    + "\t MD5:  " + getCertFingerPrint("MD5", cert)                    + "\n"                    + "\t SHA1: " + getCertFingerPrint("SHA1", cert));        */         MessageFormat form = new MessageFormat                (rb.getString(".PATTERN.printX509Cert"));        Object[] source = {cert.getSubjectDN().toString(),                        cert.getIssuerDN().toString(),                        cert.getSerialNumber().toString(16),                        cert.getNotBefore().toString(),                        cert.getNotAfter().toString(),                        getCertFingerPrint("MD5", cert),                        getCertFingerPrint("SHA1", cert),                        getCertFingerPrint("SHA-256", cert),                        cert.getSigAlgName(),                        cert.getVersion()                        };        out.println(form.format(source));         if (cert instanceof X509CertImpl) {            X509CertImpl impl = (X509CertImpl)cert;            X509CertInfo certInfo = (X509CertInfo)impl.get(X509CertImpl.NAME                                                           + "." +                                                           X509CertImpl.INFO);            CertificateExtensions exts = (CertificateExtensions)                    certInfo.get(X509CertInfo.EXTENSIONS);            if (exts != null) {                printExtensions(rb.getString("Extensions."), exts, out);            }        }    }     private static void printExtensions(String title, CertificateExtensions exts, PrintStream out)            throws Exception {        int extnum = 0;        Iterator<Extension> i1 = exts.getAllExtensions().iterator();        Iterator<Extension> i2 = exts.getUnparseableExtensions().values().iterator();        while (i1.hasNext() || i2.hasNext()) {            Extension ext = i1.hasNext()?i1.next():i2.next();            if (extnum == 0) {                out.println();                out.println(title);                out.println();            }            out.print("#"+(++extnum)+": "+ ext);            if (ext.getClass() == Extension.class) {                byte[] v = ext.getExtensionValue();                if (v.length == 0) {                    out.println(rb.getString(".Empty.value."));                } else {                    new sun.misc.HexDumpEncoder().encodeBuffer(ext.getExtensionValue(), out);                    out.println();                }            }            out.println();        }    }     /**     * Returns true if the certificate is self-signed, false otherwise.     */    private boolean isSelfSigned(X509Certificate cert) {        return signedBy(cert, cert);    }     private boolean signedBy(X509Certificate end, X509Certificate ca) {        if (!ca.getSubjectDN().equals(end.getIssuerDN())) {            return false;        }        try {            end.verify(ca.getPublicKey());            return true;        } catch (Exception e) {            return false;        }    }     /**     * Locates a signer for a given certificate from a given keystore and     * returns the signer's certificate.     * @param cert the certificate whose signer is searched, not null     * @param ks the keystore to search with, not null     * @return <code>cert</code> itself if it's already inside <code>ks</code>,     * or a certificate inside <code>ks</code> who signs <code>cert</code>,     * or null otherwise.     */    private static Certificate getTrustedSigner(Certificate cert, KeyStore ks)            throws Exception {        if (ks.getCertificateAlias(cert) != null) {            return cert;        }        for (Enumeration<String> aliases = ks.aliases();                aliases.hasMoreElements(); ) {            String name = aliases.nextElement();            Certificate trustedCert = ks.getCertificate(name);            if (trustedCert != null) {                try {                    cert.verify(trustedCert.getPublicKey());                    return trustedCert;                } catch (Exception e) {                    // Not verified, skip to the next one                }            }        }        return null;    }     /**     * Gets an X.500 name suitable for inclusion in a certification request.     */    private X500Name getX500Name() throws IOException {        BufferedReader in;        in = new BufferedReader(new InputStreamReader(System.in));        String commonName = "Unknown";        String organizationalUnit = "Unknown";        String organization = "Unknown";        String city = "Unknown";        String state = "Unknown";        String country = "Unknown";        X500Name name;        String userInput = null;         int maxRetry = 20;        do {            if (maxRetry-- < 0) {                throw new RuntimeException(rb.getString(                        "Too.many.retries.program.terminated"));            }            commonName = inputString(in,                    rb.getString("What.is.your.first.and.last.name."),                    commonName);            organizationalUnit = inputString(in,                    rb.getString                        ("What.is.the.name.of.your.organizational.unit."),                    organizationalUnit);            organization = inputString(in,                    rb.getString("What.is.the.name.of.your.organization."),                    organization);            city = inputString(in,                    rb.getString("What.is.the.name.of.your.City.or.Locality."),                    city);            state = inputString(in,                    rb.getString("What.is.the.name.of.your.State.or.Province."),                    state);            country = inputString(in,                    rb.getString                        ("What.is.the.two.letter.country.code.for.this.unit."),                    country);            name = new X500Name(commonName, organizationalUnit, organization,                                city, state, country);            MessageFormat form = new MessageFormat                (rb.getString("Is.name.correct."));            Object[] source = {name};            userInput = inputString                (in, form.format(source), rb.getString("no"));        } while (collator.compare(userInput, rb.getString("yes")) != 0 &&                 collator.compare(userInput, rb.getString("y")) != 0);         System.err.println();        return name;    }     private String inputString(BufferedReader in, String prompt,                               String defaultValue)        throws IOException    {        System.err.println(prompt);        MessageFormat form = new MessageFormat                (rb.getString(".defaultValue."));        Object[] source = {defaultValue};        System.err.print(form.format(source));        System.err.flush();         String value = in.readLine();        if (value == null || collator.compare(value, "") == 0) {            value = defaultValue;        }        return value;    }     /**     * Writes an X.509 certificate in base64 or binary encoding to an output

Lines 2501–3000 of 4217. Previous lines