Author: atm
Date: Tue Jun 3 07:23:16 2014
New Revision: 1599435
URL: http://svn.apache.org/r1599435
Log:
HADOOP-10658. SSLFactory expects truststores being configured. Contributed by
Alejandro Abdelnur.
Modified:
hadoop/common/trunk/hadoop-common-project/hadoop-common/CHANGES.txt
hadoop/common/trunk/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/ssl/FileBasedKeyStoresFactory.java
hadoop/common/trunk/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/KeyStoreTestUtil.java
hadoop/common/trunk/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/TestSSLFactory.java
Modified: hadoop/common/trunk/hadoop-common-project/hadoop-common/CHANGES.txt
URL:
http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-common-project/hadoop-common/CHANGES.txt?rev=1599435&r1=1599434&r2=1599435&view=diff
==============================================================================
--- hadoop/common/trunk/hadoop-common-project/hadoop-common/CHANGES.txt
(original)
+++ hadoop/common/trunk/hadoop-common-project/hadoop-common/CHANGES.txt Tue Jun
3 07:23:16 2014
@@ -531,6 +531,8 @@ Release 2.5.0 - UNRELEASED
HADOOP-10630. Possible race condition in RetryInvocationHandler. (jing9)
+ HADOOP-10658. SSLFactory expects truststores being configured. (tucu via
atm)
+
Release 2.4.1 - UNRELEASED
INCOMPATIBLE CHANGES
Modified:
hadoop/common/trunk/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/ssl/FileBasedKeyStoresFactory.java
URL:
http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/ssl/FileBasedKeyStoresFactory.java?rev=1599435&r1=1599434&r2=1599435&view=diff
==============================================================================
---
hadoop/common/trunk/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/ssl/FileBasedKeyStoresFactory.java
(original)
+++
hadoop/common/trunk/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/ssl/FileBasedKeyStoresFactory.java
Tue Jun 3 07:23:16 2014
@@ -188,33 +188,33 @@ public class FileBasedKeyStoresFactory i
String locationProperty =
resolvePropertyName(mode, SSL_TRUSTSTORE_LOCATION_TPL_KEY);
String truststoreLocation = conf.get(locationProperty, "");
- if (truststoreLocation.isEmpty()) {
- throw new GeneralSecurityException("The property '" + locationProperty +
- "' has not been set in the ssl configuration file.");
- }
-
- String passwordProperty = resolvePropertyName(mode,
-
SSL_TRUSTSTORE_PASSWORD_TPL_KEY);
- String truststorePassword = conf.get(passwordProperty, "");
- if (truststorePassword.isEmpty()) {
- throw new GeneralSecurityException("The property '" + passwordProperty +
- "' has not been set in the ssl configuration file.");
+ if (!truststoreLocation.isEmpty()) {
+ String passwordProperty = resolvePropertyName(mode,
+ SSL_TRUSTSTORE_PASSWORD_TPL_KEY);
+ String truststorePassword = conf.get(passwordProperty, "");
+ if (truststorePassword.isEmpty()) {
+ throw new GeneralSecurityException("The property '" + passwordProperty
+
+ "' has not been set in the ssl configuration file.");
+ }
+ long truststoreReloadInterval =
+ conf.getLong(
+ resolvePropertyName(mode,
SSL_TRUSTSTORE_RELOAD_INTERVAL_TPL_KEY),
+ DEFAULT_SSL_TRUSTSTORE_RELOAD_INTERVAL);
+
+ LOG.debug(mode.toString() + " TrustStore: " + truststoreLocation);
+
+ trustManager = new ReloadingX509TrustManager(truststoreType,
+ truststoreLocation,
+ truststorePassword,
+ truststoreReloadInterval);
+ trustManager.init();
+ LOG.debug(mode.toString() + " Loaded TrustStore: " + truststoreLocation);
+ trustManagers = new TrustManager[]{trustManager};
+ } else {
+ LOG.warn("The property '" + locationProperty + "' has not been set, " +
+ "no TrustStore will be loaded");
+ trustManagers = null;
}
- long truststoreReloadInterval =
- conf.getLong(
- resolvePropertyName(mode, SSL_TRUSTSTORE_RELOAD_INTERVAL_TPL_KEY),
- DEFAULT_SSL_TRUSTSTORE_RELOAD_INTERVAL);
-
- LOG.debug(mode.toString() + " TrustStore: " + truststoreLocation);
-
- trustManager = new ReloadingX509TrustManager(truststoreType,
- truststoreLocation,
- truststorePassword,
- truststoreReloadInterval);
- trustManager.init();
- LOG.debug(mode.toString() + " Loaded TrustStore: " + truststoreLocation);
-
- trustManagers = new TrustManager[]{trustManager};
}
/**
Modified:
hadoop/common/trunk/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/KeyStoreTestUtil.java
URL:
http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/KeyStoreTestUtil.java?rev=1599435&r1=1599434&r2=1599435&view=diff
==============================================================================
---
hadoop/common/trunk/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/KeyStoreTestUtil.java
(original)
+++
hadoop/common/trunk/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/KeyStoreTestUtil.java
Tue Jun 3 07:23:16 2014
@@ -76,8 +76,8 @@ public class KeyStoreTestUtil {
* @throws GeneralSecurityException thrown if an Security error ocurred.
*/
public static X509Certificate generateCertificate(String dn, KeyPair pair,
- int days, String algorithm)
- throws GeneralSecurityException, IOException {
+ int days, String algorithm)
+ throws GeneralSecurityException, IOException {
PrivateKey privkey = pair.getPrivate();
X509CertInfo info = new X509CertInfo();
Date from = new Date();
@@ -92,7 +92,7 @@ public class KeyStoreTestUtil {
info.set(X509CertInfo.ISSUER, new CertificateIssuerName(owner));
info.set(X509CertInfo.KEY, new CertificateX509Key(pair.getPublic()));
info
- .set(X509CertInfo.VERSION, new
CertificateVersion(CertificateVersion.V3));
+ .set(X509CertInfo.VERSION, new
CertificateVersion(CertificateVersion.V3));
AlgorithmId algo = new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid);
info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algo));
@@ -103,30 +103,30 @@ public class KeyStoreTestUtil {
// Update the algorith, and resign.
algo = (AlgorithmId) cert.get(X509CertImpl.SIG_ALG);
info
- .set(CertificateAlgorithmId.NAME + "." +
CertificateAlgorithmId.ALGORITHM,
- algo);
+ .set(CertificateAlgorithmId.NAME + "." +
CertificateAlgorithmId.ALGORITHM,
+ algo);
cert = new X509CertImpl(info);
cert.sign(privkey, algorithm);
return cert;
}
public static KeyPair generateKeyPair(String algorithm)
- throws NoSuchAlgorithmException {
+ throws NoSuchAlgorithmException {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance(algorithm);
keyGen.initialize(1024);
return keyGen.genKeyPair();
}
private static KeyStore createEmptyKeyStore()
- throws GeneralSecurityException, IOException {
+ throws GeneralSecurityException, IOException {
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(null, null); // initialize
return ks;
}
private static void saveKeyStore(KeyStore ks, String filename,
- String password)
- throws GeneralSecurityException, IOException {
+ String password)
+ throws GeneralSecurityException, IOException {
FileOutputStream out = new FileOutputStream(filename);
try {
ks.store(out, password.toCharArray());
@@ -136,18 +136,18 @@ public class KeyStoreTestUtil {
}
public static void createKeyStore(String filename,
- String password, String alias,
- Key privateKey, Certificate cert)
- throws GeneralSecurityException, IOException {
+ String password, String alias,
+ Key privateKey, Certificate cert)
+ throws GeneralSecurityException, IOException {
KeyStore ks = createEmptyKeyStore();
ks.setKeyEntry(alias, privateKey, password.toCharArray(),
- new Certificate[]{cert});
+ new Certificate[]{cert});
saveKeyStore(ks, filename, password);
}
/**
* Creates a keystore with a single key and saves it to a file.
- *
+ *
* @param filename String file to save
* @param password String store password to set on keystore
* @param keyPassword String key password to set on key
@@ -158,27 +158,27 @@ public class KeyStoreTestUtil {
* @throws IOException if there is an I/O error saving the file
*/
public static void createKeyStore(String filename,
- String password, String keyPassword,
String alias,
- Key privateKey, Certificate cert)
- throws GeneralSecurityException, IOException {
+ String password, String keyPassword, String alias,
+ Key privateKey, Certificate cert)
+ throws GeneralSecurityException, IOException {
KeyStore ks = createEmptyKeyStore();
ks.setKeyEntry(alias, privateKey, keyPassword.toCharArray(),
- new Certificate[]{cert});
+ new Certificate[]{cert});
saveKeyStore(ks, filename, password);
}
public static void createTrustStore(String filename,
- String password, String alias,
- Certificate cert)
- throws GeneralSecurityException, IOException {
+ String password, String alias,
+ Certificate cert)
+ throws GeneralSecurityException, IOException {
KeyStore ks = createEmptyKeyStore();
ks.setCertificateEntry(alias, cert);
saveKeyStore(ks, filename, password);
}
public static <T extends Certificate> void createTrustStore(
- String filename, String password, Map<String, T> certs)
- throws GeneralSecurityException, IOException {
+ String filename, String password, Map<String, T> certs)
+ throws GeneralSecurityException, IOException {
KeyStore ks = createEmptyKeyStore();
for (Map.Entry<String, T> cert : certs.entrySet()) {
ks.setCertificateEntry(cert.getKey(), cert.getValue());
@@ -187,7 +187,7 @@ public class KeyStoreTestUtil {
}
public static void cleanupSSLConfig(String keystoresDir, String sslConfDir)
- throws Exception {
+ throws Exception {
File f = new File(keystoresDir + "/clientKS.jks");
f.delete();
f = new File(keystoresDir + "/serverKS.jks");
@@ -196,7 +196,7 @@ public class KeyStoreTestUtil {
f.delete();
f = new File(sslConfDir + "/ssl-client.xml");
f.delete();
- f = new File(sslConfDir + "/ssl-server.xml");
+ f = new File(sslConfDir + "/ssl-server.xml");
f.delete();
}
@@ -205,22 +205,42 @@ public class KeyStoreTestUtil {
* SSLFactory. This includes keys, certs, keystores, truststores, the server
* SSL configuration file, the client SSL configuration file, and the master
* configuration file read by the SSLFactory.
- *
+ *
* @param keystoresDir String directory to save keystores
* @param sslConfDir String directory to save SSL configuration files
* @param conf Configuration master configuration to be used by an
SSLFactory,
- * which will be mutated by this method
+ * which will be mutated by this method
* @param useClientCert boolean true to make the client present a cert in the
- * SSL handshake
+ * SSL handshake
*/
public static void setupSSLConfig(String keystoresDir, String sslConfDir,
- Configuration conf, boolean useClientCert)
+ Configuration conf, boolean useClientCert) throws Exception {
+ setupSSLConfig(keystoresDir, sslConfDir, conf, useClientCert, true);
+ }
+
+ /**
+ * Performs complete setup of SSL configuration in preparation for testing an
+ * SSLFactory. This includes keys, certs, keystores, truststores, the server
+ * SSL configuration file, the client SSL configuration file, and the master
+ * configuration file read by the SSLFactory.
+ *
+ * @param keystoresDir String directory to save keystores
+ * @param sslConfDir String directory to save SSL configuration files
+ * @param conf Configuration master configuration to be used by an
SSLFactory,
+ * which will be mutated by this method
+ * @param useClientCert boolean true to make the client present a cert in the
+ * SSL handshake
+ * @param trustStore boolean true to create truststore, false not to create
it
+ */
+ public static void setupSSLConfig(String keystoresDir, String sslConfDir,
+ Configuration conf, boolean useClientCert,
+ boolean trustStore)
throws Exception {
String clientKS = keystoresDir + "/clientKS.jks";
String clientPassword = "clientP";
String serverKS = keystoresDir + "/serverKS.jks";
String serverPassword = "serverP";
- String trustKS = keystoresDir + "/trustKS.jks";
+ String trustKS = null;
String trustPassword = "trustP";
File sslClientConfFile = new File(sslConfDir + "/ssl-client.xml");
@@ -246,7 +266,10 @@ public class KeyStoreTestUtil {
sKP.getPrivate(), sCert);
certs.put("server", sCert);
- KeyStoreTestUtil.createTrustStore(trustKS, trustPassword, certs);
+ if (trustStore) {
+ trustKS = keystoresDir + "/trustKS.jks";
+ KeyStoreTestUtil.createTrustStore(trustKS, trustPassword, certs);
+ }
Configuration clientSSLConf = createClientSSLConfig(clientKS,
clientPassword,
clientPassword, trustKS);
Modified:
hadoop/common/trunk/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/TestSSLFactory.java
URL:
http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/TestSSLFactory.java?rev=1599435&r1=1599434&r2=1599435&view=diff
==============================================================================
---
hadoop/common/trunk/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/TestSSLFactory.java
(original)
+++
hadoop/common/trunk/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/TestSSLFactory.java
Tue Jun 3 07:23:16 2014
@@ -50,11 +50,12 @@ public class TestSSLFactory {
base.mkdirs();
}
- private Configuration createConfiguration(boolean clientCert)
+ private Configuration createConfiguration(boolean clientCert,
+ boolean trustStore)
throws Exception {
Configuration conf = new Configuration();
KeyStoreTestUtil.setupSSLConfig(KEYSTORES_DIR, sslConfsDir, conf,
- clientCert);
+ clientCert, trustStore);
return conf;
}
@@ -67,7 +68,7 @@ public class TestSSLFactory {
@Test(expected = IllegalStateException.class)
public void clientMode() throws Exception {
- Configuration conf = createConfiguration(false);
+ Configuration conf = createConfiguration(false, true);
SSLFactory sslFactory = new SSLFactory(SSLFactory.Mode.CLIENT, conf);
try {
sslFactory.init();
@@ -80,7 +81,7 @@ public class TestSSLFactory {
}
private void serverMode(boolean clientCert, boolean socket) throws Exception
{
- Configuration conf = createConfiguration(clientCert);
+ Configuration conf = createConfiguration(clientCert, true);
SSLFactory sslFactory = new SSLFactory(SSLFactory.Mode.SERVER, conf);
try {
sslFactory.init();
@@ -119,7 +120,7 @@ public class TestSSLFactory {
@Test
public void validHostnameVerifier() throws Exception {
- Configuration conf = createConfiguration(false);
+ Configuration conf = createConfiguration(false, true);
conf.unset(SSLFactory.SSL_HOSTNAME_VERIFIER_KEY);
SSLFactory sslFactory = new
SSLFactory(SSLFactory.Mode.CLIENT, conf);
@@ -157,7 +158,7 @@ public class TestSSLFactory {
@Test(expected = GeneralSecurityException.class)
public void invalidHostnameVerifier() throws Exception {
- Configuration conf = createConfiguration(false);
+ Configuration conf = createConfiguration(false, true);
conf.set(SSLFactory.SSL_HOSTNAME_VERIFIER_KEY, "foo");
SSLFactory sslFactory = new SSLFactory(SSLFactory.Mode.CLIENT, conf);
try {
@@ -169,7 +170,7 @@ public class TestSSLFactory {
@Test
public void testConnectionConfigurator() throws Exception {
- Configuration conf = createConfiguration(false);
+ Configuration conf = createConfiguration(false, true);
conf.set(SSLFactory.SSL_HOSTNAME_VERIFIER_KEY, "STRICT_IE6");
SSLFactory sslFactory = new SSLFactory(SSLFactory.Mode.CLIENT, conf);
try {
@@ -275,7 +276,7 @@ public class TestSSLFactory {
@Test
public void testNoClientCertsInitialization() throws Exception {
- Configuration conf = createConfiguration(false);
+ Configuration conf = createConfiguration(false, true);
conf.unset(SSLFactory.SSL_REQUIRE_CLIENT_CERT_KEY);
SSLFactory sslFactory = new SSLFactory(SSLFactory.Mode.CLIENT, conf);
try {
@@ -285,4 +286,16 @@ public class TestSSLFactory {
}
}
+ @Test
+ public void testNoTrustStore() throws Exception {
+ Configuration conf = createConfiguration(false, false);
+ conf.unset(SSLFactory.SSL_REQUIRE_CLIENT_CERT_KEY);
+ SSLFactory sslFactory = new SSLFactory(SSLFactory.Mode.SERVER, conf);
+ try {
+ sslFactory.init();
+ } finally {
+ sslFactory.destroy();
+ }
+ }
+
}