|
@@ -17,35 +17,41 @@
|
|
|
*/
|
|
|
package org.apache.hadoop.crypto.key;
|
|
|
|
|
|
-import static org.junit.Assert.*;
|
|
|
-
|
|
|
import java.io.ByteArrayOutputStream;
|
|
|
import java.io.File;
|
|
|
+import java.io.IOException;
|
|
|
import java.io.PrintStream;
|
|
|
import java.util.UUID;
|
|
|
|
|
|
import org.apache.hadoop.conf.Configuration;
|
|
|
import org.junit.After;
|
|
|
-import org.junit.Assert;
|
|
|
import org.junit.Before;
|
|
|
import org.junit.Test;
|
|
|
|
|
|
+import static org.junit.Assert.assertFalse;
|
|
|
+import static org.junit.Assert.assertEquals;
|
|
|
+import static org.junit.Assert.assertTrue;
|
|
|
+
|
|
|
public class TestKeyShell {
|
|
|
private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
|
|
|
private final ByteArrayOutputStream errContent = new ByteArrayOutputStream();
|
|
|
|
|
|
- private static File tmpDir;
|
|
|
-
|
|
|
private PrintStream initialStdOut;
|
|
|
private PrintStream initialStdErr;
|
|
|
|
|
|
+ /* The default JCEKS provider - for testing purposes */
|
|
|
+ private String jceksProvider;
|
|
|
+
|
|
|
@Before
|
|
|
public void setup() throws Exception {
|
|
|
outContent.reset();
|
|
|
errContent.reset();
|
|
|
- tmpDir = new File(System.getProperty("test.build.data", "target"),
|
|
|
+ final File tmpDir = new File(System.getProperty("test.build.data", "target"),
|
|
|
UUID.randomUUID().toString());
|
|
|
- tmpDir.mkdirs();
|
|
|
+ if (!tmpDir.mkdirs()) {
|
|
|
+ throw new IOException("Unable to create " + tmpDir);
|
|
|
+ }
|
|
|
+ jceksProvider = "jceks://file" + tmpDir + "/keystore.jceks";
|
|
|
initialStdOut = System.out;
|
|
|
initialStdErr = System.err;
|
|
|
System.setOut(new PrintStream(outContent));
|
|
@@ -58,65 +64,80 @@ public class TestKeyShell {
|
|
|
System.setErr(initialStdErr);
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Delete a key from the default jceksProvider
|
|
|
+ * @param ks The KeyShell instance
|
|
|
+ * @param keyName The key to delete
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ private void deleteKey(KeyShell ks, String keyName) throws Exception {
|
|
|
+ int rc;
|
|
|
+ outContent.reset();
|
|
|
+ final String[] delArgs = {"delete", keyName, "--provider", jceksProvider};
|
|
|
+ rc = ks.run(delArgs);
|
|
|
+ assertEquals(0, rc);
|
|
|
+ assertTrue(outContent.toString().contains(keyName + " has been " +
|
|
|
+ "successfully deleted."));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Lists the keys in the jceksProvider
|
|
|
+ * @param ks The KeyShell instance
|
|
|
+ * @param wantMetadata True if you want metadata returned with the keys
|
|
|
+ * @return The output from the "list" call
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ private String listKeys(KeyShell ks, boolean wantMetadata) throws Exception {
|
|
|
+ int rc;
|
|
|
+ outContent.reset();
|
|
|
+ final String[] listArgs = {"list", "--provider", jceksProvider };
|
|
|
+ final String[] listArgsM = {"list", "--metadata", "--provider", jceksProvider };
|
|
|
+ rc = ks.run(wantMetadata ? listArgsM : listArgs);
|
|
|
+ assertEquals(0, rc);
|
|
|
+ return outContent.toString();
|
|
|
+ }
|
|
|
+
|
|
|
@Test
|
|
|
public void testKeySuccessfulKeyLifecycle() throws Exception {
|
|
|
- outContent.reset();
|
|
|
- String[] args1 = {"create", "key1", "--provider",
|
|
|
- "jceks://file" + tmpDir + "/keystore.jceks"};
|
|
|
int rc = 0;
|
|
|
+ String keyName = "key1";
|
|
|
+
|
|
|
KeyShell ks = new KeyShell();
|
|
|
ks.setConf(new Configuration());
|
|
|
- rc = ks.run(args1);
|
|
|
- assertEquals(0, rc);
|
|
|
- assertTrue(outContent.toString().contains("key1 has been successfully " +
|
|
|
- "created."));
|
|
|
|
|
|
outContent.reset();
|
|
|
- String[] args2 = {"list", "--provider",
|
|
|
- "jceks://file" + tmpDir + "/keystore.jceks"};
|
|
|
- rc = ks.run(args2);
|
|
|
+ final String[] args1 = {"create", keyName, "--provider", jceksProvider};
|
|
|
+ rc = ks.run(args1);
|
|
|
assertEquals(0, rc);
|
|
|
- assertTrue(outContent.toString().contains("key1"));
|
|
|
+ assertTrue(outContent.toString().contains(keyName + " has been " +
|
|
|
+ "successfully created."));
|
|
|
|
|
|
- outContent.reset();
|
|
|
- String[] args2a = {"list", "--metadata", "--provider",
|
|
|
- "jceks://file" + tmpDir + "/keystore.jceks"};
|
|
|
- rc = ks.run(args2a);
|
|
|
- assertEquals(0, rc);
|
|
|
- assertTrue(outContent.toString().contains("key1"));
|
|
|
- assertTrue(outContent.toString().contains("description"));
|
|
|
- assertTrue(outContent.toString().contains("created"));
|
|
|
+ String listOut = listKeys(ks, false);
|
|
|
+ assertTrue(listOut.contains(keyName));
|
|
|
+
|
|
|
+ listOut = listKeys(ks, true);
|
|
|
+ assertTrue(listOut.contains(keyName));
|
|
|
+ assertTrue(listOut.contains("description"));
|
|
|
+ assertTrue(listOut.contains("created"));
|
|
|
|
|
|
outContent.reset();
|
|
|
- String[] args3 = {"roll", "key1", "--provider",
|
|
|
- "jceks://file" + tmpDir + "/keystore.jceks"};
|
|
|
- rc = ks.run(args3);
|
|
|
+ final String[] args2 = {"roll", keyName, "--provider", jceksProvider};
|
|
|
+ rc = ks.run(args2);
|
|
|
assertEquals(0, rc);
|
|
|
assertTrue(outContent.toString().contains("key1 has been successfully " +
|
|
|
"rolled."));
|
|
|
|
|
|
- outContent.reset();
|
|
|
- String[] args4 = {"delete", "key1", "--provider",
|
|
|
- "jceks://file" + tmpDir + "/keystore.jceks"};
|
|
|
- rc = ks.run(args4);
|
|
|
- assertEquals(0, rc);
|
|
|
- assertTrue(outContent.toString().contains("key1 has been successfully " +
|
|
|
- "deleted."));
|
|
|
+ deleteKey(ks, keyName);
|
|
|
|
|
|
- outContent.reset();
|
|
|
- String[] args5 = {"list", "--provider",
|
|
|
- "jceks://file" + tmpDir + "/keystore.jceks"};
|
|
|
- rc = ks.run(args5);
|
|
|
- assertEquals(0, rc);
|
|
|
- assertFalse(outContent.toString(), outContent.toString().contains("key1"));
|
|
|
+ listOut = listKeys(ks, false);
|
|
|
+ assertFalse(listOut, listOut.contains(keyName));
|
|
|
}
|
|
|
|
|
|
/* HADOOP-10586 KeyShell didn't allow -description. */
|
|
|
@Test
|
|
|
public void testKeySuccessfulCreationWithDescription() throws Exception {
|
|
|
outContent.reset();
|
|
|
- String[] args1 = {"create", "key1", "--provider",
|
|
|
- "jceks://file" + tmpDir + "/keystore.jceks",
|
|
|
+ final String[] args1 = {"create", "key1", "--provider", jceksProvider,
|
|
|
"--description", "someDescription"};
|
|
|
int rc = 0;
|
|
|
KeyShell ks = new KeyShell();
|
|
@@ -126,20 +147,16 @@ public class TestKeyShell {
|
|
|
assertTrue(outContent.toString().contains("key1 has been successfully " +
|
|
|
"created."));
|
|
|
|
|
|
- outContent.reset();
|
|
|
- String[] args2a = {"list", "--metadata", "--provider",
|
|
|
- "jceks://file" + tmpDir + "/keystore.jceks"};
|
|
|
- rc = ks.run(args2a);
|
|
|
- assertEquals(0, rc);
|
|
|
- assertTrue(outContent.toString().contains("description"));
|
|
|
- assertTrue(outContent.toString().contains("someDescription"));
|
|
|
+ String listOut = listKeys(ks, true);
|
|
|
+ assertTrue(listOut.contains("description"));
|
|
|
+ assertTrue(listOut.contains("someDescription"));
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
public void testInvalidKeySize() throws Exception {
|
|
|
- String[] args1 = {"create", "key1", "--size", "56", "--provider",
|
|
|
- "jceks://file" + tmpDir + "/keystore.jceks"};
|
|
|
-
|
|
|
+ final String[] args1 = {"create", "key1", "--size", "56", "--provider",
|
|
|
+ jceksProvider};
|
|
|
+
|
|
|
int rc = 0;
|
|
|
KeyShell ks = new KeyShell();
|
|
|
ks.setConf(new Configuration());
|
|
@@ -150,9 +167,9 @@ public class TestKeyShell {
|
|
|
|
|
|
@Test
|
|
|
public void testInvalidCipher() throws Exception {
|
|
|
- String[] args1 = {"create", "key1", "--cipher", "LJM", "--provider",
|
|
|
- "jceks://file" + tmpDir + "/keystore.jceks"};
|
|
|
-
|
|
|
+ final String[] args1 = {"create", "key1", "--cipher", "LJM", "--provider",
|
|
|
+ jceksProvider};
|
|
|
+
|
|
|
int rc = 0;
|
|
|
KeyShell ks = new KeyShell();
|
|
|
ks.setConf(new Configuration());
|
|
@@ -163,7 +180,7 @@ public class TestKeyShell {
|
|
|
|
|
|
@Test
|
|
|
public void testInvalidProvider() throws Exception {
|
|
|
- String[] args1 = {"create", "key1", "--cipher", "AES", "--provider",
|
|
|
+ final String[] args1 = {"create", "key1", "--cipher", "AES", "--provider",
|
|
|
"sdff://file/tmp/keystore.jceks"};
|
|
|
|
|
|
int rc = 0;
|
|
@@ -177,7 +194,7 @@ public class TestKeyShell {
|
|
|
|
|
|
@Test
|
|
|
public void testTransientProviderWarning() throws Exception {
|
|
|
- String[] args1 = {"create", "key1", "--cipher", "AES", "--provider",
|
|
|
+ final String[] args1 = {"create", "key1", "--cipher", "AES", "--provider",
|
|
|
"user:///"};
|
|
|
|
|
|
int rc = 0;
|
|
@@ -191,7 +208,7 @@ public class TestKeyShell {
|
|
|
|
|
|
@Test
|
|
|
public void testTransientProviderOnlyConfig() throws Exception {
|
|
|
- String[] args1 = {"create", "key1"};
|
|
|
+ final String[] args1 = {"create", "key1"};
|
|
|
|
|
|
int rc = 0;
|
|
|
KeyShell ks = new KeyShell();
|
|
@@ -206,23 +223,96 @@ public class TestKeyShell {
|
|
|
|
|
|
@Test
|
|
|
public void testFullCipher() throws Exception {
|
|
|
- String[] args1 = {"create", "key1", "--cipher", "AES/CBC/pkcs5Padding",
|
|
|
- "--provider", "jceks://file" + tmpDir + "/keystore.jceks"};
|
|
|
+ final String keyName = "key1";
|
|
|
+ final String[] args1 = {"create", keyName, "--cipher", "AES/CBC/pkcs5Padding",
|
|
|
+ "--provider", jceksProvider};
|
|
|
|
|
|
int rc = 0;
|
|
|
KeyShell ks = new KeyShell();
|
|
|
ks.setConf(new Configuration());
|
|
|
rc = ks.run(args1);
|
|
|
assertEquals(0, rc);
|
|
|
- assertTrue(outContent.toString().contains("key1 has been successfully " +
|
|
|
- "created."));
|
|
|
+ assertTrue(outContent.toString().contains(keyName + " has been " +
|
|
|
+ "successfully " + "created."));
|
|
|
+
|
|
|
+ deleteKey(ks, keyName);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testAttributes() throws Exception {
|
|
|
+ int rc;
|
|
|
+ KeyShell ks = new KeyShell();
|
|
|
+ ks.setConf(new Configuration());
|
|
|
+
|
|
|
+ /* Simple creation test */
|
|
|
+ final String[] args1 = {"create", "keyattr1", "--provider", jceksProvider,
|
|
|
+ "--attr", "foo=bar"};
|
|
|
+ rc = ks.run(args1);
|
|
|
+ assertEquals(0, rc);
|
|
|
+ assertTrue(outContent.toString().contains("keyattr1 has been " +
|
|
|
+ "successfully " + "created."));
|
|
|
+
|
|
|
+ /* ...and list to see that we have the attr */
|
|
|
+ String listOut = listKeys(ks, true);
|
|
|
+ assertTrue(listOut.contains("keyattr1"));
|
|
|
+ assertTrue(listOut.contains("attributes: [foo=bar]"));
|
|
|
|
|
|
+ /* Negative tests: no attribute */
|
|
|
outContent.reset();
|
|
|
- String[] args2 = {"delete", "key1", "--provider",
|
|
|
- "jceks://file" + tmpDir + "/keystore.jceks"};
|
|
|
+ final String[] args2 = {"create", "keyattr2", "--provider", jceksProvider,
|
|
|
+ "--attr", "=bar"};
|
|
|
+ rc = ks.run(args2);
|
|
|
+ assertEquals(-1, rc);
|
|
|
+
|
|
|
+ /* Not in attribute = value form */
|
|
|
+ outContent.reset();
|
|
|
+ args2[5] = "foo";
|
|
|
+ rc = ks.run(args2);
|
|
|
+ assertEquals(-1, rc);
|
|
|
+
|
|
|
+ /* No attribute or value */
|
|
|
+ outContent.reset();
|
|
|
+ args2[5] = "=";
|
|
|
+ rc = ks.run(args2);
|
|
|
+ assertEquals(-1, rc);
|
|
|
+
|
|
|
+ /* Legal: attribute is a, value is b=c */
|
|
|
+ outContent.reset();
|
|
|
+ args2[5] = "a=b=c";
|
|
|
rc = ks.run(args2);
|
|
|
assertEquals(0, rc);
|
|
|
- assertTrue(outContent.toString().contains("key1 has been successfully " +
|
|
|
- "deleted."));
|
|
|
+
|
|
|
+ listOut = listKeys(ks, true);
|
|
|
+ assertTrue(listOut.contains("keyattr2"));
|
|
|
+ assertTrue(listOut.contains("attributes: [a=b=c]"));
|
|
|
+
|
|
|
+ /* Test several attrs together... */
|
|
|
+ outContent.reset();
|
|
|
+ final String[] args3 = {"create", "keyattr3", "--provider", jceksProvider,
|
|
|
+ "--attr", "foo = bar",
|
|
|
+ "--attr", " glarch =baz ",
|
|
|
+ "--attr", "abc=def"};
|
|
|
+ rc = ks.run(args3);
|
|
|
+ assertEquals(0, rc);
|
|
|
+
|
|
|
+ /* ...and list to ensure they're there. */
|
|
|
+ listOut = listKeys(ks, true);
|
|
|
+ assertTrue(listOut.contains("keyattr3"));
|
|
|
+ assertTrue(listOut.contains("[foo=bar]"));
|
|
|
+ assertTrue(listOut.contains("[glarch=baz]"));
|
|
|
+ assertTrue(listOut.contains("[abc=def]"));
|
|
|
+
|
|
|
+ /* Negative test - repeated attributes should fail */
|
|
|
+ outContent.reset();
|
|
|
+ final String[] args4 = {"create", "keyattr4", "--provider", jceksProvider,
|
|
|
+ "--attr", "foo=bar",
|
|
|
+ "--attr", "foo=glarch"};
|
|
|
+ rc = ks.run(args4);
|
|
|
+ assertEquals(-1, rc);
|
|
|
+
|
|
|
+ /* Clean up to be a good citizen */
|
|
|
+ deleteKey(ks, "keyattr1");
|
|
|
+ deleteKey(ks, "keyattr2");
|
|
|
+ deleteKey(ks, "keyattr3");
|
|
|
}
|
|
|
}
|