/*
* ChainBuilder ESB
* Visual Enterprise Integration
*
* Copyright (C) 2006 Bostech Corporation
*
* 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 2 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, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* $Id: AuthenticationUtil.java 8498 2007-08-03 18:33:00Z mpreston $
*/
package com.bostechcorp.cbesb.ui.util;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/*
* This is a utility class for the Authentication Manager functionality.
*/
public class AuthenticationUtil {
protected static Log log = LogFactory.getLog(AuthenticationUtil.class);
protected static String commandResult;
public static String MULTIPLE_FILE_SEPARATOR=" ;!; ";
public static String getCommandResult() {
return commandResult;
}
protected static String getKeyToolPath()
{
String javaHome = System.getenv("JAVA_HOME");
if (javaHome != null) {
File path = new File(javaHome + File.separator + "bin" + File.separator + "keytool");
return path.getAbsolutePath();
}
//JAVA_HOME is not set, hope keytool is in the system path
return "keytool";
}
/**
* Generate a private/public key pair and self signed certificate and write it to a
* file in JKS format.
* This will overwite an existing file.
*/
public static void generateKey(File jksFileToCreate, String dName, String password) throws Exception {
if (jksFileToCreate.exists()) jksFileToCreate.delete();
String command = getKeyToolPath() + " -genkey -keyalg rsa -dname \"" +dName + "\" -keypass " + password +
" -storepass " + password + " -keystore \"" + jksFileToCreate.getAbsolutePath() + "\"" +
" -keyalg \"RSA\"";
runKeyTool(command);
}
/**
* Export a Certificate Signing Request from a private key jks file to a base-64 encoded
* export file.
*/
public static void exportCertificateSigningRequest(File jksKeyFile, String password, File exportFileToCreate) throws Exception {
String command = getKeyToolPath() + " -certreq -keypass " + password +
" -storepass " + password + " -keystore \"" + jksKeyFile.getAbsolutePath() + "\"" +
" -file \"" + exportFileToCreate.getAbsolutePath() + "\"" + " -rfc";
runKeyTool(command);
}
/**
* Export the public key certificate (or certificate chain) from a private key jks file
* to a base-64 encoded export file
*/
public static void exportPublicKeyCertificate(File jksKeyFile, String password, File exportFileToCreate) throws Exception {
String command = getKeyToolPath() + " -export -keypass " + password +
" -storepass " + password + " -keystore \"" + jksKeyFile.getAbsolutePath() + "\"" +
" -file \"" + exportFileToCreate.getAbsolutePath() + "\"" + " -rfc";
runKeyTool(command);
}
/**
* Import a base-64 encoded signed certificate chain into a jks key file.
* This replaces the existing certificate in the key file.
*/
public static void importSignedCertificate(File jksKeyFile, String password, File importFile, String preRequiredFiles) throws Exception {
importPreRequiredFiles(jksKeyFile, password, processFileList(preRequiredFiles));
String command = getKeyToolPath() + " -import -keypass " + password +
" -storepass " + password + " -keystore \"" + jksKeyFile.getAbsolutePath() + "\"" +
" -file \"" + importFile.getAbsolutePath() + "\" -noprompt";
runKeyTool(command);
}
private static void importPreRequiredFiles(File jksKeyFile, String password, File[] files) throws Exception
{
if (files!=null)
if (files.length!=0)
for (int i = 0; i < files.length; i++)
{
String command = getKeyToolPath() + " -import -alias chainCert"+i+" -keypass " + password +
" -storepass " + password + " -keystore \"" + jksKeyFile.getAbsolutePath() + "\"" +
" -file \"" + files[i].getPath() + "\" -noprompt";
runKeyTool(command);
}
}
private static File[] processFileList(String preRequiredFiles)
{
String[] fileNames=preRequiredFiles.split(MULTIPLE_FILE_SEPARATOR);
List<File> files=new ArrayList<File>();
if (fileNames.length!=0)
for (int i = 0; i < fileNames.length; i++)
{
String fileName=fileNames[i].replaceAll("\r", "").replaceAll("\n", "");
if (!"".equals(fileName.trim()))
{
File f = new File(fileName.trim());
if (f.exists())//making sure file really exists
{files.add(f);}
}
}
File[] ff=new File[files.size()];
return files.toArray(ff);
}
/**
* Return a readable string summarizing a key file
* Used to "view" a key file.
*/
public static String keyFileToString(File jksKeyFile, String password) throws Exception {
String command = getKeyToolPath() + " -list -v -keypass " + password +
" -storepass " + password + " -keystore \"" + jksKeyFile.getAbsolutePath() + "\"";
runKeyTool(command);
return getCommandResult();
}
/**
* Import a base-64 encoded certificate file into a trust store
*/
public static void importTrustedCertificate(File jksTrustStoreFile, String password, File importFile) throws Exception {
// construct an alias of the form certnnn that does not already exist in the truststore
String[] entries = {};
try {
entries = getTrustStoreEntries(jksTrustStoreFile, password);
}
catch (Exception e) {
if (!e.toString().contains("file does not exist")) throw e;
}
int maxVal=0;
for (int i=0; i<entries.length; i++) {
int val;
int index;
try {
if (entries[i].startsWith("cert") && (index = entries[i].indexOf(' ')) > 0) {
val = Integer.parseInt(entries[i].substring(4,index));
if (val > maxVal) maxVal = val;
}
} catch (NumberFormatException nfe) {
//TODO
}
}
String alias = "cert" + (++maxVal);
// import the certificate
String command = getKeyToolPath() + " -import -keypass " + password +
" -storepass " + password + " -keystore \"" + jksTrustStoreFile.getAbsolutePath() + "\"" +
" -alias " + alias + " -file \"" + importFile.getAbsolutePath() + "\"" + " -noprompt";
runKeyTool(command);
}
/**
* Get a list of the entries in a trust store file. Use this to browse a trust file for
* exporting or deleting an entry.
*/
public static String[] getTrustStoreEntries(File jksTrustStoreFile, String password) throws Exception {
String[] result = {""};
String command = getKeyToolPath() + " -list -v -keypass " + password +
" -storepass " + password + " -keystore \"" + jksTrustStoreFile.getAbsolutePath() + "\"";
runKeyTool(command);
Vector<String> aliases = new Vector<String>();
Vector<String> dNames = new Vector<String>();
BufferedReader br = new BufferedReader(new StringReader(commandResult));
String line;
int index;
while((line=br.readLine()) != null) {
if (line.startsWith("Alias") && (index = line.indexOf(':')) > 0) {
aliases.add(line.substring(index+2));
}
if (line.startsWith("Owner") && (index = line.indexOf(':')) > 0) {
dNames.add(line.substring(index+2));
}
}
int entries = aliases.size();
if (dNames.size() != entries)
throw new Exception("problem parsing file");
result = new String[entries];
for (int i=0; i<entries; i++)
result[i] = aliases.elementAt(i) + " - " + dNames.elementAt(i);
return result;
}
/**
* Export a trusted certificate from a jks trust store file to a base-64 encoded export file.
* entryName should be an alias name in the truststore. Valid entries can be found with getTrustStoreEntries()
*/
public static void exportTrustedCertificate(File jksTrustStoreFile, String password, String entryName, File exportFileToCreate) throws Exception {
String entryAlias;
int firstSpace = entryName.indexOf(' ');
if (firstSpace > 0) entryAlias = entryName.substring(0, firstSpace);
else entryAlias = entryName;
String command = getKeyToolPath() + " -export -keypass " + password +
" -storepass " + password + " -keystore \"" + jksTrustStoreFile.getAbsolutePath() + "\"" +
" -file \"" + exportFileToCreate.getAbsolutePath() + "\"" + " -rfc" + " -alias " + entryAlias;
runKeyTool(command);
}
/**
* Delete a trusted certificate from a jks trust store file.
* entryName should be an alias name in the truststore. Valid entries can be found with getTrustStoreEntries()
*/
public static void deleteTrustedCertificate(File jksTrustStoreFile, String password, String entryName) throws Exception {
String entryAlias;
int firstSpace = entryName.indexOf(' ');
if (firstSpace > 0) entryAlias = entryName.substring(0, firstSpace);
else entryAlias = entryName;
String command = getKeyToolPath() + " -delete -keypass " + password +
" -storepass " + password + " -keystore \"" + jksTrustStoreFile.getAbsolutePath() + "\"" +
" -alias " + entryAlias;
runKeyTool(command);
}
/**
* Return a readable string summarizing the contents of a trust store file.
* Used to "view" a trust store.
*/
public static String trustStoreFileToString(File jksTrustStoreFile, String password) throws Exception {
return keyFileToString(jksTrustStoreFile, password);
}
/**
* Return a human readable string summarizing the contents of a base-64 encoded export file.
* Use to "view" and export file.
*/
public static String exportFileToString(File exportFile) throws Exception {
String command = getKeyToolPath() + " -printcert -v -file \"" + exportFile.getAbsolutePath() + "\"";
runKeyTool(command);
return getCommandResult();
}
protected class ProcessMonitor extends Thread {
BufferedReader br;
PrintStream ps;
public ProcessMonitor (InputStream is, OutputStream os) {
this.br = new BufferedReader(new InputStreamReader(is));
this.ps = new PrintStream(os);
this.start();
}
public void run() {
String line;
try {
while ((line=br.readLine())!=null) ps.println(line);
}
catch (Exception e) {
//TODO handle Exception
System.out.println("\n\nmonitor got "+e);
e.printStackTrace();
}
}
}
protected static void runKeyTool(String cmd) throws Exception {
int ex=1;
AuthenticationUtil inst = new AuthenticationUtil();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Runtime rt = Runtime.getRuntime();
try {
Process ktProc = rt.exec(cmd);
ProcessMonitor m1 = inst.new ProcessMonitor(ktProc.getInputStream(), baos);
ProcessMonitor m2 = inst.new ProcessMonitor(ktProc.getErrorStream(), baos);
OutputStream os = ktProc.getOutputStream();
PrintStream ps = new PrintStream(os);
ps.println("");
ps.flush();
ex = ktProc.waitFor();
m1.join();
m2.join();
commandResult = baos.toString();
}
catch (Exception e) {
//TODO handle Exception
log.error("error processing certificate "+e, e);
}
if (ex != 0) throw new Exception(commandResult);
}
public static void main(String args[]) throws Exception {
System.out.println("AuthenticationUtil tester\n" +
" 1-Generate Private Key\n" +
" 2-Export Certificate Signing Request\n" +
" 3-Export Public Key Certificate\n" +
" 4-Import Signed Certificate\n" +
" 5-List key file contents\n" +
" 6-Import Trusted Certificate\n" +
" 7-Get Trust Store Entries\n" +
" 8-Export Trusted Certificate\n" +
" 9-Delete Trusted Certificate\n" +
" 10-List Trust Store Contents\n" +
"option:");
BufferedReader bi = new BufferedReader(new InputStreamReader(System.in));
int option = Integer.parseInt(bi.readLine());
switch (option) {
case 1: {
System.out.println("file:");
File jksFile = new File(bi.readLine());
System.out.println("password:");
String password = bi.readLine();
// make the dname
System.out.println("CN:");
String cn = bi.readLine();
System.out.println("OU:");
String ou = bi.readLine();
System.out.println("O:");
String o = bi.readLine();
System.out.println("L:");
String l = bi.readLine();
System.out.println("S:");
String s = bi.readLine();
System.out.println("C:");
String c = bi.readLine();
String dName = "CN="+cn+" OU="+ou+" O="+o+" L="+l+" S="+s+" C="+c;
AuthenticationUtil.generateKey(jksFile, dName, password);
System.out.println("\n\nresult:\n"+AuthenticationUtil.getCommandResult());
}
break;
case 2: {
System.out.println("key file:");
File jksFile = new File(bi.readLine());
System.out.println("password:");
String password = bi.readLine();
System.out.println("export file:");
File pemFile = new File(bi.readLine());
AuthenticationUtil.exportCertificateSigningRequest(jksFile, password, pemFile);
System.out.println("\n\nresult:\n"+AuthenticationUtil.getCommandResult());
}
break;
case 3: {
System.out.println("key file:");
File jksFile = new File(bi.readLine());
System.out.println("password:");
String password = bi.readLine();
System.out.println("export file:");
File pemFile = new File(bi.readLine());
AuthenticationUtil.exportPublicKeyCertificate(jksFile, password, pemFile);
System.out.println("\n\nresult:\n"+AuthenticationUtil.getCommandResult());
}
break;
case 4: {
System.out.println("key file:");
File jksFile = new File(bi.readLine());
System.out.println("password:");
String password = bi.readLine();
System.out.println("import file:");
File pemFile = new File(bi.readLine());
AuthenticationUtil.importSignedCertificate(jksFile, password, pemFile,"");
System.out.println("\n\nresult:\n"+AuthenticationUtil.getCommandResult());
}
break;
case 5: {
System.out.println("key file:");
File jksFile = new File(bi.readLine());
System.out.println("password:");
String password = bi.readLine();
String content = AuthenticationUtil.keyFileToString(jksFile, password);
System.out.println("\n\ncontent:\n"+content);
}
break;
case 6: {
System.out.println("trust file:");
File jksFile = new File(bi.readLine());
System.out.println("password:");
String password = bi.readLine();
System.out.println("import file:");
File pemFile = new File(bi.readLine());
AuthenticationUtil.importTrustedCertificate(jksFile, password, pemFile);
System.out.println("\n\nresult:\n"+AuthenticationUtil.getCommandResult());
}
break;
case 7: {
System.out.println("trust file:");
File jksFile = new File(bi.readLine());
System.out.println("password:");
String password = bi.readLine();
String entries[] = AuthenticationUtil.getTrustStoreEntries(jksFile, password);
System.out.println("\n\ncontent:\n");
for (int i=0; i<entries.length; i++)
System.out.println("entry["+i+"]="+entries[i]);
}
break;
case 8: {
System.out.println("trust file:");
File jksFile = new File(bi.readLine());
System.out.println("password:");
String password = bi.readLine();
System.out.println("entry alias:");
String entry = bi.readLine();
System.out.println("export file:");
File pemFile = new File(bi.readLine());
AuthenticationUtil.exportTrustedCertificate(jksFile, password, entry, pemFile);
System.out.println("\n\nresult:\n"+AuthenticationUtil.getCommandResult());
}
break;
case 9: {
System.out.println("trust file:");
File jksFile = new File(bi.readLine());
System.out.println("password:");
String password = bi.readLine();
System.out.println("entry alias:");
String entry = bi.readLine();
AuthenticationUtil.deleteTrustedCertificate(jksFile, password, entry);
System.out.println("\n\nresult:\n"+AuthenticationUtil.getCommandResult());
}
break;
case 10: {
System.out.println("truststore file:");
File jksFile = new File(bi.readLine());
System.out.println("password:");
String password = bi.readLine();
String content = AuthenticationUtil.trustStoreFileToString(jksFile, password);
System.out.println("\n\ncontent:\n"+content);
}
break;
default:
System.out.println("bad option");
break;
}
}
}
|