7191662: JCE providers should be located via ServiceLoader
authorvaleriep
Fri, 26 Jun 2015 21:34:34 +0000
changeset 31270 e6470b24700d
parent 31269 14968253ce7e
child 31271 4a44fada91e3
child 31465 2c323e090b51
7191662: JCE providers should be located via ServiceLoader Summary: Enhanced to use ServiceLoader and switched provider to Provider.Service model. Reviewed-by: mullan, alanb, mchung
jdk/src/java.base/share/classes/java/security/Provider.java
jdk/src/java.base/share/classes/java/security/Security.java
jdk/src/java.base/share/classes/sun/security/jca/ProviderConfig.java
jdk/src/java.base/share/classes/sun/security/jca/ProviderList.java
jdk/src/java.base/share/classes/sun/security/jca/Providers.java
jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java
jdk/src/java.base/share/conf/security/java.security
jdk/src/java.naming/share/classes/sun/security/provider/certpath/ldap/JdkLDAP.java
jdk/src/java.security.jgss/share/classes/sun/security/jgss/SunProvider.java
jdk/src/java.security.sasl/share/classes/com/sun/security/sasl/Provider.java
jdk/src/java.security.sasl/share/classes/javax/security/sasl/Sasl.java
jdk/src/java.smartcardio/share/classes/sun/security/smartcardio/SunPCSC.java
jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java
jdk/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java
jdk/src/jdk.crypto.ec/share/classes/sun/security/ec/SunECEntries.java
jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/SunMSCAPI.java
jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/Config.java
jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/Secmod.java
jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/SunPKCS11.java
jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeCipher.java
jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeGCMCipher.java
jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeRSASignature.java
jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/ServiceDesc.java
jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoMech.java
jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoProvider.java
jdk/src/jdk.deploy.osx/macosx/classes/apple/security/AppleProvider.java
jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java
jdk/src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/JdkSASL.java
jdk/test/java/lang/SecurityManager/CheckSecurityProvider.java
jdk/test/java/security/Security/SynchronizedAccess.java
jdk/test/sun/security/pkcs11/KeyStore/Basic.java
jdk/test/sun/security/pkcs11/KeyStore/ClientAuth.java
jdk/test/sun/security/pkcs11/KeyStore/ProviderLoader.java
jdk/test/sun/security/pkcs11/PKCS11Test.java
jdk/test/sun/security/pkcs11/rsa/TestCACerts.java
jdk/test/tools/launcher/MiscTests.java
--- a/jdk/src/java.base/share/classes/java/security/Provider.java	Thu Jun 25 11:59:40 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/security/Provider.java	Fri Jun 26 21:34:34 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,30 +41,22 @@
  *
  * <ul>
  *
- * <li>Algorithms (such as DSA, RSA, MD5 or SHA-1).
+ * <li>Algorithms (such as DSA, RSA, or SHA-256).
  *
  * <li>Key generation, conversion, and management facilities (such as for
  * algorithm-specific keys).
  *
- *</ul>
- *
- * <p>Each provider has a name and a version number, and is configured
- * in each runtime it is installed in.
- *
- * <p>See <a href =
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#Provider">The Provider Class</a>
- * in the "Java Cryptography Architecture API Specification &amp; Reference"
- * for information about how a particular type of provider, the
- * cryptographic service provider, works and is installed. However,
- * please note that a provider can be used to implement any security
- * service in Java that uses a pluggable architecture with a choice
- * of implementations that fit underneath.
+ * </ul>
  *
  * <p>Some provider implementations may encounter unrecoverable internal
  * errors during their operation, for example a failure to communicate with a
  * security token. A {@link ProviderException} should be used to indicate
  * such errors.
  *
+ * <p>Please note that a provider can be used to implement any security
+ * service in Java that uses a pluggable architecture with a choice
+ * of implementations that fit underneath.
+ *
  * <p>The service type {@code Provider} is reserved for use by the
  * security framework. Services of this type cannot be added, removed,
  * or modified by applications.
@@ -82,6 +74,28 @@
  *     <td>{@code provider.getClass().getName()}</td>
  * </table>
  *
+ * <p>Each provider has a name and a version number. A provider normally
+ * identifies itself with a file named {@code java.security.Provider}
+ * in the resource directory {@code META-INF/services}.
+ * Security providers are looked up via the {@link ServiceLoader} mechanism
+ * using the {@link ClassLoader#getSystemClassLoader application class loader}.
+ *
+ * <p>Providers may be configured such that they are automatically
+ * installed and made available at runtime via the
+ * {@link Security#getProviders() Security.getProviders()} method.
+ * The mechanism for configuring and installing security providers is
+ * implementation-specific.
+ *
+ * @implNote
+ * The JDK implementation supports static registration of the security
+ * providers via the {@code conf/security/java.security} file in the Java
+ * installation directory. These providers are automatically installed by
+ * the JDK runtime, see <a href =
+ * "../../../technotes/guides/security/crypto/CryptoSpec.html#Provider">The Provider Class</a>
+ * in the "Java Cryptography Architecture API Specification &amp; Reference"
+ * for information about how a particular type of provider, the cryptographic
+ * service provider, works and is installed.
+ *
  * @author Benjamin Renaud
  * @author Andreas Sterbenz
  */
@@ -121,6 +135,18 @@
 
     private transient boolean initialized;
 
+    private static Object newInstanceUtil(final Class<?> clazz,
+        final Class<?> ctrParamClz, final Object ctorParamObj)
+        throws Exception {
+        if (ctrParamClz == null) {
+            Constructor<?> con = clazz.getConstructor();
+            return con.newInstance();
+        } else {
+            Constructor<?> con = clazz.getConstructor(ctrParamClz);
+            return con.newInstance(ctorParamObj);
+        }
+    }
+
     /**
      * Constructs a provider with the specified name, version number,
      * and information.
@@ -140,6 +166,34 @@
     }
 
     /**
+     * Apply the supplied configuration argument to this provider instance
+     * and return the configured provider. Note that if this provider cannot
+     * be configured in-place, a new provider will be created and returned.
+     * Therefore, callers should always use the returned provider.
+     *
+     * @implSpec
+     * The default implementation throws {@code UnsupportedOperationException}.
+     * Subclasses should override this method only if a configuration argument
+     * is supported.
+     *
+     * @param configArg the configuration information for configuring this
+     *         provider.
+     *
+     * @throws UnsupportedOperationException if a configuration argument is
+     *         not supported.
+     * @throws NullPointerException if the supplied configuration argument is
+               null.
+     * @throws InvalidParameterException if the supplied configuration argument
+     *         is invalid.
+     * @return a provider configured with the supplied configuration argument.
+     *
+     * @since 1.9
+     */
+    public Provider configure(String configArg) {
+        throw new UnsupportedOperationException("configure is not supported");
+    }
+
+    /**
      * Returns the name of this provider.
      *
      * @return the name of this provider.
@@ -212,8 +266,8 @@
     /**
      * Reads a property list (key and element pairs) from the input stream.
      *
-     * @param inStream   the input stream.
-     * @exception  IOException  if an error occurred when reading from the
+     * @param inStream the input stream.
+     * @exception IOException if an error occurred when reading from the
      *               input stream.
      * @see java.util.Properties#load
      */
@@ -1579,39 +1633,35 @@
                 }
                 registered = true;
             }
+            Class<?> ctrParamClz;
             try {
                 EngineDescription cap = knownEngines.get(type);
                 if (cap == null) {
                     // unknown engine type, use generic code
                     // this is the code path future for non-core
                     // optional packages
-                    return newInstanceGeneric(constructorParameter);
-                }
-                if (cap.constructorParameterClassName == null) {
+                    ctrParamClz = constructorParameter == null?
+                        null : constructorParameter.getClass();
+                } else {
+                    ctrParamClz = cap.constructorParameterClassName == null?
+                        null : Class.forName(cap.constructorParameterClassName);
                     if (constructorParameter != null) {
-                        throw new InvalidParameterException
-                            ("constructorParameter not used with " + type
-                            + " engines");
-                    }
-                    Class<?> clazz = getImplClass();
-                    Class<?>[] empty = {};
-                    Constructor<?> con = clazz.getConstructor(empty);
-                    return con.newInstance();
-                } else {
-                    Class<?> paramClass = cap.getConstructorParameterClass();
-                    if (constructorParameter != null) {
-                        Class<?> argClass = constructorParameter.getClass();
-                        if (paramClass.isAssignableFrom(argClass) == false) {
+                        if (ctrParamClz == null) {
                             throw new InvalidParameterException
-                            ("constructorParameter must be instanceof "
-                            + cap.constructorParameterClassName.replace('$', '.')
-                            + " for engine type " + type);
+                                ("constructorParameter not used with " + type
+                                + " engines");
+                        } else {
+                            Class<?> argClass = constructorParameter.getClass();
+                            if (ctrParamClz.isAssignableFrom(argClass) == false) {
+                                throw new InvalidParameterException
+                                    ("constructorParameter must be instanceof "
+                                    + cap.constructorParameterClassName.replace('$', '.')
+                                    + " for engine type " + type);
+                            }
                         }
                     }
-                    Class<?> clazz = getImplClass();
-                    Constructor<?> cons = clazz.getConstructor(paramClass);
-                    return cons.newInstance(constructorParameter);
                 }
+                return newInstanceUtil(getImplClass(), ctrParamClz, constructorParameter);
             } catch (NoSuchAlgorithmException e) {
                 throw e;
             } catch (InvocationTargetException e) {
@@ -1655,43 +1705,6 @@
         }
 
         /**
-         * Generic code path for unknown engine types. Call the
-         * no-args constructor if constructorParameter is null, otherwise
-         * use the first matching constructor.
-         */
-        private Object newInstanceGeneric(Object constructorParameter)
-                throws Exception {
-            Class<?> clazz = getImplClass();
-            if (constructorParameter == null) {
-                // create instance with public no-arg constructor if it exists
-                try {
-                    Class<?>[] empty = {};
-                    Constructor<?> con = clazz.getConstructor(empty);
-                    return con.newInstance();
-                } catch (NoSuchMethodException e) {
-                    throw new NoSuchAlgorithmException("No public no-arg "
-                        + "constructor found in class " + className);
-                }
-            }
-            Class<?> argClass = constructorParameter.getClass();
-            Constructor<?>[] cons = clazz.getConstructors();
-            // find first public constructor that can take the
-            // argument as parameter
-            for (Constructor<?> con : cons) {
-                Class<?>[] paramTypes = con.getParameterTypes();
-                if (paramTypes.length != 1) {
-                    continue;
-                }
-                if (paramTypes[0].isAssignableFrom(argClass) == false) {
-                    continue;
-                }
-                return con.newInstance(constructorParameter);
-            }
-            throw new NoSuchAlgorithmException("No public constructor matching "
-                + argClass.getName() + " found in class " + className);
-        }
-
-        /**
          * Test whether this Service can use the specified parameter.
          * Returns false if this service cannot use the parameter. Returns
          * true if this service can use the parameter, if a fast test is
--- a/jdk/src/java.base/share/classes/java/security/Security.java	Thu Jun 25 11:59:40 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/security/Security.java	Fri Jun 26 21:34:34 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,7 +41,7 @@
  *
  * <p>The default values of security properties are read from an
  * implementation-specific location, which is typically the properties file
- * {@code lib/security/java.security} in the Java installation directory.
+ * {@code conf/security/java.security} in the Java installation directory.
  *
  * @author Benjamin Renaud
  */
--- a/jdk/src/java.base/share/classes/sun/security/jca/ProviderConfig.java	Thu Jun 25 11:59:40 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/jca/ProviderConfig.java	Fri Jun 26 21:34:34 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,14 +27,15 @@
 
 import java.io.File;
 import java.lang.reflect.*;
+import java.util.*;
 
 import java.security.*;
 
 import sun.security.util.PropertyExpander;
 
 /**
- * Class representing a configured provider. Encapsulates configuration
- * (className plus optional argument), the provider loading logic, and
+ * Class representing a configured provider which encapsulates configuration
+ * (provider name + optional argument), the provider loading logic, and
  * the loaded Provider object itself.
  *
  * @author  Andreas Sterbenz
@@ -45,9 +46,8 @@
     private final static sun.security.util.Debug debug =
         sun.security.util.Debug.getInstance("jca", "ProviderConfig");
 
-    // classname of the SunPKCS11-Solaris provider
-    private static final String P11_SOL_NAME =
-        "sun.security.pkcs11.SunPKCS11";
+    // suffix for identifying the SunPKCS11-Solaris provider
+    private static final String P11_SOL_NAME = "SunPKCS11";
 
     // config file argument of the SunPKCS11-Solaris provider
     private static final String P11_SOL_ARG  =
@@ -56,15 +56,10 @@
     // maximum number of times to try loading a provider before giving up
     private final static int MAX_LOAD_TRIES = 30;
 
-    // parameters for the Provider(String) constructor,
-    // use by doLoadProvider()
-    private final static Class<?>[] CL_STRING = { String.class };
+    // could be provider name (module) or provider class name (legacy)
+    private final String provName;
 
-    // name of the provider class
-    private final String className;
-
-    // argument to the provider constructor,
-    // empty string indicates no-arg constructor
+    // argument to the Provider.configure() call, never null
     private final String argument;
 
     // number of times we have already tried to load this provider
@@ -77,20 +72,20 @@
     // used to detect recursion
     private boolean isLoading;
 
-    ProviderConfig(String className, String argument) {
-        if (className.equals(P11_SOL_NAME) && argument.equals(P11_SOL_ARG)) {
+    ProviderConfig(String provName, String argument) {
+        if (provName.endsWith(P11_SOL_NAME) && argument.equals(P11_SOL_ARG)) {
             checkSunPKCS11Solaris();
         }
-        this.className = className;
+        this.provName = provName;
         this.argument = expand(argument);
     }
 
-    ProviderConfig(String className) {
-        this(className, "");
+    ProviderConfig(String provName) {
+        this(provName, "");
     }
 
     ProviderConfig(Provider provider) {
-        this.className = provider.getClass().getName();
+        this.provName = provider.getName();
         this.argument = "";
         this.provider = provider;
     }
@@ -144,19 +139,20 @@
             return false;
         }
         ProviderConfig other = (ProviderConfig)obj;
-        return this.className.equals(other.className)
+        return this.provName.equals(other.provName)
             && this.argument.equals(other.argument);
+
     }
 
     public int hashCode() {
-        return className.hashCode() + argument.hashCode();
+        return provName.hashCode() + argument.hashCode();
     }
 
     public String toString() {
         if (hasArgument()) {
-            return className + "('" + argument + "')";
+            return provName + "('" + argument + "')";
         } else {
-            return className;
+            return provName;
         }
     }
 
@@ -172,21 +168,33 @@
         if (shouldLoad() == false) {
             return null;
         }
-        if (isLoading) {
-            // because this method is synchronized, this can only
-            // happen if there is recursion.
-            if (debug != null) {
-                debug.println("Recursion loading provider: " + this);
-                new Exception("Call trace").printStackTrace();
+
+        // Create providers which are in java.base directly
+        if (provName.equals("SUN") || provName.equals("sun.security.provider.Sun")) {
+            p = new sun.security.provider.Sun();
+        } else if (provName.equals("SunRsaSign") || provName.equals("sun.security.rsa.SunRsaSign")) {
+            p = new sun.security.rsa.SunRsaSign();
+        } else if (provName.equals("SunJCE") || provName.equals("com.sun.crypto.provider.SunJCE")) {
+            p = new com.sun.crypto.provider.SunJCE();
+        } else if (provName.equals("SunJSSE") || provName.equals("com.sun.net.ssl.internal.ssl.Provider")) {
+            p = new com.sun.net.ssl.internal.ssl.Provider();
+        } else {
+            if (isLoading) {
+                // because this method is synchronized, this can only
+                // happen if there is recursion.
+                if (debug != null) {
+                    debug.println("Recursion loading provider: " + this);
+                    new Exception("Call trace").printStackTrace();
+                }
+                return null;
             }
-            return null;
-        }
-        try {
-            isLoading = true;
-            tries++;
-            p = doLoadProvider();
-        } finally {
-            isLoading = false;
+            try {
+                isLoading = true;
+                tries++;
+                p = doLoadProvider();
+            } finally {
+                isLoading = false;
+            }
         }
         provider = p;
         return p;
@@ -206,55 +214,39 @@
         return AccessController.doPrivileged(new PrivilegedAction<Provider>() {
             public Provider run() {
                 if (debug != null) {
-                    debug.println("Loading provider: " + ProviderConfig.this);
+                    debug.println("Loading provider " + ProviderConfig.this);
                 }
+                ProviderLoader pl = new ProviderLoader();
                 try {
-                    ClassLoader cl = ClassLoader.getSystemClassLoader();
-                    Class<?> provClass;
-                    if (cl != null) {
-                        provClass = cl.loadClass(className);
-                    } else {
-                        provClass = Class.forName(className);
-                    }
-                    Object obj;
-                    if (hasArgument() == false) {
-                        obj = provClass.newInstance();
-                    } else {
-                        Constructor<?> cons = provClass.getConstructor(CL_STRING);
-                        obj = cons.newInstance(argument);
-                    }
-                    if (obj instanceof Provider) {
+                    Provider p = pl.load(provName);
+                    if (p != null) {
+                        if (hasArgument()) {
+                            p = p.configure(argument);
+                        }
                         if (debug != null) {
-                            debug.println("Loaded provider " + obj);
+                            debug.println("Loaded provider " + p.getName());
                         }
-                        return (Provider)obj;
                     } else {
                         if (debug != null) {
-                            debug.println(className + " is not a provider");
+                            debug.println("Error loading provider " +
+                                ProviderConfig.this);
+                        }
+                        disableLoad();
+                    }
+                    return p;
+                } catch (Exception e) {
+                    if (e instanceof ProviderException) {
+                        // pass up
+                        throw e;
+                    } else {
+                        if (debug != null) {
+                            debug.println("Error loading provider " +
+                                ProviderConfig.this);
+                            e.printStackTrace();
                         }
                         disableLoad();
                         return null;
                     }
-                } catch (Exception e) {
-                    Throwable t;
-                    if (e instanceof InvocationTargetException) {
-                        t = ((InvocationTargetException)e).getCause();
-                    } else {
-                        t = e;
-                    }
-                    if (debug != null) {
-                        debug.println("Error loading provider " + ProviderConfig.this);
-                        t.printStackTrace();
-                    }
-                    // provider indicates fatal error, pass through exception
-                    if (t instanceof ProviderException) {
-                        throw (ProviderException)t;
-                    }
-                    // provider indicates that loading should not be retried
-                    if (t instanceof UnsupportedOperationException) {
-                        disableLoad();
-                    }
-                    return null;
                 } catch (ExceptionInInitializerError err) {
                     // no sufficient permission to initialize provider class
                     if (debug != null) {
@@ -289,4 +281,119 @@
         });
     }
 
+    // Inner class for loading security providers listed in java.security file
+    private static final class ProviderLoader {
+        private final ServiceLoader<Provider> services;
+
+        ProviderLoader() {
+            // VM should already been booted at this point, if not
+            // - Only providers in java.base should be loaded, don't use
+            //   ServiceLoader
+            // - ClassLoader.getSystemClassLoader() will throw InternalError
+            services = ServiceLoader.load(java.security.Provider.class,
+                                          ClassLoader.getSystemClassLoader());
+        }
+
+        /**
+         * Loads the provider with the specified class name.
+         *
+         * @param name the name of the provider
+         * @return the Provider, or null if it cannot be found or loaded
+         * @throws ProviderException all other exceptions are ignored
+         */
+        public Provider load(String pn) {
+            if (debug != null) {
+                debug.println("Attempt to load " + pn + " using SL");
+            }
+            Iterator<Provider> iter = services.iterator();
+            while (iter.hasNext()) {
+                try {
+                    Provider p = iter.next();
+                    String pName = p.getName();
+                    if (debug != null) {
+                        debug.println("Found SL Provider named " + pName);
+                    }
+                    if (pName.equals(pn)) {
+                        return p;
+                    }
+                } catch (SecurityException | ServiceConfigurationError |
+                         InvalidParameterException ex) {
+                    // if provider loading fail due to security permission,
+                    // log it and move on to next provider
+                    if (debug != null) {
+                        debug.println("Encountered " + ex +
+                            " while iterating through SL, ignore and move on");
+                            ex.printStackTrace();
+                    }
+                }
+            }
+            // No success with ServiceLoader. Try loading provider the legacy,
+            // i.e. pre-module, way via reflection
+            try {
+                return legacyLoad(pn);
+            } catch (ProviderException pe) {
+                // pass through
+                throw pe;
+            } catch (Exception ex) {
+                // logged and ignored
+                if (debug != null) {
+                    debug.println("Encountered " + ex +
+                        " during legacy load of " + pn);
+                        ex.printStackTrace();
+                }
+                return null;
+            }
+        }
+
+        private Provider legacyLoad(String classname) {
+
+            if (debug != null) {
+                debug.println("Loading legacy provider: " + classname);
+            }
+
+            try {
+                Class<?> provClass =
+                    ClassLoader.getSystemClassLoader().loadClass(classname);
+
+                // only continue if the specified class extends Provider
+                if (!Provider.class.isAssignableFrom(provClass)) {
+                    if (debug != null) {
+                        debug.println(classname + " is not a provider");
+                    }
+                    return null;
+                }
+
+                Provider p = AccessController.doPrivileged
+                    (new PrivilegedExceptionAction<Provider>() {
+                    public Provider run() throws Exception {
+                        return (Provider) provClass.newInstance();
+                    }
+                });
+                return p;
+            } catch (Exception e) {
+                Throwable t;
+                if (e instanceof InvocationTargetException) {
+                    t = ((InvocationTargetException)e).getCause();
+                } else {
+                    t = e;
+                }
+                if (debug != null) {
+                    debug.println("Error loading legacy provider " + classname);
+                    t.printStackTrace();
+                }
+                // provider indicates fatal error, pass through exception
+                if (t instanceof ProviderException) {
+                    throw (ProviderException) t;
+                }
+                return null;
+            } catch (ExceptionInInitializerError | NoClassDefFoundError err) {
+                // no sufficient permission to access/initialize provider class
+                if (debug != null) {
+                    debug.println("Error loading legacy provider " + classname);
+                    err.printStackTrace();
+                }
+                return null;
+            }
+        }
+    }
 }
--- a/jdk/src/java.base/share/classes/sun/security/jca/ProviderList.java	Thu Jun 25 11:59:40 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/jca/ProviderList.java	Fri Jun 26 21:34:34 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -178,9 +178,9 @@
             if (k == -1) {
                 config = new ProviderConfig(entry);
             } else {
-                String className = entry.substring(0, k);
+                String provName = entry.substring(0, k);
                 String argument = entry.substring(k + 1).trim();
-                config = new ProviderConfig(className, argument);
+                config = new ProviderConfig(provName, argument);
             }
 
             // Get rid of duplicate providers.
@@ -200,10 +200,10 @@
      * bootclasspath and cannot be in signed JAR files. This is to avoid
      * possible recursion and deadlock during verification.
      */
-    ProviderList getJarList(String[] jarClassNames) {
+    ProviderList getJarList(String[] jarProvNames) {
         List<ProviderConfig> newConfigs = new ArrayList<>();
-        for (String className : jarClassNames) {
-            ProviderConfig newConfig = new ProviderConfig(className);
+        for (String provName : jarProvNames) {
+            ProviderConfig newConfig = new ProviderConfig(provName);
             for (ProviderConfig config : configs) {
                 // if the equivalent object is present in this provider list,
                 // use the old object rather than the new object.
--- a/jdk/src/java.base/share/classes/sun/security/jca/Providers.java	Thu Jun 25 11:59:40 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/jca/Providers.java	Fri Jun 26 21:34:34 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -58,9 +58,13 @@
         // empty
     }
 
-    // we need special handling to resolve circularities when loading
-    // signed JAR files during startup. The code below is part of that.
-
+    // After the switch to modules, JDK providers are all in modules and JDK
+    // no longer needs to load signed jars during start up.
+    //
+    // However, for earlier releases, it need special handling to resolve
+    // circularities when loading signed JAR files during startup. The code
+    // below is part of that.
+    //
     // Basically, before we load data from a signed JAR file, we parse
     // the PKCS#7 file and verify the signature. We need a
     // CertificateFactory, Signatures, etc. to do that. We have to make
@@ -75,35 +79,24 @@
     // The code here is used by sun.security.util.SignatureFileVerifier.
     // See there for details.
 
-    private static final String BACKUP_PROVIDER_CLASSNAME =
-        "sun.security.provider.VerificationProvider";
-
-    // Hardcoded classnames of providers to use for JAR verification.
+    // Hardcoded names of providers to use for JAR verification.
     // MUST NOT be on the bootclasspath and not in signed JAR files.
     private static final String[] jarVerificationProviders = {
-        "sun.security.provider.Sun",
-        "sun.security.rsa.SunRsaSign",
-        // Note: SunEC *is* in a signed JAR file, but it's not signed
-        // by EC itself. So it's still safe to be listed here.
+        "SUN",
+        "SunRsaSign",
+        // Note: when SunEC is in a signed JAR file, it's not signed
+        // by EC algorithms. So it's still safe to be listed here.
+        // Need to use class name here, otherwise it cannot be loaded for
+        // jar verification. Only those providers in java.base are created
+        // directly by ProviderConfig class.
         "sun.security.ec.SunEC",
-        BACKUP_PROVIDER_CLASSNAME,
     };
 
-    // Return to Sun provider or its backup.
+    // Return Sun provider.
     // This method should only be called by
     // sun.security.util.ManifestEntryVerifier and java.security.SecureRandom.
     public static Provider getSunProvider() {
-        try {
-            Class<?> clazz = Class.forName(jarVerificationProviders[0]);
-            return (Provider)clazz.newInstance();
-        } catch (Exception e) {
-            try {
-                Class<?> clazz = Class.forName(BACKUP_PROVIDER_CLASSNAME);
-                return (Provider)clazz.newInstance();
-            } catch (Exception ee) {
-                throw new RuntimeException("Sun provider not found", e);
-            }
-        }
+        return new sun.security.provider.Sun();
     }
 
     /**
@@ -115,6 +108,16 @@
     public static Object startJarVerification() {
         ProviderList currentList = getProviderList();
         ProviderList jarList = currentList.getJarList(jarVerificationProviders);
+        if (jarList.getProvider("SUN") == null) {
+            // add backup provider
+            Provider p;
+            try {
+                p = new sun.security.provider.VerificationProvider();
+            } catch (Exception e) {
+                throw new RuntimeException("Missing provider for jar verification", e);
+            }
+            ProviderList.add(jarList, p);
+        }
         // return the old thread-local provider list, usually null
         return beginThreadProviderList(jarList);
     }
--- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java	Thu Jun 25 11:59:40 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java	Fri Jun 26 21:34:34 2015 +0000
@@ -728,21 +728,19 @@
                     provClass = Class.forName(provName);
                 }
 
-                String provArg = provider.snd;
-                Object obj;
-                if (provArg == null) {
-                    obj = provClass.newInstance();
-                } else {
-                    Constructor<?> c = provClass.getConstructor(PARAM_STRING);
-                    obj = c.newInstance(provArg);
-                }
+                Object obj = provClass.newInstance();
                 if (!(obj instanceof Provider)) {
                     MessageFormat form = new MessageFormat
                         (rb.getString("provName.not.a.provider"));
                     Object[] source = {provName};
                     throw new Exception(form.format(source));
                 }
-                Security.addProvider((Provider)obj);
+                Provider p = (Provider) obj;
+                String provArg = provider.snd;
+                if (provArg != null) {
+                    p = p.configure(provArg);
+                }
+                Security.addProvider(p);
             }
         }
 
--- a/jdk/src/java.base/share/conf/security/java.security	Thu Jun 25 11:59:40 2015 -0700
+++ b/jdk/src/java.base/share/conf/security/java.security	Fri Jun 26 21:34:34 2015 +0000
@@ -66,7 +66,7 @@
 # List of providers and their preference orders (see above):
 #
 #ifdef solaris
-security.provider.tbd=com.oracle.security.ucrypto.UcryptoProvider ${java.home}/conf/security/ucrypto-solaris.cfg
+security.provider.tbd=com.oracle.security.ucrypto.UcryptoProvider
 security.provider.tbd=sun.security.pkcs11.SunPKCS11 ${java.home}/conf/security/sunpkcs11-solaris.cfg
 #endif
 security.provider.tbd=sun.security.provider.Sun
@@ -79,12 +79,17 @@
 security.provider.tbd=org.jcp.xml.dsig.internal.dom.XMLDSigRI
 security.provider.tbd=sun.security.smartcardio.SunPCSC
 security.provider.tbd=sun.security.provider.certpath.ldap.JdkLDAP
+security.provider.tbd=com.sun.security.sasl.gsskerb.JdkSASL
 #ifdef windows
 security.provider.tbd=sun.security.mscapi.SunMSCAPI
 #endif
 #ifdef macosx
 security.provider.tbd=apple.security.AppleProvider
 #endif
+#ifndef solaris
+security.provider.tbd=sun.security.pkcs11.SunPKCS11
+#endif
+
 
 #
 # Sun Provider SecureRandom seed source.
--- a/jdk/src/java.naming/share/classes/sun/security/provider/certpath/ldap/JdkLDAP.java	Thu Jun 25 11:59:40 2015 -0700
+++ b/jdk/src/java.naming/share/classes/sun/security/provider/certpath/ldap/JdkLDAP.java	Fri Jun 26 21:34:34 2015 +0000
@@ -27,11 +27,7 @@
 
 import java.util.HashMap;
 import java.util.List;
-import java.security.Provider;
-import java.security.NoSuchAlgorithmException;
-import java.security.InvalidParameterException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.ProviderException;
+import java.security.*;
 import java.security.cert.CertStoreParameters;
 
 /**
@@ -75,16 +71,22 @@
     public JdkLDAP() {
         super("JdkLDAP", 1.9d, "JdkLDAP Provider (implements LDAP CertStore)");
 
-        HashMap<String, String> attrs = new HashMap<>(2);
-        attrs.put("LDAPSchema", "RFC2587");
-        attrs.put("ImplementedIn", "Software");
+        final Provider p = this;
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            public Void run() {
+                HashMap<String, String> attrs = new HashMap<>(2);
+                attrs.put("LDAPSchema", "RFC2587");
+                attrs.put("ImplementedIn", "Software");
 
-        /*
-         * CertStore
-         * attrs: LDAPSchema, ImplementedIn
-         */
-        putService(new ProviderService(this, "CertStore",
-            "LDAP", "sun.security.provider.certpath.ldap.LDAPCertStore",
-            null, attrs));
+                /*
+                 * CertStore
+                 * attrs: LDAPSchema, ImplementedIn
+                 */
+                putService(new ProviderService(p, "CertStore",
+                           "LDAP", "sun.security.provider.certpath.ldap.LDAPCertStore",
+                           null, attrs));
+                return null;
+            }
+        });
     }
 }
--- a/jdk/src/java.security.jgss/share/classes/sun/security/jgss/SunProvider.java	Thu Jun 25 11:59:40 2015 -0700
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/jgss/SunProvider.java	Fri Jun 26 21:34:34 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,12 @@
 
 import java.security.Provider;
 import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.NoSuchAlgorithmException;
+import java.security.InvalidParameterException;
+import java.security.ProviderException;
+import sun.security.jgss.krb5.Krb5MechFactory;
+import sun.security.jgss.spnego.SpNegoMechFactory;
 
 /**
  * Defines the Sun JGSS provider.
@@ -58,23 +64,54 @@
         "(Kerberos v5, SPNEGO)";
     //  "(Kerberos v5, Dummy GSS-API Mechanism)";
 
+    private static final class ProviderService extends Provider.Service {
+        ProviderService(Provider p, String type, String algo, String cn) {
+            super(p, type, algo, cn, null, null);
+        }
+
+        @Override
+        public Object newInstance(Object ctrParamObj)
+            throws NoSuchAlgorithmException {
+            String type = getType();
+            if (ctrParamObj != null) {
+                throw new InvalidParameterException
+                    ("constructorParameter not used with " + type +
+                     " engines");
+            }
+            String algo = getAlgorithm();
+            try {
+                if (type.equals("GssApiMechanism")) {
+                    if (algo.equals("1.2.840.113554.1.2.2")) {
+                        return new Krb5MechFactory();
+                    } else if (algo.equals("1.3.6.1.5.5.2")) {
+                        return new SpNegoMechFactory();
+                    }
+                }
+            } catch (Exception ex) {
+                throw new NoSuchAlgorithmException
+                    ("Error constructing " + type + " for " +
+                    algo + " using SunJGSS", ex);
+            }
+            throw new ProviderException("No impl for " + algo +
+                " " + type);
+        }
+    }
+
     public static final SunProvider INSTANCE = new SunProvider();
 
     public SunProvider() {
         /* We are the Sun JGSS provider */
         super("SunJGSS", 1.9d, INFO);
 
-        AccessController.doPrivileged(
-                        new java.security.PrivilegedAction<Void>() {
+        final Provider p = this;
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
             public Void run() {
-                put("GssApiMechanism.1.2.840.113554.1.2.2",
-                    "sun.security.jgss.krb5.Krb5MechFactory");
-                put("GssApiMechanism.1.3.6.1.5.5.2",
-                    "sun.security.jgss.spnego.SpNegoMechFactory");
-                /*
-                  put("GssApiMechanism.1.3.6.1.4.1.42.2.26.1.2",
-                  "sun.security.jgss.dummy.DummyMechFactory");
-                */
+                putService(new ProviderService(p, "GssApiMechanism",
+                           "1.2.840.113554.1.2.2",
+                           "sun.security.jgss.krb5.Krb5MechFactory"));
+                putService(new ProviderService(p, "GssApiMechanism",
+                           "1.3.6.1.5.5.2",
+                           "sun.security.jgss.spnego.SpNegoMechFactory"));
                 return null;
             }
         });
--- a/jdk/src/java.security.sasl/share/classes/com/sun/security/sasl/Provider.java	Thu Jun 25 11:59:40 2015 -0700
+++ b/jdk/src/java.security.sasl/share/classes/com/sun/security/sasl/Provider.java	Fri Jun 26 21:34:34 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,9 @@
 
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.security.NoSuchAlgorithmException;
+import java.security.InvalidParameterException;
+import java.security.ProviderException;
 
 /**
  * The SASL provider.
@@ -34,12 +37,10 @@
  * - PLAIN
  * - CRAM-MD5
  * - DIGEST-MD5
- * - GSSAPI/Kerberos v5
  * - NTLM
  * And server support for
  * - CRAM-MD5
  * - DIGEST-MD5
- * - GSSAPI/Kerberos v5
  * - NTLM
  */
 
@@ -49,38 +50,78 @@
 
     private static final String info = "Sun SASL provider" +
         "(implements client mechanisms for: " +
-        "DIGEST-MD5, GSSAPI, EXTERNAL, PLAIN, CRAM-MD5, NTLM;" +
-        " server mechanisms for: DIGEST-MD5, GSSAPI, CRAM-MD5, NTLM)";
+        "DIGEST-MD5, EXTERNAL, PLAIN, CRAM-MD5, NTLM;" +
+        " server mechanisms for: DIGEST-MD5, CRAM-MD5, NTLM)";
+
+    private static final class ProviderService
+        extends java.security.Provider.Service {
+        ProviderService(java.security.Provider p, String type, String algo,
+            String cn) {
+            super(p, type, algo, cn, null, null);
+        }
+
+        @Override
+        public Object newInstance(Object ctrParamObj)
+            throws NoSuchAlgorithmException {
+            String type = getType();
+            if (ctrParamObj != null) {
+                throw new InvalidParameterException
+                    ("constructorParameter not used with " + type + " engines");
+            }
+
+            String algo = getAlgorithm();
+            try {
+                // DIGEST-MD5, NTLM uses same impl class for client and server
+                if (algo.equals("DIGEST-MD5")) {
+                    return new com.sun.security.sasl.digest.FactoryImpl();
+                }
+                if (algo.equals("NTLM")) {
+                    return new com.sun.security.sasl.ntlm.FactoryImpl();
+                }
+                if (type.equals("SaslClientFactory")) {
+                    if (algo.equals("EXTERNAL") || algo.equals("PLAIN") ||
+                        algo.equals("CRAM-MD5")) {
+                        return new com.sun.security.sasl.ClientFactoryImpl();
+                    }
+                } else if (type.equals("SaslServerFactory")) {
+                    if (algo.equals("CRAM-MD5")) {
+                        return new com.sun.security.sasl.ServerFactoryImpl();
+                    }
+                }
+            } catch (Exception ex) {
+                throw new NoSuchAlgorithmException("Error constructing " +
+                    type + " for " + algo + " using SunSASL", ex);
+            }
+            throw new ProviderException("No impl for " + algo +
+                " " + type);
+        }
+    }
 
     public Provider() {
         super("SunSASL", 1.9d, info);
 
+        final Provider p = this;
         AccessController.doPrivileged(new PrivilegedAction<Void>() {
             public Void run() {
                 // Client mechanisms
-                put("SaslClientFactory.DIGEST-MD5",
-                    "com.sun.security.sasl.digest.FactoryImpl");
-                put("SaslClientFactory.NTLM",
-                    "com.sun.security.sasl.ntlm.FactoryImpl");
-                put("SaslClientFactory.GSSAPI",
-                    "com.sun.security.sasl.gsskerb.FactoryImpl");
-
-                put("SaslClientFactory.EXTERNAL",
-                    "com.sun.security.sasl.ClientFactoryImpl");
-                put("SaslClientFactory.PLAIN",
-                    "com.sun.security.sasl.ClientFactoryImpl");
-                put("SaslClientFactory.CRAM-MD5",
-                    "com.sun.security.sasl.ClientFactoryImpl");
+                putService(new ProviderService(p, "SaslClientFactory",
+                           "DIGEST-MD5", "com.sun.security.sasl.digest.FactoryImpl"));
+                putService(new ProviderService(p, "SaslClientFactory",
+                           "NTLM", "com.sun.security.sasl.ntlm.FactoryImpl"));
+                putService(new ProviderService(p, "SaslClientFactory",
+                           "EXTERNAL", "com.sun.security.sasl.ClientFactoryImpl"));
+                putService(new ProviderService(p, "SaslClientFactory",
+                           "PLAIN", "com.sun.security.sasl.ClientFactoryImpl"));
+                putService(new ProviderService(p, "SaslClientFactory",
+                           "CRAM-MD5", "com.sun.security.sasl.ClientFactoryImpl"));
 
                 // Server mechanisms
-                put("SaslServerFactory.CRAM-MD5",
-                    "com.sun.security.sasl.ServerFactoryImpl");
-                put("SaslServerFactory.GSSAPI",
-                    "com.sun.security.sasl.gsskerb.FactoryImpl");
-                put("SaslServerFactory.DIGEST-MD5",
-                    "com.sun.security.sasl.digest.FactoryImpl");
-                put("SaslServerFactory.NTLM",
-                    "com.sun.security.sasl.ntlm.FactoryImpl");
+                putService(new ProviderService(p, "SaslServerFactory",
+                           "CRAM-MD5", "com.sun.security.sasl.ServerFactoryImpl"));
+                putService(new ProviderService(p, "SaslServerFactory",
+                           "DIGEST-MD5", "com.sun.security.sasl.digest.FactoryImpl"));
+                putService(new ProviderService(p, "SaslServerFactory",
+                           "NTLM", "com.sun.security.sasl.ntlm.FactoryImpl"));
                 return null;
             }
         });
--- a/jdk/src/java.security.sasl/share/classes/javax/security/sasl/Sasl.java	Thu Jun 25 11:59:40 2015 -0700
+++ b/jdk/src/java.security.sasl/share/classes/javax/security/sasl/Sasl.java	Fri Jun 26 21:34:34 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,10 @@
 import java.util.Set;
 import java.util.HashSet;
 import java.util.Collections;
+import java.security.InvalidParameterException;
+import java.security.NoSuchAlgorithmException;
 import java.security.Provider;
+import java.security.Provider.Service;
 import java.security.Security;
 
 /**
@@ -360,7 +363,7 @@
 
         SaslClient mech = null;
         SaslClientFactory fac;
-        String className;
+        Service service;
         String mechName;
 
         for (int i = 0; i < mechanisms.length; i++) {
@@ -370,31 +373,32 @@
             } else if (mechName.length() == 0) {
                 continue;
             }
-            String mechFilter = "SaslClientFactory." + mechName;
-            Provider[] provs = Security.getProviders(mechFilter);
-            for (int j = 0; provs != null && j < provs.length; j++) {
-                className = provs[j].getProperty(mechFilter);
-                if (className == null) {
-                    // Case is ignored
-                    continue;
-                }
+            String type = "SaslClientFactory";
+            Provider[] provs = Security.getProviders(type + "." + mechName);
+            if (provs != null) {
+                for (Provider p : provs) {
+                    service = p.getService(type, mechName);
+                    if (service == null) {
+                        // no such service exists
+                        continue;
+                    }
 
-                fac = (SaslClientFactory) loadFactory(provs[j], className);
-                if (fac != null) {
-                    mech = fac.createSaslClient(
-                        new String[]{mechanisms[i]}, authorizationId,
-                        protocol, serverName, props, cbh);
-                    if (mech != null) {
-                        return mech;
+                    fac = (SaslClientFactory) loadFactory(service);
+                    if (fac != null) {
+                        mech = fac.createSaslClient(
+                            new String[]{mechanisms[i]}, authorizationId,
+                            protocol, serverName, props, cbh);
+                        if (mech != null) {
+                            return mech;
+                        }
                     }
                 }
             }
         }
-
         return null;
     }
 
-    private static Object loadFactory(Provider p, String className)
+    private static Object loadFactory(Service service)
         throws SaslException {
         try {
             /*
@@ -406,18 +410,9 @@
              * have "getClassLoader" permission, or a SecurityException
              * will be thrown.
              */
-            ClassLoader cl = p.getClass().getClassLoader();
-            Class<?> implClass;
-            implClass = Class.forName(className, true, cl);
-            return implClass.newInstance();
-        } catch (ClassNotFoundException e) {
-            throw new SaslException("Cannot load class " + className, e);
-        } catch (InstantiationException e) {
-            throw new SaslException("Cannot instantiate class " + className, e);
-        } catch (IllegalAccessException e) {
-            throw new SaslException("Cannot access class " + className, e);
-        } catch (SecurityException e) {
-            throw new SaslException("Cannot access class " + className, e);
+            return service.newInstance(null);
+        } catch (InvalidParameterException | NoSuchAlgorithmException e) {
+            throw new SaslException("Cannot instantiate service " + service, e);
         }
     }
 
@@ -503,7 +498,7 @@
 
         SaslServer mech = null;
         SaslServerFactory fac;
-        String className;
+        Service service;
 
         if (mechanism == null) {
             throw new NullPointerException("Mechanism name cannot be null");
@@ -511,24 +506,25 @@
             return null;
         }
 
-        String mechFilter = "SaslServerFactory." + mechanism;
-        Provider[] provs = Security.getProviders(mechFilter);
-        for (int j = 0; provs != null && j < provs.length; j++) {
-            className = provs[j].getProperty(mechFilter);
-            if (className == null) {
-                throw new SaslException("Provider does not support " +
-                    mechFilter);
-            }
-            fac = (SaslServerFactory) loadFactory(provs[j], className);
-            if (fac != null) {
-                mech = fac.createSaslServer(
-                    mechanism, protocol, serverName, props, cbh);
-                if (mech != null) {
-                    return mech;
+        String type = "SaslServerFactory";
+        Provider[] provs = Security.getProviders(type + "." + mechanism);
+        if (provs != null) {
+            for (Provider p : provs) {
+                service = p.getService(type, mechanism);
+                if (service == null) {
+                    throw new SaslException("Provider does not support " +
+                        mechanism + " " + type);
+                }
+                fac = (SaslServerFactory) loadFactory(service);
+                if (fac != null) {
+                    mech = fac.createSaslServer(
+                        mechanism, protocol, serverName, props, cbh);
+                    if (mech != null) {
+                        return mech;
+                    }
                 }
             }
         }
-
         return null;
     }
 
@@ -582,36 +578,21 @@
             return result;
         }
 
-
-        Provider[] providers = Security.getProviders();
-        HashSet<String> classes = new HashSet<String>();
+        Provider[] provs = Security.getProviders();
         Object fac;
 
-        for (int i = 0; i < providers.length; i++) {
-            classes.clear();
+        for (Provider p : provs) {
 
-            // Check the keys for each provider.
-            for (Enumeration<Object> e = providers[i].keys(); e.hasMoreElements(); ) {
-                String currentKey = (String)e.nextElement();
-                if (currentKey.startsWith(serviceName)) {
-                    // We should skip the currentKey if it contains a
-                    // whitespace. The reason is: such an entry in the
-                    // provider property contains attributes for the
-                    // implementation of an algorithm. We are only interested
-                    // in entries which lead to the implementation
-                    // classes.
-                    if (currentKey.indexOf(' ') < 0) {
-                        String className = providers[i].getProperty(currentKey);
-                        if (!classes.contains(className)) {
-                            classes.add(className);
-                            try {
-                                fac = loadFactory(providers[i], className);
-                                if (fac != null) {
-                                    result.add(fac);
-                                }
-                            }catch (Exception ignore) {
-                            }
+            Iterator<Service> iter = p.getServices().iterator();
+            while (iter.hasNext()) {
+                Service s = iter.next();
+                if (s.getType().equals(serviceName)) {
+                    try {
+                        fac = loadFactory(s);
+                        if (fac != null) {
+                            result.add(fac);
                         }
+                    } catch (Exception ignore) {
                     }
                 }
             }
--- a/jdk/src/java.smartcardio/share/classes/sun/security/smartcardio/SunPCSC.java	Thu Jun 25 11:59:40 2015 -0700
+++ b/jdk/src/java.smartcardio/share/classes/sun/security/smartcardio/SunPCSC.java	Fri Jun 26 21:34:34 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,11 +39,39 @@
 
     private static final long serialVersionUID = 6168388284028876579L;
 
+    private static final class ProviderService extends Provider.Service {
+
+        ProviderService(Provider p, String type, String algo, String cn) {
+            super(p, type, algo, cn, null, null);
+        }
+
+        @Override
+        public Object newInstance(Object ctrParamObj)
+            throws NoSuchAlgorithmException {
+            String type = getType();
+            String algo = getAlgorithm();
+            try {
+                if (type.equals("TerminalFactory") &&
+                    algo.equals("PC/SC")) {
+                    return new SunPCSC.Factory(ctrParamObj);
+                }
+            } catch (Exception ex) {
+                throw new NoSuchAlgorithmException("Error constructing " +
+                    type + " for " + algo + " using SunPCSC", ex);
+            }
+            throw new ProviderException("No impl for " + algo +
+                " " + type);
+        }
+    }
+
     public SunPCSC() {
         super("SunPCSC", 1.9d, "Sun PC/SC provider");
+
+        final Provider p = this;
         AccessController.doPrivileged(new PrivilegedAction<Void>() {
             public Void run() {
-                put("TerminalFactory.PC/SC", "sun.security.smartcardio.SunPCSC$Factory");
+                putService(new ProviderService(p, "TerminalFactory",
+                           "PC/SC", "sun.security.smartcardio.SunPCSC$Factory"));
                 return null;
             }
         });
--- a/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java	Thu Jun 25 11:59:40 2015 -0700
+++ b/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java	Fri Jun 26 21:34:34 2015 +0000
@@ -28,7 +28,7 @@
  * ===========================================================================
  */
 /*
- * Copyright (c) 2005, 2014 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015 Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * $Id: XMLDSigRI.java 1400021 2012-10-19 10:16:04Z coheigea $
@@ -59,102 +59,156 @@
         "C14N 1.0, C14N 1.1, Exclusive C14N, Base64, Enveloped, XPath, " +
         "XPath2, XSLT TransformServices)";
 
+    private static final class ProviderService extends Provider.Service {
+
+        ProviderService(Provider p, String type, String algo, String cn) {
+            super(p, type, algo, cn, null, null);
+        }
+
+        ProviderService(Provider p, String type, String algo, String cn,
+            String[] aliases) {
+            super(p, type, algo, cn,
+                (aliases == null? null : Arrays.asList(aliases)), null);
+        }
+
+        ProviderService(Provider p, String type, String algo, String cn,
+            String[] aliases, HashMap<String, String> attrs) {
+            super(p, type, algo, cn,
+                  (aliases == null? null : Arrays.asList(aliases)), attrs);
+        }
+
+        @Override
+        public Object newInstance(Object ctrParamObj)
+            throws NoSuchAlgorithmException {
+            String type = getType();
+            if (ctrParamObj != null) {
+                throw new InvalidParameterException
+                    ("constructorParameter not used with " + type + " engines");
+            }
+
+            String algo = getAlgorithm();
+            try {
+                if (type.equals("XMLSignatureFactory")) {
+                    if (algo.equals("DOM")) {
+                        return new DOMXMLSignatureFactory();
+                    }
+                } else if (type.equals("KeyInfoFactory")) {
+                    if (algo.equals("DOM")) {
+                        return new DOMKeyInfoFactory();
+                    }
+                } else if (type.equals("TransformService")) {
+                    if (algo.equals(CanonicalizationMethod.INCLUSIVE) ||
+                        algo.equals(CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS)) {
+                        return new DOMCanonicalXMLC14NMethod();
+                    } else if (algo.equals("http://www.w3.org/2006/12/xml-c14n11") ||
+                        algo.equals("http://www.w3.org/2006/12/xml-c14n11#WithComments")) {
+                        return new DOMCanonicalXMLC14N11Method();
+                    } else if (algo.equals(CanonicalizationMethod.EXCLUSIVE) ||
+                        algo.equals(CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS)) {
+                        return new DOMExcC14NMethod();
+                    } else if (algo.equals(Transform.BASE64)) {
+                        return new DOMBase64Transform();
+                    } else if (algo.equals(Transform.ENVELOPED)) {
+                        return new DOMEnvelopedTransform();
+                    } else if (algo.equals(Transform.XPATH2)) {
+                        return new DOMXPathFilter2Transform();
+                    } else if (algo.equals(Transform.XPATH)) {
+                        return new DOMXPathTransform();
+                    } else if (algo.equals(Transform.XSLT)) {
+                        return new DOMXSLTTransform();
+                    }
+                 }
+            } catch (Exception ex) {
+                throw new NoSuchAlgorithmException("Error constructing " +
+                    type + " for " + algo + " using XMLDSig", ex);
+            }
+            throw new ProviderException("No impl for " + algo +
+                " " + type);
+        }
+    }
+
     public XMLDSigRI() {
         /* We are the XMLDSig provider */
         super("XMLDSig", 1.9d, INFO);
 
-        final Map<Object, Object> map = new HashMap<Object, Object>();
-        map.put("XMLSignatureFactory.DOM",
-                "org.jcp.xml.dsig.internal.dom.DOMXMLSignatureFactory");
-        map.put("KeyInfoFactory.DOM",
-                "org.jcp.xml.dsig.internal.dom.DOMKeyInfoFactory");
+        final Provider p = this;
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            public Void run() {
+                HashMap<String, String> MECH_TYPE = new HashMap<>();
+                MECH_TYPE.put("MechanismType", "DOM");
+
+                putService(new ProviderService(p, "XMLSignatureFactory",
+                    "DOM", "org.jcp.xml.dsig.internal.dom.DOMXMLSignatureFactory"));
+
+                putService(new ProviderService(p, "KeyInfoFactory",
+                    "DOM", "org.jcp.xml.dsig.internal.dom.DOMKeyInfoFactory"));
 
 
-        // Inclusive C14N
-        map.put("TransformService." + CanonicalizationMethod.INCLUSIVE,
-                "org.jcp.xml.dsig.internal.dom.DOMCanonicalXMLC14NMethod");
-        map.put("Alg.Alias.TransformService.INCLUSIVE",
-                CanonicalizationMethod.INCLUSIVE);
-        map.put("TransformService." + CanonicalizationMethod.INCLUSIVE +
-                " MechanismType", "DOM");
+                // Inclusive C14N
+                putService(new ProviderService(p, "TransformService",
+                    CanonicalizationMethod.INCLUSIVE,
+                    "org.jcp.xml.dsig.internal.dom.DOMCanonicalXMLC14NMethod",
+                    new String[] {"INCLUSIVE"}, MECH_TYPE));
 
-        // InclusiveWithComments C14N
-        map.put("TransformService." +
-                CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS,
-                "org.jcp.xml.dsig.internal.dom.DOMCanonicalXMLC14NMethod");
-        map.put("Alg.Alias.TransformService.INCLUSIVE_WITH_COMMENTS",
-                CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS);
-        map.put("TransformService." +
-                CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS +
-                " MechanismType", "DOM");
+                // InclusiveWithComments C14N
+                putService(new ProviderService(p, "TransformService",
+                    CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS,
+                    "org.jcp.xml.dsig.internal.dom.DOMCanonicalXMLC14NMethod",
+                    new String[] {"INCLUSIVE_WITH_COMMENTS"}, MECH_TYPE));
 
-        // Inclusive C14N 1.1
-        map.put("TransformService.http://www.w3.org/2006/12/xml-c14n11",
-                "org.jcp.xml.dsig.internal.dom.DOMCanonicalXMLC14N11Method");
-        map.put("TransformService.http://www.w3.org/2006/12/xml-c14n11" +
-                " MechanismType", "DOM");
+                // Inclusive C14N 1.1
+                putService(new ProviderService(p, "TransformService",
+                    "http://www.w3.org/2006/12/xml-c14n11",
+                    "org.jcp.xml.dsig.internal.dom.DOMCanonicalXMLC14N11Method",
+                    null, MECH_TYPE));
 
-        // InclusiveWithComments C14N 1.1
-        map.put("TransformService.http://www.w3.org/2006/12/xml-c14n11#WithComments",
-                "org.jcp.xml.dsig.internal.dom.DOMCanonicalXMLC14N11Method");
-        map.put("TransformService.http://www.w3.org/2006/12/xml-c14n11#WithComments" +
-                " MechanismType", "DOM");
+                // InclusiveWithComments C14N 1.1
+                putService(new ProviderService(p, "TransformService",
+                    "http://www.w3.org/2006/12/xml-c14n11#WithComments",
+                    "org.jcp.xml.dsig.internal.dom.DOMCanonicalXMLC14N11Method",
+                    null, MECH_TYPE));
 
-        // Exclusive C14N
-        map.put("TransformService." + CanonicalizationMethod.EXCLUSIVE,
-                "org.jcp.xml.dsig.internal.dom.DOMExcC14NMethod");
-        map.put("Alg.Alias.TransformService.EXCLUSIVE",
-                CanonicalizationMethod.EXCLUSIVE);
-        map.put("TransformService." + CanonicalizationMethod.EXCLUSIVE +
-                " MechanismType", "DOM");
+                // Exclusive C14N
+                putService(new ProviderService(p, "TransformService",
+                    CanonicalizationMethod.EXCLUSIVE,
+                    "org.jcp.xml.dsig.internal.dom.DOMExcC14NMethod",
+                    new String[] {"EXCLUSIVE"}, MECH_TYPE));
 
-        // ExclusiveWithComments C14N
-        map.put("TransformService." +
-                CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS,
-                "org.jcp.xml.dsig.internal.dom.DOMExcC14NMethod");
-        map.put("Alg.Alias.TransformService.EXCLUSIVE_WITH_COMMENTS",
-                CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS);
-        map.put("TransformService." +
-                CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS +
-                " MechanismType", "DOM");
+                // ExclusiveWithComments C14N
+                putService(new ProviderService(p, "TransformService",
+                    CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS,
+                    "org.jcp.xml.dsig.internal.dom.DOMExcC14NMethod",
+                    new String[] {"EXCLUSIVE_WITH_COMMENTS"}, MECH_TYPE));
 
-        // Base64 Transform
-        map.put("TransformService." + Transform.BASE64,
-                "org.jcp.xml.dsig.internal.dom.DOMBase64Transform");
-        map.put("Alg.Alias.TransformService.BASE64", Transform.BASE64);
-        map.put("TransformService." + Transform.BASE64 +
-                " MechanismType", "DOM");
+                // Base64 Transform
+                putService(new ProviderService(p, "TransformService",
+                    Transform.BASE64,
+                    "org.jcp.xml.dsig.internal.dom.DOMBase64Transform",
+                    new String[] {"BASE64"}, MECH_TYPE));
 
-        // Enveloped Transform
-        map.put("TransformService." + Transform.ENVELOPED,
-                "org.jcp.xml.dsig.internal.dom.DOMEnvelopedTransform");
-        map.put("Alg.Alias.TransformService.ENVELOPED", Transform.ENVELOPED);
-        map.put("TransformService." + Transform.ENVELOPED +
-                " MechanismType", "DOM");
+                // Enveloped Transform
+                putService(new ProviderService(p, "TransformService",
+                    Transform.ENVELOPED,
+                    "org.jcp.xml.dsig.internal.dom.DOMEnvelopedTransform",
+                    new String[] {"ENVELOPED"}, MECH_TYPE));
 
-        // XPath2 Transform
-        map.put("TransformService." + Transform.XPATH2,
-                "org.jcp.xml.dsig.internal.dom.DOMXPathFilter2Transform");
-        map.put("Alg.Alias.TransformService.XPATH2", Transform.XPATH2);
-        map.put("TransformService." + Transform.XPATH2 +
-                " MechanismType", "DOM");
+                // XPath2 Transform
+                putService(new ProviderService(p, "TransformService",
+                    Transform.XPATH2,
+                    "org.jcp.xml.dsig.internal.dom.DOMXPathFilter2Transform",
+                    new String[] {"XPATH2"}, MECH_TYPE));
 
-        // XPath Transform
-        map.put("TransformService." + Transform.XPATH,
-                "org.jcp.xml.dsig.internal.dom.DOMXPathTransform");
-        map.put("Alg.Alias.TransformService.XPATH", Transform.XPATH);
-        map.put("TransformService." + Transform.XPATH +
-                " MechanismType", "DOM");
+                // XPath Transform
+                putService(new ProviderService(p, "TransformService",
+                    Transform.XPATH,
+                    "org.jcp.xml.dsig.internal.dom.DOMXPathTransform",
+                    new String[] {"XPATH"}, MECH_TYPE));
 
-        // XSLT Transform
-        map.put("TransformService." + Transform.XSLT,
-                "org.jcp.xml.dsig.internal.dom.DOMXSLTTransform");
-        map.put("Alg.Alias.TransformService.XSLT", Transform.XSLT);
-        map.put("TransformService." + Transform.XSLT + " MechanismType", "DOM");
-
-        AccessController.doPrivileged(new PrivilegedAction<Void>() {
-            public Void run() {
-                putAll(map);
+                // XSLT Transform
+                putService(new ProviderService(p, "TransformService",
+                    Transform.XSLT,
+                    "org.jcp.xml.dsig.internal.dom.DOMXSLTTransform",
+                    new String[] {"XSLT"}, MECH_TYPE));
                 return null;
             }
         });
--- a/jdk/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java	Thu Jun 25 11:59:40 2015 -0700
+++ b/jdk/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java	Fri Jun 26 21:34:34 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,10 @@
 
 import java.util.*;
 import java.security.*;
-import sun.security.action.PutAllAction;
+import java.util.regex.Pattern;
+import sun.security.util.CurveDB;
+import sun.security.util.NamedCurve;
+import sun.security.util.ECParameters;
 
 /**
  * Provider class for the Elliptic Curve provider.
@@ -65,19 +68,206 @@
         }
     }
 
-    public SunEC() {
-        super("SunEC", 1.9d, "Sun Elliptic Curve provider (EC, ECDSA, ECDH)");
+    private static class ProviderService extends Provider.Service {
+
+        ProviderService(Provider p, String type, String algo, String cn) {
+            super(p, type, algo, cn, null, null);
+        }
+
+        ProviderService(Provider p, String type, String algo, String cn,
+            String[] aliases, HashMap<String, String> attrs) {
+            super(p, type, algo, cn,
+                  (aliases == null? null : Arrays.asList(aliases)), attrs);
+        }
+
+        @Override
+        public Object newInstance(Object ctrParamObj)
+            throws NoSuchAlgorithmException {
+            String type = getType();
+            if (ctrParamObj != null) {
+                throw new InvalidParameterException
+                    ("constructorParameter not used with " + type + " engines");
+            }
 
-        // if there is no security manager installed, put directly into
-        // the provider. Otherwise, create a temporary map and use a
-        // doPrivileged() call at the end to transfer the contents
-        if (System.getSecurityManager() == null) {
-            SunECEntries.putEntries(this, useFullImplementation);
-        } else {
-            Map<Object, Object> map = new HashMap<Object, Object>();
-            SunECEntries.putEntries(map, useFullImplementation);
-            AccessController.doPrivileged(new PutAllAction(this, map));
+            String algo = getAlgorithm();
+            try {
+                if (type.equals("Signature")) {
+                    boolean inP1363 = algo.endsWith("inP1363Format");
+                    if (inP1363) {
+                        algo = algo.substring(0, algo.length() - 13);
+                    }
+                    if (algo.equals("SHA1withECDSA")) {
+                        return (inP1363? new ECDSASignature.SHA1inP1363Format() :
+                            new ECDSASignature.SHA1());
+                    } else if (algo.equals("SHA224withECDSA")) {
+                        return (inP1363? new ECDSASignature.SHA224inP1363Format() :
+                            new ECDSASignature.SHA224());
+                    } else if (algo.equals("SHA256withECDSA")) {
+                        return (inP1363? new ECDSASignature.SHA256inP1363Format() :
+                            new ECDSASignature.SHA256());
+                    } else if (algo.equals("SHA384withECDSA")) {
+                        return (inP1363? new ECDSASignature.SHA384inP1363Format() :
+                            new ECDSASignature.SHA384());
+                    } else if (algo.equals("SHA512withECDSA")) {
+                        return (inP1363? new ECDSASignature.SHA512inP1363Format() :
+                            new ECDSASignature.SHA512());
+                    } else if (algo.equals("NONEwithECDSA")) {
+                        return (inP1363? new ECDSASignature.RawinP1363Format() :
+                            new ECDSASignature.Raw());
+                    }
+                } else  if (type.equals("KeyFactory")) {
+                    if (algo.equals("EC")) {
+                        return new ECKeyFactory();
+                    }
+                } else  if (type.equals("AlgorithmParameters")) {
+                    if (algo.equals("EC")) {
+                        return new sun.security.util.ECParameters();
+                    }
+                } else  if (type.equals("KeyPairGenerator")) {
+                    if (algo.equals("EC")) {
+                        return new ECKeyPairGenerator();
+                    }
+                } else  if (type.equals("KeyAgreement")) {
+                    if (algo.equals("ECDH")) {
+                        return new ECDHKeyAgreement();
+                    }
+                }
+            } catch (Exception ex) {
+                throw new NoSuchAlgorithmException("Error constructing " +
+                    type + " for " + algo + " using SunEC", ex);
+            }
+            throw new ProviderException("No impl for " + algo +
+                " " + type);
         }
     }
 
+    public SunEC() {
+        super("SunEC", 1.9d, "Sun Elliptic Curve provider (EC, ECDSA, ECDH)");
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            public Void run() {
+                putEntries(useFullImplementation);
+                return null;
+            }
+        });
+    }
+
+    void putEntries(boolean useFullImplementation) {
+        HashMap<String, String> ATTRS = new HashMap<>(3);
+        ATTRS.put("ImplementedIn", "Software");
+        String ecKeyClasses = "java.security.interfaces.ECPublicKey" +
+                 "|java.security.interfaces.ECPrivateKey";
+        ATTRS.put("SupportedKeyClasses", ecKeyClasses);
+        ATTRS.put("KeySize", "256");
+
+        /*
+         *  Key Factory engine
+         */
+        putService(new ProviderService(this, "KeyFactory",
+            "EC", "sun.security.ec.ECKeyFactory",
+            new String[] { "EllipticCurve" }, ATTRS));
+
+        /*
+         * Algorithm Parameter engine
+         */
+        // "AlgorithmParameters.EC SupportedCurves" prop used by unit test
+        boolean firstCurve = true;
+        StringBuilder names = new StringBuilder();
+        Pattern nameSplitPattern = Pattern.compile(CurveDB.SPLIT_PATTERN);
+
+        Collection<? extends NamedCurve> supportedCurves =
+            CurveDB.getSupportedCurves();
+        for (NamedCurve namedCurve : supportedCurves) {
+            if (!firstCurve) {
+                names.append("|");
+            } else {
+                firstCurve = false;
+            }
+
+            names.append("[");
+
+            String[] commonNames = nameSplitPattern.split(namedCurve.getName());
+            for (String commonName : commonNames) {
+                names.append(commonName.trim());
+                names.append(",");
+            }
+
+            names.append(namedCurve.getObjectId());
+            names.append("]");
+        }
+
+        HashMap<String, String> apAttrs = new HashMap<>(ATTRS);
+        apAttrs.put("SupportedCurves", names.toString());
+
+        putService(new ProviderService(this, "AlgorithmParameters",
+            "EC", "sun.security.util.ECParameters",
+            new String[] { "EllipticCurve", "1.2.840.10045.2.1", "OID.1.2.840.10045.2.1" },
+            apAttrs));
+
+        /*
+         * Register the algorithms below only when the full ECC implementation
+         * is available
+         */
+        if (!useFullImplementation) {
+            return;
+        }
+
+        /*
+         * Signature engines
+         */
+        putService(new ProviderService(this, "Signature",
+            "NONEwithECDSA", "sun.security.ec.ECDSASignature$Raw",
+            null, ATTRS));
+        putService(new ProviderService(this, "Signature",
+            "SHA1withECDSA", "sun.security.ec.ECDSASignature$SHA1",
+            new String[] { "1.2.840.10045.4.1", "OID.1.2.840.10045.4.1" },
+            ATTRS));
+        putService(new ProviderService(this, "Signature",
+            "SHA224withECDSA", "sun.security.ec.ECDSASignature$SHA224",
+            new String[] { "1.2.840.10045.4.3.1", "OID.1.2.840.10045.4.3.1"},
+            ATTRS));
+        putService(new ProviderService(this, "Signature",
+            "SHA256withECDSA", "sun.security.ec.ECDSASignature$SHA256",
+            new String[] { "1.2.840.10045.4.3.2", "OID.1.2.840.10045.4.3.2"},
+            ATTRS));
+        putService(new ProviderService(this, "Signature",
+            "SHA384withECDSA", "sun.security.ec.ECDSASignature$SHA384",
+            new String[] { "1.2.840.10045.4.3.3", "OID.1.2.840.10045.4.3.3" },
+            ATTRS));
+        putService(new ProviderService(this, "Signature",
+            "SHA512withECDSA", "sun.security.ec.ECDSASignature$SHA512",
+            new String[] { "1.2.840.10045.4.3.4", "OID.1.2.840.10045.4.3.4" },
+            ATTRS));
+
+        putService(new ProviderService(this, "Signature",
+             "NONEwithECDSAinP1363Format",
+             "sun.security.ec.ECDSASignature$RawinP1363Format"));
+        putService(new ProviderService(this, "Signature",
+             "SHA1withECDSAinP1363Format",
+             "sun.security.ec.ECDSASignature$SHA1inP1363Format"));
+        putService(new ProviderService(this, "Signature",
+             "SHA224withECDSAinP1363Format",
+             "sun.security.ec.ECDSASignature$SHA224inP1363Format"));
+        putService(new ProviderService(this, "Signature",
+             "SHA256withECDSAinP1363Format",
+             "sun.security.ec.ECDSASignature$SHA256inP1363Format"));
+        putService(new ProviderService(this, "Signature",
+            "SHA384withECDSAinP1363Format",
+            "sun.security.ec.ECDSASignature$SHA384inP1363Format"));
+        putService(new ProviderService(this, "Signature",
+            "SHA512withECDSAinP1363Format",
+            "sun.security.ec.ECDSASignature$SHA512inP1363Format"));
+
+        /*
+         *  Key Pair Generator engine
+         */
+        putService(new ProviderService(this, "KeyPairGenerator",
+            "EC", "sun.security.ec.ECKeyPairGenerator",
+            new String[] { "EllipticCurve" }, ATTRS));
+
+        /*
+         * Key Agreement engine
+         */
+        putService(new ProviderService(this, "KeyAgreement",
+            "ECDH", "sun.security.ec.ECDHKeyAgreement", null, ATTRS));
+    }
 }
--- a/jdk/src/jdk.crypto.ec/share/classes/sun/security/ec/SunECEntries.java	Thu Jun 25 11:59:40 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,184 +0,0 @@
-/*
- * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.ec;
-
-import java.util.Collection;
-import java.util.Map;
-
-import java.util.regex.Pattern;
-import sun.security.util.CurveDB;
-import sun.security.util.NamedCurve;
-
-/**
- * Defines the entries of the SunEC provider.
- *
- * @since 1.7
- */
-final class SunECEntries {
-
-    private SunECEntries() {
-        // empty
-    }
-
-    static void putEntries(Map<Object, Object> map,
-        boolean useFullImplementation) {
-
-        /*
-         *  Key Factory engine
-         */
-        map.put("KeyFactory.EC", "sun.security.ec.ECKeyFactory");
-        map.put("Alg.Alias.KeyFactory.EllipticCurve", "EC");
-
-        map.put("KeyFactory.EC ImplementedIn", "Software");
-
-        /*
-         * Algorithm Parameter engine
-         */
-        map.put("AlgorithmParameters.EC", "sun.security.util.ECParameters");
-        map.put("Alg.Alias.AlgorithmParameters.EllipticCurve", "EC");
-        map.put("Alg.Alias.AlgorithmParameters.1.2.840.10045.2.1", "EC");
-
-        map.put("AlgorithmParameters.EC KeySize", "256");
-
-        map.put("AlgorithmParameters.EC ImplementedIn", "Software");
-
-        // "AlgorithmParameters.EC SupportedCurves" prop used by unit test
-        boolean firstCurve = true;
-        StringBuilder names = new StringBuilder();
-        Pattern nameSplitPattern = Pattern.compile(CurveDB.SPLIT_PATTERN);
-
-        Collection<? extends NamedCurve> supportedCurves =
-            CurveDB.getSupportedCurves();
-        for (NamedCurve namedCurve : supportedCurves) {
-            if (!firstCurve) {
-                names.append("|");
-            } else {
-                firstCurve = false;
-            }
-
-            names.append("[");
-
-            String[] commonNames = nameSplitPattern.split(namedCurve.getName());
-            for (String commonName : commonNames) {
-                names.append(commonName.trim());
-                names.append(",");
-            }
-
-            names.append(namedCurve.getObjectId());
-            names.append("]");
-        }
-
-        map.put("AlgorithmParameters.EC SupportedCurves", names.toString());
-
-        /*
-         * Register the algorithms below only when the full ECC implementation
-         * is available
-         */
-        if (!useFullImplementation) {
-            return;
-        }
-
-        /*
-         * Signature engines
-         */
-        map.put("Signature.NONEwithECDSA",
-            "sun.security.ec.ECDSASignature$Raw");
-        map.put("Signature.SHA1withECDSA",
-            "sun.security.ec.ECDSASignature$SHA1");
-        map.put("Alg.Alias.Signature.OID.1.2.840.10045.4.1", "SHA1withECDSA");
-        map.put("Alg.Alias.Signature.1.2.840.10045.4.1", "SHA1withECDSA");
-
-        map.put("Signature.SHA224withECDSA",
-            "sun.security.ec.ECDSASignature$SHA224");
-        map.put("Alg.Alias.Signature.OID.1.2.840.10045.4.3.1", "SHA224withECDSA");
-        map.put("Alg.Alias.Signature.1.2.840.10045.4.3.1", "SHA224withECDSA");
-
-        map.put("Signature.SHA256withECDSA",
-            "sun.security.ec.ECDSASignature$SHA256");
-        map.put("Alg.Alias.Signature.OID.1.2.840.10045.4.3.2", "SHA256withECDSA");
-        map.put("Alg.Alias.Signature.1.2.840.10045.4.3.2", "SHA256withECDSA");
-
-        map.put("Signature.SHA384withECDSA",
-            "sun.security.ec.ECDSASignature$SHA384");
-        map.put("Alg.Alias.Signature.OID.1.2.840.10045.4.3.3", "SHA384withECDSA");
-        map.put("Alg.Alias.Signature.1.2.840.10045.4.3.3", "SHA384withECDSA");
-
-        map.put("Signature.SHA512withECDSA",
-            "sun.security.ec.ECDSASignature$SHA512");
-        map.put("Alg.Alias.Signature.OID.1.2.840.10045.4.3.4", "SHA512withECDSA");
-        map.put("Alg.Alias.Signature.1.2.840.10045.4.3.4", "SHA512withECDSA");
-
-        map.put("Signature.NONEwithECDSAinP1363Format",
-            "sun.security.ec.ECDSASignature$RawinP1363Format");
-        map.put("Signature.SHA1withECDSAinP1363Format",
-            "sun.security.ec.ECDSASignature$SHA1inP1363Format");
-        map.put("Signature.SHA224withECDSAinP1363Format",
-            "sun.security.ec.ECDSASignature$SHA224inP1363Format");
-        map.put("Signature.SHA256withECDSAinP1363Format",
-            "sun.security.ec.ECDSASignature$SHA256inP1363Format");
-        map.put("Signature.SHA384withECDSAinP1363Format",
-            "sun.security.ec.ECDSASignature$SHA384inP1363Format");
-        map.put("Signature.SHA512withECDSAinP1363Format",
-            "sun.security.ec.ECDSASignature$SHA512inP1363Format");
-
-        String ecKeyClasses = "java.security.interfaces.ECPublicKey" +
-                "|java.security.interfaces.ECPrivateKey";
-        map.put("Signature.NONEwithECDSA SupportedKeyClasses", ecKeyClasses);
-        map.put("Signature.SHA1withECDSA SupportedKeyClasses", ecKeyClasses);
-        map.put("Signature.SHA224withECDSA SupportedKeyClasses", ecKeyClasses);
-        map.put("Signature.SHA256withECDSA SupportedKeyClasses", ecKeyClasses);
-        map.put("Signature.SHA384withECDSA SupportedKeyClasses", ecKeyClasses);
-        map.put("Signature.SHA512withECDSA SupportedKeyClasses", ecKeyClasses);
-
-        map.put("Signature.SHA1withECDSA KeySize", "256");
-
-        map.put("Signature.NONEwithECDSA ImplementedIn", "Software");
-        map.put("Signature.SHA1withECDSA ImplementedIn", "Software");
-        map.put("Signature.SHA224withECDSA ImplementedIn", "Software");
-        map.put("Signature.SHA256withECDSA ImplementedIn", "Software");
-        map.put("Signature.SHA384withECDSA ImplementedIn", "Software");
-        map.put("Signature.SHA512withECDSA ImplementedIn", "Software");
-
-        /*
-         *  Key Pair Generator engine
-         */
-        map.put("KeyPairGenerator.EC", "sun.security.ec.ECKeyPairGenerator");
-        map.put("Alg.Alias.KeyPairGenerator.EllipticCurve", "EC");
-
-        map.put("KeyPairGenerator.EC KeySize", "256");
-
-        map.put("KeyPairGenerator.EC ImplementedIn", "Software");
-
-        /*
-         * Key Agreement engine
-         */
-        map.put("KeyAgreement.ECDH", "sun.security.ec.ECDHKeyAgreement");
-
-        map.put("KeyAgreement.ECDH SupportedKeyClasses", ecKeyClasses);
-
-        map.put("KeyAgreement.ECDH ImplementedIn", "Software");
-    }
-}
--- a/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/SunMSCAPI.java	Thu Jun 25 11:59:40 2015 -0700
+++ b/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/SunMSCAPI.java	Fri Jun 26 21:34:34 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,8 +28,11 @@
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.security.Provider;
+import java.security.NoSuchAlgorithmException;
+import java.security.InvalidParameterException;
+import java.security.ProviderException;
 import java.util.HashMap;
-import java.util.Map;
+import java.util.Arrays;
 
 /**
  * A Cryptographic Service Provider for the Microsoft Crypto API.
@@ -52,97 +55,153 @@
         });
     }
 
+    private static final class ProviderService extends Provider.Service {
+        ProviderService(Provider p, String type, String algo, String cn) {
+            super(p, type, algo, cn, null, null);
+        }
+
+        ProviderService(Provider p, String type, String algo, String cn,
+            String[] aliases, HashMap<String, String> attrs) {
+            super(p, type, algo, cn,
+                  (aliases == null? null : Arrays.asList(aliases)), attrs);
+        }
+
+        @Override
+        public Object newInstance(Object ctrParamObj)
+            throws NoSuchAlgorithmException {
+            String type = getType();
+            if (ctrParamObj != null) {
+                throw new InvalidParameterException
+                    ("constructorParameter not used with " + type +
+                     " engines");
+            }
+            String algo = getAlgorithm();
+            try {
+                if (type.equals("SecureRandom")) {
+                    if (algo.equals("Windows-PRNG")) {
+                        return new PRNG();
+                    }
+                } else if (type.equals("KeyStore")) {
+                    if (algo.equals("Windows-MY")) {
+                        return new KeyStore.MY();
+                    } else if (algo.equals("Windows-ROOT")) {
+                        return new KeyStore.ROOT();
+                    }
+                } else if (type.equals("Signature")) {
+                    if (algo.equals("NONEwithRSA")) {
+                        return new RSASignature.Raw();
+                    } else if (algo.equals("SHA1withRSA")) {
+                        return new RSASignature.SHA1();
+                    } else if (algo.equals("SHA256withRSA")) {
+                        return new RSASignature.SHA256();
+                    } else if (algo.equals("SHA384withRSA")) {
+                        return new RSASignature.SHA384();
+                    } else if (algo.equals("SHA512withRSA")) {
+                        return new RSASignature.SHA512();
+                    } else if (algo.equals("MD5withRSA")) {
+                        return new RSASignature.MD5();
+                    } else if (algo.equals("MD2withRSA")) {
+                        return new RSASignature.MD2();
+                    }
+                } else if (type.equals("KeyPairGenerator")) {
+                    if (algo.equals("RSA")) {
+                        return new RSAKeyPairGenerator();
+                    }
+                } else if (type.equals("Cipher")) {
+                    if (algo.equals("RSA") ||
+                        algo.equals("RSA/ECB/PKCS1Padding")) {
+                        return new RSACipher();
+                    }
+                }
+            } catch (Exception ex) {
+                throw new NoSuchAlgorithmException
+                    ("Error constructing " + type + " for " +
+                    algo + " using SunMSCAPI", ex);
+            }
+            throw new ProviderException("No impl for " + algo +
+                " " + type);
+        }
+    }
+
     public SunMSCAPI() {
         super("SunMSCAPI", 1.9d, INFO);
 
-        // if there is no security manager installed, put directly into
-        // the provider. Otherwise, create a temporary map and use a
-        // doPrivileged() call at the end to transfer the contents
-        final Map<Object, Object> map =
-                (System.getSecurityManager() == null)
-                ? this : new HashMap<Object, Object>();
-
-        /*
-         * Secure random
-         */
-        map.put("SecureRandom.Windows-PRNG", "sun.security.mscapi.PRNG");
-
-        /*
-         * Key store
-         */
-        map.put("KeyStore.Windows-MY", "sun.security.mscapi.KeyStore$MY");
-        map.put("KeyStore.Windows-ROOT", "sun.security.mscapi.KeyStore$ROOT");
+        final Provider p = this;
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            public Void run() {
+                /*
+                 * Secure random
+                 */
+                putService(new ProviderService(p, "SecureRandom",
+                           "Windows-PRNG", "sun.security.mscapi.PRNG"));
 
-        /*
-         * Signature engines
-         */
-        // NONEwithRSA must be supplied with a pre-computed message digest.
-        // Only the following digest algorithms are supported: MD5, SHA-1,
-        // SHA-256, SHA-384, SHA-512 and a special-purpose digest
-        // algorithm which is a concatenation of SHA-1 and MD5 digests.
-        map.put("Signature.NONEwithRSA",
-            "sun.security.mscapi.RSASignature$Raw");
-        map.put("Signature.SHA1withRSA",
-            "sun.security.mscapi.RSASignature$SHA1");
-        map.put("Signature.SHA256withRSA",
-            "sun.security.mscapi.RSASignature$SHA256");
-        map.put("Alg.Alias.Signature.1.2.840.113549.1.1.11",     "SHA256withRSA");
-        map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.11", "SHA256withRSA");
-        map.put("Signature.SHA384withRSA",
-            "sun.security.mscapi.RSASignature$SHA384");
-        map.put("Alg.Alias.Signature.1.2.840.113549.1.1.12",     "SHA384withRSA");
-        map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.12", "SHA384withRSA");
+                /*
+                 * Key store
+                 */
+                putService(new ProviderService(p, "KeyStore",
+                           "Windows-MY", "sun.security.mscapi.KeyStore$MY"));
+                putService(new ProviderService(p, "KeyStore",
+                           "Windows-ROOT", "sun.security.mscapi.KeyStore$ROOT"));
 
-        map.put("Signature.SHA512withRSA",
-            "sun.security.mscapi.RSASignature$SHA512");
-        map.put("Alg.Alias.Signature.1.2.840.113549.1.1.13",     "SHA512withRSA");
-        map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.13", "SHA512withRSA");
+                /*
+                 * Signature engines
+                 */
+                HashMap<String, String> attrs = new HashMap<>(1);
+                attrs.put("SupportedKeyClasses", "sun.security.mscapi.Key");
 
-        map.put("Signature.MD5withRSA",
-            "sun.security.mscapi.RSASignature$MD5");
-        map.put("Signature.MD2withRSA",
-            "sun.security.mscapi.RSASignature$MD2");
-
-        // supported key classes
-        map.put("Signature.NONEwithRSA SupportedKeyClasses",
-            "sun.security.mscapi.Key");
-        map.put("Signature.SHA1withRSA SupportedKeyClasses",
-            "sun.security.mscapi.Key");
-        map.put("Signature.SHA256withRSA SupportedKeyClasses",
-            "sun.security.mscapi.Key");
-        map.put("Signature.SHA384withRSA SupportedKeyClasses",
-            "sun.security.mscapi.Key");
-        map.put("Signature.SHA512withRSA SupportedKeyClasses",
-            "sun.security.mscapi.Key");
-        map.put("Signature.MD5withRSA SupportedKeyClasses",
-            "sun.security.mscapi.Key");
-        map.put("Signature.MD2withRSA SupportedKeyClasses",
-            "sun.security.mscapi.Key");
+                // NONEwithRSA must be supplied with a pre-computed message digest.
+                // Only the following digest algorithms are supported: MD5, SHA-1,
+                // SHA-256, SHA-384, SHA-512 and a special-purpose digest
+                // algorithm which is a concatenation of SHA-1 and MD5 digests.
+                putService(new ProviderService(p, "Signature",
+                           "NONEwithRSA", "sun.security.mscapi.RSASignature$Raw",
+                           null, attrs));
+                putService(new ProviderService(p, "Signature",
+                           "SHA1withRSA", "sun.security.mscapi.RSASignature$SHA1",
+                           null, attrs));
+                putService(new ProviderService(p, "Signature",
+                           "SHA256withRSA", "sun.security.mscapi.RSASignature$SHA256",
+                           new String[] { "1.2.840.113549.1.1.11", "OID.1.2.840.113549.1.1.11" },
+                           attrs));
+                putService(new ProviderService(p, "Signature",
+                           "SHA384withRSA", "sun.security.mscapi.RSASignature$SHA384",
+                           new String[] { "1.2.840.113549.1.1.12", "OID.1.2.840.113549.1.1.12" },
+                           attrs));
+                putService(new ProviderService(p, "Signature",
+                           "SHA512withRSA", "sun.security.mscapi.RSASignature$SHA512",
+                           new String[] { "1.2.840.113549.1.1.13", "OID.1.2.840.113549.1.1.13" },
+                           attrs));
+                putService(new ProviderService(p, "Signature",
+                           "MD5withRSA", "sun.security.mscapi.RSASignature$MD5",
+                           null, attrs));
+                putService(new ProviderService(p, "Signature",
+                           "MD2withRSA", "sun.security.mscapi.RSASignature$MD2",
+                           null, attrs));
 
-        /*
-         * Key Pair Generator engines
-         */
-        map.put("KeyPairGenerator.RSA",
-            "sun.security.mscapi.RSAKeyPairGenerator");
-        map.put("KeyPairGenerator.RSA KeySize", "1024");
+                /*
+                 * Key Pair Generator engines
+                 */
+                attrs.clear();
+                attrs.put("KeySize", "1024");
+                putService(new ProviderService(p, "KeyPairGenerator",
+                           "RSA", "sun.security.mscapi.RSAKeyPairGenerator",
+                           null, attrs));
 
-        /*
-         * Cipher engines
-         */
-        map.put("Cipher.RSA", "sun.security.mscapi.RSACipher");
-        map.put("Cipher.RSA/ECB/PKCS1Padding",
-            "sun.security.mscapi.RSACipher");
-        map.put("Cipher.RSA SupportedModes", "ECB");
-        map.put("Cipher.RSA SupportedPaddings", "PKCS1PADDING");
-        map.put("Cipher.RSA SupportedKeyClasses", "sun.security.mscapi.Key");
-
-        if (map != this) {
-            final Provider provider = this;
-            PrivilegedAction<Void> putAllAction = () -> {
-                provider.putAll(map);
+                /*
+                 * Cipher engines
+                 */
+                attrs.clear();
+                attrs.put("SupportedModes", "ECB");
+                attrs.put("SupportedPaddings", "PKCS1PADDING");
+                attrs.put("SupportedKeyClasses", "sun.security.mscapi.Key");
+                putService(new ProviderService(p, "Cipher",
+                           "RSA", "sun.security.mscapi.RSACipher",
+                           null, attrs));
+                putService(new ProviderService(p, "Cipher",
+                           "RSA/ECB/PKCS1Padding", "sun.security.mscapi.RSACipher",
+                           null, attrs));
                 return null;
-            };
-            AccessController.doPrivileged(putAllAction);
-        }
+            }
+        });
     }
 }
--- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/Config.java	Thu Jun 25 11:59:40 2015 -0700
+++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/Config.java	Fri Jun 26 21:34:34 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -69,30 +69,6 @@
         }
     }
 
-    // temporary storage for configurations
-    // needed because the SunPKCS11 needs to call the superclass constructor
-    // in provider before accessing any instance variables
-    private final static Map<String,Config> configMap =
-                                        new HashMap<String,Config>();
-
-    static Config getConfig(final String name, final InputStream stream) {
-        Config config = configMap.get(name);
-        if (config != null) {
-            return config;
-        }
-        try {
-            config = new Config(name, stream);
-            configMap.put(name, config);
-            return config;
-        } catch (Exception e) {
-            throw new ProviderException("Error parsing configuration", e);
-        }
-    }
-
-    static Config removeConfig(String name) {
-        return configMap.remove(name);
-    }
-
     private final static boolean DEBUG = false;
 
     private static void debug(Object o) {
@@ -101,6 +77,9 @@
         }
     }
 
+    // file name containing this configuration
+    private String filename;
+
     // Reader and StringTokenizer used during parsing
     private Reader reader;
 
@@ -201,18 +180,15 @@
     // memory footprint (true).
     private boolean nssOptimizeSpace = false;
 
-    private Config(String filename, InputStream in) throws IOException {
-        if (in == null) {
-            if (filename.startsWith("--")) {
-                // inline config
-                String config = filename.substring(2).replace("\\n", "\n");
-                reader = new StringReader(config);
-            } else {
-                in = new FileInputStream(expand(filename));
-            }
-        }
-        if (reader == null) {
-            reader = new BufferedReader(new InputStreamReader(in));
+    Config(String fn) throws IOException {
+        this.filename = fn;
+        if (filename.startsWith("--")) {
+            // inline config
+            String config = filename.substring(2).replace("\\n", "\n");
+            reader = new StringReader(config);
+        } else {
+            reader = new BufferedReader(new InputStreamReader
+                (new FileInputStream(expand(filename))));
         }
         parsedKeywords = new HashSet<String>();
         st = new StreamTokenizer(reader);
@@ -220,6 +196,10 @@
         parse();
     }
 
+    String getFileName() {
+        return filename;
+    }
+
     String getName() {
         return name;
     }
--- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/Secmod.java	Thu Jun 25 11:59:40 2015 -0700
+++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/Secmod.java	Fri Jun 26 21:34:34 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -514,8 +514,7 @@
 
         private SunPKCS11 newProvider() {
             try {
-                InputStream in = new ByteArrayInputStream(config.getBytes("UTF8"));
-                return new SunPKCS11(in);
+                return new SunPKCS11(new Config("--" + config));
             } catch (Exception e) {
                 // XXX
                 throw new ProviderException(e);
--- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/SunPKCS11.java	Thu Jun 25 11:59:40 2015 -0700
+++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/SunPKCS11.java	Fri Jun 26 21:34:34 2015 +0000
@@ -63,14 +63,9 @@
 
     static final Debug debug = Debug.getInstance("sunpkcs11");
 
-    private static int dummyConfigId;
-
     // the PKCS11 object through which we make the native calls
     final PKCS11 p11;
 
-    // name of the configuration file
-    private final String configName;
-
     // configuration information
     final Config config;
 
@@ -95,17 +90,33 @@
     }
 
     public SunPKCS11() {
-        super("SunPKCS11-Dummy", 1.9d, "SunPKCS11-Dummy");
-        throw new ProviderException
-            ("SunPKCS11 requires configuration file argument");
+        super("SunPKCS11", 1.9d, "Unconfigured and unusable PKCS11 provider");
+        p11 = null;
+        config = null;
+        slotID = 0;
+        pHandler = null;
+        removable = false;
+        nssModule = null;
+        nssUseSecmodTrust = false;
+        token = null;
+        poller = null;
     }
 
-    public SunPKCS11(String configName) {
-        this(checkNull(configName), null);
-    }
-
-    public SunPKCS11(InputStream configStream) {
-        this(getDummyConfigName(), checkNull(configStream));
+    @Override
+    public Provider configure(String configArg) throws InvalidParameterException {
+        final String newConfigName = checkNull(configArg);
+        try {
+            return AccessController.doPrivileged(new PrivilegedExceptionAction<Provider>() {
+                @Override
+                public Provider run() throws Exception {
+                    return new SunPKCS11(new Config(newConfigName));
+                }
+            });
+        } catch (PrivilegedActionException pae) {
+            InvalidParameterException ipe =
+                new InvalidParameterException("Error configuring SunPKCS11 provider");
+            throw (InvalidParameterException) ipe.initCause(pae.getException());
+        }
     }
 
     private static <T> T checkNull(T obj) {
@@ -115,25 +126,13 @@
         return obj;
     }
 
-    private static synchronized String getDummyConfigName() {
-        int id = ++dummyConfigId;
-        return "---DummyConfig-" + id + "---";
-    }
-
-    /**
-     * @deprecated use new SunPKCS11(String) or new SunPKCS11(InputStream)
-     *         instead
-     */
-    @Deprecated
-    public SunPKCS11(String configName, InputStream configStream) {
-        super("SunPKCS11-" +
-            Config.getConfig(configName, configStream).getName(),
-            1.9d, Config.getConfig(configName, configStream).getDescription());
-        this.configName = configName;
-        this.config = Config.removeConfig(configName);
+    // Used by Secmod
+    SunPKCS11(Config c) {
+        super("SunPKCS11-" + c.getName(), 1.9d, c.getDescription());
+        this.config = c;
 
         if (debug != null) {
-            System.out.println("SunPKCS11 loading " + configName);
+            System.out.println("SunPKCS11 loading " + config.getFileName());
         }
 
         String library = config.getLibrary();
@@ -811,7 +810,7 @@
         if (poller != null) {
             return;
         }
-        TokenPoller poller = new TokenPoller(this);
+        final TokenPoller poller = new TokenPoller(this);
         Thread t = new ManagedLocalsThread(poller, "Poller " + getName());
         t.setDaemon(true);
         t.setPriority(Thread.MIN_PRIORITY);
@@ -1456,7 +1455,7 @@
 
         SunPKCS11Rep(SunPKCS11 provider) throws NotSerializableException {
             providerName = provider.getName();
-            configName = provider.configName;
+            configName = provider.config.getFileName();
             if (Security.getProvider(providerName) != provider) {
                 throw new NotSerializableException("Only SunPKCS11 providers "
                     + "installed in java.security.Security can be serialized");
@@ -1465,7 +1464,7 @@
 
         private Object readResolve() throws ObjectStreamException {
             SunPKCS11 p = (SunPKCS11)Security.getProvider(providerName);
-            if ((p == null) || (p.configName.equals(configName) == false)) {
+            if ((p == null) || (p.config.getFileName().equals(configName) == false)) {
                 throw new NotSerializableException("Could not find "
                         + providerName + " in installed providers");
             }
--- a/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeCipher.java	Thu Jun 25 11:59:40 2015 -0700
+++ b/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeCipher.java	Fri Jun 26 21:34:34 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -55,11 +55,17 @@
         public AesEcbNoPadding() throws NoSuchAlgorithmException {
             super(UcryptoMech.CRYPTO_AES_ECB);
         }
+        public AesEcbNoPadding(int keySize) throws NoSuchAlgorithmException {
+            super(UcryptoMech.CRYPTO_AES_ECB, keySize);
+        }
     }
     public static final class AesCbcNoPadding extends NativeCipher {
         public AesCbcNoPadding() throws NoSuchAlgorithmException {
             super(UcryptoMech.CRYPTO_AES_CBC);
         }
+        public AesCbcNoPadding(int keySize) throws NoSuchAlgorithmException {
+            super(UcryptoMech.CRYPTO_AES_CBC, keySize);
+        }
     }
     public static final class AesCtrNoPadding extends NativeCipher {
         public AesCtrNoPadding() throws NoSuchAlgorithmException {
@@ -72,38 +78,6 @@
         }
     }
 
-    // public implementation classes with fixed key sizes
-    public static final class Aes128EcbNoPadding extends NativeCipher {
-        public Aes128EcbNoPadding() throws NoSuchAlgorithmException {
-            super(UcryptoMech.CRYPTO_AES_ECB, 16);
-        }
-    }
-    public static final class Aes128CbcNoPadding extends NativeCipher {
-        public Aes128CbcNoPadding() throws NoSuchAlgorithmException {
-            super(UcryptoMech.CRYPTO_AES_CBC, 16);
-        }
-    }
-    public static final class Aes192EcbNoPadding extends NativeCipher {
-        public Aes192EcbNoPadding() throws NoSuchAlgorithmException {
-            super(UcryptoMech.CRYPTO_AES_ECB, 24);
-        }
-    }
-    public static final class Aes192CbcNoPadding extends NativeCipher {
-        public Aes192CbcNoPadding() throws NoSuchAlgorithmException {
-            super(UcryptoMech.CRYPTO_AES_CBC, 24);
-        }
-    }
-    public static final class Aes256EcbNoPadding extends NativeCipher {
-        public Aes256EcbNoPadding() throws NoSuchAlgorithmException {
-            super(UcryptoMech.CRYPTO_AES_ECB, 32);
-        }
-    }
-    public static final class Aes256CbcNoPadding extends NativeCipher {
-        public Aes256CbcNoPadding() throws NoSuchAlgorithmException {
-            super(UcryptoMech.CRYPTO_AES_CBC, 32);
-        }
-    }
-
     // ok as constants since AES is all we support
     public static final int AES_BLOCK_SIZE = 16;
     public static final String AES_KEY_ALGO = "AES";
--- a/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeGCMCipher.java	Thu Jun 25 11:59:40 2015 -0700
+++ b/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeGCMCipher.java	Fri Jun 26 21:34:34 2015 +0000
@@ -48,20 +48,8 @@
         public AesGcmNoPadding() throws NoSuchAlgorithmException {
             super(-1);
         }
-    }
-    public static final class Aes128GcmNoPadding extends NativeGCMCipher {
-        public Aes128GcmNoPadding() throws NoSuchAlgorithmException {
-            super(16);
-        }
-    }
-    public static final class Aes192GcmNoPadding extends NativeGCMCipher {
-        public Aes192GcmNoPadding() throws NoSuchAlgorithmException {
-            super(24);
-        }
-    }
-    public static final class Aes256GcmNoPadding extends NativeGCMCipher {
-        public Aes256GcmNoPadding() throws NoSuchAlgorithmException {
-            super(32);
+        public AesGcmNoPadding(int keySize) throws NoSuchAlgorithmException {
+            super(keySize);
         }
     }
 
--- a/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeRSASignature.java	Thu Jun 25 11:59:40 2015 -0700
+++ b/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeRSASignature.java	Fri Jun 26 21:34:34 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -48,7 +48,6 @@
 import java.security.spec.InvalidKeySpecException;
 import sun.nio.ch.DirectBuffer;
 import java.nio.ByteBuffer;
-import sun.security.rsa.RSAPadding;
 
 /**
  * Signature implementation class. This class currently supports the
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/ServiceDesc.java	Fri Jun 26 21:34:34 2015 +0000
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.security.ucrypto;
+
+import java.util.*;
+
+/**
+ * Class for encapsulating the type, algorithm, and class name of
+ * a Provider.Service object.
+ */
+final class ServiceDesc {
+
+    private final String type;
+    private final String algo;
+    private final String cn;
+    private final List<String> aliases;
+
+    ServiceDesc(String type, String algo, String cn) {
+        this(type, algo, cn, null);
+    }
+
+    ServiceDesc(String type, String algo, String cn, String[] aliases) {
+        this.type = type;
+        this.algo = algo;
+        this.cn = cn;
+        if (aliases != null) {
+            this.aliases = Arrays.asList(aliases);
+        } else {
+            this.aliases = null;
+        }
+    }
+    String getType() {
+        return type;
+    }
+    String getAlgorithm() {
+        return algo;
+    }
+    String getClassName() {
+        return cn;
+    }
+    List<String> getAliases() {
+        return aliases;
+    }
+    public String toString() {
+        return type + "." + algo + ": " + cn + ", aliases =" + aliases;
+    }
+}
--- a/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoMech.java	Thu Jun 25 11:59:40 2015 -0700
+++ b/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoMech.java	Fri Jun 26 21:34:34 2015 +0000
@@ -1,5 +1,5 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+/**
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,88 +34,79 @@
  */
 // Check /usr/include/libsoftcrypto.h for updates
 public enum UcryptoMech {
-    CRYPTO_AES_ECB(1, new String[]
-        { "Cipher.AES/ECB/NoPadding;com.oracle.security.ucrypto.NativeCipher$AesEcbNoPadding",
-          "Cipher.AES/ECB/PKCS5Padding;com.oracle.security.ucrypto.NativeCipherWithJavaPadding$AesEcbPKCS5",
-          "Alg.Alias.Cipher.AES;AES/ECB/PKCS5Padding",
-          "Cipher.AES_128/ECB/NoPadding;com.oracle.security.ucrypto.NativeCipher$Aes128EcbNoPadding",
-          "Alg.Alias.Cipher.2.16.840.1.101.3.4.1.1;AES_128/ECB/NoPadding",
-          "Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.1;AES_128/ECB/NoPadding",
-          "Cipher.AES_192/ECB/NoPadding;com.oracle.security.ucrypto.NativeCipher$Aes192EcbNoPadding",
-          "Alg.Alias.Cipher.2.16.840.1.101.3.4.1.21;AES_192/ECB/NoPadding",
-          "Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.21;AES_192/ECB/NoPadding",
-          "Cipher.AES_256/ECB/NoPadding;com.oracle.security.ucrypto.NativeCipher$Aes256EcbNoPadding",
-          "Alg.Alias.Cipher.2.16.840.1.101.3.4.1.41;AES_256/ECB/NoPadding",
-          "Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.41;AES_256/ECB/NoPadding"
+
+    CRYPTO_AES_ECB(1, new ServiceDesc[]
+        { sd("Cipher", "AES/ECB/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesEcbNoPadding"),
+          sd("Cipher", "AES/ECB/PKCS5Padding", "com.oracle.security.ucrypto.NativeCipherWithJavaPadding$AesEcbPKCS5",
+             "AES"),
+          sd("Cipher", "AES_128/ECB/NoPadding", "com.oracle.security.ucrypto.NativeCipher$Aes128EcbNoPadding",
+             "2.16.840.1.101.3.4.1.1", "OID.2.16.840.1.101.3.4.1.1"),
+          sd("Cipher", "AES_192/ECB/NoPadding", "com.oracle.security.ucrypto.NativeCipher$Aes192EcbNoPadding",
+             "2.16.840.1.101.3.4.1.21", "OID.2.16.840.1.101.3.4.1.21"),
+          sd("Cipher", "AES_256/ECB/NoPadding", "com.oracle.security.ucrypto.NativeCipher$Aes256EcbNoPadding",
+             "2.16.840.1.101.3.4.1.41", "OID.2.16.840.1.101.3.4.1.41")
         }),
-    CRYPTO_AES_CBC(2, new String[]
-        { "Cipher.AES/CBC/NoPadding;com.oracle.security.ucrypto.NativeCipher$AesCbcNoPadding",
-          "Cipher.AES/CBC/PKCS5Padding;com.oracle.security.ucrypto.NativeCipherWithJavaPadding$AesCbcPKCS5",
-          "Cipher.AES_128/CBC/NoPadding;com.oracle.security.ucrypto.NativeCipher$Aes128CbcNoPadding",
-          "Alg.Alias.Cipher.2.16.840.1.101.3.4.1.2;AES_128/CBC/NoPadding",
-          "Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.2;AES_128/CBC/NoPadding",
-          "Cipher.AES_192/CBC/NoPadding;com.oracle.security.ucrypto.NativeCipher$Aes192CbcNoPadding",
-          "Alg.Alias.Cipher.2.16.840.1.101.3.4.1.22;AES_192/CBC/NoPadding",
-          "Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.22;AES_192/CBC/NoPadding",
-          "Cipher.AES_256/CBC/NoPadding;com.oracle.security.ucrypto.NativeCipher$Aes256CbcNoPadding",
-          "Alg.Alias.Cipher.2.16.840.1.101.3.4.1.42;AES_256/CBC/NoPadding",
-          "Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.42;AES_256/CBC/NoPadding"
+    CRYPTO_AES_CBC(2, new ServiceDesc[]
+        { sd("Cipher", "AES/CBC/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesCbcNoPadding"),
+          sd("Cipher", "AES/CBC/PKCS5Padding", "com.oracle.security.ucrypto.NativeCipherWithJavaPadding$AesCbcPKCS5"),
+          sd("Cipher", "AES_128/CBC/NoPadding", "com.oracle.security.ucrypto.NativeCipher$Aes128CbcNoPadding",
+             "2.16.840.1.101.3.4.1.2", "OID.2.16.840.1.101.3.4.1.2"),
+          sd("Cipher", "AES_192/CBC/NoPadding", "com.oracle.security.ucrypto.NativeCipher$Aes192CbcNoPadding",
+             "2.16.840.1.101.3.4.1.22", "OID.2.16.840.1.101.3.4.1.22"),
+          sd("Cipher", "AES_256/CBC/NoPadding", "com.oracle.security.ucrypto.NativeCipher$Aes256CbcNoPadding",
+             "2.16.840.1.101.3.4.1.42", "OID.2.16.840.1.101.3.4.1.42")
         }),
     CRYPTO_AES_CBC_PAD(3, null), // No support from Solaris yet
-    CRYPTO_AES_CTR(4, new String[]
-        { "Cipher.AES/CTR/NoPadding;com.oracle.security.ucrypto.NativeCipher$AesCtrNoPadding" }),
+    CRYPTO_AES_CTR(4, new ServiceDesc[]
+        { sd("Cipher", "AES/CTR/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesCtrNoPadding") }),
     CRYPTO_AES_CCM(5, null), // Cannot support due to lack of Java API which corresponds to CK_AES_CCM_PARAMS
-    CRYPTO_AES_GCM(6, new String[]
-        { "Cipher.AES/GCM/NoPadding;com.oracle.security.ucrypto.NativeGCMCipher$AesGcmNoPadding",
-          "Cipher.AES_128/GCM/NoPadding;com.oracle.security.ucrypto.NativeGCMCipher$Aes128GcmNoPadding",
-          "Alg.Alias.Cipher.2.16.840.1.101.3.4.1.6;AES_128/GCM/NoPadding",
-          "Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.6;AES_128/GCM/NoPadding",
-          "Cipher.AES_192/GCM/NoPadding;com.oracle.security.ucrypto.NativeGCMCipher$Aes192GcmNoPadding",
-          "Alg.Alias.Cipher.2.16.840.1.101.3.4.1.26;AES_192/GCM/NoPadding",
-          "Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.26;AES_192/GCM/NoPadding",
-          "Cipher.AES_256/GCM/NoPadding;com.oracle.security.ucrypto.NativeGCMCipher$Aes256GcmNoPadding",
-          "Alg.Alias.Cipher.2.16.840.1.101.3.4.1.46;AES_256/GCM/NoPadding",
-          "Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.46;AES_256/GCM/NoPadding",
+    CRYPTO_AES_GCM(6, new ServiceDesc[]
+        { sd("Cipher", "AES/GCM/NoPadding", "com.oracle.security.ucrypto.NativeGCMCipher$AesGcmNoPadding"),
+          sd("Cipher", "AES_128/GCM/NoPadding", "com.oracle.security.ucrypto.NativeGCMCipher$Aes128GcmNoPadding",
+             "2.16.840.1.101.3.4.1.6", "OID.2.16.840.1.101.3.4.1.6"),
+          sd("Cipher", "AES_192/GCM/NoPadding", "com.oracle.security.ucrypto.NativeGCMCipher$Aes192GcmNoPadding",
+             "2.16.840.1.101.3.4.1.26", "OID.2.16.840.1.101.3.4.1.26"),
+          sd("Cipher", "AES_256/GCM/NoPadding", "com.oracle.security.ucrypto.NativeGCMCipher$Aes256GcmNoPadding",
+             "2.16.840.1.101.3.4.1.46", "OID.2.16.840.1.101.3.4.1.46")
         }),
     CRYPTO_AES_GMAC(7, null), // No support from Solaris yet
-    CRYPTO_AES_CFB128(8, new String[]
-        { "Cipher.AES/CFB128/NoPadding;com.oracle.security.ucrypto.NativeCipher$AesCfb128NoPadding",
-          "Cipher.AES/CFB128/PKCS5Padding;com.oracle.security.ucrypto.NativeCipherWithJavaPadding$AesCfb128PKCS5" }),
-    CRYPTO_RSA_PKCS(31, new String[]
-        { "Cipher.RSA/ECB/PKCS1Padding;com.oracle.security.ucrypto.NativeRSACipher$PKCS1Padding",
-          "Alg.Alias.Cipher.RSA;RSA/ECB/PKCS1Padding" }),
-    CRYPTO_RSA_X_509(32, new String[]
-        { "Cipher.RSA/ECB/NoPadding;com.oracle.security.ucrypto.NativeRSACipher$NoPadding" }),
-    CRYPTO_MD5_RSA_PKCS(33, new String[]
-        { "Signature.MD5withRSA;com.oracle.security.ucrypto.NativeRSASignature$MD5",
-          "Alg.Alias.Signature.1.2.840.113549.1.1.4;MD5withRSA",
-          "Alg.Alias.Signature.OID.1.2.840.113549.1.1.4;MD5withRSA" }),
-    CRYPTO_SHA1_RSA_PKCS(34, new String[]
-        { "Signature.SHA1withRSA;com.oracle.security.ucrypto.NativeRSASignature$SHA1",
-          "Alg.Alias.Signature.1.2.840.113549.1.1.5;SHA1withRSA",
-          "Alg.Alias.Signature.OID.1.2.840.113549.1.1.5;SHA1withRSA",
-          "Alg.Alias.Signature.1.3.14.3.2.29;SHA1withRSA" }),
-    CRYPTO_SHA256_RSA_PKCS(35, new String[]
-        { "Signature.SHA256withRSA;com.oracle.security.ucrypto.NativeRSASignature$SHA256",
-          "Alg.Alias.Signature.1.2.840.113549.1.1.11;SHA256withRSA",
-          "Alg.Alias.Signature.OID.1.2.840.113549.1.1.11;SHA256withRSA" }),
-    CRYPTO_SHA384_RSA_PKCS(36, new String[]
-        { "Signature.SHA384withRSA;com.oracle.security.ucrypto.NativeRSASignature$SHA384",
-          "Alg.Alias.Signature.1.2.840.113549.1.1.12;SHA384withRSA",
-          "Alg.Alias.Signature.OID.1.2.840.113549.1.1.12;SHA384withRSA" }),
-    CRYPTO_SHA512_RSA_PKCS(37, new String[]
-        { "Signature.SHA512withRSA;com.oracle.security.ucrypto.NativeRSASignature$SHA512",
-          "Alg.Alias.Signature.1.2.840.113549.1.1.13;SHA512withRSA",
-          "Alg.Alias.Signature.OID.1.2.840.113549.1.1.13;SHA512withRSA" });
+    CRYPTO_AES_CFB128(8, new ServiceDesc[]
+        { sd("Cipher", "AES/CFB128/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesCfb128NoPadding"),
+          sd("Cipher", "AES/CFB128/PKCS5Padding", "com.oracle.security.ucrypto.NativeCipherWithJavaPadding$AesCfb128PKCS5") }),
+    CRYPTO_RSA_PKCS(31, new ServiceDesc[]
+        { sd("Cipher", "RSA/ECB/PKCS1Padding", "com.oracle.security.ucrypto.NativeRSACipher$PKCS1Padding",
+             "RSA") }),
+    CRYPTO_RSA_X_509(32, new ServiceDesc[]
+        { sd("Cipher", "RSA/ECB/NoPadding", "com.oracle.security.ucrypto.NativeRSACipher$NoPadding") }),
+    CRYPTO_MD5_RSA_PKCS(33, new ServiceDesc[]
+        { sd("Signature", "MD5withRSA", "com.oracle.security.ucrypto.NativeRSASignature$MD5",
+             "1.2.840.113549.1.1.4", "OID.1.2.840.113549.1.1.4") }),
+    CRYPTO_SHA1_RSA_PKCS(34, new ServiceDesc[]
+        { sd("Signature", "SHA1withRSA", "com.oracle.security.ucrypto.NativeRSASignature$SHA1",
+             "1.2.840.113549.1.1.5", "OID.1.2.840.113549.1.1.5",
+             "1.3.14.3.2.29") }),
+    CRYPTO_SHA256_RSA_PKCS(35, new ServiceDesc[]
+        { sd("Signature", "SHA256withRSA", "com.oracle.security.ucrypto.NativeRSASignature$SHA256",
+             "1.2.840.113549.1.1.11", "OID.1.2.840.113549.1.1.11") }),
+    CRYPTO_SHA384_RSA_PKCS(36, new ServiceDesc[]
+        { sd("Signature", "SHA384withRSA", "com.oracle.security.ucrypto.NativeRSASignature$SHA384",
+             "1.2.840.113549.1.1.12", "OID.1.2.840.113549.1.1.12") }),
+    CRYPTO_SHA512_RSA_PKCS(37, new ServiceDesc[]
+        { sd("Signature", "SHA512withRSA", "com.oracle.security.ucrypto.NativeRSASignature$SHA512",
+             "1.2.840.113549.1.1.13", "OID.1.2.840.113549.1.1.13") });
 
-    private int mech;
-    private String[] jceProps;
+    private final int mech;
+    private final ServiceDesc[] serviceDescs;
 
-    UcryptoMech(int mech, String[] jceProps) {
+    private static ServiceDesc sd(String type, String algo, String cn, String... aliases) {
+        return new ServiceDesc(type, algo, cn, aliases);
+    }
+
+    UcryptoMech(int mech, ServiceDesc[] serviceDescs) {
         this.mech = mech;
-        this.jceProps = jceProps;
+        this.serviceDescs = serviceDescs;
     }
 
     public int value() { return mech; }
-    public String[] jceProperties() { return jceProps; }
+    public ServiceDesc[] getServiceDescriptions() { return serviceDescs; }
 }
--- a/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoProvider.java	Thu Jun 25 11:59:40 2015 -0700
+++ b/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoProvider.java	Fri Jun 26 21:34:34 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,11 +26,9 @@
 package com.oracle.security.ucrypto;
 
 import java.io.IOException;
-import java.util.HashMap;
-import java.util.StringTokenizer;
+import java.io.File;
+import java.util.*;
 import java.security.*;
-import sun.security.action.PutAllAction;
-import sun.security.action.GetPropertyAction;
 
 /**
  * OracleUcrypto provider main class.
@@ -41,92 +39,180 @@
 
     private static final long serialVersionUID = 351251234302833L;
 
-    private static boolean DEBUG;
-    private static HashMap<String, String> provProp;
+    private static boolean DEBUG = false;
+    private static HashMap<String, ServiceDesc> provProp = null;
+    private static String defConfigName = "";
 
     static {
         try {
-            DEBUG = Boolean.parseBoolean(AccessController.doPrivileged
-                (new GetPropertyAction("com.oracle.security.ucrypto.debug")));
-
             // cannot use LoadLibraryAction because that would make the native
             // library available to the bootclassloader, but we run in the
             // extension classloader.
-            provProp = AccessController.doPrivileged
-                (new PrivilegedAction<HashMap<String, String>>() {
-                    public HashMap<String, String> run() {
-                        try {
-                            System.loadLibrary("j2ucrypto");
-                            String osname = System.getProperty("os.name");
-                            if (osname.startsWith("SunOS")) {
-                                return new HashMap<String, String>();
-                            } else return null;
-                        } catch (Error err) {
-                            return null;
-                        } catch (SecurityException se) {
-                            return null;
+            String osname = System.getProperty("os.name");
+            if (osname.startsWith("SunOS")) {
+                provProp = AccessController.doPrivileged
+                    (new PrivilegedAction<HashMap<String, ServiceDesc>>() {
+                        public HashMap<String, ServiceDesc> run() {
+                            try {
+                                DEBUG = Boolean.parseBoolean(System.getProperty("com.oracle.security.ucrypto.debug"));
+                                String javaHome = System.getProperty("java.home");
+                                String sep = System.getProperty("file.separator");
+                                defConfigName = javaHome + sep + "conf" + sep + "security" + sep +
+                                    "ucrypto-solaris.cfg";
+                                System.loadLibrary("j2ucrypto");
+                                return new HashMap<>();
+                            } catch (Error err) {
+                                if (DEBUG) err.printStackTrace();
+                                return null;
+                            } catch (SecurityException se) {
+                                if (DEBUG) se.printStackTrace();
+                                return null;
+                            }
                         }
-                    }
-                });
+                    });
+            }
             if (provProp != null) {
                 boolean[] result = loadLibraries();
                 if (result.length == 2) {
                     if (result[0]) { // successfully loaded libmd
                         provProp.put("MessageDigest.MD5",
-                                     "com.oracle.security.ucrypto.NativeDigest$MD5");
+                            sd("MessageDigest", "MD5",
+                               "com.oracle.security.ucrypto.NativeDigest$MD5"));
                         provProp.put("MessageDigest.SHA",
-                                     "com.oracle.security.ucrypto.NativeDigest$SHA1");
-                        provProp.put("Alg.Alias.MessageDigest.SHA-1", "SHA");
-                        provProp.put("Alg.Alias.MessageDigest.SHA1", "SHA");
+                            sd("MessageDigest", "SHA",
+                               "com.oracle.security.ucrypto.NativeDigest$SHA1",
+                               "SHA-1", "SHA1"));
                         provProp.put("MessageDigest.SHA-256",
-                                     "com.oracle.security.ucrypto.NativeDigest$SHA256");
-                        provProp.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.1", "SHA-256");
-                        provProp.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.1", "SHA-256");
+                            sd("MessageDigest", "SHA-256",
+                               "com.oracle.security.ucrypto.NativeDigest$SHA256",
+                               "2.16.840.1.101.3.4.2.1", "OID.2.16.840.1.101.3.4.2.1"));
 
                         provProp.put("MessageDigest.SHA-384",
-                                     "com.oracle.security.ucrypto.NativeDigest$SHA384");
-                        provProp.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.2", "SHA-384");
-                        provProp.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.2", "SHA-384");
+                            sd("MessageDigest", "SHA-384",
+                               "com.oracle.security.ucrypto.NativeDigest$SHA384",
+                               "2.16.840.1.101.3.4.2.2", "OID.2.16.840.1.101.3.4.2.2"));
 
                         provProp.put("MessageDigest.SHA-512",
-                                     "com.oracle.security.ucrypto.NativeDigest$SHA512");
-                        provProp.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.3", "SHA-512");
-                        provProp.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.3", "SHA-512");
-
-                    }
+                            sd("MessageDigest", "SHA-512",
+                               "com.oracle.security.ucrypto.NativeDigest$SHA512",
+                               "2.16.840.1.101.3.4.2.3", "OID.2.16.840.1.101.3.4.2.3"));
+                    };
                     if (result[1]) { // successfully loaded libsoftcrypto
                         String supportedMechs = getMechList();
                         debug("Prov: supported mechs = " + supportedMechs);
                         for (UcryptoMech m : UcryptoMech.values()) {
                             if (supportedMechs.indexOf(m.name() + ",") != -1) {
-                                String[] jceProps = m.jceProperties();
+                                ServiceDesc[] services = m.getServiceDescriptions();
                                 // skip unsupported UcryptoMech
-                                if (jceProps == null) continue;
-                                for (int p = 0; p < jceProps.length; p++) {
-                                    StringTokenizer st =
-                                        new StringTokenizer(jceProps[p], ";");
-                                    if (st.countTokens() != 2) {
-                                        throw new RuntimeException("Wrong format: " + jceProps[p]);
-                                    }
-                                    provProp.put(st.nextToken(), st.nextToken());
+                                if (services == null || services.length == 0) continue;
+                                for (int p = 0; p < services.length; p++) {
+                                    ServiceDesc entry = services[p];
+                                    provProp.put(entry.getType() + "." + entry.getAlgorithm(),
+                                                 entry);
                                 }
                             }
                         }
                         // NOTE: GCM support is only available since jdk 7
                         provProp.put("AlgorithmParameters.GCM",
-                                     "com.oracle.security.ucrypto.GCMParameters");
+                                     sd("AlgorithmParameters", "GCM", "com.oracle.security.ucrypto.GCMParameters"));
                     }
                 } else {
                     debug("Prov: unexpected ucrypto library loading error, got " + result.length);
                 }
             }
         } catch (AccessControlException ace) {
+            if (DEBUG) ace.printStackTrace();
             // disable Ucrypto provider
-            DEBUG = false;
             provProp = null;
         }
     }
 
+    private static ServiceDesc sd(String type, String algo, String cn,
+        String... aliases) {
+        return new ServiceDesc(type, algo, cn, aliases);
+    }
+
+    private static final class ProviderService extends Provider.Service {
+        ProviderService(Provider p, ServiceDesc sd) {
+            super(p, sd.getType(), sd.getAlgorithm(), sd.getClassName(),
+                  sd.getAliases(), null);
+        }
+
+        @Override
+        public Object newInstance(Object ctrParamObj)
+            throws NoSuchAlgorithmException {
+            String type = getType();
+            if (ctrParamObj != null) {
+                throw new InvalidParameterException
+                    ("constructorParameter not used with " + type + " engines");
+            }
+            String algo = getAlgorithm();
+            try {
+                if (type.equals("Cipher")) {
+                    int keySize = -1;
+                    if (algo.charAt(3) == '_') {
+                        keySize = Integer.parseInt(algo.substring(4, 7))/8;
+                        algo = algo.substring(0, 3) + algo.substring(7);
+                    }
+                    if (algo.equals("AES/ECB/NoPadding")) {
+                        return new NativeCipher.AesEcbNoPadding(keySize);
+                    } else if (algo.equals("AES/ECB/PKCS5Padding")) {
+                        return new NativeCipherWithJavaPadding.AesEcbPKCS5();
+                    } else if (algo.equals("AES/CBC/NoPadding")) {
+                        return new NativeCipher.AesCbcNoPadding(keySize);
+                    } else if (algo.equals("AES/CBC/PKCS5Padding")) {
+                        return new NativeCipherWithJavaPadding.AesCbcPKCS5();
+                    } else if (algo.equals("AES/CTR/NoPadding")) {
+                        return new NativeCipher.AesCtrNoPadding();
+                    } else if (algo.equals("AES/GCM/NoPadding")) {
+                        return new NativeGCMCipher.AesGcmNoPadding(keySize);
+                    } else if (algo.equals("AES/CFB128/NoPadding")) {
+                        return new NativeCipher.AesCfb128NoPadding();
+                    } else if (algo.equals("AES/CFB128/PKCS5Padding")) {
+                        return new NativeCipherWithJavaPadding.AesCfb128PKCS5();
+                    } else if (algo.equals("RSA/ECB/NoPadding")) {
+                        return new NativeRSACipher.NoPadding();
+                    } else if (algo.equals("RSA/ECB/PKCS1Padding")) {
+                        return new NativeRSACipher.PKCS1Padding();
+                    }
+                } else if (type.equals("Signature")) {
+                    if (algo.equals("SHA1withRSA")) {
+                        return new NativeRSASignature.SHA1();
+                    } else if (algo.equals("SHA256withRSA")) {
+                        return new NativeRSASignature.SHA256();
+                    } else if (algo.equals("SHA384withRSA")) {
+                        return new NativeRSASignature.SHA384();
+                    } else if (algo.equals("SHA512withRSA")) {
+                        return new NativeRSASignature.SHA512();
+                    } else if (algo.equals("MD5withRSA")) {
+                        return new NativeRSASignature.MD5();
+                    }
+                } else if (type.equals("MessageDigest")) {
+                    if (algo.equals("SHA")) {
+                        return new NativeDigest.SHA1();
+                    } else if (algo.equals("SHA-256")) {
+                        return new NativeDigest.SHA256();
+                    } else if (algo.equals("SHA-384")) {
+                        return new NativeDigest.SHA384();
+                    } else if (algo.equals("SHA-512")) {
+                        return new NativeDigest.SHA512();
+                    } else if (algo.equals("MD5")) {
+                        return new NativeDigest.MD5();
+                    }
+                } else if (type.equals("AlgorithmParameters")) {
+                    if (algo.equals("GCM")) {
+                        return new GCMParameters();
+                    }
+                }
+            } catch (Exception ex) {
+                throw new NoSuchAlgorithmException("Error constructing " +
+                    type + " for " + algo + " using OracleUcrypto", ex);
+            }
+            throw new ProviderException("No impl for " + algo +
+                " " + type);
+        }
+    }
+
     static Provider provider = null;
     private static native boolean[] loadLibraries();
     private static native String getMechList();
@@ -139,34 +225,52 @@
 
     public UcryptoProvider() {
         super("OracleUcrypto", 1.9d, "Provider using Oracle Ucrypto API");
-        if (provProp != null) {
-            AccessController.doPrivileged(new PutAllAction(this, provProp));
-        }
+
+        AccessController.doPrivileged(new PrivilegedAction<>() {
+            public Void run() {
+                init(defConfigName);
+                return null;
+            }
+        });
         if (provider == null) provider = this;
     }
 
-    public UcryptoProvider(String configName) {
-        super("OracleUcrypto", 1.9d, "Provider using Oracle Ucrypto API");
-        try {
-            if (provProp != null) {
-                HashMap<String, String> customProvProp =
-                    new HashMap<String, String>(provProp);
-                Config c = new Config(configName);
-                String[] disabledServices = c.getDisabledServices();
-                for (int i = 0; i < disabledServices.length; i++) {
-                    if (customProvProp.remove(disabledServices[i]) != null) {
-                        debug("Prov: remove config-disabled service " + disabledServices[i]);
-                    } else {
-                        debug("Prov: ignore unsupported config-disabled service " +
-                              disabledServices[i]);
-                    }
+    private void init(final String configName) {
+        if (provProp != null) {
+            debug("Prov: configuration file " + configName);
+            Config c;
+            try {
+                c = new Config(configName);
+            } catch (Exception ex) {
+                throw new UcryptoException("Error parsing Config", ex);
+            }
+
+            String[] disabledServices = c.getDisabledServices();
+            for (String ds : disabledServices) {
+                if (provProp.remove(ds) != null) {
+                    debug("Prov: remove config-disabled service " + ds);
+                } else {
+                    debug("Prov: ignore unsupported service " + ds);
                 }
-                AccessController.doPrivileged(new PutAllAction(this, customProvProp));
+            }
+
+            for (ServiceDesc s: provProp.values()) {
+                debug("Prov: add service for " + s);
+                putService(new ProviderService(this, s));
             }
-        } catch (IOException ioe) { // thrown by Config
-            throw new UcryptoException("Error parsing Config", ioe);
         }
-        if (provider == null) provider = this;
+    }
+
+    @Override
+    public Provider configure(String configArg) throws InvalidParameterException {
+        // default policy entry only grants read access to default config
+        if (!defConfigName.equals(configArg)) {
+            throw new InvalidParameterException("Ucrypto provider can only be " +
+                "configured with default configuration file");
+        }
+        // re-read the config
+        init(defConfigName);
+        return this;
     }
 
     public boolean equals(Object obj) {
--- a/jdk/src/jdk.deploy.osx/macosx/classes/apple/security/AppleProvider.java	Thu Jun 25 11:59:40 2015 -0700
+++ b/jdk/src/jdk.deploy.osx/macosx/classes/apple/security/AppleProvider.java	Fri Jun 26 21:34:34 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,18 +41,46 @@
 
     private static final String info = "Apple Provider";
 
+    private static final class ProviderService extends Provider.Service {
+        ProviderService(Provider p, String type, String algo, String cn) {
+            super(p, type, algo, cn, null, null);
+        }
+
+        @Override
+        public Object newInstance(Object ctrParamObj)
+            throws NoSuchAlgorithmException {
+            String type = getType();
+            if (ctrParamObj != null) {
+                throw new InvalidParameterException
+                    ("constructorParameter not used with " + type + " engines");
+            }
+
+            String algo = getAlgorithm();
+            try {
+                if (type.equals("KeyStore")) {
+                    if (algo.equals("KeychainStore")) {
+                        return new KeychainStore();
+                    }
+                }
+            } catch (Exception ex) {
+                throw new NoSuchAlgorithmException("Error constructing " +
+                    type + " for " + algo + " using Apple", ex);
+            }
+            throw new ProviderException("No impl for " + algo +
+                " " + type);
+        }
+    }
+
+
     public AppleProvider() {
         /* We are the Apple provider */
         super("Apple", 1.9d, info);
 
-        AccessController.<Object>doPrivileged(new java.security.PrivilegedAction<Object>() {
-            public Object run() {
-
-                /*
-                 * KeyStore
-                 */
-                put("KeyStore.KeychainStore", "apple.security.KeychainStore");
-
+        final Provider p = this;
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            public Void run() {
+                putService(new ProviderService(p, "KeyStore",
+                           "KeychainStore", "apple.security.KeychainStore"));
                 return null;
             }
         });
--- a/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java	Thu Jun 25 11:59:40 2015 -0700
+++ b/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java	Fri Jun 26 21:34:34 2015 +0000
@@ -193,23 +193,19 @@
                         provClass = Class.forName(provName);
                     }
 
-                    String provArg = providerArgs.get(provName);
-                    Object obj;
-                    if (provArg == null) {
-                        obj = provClass.newInstance();
-                    } else {
-                        Constructor<?> c =
-                                provClass.getConstructor(PARAM_STRING);
-                        obj = c.newInstance(provArg);
-                    }
-
+                    Object obj = provClass.newInstance();
                     if (!(obj instanceof Provider)) {
                         MessageFormat form = new MessageFormat(rb.getString
                             ("provName.not.a.provider"));
                         Object[] source = {provName};
                         throw new Exception(form.format(source));
                     }
-                    Security.addProvider((Provider)obj);
+                    Provider p = (Provider) obj;
+                    String provArg = providerArgs.get(provName);
+                    if (provArg != null) {
+                        p = p.configure(provArg);
+                    }
+                    Security.addProvider(p);
                 }
             }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/JdkSASL.java	Fri Jun 26 21:34:34 2015 +0000
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.security.sasl.gsskerb;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.Provider;
+import java.security.NoSuchAlgorithmException;
+import java.security.InvalidParameterException;
+import java.security.ProviderException;
+
+/**
+ * The JdkSASL provider class -
+ * provides client and server support for GSSAPI/Kerberos v5
+ */
+
+public final class JdkSASL extends Provider {
+
+    private static final long serialVersionUID = 8622590901641830849L;
+
+    private static final String info = "JDK SASL provider" +
+        "(implements client and server mechanisms for GSSAPI)";
+
+    private static final class ProviderService extends Provider.Service {
+
+        ProviderService(Provider p, String type, String algo, String cn) {
+            super(p, type, algo, cn, null, null);
+        }
+
+        @Override
+        public Object newInstance(Object ctrParamObj)
+            throws NoSuchAlgorithmException {
+            String type = getType();
+            if (ctrParamObj != null) {
+                throw new InvalidParameterException
+                    ("constructorParameter not used with " + type + " engines");
+            }
+            String algo = getAlgorithm();
+            // GSSAPI uses same impl class for client and server
+            try {
+                if (algo.equals("GSSAPI")) {
+                    return new com.sun.security.sasl.gsskerb.FactoryImpl();
+                }
+            } catch (Exception ex) {
+                throw new NoSuchAlgorithmException("Error constructing " +
+                     type + " for " + algo + " using JdkSASL", ex);
+            }
+            throw new ProviderException("No impl for " + algo +
+                " " + type);
+        }
+    }
+
+    public JdkSASL() {
+        super("JdkSASL", 1.9d, info);
+
+        final Provider p = this;
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            public Void run() {
+                putService(new ProviderService(p, "SaslClientFactory",
+                           "GSSAPI", "com.sun.security.sasl.gsskerb.FactoryImpl"));
+                putService(new ProviderService(p, "SaslServerFactory",
+                           "GSSAPI", "com.sun.security.sasl.gsskerb.FactoryImpl"));
+                return null;
+            }
+        });
+    }
+}
--- a/jdk/test/java/lang/SecurityManager/CheckSecurityProvider.java	Thu Jun 25 11:59:40 2015 -0700
+++ b/jdk/test/java/lang/SecurityManager/CheckSecurityProvider.java	Fri Jun 26 21:34:34 2015 +0000
@@ -23,8 +23,9 @@
 
 /*
  * @test
- * @bug 6997010
+ * @bug 6997010 7191662
  * @summary Consolidate java.security files into one file with modifications
+ * @run main/othervm CheckSecurityProvider
  */
 
 import java.security.Provider;
@@ -36,14 +37,14 @@
 /*
  * The main benefit of this test is to catch merge errors or other types
  * of issues where one or more of the security providers are accidentally
- * removed. This is why the known security providers have to
- * be explicitly listed below.
+ * removed. With the security manager enabled, this test can also catch
+ * scenarios where the default permission policy needs to be updated.
  */
 public class CheckSecurityProvider {
     public static void main(String[] args) throws Exception {
+        System.setSecurityManager(new SecurityManager());
 
         String os = System.getProperty("os.name");
-
         /*
          * This array should be updated whenever new security providers
          * are added to the the java.security file.
@@ -52,10 +53,9 @@
 
         List<String> expected = new ArrayList<>();
 
+        // NOTE: the ordering must match what's defined inside java.security
         if (os.equals("SunOS")) {
-            if (!isOpenJDKOnly()) {
-                expected.add("com.oracle.security.ucrypto.UcryptoProvider");
-            }
+            expected.add("com.oracle.security.ucrypto.UcryptoProvider");
             expected.add("sun.security.pkcs11.SunPKCS11");
         }
         expected.add("sun.security.provider.Sun");
@@ -68,12 +68,16 @@
         expected.add("org.jcp.xml.dsig.internal.dom.XMLDSigRI");
         expected.add("sun.security.smartcardio.SunPCSC");
         expected.add("sun.security.provider.certpath.ldap.JdkLDAP");
+        expected.add("com.sun.security.sasl.gsskerb.JdkSASL");
         if (os.startsWith("Windows")) {
             expected.add("sun.security.mscapi.SunMSCAPI");
         }
         if (os.contains("OS X")) {
             expected.add("apple.security.AppleProvider");
         }
+        if (!os.equals("SunOS")) {
+            expected.add("sun.security.pkcs11.SunPKCS11");
+        }
 
         Iterator<String> iter = expected.iterator();
         for (Provider p: Security.getProviders()) {
@@ -90,10 +94,4 @@
             throw new Exception("More expected");
         }
     }
-
-    // Copied from CheckPackageAccess.java in the same directory
-    private static boolean isOpenJDKOnly() {
-        String prop = System.getProperty("java.runtime.name");
-        return prop != null && prop.startsWith("OpenJDK");
-    }
 }
--- a/jdk/test/java/security/Security/SynchronizedAccess.java	Thu Jun 25 11:59:40 2015 -0700
+++ b/jdk/test/java/security/Security/SynchronizedAccess.java	Fri Jun 26 21:34:34 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -47,6 +47,8 @@
             acc[i] = new AccessorThread("thread"+i);
         for (int i=0; i < acc.length; i++)
             acc[i].start();
+        for (int i=0; i < acc.length; i++)
+            acc[i].join();
     }
 }
 
--- a/jdk/test/sun/security/pkcs11/KeyStore/Basic.java	Thu Jun 25 11:59:40 2015 -0700
+++ b/jdk/test/sun/security/pkcs11/KeyStore/Basic.java	Fri Jun 26 21:34:34 2015 +0000
@@ -367,7 +367,7 @@
     private static void module() throws Exception {
 
         // perform Security.addProvider of P11 provider
-        ProviderLoader.go(System.getProperty("CUSTOM_P11_CONFIG"));
+        Security.addProvider(getSunPKCS11(System.getProperty("CUSTOM_P11_CONFIG")));
 
         String KS_PROVIDER = "SunPKCS11-" + System.getProperty("TOKEN");
 
--- a/jdk/test/sun/security/pkcs11/KeyStore/ClientAuth.java	Thu Jun 25 11:59:40 2015 -0700
+++ b/jdk/test/sun/security/pkcs11/KeyStore/ClientAuth.java	Fri Jun 26 21:34:34 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,6 @@
 import java.security.*;
 import javax.net.*;
 import javax.net.ssl.*;
-import java.lang.reflect.*;
 
 public class ClientAuth extends PKCS11Test {
 
@@ -223,7 +222,7 @@
         System.setProperty("javax.net.ssl.trustStorePassword", JKS_PWD);
 
         // perform Security.addProvider of P11 provider
-        ProviderLoader.go(System.getProperty("CUSTOM_P11_CONFIG"));
+        Security.addProvider(getSunPKCS11(System.getProperty("CUSTOM_P11_CONFIG")));
 
         if (debug) {
             System.setProperty("javax.net.debug", "all");
--- a/jdk/test/sun/security/pkcs11/KeyStore/ProviderLoader.java	Thu Jun 25 11:59:40 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * This is a not a test.
- *
- * This is supporting code for other tests.
- * It is compiled and placed into loader.jar
- */
-import java.security.*;
-import sun.security.pkcs11.SunPKCS11;
-
-public class ProviderLoader {
-    public static void go(final String config) throws Exception {
-        AccessController.doPrivileged(new PrivilegedAction() {
-            public Object run() {
-                SunPKCS11 provider = new SunPKCS11(config);
-                Security.addProvider(provider);
-                return null;
-            }
-        });
-    }
-}
--- a/jdk/test/sun/security/pkcs11/PKCS11Test.java	Thu Jun 25 11:59:40 2015 -0700
+++ b/jdk/test/sun/security/pkcs11/PKCS11Test.java	Fri Jun 26 21:34:34 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,6 @@
 
 import java.io.*;
 import java.util.*;
-import java.lang.reflect.*;
 
 import java.security.*;
 import java.security.spec.ECGenParameterSpec;
@@ -70,12 +69,44 @@
     // for quick checking for generic testing than many if-else statements.
     static double softoken3_version = -1;
     static double nss3_version = -1;
+    static Provider pkcs11;
 
+    // Goes through ServiceLoader instead of Provider.getInstance() since it
+    // works on all platforms
+    static {
+        ServiceLoader sl = ServiceLoader.load(java.security.Provider.class);
+        Iterator<Provider> iter = sl.iterator();
+        Provider p = null;
+        boolean found = false;
+        while (iter.hasNext()) {
+            try {
+                p = iter.next();
+                if (p.getName().equals("SunPKCS11")) {
+                    found = true;
+                    break;
+                };
+            } catch (Exception e) {
+                // ignore and move on to the next one
+            }
+        }
+        // Nothing found through ServiceLoader; fall back to reflection
+        if (!found) {
+            try {
+                Class clazz = Class.forName("sun.security.pkcs11.SunPKCS11");
+                p = (Provider) clazz.newInstance();
+            } catch (Exception ex) {
+                ex.printStackTrace();
+            }
+        }
+        pkcs11 = p;
+    }
+
+    // Return a SunPKCS11 provider configured with the specified config file
     static Provider getSunPKCS11(String config) throws Exception {
-        Class clazz = Class.forName("sun.security.pkcs11.SunPKCS11");
-        Constructor cons = clazz.getConstructor(new Class[] {String.class});
-        Object obj = cons.newInstance(new Object[] {config});
-        return (Provider)obj;
+        if (pkcs11 == null) {
+            throw new NoSuchProviderException("No PKCS11 provider available");
+        }
+        return pkcs11.configure(config);
     }
 
     public abstract void main(Provider p) throws Exception;
@@ -85,7 +116,8 @@
         System.out.println("Running test with provider " + p.getName() + "...");
         main(p);
         long stop = System.currentTimeMillis();
-        System.out.println("Completed test with provider " + p.getName() + " (" + (stop - start) + " ms).");
+        System.out.println("Completed test with provider " + p.getName() +
+            " (" + (stop - start) + " ms).");
     }
 
     public static void main(PKCS11Test test) throws Exception {
@@ -576,8 +608,7 @@
         if ((b == null) || (b.length == 0)) {
             return a;
         }
-        T[] r = (T[])java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), a.length + b.length);
-        System.arraycopy(a, 0, r, 0, a.length);
+        T[] r = Arrays.copyOf(a, a.length + b.length);
         System.arraycopy(b, 0, r, a.length, b.length);
         return r;
     }
--- a/jdk/test/sun/security/pkcs11/rsa/TestCACerts.java	Thu Jun 25 11:59:40 2015 -0700
+++ b/jdk/test/sun/security/pkcs11/rsa/TestCACerts.java	Fri Jun 26 21:34:34 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
  * @summary Test the new RSA provider can verify all the RSA certs in the cacerts file
  * @author Andreas Sterbenz
  * @library ..
+ * @library ../../../../java/security/testlibrary
  */
 
 // this test serves as our known answer test
@@ -47,7 +48,7 @@
 
     public void main(Provider p) throws Exception {
         long start = System.currentTimeMillis();
-        Security.addProvider(p);
+        Providers.setAt(p, 1);
         try {
             String PROVIDER = p.getName();
             String javaHome = System.getProperty("java.home");
@@ -75,8 +76,8 @@
             }
             long stop = System.currentTimeMillis();
             System.out.println("All tests passed (" + (stop - start) + " ms).");
-        } finally {
+         } finally {
             Security.removeProvider(p.getName());
-        }
+         }
     }
 }
--- a/jdk/test/tools/launcher/MiscTests.java	Thu Jun 25 11:59:40 2015 -0700
+++ b/jdk/test/tools/launcher/MiscTests.java	Fri Jun 26 21:34:34 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,13 +37,9 @@
 
     // 6856415: Checks to ensure that proper exceptions are thrown by java
     static void test6856415() {
-        // No pkcs library on win-x64, so we bail out.
-        if (is64Bit && isWindows) {
-            return;
-        }
         StringBuilder sb = new StringBuilder();
         sb.append("public static void main(String... args) {\n");
-        sb.append("java.security.Provider p = new sun.security.pkcs11.SunPKCS11(args[0]);\n");
+        sb.append("java.security.Provider p = new sun.security.pkcs11.SunPKCS11();\n");
         sb.append("java.security.Security.insertProviderAt(p, 1);\n");
         sb.append("}");
         File testJar = new File("Foo.jar");