trust store changes

This commit is contained in:
Greg DiCristofaro 2023-08-03 15:37:14 -04:00
parent 5368f84853
commit 7ec44a2fb2

View File

@ -28,6 +28,12 @@ import java.net.PasswordAuthentication;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.UnrecoverableKeyException;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -37,7 +43,12 @@ import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Objects; import java.util.Objects;
import java.util.logging.Level; import java.util.logging.Level;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import org.apache.commons.collections4.MapUtils; import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity; import org.apache.http.HttpEntity;
@ -62,6 +73,7 @@ import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.client.SystemDefaultCredentialsProvider; import org.apache.http.impl.client.SystemDefaultCredentialsProvider;
import org.apache.http.impl.client.WinHttpClients; import org.apache.http.impl.client.WinHttpClients;
import org.apache.http.ssl.SSLInitializationException;
import org.sleuthkit.autopsy.coreutils.Version; import org.sleuthkit.autopsy.coreutils.Version;
/** /**
@ -69,7 +81,8 @@ import org.sleuthkit.autopsy.coreutils.Version;
*/ */
class CTCloudHttpClient { class CTCloudHttpClient {
private static final CTCloudHttpClient instance = new CTCloudHttpClient(); private static final String KS_PASSWORD = "changeit"; // system default java password
private static final Logger LOGGER = Logger.getLogger(CTCloudHttpClient.class.getName()); private static final Logger LOGGER = Logger.getLogger(CTCloudHttpClient.class.getName());
private static final String HOST_URL = Version.getBuildType() == Version.Type.RELEASE ? Constants.CT_CLOUD_SERVER : Constants.CT_CLOUD_DEV_SERVER; private static final String HOST_URL = Version.getBuildType() == Version.Type.RELEASE ? Constants.CT_CLOUD_SERVER : Constants.CT_CLOUD_DEV_SERVER;
@ -84,6 +97,8 @@ class CTCloudHttpClient {
private static final int CONNECTION_TIMEOUT_MS = 58 * 1000; // milli sec private static final int CONNECTION_TIMEOUT_MS = 58 * 1000; // milli sec
private static final CTCloudHttpClient instance = new CTCloudHttpClient();
public static CTCloudHttpClient getInstance() { public static CTCloudHttpClient getInstance() {
return instance; return instance;
} }
@ -94,7 +109,7 @@ class CTCloudHttpClient {
private CTCloudHttpClient() { private CTCloudHttpClient() {
// leave as null for now unless we want to customize this at a later date // leave as null for now unless we want to customize this at a later date
this.sslContext = null; this.sslContext = createSSLContext();
} }
private ProxySettingArgs getProxySettings() { private ProxySettingArgs getProxySettings() {
@ -151,7 +166,6 @@ class CTCloudHttpClient {
URI postURI = builder.build(); URI postURI = builder.build();
HttpPost postRequest = new HttpPost(postURI); HttpPost postRequest = new HttpPost(postURI);
configureRequestTimeout(postRequest); configureRequestTimeout(postRequest);
postRequest.setHeader("Content-type", "application/json"); postRequest.setHeader("Content-type", "application/json");
@ -189,6 +203,9 @@ class CTCloudHttpClient {
} catch (IOException ex) { } catch (IOException ex) {
LOGGER.log(Level.WARNING, "IO Exception raised when connecting to CT Cloud using " + url, ex); LOGGER.log(Level.WARNING, "IO Exception raised when connecting to CT Cloud using " + url, ex);
throw new CTCloudException(CTCloudException.ErrorCode.NETWORK_ERROR, ex); throw new CTCloudException(CTCloudException.ErrorCode.NETWORK_ERROR, ex);
} catch (SSLInitializationException ex) {
LOGGER.log(Level.WARNING, "No such algorithm exception raised when creating SSL connection for CT Cloud using " + url, ex);
throw new CTCloudException(CTCloudException.ErrorCode.NETWORK_ERROR, ex);
} catch (URISyntaxException ex) { } catch (URISyntaxException ex) {
LOGGER.log(Level.WARNING, "Wrong URL syntax for CT Cloud " + url, ex); LOGGER.log(Level.WARNING, "Wrong URL syntax for CT Cloud " + url, ex);
throw new CTCloudException(CTCloudException.ErrorCode.UNKNOWN, ex); throw new CTCloudException(CTCloudException.ErrorCode.UNKNOWN, ex);
@ -226,6 +243,9 @@ class CTCloudHttpClient {
handleNonOKResponse(response, fileName); handleNonOKResponse(response, fileName);
} }
} }
} catch (SSLInitializationException ex) {
LOGGER.log(Level.WARNING, "SSL exception raised when connecting to Reversing Labs for file content upload ", ex);
throw new CTCloudException(CTCloudException.ErrorCode.NETWORK_ERROR, ex);
} catch (IOException ex) { } catch (IOException ex) {
LOGGER.log(Level.WARNING, "IO Exception raised when connecting to Reversing Labs for file content upload ", ex); LOGGER.log(Level.WARNING, "IO Exception raised when connecting to Reversing Labs for file content upload ", ex);
throw new CTCloudException(CTCloudException.ErrorCode.NETWORK_ERROR, ex); throw new CTCloudException(CTCloudException.ErrorCode.NETWORK_ERROR, ex);
@ -295,19 +315,71 @@ class CTCloudHttpClient {
/** /**
* Creates a connection to CT Cloud with the given arguments. * Creates a connection to CT Cloud with the given arguments.
*
* @param proxySettings The network proxy settings. * @param proxySettings The network proxy settings.
* @param sslContext The ssl context or null. * @param sslContext The ssl context or null.
* @return The connection to CT Cloud. * @return The connection to CT Cloud.
*/ */
private static CloseableHttpClient createConnection(ProxySettingArgs proxySettings, SSLContext sslContext) { private static CloseableHttpClient createConnection(ProxySettingArgs proxySettings, SSLContext sslContext) throws SSLInitializationException {
HttpClientBuilder builder = getHttpClientBuilder(proxySettings); HttpClientBuilder builder = getHttpClientBuilder(proxySettings);
if (sslContext != null) { if (sslContext != null) {
builder.setSSLContext(sslContext); builder.setSSLContext(sslContext);
} }
return builder.build(); return builder.build();
} }
/**
* Create an SSLContext object using our in-memory keystore.
*
* @return
*/
private static SSLContext createSSLContext() {
LOGGER.log(Level.INFO, "Creating custom SSL context");
try {
// I'm not sure how much of this is really necessary to set up, but it works
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
KeyManager[] keyManagers = getKeyManagers();
TrustManager[] trustManagers = getTrustManagers();
sslContext.init(keyManagers, trustManagers, new SecureRandom());
return sslContext;
} catch (NoSuchAlgorithmException | KeyManagementException ex) {
LOGGER.log(Level.SEVERE, "Error creating SSL context", ex);
return null;
}
}
// based in part on this: https://stackoverflow.com/questions/1793979/registering-multiple-keystores-in-jvm/16229909
private static KeyManager[] getKeyManagers() {
LOGGER.log(Level.INFO, "Using default algorithm to create trust store: " + KeyManagerFactory.getDefaultAlgorithm());
try {
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(null, null);
return kmf.getKeyManagers();
} catch (NoSuchAlgorithmException | KeyStoreException | UnrecoverableKeyException ex) {
LOGGER.log(Level.SEVERE, "Error getting KeyManagers", ex);
return new KeyManager[0];
}
}
// based in part on this: https://stackoverflow.com/questions/1793979/registering-multiple-keystores-in-jvm/16229909
private static TrustManager[] getTrustManagers() {
try {
LOGGER.log(Level.INFO, "Using default algorithm to create trust store: " + TrustManagerFactory.getDefaultAlgorithm());
TrustManagerFactory tmf
= TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init((KeyStore) null);
X509TrustManager tm = (X509TrustManager) tmf.getTrustManagers()[0];
return new TrustManager[]{tm};
} catch (KeyStoreException | NoSuchAlgorithmException ex) {
LOGGER.log(Level.SEVERE, "Error getting TrustManager", ex);
return new TrustManager[0];
}
}
private static HttpClientBuilder getHttpClientBuilder(ProxySettingArgs proxySettings) { private static HttpClientBuilder getHttpClientBuilder(ProxySettingArgs proxySettings) {
if (proxySettings.isSystemOrManualProxy()) { if (proxySettings.isSystemOrManualProxy()) {