package at.chille.crawler.analysis; import java.io.ByteArrayInputStream; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.List; import java.util.Set; import javax.security.auth.x500.X500Principal; import at.chille.crawler.database.model.Certificate; /** * Parsing and Sorting Certificates using the Subject and Issuer Principals. * @author chille * */ public class CertificateSorter { private static CertificateFactory cf; /** * Restores an encoded X509Certificate and stores it at the given position in the chain. * @param certs * @return */ public static List<X509Certificate> parseCertificates(Set<Certificate> certs) { if (cf == null) { try { cf = CertificateFactory.getInstance("X.509"); } catch (CertificateException e) { e.printStackTrace(); } } // System.out.println("Size: " + certs.size()); ArrayList<X509Certificate> chain = new ArrayList<X509Certificate>(); for (int i = 0; i < certs.size(); i++) { chain.add(null); } try { for (Certificate cert : certs) { byte[] encodedCert = cert.getEncodedCertificate(); ByteArrayInputStream bais = new ByteArrayInputStream( encodedCert); X509Certificate certb; certb = (X509Certificate) cf.generateCertificate(bais); bais.close(); // System.out.println("depth: " + cert.getDepth() + // " i"+cert.getIssuer()); chain.set(cert.getDepth(), certb); // out.println(" X509 back again " + certb.getSigAlgName()); } } catch (Exception e) { e.printStackTrace(); } while (chain.size() - 1 > 0 && chain.get(chain.size() - 1) == null) { chain.remove(chain.size() - 1); System.err.println("Duplicate Certificate Stored in database."); } return chain; } /** * Sorts the Certificate Chain by IssuerDN and SubjectDN. The [0]-Element should be the Hostname, * the last Element should be the Root Certificate. * * @param certs * The first element must be the correct one. * @return sorted Certificate Chain */ public static List<X509Certificate> sortCertificates( List<X509Certificate> certs) { int length = certs.size(); if (certs.size() <= 1) { return certs; } for (X509Certificate cert : certs) { if (cert == null) { throw new NullPointerException(); } } for (int i = 0; i < length; i++) { boolean found = false; // Principal issuer = certs.get(i).getIssuerDN(); X500Principal issuer = certs.get(i).getIssuerX500Principal(); for (int j = i + 1; j < length; j++) { // Principal subject = certs.get(j).getSubjectDN(); X500Principal subject = certs.get(j).getSubjectX500Principal(); if (issuer.equals(subject)) { // sorting necessary? if (i + 1 != j) { X509Certificate tmp = certs.get(i + 1); certs.set(i + 1, certs.get(j)); certs.set(j, tmp); } found = true; } } if (!found) { break; } } return certs; } }