8130850: Support loading a keystore with a custom KeyStore.LoadStoreParameter class
authorvinnie
Fri, 31 Jul 2015 14:29:25 +0100
changeset 32005 2c716d9dac38
parent 32004 5dba041fc305
child 32006 97c6167e698a
8130850: Support loading a keystore with a custom KeyStore.LoadStoreParameter class Reviewed-by: mullan
jdk/src/java.base/share/classes/java/security/KeyStoreSpi.java
jdk/test/java/security/KeyStore/EntryMethods.java
--- a/jdk/src/java.base/share/classes/java/security/KeyStoreSpi.java	Fri Jul 31 15:19:15 2015 +0200
+++ b/jdk/src/java.base/share/classes/java/security/KeyStoreSpi.java	Fri Jul 31 14:29:25 2015 +0100
@@ -360,6 +360,22 @@
      *          that specifies how to load the keystore,
      *          which may be {@code null}
      *
+     * @implSpec
+     * The default implementation examines {@code KeyStore.LoadStoreParameter}
+     * to extract its password and pass it to
+     * {@link KeyStoreSpi#engineLoad(InputStream, char[])} along with a
+     * {@code null} {@code InputStream}.
+     * <p>
+     * If {@code KeyStore.LoadStoreParameter} is {@code null} then
+     * the password parameter will also be {@code null}.
+     * Otherwise the {@code KeyStore.ProtectionParameter} of
+     * {@code KeyStore.LoadStoreParameter} must be either a
+     * {@code KeyStore.PasswordProtection} or a
+     * {@code KeyStore.CallbackHandlerProtection} that supports
+     * {@code PasswordCallback} so that the password parameter can be
+     * extracted. If the {@code KeyStore.ProtectionParameter} is neither
+     * of those classes then a {@code NoSuchAlgorithmException} is thrown.
+     *
      * @exception IllegalArgumentException if the given
      *          {@code KeyStore.LoadStoreParameter}
      *          input is not recognized
@@ -385,37 +401,32 @@
             return;
         }
 
-        if (param instanceof KeyStore.SimpleLoadStoreParameter) {
-            ProtectionParameter protection = param.getProtectionParameter();
-            char[] password;
-            if (protection instanceof PasswordProtection) {
-                password = ((PasswordProtection)protection).getPassword();
-            } else if (protection instanceof CallbackHandlerProtection) {
-                CallbackHandler handler =
-                    ((CallbackHandlerProtection)protection).getCallbackHandler();
-                PasswordCallback callback =
-                    new PasswordCallback("Password: ", false);
-                try {
-                    handler.handle(new Callback[] {callback});
-                } catch (UnsupportedCallbackException e) {
-                    throw new NoSuchAlgorithmException
-                        ("Could not obtain password", e);
-                }
-                password = callback.getPassword();
-                callback.clearPassword();
-                if (password == null) {
-                    throw new NoSuchAlgorithmException
-                        ("No password provided");
-                }
-            } else {
-                throw new NoSuchAlgorithmException("ProtectionParameter must"
-                    + " be PasswordProtection or CallbackHandlerProtection");
+        ProtectionParameter protection = param.getProtectionParameter();
+        char[] password;
+        if (protection instanceof PasswordProtection) {
+            password = ((PasswordProtection)protection).getPassword();
+        } else if (protection instanceof CallbackHandlerProtection) {
+            CallbackHandler handler =
+                ((CallbackHandlerProtection)protection).getCallbackHandler();
+            PasswordCallback callback =
+                new PasswordCallback("Password: ", false);
+            try {
+                handler.handle(new Callback[] {callback});
+            } catch (UnsupportedCallbackException e) {
+                throw new NoSuchAlgorithmException
+                    ("Could not obtain password", e);
             }
-            engineLoad(null, password);
-            return;
+            password = callback.getPassword();
+            callback.clearPassword();
+            if (password == null) {
+                throw new NoSuchAlgorithmException("No password provided");
+            }
+        } else {
+            throw new NoSuchAlgorithmException("ProtectionParameter must"
+                + " be PasswordProtection or CallbackHandlerProtection");
         }
-
-        throw new UnsupportedOperationException();
+        engineLoad(null, password);
+        return;
     }
 
     /**
--- a/jdk/test/java/security/KeyStore/EntryMethods.java	Fri Jul 31 15:19:15 2015 +0200
+++ b/jdk/test/java/security/KeyStore/EntryMethods.java	Fri Jul 31 14:29:25 2015 +0100
@@ -23,7 +23,7 @@
 
 /*
  * @test 1.5, 03/06/24
- * @bug 4850376
+ * @bug 4850376 8130850
  * @summary Provide generic storage KeyStore storage facilities
  */
 
@@ -50,6 +50,20 @@
         }
     }
 
+    public static class MyLoadStoreParameter
+        implements KeyStore.LoadStoreParameter {
+
+        private KeyStore.ProtectionParameter protection;
+
+        MyLoadStoreParameter(KeyStore.ProtectionParameter protection) {
+            this.protection = protection;
+        }
+
+        public KeyStore.ProtectionParameter getProtectionParameter() {
+            return protection;
+        }
+    }
+
     public static class FooEntry implements KeyStore.Entry { }
 
     public EntryMethods() throws Exception {
@@ -103,9 +117,17 @@
             throw new SecurityException("[Pre1.5] test " + tNum + " failed");
         } catch (UnsupportedOperationException uoe) {
             System.out.println("[Pre1.5] test " + tNum++ + " passed");
+        } catch (NoSuchAlgorithmException nsae) {
+            System.out.println("[Pre1.5] test " + tNum++ + " passed");
         }
 
 
+        // TEST load custom param
+        ks.load(new MyLoadStoreParameter(
+            new KeyStore.PasswordProtection(password)));
+        System.out.println("[Pre1.5] test " + tNum++ + " passed");
+
+
         // TEST store random param
         ks.load(pre15fis, password);