[NO ISSUE][HYR][NET] += trust store to sec cfg, store serialization
Change-Id: I358eb5b9b0f0f40b1588c12ed473e4e920e8fbbe
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/13423
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Michael Blow <mblow@apache.org>
Reviewed-by: Ian Maxon <imaxon@uci.edu>
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/library/ExternalLibraryManager.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/library/ExternalLibraryManager.java
index e54b729..f71150a 100755
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/library/ExternalLibraryManager.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/library/ExternalLibraryManager.java
@@ -639,7 +639,9 @@
final INetworkSecurityConfig configuration = networkSecurityManager.getConfiguration();
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
try (FileInputStream trustStoreFile = new FileInputStream(configuration.getTrustStoreFile())) {
- trustStore.load(trustStoreFile, configuration.getKeyStorePassword().toCharArray());
+ String ksPassword = configuration.getKeyStorePassword();
+ trustStore.load(trustStoreFile,
+ ksPassword == null || ksPassword.isEmpty() ? null : ksPassword.toCharArray());
}
SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(trustStore, null).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext,
diff --git a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/network/INetworkSecurityConfig.java b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/network/INetworkSecurityConfig.java
index 32f784b..b483158 100644
--- a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/network/INetworkSecurityConfig.java
+++ b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/network/INetworkSecurityConfig.java
@@ -53,7 +53,14 @@
String getKeyStorePassword();
/**
- * Gets a trust store file to be used for validating certificates of secured connections.
+ * Gets the trust store to be used for validating certificates of secured connections
+ *
+ * @return the trust store to be used
+ */
+ KeyStore getTrustStore();
+
+ /**
+ * Gets a trust store file to be used if {@link INetworkSecurityConfig#getTrustStore()} returns null.
*
* @return the trust store file
*/
diff --git a/hyracks-fullstack/hyracks/hyracks-ipc/src/main/java/org/apache/hyracks/ipc/security/NetworkSecurityConfig.java b/hyracks-fullstack/hyracks/hyracks-ipc/src/main/java/org/apache/hyracks/ipc/security/NetworkSecurityConfig.java
index 25ea787..2170c15 100644
--- a/hyracks-fullstack/hyracks/hyracks-ipc/src/main/java/org/apache/hyracks/ipc/security/NetworkSecurityConfig.java
+++ b/hyracks-fullstack/hyracks/hyracks-ipc/src/main/java/org/apache/hyracks/ipc/security/NetworkSecurityConfig.java
@@ -19,55 +19,113 @@
package org.apache.hyracks.ipc.security;
import java.io.File;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
import org.apache.hyracks.api.network.INetworkSecurityConfig;
public class NetworkSecurityConfig implements INetworkSecurityConfig {
- private static final long serialVersionUID = -1914030130038989199L;
+ private static final long serialVersionUID = 2L;
+ private static final char[] INTEGRITY_PASSWORD = NetworkSecurityConfig.class.getName().toCharArray();
private final boolean sslEnabled;
private final File keyStoreFile;
private final File trustStoreFile;
private final String keyStorePassword;
- private final transient KeyStore keyStore;
+ private transient KeyStore keyStore;
+ private transient KeyStore trustStore;
private NetworkSecurityConfig(boolean sslEnabled, String keyStoreFile, String keyStorePassword,
- String trustStoreFile, KeyStore keyStore) {
+ String trustStoreFile, KeyStore keyStore, KeyStore trustStore) {
this.sslEnabled = sslEnabled;
this.keyStoreFile = keyStoreFile != null ? new File(keyStoreFile) : null;
this.keyStorePassword = keyStorePassword;
this.trustStoreFile = trustStoreFile != null ? new File(trustStoreFile) : null;
this.keyStore = keyStore;
+ this.trustStore = trustStore;
}
public static NetworkSecurityConfig of(boolean sslEnabled, String keyStoreFile, String keyStorePassword,
String trustStoreFile) {
- return new NetworkSecurityConfig(sslEnabled, keyStoreFile, keyStorePassword, trustStoreFile, null);
+ return new NetworkSecurityConfig(sslEnabled, keyStoreFile, keyStorePassword, trustStoreFile, null, null);
}
public static NetworkSecurityConfig of(boolean sslEnabled, KeyStore keyStore, String keyStorePassword,
- String trustStoreFile) {
- return new NetworkSecurityConfig(sslEnabled, null, keyStorePassword, trustStoreFile, keyStore);
+ KeyStore trustStore) {
+ return new NetworkSecurityConfig(sslEnabled, null, keyStorePassword, null, keyStore, trustStore);
}
+ @Override
public boolean isSslEnabled() {
return sslEnabled;
}
+ @Override
public File getKeyStoreFile() {
return keyStoreFile;
}
+ @Override
public String getKeyStorePassword() {
return keyStorePassword;
}
+ @Override
public KeyStore getKeyStore() {
return keyStore;
}
+ @Override
+ public KeyStore getTrustStore() {
+ return trustStore;
+ }
+
+ @Override
public File getTrustStoreFile() {
return trustStoreFile;
}
+
+ private void writeObject(ObjectOutputStream out) throws IOException {
+ out.defaultWriteObject();
+ writeStore(keyStore, out);
+ writeStore(trustStore, out);
+ }
+
+ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ keyStore = readStore(in);
+ trustStore = readStore(in);
+ }
+
+ private void writeStore(KeyStore keyStore, ObjectOutputStream out) throws IOException {
+ if (keyStore == null) {
+ out.writeUTF("");
+ return;
+ }
+ out.writeUTF(keyStore.getType());
+ try {
+ keyStore.store(out, INTEGRITY_PASSWORD);
+ } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ private KeyStore readStore(ObjectInputStream in) throws IOException {
+ String keyStoreType = in.readUTF();
+ if (keyStoreType.isEmpty()) {
+ return null;
+ }
+ try {
+ KeyStore store = KeyStore.getInstance(keyStoreType);
+ store.load(in, INTEGRITY_PASSWORD);
+ return store;
+ } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException e) {
+ throw new IllegalStateException(e);
+ }
+ }
}
diff --git a/hyracks-fullstack/hyracks/hyracks-ipc/src/main/java/org/apache/hyracks/ipc/security/NetworkSecurityManager.java b/hyracks-fullstack/hyracks/hyracks-ipc/src/main/java/org/apache/hyracks/ipc/security/NetworkSecurityManager.java
index b7c0d0f..42dacf5 100644
--- a/hyracks-fullstack/hyracks/hyracks-ipc/src/main/java/org/apache/hyracks/ipc/security/NetworkSecurityManager.java
+++ b/hyracks-fullstack/hyracks/hyracks-ipc/src/main/java/org/apache/hyracks/ipc/security/NetworkSecurityManager.java
@@ -87,7 +87,10 @@
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(defaultAlgorithm);
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(defaultAlgorithm);
keyManagerFactory.init(engineKeyStore, password);
- final KeyStore trustStore = loadTrustStoreFromFile(password, config);
+ KeyStore trustStore = config.getTrustStore();
+ if (trustStore == null) {
+ trustStore = loadTrustStoreFromFile(password, config);
+ }
trustManagerFactory.init(trustStore);
SSLContext ctx = SSLContext.getInstance(TSL_VERSION);
ctx.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());