package org.properssl.sslcertx;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import javax.naming.ldap.LdapName;
import javax.naming.ldap.Rdn;
import javax.security.auth.x500.X500Principal;
import org.apache.commons.codec.binary.Hex;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
import org.kohsuke.args4j.Option;
import org.postgresql.util.Base64;
import org.properssl.sslcertx.mariadb.MariaDBCertificateExtractor;
import org.properssl.sslcertx.postgresql.PostgreSQLCertificateExtractor;
import org.properssl.sslcertx.type.ServerType;
public class App {
@Option(name = "--type", required = true, usage = "the type of remote server")
ServerType type;
@Option(name = "--host", required = true, usage = "the hostname or ip address of the remote server")
String host;
@Option(name = "--port", required = false, usage = "the port of the remote server")
int port = -1;
public static void main(String args[]) {
new App().doMain(args);
}
public void doMain(String[] args) {
CmdLineParser parser = new CmdLineParser(this);
try {
// parse the arguments.
parser.parseArgument(args);
} catch (CmdLineException e) {
System.err.println(e.getMessage());
System.err.println("java -jar sslcertx.jar [options...]");
// print the list of available options
parser.printUsage(System.err);
System.err.println();
return;
}
if (port < 0) {
port = type.getDefaultPort();
}
X509Certificate chain[] = null;
switch (type) {
case POSTGRESQL:
chain = PostgreSQLCertificateExtractor.extractCertificate(host,
port);
break;
case MYSQL:
case MARIADB:
chain = MariaDBCertificateExtractor.extractCertificate(host, port);
break;
default:
throw new RuntimeException("Unhandled server type: " + type);
}
try {
for (int i = 0; i < chain.length; i++) {
X509Certificate cert = chain[i];
X500Principal principal = cert.getSubjectX500Principal();
if (i == 0) {
System.out.println("Client Certificate:");
} else {
System.out.println("\n");
System.out.println("Parent Certificate #" + i + ":");
}
String dn = principal.getName();
LdapName ldapDN = new LdapName(dn);
for (Rdn rdn : ldapDN.getRdns()) {
System.out.println(rdn.getType() + " -> " + rdn.getValue());
}
System.out.println("SHA1 Fingerprint: " + getFingerprint(cert));
System.out.print(encodeCert(cert.getEncoded()));
}
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
private static String encodeCert(byte[] cert) {
StringBuilder sb = new StringBuilder();
sb.append("-----BEGIN CERTIFICATE-----\n");
sb.append(Base64.encodeBytes(cert));
sb.append("\n");
sb.append("-----END CERTIFICATE-----\n");
return sb.toString();
}
public static String getFingerprint(X509Certificate cert)
throws NoSuchAlgorithmException, CertificateEncodingException {
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] der = cert.getEncoded();
md.update(der);
byte[] digest = md.digest();
String hex = Hex.encodeHexString(digest).toUpperCase();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hex.length(); i++) {
if (i > 0 && i % 2 == 0) {
sb.append(":");
}
sb.append(hex.charAt(i));
}
return sb.toString();
}
}