package org.cagrid.gaards.pki.tools;
import gov.nih.nci.cagrid.common.Utils;
import java.io.File;
import java.io.PrintWriter;
import java.security.cert.X509CRL;
import java.security.cert.X509CRLEntry;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
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.cagrid.gaards.pki.CertUtil;
import org.cagrid.gaards.pki.TrustUtils;
import org.cagrid.gaards.pki.TrustedCAFileListing;
public class GenerateTrustReport {
public static final String OUT_OPT = "o";
public static final String OUT_OPT_FULL = "out";
public static final String HELP_OPT = "h";
public static final String HELP_OPT_FULL = "help";
public static PrintWriter pw;
public static void main(String[] args) {
Options options = new Options();
Option help = new Option(HELP_OPT, HELP_OPT_FULL, false, "Prints this message.");
Option out = new Option(OUT_OPT, OUT_OPT_FULL, true, "The file to write the report to.");
out.setRequired(false);
options.addOption(help);
options.addOption(out);
try {
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 str = out.getValue();
if (Utils.clean(str) == null) {
str = "grid-trust-report.txt";
}
System.out.println(str);
pw = new PrintWriter(new File(str));
File f = Utils.getTrustedCerificatesDirectory();
List<TrustedCAFileListing> list = TrustUtils.getTrustedCertificates(f);
report("================================================");
report("| *** GRID TRUST REPORT *** |");
report("================================================");
report("");
report("Certificates Directory: " + f.getAbsolutePath());
report("Number of Certificates: " + list.size());
report("Report Date: " + new Date());
report("");
report("");
boolean warningsFound = false;
report("*** WARNINGS ***");
report("");
if (checkDuplicates(list)) {
warningsFound = true;
}
if (checkValidity(list)) {
warningsFound = true;
}
if (!warningsFound) {
report(" NO WARNINGS DETECTED.");
}
report("");
report("*** CERTIFICATE SUMMARY ***");
report("");
for (int i = 0; i < list.size(); i++) {
TrustedCAFileListing ca = list.get(i);
try {
X509Certificate cert = CertUtil.loadCertificate(ca.getCertificate());
report("Certificate Subject: " + cert.getSubjectDN());
report("Serial Number: " + cert.getSerialNumber());
report("Valid On: " + cert.getNotBefore());
report("Valid After: " + cert.getNotAfter());
report("File Prefix: " + ca.getName());
report("Certificate File: " + ca.getCertificate().getAbsolutePath());
report("Certificate Last Modified: " + new Date(ca.getCertificate().lastModified()));
if (ca.getSigningPolicy() == null) {
report("Signing Policy: NONE");
} else {
report("Signing Policy: " + ca.getSigningPolicy().getAbsolutePath());
}
if (ca.getMetadata() == null) {
report("SyncGTS Report: NONE");
} else {
report("SyncGTS Report: " + ca.getMetadata().getAbsolutePath());
}
if (ca.getCRL() == null) {
report("CRL: NONE");
} else {
report("CRL: " + ca.getCRL().getAbsolutePath());
X509CRL crl = CertUtil.loadCRL(ca.getCRL());
Set s = crl.getRevokedCertificates();
if (s == null) {
report("Certificates Revoked: 0");
} else {
report("Certificates Revoked: " + s.size());
Iterator curr = s.iterator();
report("Revoked Ceritficates:");
int count = 1;
while (curr.hasNext()) {
X509CRLEntry entry = (X509CRLEntry) curr.next();
report(" " + count + ") " + entry.getSerialNumber());
count++;
}
}
}
report("");
} catch (Exception e) {
report("");
report("*** ERROR LOADING CA " + ca.getName() + " ***");
report("*** REASON: " + e.getMessage() + " ***");
report("");
}
}
}
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
} finally {
if (pw != null) {
pw.close();
}
}
}
public static boolean checkDuplicates(List<TrustedCAFileListing> list) throws Exception {
boolean warning = false;
Set<String> found = new HashSet<String>();
for (int i = 0; i < list.size(); i++) {
TrustedCAFileListing ca = list.get(i);
X509Certificate cert = CertUtil.loadCertificate(ca.getCertificate());
if (found.contains(cert.getSubjectDN().getName())) {
report("Duplicate entries found for " + cert.getSubjectDN().getName());
warning = true;
} else {
found.add(cert.getSubjectDN().getName());
}
}
return warning;
}
public static boolean checkValidity(List<TrustedCAFileListing> list) throws Exception {
boolean warning = false;
for (int i = 0; i < list.size(); i++) {
TrustedCAFileListing ca = list.get(i);
X509Certificate cert = CertUtil.loadCertificate(ca.getCertificate());
try {
cert.checkValidity();
} catch (Exception e) {
report("The certificate " + cert.getSubjectDN().getName() + " is invalid.");
warning = true;
}
}
return warning;
}
public static void report(String message) {
System.out.println(message);
pw.println(message);
}
}