HADOOP-10201. Add listing to KeyProvider API. (Larry McCay via omalley)

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1556072 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Owen O'Malley 2014-01-06 23:43:08 +00:00
parent 0c591a624d
commit cbdad3d471
6 changed files with 121 additions and 10 deletions

View File

@ -108,6 +108,8 @@ Trunk (Unreleased)
HADOOP-10141. Create KeyProvider API to separate encryption key storage HADOOP-10141. Create KeyProvider API to separate encryption key storage
from the applications. (omalley) from the applications. (omalley)
HADOOP-10201. Add listing to KeyProvider API. (Larry McCay via omalley)
BUG FIXES BUG FIXES
HADOOP-9451. Fault single-layer config if node group topology is enabled. HADOOP-9451. Fault single-layer config if node group topology is enabled.

View File

@ -36,8 +36,11 @@
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException; import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
@ -56,6 +59,7 @@
*/ */
@InterfaceAudience.Private @InterfaceAudience.Private
public class JavaKeyStoreProvider extends KeyProvider { public class JavaKeyStoreProvider extends KeyProvider {
private static final String KEY_METADATA = "KeyMetadata";
public static final String SCHEME_NAME = "jceks"; public static final String SCHEME_NAME = "jceks";
public static final String KEYSTORE_PASSWORD_NAME = public static final String KEYSTORE_PASSWORD_NAME =
"HADOOP_KEYSTORE_PASSWORD"; "HADOOP_KEYSTORE_PASSWORD";
@ -117,6 +121,44 @@ public KeyVersion getKeyVersion(String versionName) throws IOException {
return new KeyVersion(versionName, key.getEncoded()); return new KeyVersion(versionName, key.getEncoded());
} }
@Override
public List<String> getKeys() throws IOException {
ArrayList<String> list = new ArrayList<String>();
String alias = null;
try {
Enumeration<String> 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<KeyVersion> getKeyVersions(String name) throws IOException {
List<KeyVersion> list = new ArrayList<KeyVersion>();
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 @Override
public Metadata getMetadata(String name) throws IOException { public Metadata getMetadata(String name) throws IOException {
if (cache.containsKey(name)) { if (cache.containsKey(name)) {
@ -288,7 +330,7 @@ public String getAlgorithm() {
@Override @Override
public String getFormat() { public String getFormat() {
return "KeyMetadata"; return KEY_METADATA;
} }
@Override @Override

View File

@ -254,6 +254,20 @@ public static Options options(Configuration conf) {
public abstract KeyVersion getKeyVersion(String versionName public abstract KeyVersion getKeyVersion(String versionName
) throws IOException; ) throws IOException;
/**
* Get the key names for all keys.
* @return the list of key names
* @throws IOException
*/
public abstract List<String> 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<KeyVersion> getKeyVersions(String name) throws IOException;
/** /**
* Get the current version of the key, which should be used for encrypting new * Get the current version of the key, which should be used for encrypting new
* data. * data.

View File

@ -20,8 +20,10 @@
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.classification.InterfaceAudience;
@ -142,4 +144,32 @@ public KeyProvider createProvider(URI providerName,
return null; return null;
} }
} }
@Override
public List<String> getKeys() throws IOException {
List<String> list = new ArrayList<String>();
List<Text> keys = credentials.getAllSecretKeys();
for (Text key : keys) {
if (key.find("@") == -1) {
list.add(key.toString());
}
}
return list;
}
@Override
public List<KeyVersion> getKeyVersions(String name) throws IOException {
List<KeyVersion> list = new ArrayList<KeyVersion>();
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;
}
} }

View File

@ -29,7 +29,9 @@
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -73,15 +75,6 @@ public Credentials(Credentials credentials) {
this.addAll(credentials); this.addAll(credentials);
} }
/**
* Returns the key bytes for the alias
* @param alias the alias for the key
* @return key for this alias
*/
public byte[] getSecretKey(Text alias) {
return secretKeysMap.get(alias);
}
/** /**
* Returns the Token object for the alias * Returns the Token object for the alias
* @param alias the alias for the Token * @param alias the alias for the Token
@ -118,6 +111,15 @@ public int numberOfTokens() {
return tokenMap.size(); return tokenMap.size();
} }
/**
* Returns the key bytes for the alias
* @param alias the alias for the key
* @return key for this alias
*/
public byte[] getSecretKey(Text alias) {
return secretKeysMap.get(alias);
}
/** /**
* @return number of keys in the in-memory map * @return number of keys in the in-memory map
*/ */
@ -142,6 +144,16 @@ public void removeSecretKey(Text alias) {
secretKeysMap.remove(alias); secretKeysMap.remove(alias);
} }
/**
* Return all the secret key entries in the in-memory map
*/
public List<Text> getAllSecretKeys() {
List<Text> list = new java.util.ArrayList<Text>();
list.addAll(secretKeysMap.keySet());
return list;
}
/** /**
* Convenience method for reading a token storage file, and loading the Tokens * Convenience method for reading a token storage file, and loading the Tokens
* therein in the passed UGI * therein in the passed UGI

View File

@ -21,6 +21,7 @@
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.crypto.key.KeyProvider.KeyVersion;
import org.apache.hadoop.io.Text; import org.apache.hadoop.io.Text;
import org.apache.hadoop.security.Credentials; import org.apache.hadoop.security.Credentials;
import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.security.UserGroupInformation;
@ -160,6 +161,16 @@ static void checkSpecificProvider(Configuration conf,
provider.getCurrentKey("key4").getMaterial()); provider.getCurrentKey("key4").getMaterial());
assertArrayEquals(key3, provider.getCurrentKey("key3").getMaterial()); assertArrayEquals(key3, provider.getCurrentKey("key3").getMaterial());
assertEquals("key3@0", provider.getCurrentKey("key3").getVersionName()); assertEquals("key3@0", provider.getCurrentKey("key3").getVersionName());
List<String> 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<KeyVersion> 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 @Test