From 4a689777aea7cc923cb0e48d8a7db72bdb7ae57b Mon Sep 17 00:00:00 2001 From: Alejandro Abdelnur Date: Thu, 21 Aug 2014 18:58:27 +0000 Subject: [PATCH] HADOOP-10201. Add listing to KeyProvider API. (Larry McCay via omalley) Conflicts: hadoop-common-project/hadoop-common/CHANGES.txt git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-2@1619507 13f79535-47bb-0310-9956-ffa450edef68 --- .../hadoop-common/CHANGES.txt | 2 + .../crypto/key/JavaKeyStoreProvider.java | 44 ++++++++++++++++++- .../apache/hadoop/crypto/key/KeyProvider.java | 14 ++++++ .../hadoop/crypto/key/UserProvider.java | 30 +++++++++++++ .../apache/hadoop/security/Credentials.java | 1 + .../crypto/key/TestKeyProviderFactory.java | 11 +++++ 6 files changed, 101 insertions(+), 1 deletion(-) diff --git a/hadoop-common-project/hadoop-common/CHANGES.txt b/hadoop-common-project/hadoop-common/CHANGES.txt index f49285f9705..9f4fd5114bc 100644 --- a/hadoop-common-project/hadoop-common/CHANGES.txt +++ b/hadoop-common-project/hadoop-common/CHANGES.txt @@ -90,6 +90,8 @@ Release 2.6.0 - UNRELEASED HADOOP-10975. org.apache.hadoop.util.DataChecksum should support calculating checksums in native code (James Thomas via Colin Patrick McCabe) + HADOOP-10201. Add listing to KeyProvider API. (Larry McCay via omalley) + OPTIMIZATIONS HADOOP-10838. Byte array native checksumming. (James Thomas via todd) 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 3c82563628e..93a47deaa73 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 @@ -36,8 +36,11 @@ import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; +import java.util.ArrayList; import java.util.Date; +import java.util.Enumeration; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -56,6 +59,7 @@ import java.util.Map; */ @InterfaceAudience.Private public class JavaKeyStoreProvider extends KeyProvider { + private static final String KEY_METADATA = "KeyMetadata"; public static final String SCHEME_NAME = "jceks"; public static final String KEYSTORE_PASSWORD_NAME = "HADOOP_KEYSTORE_PASSWORD"; @@ -117,6 +121,44 @@ public class JavaKeyStoreProvider extends KeyProvider { return new KeyVersion(versionName, key.getEncoded()); } + @Override + public List getKeys() throws IOException { + ArrayList list = new ArrayList(); + String alias = null; + try { + Enumeration e = keyStore.aliases(); + while (e.hasMoreElements()) { + alias = e.nextElement(); + // only include the metadata key names in the list of names + if (!alias.contains("@")) { + list.add(alias); + } + } + } catch (KeyStoreException e) { + throw new IOException("Can't get key " + alias + " from " + path, e); + } + return list; + } + + @Override + public List getKeyVersions(String name) throws IOException { + List list = new ArrayList(); + Metadata km = getMetadata(name); + if (km != null) { + int latestVersion = km.getVersions(); + KeyVersion v = null; + String versionName = null; + for (int i = 0; i < latestVersion; i++) { + versionName = buildVersionName(name, i); + v = getKeyVersion(versionName); + if (v != null) { + list.add(v); + } + } + } + return list; + } + @Override public Metadata getMetadata(String name) throws IOException { if (cache.containsKey(name)) { @@ -288,7 +330,7 @@ public class JavaKeyStoreProvider extends KeyProvider { @Override public String getFormat() { - return "KeyMetadata"; + return KEY_METADATA; } @Override diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/key/KeyProvider.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/key/KeyProvider.java index a8e95e5eb6e..6f9f016f62c 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/key/KeyProvider.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/key/KeyProvider.java @@ -254,6 +254,20 @@ public abstract class KeyProvider { public abstract KeyVersion getKeyVersion(String versionName ) throws IOException; + /** + * Get the key names for all keys. + * @return the list of key names + * @throws IOException + */ + public abstract List getKeys() throws IOException; + + /** + * Get the key material for all versions of a specific key name. + * @return the list of key material + * @throws IOException + */ + public abstract List getKeyVersions(String name) throws IOException; + /** * Get the current version of the key, which should be used for encrypting new * data. diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/key/UserProvider.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/key/UserProvider.java index 42ce69341d1..424e7ca8503 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/key/UserProvider.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/key/UserProvider.java @@ -20,8 +20,10 @@ package org.apache.hadoop.crypto.key; import java.io.IOException; import java.net.URI; +import java.util.ArrayList; import java.util.Date; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.apache.hadoop.classification.InterfaceAudience; @@ -142,4 +144,32 @@ public class UserProvider extends KeyProvider { return null; } } + + @Override + public List getKeys() throws IOException { + List list = new ArrayList(); + List keys = credentials.getAllSecretKeys(); + for (Text key : keys) { + if (key.find("@") == -1) { + list.add(key.toString()); + } + } + return list; + } + + @Override + public List getKeyVersions(String name) throws IOException { + List list = new ArrayList(); + Metadata km = getMetadata(name); + if (km != null) { + int latestVersion = km.getVersions(); + for (int i = 0; i < latestVersion; i++) { + KeyVersion v = getKeyVersion(buildVersionName(name, i)); + if (v != null) { + list.add(v); + } + } + } + return list; + } } diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/Credentials.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/Credentials.java index b81e810f191..b796743eaa1 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/Credentials.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/Credentials.java @@ -31,6 +31,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; 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 8d073f7d514..b2964af6f80 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 @@ -21,6 +21,7 @@ import java.io.File; import java.io.IOException; import java.util.List; import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.crypto.key.KeyProvider.KeyVersion; import org.apache.hadoop.io.Text; import org.apache.hadoop.security.Credentials; import org.apache.hadoop.security.UserGroupInformation; @@ -160,6 +161,16 @@ public class TestKeyProviderFactory { provider.getCurrentKey("key4").getMaterial()); assertArrayEquals(key3, provider.getCurrentKey("key3").getMaterial()); assertEquals("key3@0", provider.getCurrentKey("key3").getVersionName()); + + List keys = provider.getKeys(); + assertTrue("Keys should have been returned.", keys.size() == 2); + assertTrue("Returned Keys should have included key3.", keys.contains("key3")); + assertTrue("Returned Keys should have included key4.", keys.contains("key4")); + + List kvl = provider.getKeyVersions("key3"); + assertTrue("KeyVersions should have been returned for key3.", kvl.size() == 1); + assertTrue("KeyVersions should have included key3@0.", kvl.get(0).getVersionName().equals("key3@0")); + assertArrayEquals(key3, kvl.get(0).getMaterial()); } @Test