package io.cattle.platform.ssh.common; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.StringReader; import java.security.DigestInputStream; import java.security.MessageDigest; import java.security.PublicKey; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.security.interfaces.RSAPublicKey; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import javax.naming.ldap.LdapName; import javax.naming.ldap.Rdn; import org.apache.commons.codec.binary.Hex; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; import org.bouncycastle.openssl.PEMParser; import org.bouncycastle.util.io.pem.PemObject; public class SslCertificateUtils { public static Integer getKeySize(String certInput) throws Exception { X509Certificate cert = getCertificateFromPem(certInput); PublicKey key = cert.getPublicKey(); if (key instanceof RSAPublicKey) { RSAPublicKey keySpec = (RSAPublicKey) key; return keySpec.getModulus().bitLength(); } return null; } public static List<?> getSubjectAlternativeNames(String certInput) throws Exception { X509Certificate cert = getCertificateFromPem(certInput); Collection<List<?>> names = cert.getSubjectAlternativeNames(); if (names == null) { return null; } List<String> altNames = new ArrayList<>(); Iterator<List<?>> it = names.iterator(); while (it.hasNext()) { List<?> obj = it.next(); // first value is type identifier (IP, DNS, etc), so adding second only altNames.add(obj.get(1).toString()); } return altNames; } public static String getExpirationDate(String certInput) throws Exception { X509Certificate cert = getCertificateFromPem(certInput); return cert.getNotAfter().toString(); } public static String getSerialNumber(String certInput) throws Exception { X509Certificate cert = getCertificateFromPem(certInput); return cert.getSerialNumber().toString(); } public static String getAlgorithm(String certInput) throws Exception { X509Certificate cert = getCertificateFromPem(certInput); return cert.getSigAlgName(); } public static String getVersion(String certInput) throws Exception { X509Certificate cert = getCertificateFromPem(certInput); return String.valueOf(cert.getVersion()); } public static String getIssuedDate(String certInput) throws Exception { X509Certificate cert = getCertificateFromPem(certInput); return cert.getNotBefore().toString(); } public static String getIssuer(String certInput) throws Exception { X509Certificate cert = getCertificateFromPem(certInput); return cert.getIssuerX500Principal().getName(); } public static String getCN(String certInput) throws Exception { X509Certificate cert = getCertificateFromPem(certInput); String dn = cert.getSubjectX500Principal().getName(); LdapName ln = new LdapName(dn); for (Rdn rdn : ln.getRdns()) { if (rdn.getType().equalsIgnoreCase("CN")) { return rdn.getValue().toString(); } } return null; } private static X509Certificate getCertificateFromPem(String certInput) throws IOException, CertificateException { StringReader reader = new StringReader(certInput); PEMParser pr = new PEMParser(reader); try { PemObject pem = pr.readPemObject(); X509CertificateHolder holder = new X509CertificateHolder(pem.getContent()); return new JcaX509CertificateConverter().setProvider("BC") .getCertificate(holder); } finally { pr.close(); } } /** * Obtains the fingerprint of the certificate in the "ab:cd:ef:...:12" format. */ public static String getCertificateFingerprint(String certInput) throws Exception { X509Certificate cert = getCertificateFromPem(certInput); if (cert == null) { return null; } return digest(cert); } public static String digest(X509Certificate k) throws Exception { MessageDigest md5 = MessageDigest.getInstance("SHA1"); DigestInputStream in = new DigestInputStream(new ByteArrayInputStream(k.getEncoded()), md5); try { while (in.read(new byte[128]) > 0) { } } finally { in.close(); } StringBuilder buf = new StringBuilder(); char[] hex = Hex.encodeHex(md5.digest()); for (int i = 0; i < hex.length; i += 2) { if (buf.length() > 0) buf.append(':'); buf.append(hex, i, 2); } return buf.toString(); } }