Security Java

/*
   This program is a part of the companion code for Core Java 8th ed.
   (http://horstmann.com/corejava)
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
   This program 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 for more details.
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see .
*/
import java.io.Console;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.Principal;
import java.security.PrivateKey;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import sun.security.x509.CertificateIssuerName;
import sun.security.x509.X500Name;
import sun.security.x509.X509CertImpl;
import sun.security.x509.X509CertInfo;
/**
 * This program signs a certificate, using the private key of another certificate in a keystore.
 * @version 1.01 2007-10-07
 * @author Cay Horstmann
 */
public class CertificateSigner
{
   public static void main(String[] args)
   {
      String ksname = null; // the keystore name
      String alias = null; // the private key alias
      String inname = null; // the input file name
      String outname = null; // the output file name
      for (int i = 0; i < args.length; i += 2)
      {
         if (args[i].equals("-keystore")) ksname = args[i + 1];
         else if (args[i].equals("-alias")) alias = args[i + 1];
         else if (args[i].equals("-infile")) inname = args[i + 1];
         else if (args[i].equals("-outfile")) outname = args[i + 1];
         else usage();
      }
      if (ksname == null || alias == null || inname == null || outname == null) usage();
      try
      {
         Console console = System.console();
         if (console == null) error("No console");
         char[] password = console.readPassword("Keystore password: ");
         KeyStore store = KeyStore.getInstance("JKS", "SUN");
         InputStream in = new FileInputStream(ksname);
         store.load(in, password);
         Arrays.fill(password, ' ');
         in.close();
         char[] keyPassword = console.readPassword("Key password for %s: ", alias);
         PrivateKey issuerPrivateKey = (PrivateKey) store.getKey(alias, keyPassword);
         Arrays.fill(keyPassword, ' ');
         if (issuerPrivateKey == null) error("No such private key");
         in = new FileInputStream(inname);
         CertificateFactory factory = CertificateFactory.getInstance("X.509");
         X509Certificate inCert = (X509Certificate) factory.generateCertificate(in);
         in.close();
         byte[] inCertBytes = inCert.getTBSCertificate();
         X509Certificate issuerCert = (X509Certificate) store.getCertificate(alias);
         Principal issuer = issuerCert.getSubjectDN();
         String issuerSigAlg = issuerCert.getSigAlgName();
         FileOutputStream out = new FileOutputStream(outname);
         X509CertInfo info = new X509CertInfo(inCertBytes);
         info.set(X509CertInfo.ISSUER, new CertificateIssuerName((X500Name) issuer));
         X509CertImpl outCert = new X509CertImpl(info);
         outCert.sign(issuerPrivateKey, issuerSigAlg);
         outCert.derEncode(out);
         out.close();
      }
      catch (Exception e)
      {
         e.printStackTrace();
      }
   }
   /**
    * Prints an error message and exits.
    * @param message the error message
    */
   public static void error(String message)
   {
      System.out.println(message);
      System.exit(1);
   }
   /**
    * Prints a usage message and exits.
    */
   public static void usage()
   {
      System.out.println("Usage: java CertificateSigner"
            + " -keystore keyStore -alias issuerKeyAlias"
            + " -infile inputFile -outfile outputFile");
      System.exit(1);
   }
}