diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/key/JavaKeyStoreProvider.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/key/JavaKeyStoreProvider.java index a9738bad62c..bfec1ef1a90 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/key/JavaKeyStoreProvider.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/key/JavaKeyStoreProvider.java @@ -21,7 +21,6 @@ package org.apache.hadoop.crypto.key; import com.google.common.base.Preconditions; import org.apache.commons.io.IOUtils; import org.apache.hadoop.classification.InterfaceAudience; -import org.apache.hadoop.classification.InterfaceAudience.Private; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FSDataOutputStream; import org.apache.hadoop.fs.FileStatus; @@ -401,6 +400,10 @@ public class JavaKeyStoreProvider extends KeyProvider { Metadata meta = ((KeyMetadata) keyStore.getKey(name, password)).metadata; cache.put(name, meta); return meta; + } catch (ClassCastException e) { + throw new IOException("Can't cast key for " + name + " in keystore " + + path + " to a KeyMetadata. Key may have been added using " + + " keytool or some other non-Hadoop method.", e); } catch (KeyStoreException e) { throw new IOException("Can't get metadata for " + name + " from keystore " + path, e); diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/key/TestKeyProviderFactory.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/key/TestKeyProviderFactory.java index 998cd6fe122..ef09d947396 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/key/TestKeyProviderFactory.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/key/TestKeyProviderFactory.java @@ -42,6 +42,7 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; public class TestKeyProviderFactory { @@ -430,4 +431,51 @@ public class TestKeyProviderFactory { Assert.assertNull(kp); } + + @Test + public void testJksProviderWithKeytoolKeys() throws Exception { + final Configuration conf = new Configuration(); + final String keystoreDirAbsolutePath = + conf.getResource("hdfs7067.keystore").getPath(); + final String ourUrl = JavaKeyStoreProvider.SCHEME_NAME + "://file@/" + + keystoreDirAbsolutePath; + + conf.set(KeyProviderFactory.KEY_PROVIDER_PATH, ourUrl); + + final KeyProvider provider = KeyProviderFactory.getProviders(conf).get(0); + + // Sanity check that we are using the right keystore + @SuppressWarnings("unused") + final KeyProvider.KeyVersion keyVersion = + provider.getKeyVersion("testkey5@0"); + try { + @SuppressWarnings("unused") + final KeyProvider.KeyVersion keyVersionWrongKeyNameFormat = + provider.getKeyVersion("testkey2"); + fail("should have thrown an exception"); + } catch (IOException e) { + // No version in key path testkey2/ + GenericTestUtils.assertExceptionContains("No version in key path", e); + } + try { + @SuppressWarnings("unused") + final KeyProvider.KeyVersion keyVersionCurrentKeyNotWrongKeyNameFormat = + provider.getCurrentKey("testkey5@0"); + fail("should have thrown an exception getting testkey5@0"); + } catch (IOException e) { + // javax.crypto.spec.SecretKeySpec cannot be cast to + // org.apache.hadoop.crypto.key.JavaKeyStoreProvider$KeyMetadata + GenericTestUtils.assertExceptionContains("other non-Hadoop method", e); + } + try { + @SuppressWarnings("unused") + KeyProvider.KeyVersion keyVersionCurrentKeyNotReally = + provider.getCurrentKey("testkey2"); + fail("should have thrown an exception getting testkey2"); + } catch (IOException e) { + // javax.crypto.spec.SecretKeySpec cannot be cast to + // org.apache.hadoop.crypto.key.JavaKeyStoreProvider$KeyMetadata + GenericTestUtils.assertExceptionContains("other non-Hadoop method", e); + } + } } diff --git a/hadoop-common-project/hadoop-common/src/test/resources/hdfs7067.keystore b/hadoop-common-project/hadoop-common/src/test/resources/hdfs7067.keystore new file mode 100644 index 00000000000..a0a69b194a3 Binary files /dev/null and b/hadoop-common-project/hadoop-common/src/test/resources/hdfs7067.keystore differ