Package org.apache.harmony.tools.keytool

Source Code of org.apache.harmony.tools.keytool.KeyStoreCertPrinter

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/

package org.apache.harmony.tools.keytool;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;

import org.apache.harmony.luni.util.Base64;

/**
* Class for printing to stdout the contents of the keystore or a single
* certificate. The certificate can be in the keystore (list(..) method) or not
* (printCert(..) method).
*/
public class KeyStoreCertPrinter {

    /**
     * Prints the contents of the entry associated with the alias given in
     * param. If no alias is specified, the contents of the entire keystore are
     * printed.
     *
     * @param param
     * @throws KeyStoreException
     * @throws NoSuchAlgorithmException
     * @throws NoSuchProviderException
     * @throws UnrecoverableKeyException
     * @throws IOException
     * @throws FileNotFoundException
     * @throws CertificateException
     */
    static void list(KeytoolParameters param) throws KeyStoreException,
            NoSuchAlgorithmException, NoSuchProviderException,
            UnrecoverableKeyException, CertificateException,
            FileNotFoundException, IOException {
        Enumeration aliases;
        KeyStore keyStore = param.getKeyStore();
        String alias = param.getAlias();

        if (alias != null) {
            // if the alias is specified, make a single-element
            // enumeration of it
            aliases = Collections.enumeration(Collections.singleton(alias));
        } else {// if the alias is not given,
            // get all aliases
            aliases = keyStore.aliases();
            // print the keystore info
            System.out.println("Type of keystore: " + keyStore.getType());
            System.out.println("Keystore provider name: "
                    + keyStore.getProvider().getName());
            int keyStoreSize = keyStore.size();
            System.out.println("\nThe keystore contains " + keyStoreSize
                    + ((keyStoreSize == 1) ? " entry \n" : " entries \n"));
        }

        String mdProvider = (param.getMdProvider() != null) ? param
                .getMdProvider() : param.getProvider();

        while (aliases.hasMoreElements()) {
            String currentAlias = (String) aliases.nextElement();
            String creationDate = keyStore.getCreationDate(currentAlias)
                    .toString();

            // true if the keystore entry is a TrustedCertificateEntry
            boolean trustedEntry = false;
            // true if the keystore entry is a SecretKeyEntry
            boolean secretKeyEntry = false;

            // get the type of the entry to print it out
            String entryType = "Key entry";
            if (keyStore.entryInstanceOf(currentAlias,
                    KeyStore.TrustedCertificateEntry.class)) {
                entryType = "Trusted certificate entry";
                trustedEntry = true;
            } else if (keyStore.entryInstanceOf(currentAlias,
                    KeyStore.PrivateKeyEntry.class)) {
                entryType = "Private key entry";
            } else if (keyStore.entryInstanceOf(currentAlias,
                    KeyStore.SecretKeyEntry.class)) {
                entryType = "Secret key entry";
                secretKeyEntry = true;
            }

            // get the certificate associated with the currentAlias
            X509Certificate x509cert = ((X509Certificate) keyStore
                    .getCertificate(currentAlias));

            // if -v or -rfc options are specified
            if (param.isVerbose() || param.isRfc()) {
                // print detailed info about the _entry_
                System.out.println("Alias name: " + currentAlias);
                System.out.println("Date of creation: " + creationDate);
                System.out.println("Type of the entry: " + entryType);

                if (!secretKeyEntry) {
                    Certificate[] certChain = keyStore
                            .getCertificateChain(currentAlias);

                    if (!trustedEntry) {
                        System.out.println("Certificate chain length: "
                                + certChain.length);
                    }

                    // if -v option was given, print the detailed info about
                    // the certificate
                    if (param.isVerbose()) {
                        // print out the first certificate
                        System.out.println("Certificate[1]:");
                        printX509CertDetailed(x509cert, mdProvider);
                        if (!trustedEntry) {
                            for (int i = 1; i < certChain.length; i++) {
                                System.out.println("Certificate[" + (i + 1)
                                        + "]:");
                                printX509CertDetailed(
                                        (X509Certificate) certChain[i],
                                        mdProvider);
                            }
                        }
                    }
                    // if -rfc option is given, print the certificate in Base64
                    // printable format
                    else {
                        // print out the first certificate
                        System.out.println("Certificate[1]:");
                        System.out.println("-----BEGIN CERTIFICATE-----");
                        System.out.println(Base64.encode(x509cert.getEncoded(),
                                "ISO-8859-1"));
                        System.out.println("-----END CERTIFICATE-----");

                        if (!trustedEntry) {
                            for (int i = 1; i < certChain.length; i++) {
                                System.out.println("Certificate[" + (i + 1)
                                        + "]:");
                                System.out
                                        .println("-----BEGIN CERTIFICATE-----");
                                System.out.println(Base64.encode(certChain[i]
                                        .getEncoded(), "ISO-8859-1"));
                                System.out.println("-----END CERTIFICATE-----");
                            }
                        }
                    }
                } else {
                    // if the key is explicitly asked to be printed
                    // by setting the alias, print it out, otherwise - do
                    // nothing.
                    if (alias != null) {
                        // TODO: ask for password if not set, when read from
                        // stdin is OK.
                        char[] keyPass;
                        if ((keyPass = param.getKeyPass()) != null) {
                            Key key = keyStore.getKey(currentAlias, keyPass);
                            System.out.println("Algorithm: "
                                    + key.getAlgorithm() + "\nFormat: "
                                    + key.getFormat());
                            System.out.println("Key: "
                                    + formatBytes(key.getEncoded()));
                        } else {
                            System.out.println("If you want to print the key, "
                                    + "please set the entry password using "
                                    + "\"-keypass\" option");
                        }

                    }
                }
                System.out.println("\n*******************************"
                        + "*******************************\n");

            } else {// if neither -v nor -rfc options specified
                String commaSpc = ", ";
                System.out.print(currentAlias + commaSpc + creationDate
                        + commaSpc + entryType);

                if (!secretKeyEntry) {
                    System.out.print(commaSpc
                            + "\nCertificate fingerprint (MD5):  ");
                    printMD(x509cert.getEncoded(), "MD5", mdProvider);
                } else {
                    // If the key is explicitly asked to be printed
                    // by setting the alias, print it out, otherwise - do
                    // nothing.
                    if (alias != null) {
                        char[] keyPass;
                        if ((keyPass = param.getKeyPass()) != null) {
                            Key key = keyStore.getKey(currentAlias, keyPass);
                            System.out.println(key.getAlgorithm() + ", "
                                    + key.getFormat() + ", "
                                    + formatBytes(key.getEncoded()));
                        } else {
                            System.out.println("If you want to print the key, "
                                    + "please set the entry password using "
                                    + "\"-keypass\" option");
                        }
                    }
                }
            }
        }

    }

    /**
     * Prints the detailed description of a certificate in a human-readable
     * format: its owner and issuer, serial number, validity period and
     * fingerprints. providerName is needed to generate MessageDigest. If it is
     * null, a default one is used.
     *
     * @param x509cert
     * @param providerName
     * @throws CertificateEncodingException
     * @throws NoSuchAlgorithmException
     * @throws NoSuchProviderException
     */
    static void printX509CertDetailed(X509Certificate x509cert,
            String providerName) throws CertificateEncodingException,
            NoSuchAlgorithmException, NoSuchProviderException {
        System.out.println("Owner: " + x509cert.getSubjectX500Principal());
        System.out.println("Issuer: " + x509cert.getIssuerX500Principal());
        System.out.println("Serial number: "
                + Integer.toHexString(x509cert.getSerialNumber().intValue()));
        System.out.println("Validity period \n\t from:  "
                + x509cert.getNotBefore() + "\n\t until: "
                + x509cert.getNotAfter());

        // print certificate fingerprints (MD5 and SHA1).
        byte[] encodedCert;
        try {
            encodedCert = x509cert.getEncoded();
        } catch (CertificateEncodingException e) {
            throw new CertificateEncodingException(
                    "Failed to encode the certificate", e);
        }

        String strMD5 = "MD5";
        String strSHA1 = "SHA1";

        System.out.print("Certificate fingerprints: " + "\n\t " + strMD5
                + ":  ");
        printMD(encodedCert, strMD5, providerName);

        System.out.print("\t " + strSHA1 + ": ");
        printMD(encodedCert, strSHA1, providerName);
    }

    // Prints out the message digest of the encoding using the given algorithm
    // and provider. Provider can be null.
    private static void printMD(byte[] encoding, String mdAlgorithm,
            String providerName) throws NoSuchAlgorithmException,
            NoSuchProviderException {
        byte[] digest;
        // if provider name is given, use it when getting
        // an instance of MessageDigest.
        try {
            if (providerName != null) {
                digest = MessageDigest.getInstance(mdAlgorithm, providerName)
                        .digest(encoding);
            } else {
                digest = MessageDigest.getInstance(mdAlgorithm)
                        .digest(encoding);
            }
        } catch (NoSuchAlgorithmException e) {
            throw new NoSuchAlgorithmException("The algorithm " + mdAlgorithm
                    + " is not found in the environment.", e);
        } catch (NoSuchProviderException e) {
            throw (NoSuchProviderException) new NoSuchProviderException(
                    "The provider " + providerName
                            + " is not found in the environment.").initCause(e);
        }

        // print out in the way: "0A:1B:C3:D4:..."
        System.out.println(formatBytes(digest));
    }

    /**
     * Reads an X.509 certificate from the file specified in param and prints it
     * in a human-readable format. If param.getFileName() returns null, the
     * certificate is read from the standard input. The input data is awaited
     * for 3 seconds. If the data is not entered, an exception is thrown.
     *
     * @param param
     * @throws KeytoolException
     * @throws IOException
     * @throws CertificateException
     * @throws FileNotFoundException
     * @throws NoSuchAlgorithmException
     * @throws NoSuchProviderException
     */
    static void printCert(KeytoolParameters param)
            throws FileNotFoundException, CertificateException, IOException,
            KeytoolException, NoSuchAlgorithmException, NoSuchProviderException {

        String provider = param.getProvider();
        String certProvider = (param.getCertProvider() != null) ? param
                .getCertProvider() : provider;
        String mdProvider = (param.getMdProvider() != null) ? param
                .getMdProvider() : provider;
        // get the certificate(s) from the file
        Collection certCollection = CertReader.readCerts(param.getFileName(),
                false, certProvider);
        Iterator certIter = certCollection.iterator();
        int counter = 1;

        // print the datailed info on all certificates
        while (certIter.hasNext()) {
            X509Certificate cert = (X509Certificate) certIter.next();
            System.out.println("\nCertificate[" + counter + "]:");
            printX509CertDetailed(cert, mdProvider);
            ++counter;
        }
    }

    // Formats byte array as a String looking like "0A:1B:C3:D4:....:E5".
    private static String formatBytes(byte[] bytes) {
        int i;
        // The method is expected to format mostly message digest results and
        // the length of the String repesenting a SHA1 digest printed in
        // the way: "0A:1B:C3:D4:....:E5" is the biggest and is 59.
        StringBuffer buffer = new StringBuffer(59);
        int length;
        String currentByte;
        for (i = 0; i < bytes.length - 1; i++) {
            // TODO: change when String.format(..) method is implemented.
            // buffer.append(String.format("%02X", bytes[i]) + ":");
            currentByte = Integer.toHexString(bytes[i]).toUpperCase();
            if ((length = currentByte.length()) > 1) {
                buffer.append(currentByte.substring(length - 2) + ":");
            } else {
                buffer.append("0" + currentByte + ":");
            }
        }
        // The last byte doesn't need ":" after it ("...:E5:6F")
        // TODO: change in the same way to (String.format(..))
        currentByte = Integer.toHexString(bytes[i]).toUpperCase();
        if ((length = currentByte.length()) > 1) {
            buffer.append(currentByte.substring(length - 2));
        } else {
            buffer.append("0" + currentByte);
        }
        return new String(buffer);
    }
}
TOP

Related Classes of org.apache.harmony.tools.keytool.KeyStoreCertPrinter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.