/* * Copyright (C) 2013 Intel Corporation * All rights reserved. */ package test.ssl; import com.intel.dcsg.cpg.tls.policy.impl.*; import com.intel.dcsg.cpg.tls.policy.TlsPolicy; import org.junit.Test; import java.util.ArrayList; import java.util.HashMap; import java.io.FileNotFoundException; import static org.junit.Assert.*; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.net.ssl.X509TrustManager; import org.apache.commons.io.IOUtils; //import org.apache.http.conn.scheme.Scheme; //import org.apache.http.conn.ssl.SSLSocketFactory; /** * This class tests a model where each destination address can have just * one TLS Policy associated with it. Selecting this model means we would * have to edit the database schema to add a new mw_tls_policy table with * fields like (ID, InternetAddress, TlsPolicyName, TlsKeystore). * So for example, there would only be one policy associated with a given * vcenter and it can be managed independently of any related host records. * * The challenge is still that the clients just accept a URL and they open * their own SSL connection - so we can't even provide the right policy when * it's one policy per address... there is still a race condition for * concurrent connections. * * @author jbuhacoff */ public class SinglePolicyPerAddressTest { private Logger log = LoggerFactory.getLogger(getClass()); private ArrayList<String> getTargets() { // vmware: 10.1.71.175, 10.1.71.173, 10.1.71.176, 10.1.71.174 // citrix: 10.1.71.201, 10.1.71.126 // intel: 10.1.71.167, 10.1.71.170 ArrayList<String> targets = new ArrayList<String>(); targets.add("https://10.1.71.162/sdk"); //;Administrator;intel123!"); targets.add("https://10.1.71.163/sdk"); //;Administrator;intel123!"); targets.add("https://10.1.71.201/"); // root;P@ssw0rd // targets.add("https://10.1.71.126/;Administrator;intel123!"); // targets.add("https://10.1.71.167:9999"); // targets.add("https://10.1.71.170:9999"); return targets; } @Test public void testTwoSslContextInstancesAreDifferent() throws NoSuchAlgorithmException { SSLContext ctx1 = SSLContext.getInstance("SSL"); SSLContext ctx2 = SSLContext.getInstance("SSL"); assertNotEquals(ctx1,ctx2); log.debug("context 1 hashcode {}", ctx1.hashCode()); log.debug("context 2 hashcode {}", ctx2.hashCode()); } private void connect(URL url, TlsPolicy tlsPolicy) throws NoSuchAlgorithmException, KeyManagementException, IOException { /* SSLContext sslcontext = SSLContext.getInstance("TLS"); sslcontext.init(null, new X509TrustManager[] { tlsPolicy.getTrustManager() }, null); // key manager, trust manager, securerandom SSLSocketFactory sf = new SSLSocketFactory( sslcontext, tlsPolicy.getHostnameVerifier() ); Scheme https = new Scheme("https", port, sf); // URl defaults to 443 for https but if user specified a different port we use that instead sr.register(https); */ SSLContext ctx = SSLContext.getInstance("SSL"); // it's a factory, returns a new instance ctx.init(null, new javax.net.ssl.TrustManager[]{ tlsPolicy.getTrustManager() }, null); HttpsURLConnection.setDefaultHostnameVerifier(tlsPolicy.getHostnameVerifier()); // without this, even InsecureTlsPolicy will not prevent java.security.cert.CertificateException: No subject alternative names matching IP address 10.1.71.162 found HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory()); // without this, even with InsecureTlsPolicy we get ERROR: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certificateion path to requested target // SSLSocketFactory sslsocketfactory = ctx.getSocketFactory(); // SSLSocket sock = (SSLSocket) sslsocketfactory.createSocket(); InputStream in = url.openStream(); String content = IOUtils.toString(in); System.out.println("---\n"+url.toString()+"\n---\n"+content+"\n---\n\n"); } @Test public void testInsecurePolicy() throws MalformedURLException, NoSuchAlgorithmException, KeyManagementException, IOException { TlsPolicy tlsPolicy = new InsecureTlsPolicy(); ArrayList<String> targets = getTargets(); for(String target : targets) { URL url = new URL(target); // throws MalformedURLException try { connect(url,tlsPolicy); // throws NoSuchAlgorithmException, KeyManagementException, IOException } catch(FileNotFoundException e) { log.error("File not found (but ssl connection worked): {}", url.toString()); } } } /** * This one should work because we can create a different instance for each connection; * However it's not an option for production since we don't control the client code... */ @Test public void testApacheHttpConnectionsWithTrustFirstPolicy() { // set up the workload: ArrayList<String> targets = getTargets(); // HashMap<String,TrustFirstCertificateTlsPolicy> map = new HashMap<String,TrustFirstCertificateTlsPolicy>(); for(String url : targets) {/* ByteArrayResource resource = new ByteArrayResource(); TrustFirstCertificateTlsPolicy tlsPolicy = new TrustFirstCertificateTlsPolicy(); map.put(tlsPolicy);*/ } // connect one at a time with a trust first policy to collect the current certificates // now we have a "trust first certicate" policy and keystore for each one. // spawn a thread for each connection and connect again, look for errors; expect some random errors } /** * This one should result in errors because the ssl context is shared */ @Test public void testJavaSslContextConnectionsWithTrustFirstPolicy() { // set up the workload: // vmware: 10.1.71.175, 10.1.71.173, 10.1.71.176, 10.1.71.174 // citrix: 10.1.71.201, 10.1.71.126 // intel: 10.1.71.167, 10.1.71.170 ArrayList<String> targets = new ArrayList<String>(); targets.add("https://10.1.71.162/sdk;"); // connect one at a time with a trust first policy to collect the current certificates // now we have a "trust first certicate" policy and keystore for each one. // spawn a thread for each connection and connect again, look for errors; expect some random errors } @Test public void testConnectionsWithInsecurePolicy() { // set up the workload: // vmware: 10.1.71.175, 10.1.71.173, 10.1.71.176, 10.1.71.174 // citrix: 10.1.71.201, 10.1.71.126 // intel: 10.1.71.167, 10.1.71.170 // now we have an "insecure" policy // spawn a thread for each connection and connect again, look for errors; expect none } }