/* * Copyright (C) 2014 Intel Corporation * All rights reserved. */ package com.intel.mtwilson.tls.policy.factory; import com.intel.dcsg.cpg.crypto.SimpleKeystore; import com.intel.dcsg.cpg.io.Resource; import com.intel.dcsg.cpg.tls.policy.TlsPolicy; import com.intel.dcsg.cpg.tls.policy.TlsPolicyBuilder; import com.intel.dcsg.cpg.tls.policy.impl.FirstCertificateTrustDelegate; import com.intel.dcsg.cpg.tls.policy.impl.InsecureTlsPolicy; import com.intel.dcsg.cpg.x509.X509Util; import com.intel.dcsg.cpg.x509.repository.KeystoreCertificateRepository; import com.intel.mtwilson.My; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.security.KeyManagementException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.apache.commons.io.IOUtils; /** * * @author jbuhacoff * @deprecated need to migrate to Mt Wilson 2.0 tls policy types and factories */ public class V1TlsPolicyFactory { private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(TlsPolicyFactory.class); private static final V1TlsPolicyFactory instance = new V1TlsPolicyFactory(); public static V1TlsPolicyFactory getInstance() { return instance; } public TlsPolicy getTlsPolicyWithKeystore(String tlsPolicyName, Resource resource) throws KeyManagementException, IOException { String password = My.configuration().getTlsKeystorePassword(); SimpleKeystore tlsKeystore = new SimpleKeystore(resource, password); // XXX TODO only because txthost doesn't have the field yet... we should get the keystore from the txthost object TlsPolicy tlsPolicy = getTlsPolicyWithKeystore(tlsPolicyName, tlsKeystore); // XXX TODO not sure that this belongs in the http-authorization package, because policy names are an application-level thing (allowed configurations), and creating the right repository is an application-level thing too (mutable vs immutable, and underlying implementation - keystore, array, cms of pem-list. return tlsPolicy; } public TlsPolicy getTlsPolicyWithKeystore(SimpleKeystore tlsKeystore) throws IOException, KeyManagementException { return getTlsPolicyWithKeystore(null, tlsKeystore); } public TlsPolicy getTlsPolicyWithKeystore(String tlsPolicyName, SimpleKeystore tlsKeystore) throws IOException, KeyManagementException { if (tlsPolicyName == null) { tlsPolicyName = My.configuration().getDefaultTlsPolicyId(); } // XXX for backwards compatibility with records that don't have a policy set, but maybe this isn't the place to put it - maybe it should be in the DAO that provides us the txthost object. if (tlsPolicyName == null) { throw new IllegalArgumentException("A TLS policy must be specified."); } String ucName = tlsPolicyName.toUpperCase(); if (ucName.equals("TRUST_CA_VERIFY_HOSTNAME")) { // XXX TODO use TlsPolicyName for (X509Certificate cacert : getMtWilsonTrustedTlsCertificates()) { log.debug("Adding trusted TLS CA certificate {}", cacert.getSubjectX500Principal().getName()); try { tlsKeystore.addTrustedSslCertificate(cacert, cacert.getSubjectX500Principal().getName()); } catch (KeyManagementException e) { log.error("Cannot add TLS certificate authority to host keystore {}", cacert.getSubjectX500Principal().getName()); } } // My.configuration().get tls keystore trusted cas; add them to tlsKeystore beforee making the policy so that a global keystore can be used; or just use the global kesytore... // return new TrustCaAndVerifyHostnameTlsPolicy(new KeystoreCertificateRepository(tlsKeystore)); return TlsPolicyBuilder.factory().strict(tlsKeystore.getRepository()).build(); } if (ucName.equals("TRUST_FIRST_CERTIFICATE")) {// XXX TODO use TlsPolicyName // return new TrustFirstCertificateTlsPolicy(new KeystoreCertificateRepository(tlsKeystore)); KeystoreCertificateRepository repository = tlsKeystore.getRepository(); return TlsPolicyBuilder.factory().strict(repository).trustDelegate(new FirstCertificateTrustDelegate(repository)).skipHostnameVerification().build(); } if (ucName.equals("TRUST_KNOWN_CERTIFICATE")) {// XXX TODO use TlsPolicyName // return new TrustKnownCertificateTlsPolicy(new KeystoreCertificateRepository(tlsKeystore)); return TlsPolicyBuilder.factory().strict(tlsKeystore.getRepository()).skipHostnameVerification().build(); } if (ucName.equals("INSECURE")) {// XXX TODO use TlsPolicyName return new InsecureTlsPolicy(); } throw new IllegalArgumentException("Unknown TLS Policy: " + tlsPolicyName); } private static TrustedTlsCertificateFileLoader cacertsLoader = new TrustedTlsCertificateFileLoader(); public static List<X509Certificate> getMtWilsonTrustedTlsCertificates() { return cacertsLoader.getTlsTrustedCertificateAuthorities(); } public static class TrustedTlsCertificateFileLoader { private static long tlsPemLastModified = 0; private static long tlsCrtLastModified = 0; private static final ArrayList<X509Certificate> tlsAuthorities = new ArrayList<>(); public List<X509Certificate> getTlsTrustedCertificateAuthorities() { try { initTlsTrustedCertificateAuthorities(); return tlsAuthorities; } catch(IOException e) { log.warn("Cannot initialize trusted certificate authorities: {}", e.getMessage()); return Collections.EMPTY_LIST; } } // for backward compatibility, can load the mtwilson 1.x trusted tls cacerts file private void initTlsTrustedCertificateAuthorities() throws IOException { String tlsCaFilename = My.configuration().getConfiguration().getString("mtwilson.tls.certificate.file", "mtwilson-tls.pem"); if (tlsCaFilename != null) { if (!tlsCaFilename.startsWith("/")) { tlsCaFilename = String.format("/etc/intel/cloudsecurity/%s", tlsCaFilename); } if (tlsCaFilename.endsWith(".pem")) { File tlsPemFile = new File(tlsCaFilename); if (tlsPemFile.lastModified() > tlsPemLastModified) { tlsPemLastModified = tlsPemFile.lastModified(); tlsAuthorities.clear(); try (final FileInputStream in = new FileInputStream(tlsPemFile)) { String content = IOUtils.toString(in); List<X509Certificate> cacerts = X509Util.decodePemCertificates(content); tlsAuthorities.addAll(cacerts); } catch (CertificateException e) { log.error("Cannot read trusted TLS CA certificates", e); } } } if (tlsCaFilename.endsWith(".crt")) { File tlsCrtFile = new File(tlsCaFilename); if (tlsCrtFile.lastModified() > tlsCrtLastModified) { tlsCrtLastModified = tlsCrtFile.lastModified(); tlsAuthorities.clear(); try (final FileInputStream in = new FileInputStream(tlsCrtFile)) { byte[] content = IOUtils.toByteArray(in); X509Certificate cert = X509Util.decodeDerCertificate(content); tlsAuthorities.add(cert); } catch (CertificateException e) { log.error("Cannot read trusted TLS CA certificates", e); } } } } } } }