/* ************************************************************************
#
# DivConq
#
# http://divconq.com/
#
# Copyright:
# Copyright 2014 eTimeline, LLC. All rights reserved.
#
# License:
# See the license.txt file in the project's top-level directory for details.
#
# Authors:
# * Andy White
#
************************************************************************ */
package divconq.util;
import java.io.ByteArrayInputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.KeyStore;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.List;
import divconq.lang.op.FuncResult;
public class KeyUtil {
static public class CertSummary {
public String alias = null;
public String subject = null;
public String thumbprint = null;
public boolean privatekey = false;
}
static public FuncResult<Collection<CertSummary>> loadKeystoreSummary(Path keystore, char[] password) {
FuncResult<Collection<CertSummary>> res = new FuncResult<>();
KeyStore ks = null;
try {
// load key store
ks = KeyStore.getInstance("JKS");
ks.load(Files.newInputStream(keystore), password);
}
catch (Exception x) {
res.error("Unable to open/read keystore file: " + x);
return res;
}
try {
List<CertSummary> certs = new ArrayList<>();
res.setResult(certs);
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
Enumeration<String> aliases = ks.aliases();
while (aliases.hasMoreElements()) {
CertSummary summ = new CertSummary();
summ.alias = aliases.nextElement();
byte[] encoded = null;
if (ks.isCertificateEntry(summ.alias))
encoded = ((KeyStore.TrustedCertificateEntry) ks.getEntry(summ.alias, null)).getTrustedCertificate().getEncoded();
else if (ks.isKeyEntry(summ.alias)) {
encoded = ((KeyStore.PrivateKeyEntry) ks.getEntry(summ.alias, new KeyStore.PasswordProtection(password))).getCertificate().getEncoded();
summ.privatekey = true;
}
if (encoded == null) {
res.error("Unable to decode: " + summ.alias);
return res;
}
X509Certificate cert = (X509Certificate)certFactory.generateCertificate(new ByteArrayInputStream(encoded));
summ.subject = cert.getSubjectDN().toString();
summ.thumbprint = KeyUtil.getCertThumbprint(cert);
certs.add(summ);
}
}
catch (Exception x) {
res.error("Unable to decode keystore file: " + x);
}
return res;
}
/* key export notes
if ((key instanceof PrivateKey) && "PKCS#8".equals(key.getFormat())) {
// Most PrivateKeys use this format, but check for safety.
try (FileOutputStream os = new FileOutputStream(alias + ".key")) {
os.write(key.getEncoded());
os.flush();
}
}
*/
public static String getCertThumbprint(X509Certificate cert) {
try {
return HashUtil.getSha1(new ByteArrayInputStream(cert.getEncoded()));
}
catch (CertificateEncodingException x) {
}
return null;
}
public static String getCertThumbprint(javax.security.cert.X509Certificate cert) {
try {
return HashUtil.getSha1(new ByteArrayInputStream(cert.getEncoded()));
}
catch (javax.security.cert.CertificateEncodingException x) {
}
return null;
}
public static String getKeyThumbprint(java.security.Key key) {
return HashUtil.getSha1(new ByteArrayInputStream(key.getEncoded()));
}
public static String getCertThumbprint(java.security.cert.Certificate cert) {
try {
return HashUtil.getSha1(new ByteArrayInputStream(cert.getEncoded()));
}
catch (java.security.cert.CertificateEncodingException x) {
}
return null;
}
}