package org.cagrid.gaards.pki.tools;
import java.io.File;
import java.security.GeneralSecurityException;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.Security;
import java.security.cert.X509Certificate;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.PosixParser;
import org.bouncycastle.jce.PKCS10CertificationRequest;
import org.cagrid.gaards.pki.CertUtil;
import org.cagrid.gaards.pki.KeyUtil;
/**
* @author <A href="mailto:langella@bmi.osu.edu">Stephen Langella </A>
* @author <A href="mailto:oster@bmi.osu.edu">Scott Oster </A>
* @author <A href="mailto:hastings@bmi.osu.edu">Shannon Hastings </A>
* @version $Id: ArgumentManagerTable.java,v 1.2 2004/10/15 16:35:16 langella
* Exp $
*/
public class CreateHostCertificate {
public static final String CA_KEY = "cakey";
public static final String CA_KEY_DESCRIPTION = "The location of the CA private key that will be used to sign the host certificate.";
public static final String CA_CERT = "cacert";
public static final String CA_CERT_DESCRIPTION = "The location of the CA private key that will be used to sign the host certificate.";
public static final String HOSTNAME = "host";
public static final String HOSTNAME_DESCRIPTION = "The host name of the host whom the certificate will be created for.";
public static final String LIFETIME = "lifetime";
public static final String LIFETIME_DESCRIPTION = "The number of days the certificate authority should be valid for.";
public static final String PASSWORD = "password";
public static final String PASSWORD_DESCRIPTION = "The password for the CA's private key.";
public static final String KEY = "key";
public static final String KEY_DESCRIPTION = "The location to write the host private key to.";
public static final String CERT = "cert";
public static final String CERT_DESCRIPTION = "The location to write the host certificate to.";
public static final String HELP_OPT = "h";
public static final String HELP_OPT_FULL = "help";
public static void main(String[] args) {
try {
Security
.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
Options options = new Options();
Option help = new Option(HELP_OPT, HELP_OPT_FULL, false,
"Prints this message.");
options.addOption(help);
Option caKeyOpt = new Option(CA_KEY, true, CA_KEY_DESCRIPTION);
caKeyOpt.setRequired(true);
options.addOption(caKeyOpt);
Option passwordOpt = new Option(PASSWORD, true,
PASSWORD_DESCRIPTION);
options.addOption(passwordOpt);
Option caCertOpt = new Option(CA_CERT, true, CA_CERT_DESCRIPTION);
caCertOpt.setRequired(true);
options.addOption(caCertOpt);
Option hostOpt = new Option(HOSTNAME, true, HOSTNAME_DESCRIPTION);
hostOpt.setRequired(true);
options.addOption(hostOpt);
Option lifetimeOpt = new Option(LIFETIME, true,
LIFETIME_DESCRIPTION);
lifetimeOpt.setRequired(true);
options.addOption(lifetimeOpt);
Option certOpt = new Option(CERT, true, CERT_DESCRIPTION);
certOpt.setRequired(true);
options.addOption(certOpt);
Option keyOpt = new Option(KEY, true, KEY_DESCRIPTION);
keyOpt.setRequired(true);
options.addOption(keyOpt);
CommandLineParser parser = new PosixParser();
CommandLine line = parser.parse(options, args);
if (line.hasOption(HELP_OPT)) {
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp(GenerateTrustReport.class.getName(),
options);
System.exit(0);
} else {
String key = caKeyOpt.getValue();
String password = passwordOpt.getValue();
String cert = caCertOpt.getValue();
String cn = hostOpt.getValue();
String daysValid = lifetimeOpt.getValue();
String keyOut = keyOpt.getValue();
String certOut = certOpt.getValue();
int days = Integer.valueOf(daysValid).intValue();
while (days <= 0) {
System.err.println("Days Valid must be >0");
System.exit(1);
}
PrivateKey cakey = KeyUtil.loadPrivateKey(new File(key),
password);
X509Certificate cacert = CertUtil.loadCertificate("BC",
new File(cert));
KeyPair pair = KeyUtil.generateRSAKeyPair1024("BC");
String rootSub = cacert.getSubjectDN().toString();
int index = rootSub.lastIndexOf(",");
String subject = rootSub.substring(0, index) + ",CN=host/" + cn;
PKCS10CertificationRequest request = CertUtil
.generateCertficateRequest(subject, pair);
GregorianCalendar date = new GregorianCalendar(TimeZone
.getTimeZone("GMT"));
/* Allow for a five minute clock skew here. */
date.add(Calendar.MINUTE, -5);
Date start = new Date(date.getTimeInMillis());
Date end = null;
/* If hours = 0, then cert lifetime is set to user cert */
if (days <= 0) {
end = cacert.getNotAfter();
} else {
date.add(Calendar.MINUTE, 5);
date.add(Calendar.DAY_OF_MONTH, days);
Date d = new Date(date.getTimeInMillis());
if (cacert.getNotAfter().before(d)) {
throw new GeneralSecurityException(
"Cannot create a certificate that expires after issuing certificate.");
}
end = d;
}
X509Certificate userCert = CertUtil.signCertificateRequest(
request, start, end, cacert, cakey, null);
KeyUtil.writePrivateKey(pair.getPrivate(), new File(keyOut));
CertUtil.writeCertificate(userCert, new File(certOut));
System.out
.println("Successfully created the host certificate:");
System.out.println(userCert.getSubjectDN().toString());
System.out.println("Host certificate issued by:");
System.out.println(cacert.getSubjectDN().toString());
System.out.println("Host certificate valid till:");
System.out.println(userCert.getNotAfter());
System.out.println("Host private key written to:");
System.out.println(keyOut);
System.out.println("Host certificate written to:");
System.out.println(certOut);
}
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
}