package org.ovirt.engine.core.utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateFactory;
import org.apache.commons.codec.binary.Base64;
import org.ovirt.engine.core.common.config.Config;
import org.ovirt.engine.core.common.config.ConfigValues;
import org.ovirt.engine.core.uutils.ssh.OpenSSHUtils;
public class PKIResources {
private static Resource caCertificate;
private static Resource engineCertificate;
public static Resource getCaCertificate() {
if (caCertificate == null) {
initCaCertificate();
}
return caCertificate;
}
private static synchronized void initCaCertificate() {
if (caCertificate == null) {
caCertificate = new Resource(
EngineLocalConfig.getInstance().getPKICACert(),
Format.X509_PEM_CA,
null);
}
}
public static Resource getEngineCertificate() {
if (engineCertificate == null) {
initEngineCertificate();
}
return engineCertificate;
}
private static synchronized void initEngineCertificate() {
if (engineCertificate == null) {
engineCertificate = new Resource(
EngineLocalConfig.getInstance().getPKIEngineCert(),
Format.X509_PEM,
Config.getValue(ConfigValues.SSHKeyAlias));
}
}
@FunctionalInterface
private interface IFormatter {
String toString(Certificate cert, String alias);
}
private static IFormatter formatPEM = (cert, alias) -> {
try {
return String.format(
"-----BEGIN CERTIFICATE-----%1$c" +
"%2$s" +
"-----END CERTIFICATE-----%1$c",
'\n',
new Base64(
76,
new byte[] { (byte)'\n' }
).encodeToString(
cert.getEncoded()
)
);
}
catch (CertificateEncodingException e) {
throw new RuntimeException(e);
}
};
private static IFormatter formatOpenSSH = (cert, alias) -> OpenSSHUtils.getKeyString(cert.getPublicKey(), alias);
public enum Format {
X509_PEM_CA("application/x-x509-ca-cert", formatPEM),
X509_PEM("application/x-x509-cert", formatPEM),
OPENSSH_PUBKEY("text/plain", formatOpenSSH);
private final String contentType;
private final IFormatter formatter;
private Format(String contentType, IFormatter formatter) {
this.contentType = contentType;
this.formatter = formatter;
}
public String getContentType() {
return contentType;
}
public String toString(Certificate cert, String alias) {
return formatter.toString(cert, alias);
}
public String toString(Certificate cert) {
return toString(cert, null);
}
}
public static class Resource {
private final Certificate cert;
private final Format defaultFormat;
private final String defaultAlias;
private Resource(File cert, Format defaultFormat, String defaultAlias) {
try (InputStream in = new FileInputStream(cert)) {
this.cert = CertificateFactory.getInstance("X.509").generateCertificate(in);
this.defaultFormat = defaultFormat;
this.defaultAlias = defaultAlias;
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
public String toString(Format format, String alias) {
return (format != null ? format : defaultFormat).toString(
cert,
alias != null ? alias : defaultAlias
);
}
public String toString(Format format) {
return toString(format, null);
}
public String toString() {
return toString(null, null);
}
public String getContentType(Format format) {
return (format != null ? format : defaultFormat).getContentType();
}
public String getContentType() {
return getContentType(null);
}
}
}