You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by tu...@apache.org on 2014/08/21 20:58:36 UTC
svn commit: r1619511 - in
/hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common: ./
src/main/java/org/apache/hadoop/crypto/key/
src/test/java/org/apache/hadoop/crypto/key/
Author: tucu
Date: Thu Aug 21 18:58:35 2014
New Revision: 1619511
URL: http://svn.apache.org/r1619511
Log:
HADOOP-10429. KeyStores should have methods to generate the materials themselves, KeyShell should use them. (tucu)
Conflicts:
hadoop-common-project/hadoop-common/CHANGES.txt
Modified:
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/CHANGES.txt
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/key/KeyProvider.java
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/key/KeyShell.java
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/key/TestKeyProvider.java
Modified: hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/CHANGES.txt
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/CHANGES.txt?rev=1619511&r1=1619510&r2=1619511&view=diff
==============================================================================
--- hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/CHANGES.txt (original)
+++ hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/CHANGES.txt Thu Aug 21 18:58:35 2014
@@ -97,6 +97,9 @@ Release 2.6.0 - UNRELEASED
HADOOP-10432. Refactor SSLFactory to expose static method to determine
HostnameVerifier. (tucu)
+ HADOOP-10429. KeyStores should have methods to generate the materials
+ themselves, KeyShell should use them. (tucu)
+
OPTIMIZATIONS
HADOOP-10838. Byte array native checksumming. (James Thomas via todd)
Modified: hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/key/KeyProvider.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/key/KeyProvider.java?rev=1619511&r1=1619510&r2=1619511&view=diff
==============================================================================
--- hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/key/KeyProvider.java (original)
+++ hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/key/KeyProvider.java Thu Aug 21 18:58:35 2014
@@ -24,6 +24,7 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URI;
+import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.List;
@@ -34,6 +35,8 @@ import org.apache.hadoop.classification.
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
+import javax.crypto.KeyGenerator;
+
/**
* A provider of secret key material for Hadoop applications. Provides an
* abstraction to separate key storage from users of encryption. It
@@ -315,6 +318,56 @@ public abstract class KeyProvider {
Options options) throws IOException;
/**
+ * Get the algorithm from the cipher.
+ *
+ * @return the algorithm name
+ */
+ private String getAlgorithm(String cipher) {
+ int slash = cipher.indexOf('/');
+ if (slash == -1) {
+ return cipher;
+ } else {
+ return cipher.substring(0, slash);
+ }
+ }
+
+ /**
+ * Generates a key material.
+ *
+ * @param size length of the key.
+ * @param algorithm algorithm to use for generating the key.
+ * @return the generated key.
+ * @throws NoSuchAlgorithmException
+ */
+ protected byte[] generateKey(int size, String algorithm)
+ throws NoSuchAlgorithmException {
+ algorithm = getAlgorithm(algorithm);
+ KeyGenerator keyGenerator = KeyGenerator.getInstance(algorithm);
+ keyGenerator.init(size);
+ byte[] key = keyGenerator.generateKey().getEncoded();
+ return key;
+ }
+
+ /**
+ * Create a new key generating the material for it.
+ * The given key must not already exist.
+ * <p/>
+ * This implementation generates the key material and calls the
+ * {@link #createKey(String, byte[], Options)} method.
+ *
+ * @param name the base name of the key
+ * @param options the options for the new key.
+ * @return the version name of the first version of the key.
+ * @throws IOException
+ * @throws NoSuchAlgorithmException
+ */
+ public KeyVersion createKey(String name, Options options)
+ throws NoSuchAlgorithmException, IOException {
+ byte[] material = generateKey(options.getBitLength(), options.getCipher());
+ return createKey(name, material, options);
+ }
+
+ /**
* Delete the given key.
* @param name the name of the key to delete
* @throws IOException
@@ -333,6 +386,23 @@ public abstract class KeyProvider {
) throws IOException;
/**
+ * Roll a new version of the given key generating the material for it.
+ * <p/>
+ * This implementation generates the key material and calls the
+ * {@link #rollNewVersion(String, byte[])} method.
+ *
+ * @param name the basename of the key
+ * @return the name of the new version of the key
+ * @throws IOException
+ */
+ public KeyVersion rollNewVersion(String name) throws NoSuchAlgorithmException,
+ IOException {
+ Metadata meta = getMetadata(name);
+ byte[] material = generateKey(meta.getBitLength(), meta.getCipher());
+ return rollNewVersion(name, material);
+ }
+
+ /**
* Ensures that any changes to the keys are written to persistent store.
* @throws IOException
*/
Modified: hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/key/KeyShell.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/key/KeyShell.java?rev=1619511&r1=1619510&r2=1619511&view=diff
==============================================================================
--- hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/key/KeyShell.java (original)
+++ hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/key/KeyShell.java Thu Aug 21 18:58:35 2014
@@ -185,16 +185,6 @@ public class KeyShell extends Configured
return provider;
}
- protected byte[] generateKey(int size, String algorithm)
- throws NoSuchAlgorithmException {
- out.println("Generating key using size: " + size + " and algorithm: "
- + algorithm);
- KeyGenerator keyGenerator = KeyGenerator.getInstance(algorithm);
- keyGenerator.init(size);
- byte[] key = keyGenerator.generateKey().getEncoded();
- return key;
- }
-
protected void printProviderWritten() {
out.println(provider.getClass().getName() + " has been updated.");
}
@@ -289,9 +279,7 @@ public class KeyShell extends Configured
out.println("Rolling key version from KeyProvider: "
+ provider.toString() + " for key name: " + keyName);
try {
- byte[] material = null;
- material = generateKey(md.getBitLength(), md.getAlgorithm());
- provider.rollNewVersion(keyName, material);
+ provider.rollNewVersion(keyName);
out.println(keyName + " has been successfully rolled.");
provider.flush();
printProviderWritten();
@@ -423,9 +411,7 @@ public class KeyShell extends Configured
warnIfTransientProvider();
try {
Options options = KeyProvider.options(getConf());
- String alg = getAlgorithm(options.getCipher());
- byte[] material = generateKey(options.getBitLength(), alg);
- provider.createKey(keyName, material, options);
+ provider.createKey(keyName, options);
out.println(keyName + " has been successfully created.");
provider.flush();
printProviderWritten();
@@ -441,19 +427,6 @@ public class KeyShell extends Configured
}
}
- /**
- * Get the algorithm from the cipher.
- * @return the algorithm name
- */
- public String getAlgorithm(String cipher) {
- int slash = cipher.indexOf('/');
- if (slash == - 1) {
- return cipher;
- } else {
- return cipher.substring(0, slash);
- }
- }
-
@Override
public String getUsage() {
return USAGE + ":\n\n" + DESC;
Modified: hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/key/TestKeyProvider.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/key/TestKeyProvider.java?rev=1619511&r1=1619510&r2=1619511&view=diff
==============================================================================
--- hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/key/TestKeyProvider.java (original)
+++ hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/key/TestKeyProvider.java Thu Aug 21 18:58:35 2014
@@ -17,6 +17,7 @@
*/
package org.apache.hadoop.crypto.key;
+import junit.framework.Assert;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
@@ -24,9 +25,11 @@ import org.junit.Test;
import java.io.IOException;
import java.net.URI;
+import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
+import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -34,6 +37,8 @@ import static org.junit.Assert.assertArr
public class TestKeyProvider {
+ private static final String CIPHER = "AES";
+
@Test
public void testBuildVersionName() throws Exception {
assertEquals("/a/b@3", KeyProvider.buildVersionName("/a/b", 3));
@@ -109,4 +114,82 @@ public class TestKeyProvider {
assertEquals(new Path("user:///"),
KeyProvider.unnestUri(new URI("outer://user/")));
}
+
+ private static class MyKeyProvider extends KeyProvider {
+ private String algorithm;
+ private int size;
+ private byte[] material;
+
+ @Override
+ public KeyVersion getKeyVersion(String versionName)
+ throws IOException {
+ return null;
+ }
+
+ @Override
+ public List<String> getKeys() throws IOException {
+ return null;
+ }
+
+ @Override
+ public List<KeyVersion> getKeyVersions(String name)
+ throws IOException {
+ return null;
+ }
+
+ @Override
+ public Metadata getMetadata(String name) throws IOException {
+ return new Metadata(CIPHER, 128, new Date(), 0);
+ }
+
+ @Override
+ public KeyVersion createKey(String name, byte[] material,
+ Options options) throws IOException {
+ this.material = material;
+ return null;
+ }
+
+ @Override
+ public void deleteKey(String name) throws IOException {
+
+ }
+
+ @Override
+ public KeyVersion rollNewVersion(String name, byte[] material)
+ throws IOException {
+ this.material = material;
+ return null;
+ }
+
+ @Override
+ public void flush() throws IOException {
+
+ }
+
+ @Override
+ protected byte[] generateKey(int size, String algorithm)
+ throws NoSuchAlgorithmException {
+ this.size = size;
+ this.algorithm = algorithm;
+ return super.generateKey(size, algorithm);
+ }
+ }
+
+ @Test
+ public void testMaterialGeneration() throws Exception {
+ MyKeyProvider kp = new MyKeyProvider();
+ KeyProvider.Options options = new KeyProvider.Options(new Configuration());
+ options.setCipher(CIPHER);
+ options.setBitLength(128);
+ kp.createKey("hello", options);
+ Assert.assertEquals(128, kp.size);
+ Assert.assertEquals(CIPHER, kp.algorithm);
+ Assert.assertNotNull(kp.material);
+
+ kp = new MyKeyProvider();
+ kp.rollNewVersion("hello");
+ Assert.assertEquals(128, kp.size);
+ Assert.assertEquals(CIPHER, kp.algorithm);
+ Assert.assertNotNull(kp.material);
+ }
}