HDFS-7067. ClassCastException while using a key created by keytool to create encryption zone. (Charles Lamb via Colin P. McCabe)
Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/1cf49d59 Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/1cf49d59 Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/1cf49d59 Branch: refs/heads/HDFS-EC Commit: 1cf49d598917001fc80458ee3aba18bd8976350f Parents: e350126 Author: Colin Patrick Mccabe <cmcc...@cloudera.com> Authored: Wed Jan 14 17:42:59 2015 -0800 Committer: Zhe Zhang <z...@apache.org> Committed: Tue Jan 20 09:43:08 2015 -0800 ---------------------------------------------------------------------- .../hadoop/crypto/key/JavaKeyStoreProvider.java | 5 +- .../crypto/key/TestKeyProviderFactory.java | 48 +++++++++++++++++++ .../src/test/resources/hdfs7067.keystore | Bin 0 -> 6067 bytes 3 files changed, 52 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hadoop/blob/1cf49d59/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/key/JavaKeyStoreProvider.java ---------------------------------------------------------------------- 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 a9738ba..bfec1ef 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); http://git-wip-us.apache.org/repos/asf/hadoop/blob/1cf49d59/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/key/TestKeyProviderFactory.java ---------------------------------------------------------------------- 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 998cd6f..ef09d94 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); + } + } } http://git-wip-us.apache.org/repos/asf/hadoop/blob/1cf49d59/hadoop-common-project/hadoop-common/src/test/resources/hdfs7067.keystore ---------------------------------------------------------------------- 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 0000000..a0a69b1 Binary files /dev/null and b/hadoop-common-project/hadoop-common/src/test/resources/hdfs7067.keystore differ