diff --git a/java/security/AccessControlContext.java b/java/security/AccessControlContext.java
new file mode 100644
index 0000000..506898f
--- /dev/null
+++ b/java/security/AccessControlContext.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1997, 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 java.security;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+// Android-changed: Stubbed the implementation.  Android doesn't support SecurityManager.
+// See comments in java.lang.SecurityManager for details.
+/**
+ * Legacy security code; do not use.
+ */
+public final class AccessControlContext {
+    public AccessControlContext(ProtectionDomain context[]) {
+    }
+
+    public AccessControlContext(AccessControlContext acc,
+                                DomainCombiner combiner) {
+    }
+
+
+    public DomainCombiner getDomainCombiner() {
+      return null;
+    }
+
+    public void checkPermission(Permission perm)
+        throws AccessControlException {
+    }
+
+}
diff --git a/java/security/AccessControlException.java b/java/security/AccessControlException.java
new file mode 100644
index 0000000..a4f2a78
--- /dev/null
+++ b/java/security/AccessControlException.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security;
+
+/**
+ * <p> This exception is thrown by the AccessController to indicate
+ * that a requested access (to a critical system resource such as the
+ * file system or the network) is denied.
+ *
+ * <p> The reason to deny access can vary.  For example, the requested
+ * permission might be of an incorrect type,  contain an invalid
+ * value, or request access that is not allowed according to the
+ * security policy.  Such information should be given whenever
+ * possible at the time the exception is thrown.
+ *
+ * @author Li Gong
+ * @author Roland Schemers
+ */
+
+public class AccessControlException extends SecurityException {
+
+    private static final long serialVersionUID = 5138225684096988535L;
+
+    // the permission that caused the exception to be thrown.
+    private Permission perm;
+
+    /**
+     * Constructs an {@code AccessControlException} with the
+     * specified, detailed message.
+     *
+     * @param   s   the detail message.
+     */
+    public AccessControlException(String s) {
+        super(s);
+    }
+
+    /**
+     * Constructs an {@code AccessControlException} with the
+     * specified, detailed message, and the requested permission that caused
+     * the exception.
+     *
+     * @param   s   the detail message.
+     * @param   p   the permission that caused the exception.
+     */
+    public AccessControlException(String s, Permission p) {
+        super(s);
+        perm = p;
+    }
+
+    /**
+     * Gets the Permission object associated with this exception, or
+     * null if there was no corresponding Permission object.
+     *
+     * @return the Permission object.
+     */
+    public Permission getPermission() {
+        return perm;
+    }
+}
diff --git a/java/security/AccessController.java b/java/security/AccessController.java
new file mode 100644
index 0000000..ad844ba
--- /dev/null
+++ b/java/security/AccessController.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1997, 2013, 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 java.security;
+
+
+// Android-changed: Stubbed the implementation.  Android doesn't support SecurityManager.
+// See comments in java.lang.SecurityManager for details.
+/**
+ * Legacy security code; do not use.
+ */
+public final class AccessController {
+
+    private AccessController() { }
+
+    /**
+     * Calls {@code action.run()}.
+     */
+    public static <T> T doPrivileged(PrivilegedAction<T> action) {
+        return action.run();
+    }
+
+    /**
+     * Calls {@code action.run()}.
+     */
+    public static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action) {
+        return action.run();
+    }
+
+
+    /**
+     * Calls {@code action.run()}.
+     */
+    public static <T> T doPrivileged(PrivilegedAction<T> action,
+                                     AccessControlContext context) {
+        return action.run();
+    }
+
+    /**
+     * Calls {@code action.run()}.
+     */
+    public static <T> T
+        doPrivileged(PrivilegedExceptionAction<T> action)
+        throws PrivilegedActionException {
+        try {
+            return action.run();
+        } catch (RuntimeException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new PrivilegedActionException(e);
+        }
+    }
+
+
+    /**
+     * Calls {@code action.run()}.
+     */
+    public static <T> T doPrivilegedWithCombiner
+        (PrivilegedExceptionAction<T> action) throws PrivilegedActionException {
+        return doPrivileged(action);
+    }
+
+
+    /**
+     * Calls {@code action.run()}.
+     */
+    public static <T> T
+        doPrivileged(PrivilegedExceptionAction<T> action,
+                     AccessControlContext context)
+        throws PrivilegedActionException {
+        return doPrivileged(action);
+    }
+
+    public static AccessControlContext getContext() {
+        return new AccessControlContext(null);
+    }
+
+    public static void checkPermission(Permission perm)
+                 throws AccessControlException {
+    }
+}
diff --git a/java/security/AlgorithmConstraints.java b/java/security/AlgorithmConstraints.java
new file mode 100644
index 0000000..7341603
--- /dev/null
+++ b/java/security/AlgorithmConstraints.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2010, 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 java.security;
+
+import java.util.Set;
+
+/**
+ * This interface specifies constraints for cryptographic algorithms,
+ * keys (key sizes), and other algorithm parameters.
+ * <p>
+ * {@code AlgorithmConstraints} objects are immutable.  An implementation
+ * of this interface should not provide methods that can change the state
+ * of an instance once it has been created.
+ * <p>
+ * Note that {@code AlgorithmConstraints} can be used to represent the
+ * restrictions described by the security properties
+ * {@code jdk.certpath.disabledAlgorithms} and
+ * {@code jdk.tls.disabledAlgorithms}, or could be used by a
+ * concrete {@code PKIXCertPathChecker} to check whether a specified
+ * certificate in the certification path contains the required algorithm
+ * constraints.
+ *
+ * @see javax.net.ssl.SSLParameters#getAlgorithmConstraints
+ * @see javax.net.ssl.SSLParameters#setAlgorithmConstraints(AlgorithmConstraints)
+ *
+ * @since 1.7
+ */
+
+public interface AlgorithmConstraints {
+
+    /**
+     * Determines whether an algorithm is granted permission for the
+     * specified cryptographic primitives.
+     *
+     * @param primitives a set of cryptographic primitives
+     * @param algorithm the algorithm name
+     * @param parameters the algorithm parameters, or null if no additional
+     *     parameters
+     *
+     * @return true if the algorithm is permitted and can be used for all
+     *     of the specified cryptographic primitives
+     *
+     * @throws IllegalArgumentException if primitives or algorithm is null
+     *     or empty
+     */
+    public boolean permits(Set<CryptoPrimitive> primitives,
+            String algorithm, AlgorithmParameters parameters);
+
+    /**
+     * Determines whether a key is granted permission for the specified
+     * cryptographic primitives.
+     * <p>
+     * This method is usually used to check key size and key usage.
+     *
+     * @param primitives a set of cryptographic primitives
+     * @param key the key
+     *
+     * @return true if the key can be used for all of the specified
+     *     cryptographic primitives
+     *
+     * @throws IllegalArgumentException if primitives is null or empty,
+     *     or the key is null
+     */
+    public boolean permits(Set<CryptoPrimitive> primitives, Key key);
+
+    /**
+     * Determines whether an algorithm and the corresponding key are granted
+     * permission for the specified cryptographic primitives.
+     *
+     * @param primitives a set of cryptographic primitives
+     * @param algorithm the algorithm name
+     * @param key the key
+     * @param parameters the algorithm parameters, or null if no additional
+     *     parameters
+     *
+     * @return true if the key and the algorithm can be used for all of the
+     *     specified cryptographic primitives
+     *
+     * @throws IllegalArgumentException if primitives or algorithm is null
+     *     or empty, or the key is null
+     */
+    public boolean permits(Set<CryptoPrimitive> primitives,
+                String algorithm, Key key, AlgorithmParameters parameters);
+
+}
diff --git a/java/security/AlgorithmParameterGenerator.java b/java/security/AlgorithmParameterGenerator.java
new file mode 100644
index 0000000..7355405
--- /dev/null
+++ b/java/security/AlgorithmParameterGenerator.java
@@ -0,0 +1,366 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security;
+
+import java.security.spec.AlgorithmParameterSpec;
+
+/**
+ * The {@code AlgorithmParameterGenerator} class is used to generate a
+ * set of
+ * parameters to be used with a certain algorithm. Parameter generators
+ * are constructed using the {@code getInstance} factory methods
+ * (static methods that return instances of a given class).
+ *
+ * <P>The object that will generate the parameters can be initialized
+ * in two different ways: in an algorithm-independent manner, or in an
+ * algorithm-specific manner:
+ *
+ * <ul>
+ * <li>The algorithm-independent approach uses the fact that all parameter
+ * generators share the concept of a "size" and a
+ * source of randomness. The measure of size is universally shared
+ * by all algorithm parameters, though it is interpreted differently
+ * for different algorithms. For example, in the case of parameters for
+ * the <i>DSA</i> algorithm, "size" corresponds to the size
+ * of the prime modulus (in bits).
+ * When using this approach, algorithm-specific parameter generation
+ * values - if any - default to some standard values, unless they can be
+ * derived from the specified size.
+ *
+ * <li>The other approach initializes a parameter generator object
+ * using algorithm-specific semantics, which are represented by a set of
+ * algorithm-specific parameter generation values. To generate
+ * Diffie-Hellman system parameters, for example, the parameter generation
+ * values usually
+ * consist of the size of the prime modulus and the size of the
+ * random exponent, both specified in number of bits.
+ * </ul>
+ *
+ * <P>In case the client does not explicitly initialize the
+ * AlgorithmParameterGenerator
+ * (via a call to an {@code init} method), each provider must supply (and
+ * document) a default initialization. For example, the Sun provider uses a
+ * default modulus prime size of 1024 bits for the generation of DSA
+ * parameters.
+ *
+ * <p> Android provides the following <code>AlgorithmParameterGenerator</code> algorithms:
+ * <table>
+ *   <thead>
+ *     <tr>
+ *       <th>Algorithm</th>
+ *       <th>Supported API Levels</th>
+ *     </tr>
+ *   </thead>
+ *   <tbody>
+ *     <tr class="deprecated">
+ *       <td>AES</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>DES</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>DESede</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr>
+ *       <td>DH</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>DSA</td>
+ *       <td>1+</td>
+ *     </tr>
+ *   </tbody>
+ * </table>
+ *
+ * These algorithms are described in the <a href=
+ * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#AlgorithmParameterGenerator">
+ * AlgorithmParameterGenerator section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ *
+ * @author Jan Luehe
+ *
+ *
+ * @see AlgorithmParameters
+ * @see java.security.spec.AlgorithmParameterSpec
+ *
+ * @since 1.2
+ */
+
+public class AlgorithmParameterGenerator {
+
+    // The provider
+    private Provider provider;
+
+    // The provider implementation (delegate)
+    private AlgorithmParameterGeneratorSpi paramGenSpi;
+
+    // The algorithm
+    private String algorithm;
+
+    /**
+     * Creates an AlgorithmParameterGenerator object.
+     *
+     * @param paramGenSpi the delegate
+     * @param provider the provider
+     * @param algorithm the algorithm
+     */
+    protected AlgorithmParameterGenerator
+    (AlgorithmParameterGeneratorSpi paramGenSpi, Provider provider,
+     String algorithm) {
+        this.paramGenSpi = paramGenSpi;
+        this.provider = provider;
+        this.algorithm = algorithm;
+    }
+
+    /**
+     * Returns the standard name of the algorithm this parameter
+     * generator is associated with.
+     *
+     * @return the string name of the algorithm.
+     */
+    public final String getAlgorithm() {
+        return this.algorithm;
+    }
+
+    /**
+     * Returns an AlgorithmParameterGenerator object for generating
+     * a set of parameters to be used with the specified algorithm.
+     *
+     * <p> This method traverses the list of registered security Providers,
+     * starting with the most preferred Provider.
+     * A new AlgorithmParameterGenerator object encapsulating the
+     * AlgorithmParameterGeneratorSpi implementation from the first
+     * Provider that supports the specified algorithm is returned.
+     *
+     * <p> Note that the list of registered providers may be retrieved via
+     * the {@link Security#getProviders() Security.getProviders()} method.
+     *
+     * @param algorithm the name of the algorithm this
+     * parameter generator is associated with.
+     * See the AlgorithmParameterGenerator section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#AlgorithmParameterGenerator">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard algorithm names.
+     *
+     * @return the new AlgorithmParameterGenerator object.
+     *
+     * @exception NoSuchAlgorithmException if no Provider supports an
+     *          AlgorithmParameterGeneratorSpi implementation for the
+     *          specified algorithm.
+     *
+     * @see Provider
+     */
+    public static AlgorithmParameterGenerator getInstance(String algorithm)
+        throws NoSuchAlgorithmException {
+            try {
+                Object[] objs = Security.getImpl(algorithm,
+                                                 "AlgorithmParameterGenerator",
+                                                 (String)null);
+                return new AlgorithmParameterGenerator
+                    ((AlgorithmParameterGeneratorSpi)objs[0],
+                     (Provider)objs[1],
+                     algorithm);
+            } catch(NoSuchProviderException e) {
+                throw new NoSuchAlgorithmException(algorithm + " not found");
+            }
+    }
+
+    /**
+     * Returns an AlgorithmParameterGenerator object for generating
+     * a set of parameters to be used with the specified algorithm.
+     *
+     * <p> A new AlgorithmParameterGenerator object encapsulating the
+     * AlgorithmParameterGeneratorSpi implementation from the specified provider
+     * is returned.  The specified provider must be registered
+     * in the security provider list.
+     *
+     * <p> Note that the list of registered providers may be retrieved via
+     * the {@link Security#getProviders() Security.getProviders()} method.
+     *
+     * @param algorithm the name of the algorithm this
+     * parameter generator is associated with.
+     * See the AlgorithmParameterGenerator section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#AlgorithmParameterGenerator">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard algorithm names.
+     *
+     * @param provider the string name of the Provider.
+     *
+     * @return the new AlgorithmParameterGenerator object.
+     *
+     * @exception NoSuchAlgorithmException if an AlgorithmParameterGeneratorSpi
+     *          implementation for the specified algorithm is not
+     *          available from the specified provider.
+     *
+     * @exception NoSuchProviderException if the specified provider is not
+     *          registered in the security provider list.
+     *
+     * @exception IllegalArgumentException if the provider name is null
+     *          or empty.
+     *
+     * @see Provider
+     */
+    public static AlgorithmParameterGenerator getInstance(String algorithm,
+                                                          String provider)
+        throws NoSuchAlgorithmException, NoSuchProviderException
+    {
+        if (provider == null || provider.length() == 0)
+            throw new IllegalArgumentException("missing provider");
+        Object[] objs = Security.getImpl(algorithm,
+                                         "AlgorithmParameterGenerator",
+                                         provider);
+        return new AlgorithmParameterGenerator
+            ((AlgorithmParameterGeneratorSpi)objs[0], (Provider)objs[1],
+             algorithm);
+    }
+
+    /**
+     * Returns an AlgorithmParameterGenerator object for generating
+     * a set of parameters to be used with the specified algorithm.
+     *
+     * <p> A new AlgorithmParameterGenerator object encapsulating the
+     * AlgorithmParameterGeneratorSpi implementation from the specified Provider
+     * object is returned.  Note that the specified Provider object
+     * does not have to be registered in the provider list.
+     *
+     * @param algorithm the string name of the algorithm this
+     * parameter generator is associated with.
+     * See the AlgorithmParameterGenerator section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#AlgorithmParameterGenerator">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard algorithm names.
+     *
+     * @param provider the Provider object.
+     *
+     * @return the new AlgorithmParameterGenerator object.
+     *
+     * @exception NoSuchAlgorithmException if an AlgorithmParameterGeneratorSpi
+     *          implementation for the specified algorithm is not available
+     *          from the specified Provider object.
+     *
+     * @exception IllegalArgumentException if the specified provider is null.
+     *
+     * @see Provider
+     *
+     * @since 1.4
+     */
+    public static AlgorithmParameterGenerator getInstance(String algorithm,
+                                                          Provider provider)
+        throws NoSuchAlgorithmException
+    {
+        if (provider == null)
+            throw new IllegalArgumentException("missing provider");
+        Object[] objs = Security.getImpl(algorithm,
+                                         "AlgorithmParameterGenerator",
+                                         provider);
+        return new AlgorithmParameterGenerator
+            ((AlgorithmParameterGeneratorSpi)objs[0], (Provider)objs[1],
+             algorithm);
+    }
+
+    /**
+     * Returns the provider of this algorithm parameter generator object.
+     *
+     * @return the provider of this algorithm parameter generator object
+     */
+    public final Provider getProvider() {
+        return this.provider;
+    }
+
+    /**
+     * Initializes this parameter generator for a certain size.
+     * To create the parameters, the {@code SecureRandom}
+     * implementation of the highest-priority installed provider is used as
+     * the source of randomness.
+     * (If none of the installed providers supply an implementation of
+     * {@code SecureRandom}, a system-provided source of randomness is
+     * used.)
+     *
+     * @param size the size (number of bits).
+     */
+    public final void init(int size) {
+        paramGenSpi.engineInit(size, new SecureRandom());
+    }
+
+    /**
+     * Initializes this parameter generator for a certain size and source
+     * of randomness.
+     *
+     * @param size the size (number of bits).
+     * @param random the source of randomness.
+     */
+    public final void init(int size, SecureRandom random) {
+        paramGenSpi.engineInit(size, random);
+    }
+
+    /**
+     * Initializes this parameter generator with a set of algorithm-specific
+     * parameter generation values.
+     * To generate the parameters, the {@code SecureRandom}
+     * implementation of the highest-priority installed provider is used as
+     * the source of randomness.
+     * (If none of the installed providers supply an implementation of
+     * {@code SecureRandom}, a system-provided source of randomness is
+     * used.)
+     *
+     * @param genParamSpec the set of algorithm-specific parameter generation values.
+     *
+     * @exception InvalidAlgorithmParameterException if the given parameter
+     * generation values are inappropriate for this parameter generator.
+     */
+    public final void init(AlgorithmParameterSpec genParamSpec)
+        throws InvalidAlgorithmParameterException {
+            paramGenSpi.engineInit(genParamSpec, new SecureRandom());
+    }
+
+    /**
+     * Initializes this parameter generator with a set of algorithm-specific
+     * parameter generation values.
+     *
+     * @param genParamSpec the set of algorithm-specific parameter generation values.
+     * @param random the source of randomness.
+     *
+     * @exception InvalidAlgorithmParameterException if the given parameter
+     * generation values are inappropriate for this parameter generator.
+     */
+    public final void init(AlgorithmParameterSpec genParamSpec,
+                           SecureRandom random)
+        throws InvalidAlgorithmParameterException {
+            paramGenSpi.engineInit(genParamSpec, random);
+    }
+
+    /**
+     * Generates the parameters.
+     *
+     * @return the new AlgorithmParameters object.
+     */
+    public final AlgorithmParameters generateParameters() {
+        return paramGenSpi.engineGenerateParameters();
+    }
+}
diff --git a/java/security/AlgorithmParameterGeneratorSpi.java b/java/security/AlgorithmParameterGeneratorSpi.java
new file mode 100644
index 0000000..721fb52
--- /dev/null
+++ b/java/security/AlgorithmParameterGeneratorSpi.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security;
+
+import java.security.spec.AlgorithmParameterSpec;
+
+/**
+ * This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
+ * for the {@code AlgorithmParameterGenerator} class, which
+ * is used to generate a set of parameters to be used with a certain algorithm.
+ *
+ * <p> All the abstract methods in this class must be implemented by each
+ * cryptographic service provider who wishes to supply the implementation
+ * of a parameter generator for a particular algorithm.
+ *
+ * <p> In case the client does not explicitly initialize the
+ * AlgorithmParameterGenerator (via a call to an {@code engineInit}
+ * method), each provider must supply (and document) a default initialization.
+ * For example, the Sun provider uses a default modulus prime size of 1024
+ * bits for the generation of DSA parameters.
+ *
+ * @author Jan Luehe
+ *
+ *
+ * @see AlgorithmParameterGenerator
+ * @see AlgorithmParameters
+ * @see java.security.spec.AlgorithmParameterSpec
+ *
+ * @since 1.2
+ */
+
+public abstract class AlgorithmParameterGeneratorSpi {
+
+    /**
+     * Initializes this parameter generator for a certain size
+     * and source of randomness.
+     *
+     * @param size the size (number of bits).
+     * @param random the source of randomness.
+     */
+    protected abstract void engineInit(int size, SecureRandom random);
+
+    /**
+     * Initializes this parameter generator with a set of
+     * algorithm-specific parameter generation values.
+     *
+     * @param genParamSpec the set of algorithm-specific parameter generation values.
+     * @param random the source of randomness.
+     *
+     * @exception InvalidAlgorithmParameterException if the given parameter
+     * generation values are inappropriate for this parameter generator.
+     */
+    protected abstract void engineInit(AlgorithmParameterSpec genParamSpec,
+                                       SecureRandom random)
+        throws InvalidAlgorithmParameterException;
+
+    /**
+     * Generates the parameters.
+     *
+     * @return the new AlgorithmParameters object.
+     */
+    protected abstract AlgorithmParameters engineGenerateParameters();
+}
diff --git a/java/security/AlgorithmParameters.java b/java/security/AlgorithmParameters.java
new file mode 100644
index 0000000..36bb3ee
--- /dev/null
+++ b/java/security/AlgorithmParameters.java
@@ -0,0 +1,488 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security;
+
+import java.io.*;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+
+/**
+ * This class is used as an opaque representation of cryptographic parameters.
+ *
+ * <p>An {@code AlgorithmParameters} object for managing the parameters
+ * for a particular algorithm can be obtained by
+ * calling one of the {@code getInstance} factory methods
+ * (static methods that return instances of a given class).
+ *
+ * <p>Once an {@code AlgorithmParameters} object is obtained, it must be
+ * initialized via a call to {@code init}, using an appropriate parameter
+ * specification or parameter encoding.
+ *
+ * <p>A transparent parameter specification is obtained from an
+ * {@code AlgorithmParameters} object via a call to
+ * {@code getParameterSpec}, and a byte encoding of the parameters is
+ * obtained via a call to {@code getEncoded}.
+ *
+ * <p> Android provides the following <code>AlgorithmParameters</code> algorithms:
+ * <table>
+ *   <thead>
+ *     <tr>
+ *       <th>Algorithm</th>
+ *       <th>Supported API Levels</th>
+ *     </tr>
+ *   </thead>
+ *   <tbody>
+ *     <tr>
+ *       <td>AES</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>BLOWFISH</td>
+ *       <td>10+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>DES</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>DESede</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>DH</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>DSA</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>EC</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>GCM</td>
+ *       <td>22+</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>IES</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr>
+ *       <td>OAEP</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA1AndAES_128</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA1AndAES_256</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA224AndAES_128</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA224AndAES_256</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA256AndAES_128</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA256AndAES_256</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA384AndAES_128</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA384AndAES_256</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA512AndAES_128</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA512AndAES_256</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PKCS12PBE</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PSS</td>
+ *       <td>1-8,24+</td>
+ *     </tr>
+ *   </tbody>
+ * </table>
+ *
+ * These algorithms are described in the <a href=
+ * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#AlgorithmParameters">
+ * AlgorithmParameters section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ *
+ * @author Jan Luehe
+ *
+ *
+ * @see java.security.spec.AlgorithmParameterSpec
+ * @see java.security.spec.DSAParameterSpec
+ * @see KeyPairGenerator
+ *
+ * @since 1.2
+ */
+
+public class AlgorithmParameters {
+
+    // The provider
+    private Provider provider;
+
+    // The provider implementation (delegate)
+    private AlgorithmParametersSpi paramSpi;
+
+    // The algorithm
+    private String algorithm;
+
+    // Has this object been initialized?
+    private boolean initialized = false;
+
+    /**
+     * Creates an AlgorithmParameters object.
+     *
+     * @param paramSpi the delegate
+     * @param provider the provider
+     * @param algorithm the algorithm
+     */
+    protected AlgorithmParameters(AlgorithmParametersSpi paramSpi,
+                                  Provider provider, String algorithm)
+    {
+        this.paramSpi = paramSpi;
+        this.provider = provider;
+        this.algorithm = algorithm;
+    }
+
+    /**
+     * Returns the name of the algorithm associated with this parameter object.
+     *
+     * @return the algorithm name.
+     */
+    public final String getAlgorithm() {
+        return this.algorithm;
+    }
+
+    /**
+     * Returns a parameter object for the specified algorithm.
+     *
+     * <p> This method traverses the list of registered security Providers,
+     * starting with the most preferred Provider.
+     * A new AlgorithmParameters object encapsulating the
+     * AlgorithmParametersSpi implementation from the first
+     * Provider that supports the specified algorithm is returned.
+     *
+     * <p> Note that the list of registered providers may be retrieved via
+     * the {@link Security#getProviders() Security.getProviders()} method.
+     *
+     * <p> The returned parameter object must be initialized via a call to
+     * {@code init}, using an appropriate parameter specification or
+     * parameter encoding.
+     *
+     * @param algorithm the name of the algorithm requested.
+     * See the AlgorithmParameters section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#AlgorithmParameters">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard algorithm names.
+     *
+     * @return the new parameter object.
+     *
+     * @exception NoSuchAlgorithmException if no Provider supports an
+     *          AlgorithmParametersSpi implementation for the
+     *          specified algorithm.
+     *
+     * @see Provider
+     */
+    public static AlgorithmParameters getInstance(String algorithm)
+    throws NoSuchAlgorithmException {
+        try {
+            Object[] objs = Security.getImpl(algorithm, "AlgorithmParameters",
+                                             (String)null);
+            return new AlgorithmParameters((AlgorithmParametersSpi)objs[0],
+                                           (Provider)objs[1],
+                                           algorithm);
+        } catch(NoSuchProviderException e) {
+            throw new NoSuchAlgorithmException(algorithm + " not found");
+        }
+    }
+
+    /**
+     * Returns a parameter object for the specified algorithm.
+     *
+     * <p> A new AlgorithmParameters object encapsulating the
+     * AlgorithmParametersSpi implementation from the specified provider
+     * is returned.  The specified provider must be registered
+     * in the security provider list.
+     *
+     * <p> Note that the list of registered providers may be retrieved via
+     * the {@link Security#getProviders() Security.getProviders()} method.
+     *
+     * <p>The returned parameter object must be initialized via a call to
+     * {@code init}, using an appropriate parameter specification or
+     * parameter encoding.
+     *
+     * @param algorithm the name of the algorithm requested.
+     * See the AlgorithmParameters section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#AlgorithmParameters">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard algorithm names.
+     *
+     * @param provider the name of the provider.
+     *
+     * @return the new parameter object.
+     *
+     * @exception NoSuchAlgorithmException if an AlgorithmParametersSpi
+     *          implementation for the specified algorithm is not
+     *          available from the specified provider.
+     *
+     * @exception NoSuchProviderException if the specified provider is not
+     *          registered in the security provider list.
+     *
+     * @exception IllegalArgumentException if the provider name is null
+     *          or empty.
+     *
+     * @see Provider
+     */
+    public static AlgorithmParameters getInstance(String algorithm,
+                                                  String provider)
+        throws NoSuchAlgorithmException, NoSuchProviderException
+    {
+        if (provider == null || provider.length() == 0)
+            throw new IllegalArgumentException("missing provider");
+        Object[] objs = Security.getImpl(algorithm, "AlgorithmParameters",
+                                         provider);
+        return new AlgorithmParameters((AlgorithmParametersSpi)objs[0],
+                                       (Provider)objs[1],
+                                       algorithm);
+    }
+
+    /**
+     * Returns a parameter object for the specified algorithm.
+     *
+     * <p> A new AlgorithmParameters object encapsulating the
+     * AlgorithmParametersSpi implementation from the specified Provider
+     * object is returned.  Note that the specified Provider object
+     * does not have to be registered in the provider list.
+     *
+     * <p>The returned parameter object must be initialized via a call to
+     * {@code init}, using an appropriate parameter specification or
+     * parameter encoding.
+     *
+     * @param algorithm the name of the algorithm requested.
+     * See the AlgorithmParameters section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#AlgorithmParameters">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard algorithm names.
+     *
+     * @param provider the name of the provider.
+     *
+     * @return the new parameter object.
+     *
+     * @exception NoSuchAlgorithmException if an AlgorithmParameterGeneratorSpi
+     *          implementation for the specified algorithm is not available
+     *          from the specified Provider object.
+     *
+     * @exception IllegalArgumentException if the provider is null.
+     *
+     * @see Provider
+     *
+     * @since 1.4
+     */
+    public static AlgorithmParameters getInstance(String algorithm,
+                                                  Provider provider)
+        throws NoSuchAlgorithmException
+    {
+        if (provider == null)
+            throw new IllegalArgumentException("missing provider");
+        Object[] objs = Security.getImpl(algorithm, "AlgorithmParameters",
+                                         provider);
+        return new AlgorithmParameters((AlgorithmParametersSpi)objs[0],
+                                       (Provider)objs[1],
+                                       algorithm);
+    }
+
+    /**
+     * Returns the provider of this parameter object.
+     *
+     * @return the provider of this parameter object
+     */
+    public final Provider getProvider() {
+        return this.provider;
+    }
+
+    /**
+     * Initializes this parameter object using the parameters
+     * specified in {@code paramSpec}.
+     *
+     * @param paramSpec the parameter specification.
+     *
+     * @exception InvalidParameterSpecException if the given parameter
+     * specification is inappropriate for the initialization of this parameter
+     * object, or if this parameter object has already been initialized.
+     */
+    public final void init(AlgorithmParameterSpec paramSpec)
+        throws InvalidParameterSpecException
+    {
+        if (this.initialized)
+            throw new InvalidParameterSpecException("already initialized");
+        paramSpi.engineInit(paramSpec);
+        this.initialized = true;
+    }
+
+    /**
+     * Imports the specified parameters and decodes them according to the
+     * primary decoding format for parameters. The primary decoding
+     * format for parameters is ASN.1, if an ASN.1 specification for this type
+     * of parameters exists.
+     *
+     * @param params the encoded parameters.
+     *
+     * @exception IOException on decoding errors, or if this parameter object
+     * has already been initialized.
+     */
+    public final void init(byte[] params) throws IOException {
+        if (this.initialized)
+            throw new IOException("already initialized");
+        paramSpi.engineInit(params);
+        this.initialized = true;
+    }
+
+    /**
+     * Imports the parameters from {@code params} and decodes them
+     * according to the specified decoding scheme.
+     * If {@code format} is null, the
+     * primary decoding format for parameters is used. The primary decoding
+     * format is ASN.1, if an ASN.1 specification for these parameters
+     * exists.
+     *
+     * @param params the encoded parameters.
+     *
+     * @param format the name of the decoding scheme.
+     *
+     * @exception IOException on decoding errors, or if this parameter object
+     * has already been initialized.
+     */
+    public final void init(byte[] params, String format) throws IOException {
+        if (this.initialized)
+            throw new IOException("already initialized");
+        paramSpi.engineInit(params, format);
+        this.initialized = true;
+    }
+
+    /**
+     * Returns a (transparent) specification of this parameter object.
+     * {@code paramSpec} identifies the specification class in which
+     * the parameters should be returned. It could, for example, be
+     * {@code DSAParameterSpec.class}, to indicate that the
+     * parameters should be returned in an instance of the
+     * {@code DSAParameterSpec} class.
+     *
+     * @param <T> the type of the parameter specification to be returrned
+     * @param paramSpec the specification class in which
+     * the parameters should be returned.
+     *
+     * @return the parameter specification.
+     *
+     * @exception InvalidParameterSpecException if the requested parameter
+     * specification is inappropriate for this parameter object, or if this
+     * parameter object has not been initialized.
+     */
+    public final <T extends AlgorithmParameterSpec>
+        T getParameterSpec(Class<T> paramSpec)
+        throws InvalidParameterSpecException
+    {
+        if (this.initialized == false) {
+            throw new InvalidParameterSpecException("not initialized");
+        }
+        return paramSpi.engineGetParameterSpec(paramSpec);
+    }
+
+    /**
+     * Returns the parameters in their primary encoding format.
+     * The primary encoding format for parameters is ASN.1, if an ASN.1
+     * specification for this type of parameters exists.
+     *
+     * @return the parameters encoded using their primary encoding format.
+     *
+     * @exception IOException on encoding errors, or if this parameter object
+     * has not been initialized.
+     */
+    public final byte[] getEncoded() throws IOException
+    {
+        if (this.initialized == false) {
+            throw new IOException("not initialized");
+        }
+        return paramSpi.engineGetEncoded();
+    }
+
+    /**
+     * Returns the parameters encoded in the specified scheme.
+     * If {@code format} is null, the
+     * primary encoding format for parameters is used. The primary encoding
+     * format is ASN.1, if an ASN.1 specification for these parameters
+     * exists.
+     *
+     * @param format the name of the encoding format.
+     *
+     * @return the parameters encoded using the specified encoding scheme.
+     *
+     * @exception IOException on encoding errors, or if this parameter object
+     * has not been initialized.
+     */
+    public final byte[] getEncoded(String format) throws IOException
+    {
+        if (this.initialized == false) {
+            throw new IOException("not initialized");
+        }
+        return paramSpi.engineGetEncoded(format);
+    }
+
+    /**
+     * Returns a formatted string describing the parameters.
+     *
+     * @return a formatted string describing the parameters, or null if this
+     * parameter object has not been initialized.
+     */
+    public final String toString() {
+        if (this.initialized == false) {
+            return null;
+        }
+        return paramSpi.engineToString();
+    }
+}
diff --git a/java/security/AlgorithmParametersSpi.java b/java/security/AlgorithmParametersSpi.java
new file mode 100644
index 0000000..282493b
--- /dev/null
+++ b/java/security/AlgorithmParametersSpi.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security;
+
+import java.io.*;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+
+/**
+ * This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
+ * for the {@code AlgorithmParameters} class, which is used to manage
+ * algorithm parameters.
+ *
+ * <p> All the abstract methods in this class must be implemented by each
+ * cryptographic service provider who wishes to supply parameter management
+ * for a particular algorithm.
+ *
+ * @author Jan Luehe
+ *
+ *
+ * @see AlgorithmParameters
+ * @see java.security.spec.AlgorithmParameterSpec
+ * @see java.security.spec.DSAParameterSpec
+ *
+ * @since 1.2
+ */
+
+public abstract class AlgorithmParametersSpi {
+
+    /**
+     * Initializes this parameters object using the parameters
+     * specified in {@code paramSpec}.
+     *
+     * @param paramSpec the parameter specification.
+     *
+     * @exception InvalidParameterSpecException if the given parameter
+     * specification is inappropriate for the initialization of this parameter
+     * object.
+     */
+    protected abstract void engineInit(AlgorithmParameterSpec paramSpec)
+        throws InvalidParameterSpecException;
+
+    /**
+     * Imports the specified parameters and decodes them
+     * according to the primary decoding format for parameters.
+     * The primary decoding format for parameters is ASN.1, if an ASN.1
+     * specification for this type of parameters exists.
+     *
+     * @param params the encoded parameters.
+     *
+     * @exception IOException on decoding errors
+     */
+    protected abstract void engineInit(byte[] params)
+        throws IOException;
+
+    /**
+     * Imports the parameters from {@code params} and
+     * decodes them according to the specified decoding format.
+     * If {@code format} is null, the
+     * primary decoding format for parameters is used. The primary decoding
+     * format is ASN.1, if an ASN.1 specification for these parameters
+     * exists.
+     *
+     * @param params the encoded parameters.
+     *
+     * @param format the name of the decoding format.
+     *
+     * @exception IOException on decoding errors
+     */
+    protected abstract void engineInit(byte[] params, String format)
+        throws IOException;
+
+    /**
+     * Returns a (transparent) specification of this parameters
+     * object.
+     * {@code paramSpec} identifies the specification class in which
+     * the parameters should be returned. It could, for example, be
+     * {@code DSAParameterSpec.class}, to indicate that the
+     * parameters should be returned in an instance of the
+     * {@code DSAParameterSpec} class.
+     *
+     * @param <T> the type of the parameter specification to be returned
+     *
+     * @param paramSpec the specification class in which
+     * the parameters should be returned.
+     *
+     * @return the parameter specification.
+     *
+     * @exception InvalidParameterSpecException if the requested parameter
+     * specification is inappropriate for this parameter object.
+     */
+    protected abstract
+        <T extends AlgorithmParameterSpec>
+        T engineGetParameterSpec(Class<T> paramSpec)
+        throws InvalidParameterSpecException;
+
+    /**
+     * Returns the parameters in their primary encoding format.
+     * The primary encoding format for parameters is ASN.1, if an ASN.1
+     * specification for this type of parameters exists.
+     *
+     * @return the parameters encoded using their primary encoding format.
+     *
+     * @exception IOException on encoding errors.
+     */
+    protected abstract byte[] engineGetEncoded() throws IOException;
+
+    /**
+     * Returns the parameters encoded in the specified format.
+     * If {@code format} is null, the
+     * primary encoding format for parameters is used. The primary encoding
+     * format is ASN.1, if an ASN.1 specification for these parameters
+     * exists.
+     *
+     * @param format the name of the encoding format.
+     *
+     * @return the parameters encoded using the specified encoding scheme.
+     *
+     * @exception IOException on encoding errors.
+     */
+    protected abstract byte[] engineGetEncoded(String format)
+        throws IOException;
+
+    /**
+     * Returns a formatted string describing the parameters.
+     *
+     * @return a formatted string describing the parameters.
+     */
+    protected abstract String engineToString();
+}
diff --git a/java/security/AllPermission.java b/java/security/AllPermission.java
new file mode 100644
index 0000000..61bcaea
--- /dev/null
+++ b/java/security/AllPermission.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 1998, 2006, 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 java.security;
+
+// Android-changed: Stubbed the implementation.  Android doesn't support SecurityManager.
+// See comments in java.lang.SecurityManager for details.
+/**
+ * Legacy security code; do not use.
+ */
+
+public final class AllPermission extends Permission {
+
+    public AllPermission() { super(""); }
+
+    public AllPermission(String name, String actions) { super(""); }
+
+    public boolean implies(Permission p) { return true; }
+
+    public String getActions() { return null; }
+}
diff --git a/java/security/AuthProvider.java b/java/security/AuthProvider.java
new file mode 100644
index 0000000..e87daa9
--- /dev/null
+++ b/java/security/AuthProvider.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2003, 2013, 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 java.security;
+
+import javax.security.auth.Subject;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.callback.CallbackHandler;
+
+// Android-changed: Stubbed the implementation.  Android doesn't support SecurityManager.
+// See comments in java.lang.SecurityManager for details.
+/**
+ * Legacy security code; do not use.
+ */
+public abstract class AuthProvider extends Provider {
+
+    protected AuthProvider(String name, double version, String info) {
+        super("", 0d, "");
+    }
+
+    public abstract void login(Subject subject, CallbackHandler handler)
+        throws LoginException;
+
+    public abstract void logout() throws LoginException;
+
+    public abstract void setCallbackHandler(CallbackHandler handler);
+}
diff --git a/java/security/BasicPermission.java b/java/security/BasicPermission.java
new file mode 100644
index 0000000..1836b10
--- /dev/null
+++ b/java/security/BasicPermission.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1997, 2011, 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 java.security;
+
+// Android-changed: Stubbed the implementation.  Android doesn't support SecurityManager.
+// See comments in java.lang.SecurityManager for details.
+/**
+ * Legacy security code; do not use.
+ */
+
+public abstract class BasicPermission extends Permission
+implements java.io.Serializable
+{
+
+    public BasicPermission(String name) { super(""); }
+
+    public BasicPermission(String name, String actions) { super(""); }
+
+    public boolean implies(Permission p) { return true; }
+
+    public String getActions()
+    {
+        return "";
+    }
+}
diff --git a/java/security/Certificate.java b/java/security/Certificate.java
new file mode 100644
index 0000000..489c6d6
--- /dev/null
+++ b/java/security/Certificate.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 1996, 2013, 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 java.security;
+
+import java.io.*;
+import java.util.Date;
+
+/**
+ * <p>This is an interface of abstract methods for managing a
+ * variety of identity certificates.
+ * An identity certificate is a guarantee by a principal that
+ * a public key is that of another principal.  (A principal represents
+ * an entity such as an individual user, a group, or a corporation.)
+ *
+ * <p>In particular, this interface is intended to be a common
+ * abstraction for constructs that have different formats but
+ * important common uses.  For example, different types of
+ * certificates, such as X.509 certificates and PGP certificates,
+ * share general certificate functionality (the need to encode and
+ * decode certificates) and some types of information, such as a
+ * public key, the principal whose key it is, and the guarantor
+ * guaranteeing that the public key is that of the specified
+ * principal. So an implementation of X.509 certificates and an
+ * implementation of PGP certificates can both utilize the Certificate
+ * interface, even though their formats and additional types and
+ * amounts of information stored are different.
+ *
+ * <p><b>Important</b>: This interface is useful for cataloging and
+ * grouping objects sharing certain common uses. It does not have any
+ * semantics of its own. In particular, a Certificate object does not
+ * make any statement as to the <i>validity</i> of the binding. It is
+ * the duty of the application implementing this interface to verify
+ * the certificate and satisfy itself of its validity.
+ *
+ * @author Benjamin Renaud
+ * @deprecated A new certificate handling package is created in the Java platform.
+ *             This Certificate interface is entirely deprecated and
+ *             is here to allow for a smooth transition to the new
+ *             package.
+ * @see java.security.cert.Certificate
+ */
+@Deprecated
+public interface Certificate {
+
+    /**
+     * Returns the guarantor of the certificate, that is, the principal
+     * guaranteeing that the public key associated with this certificate
+     * is that of the principal associated with this certificate. For X.509
+     * certificates, the guarantor will typically be a Certificate Authority
+     * (such as the United States Postal Service or Verisign, Inc.).
+     *
+     * @return the guarantor which guaranteed the principal-key
+     * binding.
+     */
+    public abstract Principal getGuarantor();
+
+    /**
+     * Returns the principal of the principal-key pair being guaranteed by
+     * the guarantor.
+     *
+     * @return the principal to which this certificate is bound.
+     */
+    public abstract Principal getPrincipal();
+
+    /**
+     * Returns the key of the principal-key pair being guaranteed by
+     * the guarantor.
+     *
+     * @return the public key that this certificate certifies belongs
+     * to a particular principal.
+     */
+    public abstract PublicKey getPublicKey();
+
+    /**
+     * Encodes the certificate to an output stream in a format that can
+     * be decoded by the {@code decode} method.
+     *
+     * @param stream the output stream to which to encode the
+     * certificate.
+     *
+     * @exception KeyException if the certificate is not
+     * properly initialized, or data is missing, etc.
+     *
+     * @exception IOException if a stream exception occurs while
+     * trying to output the encoded certificate to the output stream.
+     *
+     * @see #decode
+     * @see #getFormat
+     */
+    public abstract void encode(OutputStream stream)
+        throws KeyException, IOException;
+
+    /**
+     * Decodes a certificate from an input stream. The format should be
+     * that returned by {@code getFormat} and produced by
+     * {@code encode}.
+     *
+     * @param stream the input stream from which to fetch the data
+     * being decoded.
+     *
+     * @exception KeyException if the certificate is not properly initialized,
+     * or data is missing, etc.
+     *
+     * @exception IOException if an exception occurs while trying to input
+     * the encoded certificate from the input stream.
+     *
+     * @see #encode
+     * @see #getFormat
+     */
+    public abstract void decode(InputStream stream)
+        throws KeyException, IOException;
+
+
+    /**
+     * Returns the name of the coding format. This is used as a hint to find
+     * an appropriate parser. It could be "X.509", "PGP", etc. This is
+     * the format produced and understood by the {@code encode}
+     * and {@code decode} methods.
+     *
+     * @return the name of the coding format.
+     */
+    public abstract String getFormat();
+
+    /**
+     * Returns a string that represents the contents of the certificate.
+     *
+     * @param detailed whether or not to give detailed information
+     * about the certificate
+     *
+     * @return a string representing the contents of the certificate
+     */
+    public String toString(boolean detailed);
+}
diff --git a/java/security/CodeSigner.java b/java/security/CodeSigner.java
new file mode 100644
index 0000000..37c12b1
--- /dev/null
+++ b/java/security/CodeSigner.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2003, 2013, 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 java.security;
+
+import java.io.*;
+import java.security.cert.CertPath;
+
+/**
+ * This class encapsulates information about a code signer.
+ * It is immutable.
+ *
+ * @since 1.5
+ * @author Vincent Ryan
+ */
+
+public final class CodeSigner implements Serializable {
+
+    private static final long serialVersionUID = 6819288105193937581L;
+
+    /**
+     * The signer's certificate path.
+     *
+     * @serial
+     */
+    private CertPath signerCertPath;
+
+    /*
+     * The signature timestamp.
+     *
+     * @serial
+     */
+    private Timestamp timestamp;
+
+    /*
+     * Hash code for this code signer.
+     */
+    private transient int myhash = -1;
+
+    /**
+     * Constructs a CodeSigner object.
+     *
+     * @param signerCertPath The signer's certificate path.
+     *                       It must not be {@code null}.
+     * @param timestamp A signature timestamp.
+     *                  If {@code null} then no timestamp was generated
+     *                  for the signature.
+     * @throws NullPointerException if {@code signerCertPath} is
+     *                              {@code null}.
+     */
+    public CodeSigner(CertPath signerCertPath, Timestamp timestamp) {
+        if (signerCertPath == null) {
+            throw new NullPointerException();
+        }
+        this.signerCertPath = signerCertPath;
+        this.timestamp = timestamp;
+    }
+
+    /**
+     * Returns the signer's certificate path.
+     *
+     * @return A certificate path.
+     */
+    public CertPath getSignerCertPath() {
+        return signerCertPath;
+    }
+
+    /**
+     * Returns the signature timestamp.
+     *
+     * @return The timestamp or {@code null} if none is present.
+     */
+    public Timestamp getTimestamp() {
+        return timestamp;
+    }
+
+    /**
+     * Returns the hash code value for this code signer.
+     * The hash code is generated using the signer's certificate path and the
+     * timestamp, if present.
+     *
+     * @return a hash code value for this code signer.
+     */
+    public int hashCode() {
+        if (myhash == -1) {
+            if (timestamp == null) {
+                myhash = signerCertPath.hashCode();
+            } else {
+                myhash = signerCertPath.hashCode() + timestamp.hashCode();
+            }
+        }
+        return myhash;
+    }
+
+    /**
+     * Tests for equality between the specified object and this
+     * code signer. Two code signers are considered equal if their
+     * signer certificate paths are equal and if their timestamps are equal,
+     * if present in both.
+     *
+     * @param obj the object to test for equality with this object.
+     *
+     * @return true if the objects are considered equal, false otherwise.
+     */
+    public boolean equals(Object obj) {
+        if (obj == null || (!(obj instanceof CodeSigner))) {
+            return false;
+        }
+        CodeSigner that = (CodeSigner)obj;
+
+        if (this == that) {
+            return true;
+        }
+        Timestamp thatTimestamp = that.getTimestamp();
+        if (timestamp == null) {
+            if (thatTimestamp != null) {
+                return false;
+            }
+        } else {
+            if (thatTimestamp == null ||
+                (! timestamp.equals(thatTimestamp))) {
+                return false;
+            }
+        }
+        return signerCertPath.equals(that.getSignerCertPath());
+    }
+
+    /**
+     * Returns a string describing this code signer.
+     *
+     * @return A string comprising the signer's certificate and a timestamp,
+     *         if present.
+     */
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append("(");
+        sb.append("Signer: " + signerCertPath.getCertificates().get(0));
+        if (timestamp != null) {
+            sb.append("timestamp: " + timestamp);
+        }
+        sb.append(")");
+        return sb.toString();
+    }
+
+    // Explicitly reset hash code value to -1
+    private void readObject(ObjectInputStream ois)
+        throws IOException, ClassNotFoundException {
+     ois.defaultReadObject();
+     myhash = -1;
+    }
+}
diff --git a/java/security/CodeSource.java b/java/security/CodeSource.java
new file mode 100644
index 0000000..8e6653b
--- /dev/null
+++ b/java/security/CodeSource.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security;
+
+
+import java.net.URL;
+import java.net.SocketPermission;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Hashtable;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.security.cert.*;
+
+// Android-changed: Stubbed the implementation.  Android doesn't support SecurityManager.
+// See comments in java.lang.SecurityManager for details.
+/**
+ * Legacy security code; do not use.
+ */
+
+public class CodeSource implements java.io.Serializable {
+
+    /**
+     * The code location.
+     *
+     * @serial
+     */
+    private URL location;
+
+    public CodeSource(URL url, java.security.cert.Certificate certs[]) {
+        this.location = url;
+    }
+
+    public CodeSource(URL url, CodeSigner[] signers) {
+        this.location = url;
+    }
+
+    public final URL getLocation() {
+        /* since URL is practically immutable, returning itself is not
+           a security problem */
+        return this.location;
+    }
+
+    public final java.security.cert.Certificate[] getCertificates() { return null; }
+
+    public final CodeSigner[] getCodeSigners() { return null; }
+
+    public boolean implies(CodeSource codesource) { return true; }
+}
diff --git a/java/security/CryptoPrimitive.java b/java/security/CryptoPrimitive.java
new file mode 100644
index 0000000..158643b
--- /dev/null
+++ b/java/security/CryptoPrimitive.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2010, 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 java.security;
+
+/**
+ * An enumeration of cryptographic primitives.
+ *
+ * @since 1.7
+ */
+public enum CryptoPrimitive {
+    /**
+     * Hash function
+     */
+    MESSAGE_DIGEST,
+
+    /**
+     * Cryptographic random number generator
+     */
+    SECURE_RANDOM,
+
+    /**
+     * Symmetric primitive: block cipher
+     */
+    BLOCK_CIPHER,
+
+    /**
+     * Symmetric primitive: stream cipher
+     */
+    STREAM_CIPHER,
+
+    /**
+     * Symmetric primitive: message authentication code
+     */
+    MAC,
+
+    /**
+     * Symmetric primitive: key wrap
+     */
+    KEY_WRAP,
+
+    /**
+     * Asymmetric primitive: public key encryption
+     */
+    PUBLIC_KEY_ENCRYPTION,
+
+    /**
+     * Asymmetric primitive: signature scheme
+     */
+    SIGNATURE,
+
+    /**
+     * Asymmetric primitive: key encapsulation mechanism
+     */
+    KEY_ENCAPSULATION,
+
+    /**
+     * Asymmetric primitive: key agreement and key distribution
+     */
+    KEY_AGREEMENT
+}
diff --git a/java/security/DigestException.java b/java/security/DigestException.java
new file mode 100644
index 0000000..2327c98
--- /dev/null
+++ b/java/security/DigestException.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 1996, 2013, 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 java.security;
+
+/**
+ * This is the generic Message Digest exception.
+ *
+ * @author Benjamin Renaud
+ */
+public class DigestException extends GeneralSecurityException {
+
+    private static final long serialVersionUID = 5821450303093652515L;
+
+    /**
+     * Constructs a DigestException with no detail message.  (A
+     * detail message is a String that describes this particular
+     * exception.)
+     */
+    public DigestException() {
+        super();
+    }
+
+    /**
+     * Constructs a DigestException with the specified detail
+     * message.  (A detail message is a String that describes this
+     * particular exception.)
+     *
+     * @param msg the detail message.
+     */
+   public DigestException(String msg) {
+       super(msg);
+    }
+
+    /**
+     * Creates a {@code DigestException} with the specified
+     * detail message and cause.
+     *
+     * @param message the detail message (which is saved for later retrieval
+     *        by the {@link #getMessage()} method).
+     * @param cause the cause (which is saved for later retrieval by the
+     *        {@link #getCause()} method).  (A {@code null} value is permitted,
+     *        and indicates that the cause is nonexistent or unknown.)
+     * @since 1.5
+     */
+    public DigestException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Creates a {@code DigestException} with the specified cause
+     * and a detail message of {@code (cause==null ? null : cause.toString())}
+     * (which typically contains the class and detail message of
+     * {@code cause}).
+     *
+     * @param cause the cause (which is saved for later retrieval by the
+     *        {@link #getCause()} method).  (A {@code null} value is permitted,
+     *        and indicates that the cause is nonexistent or unknown.)
+     * @since 1.5
+     */
+    public DigestException(Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/java/security/DigestInputStream.java b/java/security/DigestInputStream.java
new file mode 100644
index 0000000..a1bf55a
--- /dev/null
+++ b/java/security/DigestInputStream.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 1996, 2013, 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 java.security;
+
+import java.io.IOException;
+import java.io.EOFException;
+import java.io.InputStream;
+import java.io.FilterInputStream;
+import java.io.PrintStream;
+import java.io.ByteArrayInputStream;
+
+/**
+ * A transparent stream that updates the associated message digest using
+ * the bits going through the stream.
+ *
+ * <p>To complete the message digest computation, call one of the
+ * {@code digest} methods on the associated message
+ * digest after your calls to one of this digest input stream's
+ * {@link #read() read} methods.
+ *
+ * <p>It is possible to turn this stream on or off (see
+ * {@link #on(boolean) on}). When it is on, a call to one of the
+ * {@code read} methods
+ * results in an update on the message digest.  But when it is off,
+ * the message digest is not updated. The default is for the stream
+ * to be on.
+ *
+ * <p>Note that digest objects can compute only one digest (see
+ * {@link MessageDigest}),
+ * so that in order to compute intermediate digests, a caller should
+ * retain a handle onto the digest object, and clone it for each
+ * digest to be computed, leaving the orginal digest untouched.
+ *
+ * @see MessageDigest
+ *
+ * @see DigestOutputStream
+ *
+ * @author Benjamin Renaud
+ */
+
+public class DigestInputStream extends FilterInputStream {
+
+    /* NOTE: This should be made a generic UpdaterInputStream */
+
+    /* Are we on or off? */
+    private boolean on = true;
+
+    /**
+     * The message digest associated with this stream.
+     */
+    protected MessageDigest digest;
+
+    /**
+     * Creates a digest input stream, using the specified input stream
+     * and message digest.
+     *
+     * @param stream the input stream.
+     *
+     * @param digest the message digest to associate with this stream.
+     */
+    public DigestInputStream(InputStream stream, MessageDigest digest) {
+        super(stream);
+        setMessageDigest(digest);
+    }
+
+    /**
+     * Returns the message digest associated with this stream.
+     *
+     * @return the message digest associated with this stream.
+     * @see #setMessageDigest(java.security.MessageDigest)
+     */
+    public MessageDigest getMessageDigest() {
+        return digest;
+    }
+
+    /**
+     * Associates the specified message digest with this stream.
+     *
+     * @param digest the message digest to be associated with this stream.
+     * @see #getMessageDigest()
+     */
+    public void setMessageDigest(MessageDigest digest) {
+        this.digest = digest;
+    }
+
+    /**
+     * Reads a byte, and updates the message digest (if the digest
+     * function is on).  That is, this method reads a byte from the
+     * input stream, blocking until the byte is actually read. If the
+     * digest function is on (see {@link #on(boolean) on}), this method
+     * will then call {@code update} on the message digest associated
+     * with this stream, passing it the byte read.
+     *
+     * @return the byte read.
+     *
+     * @exception IOException if an I/O error occurs.
+     *
+     * @see MessageDigest#update(byte)
+     */
+    public int read() throws IOException {
+        int ch = in.read();
+        if (on && ch != -1) {
+            digest.update((byte)ch);
+        }
+        return ch;
+    }
+
+    /**
+     * Reads into a byte array, and updates the message digest (if the
+     * digest function is on).  That is, this method reads up to
+     * {@code len} bytes from the input stream into the array
+     * {@code b}, starting at offset {@code off}. This method
+     * blocks until the data is actually
+     * read. If the digest function is on (see
+     * {@link #on(boolean) on}), this method will then call {@code update}
+     * on the message digest associated with this stream, passing it
+     * the data.
+     *
+     * @param b the array into which the data is read.
+     *
+     * @param off the starting offset into {@code b} of where the
+     * data should be placed.
+     *
+     * @param len the maximum number of bytes to be read from the input
+     * stream into b, starting at offset {@code off}.
+     *
+     * @return  the actual number of bytes read. This is less than
+     * {@code len} if the end of the stream is reached prior to
+     * reading {@code len} bytes. -1 is returned if no bytes were
+     * read because the end of the stream had already been reached when
+     * the call was made.
+     *
+     * @exception IOException if an I/O error occurs.
+     *
+     * @see MessageDigest#update(byte[], int, int)
+     */
+    public int read(byte[] b, int off, int len) throws IOException {
+        int result = in.read(b, off, len);
+        if (on && result != -1) {
+            digest.update(b, off, result);
+        }
+        return result;
+    }
+
+    /**
+     * Turns the digest function on or off. The default is on.  When
+     * it is on, a call to one of the {@code read} methods results in an
+     * update on the message digest.  But when it is off, the message
+     * digest is not updated.
+     *
+     * @param on true to turn the digest function on, false to turn
+     * it off.
+     */
+    public void on(boolean on) {
+        this.on = on;
+    }
+
+    /**
+     * Prints a string representation of this digest input stream and
+     * its associated message digest object.
+     */
+     public String toString() {
+         return "[Digest Input Stream] " + digest.toString();
+     }
+}
diff --git a/java/security/DigestOutputStream.java b/java/security/DigestOutputStream.java
new file mode 100644
index 0000000..4d076ca
--- /dev/null
+++ b/java/security/DigestOutputStream.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 1996, 2013, 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 java.security;
+
+import java.io.IOException;
+import java.io.EOFException;
+import java.io.OutputStream;
+import java.io.FilterOutputStream;
+import java.io.PrintStream;
+import java.io.ByteArrayOutputStream;
+
+/**
+ * A transparent stream that updates the associated message digest using
+ * the bits going through the stream.
+ *
+ * <p>To complete the message digest computation, call one of the
+ * {@code digest} methods on the associated message
+ * digest after your calls to one of this digest output stream's
+ * {@link #write(int) write} methods.
+ *
+ * <p>It is possible to turn this stream on or off (see
+ * {@link #on(boolean) on}). When it is on, a call to one of the
+ * {@code write} methods results in
+ * an update on the message digest.  But when it is off, the message
+ * digest is not updated. The default is for the stream to be on.
+ *
+ * @see MessageDigest
+ * @see DigestInputStream
+ *
+ * @author Benjamin Renaud
+ */
+public class DigestOutputStream extends FilterOutputStream {
+
+    private boolean on = true;
+
+    /**
+     * The message digest associated with this stream.
+     */
+    protected MessageDigest digest;
+
+    /**
+     * Creates a digest output stream, using the specified output stream
+     * and message digest.
+     *
+     * @param stream the output stream.
+     *
+     * @param digest the message digest to associate with this stream.
+     */
+    public DigestOutputStream(OutputStream stream, MessageDigest digest) {
+        super(stream);
+        setMessageDigest(digest);
+    }
+
+    /**
+     * Returns the message digest associated with this stream.
+     *
+     * @return the message digest associated with this stream.
+     * @see #setMessageDigest(java.security.MessageDigest)
+     */
+    public MessageDigest getMessageDigest() {
+        return digest;
+    }
+
+    /**
+     * Associates the specified message digest with this stream.
+     *
+     * @param digest the message digest to be associated with this stream.
+     * @see #getMessageDigest()
+     */
+    public void setMessageDigest(MessageDigest digest) {
+        this.digest = digest;
+    }
+
+    /**
+     * Updates the message digest (if the digest function is on) using
+     * the specified byte, and in any case writes the byte
+     * to the output stream. That is, if the digest function is on
+     * (see {@link #on(boolean) on}), this method calls
+     * {@code update} on the message digest associated with this
+     * stream, passing it the byte {@code b}. This method then
+     * writes the byte to the output stream, blocking until the byte
+     * is actually written.
+     *
+     * @param b the byte to be used for updating and writing to the
+     * output stream.
+     *
+     * @exception IOException if an I/O error occurs.
+     *
+     * @see MessageDigest#update(byte)
+     */
+    public void write(int b) throws IOException {
+        out.write(b);
+        if (on) {
+            digest.update((byte)b);
+        }
+    }
+
+    /**
+     * Updates the message digest (if the digest function is on) using
+     * the specified subarray, and in any case writes the subarray to
+     * the output stream. That is, if the digest function is on (see
+     * {@link #on(boolean) on}), this method calls {@code update}
+     * on the message digest associated with this stream, passing it
+     * the subarray specifications. This method then writes the subarray
+     * bytes to the output stream, blocking until the bytes are actually
+     * written.
+     *
+     * @param b the array containing the subarray to be used for updating
+     * and writing to the output stream.
+     *
+     * @param off the offset into {@code b} of the first byte to
+     * be updated and written.
+     *
+     * @param len the number of bytes of data to be updated and written
+     * from {@code b}, starting at offset {@code off}.
+     *
+     * @exception IOException if an I/O error occurs.
+     *
+     * @see MessageDigest#update(byte[], int, int)
+     */
+    public void write(byte[] b, int off, int len) throws IOException {
+        // BEGIN Android-added: perform checks for parameters first.
+        // See org.apache.harmony.security.tests.j.s.DigestOutputStreamTest#test_write$BII_6
+        if (b == null || off + len > b.length) {
+            throw new IllegalArgumentException("wrong parameters for write");
+        }
+        if (off < 0 || len < 0) {
+            throw new IndexOutOfBoundsException("wrong index for write");
+        }
+        // END Android-added
+        out.write(b, off, len);
+        if (on) {
+            digest.update(b, off, len);
+        }
+    }
+
+    /**
+     * Turns the digest function on or off. The default is on.  When
+     * it is on, a call to one of the {@code write} methods results in an
+     * update on the message digest.  But when it is off, the message
+     * digest is not updated.
+     *
+     * @param on true to turn the digest function on, false to turn it
+     * off.
+     */
+    public void on(boolean on) {
+        this.on = on;
+    }
+
+    /**
+     * Prints a string representation of this digest output stream and
+     * its associated message digest object.
+     */
+     public String toString() {
+         return "[Digest Output Stream] " + digest.toString();
+     }
+}
diff --git a/java/security/DomainCombiner.java b/java/security/DomainCombiner.java
new file mode 100644
index 0000000..e9c010f
--- /dev/null
+++ b/java/security/DomainCombiner.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 1999, 2013, 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 java.security;
+
+// Android-changed: Stubbed the implementation.  Android doesn't support SecurityManager.
+// See comments in java.lang.SecurityManager for details.
+/**
+ * Legacy security code; do not use.
+ */
+public interface DomainCombiner {
+
+    ProtectionDomain[] combine(ProtectionDomain[] currentDomains,
+                                ProtectionDomain[] assignedDomains);
+}
diff --git a/java/security/DomainLoadStoreParameter.java b/java/security/DomainLoadStoreParameter.java
new file mode 100644
index 0000000..bc96975
--- /dev/null
+++ b/java/security/DomainLoadStoreParameter.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2013, 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 java.security;
+
+import java.net.URI;
+import java.util.*;
+import static java.security.KeyStore.*;
+
+/**
+ * Configuration data that specifies the keystores in a keystore domain.
+ * A keystore domain is a collection of keystores that are presented as a
+ * single logical keystore. The configuration data is used during
+ * {@code KeyStore}
+ * {@link KeyStore#load(KeyStore.LoadStoreParameter) load} and
+ * {@link KeyStore#store(KeyStore.LoadStoreParameter) store} operations.
+ * <p>
+ * The following syntax is supported for configuration data:
+ * <pre>{@code
+ *     domain <domainName> [<property> ...] {
+ *         keystore <keystoreName> [<property> ...] ;
+ *         ...
+ *     };
+ *     ...
+ * }</pre>
+ * where {@code domainName} and {@code keystoreName} are identifiers
+ * and {@code property} is a key/value pairing. The key and value are
+ * separated by an 'equals' symbol and the value is enclosed in double
+ * quotes. A property value may be either a printable string or a binary
+ * string of colon-separated pairs of hexadecimal digits. Multi-valued
+ * properties are represented as a comma-separated list of values,
+ * enclosed in square brackets.
+ * See {@link Arrays#toString(java.lang.Object[])}.
+ * <p>
+ * To ensure that keystore entries are uniquely identified, each
+ * entry's alias is prefixed by its {@code keystoreName} followed
+ * by the entry name separator and each {@code keystoreName} must be
+ * unique within its domain. Entry name prefixes are omitted when
+ * storing a keystore.
+ * <p>
+ * Properties are context-sensitive: properties that apply to
+ * all the keystores in a domain are located in the domain clause,
+ * and properties that apply only to a specific keystore are located
+ * in that keystore's clause.
+ * Unless otherwise specified, a property in a keystore clause overrides
+ * a property of the same name in the domain clause. All property names
+ * are case-insensitive. The following properties are supported:
+ * <dl>
+ * <dt> {@code keystoreType="<type>"} </dt>
+ *     <dd> The keystore type. </dd>
+ * <dt> {@code keystoreURI="<url>"} </dt>
+ *     <dd> The keystore location. </dd>
+ * <dt> {@code keystoreProviderName="<name>"} </dt>
+ *     <dd> The name of the keystore's JCE provider. </dd>
+ * <dt> {@code keystorePasswordEnv="<environment-variable>"} </dt>
+ *     <dd> The environment variable that stores a keystore password.
+ *          Alternatively, passwords may be supplied to the constructor
+ *          method in a {@code Map<String, ProtectionParameter>}. </dd>
+ * <dt> {@code entryNameSeparator="<separator>"} </dt>
+ *     <dd> The separator between a keystore name prefix and an entry name.
+ *          When specified, it applies to all the entries in a domain.
+ *          Its default value is a space. </dd>
+ * </dl>
+ * <p>
+ * For example, configuration data for a simple keystore domain
+ * comprising three keystores is shown below:
+ * <pre>
+ *
+ * domain app1 {
+ *     keystore app1-truststore
+ *         keystoreURI="file:///app1/etc/truststore.jks";
+ *
+ *     keystore system-truststore
+ *         keystoreURI="${java.home}/lib/security/cacerts";
+ *
+ *     keystore app1-keystore
+ *         keystoreType="PKCS12"
+ *         keystoreURI="file:///app1/etc/keystore.p12";
+ * };
+ *
+ * </pre>
+ * @since 1.8
+ */
+public final class DomainLoadStoreParameter implements LoadStoreParameter {
+
+    private final URI configuration;
+    private final Map<String,ProtectionParameter> protectionParams;
+
+    /**
+     * Constructs a DomainLoadStoreParameter for a keystore domain with
+     * the parameters used to protect keystore data.
+     *
+     * @param configuration identifier for the domain configuration data.
+     *     The name of the target domain should be specified in the
+     *     {@code java.net.URI} fragment component when it is necessary
+     *     to distinguish between several domain configurations at the
+     *     same location.
+     *
+     * @param protectionParams the map from keystore name to the parameter
+     *     used to protect keystore data.
+     *     A {@code java.util.Collections.EMPTY_MAP} should be used
+     *     when protection parameters are not required or when they have
+     *     been specified by properties in the domain configuration data.
+     *     It is cloned to prevent subsequent modification.
+     *
+     * @exception NullPointerException if {@code configuration} or
+     *     {@code protectionParams} is {@code null}
+     */
+    public DomainLoadStoreParameter(URI configuration,
+        Map<String,ProtectionParameter> protectionParams) {
+        if (configuration == null || protectionParams == null) {
+            throw new NullPointerException("invalid null input");
+        }
+        this.configuration = configuration;
+        this.protectionParams =
+            Collections.unmodifiableMap(new HashMap<>(protectionParams));
+    }
+
+    /**
+     * Gets the identifier for the domain configuration data.
+     *
+     * @return the identifier for the configuration data
+     */
+    public URI getConfiguration() {
+        return configuration;
+    }
+
+    /**
+     * Gets the keystore protection parameters for keystores in this
+     * domain.
+     *
+     * @return an unmodifiable map of keystore names to protection
+     *     parameters
+     */
+    public Map<String,ProtectionParameter> getProtectionParams() {
+        return protectionParams;
+    }
+
+    /**
+     * Gets the keystore protection parameters for this domain.
+     * Keystore domains do not support a protection parameter.
+     *
+     * @return always returns {@code null}
+     */
+    @Override
+    public KeyStore.ProtectionParameter getProtectionParameter() {
+        return null;
+    }
+}
diff --git a/java/security/GeneralSecurityException.java b/java/security/GeneralSecurityException.java
new file mode 100644
index 0000000..dc9ea06
--- /dev/null
+++ b/java/security/GeneralSecurityException.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security;
+
+/**
+ * The {@code GeneralSecurityException} class is a generic
+ * security exception class that provides type safety for all the
+ * security-related exception classes that extend from it.
+ *
+ * @author Jan Luehe
+ */
+
+public class GeneralSecurityException extends Exception {
+
+    private static final long serialVersionUID = 894798122053539237L;
+
+    /**
+     * Constructs a GeneralSecurityException with no detail message.
+     */
+    public GeneralSecurityException() {
+        super();
+    }
+
+    /**
+     * Constructs a GeneralSecurityException with the specified detail
+     * message.
+     * A detail message is a String that describes this particular
+     * exception.
+     *
+     * @param msg the detail message.
+     */
+    public GeneralSecurityException(String msg) {
+        super(msg);
+    }
+
+    /**
+     * Creates a {@code GeneralSecurityException} with the specified
+     * detail message and cause.
+     *
+     * @param message the detail message (which is saved for later retrieval
+     *        by the {@link #getMessage()} method).
+     * @param cause the cause (which is saved for later retrieval by the
+     *        {@link #getCause()} method).  (A {@code null} value is permitted,
+     *        and indicates that the cause is nonexistent or unknown.)
+     * @since 1.5
+     */
+    public GeneralSecurityException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Creates a {@code GeneralSecurityException} with the specified cause
+     * and a detail message of {@code (cause==null ? null : cause.toString())}
+     * (which typically contains the class and detail message of
+     * {@code cause}).
+     *
+     * @param cause the cause (which is saved for later retrieval by the
+     *        {@link #getCause()} method).  (A {@code null} value is permitted,
+     *        and indicates that the cause is nonexistent or unknown.)
+     * @since 1.5
+     */
+    public GeneralSecurityException(Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/java/security/Guard.java b/java/security/Guard.java
new file mode 100644
index 0000000..abafb58
--- /dev/null
+++ b/java/security/Guard.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security;
+
+/**
+ * <p> This interface represents a guard, which is an object that is used
+ * to protect access to another object.
+ *
+ * <p>This interface contains a single method, {@code checkGuard},
+ * with a single {@code object} argument. {@code checkGuard} is
+ * invoked (by the GuardedObject {@code getObject} method)
+ * to determine whether or not to allow access to the object.
+ *
+ * @see GuardedObject
+ *
+ * @author Roland Schemers
+ * @author Li Gong
+ */
+
+public interface Guard {
+
+    /**
+     * Determines whether or not to allow access to the guarded object
+     * {@code object}. Returns silently if access is allowed.
+     * Otherwise, throws a SecurityException.
+     *
+     * @param object the object being protected by the guard.
+     *
+     * @exception SecurityException if access is denied.
+     *
+     */
+    void checkGuard(Object object) throws SecurityException;
+}
diff --git a/java/security/GuardedObject.java b/java/security/GuardedObject.java
new file mode 100644
index 0000000..a275ddf
--- /dev/null
+++ b/java/security/GuardedObject.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security;
+
+/**
+ * A GuardedObject is an object that is used to protect access to
+ * another object.
+ *
+ * <p>A GuardedObject encapsulates a target object and a Guard object,
+ * such that access to the target object is possible
+ * only if the Guard object allows it.
+ * Once an object is encapsulated by a GuardedObject,
+ * access to that object is controlled by the {@code getObject}
+ * method, which invokes the
+ * {@code checkGuard} method on the Guard object that is
+ * guarding access. If access is not allowed,
+ * an exception is thrown.
+ *
+ * @see Guard
+ * @see Permission
+ *
+ * @author Roland Schemers
+ * @author Li Gong
+ */
+
+public class GuardedObject implements java.io.Serializable {
+
+    private static final long serialVersionUID = -5240450096227834308L;
+
+    private Object object; // the object we are guarding
+    private Guard guard;   // the guard
+
+    /**
+     * Constructs a GuardedObject using the specified object and guard.
+     * If the Guard object is null, then no restrictions will
+     * be placed on who can access the object.
+     *
+     * @param object the object to be guarded.
+     *
+     * @param guard the Guard object that guards access to the object.
+     */
+
+    public GuardedObject(Object object, Guard guard)
+    {
+        this.guard = guard;
+        this.object = object;
+    }
+
+    /**
+     * Retrieves the guarded object, or throws an exception if access
+     * to the guarded object is denied by the guard.
+     *
+     * @return the guarded object.
+     *
+     * @exception SecurityException if access to the guarded object is
+     * denied.
+     */
+    public Object getObject()
+        throws SecurityException
+    {
+        if (guard != null)
+            guard.checkGuard(object);
+
+        return object;
+    }
+
+    /**
+     * Writes this object out to a stream (i.e., serializes it).
+     * We check the guard if there is one.
+     */
+    private void writeObject(java.io.ObjectOutputStream oos)
+        throws java.io.IOException
+    {
+        if (guard != null)
+            guard.checkGuard(object);
+
+        oos.defaultWriteObject();
+    }
+}
diff --git a/java/security/Identity.java b/java/security/Identity.java
new file mode 100644
index 0000000..e63131e
--- /dev/null
+++ b/java/security/Identity.java
@@ -0,0 +1,501 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * 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
+ * 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 java.security;
+
+import java.io.Serializable;
+import java.util.*;
+
+/**
+ * <p>This class represents identities: real-world objects such as people,
+ * companies or organizations whose identities can be authenticated using
+ * their public keys. Identities may also be more abstract (or concrete)
+ * constructs, such as daemon threads or smart cards.
+ *
+ * <p>All Identity objects have a name and a public key. Names are
+ * immutable. Identities may also be scoped. That is, if an Identity is
+ * specified to have a particular scope, then the name and public
+ * key of the Identity are unique within that scope.
+ *
+ * <p>An Identity also has a set of certificates (all certifying its own
+ * public key). The Principal names specified in these certificates need
+ * not be the same, only the key.
+ *
+ * <p>An Identity can be subclassed, to include postal and email addresses,
+ * telephone numbers, images of faces and logos, and so on.
+ *
+ * @see IdentityScope
+ * @see Signer
+ * @see Principal
+ *
+ * @author Benjamin Renaud
+ * @deprecated This class is no longer used. Its functionality has been
+ * replaced by {@code java.security.KeyStore}, the
+ * {@code java.security.cert} package, and
+ * {@code java.security.Principal}.
+ */
+@Deprecated
+public abstract class Identity implements Principal, Serializable {
+
+    /** use serialVersionUID from JDK 1.1.x for interoperability */
+    private static final long serialVersionUID = 3609922007826600659L;
+
+    /**
+     * The name for this identity.
+     *
+     * @serial
+     */
+    private String name;
+
+    /**
+     * The public key for this identity.
+     *
+     * @serial
+     */
+    private PublicKey publicKey;
+
+    /**
+     * Generic, descriptive information about the identity.
+     *
+     * @serial
+     */
+    String info = "No further information available.";
+
+    /**
+     * The scope of the identity.
+     *
+     * @serial
+     */
+    IdentityScope scope;
+
+    /**
+     * The certificates for this identity.
+     *
+     * @serial
+     */
+    Vector<Certificate> certificates;
+
+    /**
+     * Constructor for serialization only.
+     */
+    protected Identity() {
+        this("restoring...");
+    }
+
+    /**
+     * Constructs an identity with the specified name and scope.
+     *
+     * @param name the identity name.
+     * @param scope the scope of the identity.
+     *
+     * @exception KeyManagementException if there is already an identity
+     * with the same name in the scope.
+     */
+    public Identity(String name, IdentityScope scope) throws
+    KeyManagementException {
+        this(name);
+        if (scope != null) {
+            scope.addIdentity(this);
+        }
+        this.scope = scope;
+    }
+
+    /**
+     * Constructs an identity with the specified name and no scope.
+     *
+     * @param name the identity name.
+     */
+    public Identity(String name) {
+        this.name = name;
+    }
+
+    /**
+     * Returns this identity's name.
+     *
+     * @return the name of this identity.
+     */
+    public final String getName() {
+        return name;
+    }
+
+    /**
+     * Returns this identity's scope.
+     *
+     * @return the scope of this identity.
+     */
+    public final IdentityScope getScope() {
+        return scope;
+    }
+
+    /**
+     * Returns this identity's public key.
+     *
+     * @return the public key for this identity.
+     *
+     * @see #setPublicKey
+     */
+    public PublicKey getPublicKey() {
+        return publicKey;
+    }
+
+    /**
+     * Sets this identity's public key. The old key and all of this
+     * identity's certificates are removed by this operation.
+     *
+     * <p>First, if there is a security manager, its {@code checkSecurityAccess}
+     * method is called with {@code "setIdentityPublicKey"}
+     * as its argument to see if it's ok to set the public key.
+     *
+     * @param key the public key for this identity.
+     *
+     * @exception KeyManagementException if another identity in the
+     * identity's scope has the same public key, or if another exception occurs.
+     *
+     * @exception  SecurityException  if a security manager exists and its
+     * {@code checkSecurityAccess} method doesn't allow
+     * setting the public key.
+     *
+     * @see #getPublicKey
+     * @see SecurityManager#checkSecurityAccess
+     */
+    /* Should we throw an exception if this is already set? */
+    public void setPublicKey(PublicKey key) throws KeyManagementException {
+
+        check("setIdentityPublicKey");
+        this.publicKey = key;
+        certificates = new Vector<Certificate>();
+    }
+
+    /**
+     * Specifies a general information string for this identity.
+     *
+     * <p>First, if there is a security manager, its {@code checkSecurityAccess}
+     * method is called with {@code "setIdentityInfo"}
+     * as its argument to see if it's ok to specify the information string.
+     *
+     * @param info the information string.
+     *
+     * @exception  SecurityException  if a security manager exists and its
+     * {@code checkSecurityAccess} method doesn't allow
+     * setting the information string.
+     *
+     * @see #getInfo
+     * @see SecurityManager#checkSecurityAccess
+     */
+    public void setInfo(String info) {
+        check("setIdentityInfo");
+        this.info = info;
+    }
+
+    /**
+     * Returns general information previously specified for this identity.
+     *
+     * @return general information about this identity.
+     *
+     * @see #setInfo
+     */
+    public String getInfo() {
+        return info;
+    }
+
+    /**
+     * Adds a certificate for this identity. If the identity has a public
+     * key, the public key in the certificate must be the same, and if
+     * the identity does not have a public key, the identity's
+     * public key is set to be that specified in the certificate.
+     *
+     * <p>First, if there is a security manager, its {@code checkSecurityAccess}
+     * method is called with {@code "addIdentityCertificate"}
+     * as its argument to see if it's ok to add a certificate.
+     *
+     * @param certificate the certificate to be added.
+     *
+     * @exception KeyManagementException if the certificate is not valid,
+     * if the public key in the certificate being added conflicts with
+     * this identity's public key, or if another exception occurs.
+     *
+     * @exception  SecurityException  if a security manager exists and its
+     * {@code checkSecurityAccess} method doesn't allow
+     * adding a certificate.
+     *
+     * @see SecurityManager#checkSecurityAccess
+     */
+    public void addCertificate(Certificate certificate)
+    throws KeyManagementException {
+
+        check("addIdentityCertificate");
+
+        if (certificates == null) {
+            certificates = new Vector<Certificate>();
+        }
+        if (publicKey != null) {
+            if (!keyEquals(publicKey, certificate.getPublicKey())) {
+                throw new KeyManagementException(
+                    "public key different from cert public key");
+            }
+        } else {
+            publicKey = certificate.getPublicKey();
+        }
+        certificates.addElement(certificate);
+    }
+
+    private boolean keyEquals(PublicKey aKey, PublicKey anotherKey) {
+        String aKeyFormat = aKey.getFormat();
+        String anotherKeyFormat = anotherKey.getFormat();
+        if ((aKeyFormat == null) ^ (anotherKeyFormat == null))
+            return false;
+        if (aKeyFormat != null && anotherKeyFormat != null)
+            if (!aKeyFormat.equalsIgnoreCase(anotherKeyFormat))
+                return false;
+        return java.util.Arrays.equals(aKey.getEncoded(),
+                                     anotherKey.getEncoded());
+    }
+
+
+    /**
+     * Removes a certificate from this identity.
+     *
+     * <p>First, if there is a security manager, its {@code checkSecurityAccess}
+     * method is called with {@code "removeIdentityCertificate"}
+     * as its argument to see if it's ok to remove a certificate.
+     *
+     * @param certificate the certificate to be removed.
+     *
+     * @exception KeyManagementException if the certificate is
+     * missing, or if another exception occurs.
+     *
+     * @exception  SecurityException  if a security manager exists and its
+     * {@code checkSecurityAccess} method doesn't allow
+     * removing a certificate.
+     *
+     * @see SecurityManager#checkSecurityAccess
+     */
+    public void removeCertificate(Certificate certificate)
+    throws KeyManagementException {
+        check("removeIdentityCertificate");
+        if (certificates != null) {
+            // Android-changed: Throw a KeyManagementException if certificate is null or
+            // not contained within |certificates|.
+            if (certificate == null || !certificates.contains(certificate)) {
+                throw new KeyManagementException();
+            }
+            certificates.removeElement(certificate);
+        }
+    }
+
+    /**
+     * Returns a copy of all the certificates for this identity.
+     *
+     * @return a copy of all the certificates for this identity.
+     */
+    public Certificate[] certificates() {
+        if (certificates == null) {
+            return new Certificate[0];
+        }
+        int len = certificates.size();
+        Certificate[] certs = new Certificate[len];
+        certificates.copyInto(certs);
+        return certs;
+    }
+
+    /**
+     * Tests for equality between the specified object and this identity.
+     * This first tests to see if the entities actually refer to the same
+     * object, in which case it returns true. Next, it checks to see if
+     * the entities have the same name and the same scope. If they do,
+     * the method returns true. Otherwise, it calls
+     * {@link #identityEquals(Identity) identityEquals}, which subclasses should
+     * override.
+     *
+     * @param identity the object to test for equality with this identity.
+     *
+     * @return true if the objects are considered equal, false otherwise.
+     *
+     * @see #identityEquals
+     */
+    public final boolean equals(Object identity) {
+
+        if (identity == this) {
+            return true;
+        }
+
+        if (identity instanceof Identity) {
+            Identity i = (Identity)identity;
+            if (this.fullName().equals(i.fullName())) {
+                return true;
+            } else {
+                return identityEquals(i);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Tests for equality between the specified identity and this identity.
+     * This method should be overriden by subclasses to test for equality.
+     * The default behavior is to return true if the names and public keys
+     * are equal.
+     *
+     * @param identity the identity to test for equality with this identity.
+     *
+     * @return true if the identities are considered equal, false
+     * otherwise.
+     *
+     * @see #equals
+     */
+    protected boolean identityEquals(Identity identity) {
+        if (!name.equalsIgnoreCase(identity.name))
+            return false;
+
+        if ((publicKey == null) ^ (identity.publicKey == null))
+            return false;
+
+        if (publicKey != null && identity.publicKey != null)
+            if (!publicKey.equals(identity.publicKey))
+                return false;
+
+        return true;
+
+    }
+
+    /**
+     * Returns a parsable name for identity: identityName.scopeName
+     */
+    String fullName() {
+        String parsable = name;
+        if (scope != null) {
+            parsable += "." + scope.getName();
+        }
+        return parsable;
+    }
+
+    /**
+     * Returns a short string describing this identity, telling its
+     * name and its scope (if any).
+     *
+     * <p>First, if there is a security manager, its {@code checkSecurityAccess}
+     * method is called with {@code "printIdentity"}
+     * as its argument to see if it's ok to return the string.
+     *
+     * @return information about this identity, such as its name and the
+     * name of its scope (if any).
+     *
+     * @exception  SecurityException  if a security manager exists and its
+     * {@code checkSecurityAccess} method doesn't allow
+     * returning a string describing this identity.
+     *
+     * @see SecurityManager#checkSecurityAccess
+     */
+    public String toString() {
+        check("printIdentity");
+        String printable = name;
+        if (scope != null) {
+            printable += "[" + scope.getName() + "]";
+        }
+        return printable;
+    }
+
+    /**
+     * Returns a string representation of this identity, with
+     * optionally more details than that provided by the
+     * {@code toString} method without any arguments.
+     *
+     * <p>First, if there is a security manager, its {@code checkSecurityAccess}
+     * method is called with {@code "printIdentity"}
+     * as its argument to see if it's ok to return the string.
+     *
+     * @param detailed whether or not to provide detailed information.
+     *
+     * @return information about this identity. If {@code detailed}
+     * is true, then this method returns more information than that
+     * provided by the {@code toString} method without any arguments.
+     *
+     * @exception  SecurityException  if a security manager exists and its
+     * {@code checkSecurityAccess} method doesn't allow
+     * returning a string describing this identity.
+     *
+     * @see #toString
+     * @see SecurityManager#checkSecurityAccess
+     */
+    public String toString(boolean detailed) {
+        String out = toString();
+        if (detailed) {
+            out += "\n";
+            out += printKeys();
+            out += "\n" + printCertificates();
+            if (info != null) {
+                out += "\n\t" + info;
+            } else {
+                out += "\n\tno additional information available.";
+            }
+        }
+        return out;
+    }
+
+    String printKeys() {
+        String key = "";
+        if (publicKey != null) {
+            key = "\tpublic key initialized";
+        } else {
+            key = "\tno public key";
+        }
+        return key;
+    }
+
+    String printCertificates() {
+        String out = "";
+        if (certificates == null) {
+            return "\tno certificates";
+        } else {
+            out += "\tcertificates: \n";
+
+            int i = 1;
+            for (Certificate cert : certificates) {
+                out += "\tcertificate " + i++ +
+                    "\tfor  : " + cert.getPrincipal() + "\n";
+                out += "\t\t\tfrom : " +
+                    cert.getGuarantor() + "\n";
+            }
+        }
+        return out;
+    }
+
+    /**
+     * Returns a hashcode for this identity.
+     *
+     * @return a hashcode for this identity.
+     */
+    public int hashCode() {
+        return name.hashCode();
+    }
+
+    private static void check(String directive) {
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkSecurityAccess(directive);
+        }
+    }
+}
diff --git a/java/security/IdentityScope.java b/java/security/IdentityScope.java
new file mode 100644
index 0000000..61d37cb
--- /dev/null
+++ b/java/security/IdentityScope.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 2013, 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 java.security;
+
+import java.io.Serializable;
+import java.util.Enumeration;
+import java.util.Properties;
+
+/**
+ * <p>This class represents a scope for identities. It is an Identity
+ * itself, and therefore has a name and can have a scope. It can also
+ * optionally have a public key and associated certificates.
+ *
+ * <p>An IdentityScope can contain Identity objects of all kinds, including
+ * Signers. All types of Identity objects can be retrieved, added, and
+ * removed using the same methods. Note that it is possible, and in fact
+ * expected, that different types of identity scopes will
+ * apply different policies for their various operations on the
+ * various types of Identities.
+ *
+ * <p>There is a one-to-one mapping between keys and identities, and
+ * there can only be one copy of one key per scope. For example, suppose
+ * <b>Acme Software, Inc</b> is a software publisher known to a user.
+ * Suppose it is an Identity, that is, it has a public key, and a set of
+ * associated certificates. It is named in the scope using the name
+ * "Acme Software". No other named Identity in the scope has the same
+ * public  key. Of course, none has the same name as well.
+ *
+ * @see Identity
+ * @see Signer
+ * @see Principal
+ * @see Key
+ *
+ * @author Benjamin Renaud
+ *
+ * @deprecated This class is no longer used. Its functionality has been
+ * replaced by {@code java.security.KeyStore}, the
+ * {@code java.security.cert} package, and
+ * {@code java.security.Principal}.
+ */
+@Deprecated
+public abstract
+class IdentityScope extends Identity {
+
+    private static final long serialVersionUID = -2337346281189773310L;
+
+    /* The system's scope */
+    private static IdentityScope scope;
+
+    // initialize the system scope
+    private static void initializeSystemScope() {
+
+        String classname = AccessController.doPrivileged(
+                                new PrivilegedAction<String>() {
+            public String run() {
+                return Security.getProperty("system.scope");
+            }
+        });
+
+        if (classname == null) {
+            return;
+
+        } else {
+
+            try {
+                // Android-changed: Actually set the system scope after initializing it
+                // Class.forName(classname);
+                scope = (IdentityScope) Class.forName(classname).newInstance();
+            } catch (Exception e) {
+                //Security.error("unable to establish a system scope from " +
+                //             classname);
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * This constructor is used for serialization only and should not
+     * be used by subclasses.
+     */
+    protected IdentityScope() {
+        this("restoring...");
+    }
+
+    /**
+     * Constructs a new identity scope with the specified name.
+     *
+     * @param name the scope name.
+     */
+    public IdentityScope(String name) {
+        super(name);
+    }
+
+    /**
+     * Constructs a new identity scope with the specified name and scope.
+     *
+     * @param name the scope name.
+     * @param scope the scope for the new identity scope.
+     *
+     * @exception KeyManagementException if there is already an identity
+     * with the same name in the scope.
+     */
+    public IdentityScope(String name, IdentityScope scope)
+    throws KeyManagementException {
+        super(name, scope);
+    }
+
+    /**
+     * Returns the system's identity scope.
+     *
+     * @return the system's identity scope, or {@code null} if none has been
+     *         set.
+     *
+     * @see #setSystemScope
+     */
+    public static IdentityScope getSystemScope() {
+        if (scope == null) {
+            initializeSystemScope();
+        }
+        return scope;
+    }
+
+
+    /**
+     * Sets the system's identity scope.
+     *
+     * <p>First, if there is a security manager, its
+     * {@code checkSecurityAccess}
+     * method is called with {@code "setSystemScope"}
+     * as its argument to see if it's ok to set the identity scope.
+     *
+     * @param scope the scope to set.
+     *
+     * @exception  SecurityException  if a security manager exists and its
+     * {@code checkSecurityAccess} method doesn't allow
+     * setting the identity scope.
+     *
+     * @see #getSystemScope
+     * @see SecurityManager#checkSecurityAccess
+     */
+    protected static void setSystemScope(IdentityScope scope) {
+        check("setSystemScope");
+        IdentityScope.scope = scope;
+    }
+
+    /**
+     * Returns the number of identities within this identity scope.
+     *
+     * @return the number of identities within this identity scope.
+     */
+    public abstract int size();
+
+    /**
+     * Returns the identity in this scope with the specified name (if any).
+     *
+     * @param name the name of the identity to be retrieved.
+     *
+     * @return the identity named {@code name}, or null if there are
+     * no identities named {@code name} in this scope.
+     */
+    public abstract Identity getIdentity(String name);
+
+    /**
+     * Retrieves the identity whose name is the same as that of the
+     * specified principal. (Note: Identity implements Principal.)
+     *
+     * @param principal the principal corresponding to the identity
+     * to be retrieved.
+     *
+     * @return the identity whose name is the same as that of the
+     * principal, or null if there are no identities of the same name
+     * in this scope.
+     */
+    public Identity getIdentity(Principal principal) {
+        return getIdentity(principal.getName());
+    }
+
+    /**
+     * Retrieves the identity with the specified public key.
+     *
+     * @param key the public key for the identity to be returned.
+     *
+     * @return the identity with the given key, or null if there are
+     * no identities in this scope with that key.
+     */
+    public abstract Identity getIdentity(PublicKey key);
+
+    /**
+     * Adds an identity to this identity scope.
+     *
+     * @param identity the identity to be added.
+     *
+     * @exception KeyManagementException if the identity is not
+     * valid, a name conflict occurs, another identity has the same
+     * public key as the identity being added, or another exception
+     * occurs. */
+    public abstract void addIdentity(Identity identity)
+    throws KeyManagementException;
+
+    /**
+     * Removes an identity from this identity scope.
+     *
+     * @param identity the identity to be removed.
+     *
+     * @exception KeyManagementException if the identity is missing,
+     * or another exception occurs.
+     */
+    public abstract void removeIdentity(Identity identity)
+    throws KeyManagementException;
+
+    /**
+     * Returns an enumeration of all identities in this identity scope.
+     *
+     * @return an enumeration of all identities in this identity scope.
+     */
+    public abstract Enumeration<Identity> identities();
+
+    /**
+     * Returns a string representation of this identity scope, including
+     * its name, its scope name, and the number of identities in this
+     * identity scope.
+     *
+     * @return a string representation of this identity scope.
+     */
+    public String toString() {
+        return super.toString() + "[" + size() + "]";
+    }
+
+    private static void check(String directive) {
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkSecurityAccess(directive);
+        }
+    }
+
+}
diff --git a/java/security/InvalidAlgorithmParameterException.java b/java/security/InvalidAlgorithmParameterException.java
new file mode 100644
index 0000000..559a8be
--- /dev/null
+++ b/java/security/InvalidAlgorithmParameterException.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security;
+
+/**
+ * This is the exception for invalid or inappropriate algorithm parameters.
+ *
+ * @author Jan Luehe
+ *
+ *
+ * @see AlgorithmParameters
+ * @see java.security.spec.AlgorithmParameterSpec
+ *
+ * @since 1.2
+ */
+
+public class InvalidAlgorithmParameterException
+extends GeneralSecurityException {
+
+    private static final long serialVersionUID = 2864672297499471472L;
+
+    /**
+     * Constructs an InvalidAlgorithmParameterException with no detail
+     * message.
+     * A detail message is a String that describes this particular
+     * exception.
+     */
+    public InvalidAlgorithmParameterException() {
+        super();
+    }
+
+    /**
+     * Constructs an InvalidAlgorithmParameterException with the specified
+     * detail message.
+     * A detail message is a String that describes this
+     * particular exception.
+     *
+     * @param msg the detail message.
+     */
+    public InvalidAlgorithmParameterException(String msg) {
+        super(msg);
+    }
+
+    /**
+     * Creates a {@code InvalidAlgorithmParameterException} with the
+     * specified detail message and cause.
+     *
+     * @param message the detail message (which is saved for later retrieval
+     *        by the {@link #getMessage()} method).
+     * @param cause the cause (which is saved for later retrieval by the
+     *        {@link #getCause()} method).  (A {@code null} value is permitted,
+     *        and indicates that the cause is nonexistent or unknown.)
+     * @since 1.5
+     */
+    public InvalidAlgorithmParameterException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Creates a {@code InvalidAlgorithmParameterException} with the
+     * specified cause and a detail message of
+     * {@code (cause==null ? null : cause.toString())}
+     * (which typically contains the class and detail message of
+     * {@code cause}).
+     *
+     * @param cause the cause (which is saved for later retrieval by the
+     *        {@link #getCause()} method).  (A {@code null} value is permitted,
+     *        and indicates that the cause is nonexistent or unknown.)
+     * @since 1.5
+     */
+    public InvalidAlgorithmParameterException(Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/java/security/InvalidKeyException.java b/java/security/InvalidKeyException.java
new file mode 100644
index 0000000..35fc64c
--- /dev/null
+++ b/java/security/InvalidKeyException.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 1996, 2013, 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 java.security;
+
+/**
+ * This is the exception for invalid Keys (invalid encoding, wrong
+ * length, uninitialized, etc).
+ *
+ * @author Benjamin Renaud
+ */
+
+public class InvalidKeyException extends KeyException {
+
+    private static final long serialVersionUID = 5698479920593359816L;
+
+    /**
+     * Constructs an InvalidKeyException with no detail message. A
+     * detail message is a String that describes this particular
+     * exception.
+     */
+    public InvalidKeyException() {
+        super();
+    }
+
+    /**
+     * Constructs an InvalidKeyException with the specified detail
+     * message. A detail message is a String that describes this
+     * particular exception.
+     *
+     * @param msg the detail message.
+     */
+    public InvalidKeyException(String msg) {
+        super(msg);
+    }
+
+    /**
+     * Creates a {@code InvalidKeyException} with the specified
+     * detail message and cause.
+     *
+     * @param message the detail message (which is saved for later retrieval
+     *        by the {@link #getMessage()} method).
+     * @param cause the cause (which is saved for later retrieval by the
+     *        {@link #getCause()} method).  (A {@code null} value is permitted,
+     *        and indicates that the cause is nonexistent or unknown.)
+     * @since 1.5
+     */
+    public InvalidKeyException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Creates a {@code InvalidKeyException} with the specified cause
+     * and a detail message of {@code (cause==null ? null : cause.toString())}
+     * (which typically contains the class and detail message of
+     * {@code cause}).
+     *
+     * @param cause the cause (which is saved for later retrieval by the
+     *        {@link #getCause()} method).  (A {@code null} value is permitted,
+     *        and indicates that the cause is nonexistent or unknown.)
+     * @since 1.5
+     */
+    public InvalidKeyException(Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/java/security/InvalidParameterException.java b/java/security/InvalidParameterException.java
new file mode 100644
index 0000000..a095f90
--- /dev/null
+++ b/java/security/InvalidParameterException.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1996, 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.  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 java.security;
+
+/**
+ * This exception, designed for use by the JCA/JCE engine classes,
+ * is thrown when an invalid parameter is passed
+ * to a method.
+ *
+ * @author Benjamin Renaud
+ */
+
+public class InvalidParameterException extends IllegalArgumentException {
+
+    private static final long serialVersionUID = -857968536935667808L;
+
+    /**
+     * Constructs an InvalidParameterException with no detail message.
+     * A detail message is a String that describes this particular
+     * exception.
+     */
+    public InvalidParameterException() {
+        super();
+    }
+
+    /**
+     * Constructs an InvalidParameterException with the specified
+     * detail message.  A detail message is a String that describes
+     * this particular exception.
+     *
+     * @param msg the detail message.
+     */
+    public InvalidParameterException(String msg) {
+        super(msg);
+    }
+}
diff --git a/java/security/Key.java b/java/security/Key.java
new file mode 100644
index 0000000..c8132f4
--- /dev/null
+++ b/java/security/Key.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 1996, 2013, 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 java.security;
+
+/**
+ * The Key interface is the top-level interface for all keys. It
+ * defines the functionality shared by all key objects. All keys
+ * have three characteristics:
+ *
+ * <UL>
+ *
+ * <LI>An Algorithm
+ *
+ * <P>This is the key algorithm for that key. The key algorithm is usually
+ * an encryption or asymmetric operation algorithm (such as DSA or
+ * RSA), which will work with those algorithms and with related
+ * algorithms (such as MD5 with RSA, SHA-1 with RSA, Raw DSA, etc.)
+ * The name of the algorithm of a key is obtained using the
+ * {@link #getAlgorithm() getAlgorithm} method.
+ *
+ * <LI>An Encoded Form
+ *
+ * <P>This is an external encoded form for the key used when a standard
+ * representation of the key is needed outside the Java Virtual Machine,
+ * as when transmitting the key to some other party. The key
+ * is encoded according to a standard format (such as
+ * X.509 {@code SubjectPublicKeyInfo} or PKCS#8), and
+ * is returned using the {@link #getEncoded() getEncoded} method.
+ * Note: The syntax of the ASN.1 type {@code SubjectPublicKeyInfo}
+ * is defined as follows:
+ *
+ * <pre>
+ * SubjectPublicKeyInfo ::= SEQUENCE {
+ *   algorithm AlgorithmIdentifier,
+ *   subjectPublicKey BIT STRING }
+ *
+ * AlgorithmIdentifier ::= SEQUENCE {
+ *   algorithm OBJECT IDENTIFIER,
+ *   parameters ANY DEFINED BY algorithm OPTIONAL }
+ * </pre>
+ *
+ * For more information, see
+ * <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280:
+ * Internet X.509 Public Key Infrastructure Certificate and CRL Profile</a>.
+ *
+ * <LI>A Format
+ *
+ * <P>This is the name of the format of the encoded key. It is returned
+ * by the {@link #getFormat() getFormat} method.
+ *
+ * </UL>
+ *
+ * Keys are generally obtained through key generators, certificates,
+ * or various Identity classes used to manage keys.
+ * Keys may also be obtained from key specifications (transparent
+ * representations of the underlying key material) through the use of a key
+ * factory (see {@link KeyFactory}).
+ *
+ * <p> A Key should use KeyRep as its serialized representation.
+ * Note that a serialized Key may contain sensitive information
+ * which should not be exposed in untrusted environments.  See the
+ * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/platform/serialization/spec/security.html">
+ * Security Appendix</a>
+ * of the Serialization Specification for more information.
+ *
+ * @see PublicKey
+ * @see PrivateKey
+ * @see KeyPair
+ * @see KeyPairGenerator
+ * @see KeyFactory
+ * @see KeyRep
+ * @see java.security.spec.KeySpec
+ * @see Identity
+ * @see Signer
+ *
+ * @author Benjamin Renaud
+ */
+
+public interface Key extends java.io.Serializable {
+
+    // Declare serialVersionUID to be compatible with JDK1.1
+
+   /**
+    * The class fingerprint that is set to indicate
+    * serialization compatibility with a previous
+    * version of the class.
+    */
+    static final long serialVersionUID = 6603384152749567654L;
+
+    /**
+     * Returns the standard algorithm name for this key. For
+     * example, "DSA" would indicate that this key is a DSA key.
+     * See Appendix A in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/CryptoSpec.html#AppA">
+     * Java Cryptography Architecture API Specification &amp; Reference </a>
+     * for information about standard algorithm names.
+     *
+     * @return the name of the algorithm associated with this key.
+     */
+    public String getAlgorithm();
+
+    /**
+     * Returns the name of the primary encoding format of this key,
+     * or null if this key does not support encoding.
+     * The primary encoding format is
+     * named in terms of the appropriate ASN.1 data format, if an
+     * ASN.1 specification for this key exists.
+     * For example, the name of the ASN.1 data format for public
+     * keys is <I>SubjectPublicKeyInfo</I>, as
+     * defined by the X.509 standard; in this case, the returned format is
+     * {@code "X.509"}. Similarly,
+     * the name of the ASN.1 data format for private keys is
+     * <I>PrivateKeyInfo</I>,
+     * as defined by the PKCS #8 standard; in this case, the returned format is
+     * {@code "PKCS#8"}.
+     *
+     * @return the primary encoding format of the key.
+     */
+    public String getFormat();
+
+    /**
+     * Returns the key in its primary encoding format, or null
+     * if this key does not support encoding.
+     *
+     * @return the encoded key, or null if the key does not support
+     * encoding.
+     */
+    public byte[] getEncoded();
+}
diff --git a/java/security/KeyException.java b/java/security/KeyException.java
new file mode 100644
index 0000000..59cdd6f
--- /dev/null
+++ b/java/security/KeyException.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 1996, 2013, 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 java.security;
+
+/**
+ * This is the basic key exception.
+ *
+ * @see Key
+ * @see InvalidKeyException
+ * @see KeyManagementException
+ *
+ * @author Benjamin Renaud
+ */
+
+public class KeyException extends GeneralSecurityException {
+
+    private static final long serialVersionUID = -7483676942812432108L;
+
+    /**
+     * Constructs a KeyException with no detail message. A detail
+     * message is a String that describes this particular exception.
+     */
+    public KeyException() {
+        super();
+    }
+
+    /**
+     * Constructs a KeyException with the specified detail message.
+     * A detail message is a String that describes this particular
+     * exception.
+     *
+     * @param msg the detail message.
+     */
+    public KeyException(String msg) {
+        super(msg);
+    }
+
+    /**
+     * Creates a {@code KeyException} with the specified
+     * detail message and cause.
+     *
+     * @param message the detail message (which is saved for later retrieval
+     *        by the {@link #getMessage()} method).
+     * @param cause the cause (which is saved for later retrieval by the
+     *        {@link #getCause()} method).  (A {@code null} value is permitted,
+     *        and indicates that the cause is nonexistent or unknown.)
+     * @since 1.5
+     */
+    public KeyException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Creates a {@code KeyException} with the specified cause
+     * and a detail message of {@code (cause==null ? null : cause.toString())}
+     * (which typically contains the class and detail message of
+     * {@code cause}).
+     *
+     * @param cause the cause (which is saved for later retrieval by the
+     *        {@link #getCause()} method).  (A {@code null} value is permitted,
+     *        and indicates that the cause is nonexistent or unknown.)
+     * @since 1.5
+     */
+    public KeyException(Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/java/security/KeyFactory.java b/java/security/KeyFactory.java
new file mode 100644
index 0000000..a6b912c
--- /dev/null
+++ b/java/security/KeyFactory.java
@@ -0,0 +1,499 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security;
+
+import java.util.*;
+import java.security.Provider.Service;
+import java.security.spec.KeySpec;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.RSAPrivateKeySpec;
+
+import sun.security.util.Debug;
+import sun.security.jca.*;
+import sun.security.jca.GetInstance.Instance;
+
+/**
+ * Key factories are used to convert <I>keys</I> (opaque
+ * cryptographic keys of type {@code Key}) into <I>key specifications</I>
+ * (transparent representations of the underlying key material), and vice
+ * versa.
+ *
+ * <P> Key factories are bi-directional. That is, they allow you to build an
+ * opaque key object from a given key specification (key material), or to
+ * retrieve the underlying key material of a key object in a suitable format.
+ *
+ * <P> Multiple compatible key specifications may exist for the same key.
+ * For example, a DSA public key may be specified using
+ * {@code DSAPublicKeySpec} or
+ * {@code X509EncodedKeySpec}. A key factory can be used to translate
+ * between compatible key specifications.
+ *
+ * <P> The following is an example of how to use a key factory in order to
+ * instantiate a DSA public key from its encoding.
+ * Assume Alice has received a digital signature from Bob.
+ * Bob also sent her his public key (in encoded format) to verify
+ * his signature. Alice then performs the following actions:
+ *
+ * <pre>
+ * X509EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec(bobEncodedPubKey);
+ * KeyFactory keyFactory = KeyFactory.getInstance("DSA");
+ * PublicKey bobPubKey = keyFactory.generatePublic(bobPubKeySpec);
+ * Signature sig = Signature.getInstance("DSA");
+ * sig.initVerify(bobPubKey);
+ * sig.update(data);
+ * sig.verify(signature);
+ * </pre>
+ *
+ * <p> Android provides the following <code>KeyFactory</code> algorithms:
+ * <table>
+ *   <thead>
+ *     <tr>
+ *       <th>Algorithm</th>
+ *       <th>Supported API Levels</th>
+ *     </tr>
+ *   </thead>
+ *   <tbody>
+ *     <tr>
+ *       <td>DH</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>DSA</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>EC</td>
+ *       <td>11+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>RSA</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>X.509</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *   </tbody>
+ * </table>
+ *
+ * These algorithms are described in the <a href=
+ * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyFactory">
+ * KeyFactory section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ *
+ * @author Jan Luehe
+ *
+ * @see Key
+ * @see PublicKey
+ * @see PrivateKey
+ * @see java.security.spec.KeySpec
+ * @see java.security.spec.DSAPublicKeySpec
+ * @see java.security.spec.X509EncodedKeySpec
+ *
+ * @since 1.2
+ */
+
+public class KeyFactory {
+
+    private static final Debug debug =
+                        Debug.getInstance("jca", "KeyFactory");
+
+    // The algorithm associated with this key factory
+    private final String algorithm;
+
+    // The provider
+    private Provider provider;
+
+    // The provider implementation (delegate)
+    private volatile KeyFactorySpi spi;
+
+    // lock for mutex during provider selection
+    private final Object lock = new Object();
+
+    // remaining services to try in provider selection
+    // null once provider is selected
+    private Iterator<Service> serviceIterator;
+
+    /**
+     * Creates a KeyFactory object.
+     *
+     * @param keyFacSpi the delegate
+     * @param provider the provider
+     * @param algorithm the name of the algorithm
+     * to associate with this {@code KeyFactory}
+     */
+    protected KeyFactory(KeyFactorySpi keyFacSpi, Provider provider,
+                         String algorithm) {
+        this.spi = keyFacSpi;
+        this.provider = provider;
+        this.algorithm = algorithm;
+    }
+
+    private KeyFactory(String algorithm) throws NoSuchAlgorithmException {
+        this.algorithm = algorithm;
+        List<Service> list = GetInstance.getServices("KeyFactory", algorithm);
+        serviceIterator = list.iterator();
+        // fetch and instantiate initial spi
+        if (nextSpi(null) == null) {
+            throw new NoSuchAlgorithmException
+                (algorithm + " KeyFactory not available");
+        }
+    }
+
+    /**
+     * Returns a KeyFactory object that converts
+     * public/private keys of the specified algorithm.
+     *
+     * <p> This method traverses the list of registered security Providers,
+     * starting with the most preferred Provider.
+     * A new KeyFactory object encapsulating the
+     * KeyFactorySpi implementation from the first
+     * Provider that supports the specified algorithm is returned.
+     *
+     * <p> Note that the list of registered providers may be retrieved via
+     * the {@link Security#getProviders() Security.getProviders()} method.
+     *
+     * @param algorithm the name of the requested key algorithm.
+     * See the KeyFactory section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyFactory">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard algorithm names.
+     *
+     * @return the new KeyFactory object.
+     *
+     * @exception NoSuchAlgorithmException if no Provider supports a
+     *          KeyFactorySpi implementation for the
+     *          specified algorithm.
+     *
+     * @see Provider
+     */
+    public static KeyFactory getInstance(String algorithm)
+            throws NoSuchAlgorithmException {
+        return new KeyFactory(algorithm);
+    }
+
+    /**
+     * Returns a KeyFactory object that converts
+     * public/private keys of the specified algorithm.
+     *
+     * <p> A new KeyFactory object encapsulating the
+     * KeyFactorySpi implementation from the specified provider
+     * is returned.  The specified provider must be registered
+     * in the security provider list.
+     *
+     * <p> Note that the list of registered providers may be retrieved via
+     * the {@link Security#getProviders() Security.getProviders()} method.
+     *
+     * @param algorithm the name of the requested key algorithm.
+     * See the KeyFactory section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyFactory">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard algorithm names.
+     *
+     * @param provider the name of the provider.
+     *
+     * @return the new KeyFactory object.
+     *
+     * @exception NoSuchAlgorithmException if a KeyFactorySpi
+     *          implementation for the specified algorithm is not
+     *          available from the specified provider.
+     *
+     * @exception NoSuchProviderException if the specified provider is not
+     *          registered in the security provider list.
+     *
+     * @exception IllegalArgumentException if the provider name is null
+     *          or empty.
+     *
+     * @see Provider
+     */
+    public static KeyFactory getInstance(String algorithm, String provider)
+            throws NoSuchAlgorithmException, NoSuchProviderException {
+        Instance instance = GetInstance.getInstance("KeyFactory",
+            KeyFactorySpi.class, algorithm, provider);
+        return new KeyFactory((KeyFactorySpi)instance.impl,
+            instance.provider, algorithm);
+    }
+
+    /**
+     * Returns a KeyFactory object that converts
+     * public/private keys of the specified algorithm.
+     *
+     * <p> A new KeyFactory object encapsulating the
+     * KeyFactorySpi implementation from the specified Provider
+     * object is returned.  Note that the specified Provider object
+     * does not have to be registered in the provider list.
+     *
+     * @param algorithm the name of the requested key algorithm.
+     * See the KeyFactory section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyFactory">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard algorithm names.
+     *
+     * @param provider the provider.
+     *
+     * @return the new KeyFactory object.
+     *
+     * @exception NoSuchAlgorithmException if a KeyFactorySpi
+     *          implementation for the specified algorithm is not available
+     *          from the specified Provider object.
+     *
+     * @exception IllegalArgumentException if the specified provider is null.
+     *
+     * @see Provider
+     *
+     * @since 1.4
+     */
+    public static KeyFactory getInstance(String algorithm, Provider provider)
+            throws NoSuchAlgorithmException {
+        Instance instance = GetInstance.getInstance("KeyFactory",
+            KeyFactorySpi.class, algorithm, provider);
+        return new KeyFactory((KeyFactorySpi)instance.impl,
+            instance.provider, algorithm);
+    }
+
+    /**
+     * Returns the provider of this key factory object.
+     *
+     * @return the provider of this key factory object
+     */
+    public final Provider getProvider() {
+        synchronized (lock) {
+            // disable further failover after this call
+            serviceIterator = null;
+            return provider;
+        }
+    }
+
+    /**
+     * Gets the name of the algorithm
+     * associated with this {@code KeyFactory}.
+     *
+     * @return the name of the algorithm associated with this
+     * {@code KeyFactory}
+     */
+    public final String getAlgorithm() {
+        return this.algorithm;
+    }
+
+    /**
+     * Update the active KeyFactorySpi of this class and return the next
+     * implementation for failover. If no more implemenations are
+     * available, this method returns null. However, the active spi of
+     * this class is never set to null.
+     */
+    private KeyFactorySpi nextSpi(KeyFactorySpi oldSpi) {
+        synchronized (lock) {
+            // somebody else did a failover concurrently
+            // try that spi now
+            if ((oldSpi != null) && (oldSpi != spi)) {
+                return spi;
+            }
+            if (serviceIterator == null) {
+                return null;
+            }
+            while (serviceIterator.hasNext()) {
+                Service s = serviceIterator.next();
+                try {
+                    Object obj = s.newInstance(null);
+                    if (obj instanceof KeyFactorySpi == false) {
+                        continue;
+                    }
+                    KeyFactorySpi spi = (KeyFactorySpi)obj;
+                    provider = s.getProvider();
+                    this.spi = spi;
+                    return spi;
+                } catch (NoSuchAlgorithmException e) {
+                    // ignore
+                }
+            }
+            serviceIterator = null;
+            return null;
+        }
+    }
+
+    /**
+     * Generates a public key object from the provided key specification
+     * (key material).
+     *
+     * @param keySpec the specification (key material) of the public key.
+     *
+     * @return the public key.
+     *
+     * @exception InvalidKeySpecException if the given key specification
+     * is inappropriate for this key factory to produce a public key.
+     */
+    public final PublicKey generatePublic(KeySpec keySpec)
+            throws InvalidKeySpecException {
+        if (serviceIterator == null) {
+            return spi.engineGeneratePublic(keySpec);
+        }
+        Exception failure = null;
+        KeyFactorySpi mySpi = spi;
+        do {
+            try {
+                return mySpi.engineGeneratePublic(keySpec);
+            } catch (Exception e) {
+                if (failure == null) {
+                    failure = e;
+                }
+                mySpi = nextSpi(mySpi);
+            }
+        } while (mySpi != null);
+        if (failure instanceof RuntimeException) {
+            throw (RuntimeException)failure;
+        }
+        if (failure instanceof InvalidKeySpecException) {
+            throw (InvalidKeySpecException)failure;
+        }
+        throw new InvalidKeySpecException
+                ("Could not generate public key", failure);
+    }
+
+    /**
+     * Generates a private key object from the provided key specification
+     * (key material).
+     *
+     * @param keySpec the specification (key material) of the private key.
+     *
+     * @return the private key.
+     *
+     * @exception InvalidKeySpecException if the given key specification
+     * is inappropriate for this key factory to produce a private key.
+     */
+    public final PrivateKey generatePrivate(KeySpec keySpec)
+            throws InvalidKeySpecException {
+        if (serviceIterator == null) {
+            return spi.engineGeneratePrivate(keySpec);
+        }
+        Exception failure = null;
+        KeyFactorySpi mySpi = spi;
+        do {
+            try {
+                return mySpi.engineGeneratePrivate(keySpec);
+            } catch (Exception e) {
+                if (failure == null) {
+                    failure = e;
+                }
+                mySpi = nextSpi(mySpi);
+            }
+        } while (mySpi != null);
+        if (failure instanceof RuntimeException) {
+            throw (RuntimeException)failure;
+        }
+        if (failure instanceof InvalidKeySpecException) {
+            throw (InvalidKeySpecException)failure;
+        }
+        throw new InvalidKeySpecException
+                ("Could not generate private key", failure);
+    }
+
+    /**
+     * Returns a specification (key material) of the given key object.
+     * {@code keySpec} identifies the specification class in which
+     * the key material should be returned. It could, for example, be
+     * {@code DSAPublicKeySpec.class}, to indicate that the
+     * key material should be returned in an instance of the
+     * {@code DSAPublicKeySpec} class.
+     *
+     * @param <T> the type of the key specification to be returned
+     *
+     * @param key the key.
+     *
+     * @param keySpec the specification class in which
+     * the key material should be returned.
+     *
+     * @return the underlying key specification (key material) in an instance
+     * of the requested specification class.
+     *
+     * @exception InvalidKeySpecException if the requested key specification is
+     * inappropriate for the given key, or the given key cannot be processed
+     * (e.g., the given key has an unrecognized algorithm or format).
+     */
+    public final <T extends KeySpec> T getKeySpec(Key key, Class<T> keySpec)
+            throws InvalidKeySpecException {
+        if (serviceIterator == null) {
+            return spi.engineGetKeySpec(key, keySpec);
+        }
+        Exception failure = null;
+        KeyFactorySpi mySpi = spi;
+        do {
+            try {
+                return mySpi.engineGetKeySpec(key, keySpec);
+            } catch (Exception e) {
+                if (failure == null) {
+                    failure = e;
+                }
+                mySpi = nextSpi(mySpi);
+            }
+        } while (mySpi != null);
+        if (failure instanceof RuntimeException) {
+            throw (RuntimeException)failure;
+        }
+        if (failure instanceof InvalidKeySpecException) {
+            throw (InvalidKeySpecException)failure;
+        }
+        throw new InvalidKeySpecException
+                ("Could not get key spec", failure);
+    }
+
+    /**
+     * Translates a key object, whose provider may be unknown or potentially
+     * untrusted, into a corresponding key object of this key factory.
+     *
+     * @param key the key whose provider is unknown or untrusted.
+     *
+     * @return the translated key.
+     *
+     * @exception InvalidKeyException if the given key cannot be processed
+     * by this key factory.
+     */
+    public final Key translateKey(Key key) throws InvalidKeyException {
+        if (serviceIterator == null) {
+            return spi.engineTranslateKey(key);
+        }
+        Exception failure = null;
+        KeyFactorySpi mySpi = spi;
+        do {
+            try {
+                return mySpi.engineTranslateKey(key);
+            } catch (Exception e) {
+                if (failure == null) {
+                    failure = e;
+                }
+                mySpi = nextSpi(mySpi);
+            }
+        } while (mySpi != null);
+        if (failure instanceof RuntimeException) {
+            throw (RuntimeException)failure;
+        }
+        if (failure instanceof InvalidKeyException) {
+            throw (InvalidKeyException)failure;
+        }
+        throw new InvalidKeyException
+                ("Could not translate key", failure);
+    }
+
+}
diff --git a/java/security/KeyFactorySpi.java b/java/security/KeyFactorySpi.java
new file mode 100644
index 0000000..5ee7f45
--- /dev/null
+++ b/java/security/KeyFactorySpi.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security;
+
+import java.security.spec.KeySpec;
+import java.security.spec.InvalidKeySpecException;
+
+/**
+ * This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
+ * for the {@code KeyFactory} class.
+ * All the abstract methods in this class must be implemented by each
+ * cryptographic service provider who wishes to supply the implementation
+ * of a key factory for a particular algorithm.
+ *
+ * <P> Key factories are used to convert <I>keys</I> (opaque
+ * cryptographic keys of type {@code Key}) into <I>key specifications</I>
+ * (transparent representations of the underlying key material), and vice
+ * versa.
+ *
+ * <P> Key factories are bi-directional. That is, they allow you to build an
+ * opaque key object from a given key specification (key material), or to
+ * retrieve the underlying key material of a key object in a suitable format.
+ *
+ * <P> Multiple compatible key specifications may exist for the same key.
+ * For example, a DSA public key may be specified using
+ * {@code DSAPublicKeySpec} or
+ * {@code X509EncodedKeySpec}. A key factory can be used to translate
+ * between compatible key specifications.
+ *
+ * <P> A provider should document all the key specifications supported by its
+ * key factory.
+ *
+ * @author Jan Luehe
+ *
+ *
+ * @see KeyFactory
+ * @see Key
+ * @see PublicKey
+ * @see PrivateKey
+ * @see java.security.spec.KeySpec
+ * @see java.security.spec.DSAPublicKeySpec
+ * @see java.security.spec.X509EncodedKeySpec
+ *
+ * @since 1.2
+ */
+
+public abstract class KeyFactorySpi {
+
+    /**
+     * Generates a public key object from the provided key
+     * specification (key material).
+     *
+     * @param keySpec the specification (key material) of the public key.
+     *
+     * @return the public key.
+     *
+     * @exception InvalidKeySpecException if the given key specification
+     * is inappropriate for this key factory to produce a public key.
+     */
+    protected abstract PublicKey engineGeneratePublic(KeySpec keySpec)
+        throws InvalidKeySpecException;
+
+    /**
+     * Generates a private key object from the provided key
+     * specification (key material).
+     *
+     * @param keySpec the specification (key material) of the private key.
+     *
+     * @return the private key.
+     *
+     * @exception InvalidKeySpecException if the given key specification
+     * is inappropriate for this key factory to produce a private key.
+     */
+    protected abstract PrivateKey engineGeneratePrivate(KeySpec keySpec)
+        throws InvalidKeySpecException;
+
+    /**
+     * Returns a specification (key material) of the given key
+     * object.
+     * {@code keySpec} identifies the specification class in which
+     * the key material should be returned. It could, for example, be
+     * {@code DSAPublicKeySpec.class}, to indicate that the
+     * key material should be returned in an instance of the
+     * {@code DSAPublicKeySpec} class.
+     *
+     * @param <T> the type of the key specification to be returned
+     *
+     * @param key the key.
+     *
+     * @param keySpec the specification class in which
+     * the key material should be returned.
+     *
+     * @return the underlying key specification (key material) in an instance
+     * of the requested specification class.
+
+     * @exception InvalidKeySpecException if the requested key specification is
+     * inappropriate for the given key, or the given key cannot be dealt with
+     * (e.g., the given key has an unrecognized format).
+     */
+    protected abstract <T extends KeySpec>
+        T engineGetKeySpec(Key key, Class<T> keySpec)
+        throws InvalidKeySpecException;
+
+    /**
+     * Translates a key object, whose provider may be unknown or
+     * potentially untrusted, into a corresponding key object of this key
+     * factory.
+     *
+     * @param key the key whose provider is unknown or untrusted.
+     *
+     * @return the translated key.
+     *
+     * @exception InvalidKeyException if the given key cannot be processed
+     * by this key factory.
+     */
+    protected abstract Key engineTranslateKey(Key key)
+        throws InvalidKeyException;
+
+}
diff --git a/java/security/KeyManagementException.java b/java/security/KeyManagementException.java
new file mode 100644
index 0000000..be212b9
--- /dev/null
+++ b/java/security/KeyManagementException.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 1996, 2013, 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 java.security;
+
+/**
+ * This is the general key management exception for all operations
+ * dealing with key management. Examples of subclasses of
+ * KeyManagementException that developers might create for
+ * giving more detailed information could include:
+ *
+ * <ul>
+ * <li>KeyIDConflictException
+ * <li>KeyAuthorizationFailureException
+ * <li>ExpiredKeyException
+ * </ul>
+ *
+ * @author Benjamin Renaud
+ *
+ * @see Key
+ * @see KeyException
+ */
+
+public class KeyManagementException extends KeyException {
+
+    private static final long serialVersionUID = 947674216157062695L;
+
+    /**
+     * Constructs a KeyManagementException with no detail message. A
+     * detail message is a String that describes this particular
+     * exception.
+     */
+    public KeyManagementException() {
+        super();
+    }
+
+     /**
+     * Constructs a KeyManagementException with the specified detail
+     * message. A detail message is a String that describes this
+     * particular exception.
+     *
+     * @param msg the detail message.
+     */
+   public KeyManagementException(String msg) {
+        super(msg);
+    }
+
+    /**
+     * Creates a {@code KeyManagementException} with the specified
+     * detail message and cause.
+     *
+     * @param message the detail message (which is saved for later retrieval
+     *        by the {@link #getMessage()} method).
+     * @param cause the cause (which is saved for later retrieval by the
+     *        {@link #getCause()} method).  (A {@code null} value is permitted,
+     *        and indicates that the cause is nonexistent or unknown.)
+     * @since 1.5
+     */
+    public KeyManagementException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Creates a {@code KeyManagementException} with the specified cause
+     * and a detail message of {@code (cause==null ? null : cause.toString())}
+     * (which typically contains the class and detail message of
+     * {@code cause}).
+     *
+     * @param cause the cause (which is saved for later retrieval by the
+     *        {@link #getCause()} method).  (A {@code null} value is permitted,
+     *        and indicates that the cause is nonexistent or unknown.)
+     * @since 1.5
+     */
+    public KeyManagementException(Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/java/security/KeyPair.java b/java/security/KeyPair.java
new file mode 100644
index 0000000..6147a16
--- /dev/null
+++ b/java/security/KeyPair.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 1996, 2013, 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 java.security;
+
+import java.util.*;
+
+/**
+ * This class is a simple holder for a key pair (a public key and a
+ * private key). It does not enforce any security, and, when initialized,
+ * should be treated like a PrivateKey.
+ *
+ * @see PublicKey
+ * @see PrivateKey
+ *
+ * @author Benjamin Renaud
+ */
+
+public final class KeyPair implements java.io.Serializable {
+
+    private static final long serialVersionUID = -7565189502268009837L;
+
+    private PrivateKey privateKey;
+    private PublicKey publicKey;
+
+    /**
+     * Constructs a key pair from the given public key and private key.
+     *
+     * <p>Note that this constructor only stores references to the public
+     * and private key components in the generated key pair. This is safe,
+     * because {@code Key} objects are immutable.
+     *
+     * @param publicKey the public key.
+     *
+     * @param privateKey the private key.
+     */
+    public KeyPair(PublicKey publicKey, PrivateKey privateKey) {
+        this.publicKey = publicKey;
+        this.privateKey = privateKey;
+    }
+
+    /**
+     * Returns a reference to the public key component of this key pair.
+     *
+     * @return a reference to the public key.
+     */
+    public PublicKey getPublic() {
+        return publicKey;
+    }
+
+     /**
+     * Returns a reference to the private key component of this key pair.
+     *
+     * @return a reference to the private key.
+     */
+   public PrivateKey getPrivate() {
+        return privateKey;
+    }
+}
diff --git a/java/security/KeyPairGenerator.java b/java/security/KeyPairGenerator.java
new file mode 100644
index 0000000..68ab5e9
--- /dev/null
+++ b/java/security/KeyPairGenerator.java
@@ -0,0 +1,741 @@
+/*
+ * Copyright (c) 1997, 2014, 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 java.security;
+
+import java.util.*;
+
+import java.security.spec.AlgorithmParameterSpec;
+
+import java.security.Provider.Service;
+
+import sun.security.jca.*;
+import sun.security.jca.GetInstance.Instance;
+
+/**
+ * The KeyPairGenerator class is used to generate pairs of
+ * public and private keys. Key pair generators are constructed using the
+ * {@code getInstance} factory methods (static methods that
+ * return instances of a given class).
+ *
+ * <p>A Key pair generator for a particular algorithm creates a public/private
+ * key pair that can be used with this algorithm. It also associates
+ * algorithm-specific parameters with each of the generated keys.
+ *
+ * <p>There are two ways to generate a key pair: in an algorithm-independent
+ * manner, and in an algorithm-specific manner.
+ * The only difference between the two is the initialization of the object:
+ *
+ * <ul>
+ * <li><b>Algorithm-Independent Initialization</b>
+ * <p>All key pair generators share the concepts of a keysize and a
+ * source of randomness. The keysize is interpreted differently for different
+ * algorithms (e.g., in the case of the <i>DSA</i> algorithm, the keysize
+ * corresponds to the length of the modulus).
+ * There is an
+ * {@link #initialize(int, java.security.SecureRandom) initialize}
+ * method in this KeyPairGenerator class that takes these two universally
+ * shared types of arguments. There is also one that takes just a
+ * {@code keysize} argument, and uses the {@code SecureRandom}
+ * implementation of the highest-priority installed provider as the source
+ * of randomness. (If none of the installed providers supply an implementation
+ * of {@code SecureRandom}, a system-provided source of randomness is
+ * used.)
+ *
+ * <p>Since no other parameters are specified when you call the above
+ * algorithm-independent {@code initialize} methods, it is up to the
+ * provider what to do about the algorithm-specific parameters (if any) to be
+ * associated with each of the keys.
+ *
+ * <p>If the algorithm is the <i>DSA</i> algorithm, and the keysize (modulus
+ * size) is 512, 768, or 1024, then the <i>Sun</i> provider uses a set of
+ * precomputed values for the {@code p}, {@code q}, and
+ * {@code g} parameters. If the modulus size is not one of the above
+ * values, the <i>Sun</i> provider creates a new set of parameters. Other
+ * providers might have precomputed parameter sets for more than just the
+ * three modulus sizes mentioned above. Still others might not have a list of
+ * precomputed parameters at all and instead always create new parameter sets.
+ *
+ * <li><b>Algorithm-Specific Initialization</b>
+ * <p>For situations where a set of algorithm-specific parameters already
+ * exists (e.g., so-called <i>community parameters</i> in DSA), there are two
+ * {@link #initialize(java.security.spec.AlgorithmParameterSpec)
+ * initialize} methods that have an {@code AlgorithmParameterSpec}
+ * argument. One also has a {@code SecureRandom} argument, while the
+ * the other uses the {@code SecureRandom}
+ * implementation of the highest-priority installed provider as the source
+ * of randomness. (If none of the installed providers supply an implementation
+ * of {@code SecureRandom}, a system-provided source of randomness is
+ * used.)
+ * </ul>
+ *
+ * <p>In case the client does not explicitly initialize the KeyPairGenerator
+ * (via a call to an {@code initialize} method), each provider must
+ * supply (and document) a default initialization.
+ * For example, the <i>Sun</i> provider uses a default modulus size (keysize)
+ * of 1024 bits.
+ *
+ * <p>Note that this class is abstract and extends from
+ * {@code KeyPairGeneratorSpi} for historical reasons.
+ * Application developers should only take notice of the methods defined in
+ * this {@code KeyPairGenerator} class; all the methods in
+ * the superclass are intended for cryptographic service providers who wish to
+ * supply their own implementations of key pair generators.
+ *
+ * <p> Android provides the following <code>KeyPairGenerator</code> algorithms:
+ * <table>
+ *   <thead>
+ *     <tr>
+ *       <th>Algorithm</th>
+ *       <th>Supported API Levels</th>
+ *     </tr>
+ *   </thead>
+ *   <tbody>
+ *     <tr>
+ *       <td>DH</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>DSA</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>EC</td>
+ *       <td>11+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>RSA</td>
+ *       <td>1+</td>
+ *     </tr>
+ *   </tbody>
+ * </table>
+ *
+ * These algorithms are described in the <a href=
+ * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyPairGenerator">
+ * KeyPairGenerator section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ *
+ * @author Benjamin Renaud
+ *
+ * @see java.security.spec.AlgorithmParameterSpec
+ */
+
+public abstract class KeyPairGenerator extends KeyPairGeneratorSpi {
+
+    // Android-removed: this debugging mechanism is not used in Android.
+    /*
+    private static final Debug pdebug =
+                        Debug.getInstance("provider", "Provider");
+    private static final boolean skipDebug =
+        Debug.isOn("engine=") && !Debug.isOn("keypairgenerator");
+    */
+
+    private final String algorithm;
+
+    // The provider
+    Provider provider;
+
+    /**
+     * Creates a KeyPairGenerator object for the specified algorithm.
+     *
+     * @param algorithm the standard string name of the algorithm.
+     * See the KeyPairGenerator section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyPairGenerator">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard algorithm names.
+     */
+    protected KeyPairGenerator(String algorithm) {
+        this.algorithm = algorithm;
+    }
+
+    /**
+     * Returns the standard name of the algorithm for this key pair generator.
+     * See the KeyPairGenerator section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyPairGenerator">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard algorithm names.
+     *
+     * @return the standard string name of the algorithm.
+     */
+    public String getAlgorithm() {
+        return this.algorithm;
+    }
+
+    private static KeyPairGenerator getInstance(Instance instance,
+            String algorithm) {
+        KeyPairGenerator kpg;
+        if (instance.impl instanceof KeyPairGenerator) {
+            kpg = (KeyPairGenerator)instance.impl;
+        } else {
+            KeyPairGeneratorSpi spi = (KeyPairGeneratorSpi)instance.impl;
+            kpg = new Delegate(spi, algorithm);
+        }
+        kpg.provider = instance.provider;
+
+        // Android-removed: this debugging mechanism is not used in Android.
+        /*
+        if (!skipDebug && pdebug != null) {
+            pdebug.println("KeyPairGenerator." + algorithm +
+                " algorithm from: " + kpg.provider.getName());
+        }
+        */
+
+        return kpg;
+    }
+
+    /**
+     * Returns a KeyPairGenerator object that generates public/private
+     * key pairs for the specified algorithm.
+     *
+     * <p> This method traverses the list of registered security Providers,
+     * starting with the most preferred Provider.
+     * A new KeyPairGenerator object encapsulating the
+     * KeyPairGeneratorSpi implementation from the first
+     * Provider that supports the specified algorithm is returned.
+     *
+     * <p> Note that the list of registered providers may be retrieved via
+     * the {@link Security#getProviders() Security.getProviders()} method.
+     *
+     * @param algorithm the standard string name of the algorithm.
+     * See the KeyPairGenerator section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyPairGenerator">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard algorithm names.
+     *
+     * @return the new KeyPairGenerator object.
+     *
+     * @exception NoSuchAlgorithmException if no Provider supports a
+     *          KeyPairGeneratorSpi implementation for the
+     *          specified algorithm.
+     *
+     * @see Provider
+     */
+    public static KeyPairGenerator getInstance(String algorithm)
+            throws NoSuchAlgorithmException {
+        List<Service> list =
+                GetInstance.getServices("KeyPairGenerator", algorithm);
+        Iterator<Service> t = list.iterator();
+        if (t.hasNext() == false) {
+            throw new NoSuchAlgorithmException
+                (algorithm + " KeyPairGenerator not available");
+        }
+        // find a working Spi or KeyPairGenerator subclass
+        NoSuchAlgorithmException failure = null;
+        do {
+            Service s = t.next();
+            try {
+                Instance instance =
+                    GetInstance.getInstance(s, KeyPairGeneratorSpi.class);
+                if (instance.impl instanceof KeyPairGenerator) {
+                    return getInstance(instance, algorithm);
+                } else {
+                    return new Delegate(instance, t, algorithm);
+                }
+            } catch (NoSuchAlgorithmException e) {
+                if (failure == null) {
+                    failure = e;
+                }
+            }
+        } while (t.hasNext());
+        throw failure;
+    }
+
+    /**
+     * Returns a KeyPairGenerator object that generates public/private
+     * key pairs for the specified algorithm.
+     *
+     * <p> A new KeyPairGenerator object encapsulating the
+     * KeyPairGeneratorSpi implementation from the specified provider
+     * is returned.  The specified provider must be registered
+     * in the security provider list.
+     *
+     * <p> Note that the list of registered providers may be retrieved via
+     * the {@link Security#getProviders() Security.getProviders()} method.
+     *
+     * @param algorithm the standard string name of the algorithm.
+     * See the KeyPairGenerator section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyPairGenerator">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard algorithm names.
+     *
+     * @param provider the string name of the provider.
+     *
+     * @return the new KeyPairGenerator object.
+     *
+     * @exception NoSuchAlgorithmException if a KeyPairGeneratorSpi
+     *          implementation for the specified algorithm is not
+     *          available from the specified provider.
+     *
+     * @exception NoSuchProviderException if the specified provider is not
+     *          registered in the security provider list.
+     *
+     * @exception IllegalArgumentException if the provider name is null
+     *          or empty.
+     *
+     * @see Provider
+     */
+    public static KeyPairGenerator getInstance(String algorithm,
+            String provider)
+            throws NoSuchAlgorithmException, NoSuchProviderException {
+        Instance instance = GetInstance.getInstance("KeyPairGenerator",
+                KeyPairGeneratorSpi.class, algorithm, provider);
+        return getInstance(instance, algorithm);
+    }
+
+    /**
+     * Returns a KeyPairGenerator object that generates public/private
+     * key pairs for the specified algorithm.
+     *
+     * <p> A new KeyPairGenerator object encapsulating the
+     * KeyPairGeneratorSpi implementation from the specified Provider
+     * object is returned.  Note that the specified Provider object
+     * does not have to be registered in the provider list.
+     *
+     * @param algorithm the standard string name of the algorithm.
+     * See the KeyPairGenerator section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyPairGenerator">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard algorithm names.
+     *
+     * @param provider the provider.
+     *
+     * @return the new KeyPairGenerator object.
+     *
+     * @exception NoSuchAlgorithmException if a KeyPairGeneratorSpi
+     *          implementation for the specified algorithm is not available
+     *          from the specified Provider object.
+     *
+     * @exception IllegalArgumentException if the specified provider is null.
+     *
+     * @see Provider
+     *
+     * @since 1.4
+     */
+    public static KeyPairGenerator getInstance(String algorithm,
+            Provider provider) throws NoSuchAlgorithmException {
+        Instance instance = GetInstance.getInstance("KeyPairGenerator",
+                KeyPairGeneratorSpi.class, algorithm, provider);
+        return getInstance(instance, algorithm);
+    }
+
+    /**
+     * Returns the provider of this key pair generator object.
+     *
+     * @return the provider of this key pair generator object
+     */
+    public final Provider getProvider() {
+        disableFailover();
+        return this.provider;
+    }
+
+    void disableFailover() {
+        // empty, overridden in Delegate
+    }
+
+    /**
+     * Initializes the key pair generator for a certain keysize using
+     * a default parameter set and the {@code SecureRandom}
+     * implementation of the highest-priority installed provider as the source
+     * of randomness.
+     * (If none of the installed providers supply an implementation of
+     * {@code SecureRandom}, a system-provided source of randomness is
+     * used.)
+     *
+     * @param keysize the keysize. This is an
+     * algorithm-specific metric, such as modulus length, specified in
+     * number of bits.
+     *
+     * @exception InvalidParameterException if the {@code keysize} is not
+     * supported by this KeyPairGenerator object.
+     */
+    public void initialize(int keysize) {
+        initialize(keysize, JCAUtil.getSecureRandom());
+    }
+
+    /**
+     * Initializes the key pair generator for a certain keysize with
+     * the given source of randomness (and a default parameter set).
+     *
+     * @param keysize the keysize. This is an
+     * algorithm-specific metric, such as modulus length, specified in
+     * number of bits.
+     * @param random the source of randomness.
+     *
+     * @exception InvalidParameterException if the {@code keysize} is not
+     * supported by this KeyPairGenerator object.
+     *
+     * @since 1.2
+     */
+    public void initialize(int keysize, SecureRandom random) {
+        // This does nothing, because either
+        // 1. the implementation object returned by getInstance() is an
+        //    instance of KeyPairGenerator which has its own
+        //    initialize(keysize, random) method, so the application would
+        //    be calling that method directly, or
+        // 2. the implementation returned by getInstance() is an instance
+        //    of Delegate, in which case initialize(keysize, random) is
+        //    overridden to call the corresponding SPI method.
+        // (This is a special case, because the API and SPI method have the
+        // same name.)
+    }
+
+    /**
+     * Initializes the key pair generator using the specified parameter
+     * set and the {@code SecureRandom}
+     * implementation of the highest-priority installed provider as the source
+     * of randomness.
+     * (If none of the installed providers supply an implementation of
+     * {@code SecureRandom}, a system-provided source of randomness is
+     * used.).
+     *
+     * <p>This concrete method has been added to this previously-defined
+     * abstract class.
+     * This method calls the KeyPairGeneratorSpi
+     * {@link KeyPairGeneratorSpi#initialize(
+     * java.security.spec.AlgorithmParameterSpec,
+     * java.security.SecureRandom) initialize} method,
+     * passing it {@code params} and a source of randomness (obtained
+     * from the highest-priority installed provider or system-provided if none
+     * of the installed providers supply one).
+     * That {@code initialize} method always throws an
+     * UnsupportedOperationException if it is not overridden by the provider.
+     *
+     * @param params the parameter set used to generate the keys.
+     *
+     * @exception InvalidAlgorithmParameterException if the given parameters
+     * are inappropriate for this key pair generator.
+     *
+     * @since 1.2
+     */
+    public void initialize(AlgorithmParameterSpec params)
+            throws InvalidAlgorithmParameterException {
+        initialize(params, JCAUtil.getSecureRandom());
+    }
+
+    /**
+     * Initializes the key pair generator with the given parameter
+     * set and source of randomness.
+     *
+     * <p>This concrete method has been added to this previously-defined
+     * abstract class.
+     * This method calls the KeyPairGeneratorSpi {@link
+     * KeyPairGeneratorSpi#initialize(
+     * java.security.spec.AlgorithmParameterSpec,
+     * java.security.SecureRandom) initialize} method,
+     * passing it {@code params} and {@code random}.
+     * That {@code initialize}
+     * method always throws an
+     * UnsupportedOperationException if it is not overridden by the provider.
+     *
+     * @param params the parameter set used to generate the keys.
+     * @param random the source of randomness.
+     *
+     * @exception InvalidAlgorithmParameterException if the given parameters
+     * are inappropriate for this key pair generator.
+     *
+     * @since 1.2
+     */
+    public void initialize(AlgorithmParameterSpec params,
+                           SecureRandom random)
+        throws InvalidAlgorithmParameterException
+    {
+        // This does nothing, because either
+        // 1. the implementation object returned by getInstance() is an
+        //    instance of KeyPairGenerator which has its own
+        //    initialize(params, random) method, so the application would
+        //    be calling that method directly, or
+        // 2. the implementation returned by getInstance() is an instance
+        //    of Delegate, in which case initialize(params, random) is
+        //    overridden to call the corresponding SPI method.
+        // (This is a special case, because the API and SPI method have the
+        // same name.)
+    }
+
+    /**
+     * Generates a key pair.
+     *
+     * <p>If this KeyPairGenerator has not been initialized explicitly,
+     * provider-specific defaults will be used for the size and other
+     * (algorithm-specific) values of the generated keys.
+     *
+     * <p>This will generate a new key pair every time it is called.
+     *
+     * <p>This method is functionally equivalent to
+     * {@link #generateKeyPair() generateKeyPair}.
+     *
+     * @return the generated key pair
+     *
+     * @since 1.2
+     */
+    public final KeyPair genKeyPair() {
+        return generateKeyPair();
+    }
+
+    /**
+     * Generates a key pair.
+     *
+     * <p>If this KeyPairGenerator has not been initialized explicitly,
+     * provider-specific defaults will be used for the size and other
+     * (algorithm-specific) values of the generated keys.
+     *
+     * <p>This will generate a new key pair every time it is called.
+     *
+     * <p>This method is functionally equivalent to
+     * {@link #genKeyPair() genKeyPair}.
+     *
+     * @return the generated key pair
+     */
+    public KeyPair generateKeyPair() {
+        // This does nothing (except returning null), because either:
+        //
+        // 1. the implementation object returned by getInstance() is an
+        //    instance of KeyPairGenerator which has its own implementation
+        //    of generateKeyPair (overriding this one), so the application
+        //    would be calling that method directly, or
+        //
+        // 2. the implementation returned by getInstance() is an instance
+        //    of Delegate, in which case generateKeyPair is
+        //    overridden to invoke the corresponding SPI method.
+        //
+        // (This is a special case, because in JDK 1.1.x the generateKeyPair
+        // method was used both as an API and a SPI method.)
+        return null;
+    }
+
+
+    /*
+     * The following class allows providers to extend from KeyPairGeneratorSpi
+     * rather than from KeyPairGenerator. It represents a KeyPairGenerator
+     * with an encapsulated, provider-supplied SPI object (of type
+     * KeyPairGeneratorSpi).
+     * If the provider implementation is an instance of KeyPairGeneratorSpi,
+     * the getInstance() methods above return an instance of this class, with
+     * the SPI object encapsulated.
+     *
+     * Note: All SPI methods from the original KeyPairGenerator class have been
+     * moved up the hierarchy into a new class (KeyPairGeneratorSpi), which has
+     * been interposed in the hierarchy between the API (KeyPairGenerator)
+     * and its original parent (Object).
+     */
+
+    //
+    // error failover notes:
+    //
+    //  . we failover if the implementation throws an error during init
+    //    by retrying the init on other providers
+    //
+    //  . we also failover if the init succeeded but the subsequent call
+    //    to generateKeyPair() fails. In order for this to work, we need
+    //    to remember the parameters to the last successful call to init
+    //    and initialize() the next spi using them.
+    //
+    //  . although not specified, KeyPairGenerators could be thread safe,
+    //    so we make sure we do not interfere with that
+    //
+    //  . failover is not available, if:
+    //    . getInstance(algorithm, provider) was used
+    //    . a provider extends KeyPairGenerator rather than
+    //      KeyPairGeneratorSpi (JDK 1.1 style)
+    //    . once getProvider() is called
+    //
+
+    private static final class Delegate extends KeyPairGenerator {
+
+        // The provider implementation (delegate)
+        private volatile KeyPairGeneratorSpi spi;
+
+        private final Object lock = new Object();
+
+        private Iterator<Service> serviceIterator;
+
+        private final static int I_NONE   = 1;
+        private final static int I_SIZE   = 2;
+        private final static int I_PARAMS = 3;
+
+        private int initType;
+        private int initKeySize;
+        private AlgorithmParameterSpec initParams;
+        private SecureRandom initRandom;
+
+        // constructor
+        Delegate(KeyPairGeneratorSpi spi, String algorithm) {
+            super(algorithm);
+            this.spi = spi;
+        }
+
+        Delegate(Instance instance, Iterator<Service> serviceIterator,
+                String algorithm) {
+            super(algorithm);
+            spi = (KeyPairGeneratorSpi)instance.impl;
+            provider = instance.provider;
+            this.serviceIterator = serviceIterator;
+            initType = I_NONE;
+
+            // Android-removed: this debugging mechanism is not used in Android.
+            /*
+            if (!skipDebug && pdebug != null) {
+                pdebug.println("KeyPairGenerator." + algorithm +
+                    " algorithm from: " + provider.getName());
+            }
+            */
+        }
+
+        /**
+         * Update the active spi of this class and return the next
+         * implementation for failover. If no more implemenations are
+         * available, this method returns null. However, the active spi of
+         * this class is never set to null.
+         */
+        private KeyPairGeneratorSpi nextSpi(KeyPairGeneratorSpi oldSpi,
+                boolean reinit) {
+            synchronized (lock) {
+                // somebody else did a failover concurrently
+                // try that spi now
+                if ((oldSpi != null) && (oldSpi != spi)) {
+                    return spi;
+                }
+                if (serviceIterator == null) {
+                    return null;
+                }
+                while (serviceIterator.hasNext()) {
+                    Service s = serviceIterator.next();
+                    try {
+                        Object inst = s.newInstance(null);
+                        // ignore non-spis
+                        if (inst instanceof KeyPairGeneratorSpi == false) {
+                            continue;
+                        }
+                        if (inst instanceof KeyPairGenerator) {
+                            continue;
+                        }
+                        KeyPairGeneratorSpi spi = (KeyPairGeneratorSpi)inst;
+                        if (reinit) {
+                            if (initType == I_SIZE) {
+                                spi.initialize(initKeySize, initRandom);
+                            } else if (initType == I_PARAMS) {
+                                spi.initialize(initParams, initRandom);
+                            } else if (initType != I_NONE) {
+                                throw new AssertionError
+                                    ("KeyPairGenerator initType: " + initType);
+                            }
+                        }
+                        provider = s.getProvider();
+                        this.spi = spi;
+                        return spi;
+                    } catch (Exception e) {
+                        // ignore
+                    }
+                }
+                disableFailover();
+                return null;
+            }
+        }
+
+        void disableFailover() {
+            serviceIterator = null;
+            initType = 0;
+            initParams = null;
+            initRandom = null;
+        }
+
+        // engine method
+        public void initialize(int keysize, SecureRandom random) {
+            if (serviceIterator == null) {
+                spi.initialize(keysize, random);
+                return;
+            }
+            RuntimeException failure = null;
+            KeyPairGeneratorSpi mySpi = spi;
+            do {
+                try {
+                    mySpi.initialize(keysize, random);
+                    initType = I_SIZE;
+                    initKeySize = keysize;
+                    initParams = null;
+                    initRandom = random;
+                    return;
+                } catch (RuntimeException e) {
+                    if (failure == null) {
+                        failure = e;
+                    }
+                    mySpi = nextSpi(mySpi, false);
+                }
+            } while (mySpi != null);
+            throw failure;
+        }
+
+        // engine method
+        public void initialize(AlgorithmParameterSpec params,
+                SecureRandom random) throws InvalidAlgorithmParameterException {
+            if (serviceIterator == null) {
+                spi.initialize(params, random);
+                return;
+            }
+            Exception failure = null;
+            KeyPairGeneratorSpi mySpi = spi;
+            do {
+                try {
+                    mySpi.initialize(params, random);
+                    initType = I_PARAMS;
+                    initKeySize = 0;
+                    initParams = params;
+                    initRandom = random;
+                    return;
+                } catch (Exception e) {
+                    if (failure == null) {
+                        failure = e;
+                    }
+                    mySpi = nextSpi(mySpi, false);
+                }
+            } while (mySpi != null);
+            if (failure instanceof RuntimeException) {
+                throw (RuntimeException)failure;
+            }
+            // must be an InvalidAlgorithmParameterException
+            throw (InvalidAlgorithmParameterException)failure;
+        }
+
+        // engine method
+        public KeyPair generateKeyPair() {
+            if (serviceIterator == null) {
+                return spi.generateKeyPair();
+            }
+            RuntimeException failure = null;
+            KeyPairGeneratorSpi mySpi = spi;
+            do {
+                try {
+                    return mySpi.generateKeyPair();
+                } catch (RuntimeException e) {
+                    if (failure == null) {
+                        failure = e;
+                    }
+                    mySpi = nextSpi(mySpi, true);
+                }
+            } while (mySpi != null);
+            throw failure;
+        }
+    }
+
+}
diff --git a/java/security/KeyPairGeneratorSpi.java b/java/security/KeyPairGeneratorSpi.java
new file mode 100644
index 0000000..dfe8c04
--- /dev/null
+++ b/java/security/KeyPairGeneratorSpi.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security;
+
+import java.security.spec.AlgorithmParameterSpec;
+
+/**
+ * <p> This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
+ * for the {@code KeyPairGenerator} class, which is used to generate
+ * pairs of public and private keys.
+ *
+ * <p> All the abstract methods in this class must be implemented by each
+ * cryptographic service provider who wishes to supply the implementation
+ * of a key pair generator for a particular algorithm.
+ *
+ * <p> In case the client does not explicitly initialize the KeyPairGenerator
+ * (via a call to an {@code initialize} method), each provider must
+ * supply (and document) a default initialization.
+ * For example, the <i>Sun</i> provider uses a default modulus size (keysize)
+ * of 1024 bits.
+ *
+ * @author Benjamin Renaud
+ *
+ *
+ * @see KeyPairGenerator
+ * @see java.security.spec.AlgorithmParameterSpec
+ */
+
+public abstract class KeyPairGeneratorSpi {
+
+    /**
+     * Initializes the key pair generator for a certain keysize, using
+     * the default parameter set.
+     *
+     * @param keysize the keysize. This is an
+     * algorithm-specific metric, such as modulus length, specified in
+     * number of bits.
+     *
+     * @param random the source of randomness for this generator.
+     *
+     * @exception InvalidParameterException if the {@code keysize} is not
+     * supported by this KeyPairGeneratorSpi object.
+     */
+    public abstract void initialize(int keysize, SecureRandom random);
+
+    /**
+     * Initializes the key pair generator using the specified parameter
+     * set and user-provided source of randomness.
+     *
+     * <p>This concrete method has been added to this previously-defined
+     * abstract class. (For backwards compatibility, it cannot be abstract.)
+     * It may be overridden by a provider to initialize the key pair
+     * generator. Such an override
+     * is expected to throw an InvalidAlgorithmParameterException if
+     * a parameter is inappropriate for this key pair generator.
+     * If this method is not overridden, it always throws an
+     * UnsupportedOperationException.
+     *
+     * @param params the parameter set used to generate the keys.
+     *
+     * @param random the source of randomness for this generator.
+     *
+     * @exception InvalidAlgorithmParameterException if the given parameters
+     * are inappropriate for this key pair generator.
+     *
+     * @since 1.2
+     */
+    public void initialize(AlgorithmParameterSpec params,
+                           SecureRandom random)
+        throws InvalidAlgorithmParameterException {
+            throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Generates a key pair. Unless an initialization method is called
+     * using a KeyPairGenerator interface, algorithm-specific defaults
+     * will be used. This will generate a new key pair every time it
+     * is called.
+     *
+     * @return the newly generated {@code KeyPair}
+     */
+    public abstract KeyPair generateKeyPair();
+}
diff --git a/java/security/KeyRep.java b/java/security/KeyRep.java
new file mode 100644
index 0000000..97a6c16
--- /dev/null
+++ b/java/security/KeyRep.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2003, 2013, 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 java.security;
+
+import java.io.*;
+import java.util.Locale;
+
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.security.spec.InvalidKeySpecException;
+
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.SecretKeySpec;
+
+/**
+ * Standardized representation for serialized Key objects.
+ *
+ * <p>
+ *
+ * Note that a serialized Key may contain sensitive information
+ * which should not be exposed in untrusted environments.  See the
+ * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/platform/serialization/spec/security.html">
+ * Security Appendix</a>
+ * of the Serialization Specification for more information.
+ *
+ * @see Key
+ * @see KeyFactory
+ * @see javax.crypto.spec.SecretKeySpec
+ * @see java.security.spec.X509EncodedKeySpec
+ * @see java.security.spec.PKCS8EncodedKeySpec
+ *
+ * @since 1.5
+ */
+
+public class KeyRep implements Serializable {
+
+    private static final long serialVersionUID = -4757683898830641853L;
+
+    /**
+     * Key type.
+     *
+     * @since 1.5
+     */
+    public static enum Type {
+
+        /** Type for secret keys. */
+        SECRET,
+
+        /** Type for public keys. */
+        PUBLIC,
+
+        /** Type for private keys. */
+        PRIVATE,
+
+    }
+
+    private static final String PKCS8 = "PKCS#8";
+    private static final String X509 = "X.509";
+    private static final String RAW = "RAW";
+
+    /**
+     * Either one of Type.SECRET, Type.PUBLIC, or Type.PRIVATE
+     *
+     * @serial
+     */
+    private Type type;
+
+    /**
+     * The Key algorithm
+     *
+     * @serial
+     */
+    private String algorithm;
+
+    /**
+     * The Key encoding format
+     *
+     * @serial
+     */
+    private String format;
+
+    /**
+     * The encoded Key bytes
+     *
+     * @serial
+     */
+    private byte[] encoded;
+
+    /**
+     * Construct the alternate Key class.
+     *
+     * <p>
+     *
+     * @param type either one of Type.SECRET, Type.PUBLIC, or Type.PRIVATE
+     * @param algorithm the algorithm returned from
+     *          {@code Key.getAlgorithm()}
+     * @param format the encoding format returned from
+     *          {@code Key.getFormat()}
+     * @param encoded the encoded bytes returned from
+     *          {@code Key.getEncoded()}
+     *
+     * @exception NullPointerException
+     *          if type is {@code null},
+     *          if algorithm is {@code null},
+     *          if format is {@code null},
+     *          or if encoded is {@code null}
+     */
+    public KeyRep(Type type, String algorithm,
+                String format, byte[] encoded) {
+
+        if (type == null || algorithm == null ||
+            format == null || encoded == null) {
+            throw new NullPointerException("invalid null input(s)");
+        }
+
+        this.type = type;
+        this.algorithm = algorithm;
+        this.format = format.toUpperCase(Locale.ENGLISH);
+        this.encoded = encoded.clone();
+    }
+
+    /**
+     * Resolve the Key object.
+     *
+     * <p> This method supports three Type/format combinations:
+     * <ul>
+     * <li> Type.SECRET/"RAW" - returns a SecretKeySpec object
+     * constructed using encoded key bytes and algorithm
+     * <li> Type.PUBLIC/"X.509" - gets a KeyFactory instance for
+     * the key algorithm, constructs an X509EncodedKeySpec with the
+     * encoded key bytes, and generates a public key from the spec
+     * <li> Type.PRIVATE/"PKCS#8" - gets a KeyFactory instance for
+     * the key algorithm, constructs a PKCS8EncodedKeySpec with the
+     * encoded key bytes, and generates a private key from the spec
+     * </ul>
+     *
+     * <p>
+     *
+     * @return the resolved Key object
+     *
+     * @exception ObjectStreamException if the Type/format
+     *  combination is unrecognized, if the algorithm, key format, or
+     *  encoded key bytes are unrecognized/invalid, of if the
+     *  resolution of the key fails for any reason
+     */
+    protected Object readResolve() throws ObjectStreamException {
+        try {
+            if (type == Type.SECRET && RAW.equals(format)) {
+                return new SecretKeySpec(encoded, algorithm);
+            } else if (type == Type.PUBLIC && X509.equals(format)) {
+                KeyFactory f = KeyFactory.getInstance(algorithm);
+                return f.generatePublic(new X509EncodedKeySpec(encoded));
+            } else if (type == Type.PRIVATE && PKCS8.equals(format)) {
+                KeyFactory f = KeyFactory.getInstance(algorithm);
+                return f.generatePrivate(new PKCS8EncodedKeySpec(encoded));
+            } else {
+                throw new NotSerializableException
+                        ("unrecognized type/format combination: " +
+                        type + "/" + format);
+            }
+        } catch (NotSerializableException nse) {
+            throw nse;
+        } catch (Exception e) {
+            NotSerializableException nse = new NotSerializableException
+                                        ("java.security.Key: " +
+                                        "[" + type + "] " +
+                                        "[" + algorithm + "] " +
+                                        "[" + format + "]");
+            nse.initCause(e);
+            throw nse;
+        }
+    }
+}
diff --git a/java/security/KeyStore.java b/java/security/KeyStore.java
new file mode 100644
index 0000000..d091781
--- /dev/null
+++ b/java/security/KeyStore.java
@@ -0,0 +1,2040 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security;
+
+import java.io.*;
+import java.net.URI;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.security.cert.CertificateException;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.*;
+import javax.crypto.SecretKey;
+
+import javax.security.auth.DestroyFailedException;
+import javax.security.auth.callback.*;
+
+/**
+ * This class represents a storage facility for cryptographic
+ * keys and certificates.
+ *
+ * <p> A {@code KeyStore} manages different types of entries.
+ * Each type of entry implements the {@code KeyStore.Entry} interface.
+ * Three basic {@code KeyStore.Entry} implementations are provided:
+ *
+ * <ul>
+ * <li><b>KeyStore.PrivateKeyEntry</b>
+ * <p> This type of entry holds a cryptographic {@code PrivateKey},
+ * which is optionally stored in a protected format to prevent
+ * unauthorized access.  It is also accompanied by a certificate chain
+ * for the corresponding public key.
+ *
+ * <p> Private keys and certificate chains are used by a given entity for
+ * self-authentication. Applications for this authentication include software
+ * distribution organizations which sign JAR files as part of releasing
+ * and/or licensing software.
+ *
+ * <li><b>KeyStore.SecretKeyEntry</b>
+ * <p> This type of entry holds a cryptographic {@code SecretKey},
+ * which is optionally stored in a protected format to prevent
+ * unauthorized access.
+ *
+ * <li><b>KeyStore.TrustedCertificateEntry</b>
+ * <p> This type of entry contains a single public key {@code Certificate}
+ * belonging to another party. It is called a <i>trusted certificate</i>
+ * because the keystore owner trusts that the public key in the certificate
+ * indeed belongs to the identity identified by the <i>subject</i> (owner)
+ * of the certificate.
+ *
+ * <p>This type of entry can be used to authenticate other parties.
+ * </ul>
+ *
+ * <p> Each entry in a keystore is identified by an "alias" string. In the
+ * case of private keys and their associated certificate chains, these strings
+ * distinguish among the different ways in which the entity may authenticate
+ * itself. For example, the entity may authenticate itself using different
+ * certificate authorities, or using different public key algorithms.
+ *
+ * <p> Whether aliases are case sensitive is implementation dependent. In order
+ * to avoid problems, it is recommended not to use aliases in a KeyStore that
+ * only differ in case.
+ *
+ * <p> Whether keystores are persistent, and the mechanisms used by the
+ * keystore if it is persistent, are not specified here. This allows
+ * use of a variety of techniques for protecting sensitive (e.g., private or
+ * secret) keys. Smart cards or other integrated cryptographic engines
+ * (SafeKeyper) are one option, and simpler mechanisms such as files may also
+ * be used (in a variety of formats).
+ *
+ * <p> Typical ways to request a KeyStore object include
+ * relying on the default type and providing a specific keystore type.
+ *
+ * <ul>
+ * <li>To rely on the default type:
+ * <pre>
+ *    KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+ * </pre>
+ * The system will return a keystore implementation for the default type.
+ *
+ * <li>To provide a specific keystore type:
+ * <pre>
+ *      KeyStore ks = KeyStore.getInstance("JKS");
+ * </pre>
+ * The system will return the most preferred implementation of the
+ * specified keystore type available in the environment. <p>
+ * </ul>
+ *
+ * <p> Before a keystore can be accessed, it must be
+ * {@link #load(java.io.InputStream, char[]) loaded}.
+ * <pre>
+ *    KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+ *
+ *    // get user password and file input stream
+ *    char[] password = getPassword();
+ *
+ *    try (FileInputStream fis = new FileInputStream("keyStoreName")) {
+ *        ks.load(fis, password);
+ *    }
+ * </pre>
+ *
+ * To create an empty keystore using the above {@code load} method,
+ * pass {@code null} as the {@code InputStream} argument.
+ *
+ * <p> Once the keystore has been loaded, it is possible
+ * to read existing entries from the keystore, or to write new entries
+ * into the keystore:
+ * <pre>
+ *    KeyStore.ProtectionParameter protParam =
+ *        new KeyStore.PasswordProtection(password);
+ *
+ *    // get my private key
+ *    KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry)
+ *        ks.getEntry("privateKeyAlias", protParam);
+ *    PrivateKey myPrivateKey = pkEntry.getPrivateKey();
+ *
+ *    // save my secret key
+ *    javax.crypto.SecretKey mySecretKey;
+ *    KeyStore.SecretKeyEntry skEntry =
+ *        new KeyStore.SecretKeyEntry(mySecretKey);
+ *    ks.setEntry("secretKeyAlias", skEntry, protParam);
+ *
+ *    // store away the keystore
+ *    try (FileOutputStream fos = new FileOutputStream("newKeyStoreName")) {
+ *        ks.store(fos, password);
+ *    }
+ * </pre>
+ *
+ * Note that although the same password may be used to
+ * load the keystore, to protect the private key entry,
+ * to protect the secret key entry, and to store the keystore
+ * (as is shown in the sample code above),
+ * different passwords or other protection parameters
+ * may also be used.
+ *
+ * <p> Android provides the following <code>KeyStore</code> types:
+ * <table>
+ *   <thead>
+ *     <tr>
+ *       <th>Algorithm</th>
+ *       <th>Supported API Levels</th>
+ *     </tr>
+ *   </thead>
+ *   <tbody>
+ *     <tr>
+ *       <td>AndroidCAStore</td>
+ *       <td>14+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>AndroidKeyStore</td>
+ *       <td>18+</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>BCPKCS12</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr>
+ *       <td>BKS</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>BouncyCastle</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PKCS12</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>PKCS12-DEF</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *   </tbody>
+ * </table>
+ *
+ * These types are described in the <a href=
+ * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyStore">
+ * KeyStore section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ *
+ * @author Jan Luehe
+ *
+ * @see java.security.PrivateKey
+ * @see javax.crypto.SecretKey
+ * @see java.security.cert.Certificate
+ *
+ * @since 1.2
+ */
+
+public class KeyStore {
+
+    // BEGIN Android-removed: this debugging mechanism is not supported in Android.
+    /*
+    private static final Debug pdebug =
+                        Debug.getInstance("provider", "Provider");
+    private static final boolean skipDebug =
+        Debug.isOn("engine=") && !Debug.isOn("keystore");
+    */
+    // END Android-removed: this debugging mechanism is not supported in Android.
+
+    /*
+     * Constant to lookup in the Security properties file to determine
+     * the default keystore type.
+     * In the Security properties file, the default keystore type is given as:
+     * <pre>
+     * keystore.type=jks
+     * </pre>
+     */
+    private static final String KEYSTORE_TYPE = "keystore.type";
+
+    // The keystore type
+    private String type;
+
+    // The provider
+    private Provider provider;
+
+    // The provider implementation
+    private KeyStoreSpi keyStoreSpi;
+
+    // Has this keystore been initialized (loaded)?
+    private boolean initialized = false;
+
+    /**
+     * A marker interface for {@code KeyStore}
+     * {@link #load(KeyStore.LoadStoreParameter) load}
+     * and
+     * {@link #store(KeyStore.LoadStoreParameter) store}
+     * parameters.
+     *
+     * @since 1.5
+     */
+    public static interface LoadStoreParameter {
+        /**
+         * Gets the parameter used to protect keystore data.
+         *
+         * @return the parameter used to protect keystore data, or null
+         */
+        public ProtectionParameter getProtectionParameter();
+    }
+
+    /**
+     * A marker interface for keystore protection parameters.
+     *
+     * <p> The information stored in a {@code ProtectionParameter}
+     * object protects the contents of a keystore.
+     * For example, protection parameters may be used to check
+     * the integrity of keystore data, or to protect the
+     * confidentiality of sensitive keystore data
+     * (such as a {@code PrivateKey}).
+     *
+     * @since 1.5
+     */
+    public static interface ProtectionParameter { }
+
+    /**
+     * A password-based implementation of {@code ProtectionParameter}.
+     *
+     * @since 1.5
+     */
+    public static class PasswordProtection implements
+                ProtectionParameter, javax.security.auth.Destroyable {
+
+        private final char[] password;
+        private final String protectionAlgorithm;
+        private final AlgorithmParameterSpec protectionParameters;
+        private volatile boolean destroyed = false;
+
+        /**
+         * Creates a password parameter.
+         *
+         * <p> The specified {@code password} is cloned before it is stored
+         * in the new {@code PasswordProtection} object.
+         *
+         * @param password the password, which may be {@code null}
+         */
+        public PasswordProtection(char[] password) {
+            this.password = (password == null) ? null : password.clone();
+            this.protectionAlgorithm = null;
+            this.protectionParameters = null;
+        }
+
+        /**
+         * Creates a password parameter and specifies the protection algorithm
+         * and associated parameters to use when encrypting a keystore entry.
+         * <p>
+         * The specified {@code password} is cloned before it is stored in the
+         * new {@code PasswordProtection} object.
+         *
+         * @param password the password, which may be {@code null}
+         * @param protectionAlgorithm the encryption algorithm name, for
+         *     example, {@code PBEWithHmacSHA256AndAES_256}.
+         *     See the Cipher section in the <a href=
+         * "{@docRoot}/../technotes/guides/security/StandardNames.html#Cipher">
+         * Java Cryptography Architecture Standard Algorithm Name
+         * Documentation</a>
+         *     for information about standard encryption algorithm names.
+         * @param protectionParameters the encryption algorithm parameter
+         *     specification, which may be {@code null}
+         * @exception NullPointerException if {@code protectionAlgorithm} is
+         *     {@code null}
+         *
+         * @since 1.8
+         */
+        public PasswordProtection(char[] password, String protectionAlgorithm,
+            AlgorithmParameterSpec protectionParameters) {
+            if (protectionAlgorithm == null) {
+                throw new NullPointerException("invalid null input");
+            }
+            this.password = (password == null) ? null : password.clone();
+            this.protectionAlgorithm = protectionAlgorithm;
+            this.protectionParameters = protectionParameters;
+        }
+
+        /**
+         * Gets the name of the protection algorithm.
+         * If none was set then the keystore provider will use its default
+         * protection algorithm. The name of the default protection algorithm
+         * for a given keystore type is set using the
+         * {@code 'keystore.<type>.keyProtectionAlgorithm'} security property.
+         * For example, the
+         * {@code keystore.PKCS12.keyProtectionAlgorithm} property stores the
+         * name of the default key protection algorithm used for PKCS12
+         * keystores. If the security property is not set, an
+         * implementation-specific algorithm will be used.
+         *
+         * @return the algorithm name, or {@code null} if none was set
+         *
+         * @since 1.8
+         */
+        public String getProtectionAlgorithm() {
+            return protectionAlgorithm;
+        }
+
+        /**
+         * Gets the parameters supplied for the protection algorithm.
+         *
+         * @return the algorithm parameter specification, or {@code  null},
+         *     if none was set
+         *
+         * @since 1.8
+         */
+        public AlgorithmParameterSpec getProtectionParameters() {
+            return protectionParameters;
+        }
+
+        /**
+         * Gets the password.
+         *
+         * <p>Note that this method returns a reference to the password.
+         * If a clone of the array is created it is the caller's
+         * responsibility to zero out the password information
+         * after it is no longer needed.
+         *
+         * @see #destroy()
+         * @return the password, which may be {@code null}
+         * @exception IllegalStateException if the password has
+         *              been cleared (destroyed)
+         */
+        public synchronized char[] getPassword() {
+            if (destroyed) {
+                throw new IllegalStateException("password has been cleared");
+            }
+            return password;
+        }
+
+        /**
+         * Clears the password.
+         *
+         * @exception DestroyFailedException if this method was unable
+         *      to clear the password
+         */
+        public synchronized void destroy() throws DestroyFailedException {
+            destroyed = true;
+            if (password != null) {
+                Arrays.fill(password, ' ');
+            }
+        }
+
+        /**
+         * Determines if password has been cleared.
+         *
+         * @return true if the password has been cleared, false otherwise
+         */
+        public synchronized boolean isDestroyed() {
+            return destroyed;
+        }
+    }
+
+    /**
+     * A ProtectionParameter encapsulating a CallbackHandler.
+     *
+     * @since 1.5
+     */
+    public static class CallbackHandlerProtection
+            implements ProtectionParameter {
+
+        private final CallbackHandler handler;
+
+        /**
+         * Constructs a new CallbackHandlerProtection from a
+         * CallbackHandler.
+         *
+         * @param handler the CallbackHandler
+         * @exception NullPointerException if handler is null
+         */
+        public CallbackHandlerProtection(CallbackHandler handler) {
+            if (handler == null) {
+                throw new NullPointerException("handler must not be null");
+            }
+            this.handler = handler;
+        }
+
+        /**
+         * Returns the CallbackHandler.
+         *
+         * @return the CallbackHandler.
+         */
+        public CallbackHandler getCallbackHandler() {
+            return handler;
+        }
+
+    }
+
+    /**
+     * A marker interface for {@code KeyStore} entry types.
+     *
+     * @since 1.5
+     */
+    public static interface Entry {
+
+        /**
+         * Retrieves the attributes associated with an entry.
+         * <p>
+         * The default implementation returns an empty {@code Set}.
+         *
+         * @return an unmodifiable {@code Set} of attributes, possibly empty
+         *
+         * @since 1.8
+         */
+        public default Set<Attribute> getAttributes() {
+            return Collections.<Attribute>emptySet();
+        }
+
+        /**
+         * An attribute associated with a keystore entry.
+         * It comprises a name and one or more values.
+         *
+         * @since 1.8
+         */
+        public interface Attribute {
+            /**
+             * Returns the attribute's name.
+             *
+             * @return the attribute name
+             */
+            public String getName();
+
+            /**
+             * Returns the attribute's value.
+             * Multi-valued attributes encode their values as a single string.
+             *
+             * @return the attribute value
+             */
+            public String getValue();
+        }
+    }
+
+    /**
+     * A {@code KeyStore} entry that holds a {@code PrivateKey}
+     * and corresponding certificate chain.
+     *
+     * @since 1.5
+     */
+    public static final class PrivateKeyEntry implements Entry {
+
+        private final PrivateKey privKey;
+        private final Certificate[] chain;
+        private final Set<Attribute> attributes;
+
+        /**
+         * Constructs a {@code PrivateKeyEntry} with a
+         * {@code PrivateKey} and corresponding certificate chain.
+         *
+         * <p> The specified {@code chain} is cloned before it is stored
+         * in the new {@code PrivateKeyEntry} object.
+         *
+         * @param privateKey the {@code PrivateKey}
+         * @param chain an array of {@code Certificate}s
+         *      representing the certificate chain.
+         *      The chain must be ordered and contain a
+         *      {@code Certificate} at index 0
+         *      corresponding to the private key.
+         *
+         * @exception NullPointerException if
+         *      {@code privateKey} or {@code chain}
+         *      is {@code null}
+         * @exception IllegalArgumentException if the specified chain has a
+         *      length of 0, if the specified chain does not contain
+         *      {@code Certificate}s of the same type,
+         *      or if the {@code PrivateKey} algorithm
+         *      does not match the algorithm of the {@code PublicKey}
+         *      in the end entity {@code Certificate} (at index 0)
+         */
+        public PrivateKeyEntry(PrivateKey privateKey, Certificate[] chain) {
+            this(privateKey, chain, Collections.<Attribute>emptySet());
+        }
+
+        /**
+         * Constructs a {@code PrivateKeyEntry} with a {@code PrivateKey} and
+         * corresponding certificate chain and associated entry attributes.
+         *
+         * <p> The specified {@code chain} and {@code attributes} are cloned
+         * before they are stored in the new {@code PrivateKeyEntry} object.
+         *
+         * @param privateKey the {@code PrivateKey}
+         * @param chain an array of {@code Certificate}s
+         *      representing the certificate chain.
+         *      The chain must be ordered and contain a
+         *      {@code Certificate} at index 0
+         *      corresponding to the private key.
+         * @param attributes the attributes
+         *
+         * @exception NullPointerException if {@code privateKey}, {@code chain}
+         *      or {@code attributes} is {@code null}
+         * @exception IllegalArgumentException if the specified chain has a
+         *      length of 0, if the specified chain does not contain
+         *      {@code Certificate}s of the same type,
+         *      or if the {@code PrivateKey} algorithm
+         *      does not match the algorithm of the {@code PublicKey}
+         *      in the end entity {@code Certificate} (at index 0)
+         *
+         * @since 1.8
+         */
+        public PrivateKeyEntry(PrivateKey privateKey, Certificate[] chain,
+           Set<Attribute> attributes) {
+
+            if (privateKey == null || chain == null || attributes == null) {
+                throw new NullPointerException("invalid null input");
+            }
+            if (chain.length == 0) {
+                throw new IllegalArgumentException
+                                ("invalid zero-length input chain");
+            }
+
+            Certificate[] clonedChain = chain.clone();
+            String certType = clonedChain[0].getType();
+            for (int i = 1; i < clonedChain.length; i++) {
+                if (!certType.equals(clonedChain[i].getType())) {
+                    throw new IllegalArgumentException
+                                ("chain does not contain certificates " +
+                                "of the same type");
+                }
+            }
+            if (!privateKey.getAlgorithm().equals
+                        (clonedChain[0].getPublicKey().getAlgorithm())) {
+                throw new IllegalArgumentException
+                                ("private key algorithm does not match " +
+                                "algorithm of public key in end entity " +
+                                "certificate (at index 0)");
+            }
+            this.privKey = privateKey;
+
+            if (clonedChain[0] instanceof X509Certificate &&
+                !(clonedChain instanceof X509Certificate[])) {
+
+                this.chain = new X509Certificate[clonedChain.length];
+                System.arraycopy(clonedChain, 0,
+                                this.chain, 0, clonedChain.length);
+            } else {
+                this.chain = clonedChain;
+            }
+
+            this.attributes =
+                Collections.unmodifiableSet(new HashSet<>(attributes));
+        }
+
+        /**
+         * Gets the {@code PrivateKey} from this entry.
+         *
+         * @return the {@code PrivateKey} from this entry
+         */
+        public PrivateKey getPrivateKey() {
+            return privKey;
+        }
+
+        /**
+         * Gets the {@code Certificate} chain from this entry.
+         *
+         * <p> The stored chain is cloned before being returned.
+         *
+         * @return an array of {@code Certificate}s corresponding
+         *      to the certificate chain for the public key.
+         *      If the certificates are of type X.509,
+         *      the runtime type of the returned array is
+         *      {@code X509Certificate[]}.
+         */
+        public Certificate[] getCertificateChain() {
+            return chain.clone();
+        }
+
+        /**
+         * Gets the end entity {@code Certificate}
+         * from the certificate chain in this entry.
+         *
+         * @return the end entity {@code Certificate} (at index 0)
+         *      from the certificate chain in this entry.
+         *      If the certificate is of type X.509,
+         *      the runtime type of the returned certificate is
+         *      {@code X509Certificate}.
+         */
+        public Certificate getCertificate() {
+            return chain[0];
+        }
+
+        /**
+         * Retrieves the attributes associated with an entry.
+         * <p>
+         *
+         * @return an unmodifiable {@code Set} of attributes, possibly empty
+         *
+         * @since 1.8
+         */
+        @Override
+        public Set<Attribute> getAttributes() {
+            return attributes;
+        }
+
+        /**
+         * Returns a string representation of this PrivateKeyEntry.
+         * @return a string representation of this PrivateKeyEntry.
+         */
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append("Private key entry and certificate chain with "
+                + chain.length + " elements:\r\n");
+            for (Certificate cert : chain) {
+                sb.append(cert);
+                sb.append("\r\n");
+            }
+            return sb.toString();
+        }
+
+    }
+
+    /**
+     * A {@code KeyStore} entry that holds a {@code SecretKey}.
+     *
+     * @since 1.5
+     */
+    public static final class SecretKeyEntry implements Entry {
+
+        private final SecretKey sKey;
+        private final Set<Attribute> attributes;
+
+        /**
+         * Constructs a {@code SecretKeyEntry} with a
+         * {@code SecretKey}.
+         *
+         * @param secretKey the {@code SecretKey}
+         *
+         * @exception NullPointerException if {@code secretKey}
+         *      is {@code null}
+         */
+        public SecretKeyEntry(SecretKey secretKey) {
+            if (secretKey == null) {
+                throw new NullPointerException("invalid null input");
+            }
+            this.sKey = secretKey;
+            this.attributes = Collections.<Attribute>emptySet();
+        }
+
+        /**
+         * Constructs a {@code SecretKeyEntry} with a {@code SecretKey} and
+         * associated entry attributes.
+         *
+         * <p> The specified {@code attributes} is cloned before it is stored
+         * in the new {@code SecretKeyEntry} object.
+         *
+         * @param secretKey the {@code SecretKey}
+         * @param attributes the attributes
+         *
+         * @exception NullPointerException if {@code secretKey} or
+         *     {@code attributes} is {@code null}
+         *
+         * @since 1.8
+         */
+        public SecretKeyEntry(SecretKey secretKey, Set<Attribute> attributes) {
+
+            if (secretKey == null || attributes == null) {
+                throw new NullPointerException("invalid null input");
+            }
+            this.sKey = secretKey;
+            this.attributes =
+                Collections.unmodifiableSet(new HashSet<>(attributes));
+        }
+
+        /**
+         * Gets the {@code SecretKey} from this entry.
+         *
+         * @return the {@code SecretKey} from this entry
+         */
+        public SecretKey getSecretKey() {
+            return sKey;
+        }
+
+        /**
+         * Retrieves the attributes associated with an entry.
+         * <p>
+         *
+         * @return an unmodifiable {@code Set} of attributes, possibly empty
+         *
+         * @since 1.8
+         */
+        @Override
+        public Set<Attribute> getAttributes() {
+            return attributes;
+        }
+
+        /**
+         * Returns a string representation of this SecretKeyEntry.
+         * @return a string representation of this SecretKeyEntry.
+         */
+        public String toString() {
+            return "Secret key entry with algorithm " + sKey.getAlgorithm();
+        }
+    }
+
+    /**
+     * A {@code KeyStore} entry that holds a trusted
+     * {@code Certificate}.
+     *
+     * @since 1.5
+     */
+    public static final class TrustedCertificateEntry implements Entry {
+
+        private final Certificate cert;
+        private final Set<Attribute> attributes;
+
+        /**
+         * Constructs a {@code TrustedCertificateEntry} with a
+         * trusted {@code Certificate}.
+         *
+         * @param trustedCert the trusted {@code Certificate}
+         *
+         * @exception NullPointerException if
+         *      {@code trustedCert} is {@code null}
+         */
+        public TrustedCertificateEntry(Certificate trustedCert) {
+            if (trustedCert == null) {
+                throw new NullPointerException("invalid null input");
+            }
+            this.cert = trustedCert;
+            this.attributes = Collections.<Attribute>emptySet();
+        }
+
+        /**
+         * Constructs a {@code TrustedCertificateEntry} with a
+         * trusted {@code Certificate} and associated entry attributes.
+         *
+         * <p> The specified {@code attributes} is cloned before it is stored
+         * in the new {@code TrustedCertificateEntry} object.
+         *
+         * @param trustedCert the trusted {@code Certificate}
+         * @param attributes the attributes
+         *
+         * @exception NullPointerException if {@code trustedCert} or
+         *     {@code attributes} is {@code null}
+         *
+         * @since 1.8
+         */
+        public TrustedCertificateEntry(Certificate trustedCert,
+           Set<Attribute> attributes) {
+            if (trustedCert == null || attributes == null) {
+                throw new NullPointerException("invalid null input");
+            }
+            this.cert = trustedCert;
+            this.attributes =
+                Collections.unmodifiableSet(new HashSet<>(attributes));
+        }
+
+        /**
+         * Gets the trusted {@code Certficate} from this entry.
+         *
+         * @return the trusted {@code Certificate} from this entry
+         */
+        public Certificate getTrustedCertificate() {
+            return cert;
+        }
+
+        /**
+         * Retrieves the attributes associated with an entry.
+         * <p>
+         *
+         * @return an unmodifiable {@code Set} of attributes, possibly empty
+         *
+         * @since 1.8
+         */
+        @Override
+        public Set<Attribute> getAttributes() {
+            return attributes;
+        }
+
+        /**
+         * Returns a string representation of this TrustedCertificateEntry.
+         * @return a string representation of this TrustedCertificateEntry.
+         */
+        public String toString() {
+            return "Trusted certificate entry:\r\n" + cert.toString();
+        }
+    }
+
+    /**
+     * Creates a KeyStore object of the given type, and encapsulates the given
+     * provider implementation (SPI object) in it.
+     *
+     * @param keyStoreSpi the provider implementation.
+     * @param provider the provider.
+     * @param type the keystore type.
+     */
+    protected KeyStore(KeyStoreSpi keyStoreSpi, Provider provider, String type)
+    {
+        this.keyStoreSpi = keyStoreSpi;
+        this.provider = provider;
+        this.type = type;
+
+        // BEGIN Android-removed: this debugging mechanism is not supported in Android.
+        /*
+        if (!skipDebug && pdebug != null) {
+            pdebug.println("KeyStore." + type.toUpperCase() + " type from: " +
+                this.provider.getName());
+        }
+        */
+        // END Android-removed: this debugging mechanism is not supported in Android.
+    }
+
+    /**
+     * Returns a keystore object of the specified type.
+     *
+     * <p> This method traverses the list of registered security Providers,
+     * starting with the most preferred Provider.
+     * A new KeyStore object encapsulating the
+     * KeyStoreSpi implementation from the first
+     * Provider that supports the specified type is returned.
+     *
+     * <p> Note that the list of registered providers may be retrieved via
+     * the {@link Security#getProviders() Security.getProviders()} method.
+     *
+     * @param type the type of keystore.
+     * See the KeyStore section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyStore">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard keystore types.
+     *
+     * @return a keystore object of the specified type.
+     *
+     * @exception KeyStoreException if no Provider supports a
+     *          KeyStoreSpi implementation for the
+     *          specified type.
+     *
+     * @see Provider
+     */
+    public static KeyStore getInstance(String type)
+        throws KeyStoreException
+    {
+        try {
+            Object[] objs = Security.getImpl(type, "KeyStore", (String)null);
+            return new KeyStore((KeyStoreSpi)objs[0], (Provider)objs[1], type);
+        } catch (NoSuchAlgorithmException nsae) {
+            throw new KeyStoreException(type + " not found", nsae);
+        } catch (NoSuchProviderException nspe) {
+            throw new KeyStoreException(type + " not found", nspe);
+        }
+    }
+
+    /**
+     * Returns a keystore object of the specified type.
+     *
+     * <p> A new KeyStore object encapsulating the
+     * KeyStoreSpi implementation from the specified provider
+     * is returned.  The specified provider must be registered
+     * in the security provider list.
+     *
+     * <p> Note that the list of registered providers may be retrieved via
+     * the {@link Security#getProviders() Security.getProviders()} method.
+     *
+     * @param type the type of keystore.
+     * See the KeyStore section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyStore">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard keystore types.
+     *
+     * @param provider the name of the provider.
+     *
+     * @return a keystore object of the specified type.
+     *
+     * @exception KeyStoreException if a KeyStoreSpi
+     *          implementation for the specified type is not
+     *          available from the specified provider.
+     *
+     * @exception NoSuchProviderException if the specified provider is not
+     *          registered in the security provider list.
+     *
+     * @exception IllegalArgumentException if the provider name is null
+     *          or empty.
+     *
+     * @see Provider
+     */
+    public static KeyStore getInstance(String type, String provider)
+        throws KeyStoreException, NoSuchProviderException
+    {
+        if (provider == null || provider.length() == 0)
+            throw new IllegalArgumentException("missing provider");
+        try {
+            Object[] objs = Security.getImpl(type, "KeyStore", provider);
+            return new KeyStore((KeyStoreSpi)objs[0], (Provider)objs[1], type);
+        } catch (NoSuchAlgorithmException nsae) {
+            throw new KeyStoreException(type + " not found", nsae);
+        }
+    }
+
+    /**
+     * Returns a keystore object of the specified type.
+     *
+     * <p> A new KeyStore object encapsulating the
+     * KeyStoreSpi implementation from the specified Provider
+     * object is returned.  Note that the specified Provider object
+     * does not have to be registered in the provider list.
+     *
+     * @param type the type of keystore.
+     * See the KeyStore section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyStore">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard keystore types.
+     *
+     * @param provider the provider.
+     *
+     * @return a keystore object of the specified type.
+     *
+     * @exception KeyStoreException if KeyStoreSpi
+     *          implementation for the specified type is not available
+     *          from the specified Provider object.
+     *
+     * @exception IllegalArgumentException if the specified provider is null.
+     *
+     * @see Provider
+     *
+     * @since 1.4
+     */
+    public static KeyStore getInstance(String type, Provider provider)
+        throws KeyStoreException
+    {
+        if (provider == null)
+            throw new IllegalArgumentException("missing provider");
+        try {
+            Object[] objs = Security.getImpl(type, "KeyStore", provider);
+            return new KeyStore((KeyStoreSpi)objs[0], (Provider)objs[1], type);
+        } catch (NoSuchAlgorithmException nsae) {
+            throw new KeyStoreException(type + " not found", nsae);
+        }
+    }
+
+    /**
+     * Returns the default keystore type as specified by the
+     * {@code keystore.type} security property, or the string
+     * {@literal "jks"} (acronym for {@literal "Java keystore"})
+     * if no such property exists.
+     *
+     * <p>The default keystore type can be used by applications that do not
+     * want to use a hard-coded keystore type when calling one of the
+     * {@code getInstance} methods, and want to provide a default keystore
+     * type in case a user does not specify its own.
+     *
+     * <p>The default keystore type can be changed by setting the value of the
+     * {@code keystore.type} security property to the desired keystore type.
+     *
+     * @return the default keystore type as specified by the
+     * {@code keystore.type} security property, or the string {@literal "jks"}
+     * if no such property exists.
+     * @see java.security.Security security properties
+     */
+    public final static String getDefaultType() {
+        String kstype;
+        kstype = AccessController.doPrivileged(new PrivilegedAction<String>() {
+            public String run() {
+                return Security.getProperty(KEYSTORE_TYPE);
+            }
+        });
+        if (kstype == null) {
+            kstype = "jks";
+        }
+        return kstype;
+    }
+
+    /**
+     * Returns the provider of this keystore.
+     *
+     * @return the provider of this keystore.
+     */
+    public final Provider getProvider()
+    {
+        return this.provider;
+    }
+
+    /**
+     * Returns the type of this keystore.
+     *
+     * @return the type of this keystore.
+     */
+    public final String getType()
+    {
+        return this.type;
+    }
+
+    /**
+     * Returns the key associated with the given alias, using the given
+     * password to recover it.  The key must have been associated with
+     * the alias by a call to {@code setKeyEntry},
+     * or by a call to {@code setEntry} with a
+     * {@code PrivateKeyEntry} or {@code SecretKeyEntry}.
+     *
+     * @param alias the alias name
+     * @param password the password for recovering the key
+     *
+     * @return the requested key, or null if the given alias does not exist
+     * or does not identify a key-related entry.
+     *
+     * @exception KeyStoreException if the keystore has not been initialized
+     * (loaded).
+     * @exception NoSuchAlgorithmException if the algorithm for recovering the
+     * key cannot be found
+     * @exception UnrecoverableKeyException if the key cannot be recovered
+     * (e.g., the given password is wrong).
+     */
+    public final Key getKey(String alias, char[] password)
+        throws KeyStoreException, NoSuchAlgorithmException,
+            UnrecoverableKeyException
+    {
+        if (!initialized) {
+            throw new KeyStoreException("Uninitialized keystore");
+        }
+        return keyStoreSpi.engineGetKey(alias, password);
+    }
+
+    /**
+     * Returns the certificate chain associated with the given alias.
+     * The certificate chain must have been associated with the alias
+     * by a call to {@code setKeyEntry},
+     * or by a call to {@code setEntry} with a
+     * {@code PrivateKeyEntry}.
+     *
+     * @param alias the alias name
+     *
+     * @return the certificate chain (ordered with the user's certificate first
+     * followed by zero or more certificate authorities), or null if the given alias
+     * does not exist or does not contain a certificate chain
+     *
+     * @exception KeyStoreException if the keystore has not been initialized
+     * (loaded).
+     */
+    public final Certificate[] getCertificateChain(String alias)
+        throws KeyStoreException
+    {
+        if (!initialized) {
+            throw new KeyStoreException("Uninitialized keystore");
+        }
+        return keyStoreSpi.engineGetCertificateChain(alias);
+    }
+
+    /**
+     * Returns the certificate associated with the given alias.
+     *
+     * <p> If the given alias name identifies an entry
+     * created by a call to {@code setCertificateEntry},
+     * or created by a call to {@code setEntry} with a
+     * {@code TrustedCertificateEntry},
+     * then the trusted certificate contained in that entry is returned.
+     *
+     * <p> If the given alias name identifies an entry
+     * created by a call to {@code setKeyEntry},
+     * or created by a call to {@code setEntry} with a
+     * {@code PrivateKeyEntry},
+     * then the first element of the certificate chain in that entry
+     * is returned.
+     *
+     * @param alias the alias name
+     *
+     * @return the certificate, or null if the given alias does not exist or
+     * does not contain a certificate.
+     *
+     * @exception KeyStoreException if the keystore has not been initialized
+     * (loaded).
+     */
+    public final Certificate getCertificate(String alias)
+        throws KeyStoreException
+    {
+        if (!initialized) {
+            throw new KeyStoreException("Uninitialized keystore");
+        }
+        return keyStoreSpi.engineGetCertificate(alias);
+    }
+
+    /**
+     * Returns the creation date of the entry identified by the given alias.
+     *
+     * @param alias the alias name
+     *
+     * @return the creation date of this entry, or null if the given alias does
+     * not exist
+     *
+     * @exception KeyStoreException if the keystore has not been initialized
+     * (loaded).
+     */
+    public final Date getCreationDate(String alias)
+        throws KeyStoreException
+    {
+        if (!initialized) {
+            throw new KeyStoreException("Uninitialized keystore");
+        }
+        return keyStoreSpi.engineGetCreationDate(alias);
+    }
+
+    /**
+     * Assigns the given key to the given alias, protecting it with the given
+     * password.
+     *
+     * <p>If the given key is of type {@code java.security.PrivateKey},
+     * it must be accompanied by a certificate chain certifying the
+     * corresponding public key.
+     *
+     * <p>If the given alias already exists, the keystore information
+     * associated with it is overridden by the given key (and possibly
+     * certificate chain).
+     *
+     * @param alias the alias name
+     * @param key the key to be associated with the alias
+     * @param password the password to protect the key
+     * @param chain the certificate chain for the corresponding public
+     * key (only required if the given key is of type
+     * {@code java.security.PrivateKey}).
+     *
+     * @exception KeyStoreException if the keystore has not been initialized
+     * (loaded), the given key cannot be protected, or this operation fails
+     * for some other reason
+     */
+    public final void setKeyEntry(String alias, Key key, char[] password,
+                                  Certificate[] chain)
+        throws KeyStoreException
+    {
+        if (!initialized) {
+            throw new KeyStoreException("Uninitialized keystore");
+        }
+        if ((key instanceof PrivateKey) &&
+            (chain == null || chain.length == 0)) {
+            throw new IllegalArgumentException("Private key must be "
+                                               + "accompanied by certificate "
+                                               + "chain");
+        }
+        keyStoreSpi.engineSetKeyEntry(alias, key, password, chain);
+    }
+
+    /**
+     * Assigns the given key (that has already been protected) to the given
+     * alias.
+     *
+     * <p>If the protected key is of type
+     * {@code java.security.PrivateKey}, it must be accompanied by a
+     * certificate chain certifying the corresponding public key. If the
+     * underlying keystore implementation is of type {@code jks},
+     * {@code key} must be encoded as an
+     * {@code EncryptedPrivateKeyInfo} as defined in the PKCS #8 standard.
+     *
+     * <p>If the given alias already exists, the keystore information
+     * associated with it is overridden by the given key (and possibly
+     * certificate chain).
+     *
+     * @param alias the alias name
+     * @param key the key (in protected format) to be associated with the alias
+     * @param chain the certificate chain for the corresponding public
+     *          key (only useful if the protected key is of type
+     *          {@code java.security.PrivateKey}).
+     *
+     * @exception KeyStoreException if the keystore has not been initialized
+     * (loaded), or if this operation fails for some other reason.
+     */
+    public final void setKeyEntry(String alias, byte[] key,
+                                  Certificate[] chain)
+        throws KeyStoreException
+    {
+        if (!initialized) {
+            throw new KeyStoreException("Uninitialized keystore");
+        }
+        keyStoreSpi.engineSetKeyEntry(alias, key, chain);
+    }
+
+    /**
+     * Assigns the given trusted certificate to the given alias.
+     *
+     * <p> If the given alias identifies an existing entry
+     * created by a call to {@code setCertificateEntry},
+     * or created by a call to {@code setEntry} with a
+     * {@code TrustedCertificateEntry},
+     * the trusted certificate in the existing entry
+     * is overridden by the given certificate.
+     *
+     * @param alias the alias name
+     * @param cert the certificate
+     *
+     * @exception KeyStoreException if the keystore has not been initialized,
+     * or the given alias already exists and does not identify an
+     * entry containing a trusted certificate,
+     * or this operation fails for some other reason.
+     */
+    public final void setCertificateEntry(String alias, Certificate cert)
+        throws KeyStoreException
+    {
+        if (!initialized) {
+            throw new KeyStoreException("Uninitialized keystore");
+        }
+        keyStoreSpi.engineSetCertificateEntry(alias, cert);
+    }
+
+    /**
+     * Deletes the entry identified by the given alias from this keystore.
+     *
+     * @param alias the alias name
+     *
+     * @exception KeyStoreException if the keystore has not been initialized,
+     * or if the entry cannot be removed.
+     */
+    public final void deleteEntry(String alias)
+        throws KeyStoreException
+    {
+        if (!initialized) {
+            throw new KeyStoreException("Uninitialized keystore");
+        }
+        keyStoreSpi.engineDeleteEntry(alias);
+    }
+
+    /**
+     * Lists all the alias names of this keystore.
+     *
+     * @return enumeration of the alias names
+     *
+     * @exception KeyStoreException if the keystore has not been initialized
+     * (loaded).
+     */
+    public final Enumeration<String> aliases()
+        throws KeyStoreException
+    {
+        if (!initialized) {
+            throw new KeyStoreException("Uninitialized keystore");
+        }
+        return keyStoreSpi.engineAliases();
+    }
+
+    /**
+     * Checks if the given alias exists in this keystore.
+     *
+     * @param alias the alias name
+     *
+     * @return true if the alias exists, false otherwise
+     *
+     * @exception KeyStoreException if the keystore has not been initialized
+     * (loaded).
+     */
+    public final boolean containsAlias(String alias)
+        throws KeyStoreException
+    {
+        if (!initialized) {
+            throw new KeyStoreException("Uninitialized keystore");
+        }
+        return keyStoreSpi.engineContainsAlias(alias);
+    }
+
+    /**
+     * Retrieves the number of entries in this keystore.
+     *
+     * @return the number of entries in this keystore
+     *
+     * @exception KeyStoreException if the keystore has not been initialized
+     * (loaded).
+     */
+    public final int size()
+        throws KeyStoreException
+    {
+        if (!initialized) {
+            throw new KeyStoreException("Uninitialized keystore");
+        }
+        return keyStoreSpi.engineSize();
+    }
+
+    /**
+     * Returns true if the entry identified by the given alias
+     * was created by a call to {@code setKeyEntry},
+     * or created by a call to {@code setEntry} with a
+     * {@code PrivateKeyEntry} or a {@code SecretKeyEntry}.
+     *
+     * @param alias the alias for the keystore entry to be checked
+     *
+     * @return true if the entry identified by the given alias is a
+     * key-related entry, false otherwise.
+     *
+     * @exception KeyStoreException if the keystore has not been initialized
+     * (loaded).
+     */
+    public final boolean isKeyEntry(String alias)
+        throws KeyStoreException
+    {
+        if (!initialized) {
+            throw new KeyStoreException("Uninitialized keystore");
+        }
+        return keyStoreSpi.engineIsKeyEntry(alias);
+    }
+
+    /**
+     * Returns true if the entry identified by the given alias
+     * was created by a call to {@code setCertificateEntry},
+     * or created by a call to {@code setEntry} with a
+     * {@code TrustedCertificateEntry}.
+     *
+     * @param alias the alias for the keystore entry to be checked
+     *
+     * @return true if the entry identified by the given alias contains a
+     * trusted certificate, false otherwise.
+     *
+     * @exception KeyStoreException if the keystore has not been initialized
+     * (loaded).
+     */
+    public final boolean isCertificateEntry(String alias)
+        throws KeyStoreException
+    {
+        if (!initialized) {
+            throw new KeyStoreException("Uninitialized keystore");
+        }
+        return keyStoreSpi.engineIsCertificateEntry(alias);
+    }
+
+    /**
+     * Returns the (alias) name of the first keystore entry whose certificate
+     * matches the given certificate.
+     *
+     * <p> This method attempts to match the given certificate with each
+     * keystore entry. If the entry being considered was
+     * created by a call to {@code setCertificateEntry},
+     * or created by a call to {@code setEntry} with a
+     * {@code TrustedCertificateEntry},
+     * then the given certificate is compared to that entry's certificate.
+     *
+     * <p> If the entry being considered was
+     * created by a call to {@code setKeyEntry},
+     * or created by a call to {@code setEntry} with a
+     * {@code PrivateKeyEntry},
+     * then the given certificate is compared to the first
+     * element of that entry's certificate chain.
+     *
+     * @param cert the certificate to match with.
+     *
+     * @return the alias name of the first entry with a matching certificate,
+     * or null if no such entry exists in this keystore.
+     *
+     * @exception KeyStoreException if the keystore has not been initialized
+     * (loaded).
+     */
+    public final String getCertificateAlias(Certificate cert)
+        throws KeyStoreException
+    {
+        if (!initialized) {
+            throw new KeyStoreException("Uninitialized keystore");
+        }
+        return keyStoreSpi.engineGetCertificateAlias(cert);
+    }
+
+    /**
+     * Stores this keystore to the given output stream, and protects its
+     * integrity with the given password.
+     *
+     * @param stream the output stream to which this keystore is written.
+     * @param password the password to generate the keystore integrity check
+     *
+     * @exception KeyStoreException if the keystore has not been initialized
+     * (loaded).
+     * @exception IOException if there was an I/O problem with data
+     * @exception NoSuchAlgorithmException if the appropriate data integrity
+     * algorithm could not be found
+     * @exception CertificateException if any of the certificates included in
+     * the keystore data could not be stored
+     */
+    public final void store(OutputStream stream, char[] password)
+        throws KeyStoreException, IOException, NoSuchAlgorithmException,
+            CertificateException
+    {
+        if (!initialized) {
+            throw new KeyStoreException("Uninitialized keystore");
+        }
+        keyStoreSpi.engineStore(stream, password);
+    }
+
+    /**
+     * Stores this keystore using the given {@code LoadStoreParameter}.
+     *
+     * @param param the {@code LoadStoreParameter}
+     *          that specifies how to store the keystore,
+     *          which may be {@code null}
+     *
+     * @exception IllegalArgumentException if the given
+     *          {@code LoadStoreParameter}
+     *          input is not recognized
+     * @exception KeyStoreException if the keystore has not been initialized
+     *          (loaded)
+     * @exception IOException if there was an I/O problem with data
+     * @exception NoSuchAlgorithmException if the appropriate data integrity
+     *          algorithm could not be found
+     * @exception CertificateException if any of the certificates included in
+     *          the keystore data could not be stored
+     *
+     * @since 1.5
+     */
+    public final void store(LoadStoreParameter param)
+                throws KeyStoreException, IOException,
+                NoSuchAlgorithmException, CertificateException {
+        if (!initialized) {
+            throw new KeyStoreException("Uninitialized keystore");
+        }
+        keyStoreSpi.engineStore(param);
+    }
+
+    /**
+     * Loads this KeyStore from the given input stream.
+     *
+     * <p>A password may be given to unlock the keystore
+     * (e.g. the keystore resides on a hardware token device),
+     * or to check the integrity of the keystore data.
+     * If a password is not given for integrity checking,
+     * then integrity checking is not performed.
+     *
+     * <p>In order to create an empty keystore, or if the keystore cannot
+     * be initialized from a stream, pass {@code null}
+     * as the {@code stream} argument.
+     *
+     * <p> Note that if this keystore has already been loaded, it is
+     * reinitialized and loaded again from the given input stream.
+     *
+     * @param stream the input stream from which the keystore is loaded,
+     * or {@code null}
+     * @param password the password used to check the integrity of
+     * the keystore, the password used to unlock the keystore,
+     * or {@code null}
+     *
+     * @exception IOException if there is an I/O or format problem with the
+     * keystore data, if a password is required but not given,
+     * or if the given password was incorrect. If the error is due to a
+     * wrong password, the {@link Throwable#getCause cause} of the
+     * {@code IOException} should be an
+     * {@code UnrecoverableKeyException}
+     * @exception NoSuchAlgorithmException if the algorithm used to check
+     * the integrity of the keystore cannot be found
+     * @exception CertificateException if any of the certificates in the
+     * keystore could not be loaded
+     */
+    public final void load(InputStream stream, char[] password)
+        throws IOException, NoSuchAlgorithmException, CertificateException
+    {
+        keyStoreSpi.engineLoad(stream, password);
+        initialized = true;
+    }
+
+    /**
+     * Loads this keystore using the given {@code LoadStoreParameter}.
+     *
+     * <p> Note that if this KeyStore has already been loaded, it is
+     * reinitialized and loaded again from the given parameter.
+     *
+     * @param param the {@code LoadStoreParameter}
+     *          that specifies how to load the keystore,
+     *          which may be {@code null}
+     *
+     * @exception IllegalArgumentException if the given
+     *          {@code LoadStoreParameter}
+     *          input is not recognized
+     * @exception IOException if there is an I/O or format problem with the
+     *          keystore data. If the error is due to an incorrect
+     *         {@code ProtectionParameter} (e.g. wrong password)
+     *         the {@link Throwable#getCause cause} of the
+     *         {@code IOException} should be an
+     *         {@code UnrecoverableKeyException}
+     * @exception NoSuchAlgorithmException if the algorithm used to check
+     *          the integrity of the keystore cannot be found
+     * @exception CertificateException if any of the certificates in the
+     *          keystore could not be loaded
+     *
+     * @since 1.5
+     */
+    public final void load(LoadStoreParameter param)
+                throws IOException, NoSuchAlgorithmException,
+                CertificateException {
+
+        keyStoreSpi.engineLoad(param);
+        initialized = true;
+    }
+
+    /**
+     * Gets a keystore {@code Entry} for the specified alias
+     * with the specified protection parameter.
+     *
+     * @param alias get the keystore {@code Entry} for this alias
+     * @param protParam the {@code ProtectionParameter}
+     *          used to protect the {@code Entry},
+     *          which may be {@code null}
+     *
+     * @return the keystore {@code Entry} for the specified alias,
+     *          or {@code null} if there is no such entry
+     *
+     * @exception NullPointerException if
+     *          {@code alias} is {@code null}
+     * @exception NoSuchAlgorithmException if the algorithm for recovering the
+     *          entry cannot be found
+     * @exception UnrecoverableEntryException if the specified
+     *          {@code protParam} were insufficient or invalid
+     * @exception UnrecoverableKeyException if the entry is a
+     *          {@code PrivateKeyEntry} or {@code SecretKeyEntry}
+     *          and the specified {@code protParam} does not contain
+     *          the information needed to recover the key (e.g. wrong password)
+     * @exception KeyStoreException if the keystore has not been initialized
+     *          (loaded).
+     * @see #setEntry(String, KeyStore.Entry, KeyStore.ProtectionParameter)
+     *
+     * @since 1.5
+     */
+    public final Entry getEntry(String alias, ProtectionParameter protParam)
+                throws NoSuchAlgorithmException, UnrecoverableEntryException,
+                KeyStoreException {
+
+        if (alias == null) {
+            throw new NullPointerException("invalid null input");
+        }
+        if (!initialized) {
+            throw new KeyStoreException("Uninitialized keystore");
+        }
+        return keyStoreSpi.engineGetEntry(alias, protParam);
+    }
+
+    /**
+     * Saves a keystore {@code Entry} under the specified alias.
+     * The protection parameter is used to protect the
+     * {@code Entry}.
+     *
+     * <p> If an entry already exists for the specified alias,
+     * it is overridden.
+     *
+     * @param alias save the keystore {@code Entry} under this alias
+     * @param entry the {@code Entry} to save
+     * @param protParam the {@code ProtectionParameter}
+     *          used to protect the {@code Entry},
+     *          which may be {@code null}
+     *
+     * @exception NullPointerException if
+     *          {@code alias} or {@code entry}
+     *          is {@code null}
+     * @exception KeyStoreException if the keystore has not been initialized
+     *          (loaded), or if this operation fails for some other reason
+     *
+     * @see #getEntry(String, KeyStore.ProtectionParameter)
+     *
+     * @since 1.5
+     */
+    public final void setEntry(String alias, Entry entry,
+                        ProtectionParameter protParam)
+                throws KeyStoreException {
+        if (alias == null || entry == null) {
+            throw new NullPointerException("invalid null input");
+        }
+        if (!initialized) {
+            throw new KeyStoreException("Uninitialized keystore");
+        }
+        keyStoreSpi.engineSetEntry(alias, entry, protParam);
+    }
+
+    /**
+     * Determines if the keystore {@code Entry} for the specified
+     * {@code alias} is an instance or subclass of the specified
+     * {@code entryClass}.
+     *
+     * @param alias the alias name
+     * @param entryClass the entry class
+     *
+     * @return true if the keystore {@code Entry} for the specified
+     *          {@code alias} is an instance or subclass of the
+     *          specified {@code entryClass}, false otherwise
+     *
+     * @exception NullPointerException if
+     *          {@code alias} or {@code entryClass}
+     *          is {@code null}
+     * @exception KeyStoreException if the keystore has not been
+     *          initialized (loaded)
+     *
+     * @since 1.5
+     */
+    public final boolean
+        entryInstanceOf(String alias,
+                        Class<? extends KeyStore.Entry> entryClass)
+        throws KeyStoreException
+    {
+
+        if (alias == null || entryClass == null) {
+            throw new NullPointerException("invalid null input");
+        }
+        if (!initialized) {
+            throw new KeyStoreException("Uninitialized keystore");
+        }
+        return keyStoreSpi.engineEntryInstanceOf(alias, entryClass);
+    }
+
+    /**
+     * A description of a to-be-instantiated KeyStore object.
+     *
+     * <p>An instance of this class encapsulates the information needed to
+     * instantiate and initialize a KeyStore object. That process is
+     * triggered when the {@linkplain #getKeyStore} method is called.
+     *
+     * <p>This makes it possible to decouple configuration from KeyStore
+     * object creation and e.g. delay a password prompt until it is
+     * needed.
+     *
+     * @see KeyStore
+     * @see javax.net.ssl.KeyStoreBuilderParameters
+     * @since 1.5
+     */
+    public static abstract class Builder {
+
+        // maximum times to try the callbackhandler if the password is wrong
+        static final int MAX_CALLBACK_TRIES = 3;
+
+        /**
+         * Construct a new Builder.
+         */
+        protected Builder() {
+            // empty
+        }
+
+        /**
+         * Returns the KeyStore described by this object.
+         *
+         * @return the {@code KeyStore} described by this object
+         * @exception KeyStoreException if an error occurred during the
+         *   operation, for example if the KeyStore could not be
+         *   instantiated or loaded
+         */
+        public abstract KeyStore getKeyStore() throws KeyStoreException;
+
+        /**
+         * Returns the ProtectionParameters that should be used to obtain
+         * the {@link KeyStore.Entry Entry} with the given alias.
+         * The {@code getKeyStore} method must be invoked before this
+         * method may be called.
+         *
+         * @return the ProtectionParameters that should be used to obtain
+         *   the {@link KeyStore.Entry Entry} with the given alias.
+         * @param alias the alias of the KeyStore entry
+         * @throws NullPointerException if alias is null
+         * @throws KeyStoreException if an error occurred during the
+         *   operation
+         * @throws IllegalStateException if the getKeyStore method has
+         *   not been invoked prior to calling this method
+         */
+        public abstract ProtectionParameter getProtectionParameter(String alias)
+            throws KeyStoreException;
+
+        /**
+         * Returns a new Builder that encapsulates the given KeyStore.
+         * The {@linkplain #getKeyStore} method of the returned object
+         * will return {@code keyStore}, the {@linkplain
+         * #getProtectionParameter getProtectionParameter()} method will
+         * return {@code protectionParameters}.
+         *
+         * <p> This is useful if an existing KeyStore object needs to be
+         * used with Builder-based APIs.
+         *
+         * @return a new Builder object
+         * @param keyStore the KeyStore to be encapsulated
+         * @param protectionParameter the ProtectionParameter used to
+         *   protect the KeyStore entries
+         * @throws NullPointerException if keyStore or
+         *   protectionParameters is null
+         * @throws IllegalArgumentException if the keyStore has not been
+         *   initialized
+         */
+        public static Builder newInstance(final KeyStore keyStore,
+                final ProtectionParameter protectionParameter) {
+            if ((keyStore == null) || (protectionParameter == null)) {
+                throw new NullPointerException();
+            }
+            if (keyStore.initialized == false) {
+                throw new IllegalArgumentException("KeyStore not initialized");
+            }
+            return new Builder() {
+                private volatile boolean getCalled;
+
+                public KeyStore getKeyStore() {
+                    getCalled = true;
+                    return keyStore;
+                }
+
+                public ProtectionParameter getProtectionParameter(String alias)
+                {
+                    if (alias == null) {
+                        throw new NullPointerException();
+                    }
+                    if (getCalled == false) {
+                        throw new IllegalStateException
+                            ("getKeyStore() must be called first");
+                    }
+                    return protectionParameter;
+                }
+            };
+        }
+
+        /**
+         * Returns a new Builder object.
+         *
+         * <p>The first call to the {@link #getKeyStore} method on the returned
+         * builder will create a KeyStore of type {@code type} and call
+         * its {@link KeyStore#load load()} method.
+         * The {@code inputStream} argument is constructed from
+         * {@code file}.
+         * If {@code protection} is a
+         * {@code PasswordProtection}, the password is obtained by
+         * calling the {@code getPassword} method.
+         * Otherwise, if {@code protection} is a
+         * {@code CallbackHandlerProtection}, the password is obtained
+         * by invoking the CallbackHandler.
+         *
+         * <p>Subsequent calls to {@link #getKeyStore} return the same object
+         * as the initial call. If the initial call to failed with a
+         * KeyStoreException, subsequent calls also throw a
+         * KeyStoreException.
+         *
+         * <p>The KeyStore is instantiated from {@code provider} if
+         * non-null. Otherwise, all installed providers are searched.
+         *
+         * <p>Calls to {@link #getProtectionParameter getProtectionParameter()}
+         * will return a {@link KeyStore.PasswordProtection PasswordProtection}
+         * object encapsulating the password that was used to invoke the
+         * {@code load} method.
+         *
+         * <p><em>Note</em> that the {@link #getKeyStore} method is executed
+         * within the {@link AccessControlContext} of the code invoking this
+         * method.
+         *
+         * @return a new Builder object
+         * @param type the type of KeyStore to be constructed
+         * @param provider the provider from which the KeyStore is to
+         *   be instantiated (or null)
+         * @param file the File that contains the KeyStore data
+         * @param protection the ProtectionParameter securing the KeyStore data
+         * @throws NullPointerException if type, file or protection is null
+         * @throws IllegalArgumentException if protection is not an instance
+         *   of either PasswordProtection or CallbackHandlerProtection; or
+         *   if file does not exist or does not refer to a normal file
+         */
+        public static Builder newInstance(String type, Provider provider,
+                File file, ProtectionParameter protection) {
+            if ((type == null) || (file == null) || (protection == null)) {
+                throw new NullPointerException();
+            }
+            if ((protection instanceof PasswordProtection == false) &&
+                (protection instanceof CallbackHandlerProtection == false)) {
+                throw new IllegalArgumentException
+                ("Protection must be PasswordProtection or " +
+                 "CallbackHandlerProtection");
+            }
+            if (file.isFile() == false) {
+                throw new IllegalArgumentException
+                    ("File does not exist or it does not refer " +
+                     "to a normal file: " + file);
+            }
+            return new FileBuilder(type, provider, file, protection,
+                AccessController.getContext());
+        }
+
+        private static final class FileBuilder extends Builder {
+
+            private final String type;
+            private final Provider provider;
+            private final File file;
+            private ProtectionParameter protection;
+            private ProtectionParameter keyProtection;
+            private final AccessControlContext context;
+
+            private KeyStore keyStore;
+
+            private Throwable oldException;
+
+            FileBuilder(String type, Provider provider, File file,
+                    ProtectionParameter protection,
+                    AccessControlContext context) {
+                this.type = type;
+                this.provider = provider;
+                this.file = file;
+                this.protection = protection;
+                this.context = context;
+            }
+
+            public synchronized KeyStore getKeyStore() throws KeyStoreException
+            {
+                if (keyStore != null) {
+                    return keyStore;
+                }
+                if (oldException != null) {
+                    throw new KeyStoreException
+                        ("Previous KeyStore instantiation failed",
+                         oldException);
+                }
+                PrivilegedExceptionAction<KeyStore> action =
+                        new PrivilegedExceptionAction<KeyStore>() {
+                    public KeyStore run() throws Exception {
+                        if (protection instanceof CallbackHandlerProtection == false) {
+                            return run0();
+                        }
+                        // when using a CallbackHandler,
+                        // reprompt if the password is wrong
+                        int tries = 0;
+                        while (true) {
+                            tries++;
+                            try {
+                                return run0();
+                            } catch (IOException e) {
+                                if ((tries < MAX_CALLBACK_TRIES)
+                                        && (e.getCause() instanceof UnrecoverableKeyException)) {
+                                    continue;
+                                }
+                                throw e;
+                            }
+                        }
+                    }
+                    public KeyStore run0() throws Exception {
+                        KeyStore ks;
+                        if (provider == null) {
+                            ks = KeyStore.getInstance(type);
+                        } else {
+                            ks = KeyStore.getInstance(type, provider);
+                        }
+                        InputStream in = null;
+                        char[] password = null;
+                        try {
+                            in = new FileInputStream(file);
+                            if (protection instanceof PasswordProtection) {
+                                password =
+                                ((PasswordProtection)protection).getPassword();
+                                keyProtection = protection;
+                            } else {
+                                CallbackHandler handler =
+                                    ((CallbackHandlerProtection)protection)
+                                    .getCallbackHandler();
+                                PasswordCallback callback = new PasswordCallback
+                                    ("Password for keystore " + file.getName(),
+                                    false);
+                                handler.handle(new Callback[] {callback});
+                                password = callback.getPassword();
+                                if (password == null) {
+                                    throw new KeyStoreException("No password" +
+                                                                " provided");
+                                }
+                                callback.clearPassword();
+                                keyProtection = new PasswordProtection(password);
+                            }
+                            ks.load(in, password);
+                            return ks;
+                        } finally {
+                            if (in != null) {
+                                in.close();
+                            }
+                        }
+                    }
+                };
+                try {
+                    keyStore = AccessController.doPrivileged(action, context);
+                    return keyStore;
+                } catch (PrivilegedActionException e) {
+                    oldException = e.getCause();
+                    throw new KeyStoreException
+                        ("KeyStore instantiation failed", oldException);
+                }
+            }
+
+            public synchronized ProtectionParameter
+                        getProtectionParameter(String alias) {
+                if (alias == null) {
+                    throw new NullPointerException();
+                }
+                if (keyStore == null) {
+                    throw new IllegalStateException
+                        ("getKeyStore() must be called first");
+                }
+                return keyProtection;
+            }
+        }
+
+        /**
+         * Returns a new Builder object.
+         *
+         * <p>Each call to the {@link #getKeyStore} method on the returned
+         * builder will return a new KeyStore object of type {@code type}.
+         * Its {@link KeyStore#load(KeyStore.LoadStoreParameter) load()}
+         * method is invoked using a
+         * {@code LoadStoreParameter} that encapsulates
+         * {@code protection}.
+         *
+         * <p>The KeyStore is instantiated from {@code provider} if
+         * non-null. Otherwise, all installed providers are searched.
+         *
+         * <p>Calls to {@link #getProtectionParameter getProtectionParameter()}
+         * will return {@code protection}.
+         *
+         * <p><em>Note</em> that the {@link #getKeyStore} method is executed
+         * within the {@link AccessControlContext} of the code invoking this
+         * method.
+         *
+         * @return a new Builder object
+         * @param type the type of KeyStore to be constructed
+         * @param provider the provider from which the KeyStore is to
+         *   be instantiated (or null)
+         * @param protection the ProtectionParameter securing the Keystore
+         * @throws NullPointerException if type or protection is null
+         */
+        public static Builder newInstance(final String type,
+                final Provider provider, final ProtectionParameter protection) {
+            if ((type == null) || (protection == null)) {
+                throw new NullPointerException();
+            }
+            final AccessControlContext context = AccessController.getContext();
+            return new Builder() {
+                private volatile boolean getCalled;
+                private IOException oldException;
+
+                private final PrivilegedExceptionAction<KeyStore> action
+                        = new PrivilegedExceptionAction<KeyStore>() {
+
+                    public KeyStore run() throws Exception {
+                        KeyStore ks;
+                        if (provider == null) {
+                            ks = KeyStore.getInstance(type);
+                        } else {
+                            ks = KeyStore.getInstance(type, provider);
+                        }
+                        LoadStoreParameter param = new SimpleLoadStoreParameter(protection);
+                        if (protection instanceof CallbackHandlerProtection == false) {
+                            ks.load(param);
+                        } else {
+                            // when using a CallbackHandler,
+                            // reprompt if the password is wrong
+                            int tries = 0;
+                            while (true) {
+                                tries++;
+                                try {
+                                    ks.load(param);
+                                    break;
+                                } catch (IOException e) {
+                                    if (e.getCause() instanceof UnrecoverableKeyException) {
+                                        if (tries < MAX_CALLBACK_TRIES) {
+                                            continue;
+                                        } else {
+                                            oldException = e;
+                                        }
+                                    }
+                                    throw e;
+                                }
+                            }
+                        }
+                        getCalled = true;
+                        return ks;
+                    }
+                };
+
+                public synchronized KeyStore getKeyStore()
+                        throws KeyStoreException {
+                    if (oldException != null) {
+                        throw new KeyStoreException
+                            ("Previous KeyStore instantiation failed",
+                             oldException);
+                    }
+                    try {
+                        return AccessController.doPrivileged(action, context);
+                    } catch (PrivilegedActionException e) {
+                        Throwable cause = e.getCause();
+                        throw new KeyStoreException
+                            ("KeyStore instantiation failed", cause);
+                    }
+                }
+
+                public ProtectionParameter getProtectionParameter(String alias)
+                {
+                    if (alias == null) {
+                        throw new NullPointerException();
+                    }
+                    if (getCalled == false) {
+                        throw new IllegalStateException
+                            ("getKeyStore() must be called first");
+                    }
+                    return protection;
+                }
+            };
+        }
+
+    }
+
+    static class SimpleLoadStoreParameter implements LoadStoreParameter {
+
+        private final ProtectionParameter protection;
+
+        SimpleLoadStoreParameter(ProtectionParameter protection) {
+            this.protection = protection;
+        }
+
+        public ProtectionParameter getProtectionParameter() {
+            return protection;
+        }
+    }
+
+}
diff --git a/java/security/KeyStoreException.java b/java/security/KeyStoreException.java
new file mode 100644
index 0000000..cf56d6a
--- /dev/null
+++ b/java/security/KeyStoreException.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security;
+
+/**
+ * This is the generic KeyStore exception.
+ *
+ * @author Jan Luehe
+ *
+ *
+ * @since 1.2
+ */
+
+public class KeyStoreException extends GeneralSecurityException {
+
+    private static final long serialVersionUID = -1119353179322377262L;
+
+    /**
+     * Constructs a KeyStoreException with no detail message.  (A
+     * detail message is a String that describes this particular
+     * exception.)
+     */
+    public KeyStoreException() {
+        super();
+    }
+
+    /**
+     * Constructs a KeyStoreException with the specified detail
+     * message.  (A detail message is a String that describes this
+     * particular exception.)
+     *
+     * @param msg the detail message.
+     */
+   public KeyStoreException(String msg) {
+       super(msg);
+    }
+
+    /**
+     * Creates a {@code KeyStoreException} with the specified
+     * detail message and cause.
+     *
+     * @param message the detail message (which is saved for later retrieval
+     *        by the {@link #getMessage()} method).
+     * @param cause the cause (which is saved for later retrieval by the
+     *        {@link #getCause()} method).  (A {@code null} value is permitted,
+     *        and indicates that the cause is nonexistent or unknown.)
+     * @since 1.5
+     */
+    public KeyStoreException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Creates a {@code KeyStoreException} with the specified cause
+     * and a detail message of {@code (cause==null ? null : cause.toString())}
+     * (which typically contains the class and detail message of
+     * {@code cause}).
+     *
+     * @param cause the cause (which is saved for later retrieval by the
+     *        {@link #getCause()} method).  (A {@code null} value is permitted,
+     *        and indicates that the cause is nonexistent or unknown.)
+     * @since 1.5
+     */
+    public KeyStoreException(Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/java/security/KeyStoreSpi.java b/java/security/KeyStoreSpi.java
new file mode 100644
index 0000000..531a983
--- /dev/null
+++ b/java/security/KeyStoreSpi.java
@@ -0,0 +1,587 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1998, 2013, 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 java.security;
+
+import java.io.*;
+import java.util.*;
+import java.security.KeyStore;
+import java.security.KeyStore.*;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+
+import javax.crypto.SecretKey;
+
+import javax.security.auth.callback.*;
+
+/**
+ * This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
+ * for the {@code KeyStore} class.
+ * All the abstract methods in this class must be implemented by each
+ * cryptographic service provider who wishes to supply the implementation
+ * of a keystore for a particular keystore type.
+ *
+ * @author Jan Luehe
+ *
+ *
+ * @see KeyStore
+ *
+ * @since 1.2
+ */
+
+public abstract class KeyStoreSpi {
+
+    /**
+     * Returns the key associated with the given alias, using the given
+     * password to recover it.  The key must have been associated with
+     * the alias by a call to {@code setKeyEntry},
+     * or by a call to {@code setEntry} with a
+     * {@code PrivateKeyEntry} or {@code SecretKeyEntry}.
+     *
+     * @param alias the alias name
+     * @param password the password for recovering the key
+     *
+     * @return the requested key, or null if the given alias does not exist
+     * or does not identify a key-related entry.
+     *
+     * @exception NoSuchAlgorithmException if the algorithm for recovering the
+     * key cannot be found
+     * @exception UnrecoverableKeyException if the key cannot be recovered
+     * (e.g., the given password is wrong).
+     */
+    public abstract Key engineGetKey(String alias, char[] password)
+        throws NoSuchAlgorithmException, UnrecoverableKeyException;
+
+    /**
+     * Returns the certificate chain associated with the given alias.
+     * The certificate chain must have been associated with the alias
+     * by a call to {@code setKeyEntry},
+     * or by a call to {@code setEntry} with a
+     * {@code PrivateKeyEntry}.
+     *
+     * @param alias the alias name
+     *
+     * @return the certificate chain (ordered with the user's certificate first
+     * and the root certificate authority last), or null if the given alias
+     * does not exist or does not contain a certificate chain
+     */
+    public abstract Certificate[] engineGetCertificateChain(String alias);
+
+    /**
+     * Returns the certificate associated with the given alias.
+     *
+     * <p> If the given alias name identifies an entry
+     * created by a call to {@code setCertificateEntry},
+     * or created by a call to {@code setEntry} with a
+     * {@code TrustedCertificateEntry},
+     * then the trusted certificate contained in that entry is returned.
+     *
+     * <p> If the given alias name identifies an entry
+     * created by a call to {@code setKeyEntry},
+     * or created by a call to {@code setEntry} with a
+     * {@code PrivateKeyEntry},
+     * then the first element of the certificate chain in that entry
+     * (if a chain exists) is returned.
+     *
+     * @param alias the alias name
+     *
+     * @return the certificate, or null if the given alias does not exist or
+     * does not contain a certificate.
+     */
+    public abstract Certificate engineGetCertificate(String alias);
+
+    /**
+     * Returns the creation date of the entry identified by the given alias.
+     *
+     * @param alias the alias name
+     *
+     * @return the creation date of this entry, or null if the given alias does
+     * not exist
+     */
+    public abstract Date engineGetCreationDate(String alias);
+
+    /**
+     * Assigns the given key to the given alias, protecting it with the given
+     * password.
+     *
+     * <p>If the given key is of type {@code java.security.PrivateKey},
+     * it must be accompanied by a certificate chain certifying the
+     * corresponding public key.
+     *
+     * <p>If the given alias already exists, the keystore information
+     * associated with it is overridden by the given key (and possibly
+     * certificate chain).
+     *
+     * @param alias the alias name
+     * @param key the key to be associated with the alias
+     * @param password the password to protect the key
+     * @param chain the certificate chain for the corresponding public
+     * key (only required if the given key is of type
+     * {@code java.security.PrivateKey}).
+     *
+     * @exception KeyStoreException if the given key cannot be protected, or
+     * this operation fails for some other reason
+     */
+    public abstract void engineSetKeyEntry(String alias, Key key,
+                                           char[] password,
+                                           Certificate[] chain)
+        throws KeyStoreException;
+
+    /**
+     * Assigns the given key (that has already been protected) to the given
+     * alias.
+     *
+     * <p>If the protected key is of type
+     * {@code java.security.PrivateKey},
+     * it must be accompanied by a certificate chain certifying the
+     * corresponding public key.
+     *
+     * <p>If the given alias already exists, the keystore information
+     * associated with it is overridden by the given key (and possibly
+     * certificate chain).
+     *
+     * @param alias the alias name
+     * @param key the key (in protected format) to be associated with the alias
+     * @param chain the certificate chain for the corresponding public
+     * key (only useful if the protected key is of type
+     * {@code java.security.PrivateKey}).
+     *
+     * @exception KeyStoreException if this operation fails.
+     */
+    public abstract void engineSetKeyEntry(String alias, byte[] key,
+                                           Certificate[] chain)
+        throws KeyStoreException;
+
+    /**
+     * Assigns the given certificate to the given alias.
+     *
+     * <p> If the given alias identifies an existing entry
+     * created by a call to {@code setCertificateEntry},
+     * or created by a call to {@code setEntry} with a
+     * {@code TrustedCertificateEntry},
+     * the trusted certificate in the existing entry
+     * is overridden by the given certificate.
+     *
+     * @param alias the alias name
+     * @param cert the certificate
+     *
+     * @exception KeyStoreException if the given alias already exists and does
+     * not identify an entry containing a trusted certificate,
+     * or this operation fails for some other reason.
+     */
+    public abstract void engineSetCertificateEntry(String alias,
+                                                   Certificate cert)
+        throws KeyStoreException;
+
+    /**
+     * Deletes the entry identified by the given alias from this keystore.
+     *
+     * @param alias the alias name
+     *
+     * @exception KeyStoreException if the entry cannot be removed.
+     */
+    public abstract void engineDeleteEntry(String alias)
+        throws KeyStoreException;
+
+    /**
+     * Lists all the alias names of this keystore.
+     *
+     * @return enumeration of the alias names
+     */
+    public abstract Enumeration<String> engineAliases();
+
+    /**
+     * Checks if the given alias exists in this keystore.
+     *
+     * @param alias the alias name
+     *
+     * @return true if the alias exists, false otherwise
+     */
+    public abstract boolean engineContainsAlias(String alias);
+
+    /**
+     * Retrieves the number of entries in this keystore.
+     *
+     * @return the number of entries in this keystore
+     */
+    public abstract int engineSize();
+
+    /**
+     * Returns true if the entry identified by the given alias
+     * was created by a call to {@code setKeyEntry},
+     * or created by a call to {@code setEntry} with a
+     * {@code PrivateKeyEntry} or a {@code SecretKeyEntry}.
+     *
+     * @param alias the alias for the keystore entry to be checked
+     *
+     * @return true if the entry identified by the given alias is a
+     * key-related, false otherwise.
+     */
+    public abstract boolean engineIsKeyEntry(String alias);
+
+    /**
+     * Returns true if the entry identified by the given alias
+     * was created by a call to {@code setCertificateEntry},
+     * or created by a call to {@code setEntry} with a
+     * {@code TrustedCertificateEntry}.
+     *
+     * @param alias the alias for the keystore entry to be checked
+     *
+     * @return true if the entry identified by the given alias contains a
+     * trusted certificate, false otherwise.
+     */
+    public abstract boolean engineIsCertificateEntry(String alias);
+
+    /**
+     * Returns the (alias) name of the first keystore entry whose certificate
+     * matches the given certificate.
+     *
+     * <p>This method attempts to match the given certificate with each
+     * keystore entry. If the entry being considered was
+     * created by a call to {@code setCertificateEntry},
+     * or created by a call to {@code setEntry} with a
+     * {@code TrustedCertificateEntry},
+     * then the given certificate is compared to that entry's certificate.
+     *
+     * <p> If the entry being considered was
+     * created by a call to {@code setKeyEntry},
+     * or created by a call to {@code setEntry} with a
+     * {@code PrivateKeyEntry},
+     * then the given certificate is compared to the first
+     * element of that entry's certificate chain.
+     *
+     * @param cert the certificate to match with.
+     *
+     * @return the alias name of the first entry with matching certificate,
+     * or null if no such entry exists in this keystore.
+     */
+    public abstract String engineGetCertificateAlias(Certificate cert);
+
+    /**
+     * Stores this keystore to the given output stream, and protects its
+     * integrity with the given password.
+     *
+     * @param stream the output stream to which this keystore is written.
+     * @param password the password to generate the keystore integrity check
+     *
+     * @exception IOException if there was an I/O problem with data
+     * @exception NoSuchAlgorithmException if the appropriate data integrity
+     * algorithm could not be found
+     * @exception CertificateException if any of the certificates included in
+     * the keystore data could not be stored
+     */
+    public abstract void engineStore(OutputStream stream, char[] password)
+        throws IOException, NoSuchAlgorithmException, CertificateException;
+
+    /**
+     * Stores this keystore using the given
+     * {@code KeyStore.LoadStoreParmeter}.
+     *
+     * @param param the {@code KeyStore.LoadStoreParmeter}
+     *          that specifies how to store the keystore,
+     *          which may be {@code null}
+     *
+     * @exception IllegalArgumentException if the given
+     *          {@code KeyStore.LoadStoreParmeter}
+     *          input is not recognized
+     * @exception IOException if there was an I/O problem with data
+     * @exception NoSuchAlgorithmException if the appropriate data integrity
+     *          algorithm could not be found
+     * @exception CertificateException if any of the certificates included in
+     *          the keystore data could not be stored
+     *
+     * @since 1.5
+     */
+    public void engineStore(KeyStore.LoadStoreParameter param)
+                throws IOException, NoSuchAlgorithmException,
+                CertificateException {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Loads the keystore from the given input stream.
+     *
+     * <p>A password may be given to unlock the keystore
+     * (e.g. the keystore resides on a hardware token device),
+     * or to check the integrity of the keystore data.
+     * If a password is not given for integrity checking,
+     * then integrity checking is not performed.
+     *
+     * @param stream the input stream from which the keystore is loaded,
+     * or {@code null}
+     * @param password the password used to check the integrity of
+     * the keystore, the password used to unlock the keystore,
+     * or {@code null}
+     *
+     * @exception IOException if there is an I/O or format problem with the
+     * keystore data, if a password is required but not given,
+     * or if the given password was incorrect. If the error is due to a
+     * wrong password, the {@link Throwable#getCause cause} of the
+     * {@code IOException} should be an
+     * {@code UnrecoverableKeyException}
+     * @exception NoSuchAlgorithmException if the algorithm used to check
+     * the integrity of the keystore cannot be found
+     * @exception CertificateException if any of the certificates in the
+     * keystore could not be loaded
+     */
+    public abstract void engineLoad(InputStream stream, char[] password)
+        throws IOException, NoSuchAlgorithmException, CertificateException;
+
+    /**
+     * Loads the keystore using the given
+     * {@code KeyStore.LoadStoreParameter}.
+     *
+     * <p> Note that if this KeyStore has already been loaded, it is
+     * reinitialized and loaded again from the given parameter.
+     *
+     * @param param the {@code KeyStore.LoadStoreParameter}
+     *          that specifies how to load the keystore,
+     *          which may be {@code null}
+     *
+     * @exception IllegalArgumentException if the given
+     *          {@code KeyStore.LoadStoreParameter}
+     *          input is not recognized
+     * @exception IOException if there is an I/O or format problem with the
+     *          keystore data. If the error is due to an incorrect
+     *         {@code ProtectionParameter} (e.g. wrong password)
+     *         the {@link Throwable#getCause cause} of the
+     *         {@code IOException} should be an
+     *         {@code UnrecoverableKeyException}
+     * @exception NoSuchAlgorithmException if the algorithm used to check
+     *          the integrity of the keystore cannot be found
+     * @exception CertificateException if any of the certificates in the
+     *          keystore could not be loaded
+     *
+     * @since 1.5
+     */
+    public void engineLoad(KeyStore.LoadStoreParameter param)
+                throws IOException, NoSuchAlgorithmException,
+                CertificateException {
+
+        if (param == null) {
+            engineLoad((InputStream)null, (char[])null);
+            return;
+        }
+
+        if (param instanceof KeyStore.SimpleLoadStoreParameter) {
+            ProtectionParameter protection = param.getProtectionParameter();
+            char[] password;
+            if (protection instanceof PasswordProtection) {
+                password = ((PasswordProtection)protection).getPassword();
+            } else if (protection instanceof CallbackHandlerProtection) {
+                CallbackHandler handler =
+                    ((CallbackHandlerProtection)protection).getCallbackHandler();
+                PasswordCallback callback =
+                    new PasswordCallback("Password: ", false);
+                try {
+                    handler.handle(new Callback[] {callback});
+                } catch (UnsupportedCallbackException e) {
+                    throw new NoSuchAlgorithmException
+                        ("Could not obtain password", e);
+                }
+                password = callback.getPassword();
+                callback.clearPassword();
+                if (password == null) {
+                    throw new NoSuchAlgorithmException
+                        ("No password provided");
+                }
+            } else {
+                throw new NoSuchAlgorithmException("ProtectionParameter must"
+                    + " be PasswordProtection or CallbackHandlerProtection");
+            }
+            engineLoad(null, password);
+            return;
+        }
+
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Gets a {@code KeyStore.Entry} for the specified alias
+     * with the specified protection parameter.
+     *
+     * @param alias get the {@code KeyStore.Entry} for this alias
+     * @param protParam the {@code ProtectionParameter}
+     *          used to protect the {@code Entry},
+     *          which may be {@code null}
+     *
+     * @return the {@code KeyStore.Entry} for the specified alias,
+     *          or {@code null} if there is no such entry
+     *
+     * @exception KeyStoreException if the operation failed
+     * @exception NoSuchAlgorithmException if the algorithm for recovering the
+     *          entry cannot be found
+     * @exception UnrecoverableEntryException if the specified
+     *          {@code protParam} were insufficient or invalid
+     * @exception UnrecoverableKeyException if the entry is a
+     *          {@code PrivateKeyEntry} or {@code SecretKeyEntry}
+     *          and the specified {@code protParam} does not contain
+     *          the information needed to recover the key (e.g. wrong password)
+     *
+     * @since 1.5
+     */
+    public KeyStore.Entry engineGetEntry(String alias,
+                        KeyStore.ProtectionParameter protParam)
+                throws KeyStoreException, NoSuchAlgorithmException,
+                UnrecoverableEntryException {
+
+        if (!engineContainsAlias(alias)) {
+            return null;
+        }
+
+        if (protParam == null) {
+            if (engineIsCertificateEntry(alias)) {
+                return new KeyStore.TrustedCertificateEntry
+                                (engineGetCertificate(alias));
+            // Android-removed: Allow access to entries with no password.
+            // } else {
+            //    throw new UnrecoverableKeyException
+            //            ("requested entry requires a password");
+            }
+        }
+
+        // Android-changed: Add protParam == null to allow access to entries with no password.
+        if ((protParam == null) || protParam instanceof KeyStore.PasswordProtection) {
+            if (engineIsCertificateEntry(alias)) {
+                throw new UnsupportedOperationException
+                    ("trusted certificate entries are not password-protected");
+            } else if (engineIsKeyEntry(alias)) {
+                // Android-changed: Allow access to entries with no password.
+                // KeyStore.PasswordProtection pp =
+                //         (KeyStore.PasswordProtection)protParam;
+                // char[] password = pp.getPassword();
+                char[] password = null;
+                if (protParam != null) {
+                    KeyStore.PasswordProtection pp =
+                        (KeyStore.PasswordProtection)protParam;
+                    password = pp.getPassword();
+                }
+                Key key = engineGetKey(alias, password);
+                if (key instanceof PrivateKey) {
+                    Certificate[] chain = engineGetCertificateChain(alias);
+                    return new KeyStore.PrivateKeyEntry((PrivateKey)key, chain);
+                } else if (key instanceof SecretKey) {
+                    return new KeyStore.SecretKeyEntry((SecretKey)key);
+                }
+            }
+        }
+
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Saves a {@code KeyStore.Entry} under the specified alias.
+     * The specified protection parameter is used to protect the
+     * {@code Entry}.
+     *
+     * <p> If an entry already exists for the specified alias,
+     * it is overridden.
+     *
+     * @param alias save the {@code KeyStore.Entry} under this alias
+     * @param entry the {@code Entry} to save
+     * @param protParam the {@code ProtectionParameter}
+     *          used to protect the {@code Entry},
+     *          which may be {@code null}
+     *
+     * @exception KeyStoreException if this operation fails
+     *
+     * @since 1.5
+     */
+    public void engineSetEntry(String alias, KeyStore.Entry entry,
+                        KeyStore.ProtectionParameter protParam)
+                throws KeyStoreException {
+
+        // get password
+        if (protParam != null &&
+            !(protParam instanceof KeyStore.PasswordProtection)) {
+            throw new KeyStoreException("unsupported protection parameter");
+        }
+        KeyStore.PasswordProtection pProtect = null;
+        if (protParam != null) {
+            pProtect = (KeyStore.PasswordProtection)protParam;
+        }
+
+        // BEGIN Android-changed: Allow access to entries with no password.
+        char[] password = (pProtect == null) ? null : pProtect.getPassword();
+        // set entry
+        if (entry instanceof KeyStore.TrustedCertificateEntry) {
+            KeyStore.TrustedCertificateEntry tce =
+                    (KeyStore.TrustedCertificateEntry)entry;
+            engineSetCertificateEntry(alias, tce.getTrustedCertificate());
+            return;
+        } else if (entry instanceof KeyStore.PrivateKeyEntry) {
+            engineSetKeyEntry
+                (alias,
+                ((KeyStore.PrivateKeyEntry)entry).getPrivateKey(),
+                password,
+                ((KeyStore.PrivateKeyEntry)entry).getCertificateChain());
+            return;
+        } else if (entry instanceof KeyStore.SecretKeyEntry) {
+            engineSetKeyEntry
+                (alias,
+                ((KeyStore.SecretKeyEntry)entry).getSecretKey(),
+                password,
+                (Certificate[])null);
+            return;
+        }
+        // END Android-changed: Allow access to entries with no password.
+
+        throw new KeyStoreException
+                ("unsupported entry type: " + entry.getClass().getName());
+    }
+
+    /**
+     * Determines if the keystore {@code Entry} for the specified
+     * {@code alias} is an instance or subclass of the specified
+     * {@code entryClass}.
+     *
+     * @param alias the alias name
+     * @param entryClass the entry class
+     *
+     * @return true if the keystore {@code Entry} for the specified
+     *          {@code alias} is an instance or subclass of the
+     *          specified {@code entryClass}, false otherwise
+     *
+     * @since 1.5
+     */
+    public boolean
+        engineEntryInstanceOf(String alias,
+                              Class<? extends KeyStore.Entry> entryClass)
+    {
+        if (entryClass == KeyStore.TrustedCertificateEntry.class) {
+            return engineIsCertificateEntry(alias);
+        }
+        if (entryClass == KeyStore.PrivateKeyEntry.class) {
+            return engineIsKeyEntry(alias) &&
+                        engineGetCertificate(alias) != null;
+        }
+        if (entryClass == KeyStore.SecretKeyEntry.class) {
+            return engineIsKeyEntry(alias) &&
+                        engineGetCertificate(alias) == null;
+        }
+        return false;
+    }
+}
diff --git a/java/security/MessageDigest.java b/java/security/MessageDigest.java
new file mode 100644
index 0000000..8e5dab1
--- /dev/null
+++ b/java/security/MessageDigest.java
@@ -0,0 +1,640 @@
+/*
+ * 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
+ * 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 java.security;
+
+import java.util.*;
+import java.lang.*;
+import java.io.IOException;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.io.InputStream;
+import java.io.ByteArrayInputStream;
+
+import java.nio.ByteBuffer;
+
+/**
+ * This MessageDigest class provides applications the functionality of a
+ * message digest algorithm, such as SHA-1 or SHA-256.
+ * Message digests are secure one-way hash functions that take arbitrary-sized
+ * data and output a fixed-length hash value.
+ *
+ * <p>A MessageDigest object starts out initialized. The data is
+ * processed through it using the {@link #update(byte) update}
+ * methods. At any point {@link #reset() reset} can be called
+ * to reset the digest. Once all the data to be updated has been
+ * updated, one of the {@link #digest() digest} methods should
+ * be called to complete the hash computation.
+ *
+ * <p>The {@code digest} method can be called once for a given number
+ * of updates. After {@code digest} has been called, the MessageDigest
+ * object is reset to its initialized state.
+ *
+ * <p>Implementations are free to implement the Cloneable interface.
+ * Client applications can test cloneability by attempting cloning
+ * and catching the CloneNotSupportedException:
+ *
+ * <pre>{@code
+ * MessageDigest md = MessageDigest.getInstance("SHA");
+ *
+ * try {
+ *     md.update(toChapter1);
+ *     MessageDigest tc1 = md.clone();
+ *     byte[] toChapter1Digest = tc1.digest();
+ *     md.update(toChapter2);
+ *     ...etc.
+ * } catch (CloneNotSupportedException cnse) {
+ *     throw new DigestException("couldn't make digest of partial content");
+ * }
+ * }</pre>
+ *
+ * <p>Note that if a given implementation is not cloneable, it is
+ * still possible to compute intermediate digests by instantiating
+ * several instances, if the number of digests is known in advance.
+ *
+ * <p>Note that this class is abstract and extends from
+ * {@code MessageDigestSpi} for historical reasons.
+ * Application developers should only take notice of the methods defined in
+ * this {@code MessageDigest} class; all the methods in
+ * the superclass are intended for cryptographic service providers who wish to
+ * supply their own implementations of message digest algorithms.
+ *
+ * <p> Android provides the following <code>MessageDigest</code> algorithms:
+ * <table>
+ *   <thead>
+ *     <tr>
+ *       <th>Algorithm</th>
+ *       <th>Supported API Levels</th>
+ *     </tr>
+ *   </thead>
+ *   <tbody>
+ *     <tr>
+ *       <td>MD5</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA-1</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA-224</td>
+ *       <td>1-8,22+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA-256</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA-384</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA-512</td>
+ *       <td>1+</td>
+ *     </tr>
+ *   </tbody>
+ * </table>
+ *
+ * These algorithms are described in the <a href=
+ * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#MessageDigest">
+ * MessageDigest section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ *
+ * @author Benjamin Renaud
+ *
+ * @see DigestInputStream
+ * @see DigestOutputStream
+ */
+
+public abstract class MessageDigest extends MessageDigestSpi {
+
+    // Android-removed: this debugging mechanism is not used in Android.
+    /*
+    private static final Debug pdebug =
+                        Debug.getInstance("provider", "Provider");
+    private static final boolean skipDebug =
+        Debug.isOn("engine=") && !Debug.isOn("messagedigest");
+    */
+
+    private String algorithm;
+
+    // The state of this digest
+    private static final int INITIAL = 0;
+    private static final int IN_PROGRESS = 1;
+    private int state = INITIAL;
+
+    // The provider
+    private Provider provider;
+
+    /**
+     * Creates a message digest with the specified algorithm name.
+     *
+     * @param algorithm the standard name of the digest algorithm.
+     * See the MessageDigest section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#MessageDigest">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard algorithm names.
+     */
+    protected MessageDigest(String algorithm) {
+        this.algorithm = algorithm;
+    }
+
+    /**
+     * Returns a MessageDigest object that implements the specified digest
+     * algorithm.
+     *
+     * <p> This method traverses the list of registered security Providers,
+     * starting with the most preferred Provider.
+     * A new MessageDigest object encapsulating the
+     * MessageDigestSpi implementation from the first
+     * Provider that supports the specified algorithm is returned.
+     *
+     * <p> Note that the list of registered providers may be retrieved via
+     * the {@link Security#getProviders() Security.getProviders()} method.
+     *
+     * @param algorithm the name of the algorithm requested.
+     * See the MessageDigest section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#MessageDigest">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard algorithm names.
+     *
+     * @return a Message Digest object that implements the specified algorithm.
+     *
+     * @exception NoSuchAlgorithmException if no Provider supports a
+     *          MessageDigestSpi implementation for the
+     *          specified algorithm.
+     *
+     * @see Provider
+     */
+    public static MessageDigest getInstance(String algorithm)
+    throws NoSuchAlgorithmException {
+        try {
+            MessageDigest md;
+            Object[] objs = Security.getImpl(algorithm, "MessageDigest",
+                                             (String)null);
+            if (objs[0] instanceof MessageDigest) {
+                md = (MessageDigest)objs[0];
+            } else {
+                md = new Delegate((MessageDigestSpi)objs[0], algorithm);
+            }
+            md.provider = (Provider)objs[1];
+
+            // Android-removed: this debugging mechanism is not used in Android.
+            /*
+            if (!skipDebug && pdebug != null) {
+                pdebug.println("MessageDigest." + algorithm +
+                    " algorithm from: " + md.provider.getName());
+            }
+            */
+
+            return md;
+
+        } catch(NoSuchProviderException e) {
+            throw new NoSuchAlgorithmException(algorithm + " not found");
+        }
+    }
+
+    /**
+     * Returns a MessageDigest object that implements the specified digest
+     * algorithm.
+     *
+     * <p> A new MessageDigest object encapsulating the
+     * MessageDigestSpi implementation from the specified provider
+     * is returned.  The specified provider must be registered
+     * in the security provider list.
+     *
+     * <p> Note that the list of registered providers may be retrieved via
+     * the {@link Security#getProviders() Security.getProviders()} method.
+     *
+     * @param algorithm the name of the algorithm requested.
+     * See the MessageDigest section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#MessageDigest">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard algorithm names.
+     *
+     * @param provider the name of the provider.
+     *
+     * @return a MessageDigest object that implements the specified algorithm.
+     *
+     * @exception NoSuchAlgorithmException if a MessageDigestSpi
+     *          implementation for the specified algorithm is not
+     *          available from the specified provider.
+     *
+     * @exception NoSuchProviderException if the specified provider is not
+     *          registered in the security provider list.
+     *
+     * @exception IllegalArgumentException if the provider name is null
+     *          or empty.
+     *
+     * @see Provider
+     */
+    public static MessageDigest getInstance(String algorithm, String provider)
+        throws NoSuchAlgorithmException, NoSuchProviderException
+    {
+        if (provider == null || provider.length() == 0)
+            throw new IllegalArgumentException("missing provider");
+        Object[] objs = Security.getImpl(algorithm, "MessageDigest", provider);
+        if (objs[0] instanceof MessageDigest) {
+            MessageDigest md = (MessageDigest)objs[0];
+            md.provider = (Provider)objs[1];
+            return md;
+        } else {
+            MessageDigest delegate =
+                new Delegate((MessageDigestSpi)objs[0], algorithm);
+            delegate.provider = (Provider)objs[1];
+            return delegate;
+        }
+    }
+
+    /**
+     * Returns a MessageDigest object that implements the specified digest
+     * algorithm.
+     *
+     * <p> A new MessageDigest object encapsulating the
+     * MessageDigestSpi implementation from the specified Provider
+     * object is returned.  Note that the specified Provider object
+     * does not have to be registered in the provider list.
+     *
+     * @param algorithm the name of the algorithm requested.
+     * See the MessageDigest section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#MessageDigest">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard algorithm names.
+     *
+     * @param provider the provider.
+     *
+     * @return a MessageDigest object that implements the specified algorithm.
+     *
+     * @exception NoSuchAlgorithmException if a MessageDigestSpi
+     *          implementation for the specified algorithm is not available
+     *          from the specified Provider object.
+     *
+     * @exception IllegalArgumentException if the specified provider is null.
+     *
+     * @see Provider
+     *
+     * @since 1.4
+     */
+    public static MessageDigest getInstance(String algorithm,
+                                            Provider provider)
+        throws NoSuchAlgorithmException
+    {
+        if (provider == null)
+            throw new IllegalArgumentException("missing provider");
+        Object[] objs = Security.getImpl(algorithm, "MessageDigest", provider);
+        if (objs[0] instanceof MessageDigest) {
+            MessageDigest md = (MessageDigest)objs[0];
+            md.provider = (Provider)objs[1];
+            return md;
+        } else {
+            MessageDigest delegate =
+                new Delegate((MessageDigestSpi)objs[0], algorithm);
+            delegate.provider = (Provider)objs[1];
+            return delegate;
+        }
+    }
+
+    /**
+     * Returns the provider of this message digest object.
+     *
+     * @return the provider of this message digest object
+     */
+    public final Provider getProvider() {
+        return this.provider;
+    }
+
+    /**
+     * Updates the digest using the specified byte.
+     *
+     * @param input the byte with which to update the digest.
+     */
+    public void update(byte input) {
+        engineUpdate(input);
+        state = IN_PROGRESS;
+    }
+
+    /**
+     * Updates the digest using the specified array of bytes, starting
+     * at the specified offset.
+     *
+     * @param input the array of bytes.
+     *
+     * @param offset the offset to start from in the array of bytes.
+     *
+     * @param len the number of bytes to use, starting at
+     * {@code offset}.
+     */
+    public void update(byte[] input, int offset, int len) {
+        if (input == null) {
+            throw new IllegalArgumentException("No input buffer given");
+        }
+        if (input.length - offset < len) {
+            throw new IllegalArgumentException("Input buffer too short");
+        }
+        engineUpdate(input, offset, len);
+        state = IN_PROGRESS;
+    }
+
+    /**
+     * Updates the digest using the specified array of bytes.
+     *
+     * @param input the array of bytes.
+     */
+    public void update(byte[] input) {
+        engineUpdate(input, 0, input.length);
+        state = IN_PROGRESS;
+    }
+
+    /**
+     * Update the digest using the specified ByteBuffer. The digest is
+     * updated using the {@code input.remaining()} bytes starting
+     * at {@code input.position()}.
+     * Upon return, the buffer's position will be equal to its limit;
+     * its limit will not have changed.
+     *
+     * @param input the ByteBuffer
+     * @since 1.5
+     */
+    public final void update(ByteBuffer input) {
+        if (input == null) {
+            throw new NullPointerException();
+        }
+        engineUpdate(input);
+        state = IN_PROGRESS;
+    }
+
+    /**
+     * Completes the hash computation by performing final operations
+     * such as padding. The digest is reset after this call is made.
+     *
+     * @return the array of bytes for the resulting hash value.
+     */
+    public byte[] digest() {
+        /* Resetting is the responsibility of implementors. */
+        byte[] result = engineDigest();
+        state = INITIAL;
+        return result;
+    }
+
+    /**
+     * Completes the hash computation by performing final operations
+     * such as padding. The digest is reset after this call is made.
+     *
+     * @param buf output buffer for the computed digest
+     *
+     * @param offset offset into the output buffer to begin storing the digest
+     *
+     * @param len number of bytes within buf allotted for the digest
+     *
+     * @return the number of bytes placed into {@code buf}
+     *
+     * @exception DigestException if an error occurs.
+     */
+    public int digest(byte[] buf, int offset, int len) throws DigestException {
+        if (buf == null) {
+            throw new IllegalArgumentException("No output buffer given");
+        }
+        if (buf.length - offset < len) {
+            throw new IllegalArgumentException
+                ("Output buffer too small for specified offset and length");
+        }
+        int numBytes = engineDigest(buf, offset, len);
+        state = INITIAL;
+        return numBytes;
+    }
+
+    /**
+     * Performs a final update on the digest using the specified array
+     * of bytes, then completes the digest computation. That is, this
+     * method first calls {@link #update(byte[]) update(input)},
+     * passing the <i>input</i> array to the {@code update} method,
+     * then calls {@link #digest() digest()}.
+     *
+     * @param input the input to be updated before the digest is
+     * completed.
+     *
+     * @return the array of bytes for the resulting hash value.
+     */
+    public byte[] digest(byte[] input) {
+        update(input);
+        return digest();
+    }
+
+    /**
+     * Returns a string representation of this message digest object.
+     */
+    public String toString() {
+        // BEGIN Android-changed: Use StringBuilder instead of a ByteArrayOutputStream.
+        StringBuilder builder = new StringBuilder();
+        builder.append(algorithm);
+        builder.append(" Message Digest from ");
+        builder.append(provider.getName());
+        builder.append(", ");
+
+        switch (state) {
+        case INITIAL:
+            builder.append("<initialized>");
+            break;
+        case IN_PROGRESS:
+            builder.append("<in progress>");
+            break;
+        }
+
+        return builder.toString();
+        // END Android-changed: Use StringBuilder instead of a ByteArrayOutputStream.
+    }
+
+    /**
+     * Compares two digests for equality. Does a simple byte compare.
+     *
+     * @param digesta one of the digests to compare.
+     *
+     * @param digestb the other digest to compare.
+     *
+     * @return true if the digests are equal, false otherwise.
+     */
+    public static boolean isEqual(byte[] digesta, byte[] digestb) {
+        if (digesta == digestb) return true;
+        if (digesta == null || digestb == null) {
+            return false;
+        }
+        if (digesta.length != digestb.length) {
+            return false;
+        }
+
+        int result = 0;
+        // time-constant comparison
+        for (int i = 0; i < digesta.length; i++) {
+            result |= digesta[i] ^ digestb[i];
+        }
+        return result == 0;
+    }
+
+    /**
+     * Resets the digest for further use.
+     */
+    public void reset() {
+        engineReset();
+        state = INITIAL;
+    }
+
+    /**
+     * Returns a string that identifies the algorithm, independent of
+     * implementation details. The name should be a standard
+     * Java Security name (such as "SHA", "MD5", and so on).
+     * See the MessageDigest section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#MessageDigest">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard algorithm names.
+     *
+     * @return the name of the algorithm
+     */
+    public final String getAlgorithm() {
+        return this.algorithm;
+    }
+
+    /**
+     * Returns the length of the digest in bytes, or 0 if this operation is
+     * not supported by the provider and the implementation is not cloneable.
+     *
+     * @return the digest length in bytes, or 0 if this operation is not
+     * supported by the provider and the implementation is not cloneable.
+     *
+     * @since 1.2
+     */
+    public final int getDigestLength() {
+        int digestLen = engineGetDigestLength();
+        if (digestLen == 0) {
+            try {
+                MessageDigest md = (MessageDigest)clone();
+                byte[] digest = md.digest();
+                return digest.length;
+            } catch (CloneNotSupportedException e) {
+                return digestLen;
+            }
+        }
+        return digestLen;
+    }
+
+    /**
+     * Returns a clone if the implementation is cloneable.
+     *
+     * @return a clone if the implementation is cloneable.
+     *
+     * @exception CloneNotSupportedException if this is called on an
+     * implementation that does not support {@code Cloneable}.
+     */
+    public Object clone() throws CloneNotSupportedException {
+        if (this instanceof Cloneable) {
+            return super.clone();
+        } else {
+            throw new CloneNotSupportedException();
+        }
+    }
+
+
+
+
+    /*
+     * The following class allows providers to extend from MessageDigestSpi
+     * rather than from MessageDigest. It represents a MessageDigest with an
+     * encapsulated, provider-supplied SPI object (of type MessageDigestSpi).
+     * If the provider implementation is an instance of MessageDigestSpi,
+     * the getInstance() methods above return an instance of this class, with
+     * the SPI object encapsulated.
+     *
+     * Note: All SPI methods from the original MessageDigest class have been
+     * moved up the hierarchy into a new class (MessageDigestSpi), which has
+     * been interposed in the hierarchy between the API (MessageDigest)
+     * and its original parent (Object).
+     */
+
+    static class Delegate extends MessageDigest {
+
+        // The provider implementation (delegate)
+        private MessageDigestSpi digestSpi;
+
+        // constructor
+        public Delegate(MessageDigestSpi digestSpi, String algorithm) {
+            super(algorithm);
+            this.digestSpi = digestSpi;
+        }
+
+        /**
+         * Returns a clone if the delegate is cloneable.
+         *
+         * @return a clone if the delegate is cloneable.
+         *
+         * @exception CloneNotSupportedException if this is called on a
+         * delegate that does not support {@code Cloneable}.
+         */
+        public Object clone() throws CloneNotSupportedException {
+            if (digestSpi instanceof Cloneable) {
+                MessageDigestSpi digestSpiClone =
+                    (MessageDigestSpi)digestSpi.clone();
+                // Because 'algorithm', 'provider', and 'state' are private
+                // members of our supertype, we must perform a cast to
+                // access them.
+                MessageDigest that =
+                    new Delegate(digestSpiClone,
+                                 ((MessageDigest)this).algorithm);
+                that.provider = ((MessageDigest)this).provider;
+                that.state = ((MessageDigest)this).state;
+                return that;
+            } else {
+                throw new CloneNotSupportedException();
+            }
+        }
+
+        protected int engineGetDigestLength() {
+            return digestSpi.engineGetDigestLength();
+        }
+
+        protected void engineUpdate(byte input) {
+            digestSpi.engineUpdate(input);
+        }
+
+        protected void engineUpdate(byte[] input, int offset, int len) {
+            digestSpi.engineUpdate(input, offset, len);
+        }
+
+        protected void engineUpdate(ByteBuffer input) {
+            digestSpi.engineUpdate(input);
+        }
+
+        protected byte[] engineDigest() {
+            return digestSpi.engineDigest();
+        }
+
+        protected int engineDigest(byte[] buf, int offset, int len)
+            throws DigestException {
+                return digestSpi.engineDigest(buf, offset, len);
+        }
+
+        protected void engineReset() {
+            digestSpi.engineReset();
+        }
+    }
+}
diff --git a/java/security/MessageDigestSpi.java b/java/security/MessageDigestSpi.java
new file mode 100644
index 0000000..0d5ace1
--- /dev/null
+++ b/java/security/MessageDigestSpi.java
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security;
+
+import java.nio.ByteBuffer;
+
+import sun.security.jca.JCAUtil;
+
+/**
+ * This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
+ * for the {@code MessageDigest} class, which provides the functionality
+ * of a message digest algorithm, such as MD5 or SHA. Message digests are
+ * secure one-way hash functions that take arbitrary-sized data and output a
+ * fixed-length hash value.
+ *
+ * <p> All the abstract methods in this class must be implemented by a
+ * cryptographic service provider who wishes to supply the implementation
+ * of a particular message digest algorithm.
+ *
+ * <p> Implementations are free to implement the Cloneable interface.
+ *
+ * @author Benjamin Renaud
+ *
+ *
+ * @see MessageDigest
+ */
+
+public abstract class MessageDigestSpi {
+
+    // for re-use in engineUpdate(ByteBuffer input)
+    private byte[] tempArray;
+
+    /**
+     * Returns the digest length in bytes.
+     *
+     * <p>This concrete method has been added to this previously-defined
+     * abstract class. (For backwards compatibility, it cannot be abstract.)
+     *
+     * <p>The default behavior is to return 0.
+     *
+     * <p>This method may be overridden by a provider to return the digest
+     * length.
+     *
+     * @return the digest length in bytes.
+     *
+     * @since 1.2
+     */
+    protected int engineGetDigestLength() {
+        return 0;
+    }
+
+    /**
+     * Updates the digest using the specified byte.
+     *
+     * @param input the byte to use for the update.
+     */
+    protected abstract void engineUpdate(byte input);
+
+    /**
+     * Updates the digest using the specified array of bytes,
+     * starting at the specified offset.
+     *
+     * @param input the array of bytes to use for the update.
+     *
+     * @param offset the offset to start from in the array of bytes.
+     *
+     * @param len the number of bytes to use, starting at
+     * {@code offset}.
+     */
+    protected abstract void engineUpdate(byte[] input, int offset, int len);
+
+    /**
+     * Update the digest using the specified ByteBuffer. The digest is
+     * updated using the {@code input.remaining()} bytes starting
+     * at {@code input.position()}.
+     * Upon return, the buffer's position will be equal to its limit;
+     * its limit will not have changed.
+     *
+     * @param input the ByteBuffer
+     * @since 1.5
+     */
+    protected void engineUpdate(ByteBuffer input) {
+        if (input.hasRemaining() == false) {
+            return;
+        }
+        if (input.hasArray()) {
+            byte[] b = input.array();
+            int ofs = input.arrayOffset();
+            int pos = input.position();
+            int lim = input.limit();
+            engineUpdate(b, ofs + pos, lim - pos);
+            input.position(lim);
+        } else {
+            int len = input.remaining();
+            int n = JCAUtil.getTempArraySize(len);
+            if ((tempArray == null) || (n > tempArray.length)) {
+                tempArray = new byte[n];
+            }
+            while (len > 0) {
+                int chunk = Math.min(len, tempArray.length);
+                input.get(tempArray, 0, chunk);
+                engineUpdate(tempArray, 0, chunk);
+                len -= chunk;
+            }
+        }
+    }
+
+    /**
+     * Completes the hash computation by performing final
+     * operations such as padding. Once {@code engineDigest} has
+     * been called, the engine should be reset (see
+     * {@link #engineReset() engineReset}).
+     * Resetting is the responsibility of the
+     * engine implementor.
+     *
+     * @return the array of bytes for the resulting hash value.
+     */
+    protected abstract byte[] engineDigest();
+
+    /**
+     * Completes the hash computation by performing final
+     * operations such as padding. Once {@code engineDigest} has
+     * been called, the engine should be reset (see
+     * {@link #engineReset() engineReset}).
+     * Resetting is the responsibility of the
+     * engine implementor.
+     *
+     * This method should be abstract, but we leave it concrete for
+     * binary compatibility.  Knowledgeable providers should override this
+     * method.
+     *
+     * @param buf the output buffer in which to store the digest
+     *
+     * @param offset offset to start from in the output buffer
+     *
+     * @param len number of bytes within buf allotted for the digest.
+     * Both this default implementation and the SUN provider do not
+     * return partial digests.  The presence of this parameter is solely
+     * for consistency in our API's.  If the value of this parameter is less
+     * than the actual digest length, the method will throw a DigestException.
+     * This parameter is ignored if its value is greater than or equal to
+     * the actual digest length.
+     *
+     * @return the length of the digest stored in the output buffer.
+     *
+     * @exception DigestException if an error occurs.
+     *
+     * @since 1.2
+     */
+    protected int engineDigest(byte[] buf, int offset, int len)
+                                                throws DigestException {
+
+        byte[] digest = engineDigest();
+        if (len < digest.length)
+                throw new DigestException("partial digests not returned");
+        if (buf.length - offset < digest.length)
+                throw new DigestException("insufficient space in the output "
+                                          + "buffer to store the digest");
+        System.arraycopy(digest, 0, buf, offset, digest.length);
+        return digest.length;
+    }
+
+    /**
+     * Resets the digest for further use.
+     */
+    protected abstract void engineReset();
+
+    /**
+     * Returns a clone if the implementation is cloneable.
+     *
+     * @return a clone if the implementation is cloneable.
+     *
+     * @exception CloneNotSupportedException if this is called on an
+     * implementation that does not support {@code Cloneable}.
+     */
+    public Object clone() throws CloneNotSupportedException {
+        if (this instanceof Cloneable) {
+            return super.clone();
+        } else {
+            throw new CloneNotSupportedException();
+        }
+    }
+}
diff --git a/java/security/NoSuchAlgorithmException.java b/java/security/NoSuchAlgorithmException.java
new file mode 100644
index 0000000..951e44e
--- /dev/null
+++ b/java/security/NoSuchAlgorithmException.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 1996, 2013, 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 java.security;
+
+/**
+ * This exception is thrown when a particular cryptographic algorithm is
+ * requested but is not available in the environment.
+ *
+ * @author Benjamin Renaud
+ */
+
+public class NoSuchAlgorithmException extends GeneralSecurityException {
+
+    private static final long serialVersionUID = -7443947487218346562L;
+
+    /**
+     * Constructs a NoSuchAlgorithmException with no detail
+     * message. A detail message is a String that describes this
+     * particular exception.
+     */
+    public NoSuchAlgorithmException() {
+        super();
+    }
+
+    /**
+     * Constructs a NoSuchAlgorithmException with the specified
+     * detail message. A detail message is a String that describes
+     * this particular exception, which may, for example, specify which
+     * algorithm is not available.
+     *
+     * @param msg the detail message.
+     */
+    public NoSuchAlgorithmException(String msg) {
+        super(msg);
+    }
+
+    /**
+     * Creates a {@code NoSuchAlgorithmException} with the specified
+     * detail message and cause.
+     *
+     * @param message the detail message (which is saved for later retrieval
+     *        by the {@link #getMessage()} method).
+     * @param cause the cause (which is saved for later retrieval by the
+     *        {@link #getCause()} method).  (A {@code null} value is permitted,
+     *        and indicates that the cause is nonexistent or unknown.)
+     * @since 1.5
+     */
+    public NoSuchAlgorithmException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Creates a {@code NoSuchAlgorithmException} with the specified cause
+     * and a detail message of {@code (cause==null ? null : cause.toString())}
+     * (which typically contains the class and detail message of
+     * {@code cause}).
+     *
+     * @param cause the cause (which is saved for later retrieval by the
+     *        {@link #getCause()} method).  (A {@code null} value is permitted,
+     *        and indicates that the cause is nonexistent or unknown.)
+     * @since 1.5
+     */
+    public NoSuchAlgorithmException(Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/java/security/NoSuchProviderException.java b/java/security/NoSuchProviderException.java
new file mode 100644
index 0000000..9874adb
--- /dev/null
+++ b/java/security/NoSuchProviderException.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1996, 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.  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 java.security;
+
+/**
+ * This exception is thrown when a particular security provider is
+ * requested but is not available in the environment.
+ *
+ * @author Benjamin Renaud
+ */
+
+public class NoSuchProviderException extends GeneralSecurityException {
+
+    private static final long serialVersionUID = 8488111756688534474L;
+
+    /**
+     * Constructs a NoSuchProviderException with no detail message. A
+     * detail message is a String that describes this particular
+     * exception.
+     */
+    public NoSuchProviderException() {
+        super();
+    }
+
+    /**
+     * Constructs a NoSuchProviderException with the specified detail
+     * message. A detail message is a String that describes this
+     * particular exception.
+     *
+     * @param msg the detail message.
+     */
+    public NoSuchProviderException(String msg) {
+        super(msg);
+    }
+}
diff --git a/java/security/PKCS12Attribute.java b/java/security/PKCS12Attribute.java
new file mode 100644
index 0000000..e389862
--- /dev/null
+++ b/java/security/PKCS12Attribute.java
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 2013, 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 java.security;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.regex.Pattern;
+import sun.security.util.*;
+
+/**
+ * An attribute associated with a PKCS12 keystore entry.
+ * The attribute name is an ASN.1 Object Identifier and the attribute
+ * value is a set of ASN.1 types.
+ *
+ * @since 1.8
+ */
+public final class PKCS12Attribute implements KeyStore.Entry.Attribute {
+
+    private static final Pattern COLON_SEPARATED_HEX_PAIRS =
+        Pattern.compile("^[0-9a-fA-F]{2}(:[0-9a-fA-F]{2})+$");
+    private String name;
+    private String value;
+    private byte[] encoded;
+    private int hashValue = -1;
+
+    /**
+     * Constructs a PKCS12 attribute from its name and value.
+     * The name is an ASN.1 Object Identifier represented as a list of
+     * dot-separated integers.
+     * A string value is represented as the string itself.
+     * A binary value is represented as a string of colon-separated
+     * pairs of hexadecimal digits.
+     * Multi-valued attributes are represented as a comma-separated
+     * list of values, enclosed in square brackets. See
+     * {@link Arrays#toString(java.lang.Object[])}.
+     * <p>
+     * A string value will be DER-encoded as an ASN.1 UTF8String and a
+     * binary value will be DER-encoded as an ASN.1 Octet String.
+     *
+     * @param name the attribute's identifier
+     * @param value the attribute's value
+     *
+     * @exception NullPointerException if {@code name} or {@code value}
+     *     is {@code null}
+     * @exception IllegalArgumentException if {@code name} or
+     *     {@code value} is incorrectly formatted
+     */
+    public PKCS12Attribute(String name, String value) {
+        if (name == null || value == null) {
+            throw new NullPointerException();
+        }
+        // Validate name
+        ObjectIdentifier type;
+        try {
+            type = new ObjectIdentifier(name);
+        } catch (IOException e) {
+            throw new IllegalArgumentException("Incorrect format: name", e);
+        }
+        this.name = name;
+
+        // Validate value
+        int length = value.length();
+        String[] values;
+        if (value.charAt(0) == '[' && value.charAt(length - 1) == ']') {
+            values = value.substring(1, length - 1).split(", ");
+        } else {
+            values = new String[]{ value };
+        }
+        this.value = value;
+
+        try {
+            this.encoded = encode(type, values);
+        } catch (IOException e) {
+            throw new IllegalArgumentException("Incorrect format: value", e);
+        }
+    }
+
+    /**
+     * Constructs a PKCS12 attribute from its ASN.1 DER encoding.
+     * The DER encoding is specified by the following ASN.1 definition:
+     * <pre>
+     *
+     * Attribute ::= SEQUENCE {
+     *     type   AttributeType,
+     *     values SET OF AttributeValue
+     * }
+     * AttributeType ::= OBJECT IDENTIFIER
+     * AttributeValue ::= ANY defined by type
+     *
+     * </pre>
+     *
+     * @param encoded the attribute's ASN.1 DER encoding. It is cloned
+     *     to prevent subsequent modificaion.
+     *
+     * @exception NullPointerException if {@code encoded} is
+     *     {@code null}
+     * @exception IllegalArgumentException if {@code encoded} is
+     *     incorrectly formatted
+     */
+    public PKCS12Attribute(byte[] encoded) {
+        if (encoded == null) {
+            throw new NullPointerException();
+        }
+        this.encoded = encoded.clone();
+
+        try {
+            parse(encoded);
+        } catch (IOException e) {
+            throw new IllegalArgumentException("Incorrect format: encoded", e);
+        }
+    }
+
+    /**
+     * Returns the attribute's ASN.1 Object Identifier represented as a
+     * list of dot-separated integers.
+     *
+     * @return the attribute's identifier
+     */
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Returns the attribute's ASN.1 DER-encoded value as a string.
+     * An ASN.1 DER-encoded value is returned in one of the following
+     * {@code String} formats:
+     * <ul>
+     * <li> the DER encoding of a basic ASN.1 type that has a natural
+     *      string representation is returned as the string itself.
+     *      Such types are currently limited to BOOLEAN, INTEGER,
+     *      OBJECT IDENTIFIER, UTCTime, GeneralizedTime and the
+     *      following six ASN.1 string types: UTF8String,
+     *      PrintableString, T61String, IA5String, BMPString and
+     *      GeneralString.
+     * <li> the DER encoding of any other ASN.1 type is not decoded but
+     *      returned as a binary string of colon-separated pairs of
+     *      hexadecimal digits.
+     * </ul>
+     * Multi-valued attributes are represented as a comma-separated
+     * list of values, enclosed in square brackets. See
+     * {@link Arrays#toString(java.lang.Object[])}.
+     *
+     * @return the attribute value's string encoding
+     */
+    @Override
+    public String getValue() {
+        return value;
+    }
+
+    /**
+     * Returns the attribute's ASN.1 DER encoding.
+     *
+     * @return a clone of the attribute's DER encoding
+     */
+    public byte[] getEncoded() {
+        return encoded.clone();
+    }
+
+    /**
+     * Compares this {@code PKCS12Attribute} and a specified object for
+     * equality.
+     *
+     * @param obj the comparison object
+     *
+     * @return true if {@code obj} is a {@code PKCS12Attribute} and
+     * their DER encodings are equal.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof PKCS12Attribute)) {
+            return false;
+        }
+        return Arrays.equals(encoded, ((PKCS12Attribute) obj).getEncoded());
+    }
+
+    /**
+     * Returns the hashcode for this {@code PKCS12Attribute}.
+     * The hash code is computed from its DER encoding.
+     *
+     * @return the hash code
+     */
+    @Override
+    public int hashCode() {
+        if (hashValue == -1) {
+            Arrays.hashCode(encoded);
+        }
+        return hashValue;
+    }
+
+    /**
+     * Returns a string representation of this {@code PKCS12Attribute}.
+     *
+     * @return a name/value pair separated by an 'equals' symbol
+     */
+    @Override
+    public String toString() {
+        return (name + "=" + value);
+    }
+
+    private byte[] encode(ObjectIdentifier type, String[] values)
+            throws IOException {
+        DerOutputStream attribute = new DerOutputStream();
+        attribute.putOID(type);
+        DerOutputStream attrContent = new DerOutputStream();
+        for (String value : values) {
+            if (COLON_SEPARATED_HEX_PAIRS.matcher(value).matches()) {
+                byte[] bytes =
+                    new BigInteger(value.replace(":", ""), 16).toByteArray();
+                if (bytes[0] == 0) {
+                    bytes = Arrays.copyOfRange(bytes, 1, bytes.length);
+                }
+                attrContent.putOctetString(bytes);
+            } else {
+                attrContent.putUTF8String(value);
+            }
+        }
+        attribute.write(DerValue.tag_Set, attrContent);
+        DerOutputStream attributeValue = new DerOutputStream();
+        attributeValue.write(DerValue.tag_Sequence, attribute);
+
+        return attributeValue.toByteArray();
+    }
+
+    private void parse(byte[] encoded) throws IOException {
+        DerInputStream attributeValue = new DerInputStream(encoded);
+        DerValue[] attrSeq = attributeValue.getSequence(2);
+        ObjectIdentifier type = attrSeq[0].getOID();
+        DerInputStream attrContent =
+            new DerInputStream(attrSeq[1].toByteArray());
+        DerValue[] attrValueSet = attrContent.getSet(1);
+        String[] values = new String[attrValueSet.length];
+        String printableString;
+        for (int i = 0; i < attrValueSet.length; i++) {
+            if (attrValueSet[i].tag == DerValue.tag_OctetString) {
+                values[i] = Debug.toString(attrValueSet[i].getOctetString());
+            } else if ((printableString = attrValueSet[i].getAsString())
+                != null) {
+                values[i] = printableString;
+            } else if (attrValueSet[i].tag == DerValue.tag_ObjectId) {
+                values[i] = attrValueSet[i].getOID().toString();
+            } else if (attrValueSet[i].tag == DerValue.tag_GeneralizedTime) {
+                values[i] = attrValueSet[i].getGeneralizedTime().toString();
+            } else if (attrValueSet[i].tag == DerValue.tag_UtcTime) {
+                values[i] = attrValueSet[i].getUTCTime().toString();
+            } else if (attrValueSet[i].tag == DerValue.tag_Integer) {
+                values[i] = attrValueSet[i].getBigInteger().toString();
+            } else if (attrValueSet[i].tag == DerValue.tag_Boolean) {
+                values[i] = String.valueOf(attrValueSet[i].getBoolean());
+            } else {
+                values[i] = Debug.toString(attrValueSet[i].getDataBytes());
+            }
+        }
+
+        this.name = type.toString();
+        this.value = values.length == 1 ? values[0] : Arrays.toString(values);
+    }
+}
diff --git a/java/security/Permission.java b/java/security/Permission.java
new file mode 100644
index 0000000..9b258a6
--- /dev/null
+++ b/java/security/Permission.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security;
+
+// Android-changed: Stubbed the implementation.  Android doesn't support SecurityManager.
+// See comments in java.lang.SecurityManager for details.
+/**
+ * Legacy security code; do not use.
+ */
+
+public abstract class Permission implements Guard, java.io.Serializable {
+
+    private String name;
+
+    public Permission(String name) {
+        this.name = name;
+    }
+
+    public void checkGuard(Object object) throws SecurityException { }
+
+    public abstract boolean implies(Permission permission);
+
+    public final String getName() {
+        return name;
+    }
+
+    public abstract String getActions();
+
+    public PermissionCollection newPermissionCollection() { return new Permissions(); }
+}
diff --git a/java/security/PermissionCollection.java b/java/security/PermissionCollection.java
new file mode 100644
index 0000000..f1015e3
--- /dev/null
+++ b/java/security/PermissionCollection.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 1997, 2006, 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 java.security;
+
+import java.util.*;
+
+// Android-changed: Stubbed the implementation.  Android doesn't support SecurityManager.
+// See comments in java.lang.SecurityManager for details.
+/**
+ * Legacy security code; do not use.
+ */
+
+public abstract class PermissionCollection implements java.io.Serializable {
+
+    public abstract void add(Permission permission);
+
+    public abstract boolean implies(Permission permission);
+
+    public abstract Enumeration<Permission> elements();
+
+    public void setReadOnly() { }
+
+    public boolean isReadOnly() { return true; }
+}
diff --git a/java/security/Permissions.java b/java/security/Permissions.java
new file mode 100644
index 0000000..9796f01
--- /dev/null
+++ b/java/security/Permissions.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security;
+
+import java.util.Enumeration;
+import java.io.Serializable;
+
+
+// Android-changed: Stubbed the implementation.  Android doesn't support SecurityManager.
+// See comments in java.lang.SecurityManager for details.
+/**
+ * Legacy security code; do not use.
+ */
+
+public final class Permissions extends PermissionCollection
+implements Serializable
+{
+    public void add(Permission permission) { }
+
+    public boolean implies(Permission permission) { return true; }
+
+    public Enumeration<Permission> elements() { return null; }
+}
diff --git a/java/security/Policy.java b/java/security/Policy.java
new file mode 100644
index 0000000..cb7fb3b
--- /dev/null
+++ b/java/security/Policy.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1997, 2011, 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 java.security;
+
+import java.util.Enumeration;
+
+// Android-changed: Stubbed the implementation.  Android doesn't support SecurityManager.
+// See comments in java.lang.SecurityManager for details.
+/**
+ * Legacy security code; do not use.
+ */
+public abstract class Policy {
+
+    public static final PermissionCollection UNSUPPORTED_EMPTY_COLLECTION =
+                        new UnsupportedEmptyCollection();
+
+    public static Policy getPolicy()
+    {
+      return null;
+    }
+
+    public static void setPolicy(Policy p)
+    {
+    }
+
+    public static Policy getInstance(String type, Policy.Parameters params)
+                throws NoSuchAlgorithmException {
+      return null;
+    }
+
+    public static Policy getInstance(String type,
+                                Policy.Parameters params,
+                                String provider)
+                throws NoSuchProviderException, NoSuchAlgorithmException {
+      return null;
+    }
+
+
+    public static Policy getInstance(String type,
+                                Policy.Parameters params,
+                                Provider provider)
+                throws NoSuchAlgorithmException {
+      return null;
+    }
+
+    public Provider getProvider() {
+        return null;
+    }
+
+    public String getType() {
+        return null;
+    }
+
+    public Policy.Parameters getParameters() {
+        return null;
+    }
+
+    public PermissionCollection getPermissions(CodeSource codesource) {
+        return null;
+    }
+
+    public PermissionCollection getPermissions(ProtectionDomain domain) {
+        return null;
+    }
+
+    public boolean implies(ProtectionDomain domain, Permission permission) {
+        return true;
+    }
+
+    public void refresh() { }
+
+    public static interface Parameters { }
+
+    private static class UnsupportedEmptyCollection
+        extends PermissionCollection {
+
+        public UnsupportedEmptyCollection() {
+        }
+
+        @Override public void add(Permission permission) {
+        }
+
+        @Override public boolean implies(Permission permission) {
+            return true;
+        }
+
+        @Override public Enumeration<Permission> elements() {
+            return null;
+        }
+    }
+
+}
diff --git a/java/security/PolicySpi.java b/java/security/PolicySpi.java
new file mode 100644
index 0000000..608ce1f
--- /dev/null
+++ b/java/security/PolicySpi.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2005, 2013, 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 java.security;
+
+/**
+ * This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
+ * for the {@code Policy} class.
+ * All the abstract methods in this class must be implemented by each
+ * service provider who wishes to supply a Policy implementation.
+ *
+ * <p> Subclass implementations of this abstract class must provide
+ * a public constructor that takes a {@code Policy.Parameters}
+ * object as an input parameter.  This constructor also must throw
+ * an IllegalArgumentException if it does not understand the
+ * {@code Policy.Parameters} input.
+ *
+ *
+ * @since 1.6
+ */
+
+public abstract class PolicySpi {
+
+    /**
+     * Check whether the policy has granted a Permission to a ProtectionDomain.
+     *
+     * @param domain the ProtectionDomain to check.
+     *
+     * @param permission check whether this permission is granted to the
+     *          specified domain.
+     *
+     * @return boolean true if the permission is granted to the domain.
+     */
+    protected abstract boolean engineImplies
+        (ProtectionDomain domain, Permission permission);
+
+    /**
+     * Refreshes/reloads the policy configuration. The behavior of this method
+     * depends on the implementation. For example, calling {@code refresh}
+     * on a file-based policy will cause the file to be re-read.
+     *
+     * <p> The default implementation of this method does nothing.
+     * This method should be overridden if a refresh operation is supported
+     * by the policy implementation.
+     */
+    protected void engineRefresh() { }
+
+    /**
+     * Return a PermissionCollection object containing the set of
+     * permissions granted to the specified CodeSource.
+     *
+     * <p> The default implementation of this method returns
+     * Policy.UNSUPPORTED_EMPTY_COLLECTION object.  This method can be
+     * overridden if the policy implementation can return a set of
+     * permissions granted to a CodeSource.
+     *
+     * @param codesource the CodeSource to which the returned
+     *          PermissionCollection has been granted.
+     *
+     * @return a set of permissions granted to the specified CodeSource.
+     *          If this operation is supported, the returned
+     *          set of permissions must be a new mutable instance
+     *          and it must support heterogeneous Permission types.
+     *          If this operation is not supported,
+     *          Policy.UNSUPPORTED_EMPTY_COLLECTION is returned.
+     */
+    protected PermissionCollection engineGetPermissions
+                                        (CodeSource codesource) {
+        return Policy.UNSUPPORTED_EMPTY_COLLECTION;
+    }
+
+    /**
+     * Return a PermissionCollection object containing the set of
+     * permissions granted to the specified ProtectionDomain.
+     *
+     * <p> The default implementation of this method returns
+     * Policy.UNSUPPORTED_EMPTY_COLLECTION object.  This method can be
+     * overridden if the policy implementation can return a set of
+     * permissions granted to a ProtectionDomain.
+     *
+     * @param domain the ProtectionDomain to which the returned
+     *          PermissionCollection has been granted.
+     *
+     * @return a set of permissions granted to the specified ProtectionDomain.
+     *          If this operation is supported, the returned
+     *          set of permissions must be a new mutable instance
+     *          and it must support heterogeneous Permission types.
+     *          If this operation is not supported,
+     *          Policy.UNSUPPORTED_EMPTY_COLLECTION is returned.
+     */
+    protected PermissionCollection engineGetPermissions
+                                        (ProtectionDomain domain) {
+        return Policy.UNSUPPORTED_EMPTY_COLLECTION;
+    }
+}
diff --git a/java/security/Principal.java b/java/security/Principal.java
new file mode 100644
index 0000000..a538e70
--- /dev/null
+++ b/java/security/Principal.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 1996, 2013, 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 java.security;
+
+import javax.security.auth.Subject;
+
+/**
+ * This interface represents the abstract notion of a principal, which
+ * can be used to represent any entity, such as an individual, a
+ * corporation, and a login id.
+ *
+ * @see java.security.cert.X509Certificate
+ *
+ * @author Li Gong
+ */
+public interface Principal {
+
+    /**
+     * Compares this principal to the specified object.  Returns true
+     * if the object passed in matches the principal represented by
+     * the implementation of this interface.
+     *
+     * @param another principal to compare with.
+     *
+     * @return true if the principal passed in is the same as that
+     * encapsulated by this principal, and false otherwise.
+     */
+    public boolean equals(Object another);
+
+    /**
+     * Returns a string representation of this principal.
+     *
+     * @return a string representation of this principal.
+     */
+    public String toString();
+
+    /**
+     * Returns a hashcode for this principal.
+     *
+     * @return a hashcode for this principal.
+     */
+    public int hashCode();
+
+    /**
+     * Returns the name of this principal.
+     *
+     * @return the name of this principal.
+     */
+    public String getName();
+
+    /**
+     * Returns true if the specified subject is implied by this principal.
+     *
+     * <p>The default implementation of this method returns true if
+     * {@code subject} is non-null and contains at least one principal that
+     * is equal to this principal.
+     *
+     * <p>Subclasses may override this with a different implementation, if
+     * necessary.
+     *
+     * @param subject the {@code Subject}
+     * @return true if {@code subject} is non-null and is
+     *              implied by this principal, or false otherwise.
+     * @since 1.8
+     */
+    public default boolean implies(Subject subject) {
+        if (subject == null)
+            return false;
+        return subject.getPrincipals().contains(this);
+    }
+}
diff --git a/java/security/PrivateKey.java b/java/security/PrivateKey.java
new file mode 100644
index 0000000..7d8a7ea
--- /dev/null
+++ b/java/security/PrivateKey.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 1996, 2013, 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 java.security;
+
+/**
+ * A private key.
+ * The purpose of this interface is to group (and provide type safety
+ * for) all private key interfaces.
+ * <p>
+ * Note: The specialized private key interfaces extend this interface.
+ * See, for example, the {@code DSAPrivateKey} interface in
+ * {@link java.security.interfaces}.
+ * <p>
+ * Implementations should override the default {@code destroy} and
+ * {@code isDestroyed} methods from the
+ * {@link javax.security.auth.Destroyable} interface to enable
+ * sensitive key information to be destroyed, cleared, or in the case
+ * where such information is immutable, unreferenced.
+ * Finally, since {@code PrivateKey} is {@code Serializable}, implementations
+ * should also override
+ * {@link java.io.ObjectOutputStream#writeObject(java.lang.Object)}
+ * to prevent keys that have been destroyed from being serialized.
+ *
+ * @see Key
+ * @see PublicKey
+ * @see Certificate
+ * @see Signature#initVerify
+ * @see java.security.interfaces.DSAPrivateKey
+ * @see java.security.interfaces.RSAPrivateKey
+ * @see java.security.interfaces.RSAPrivateCrtKey
+ *
+ * @author Benjamin Renaud
+ * @author Josh Bloch
+ */
+
+public interface PrivateKey extends Key, javax.security.auth.Destroyable {
+
+    // Declare serialVersionUID to be compatible with JDK1.1
+    /**
+     * The class fingerprint that is set to indicate serialization
+     * compatibility with a previous version of the class.
+     */
+    static final long serialVersionUID = 6034044314589513430L;
+}
diff --git a/java/security/PrivilegedAction.java b/java/security/PrivilegedAction.java
new file mode 100644
index 0000000..5844b4d
--- /dev/null
+++ b/java/security/PrivilegedAction.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 1998, 2013, 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 java.security;
+
+
+// Android-changed: Stubbed the implementation.  Android doesn't support SecurityManager.
+// See comments in java.lang.SecurityManager for details.
+/**
+ * Legacy security code; do not use.
+ */
+
+public interface PrivilegedAction<T> {
+
+    T run();
+}
diff --git a/java/security/PrivilegedActionException.java b/java/security/PrivilegedActionException.java
new file mode 100644
index 0000000..b1eb28f
--- /dev/null
+++ b/java/security/PrivilegedActionException.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 1998, 2013, 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 java.security;
+
+// Android-changed: Stubbed the implementation.  Android doesn't support SecurityManager.
+// See comments in java.lang.SecurityManager for details.
+/**
+ * Legacy security code; do not use.
+ *
+ * This exception is thrown by
+ * {@code doPrivileged(PrivilegedExceptionAction)} and
+ * {@code doPrivileged(PrivilegedExceptionAction,
+ * AccessControlContext context)} to indicate
+ * that the action being performed threw a checked exception.  The exception
+ * thrown by the action can be obtained by calling the
+ * {@code getException} method.  In effect, an
+ * {@code PrivilegedActionException} is a "wrapper"
+ * for an exception thrown by a privileged action.
+ *
+ * <p>As of release 1.4, this exception has been retrofitted to conform to
+ * the general purpose exception-chaining mechanism.  The "exception thrown
+ * by the privileged computation" that is provided at construction time and
+ * accessed via the {@link #getException()} method is now known as the
+ * <i>cause</i>, and may be accessed via the {@link Throwable#getCause()}
+ * method, as well as the aforementioned "legacy method."
+ *
+ * @see PrivilegedExceptionAction
+ * @see AccessController#doPrivileged(PrivilegedExceptionAction)
+ * @see AccessController#doPrivileged(PrivilegedExceptionAction,AccessControlContext)
+ */
+public class PrivilegedActionException extends Exception {
+    // use serialVersionUID from JDK 1.2.2 for interoperability
+    private static final long serialVersionUID = 4724086851538908602L;
+
+    /**
+     * @serial
+     */
+    private Exception exception;
+
+    /**
+     * Constructs a new PrivilegedActionException &quot;wrapping&quot;
+     * the specific Exception.
+     *
+     * @param exception The exception thrown
+     */
+    public PrivilegedActionException(Exception exception) {
+        super((Throwable)null);  // Disallow initCause
+        this.exception = exception;
+    }
+
+    /**
+     * Returns the exception thrown by the privileged computation that
+     * resulted in this {@code PrivilegedActionException}.
+     *
+     * <p>This method predates the general-purpose exception chaining facility.
+     * The {@link Throwable#getCause()} method is now the preferred means of
+     * obtaining this information.
+     *
+     * @return the exception thrown by the privileged computation that
+     *         resulted in this {@code PrivilegedActionException}.
+     * @see PrivilegedExceptionAction
+     * @see AccessController#doPrivileged(PrivilegedExceptionAction)
+     * @see AccessController#doPrivileged(PrivilegedExceptionAction,
+     *                                            AccessControlContext)
+     */
+    public Exception getException() {
+        return exception;
+    }
+
+    /**
+     * Returns the cause of this exception (the exception thrown by
+     * the privileged computation that resulted in this
+     * {@code PrivilegedActionException}).
+     *
+     * @return  the cause of this exception.
+     * @since   1.4
+     */
+    public Throwable getCause() {
+        return exception;
+    }
+
+    public String toString() {
+        String s = getClass().getName();
+        return (exception != null) ? (s + ": " + exception.toString()) : s;
+    }
+}
diff --git a/java/security/PrivilegedExceptionAction.java b/java/security/PrivilegedExceptionAction.java
new file mode 100644
index 0000000..4023150
--- /dev/null
+++ b/java/security/PrivilegedExceptionAction.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 1998, 2013, 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 java.security;
+
+
+// Android-changed: Stubbed the implementation.  Android doesn't support SecurityManager.
+// See comments in java.lang.SecurityManager for details.
+/**
+ * Legacy security code; do not use.
+ */
+public interface PrivilegedExceptionAction<T> {
+
+    T run() throws Exception;
+}
diff --git a/java/security/ProtectionDomain.java b/java/security/ProtectionDomain.java
new file mode 100644
index 0000000..9e117a6
--- /dev/null
+++ b/java/security/ProtectionDomain.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1997, 2013, 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 java.security;
+
+// Android-changed: Stubbed the implementation.  Android doesn't support SecurityManager.
+// See comments in java.lang.SecurityManager for details.
+/**
+ * Legacy security code; do not use.
+ */
+
+public class ProtectionDomain {
+
+    public ProtectionDomain(CodeSource codesource,
+                            PermissionCollection permissions) { }
+
+    public ProtectionDomain(CodeSource codesource,
+                            PermissionCollection permissions,
+                            ClassLoader classloader,
+                            Principal[] principals) { }
+
+    public final CodeSource getCodeSource() { return null; }
+
+    public final ClassLoader getClassLoader() { return null; }
+
+    public final Principal[] getPrincipals() { return null; }
+
+    public final PermissionCollection getPermissions() { return null; }
+
+    public boolean implies(Permission permission) { return true; }
+}
diff --git a/java/security/Provider.java b/java/security/Provider.java
new file mode 100644
index 0000000..cbf37db
--- /dev/null
+++ b/java/security/Provider.java
@@ -0,0 +1,1925 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 2014, 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 java.security;
+
+import java.io.*;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static java.util.Locale.ENGLISH;
+
+import java.lang.ref.*;
+import java.lang.reflect.*;
+import java.security.Security;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+/**
+ * This class represents a "provider" for the
+ * Java Security API, where a provider implements some or all parts of
+ * Java Security. Services that a provider may implement include:
+ *
+ * <ul>
+ *
+ * <li>Algorithms (such as DSA, RSA, MD5 or SHA-1).
+ *
+ * <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 =
+ * "{@docRoot}openjdk-redirect.html?v=8&path=/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.
+ *
+ * <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>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.
+ * The following attributes are automatically placed in each Provider object:
+ * <table cellspacing=4>
+ * <caption><b>Attributes Automatically Placed in a Provider Object</b></caption>
+ * <tr><th>Name</th><th>Value</th>
+ * <tr><td>{@code Provider.id name}</td>
+  *    <td>{@code String.valueOf(provider.getName())}</td>
+ * <tr><td>{@code Provider.id version}</td>
+ *     <td>{@code String.valueOf(provider.getVersion())}</td>
+ * <tr><td>{@code Provider.id info}</td>
+       <td>{@code String.valueOf(provider.getInfo())}</td>
+ * <tr><td>{@code Provider.id className}</td>
+ *     <td>{@code provider.getClass().getName()}</td>
+ * </table>
+ *
+ * @author Benjamin Renaud
+ * @author Andreas Sterbenz
+ */
+public abstract class Provider extends Properties {
+
+    // Declare serialVersionUID to be compatible with JDK1.1
+    static final long serialVersionUID = -4298000515446427739L;
+
+    // Android-added: Provider registration
+    // Marking a provider as "registered" makes it change the security version when
+    // changes to it are made.  As of 2017-05-22 this is only used in ProviderTest.
+    // TODO: Change ProviderTest to no longer require this mechanism
+    private volatile boolean registered = false;
+
+    private static final sun.security.util.Debug debug =
+        sun.security.util.Debug.getInstance
+        ("provider", "Provider");
+
+    /**
+     * The provider name.
+     *
+     * @serial
+     */
+    private String name;
+
+    /**
+     * A description of the provider and its services.
+     *
+     * @serial
+     */
+    private String info;
+
+    /**
+     * The provider version number.
+     *
+     * @serial
+     */
+    private double version;
+
+
+    private transient Set<Map.Entry<Object,Object>> entrySet = null;
+    private transient int entrySetCallCount = 0;
+
+    private transient boolean initialized;
+
+    /**
+     * Constructs a provider with the specified name, version number,
+     * and information.
+     *
+     * @param name the provider name.
+     *
+     * @param version the provider version number.
+     *
+     * @param info a description of the provider and its services.
+     */
+    protected Provider(String name, double version, String info) {
+        this.name = name;
+        this.version = version;
+        this.info = info;
+        putId();
+        initialized = true;
+    }
+
+    /**
+     * Returns the name of this provider.
+     *
+     * @return the name of this provider.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Returns the version number for this provider.
+     *
+     * @return the version number for this provider.
+     */
+    public double getVersion() {
+        return version;
+    }
+
+    /**
+     * Returns a human-readable description of the provider and its
+     * services.  This may return an HTML page, with relevant links.
+     *
+     * @return a description of the provider and its services.
+     */
+    public String getInfo() {
+        return info;
+    }
+
+    /**
+     * Returns a string with the name and the version number
+     * of this provider.
+     *
+     * @return the string with the name and the version number
+     * for this provider.
+     */
+    public String toString() {
+        return name + " version " + version;
+    }
+
+    /*
+     * override the following methods to ensure that provider
+     * information can only be changed if the caller has the appropriate
+     * permissions.
+     */
+
+    /**
+     * Clears this provider so that it no longer contains the properties
+     * used to look up facilities implemented by the provider.
+     *
+     * <p>If a security manager is enabled, its {@code checkSecurityAccess}
+     * method is called with the string {@code "clearProviderProperties."+name}
+     * (where {@code name} is the provider name) to see if it's ok to clear
+     * this provider.
+     *
+     * @throws  SecurityException
+     *          if a security manager exists and its {@link
+     *          java.lang.SecurityManager#checkSecurityAccess} method
+     *          denies access to clear this provider
+     *
+     * @since 1.2
+     */
+    @Override
+    public synchronized void clear() {
+        check("clearProviderProperties."+name);
+        if (debug != null) {
+            debug.println("Remove " + name + " provider properties");
+        }
+        implClear();
+    }
+
+    /**
+     * 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
+     *               input stream.
+     * @see java.util.Properties#load
+     */
+    @Override
+    public synchronized void load(InputStream inStream) throws IOException {
+        check("putProviderProperty."+name);
+        if (debug != null) {
+            debug.println("Load " + name + " provider properties");
+        }
+        Properties tempProperties = new Properties();
+        tempProperties.load(inStream);
+        implPutAll(tempProperties);
+    }
+
+    /**
+     * Copies all of the mappings from the specified Map to this provider.
+     * These mappings will replace any properties that this provider had
+     * for any of the keys currently in the specified Map.
+     *
+     * @since 1.2
+     */
+    @Override
+    public synchronized void putAll(Map<?,?> t) {
+        check("putProviderProperty."+name);
+        if (debug != null) {
+            debug.println("Put all " + name + " provider properties");
+        }
+        implPutAll(t);
+    }
+
+    /**
+     * Returns an unmodifiable Set view of the property entries contained
+     * in this Provider.
+     *
+     * @see   java.util.Map.Entry
+     * @since 1.2
+     */
+    @Override
+    public synchronized Set<Map.Entry<Object,Object>> entrySet() {
+        checkInitialized();
+        if (entrySet == null) {
+            if (entrySetCallCount++ == 0)  // Initial call
+                entrySet = Collections.unmodifiableMap(this).entrySet();
+            else
+                return super.entrySet();   // Recursive call
+        }
+
+        // This exception will be thrown if the implementation of
+        // Collections.unmodifiableMap.entrySet() is changed such that it
+        // no longer calls entrySet() on the backing Map.  (Provider's
+        // entrySet implementation depends on this "implementation detail",
+        // which is unlikely to change.
+        if (entrySetCallCount != 2)
+            throw new RuntimeException("Internal error.");
+
+        return entrySet;
+    }
+
+    /**
+     * Returns an unmodifiable Set view of the property keys contained in
+     * this provider.
+     *
+     * @since 1.2
+     */
+    @Override
+    public Set<Object> keySet() {
+        checkInitialized();
+        return Collections.unmodifiableSet(super.keySet());
+    }
+
+    /**
+     * Returns an unmodifiable Collection view of the property values
+     * contained in this provider.
+     *
+     * @since 1.2
+     */
+    @Override
+    public Collection<Object> values() {
+        checkInitialized();
+        return Collections.unmodifiableCollection(super.values());
+    }
+
+    /**
+     * Sets the {@code key} property to have the specified
+     * {@code value}.
+     *
+     * <p>If a security manager is enabled, its {@code checkSecurityAccess}
+     * method is called with the string {@code "putProviderProperty."+name},
+     * where {@code name} is the provider name, to see if it's ok to set this
+     * provider's property values.
+     *
+     * @throws  SecurityException
+     *          if a security manager exists and its {@link
+     *          java.lang.SecurityManager#checkSecurityAccess} method
+     *          denies access to set property values.
+     *
+     * @since 1.2
+     */
+    @Override
+    public synchronized Object put(Object key, Object value) {
+        check("putProviderProperty."+name);
+        if (debug != null) {
+            debug.println("Set " + name + " provider property [" +
+                          key + "/" + value +"]");
+        }
+        return implPut(key, value);
+    }
+
+    /**
+     * If the specified key is not already associated with a value (or is mapped
+     * to {@code null}) associates it with the given value and returns
+     * {@code null}, else returns the current value.
+     *
+     * <p>If a security manager is enabled, its {@code checkSecurityAccess}
+     * method is called with the string {@code "putProviderProperty."+name},
+     * where {@code name} is the provider name, to see if it's ok to set this
+     * provider's property values.
+     *
+     * @throws  SecurityException
+     *          if a security manager exists and its {@link
+     *          java.lang.SecurityManager#checkSecurityAccess} method
+     *          denies access to set property values.
+     *
+     * @since 1.8
+     */
+    @Override
+    public synchronized Object putIfAbsent(Object key, Object value) {
+        check("putProviderProperty."+name);
+        if (debug != null) {
+            debug.println("Set " + name + " provider property [" +
+                          key + "/" + value +"]");
+        }
+        return implPutIfAbsent(key, value);
+    }
+
+    /**
+     * Removes the {@code key} property (and its corresponding
+     * {@code value}).
+     *
+     * <p>If a security manager is enabled, its {@code checkSecurityAccess}
+     * method is called with the string {@code "removeProviderProperty."+name},
+     * where {@code name} is the provider name, to see if it's ok to remove this
+     * provider's properties.
+     *
+     * @throws  SecurityException
+     *          if a security manager exists and its {@link
+     *          java.lang.SecurityManager#checkSecurityAccess} method
+     *          denies access to remove this provider's properties.
+     *
+     * @since 1.2
+     */
+    @Override
+    public synchronized Object remove(Object key) {
+        check("removeProviderProperty."+name);
+        if (debug != null) {
+            debug.println("Remove " + name + " provider property " + key);
+        }
+        return implRemove(key);
+    }
+
+    /**
+     * Removes the entry for the specified key only if it is currently
+     * mapped to the specified value.
+     *
+     * <p>If a security manager is enabled, its {@code checkSecurityAccess}
+     * method is called with the string {@code "removeProviderProperty."+name},
+     * where {@code name} is the provider name, to see if it's ok to remove this
+     * provider's properties.
+     *
+     * @throws  SecurityException
+     *          if a security manager exists and its {@link
+     *          java.lang.SecurityManager#checkSecurityAccess} method
+     *          denies access to remove this provider's properties.
+     *
+     * @since 1.8
+     */
+    @Override
+    public synchronized boolean remove(Object key, Object value) {
+        check("removeProviderProperty."+name);
+        if (debug != null) {
+            debug.println("Remove " + name + " provider property " + key);
+        }
+        return implRemove(key, value);
+    }
+
+    /**
+     * Replaces the entry for the specified key only if currently
+     * mapped to the specified value.
+     *
+     * <p>If a security manager is enabled, its {@code checkSecurityAccess}
+     * method is called with the string {@code "putProviderProperty."+name},
+     * where {@code name} is the provider name, to see if it's ok to set this
+     * provider's property values.
+     *
+     * @throws  SecurityException
+     *          if a security manager exists and its {@link
+     *          java.lang.SecurityManager#checkSecurityAccess} method
+     *          denies access to set property values.
+     *
+     * @since 1.8
+     */
+    @Override
+    public synchronized boolean replace(Object key, Object oldValue,
+            Object newValue) {
+        check("putProviderProperty." + name);
+
+        if (debug != null) {
+            debug.println("Replace " + name + " provider property " + key);
+        }
+        return implReplace(key, oldValue, newValue);
+    }
+
+    /**
+     * Replaces the entry for the specified key only if it is
+     * currently mapped to some value.
+     *
+     * <p>If a security manager is enabled, its {@code checkSecurityAccess}
+     * method is called with the string {@code "putProviderProperty."+name},
+     * where {@code name} is the provider name, to see if it's ok to set this
+     * provider's property values.
+     *
+     * @throws  SecurityException
+     *          if a security manager exists and its {@link
+     *          java.lang.SecurityManager#checkSecurityAccess} method
+     *          denies access to set property values.
+     *
+     * @since 1.8
+     */
+    @Override
+    public synchronized Object replace(Object key, Object value) {
+        check("putProviderProperty." + name);
+
+        if (debug != null) {
+            debug.println("Replace " + name + " provider property " + key);
+        }
+        return implReplace(key, value);
+    }
+
+    /**
+     * Replaces each entry's value with the result of invoking the given
+     * function on that entry, in the order entries are returned by an entry
+     * set iterator, until all entries have been processed or the function
+     * throws an exception.
+     *
+     * <p>If a security manager is enabled, its {@code checkSecurityAccess}
+     * method is called with the string {@code "putProviderProperty."+name},
+     * where {@code name} is the provider name, to see if it's ok to set this
+     * provider's property values.
+     *
+     * @throws  SecurityException
+     *          if a security manager exists and its {@link
+     *          java.lang.SecurityManager#checkSecurityAccess} method
+     *          denies access to set property values.
+     *
+     * @since 1.8
+     */
+    @Override
+    public synchronized void replaceAll(BiFunction<? super Object, ? super Object, ? extends Object> function) {
+        check("putProviderProperty." + name);
+
+        if (debug != null) {
+            debug.println("ReplaceAll " + name + " provider property ");
+        }
+        implReplaceAll(function);
+    }
+
+    /**
+     * Attempts to compute a mapping for the specified key and its
+     * current mapped value (or {@code null} if there is no current
+     * mapping).
+     *
+     * <p>If a security manager is enabled, its {@code checkSecurityAccess}
+     * method is called with the strings {@code "putProviderProperty."+name}
+     * and {@code "removeProviderProperty."+name}, where {@code name} is the
+     * provider name, to see if it's ok to set this provider's property values
+     * and remove this provider's properties.
+     *
+     * @throws  SecurityException
+     *          if a security manager exists and its {@link
+     *          java.lang.SecurityManager#checkSecurityAccess} method
+     *          denies access to set property values or remove properties.
+     *
+     * @since 1.8
+     */
+    @Override
+    public synchronized Object compute(Object key,
+        BiFunction<? super Object, ? super Object, ? extends Object> remappingFunction) {
+        check("putProviderProperty." + name);
+        check("removeProviderProperty" + name);
+
+        if (debug != null) {
+            debug.println("Compute " + name + " provider property " + key);
+        }
+        return implCompute(key, remappingFunction);
+    }
+
+    /**
+     * If the specified key is not already associated with a value (or
+     * is mapped to {@code null}), attempts to compute its value using
+     * the given mapping function and enters it into this map unless
+     * {@code null}.
+     *
+     * <p>If a security manager is enabled, its {@code checkSecurityAccess}
+     * method is called with the strings {@code "putProviderProperty."+name}
+     * and {@code "removeProviderProperty."+name}, where {@code name} is the
+     * provider name, to see if it's ok to set this provider's property values
+     * and remove this provider's properties.
+     *
+     * @throws  SecurityException
+     *          if a security manager exists and its {@link
+     *          java.lang.SecurityManager#checkSecurityAccess} method
+     *          denies access to set property values and remove properties.
+     *
+     * @since 1.8
+     */
+    @Override
+    public synchronized Object computeIfAbsent(Object key, Function<? super Object, ? extends Object> mappingFunction) {
+        check("putProviderProperty." + name);
+        check("removeProviderProperty" + name);
+
+        if (debug != null) {
+            debug.println("ComputeIfAbsent " + name + " provider property " +
+                    key);
+        }
+        return implComputeIfAbsent(key, mappingFunction);
+    }
+
+    /**
+     * If the value for the specified key is present and non-null, attempts to
+     * compute a new mapping given the key and its current mapped value.
+     *
+     * <p>If a security manager is enabled, its {@code checkSecurityAccess}
+     * method is called with the strings {@code "putProviderProperty."+name}
+     * and {@code "removeProviderProperty."+name}, where {@code name} is the
+     * provider name, to see if it's ok to set this provider's property values
+     * and remove this provider's properties.
+     *
+     * @throws  SecurityException
+     *          if a security manager exists and its {@link
+     *          java.lang.SecurityManager#checkSecurityAccess} method
+     *          denies access to set property values or remove properties.
+     *
+     * @since 1.8
+     */
+    @Override
+    public synchronized Object computeIfPresent(Object key, BiFunction<? super Object, ? super Object, ? extends Object> remappingFunction) {
+        check("putProviderProperty." + name);
+        check("removeProviderProperty" + name);
+
+        if (debug != null) {
+            debug.println("ComputeIfPresent " + name + " provider property " +
+                    key);
+        }
+        return implComputeIfPresent(key, remappingFunction);
+    }
+
+    /**
+     * If the specified key is not already associated with a value or is
+     * associated with null, associates it with the given value. Otherwise,
+     * replaces the value with the results of the given remapping function,
+     * or removes if the result is null. This method may be of use when
+     * combining multiple mapped values for a key.
+     *
+     * <p>If a security manager is enabled, its {@code checkSecurityAccess}
+     * method is called with the strings {@code "putProviderProperty."+name}
+     * and {@code "removeProviderProperty."+name}, where {@code name} is the
+     * provider name, to see if it's ok to set this provider's property values
+     * and remove this provider's properties.
+     *
+     * @throws  SecurityException
+     *          if a security manager exists and its {@link
+     *          java.lang.SecurityManager#checkSecurityAccess} method
+     *          denies access to set property values or remove properties.
+     *
+     * @since 1.8
+     */
+    @Override
+    public synchronized Object merge(Object key, Object value,  BiFunction<? super Object, ? super Object, ? extends Object>  remappingFunction) {
+        check("putProviderProperty." + name);
+        check("removeProviderProperty" + name);
+
+        if (debug != null) {
+            debug.println("Merge " + name + " provider property " + key);
+        }
+        return implMerge(key, value, remappingFunction);
+    }
+
+    // let javadoc show doc from superclass
+    @Override
+    public Object get(Object key) {
+        checkInitialized();
+        return super.get(key);
+    }
+    /**
+     * @since 1.8
+     */
+    @Override
+    public synchronized Object getOrDefault(Object key, Object defaultValue) {
+        checkInitialized();
+        return super.getOrDefault(key, defaultValue);
+    }
+
+    /**
+     * @since 1.8
+     */
+    @Override
+    public synchronized void forEach(BiConsumer<? super Object, ? super Object> action) {
+        checkInitialized();
+        super.forEach(action);
+    }
+
+    // let javadoc show doc from superclass
+    @Override
+    public Enumeration<Object> keys() {
+        checkInitialized();
+        return super.keys();
+    }
+
+    // let javadoc show doc from superclass
+    @Override
+    public Enumeration<Object> elements() {
+        checkInitialized();
+        return super.elements();
+    }
+
+    // let javadoc show doc from superclass
+    public String getProperty(String key) {
+        checkInitialized();
+        return super.getProperty(key);
+    }
+
+    private void checkInitialized() {
+        if (!initialized) {
+            throw new IllegalStateException();
+        }
+    }
+
+    private void check(String directive) {
+        checkInitialized();
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkSecurityAccess(directive);
+        }
+    }
+
+    // legacy properties changed since last call to any services method?
+    private transient boolean legacyChanged;
+    // serviceMap changed since last call to getServices()
+    private transient boolean servicesChanged;
+
+    // Map<String,String>
+    private transient Map<String,String> legacyStrings;
+
+    // Map<ServiceKey,Service>
+    // used for services added via putService(), initialized on demand
+    private transient Map<ServiceKey,Service> serviceMap;
+
+    // Map<ServiceKey,Service>
+    // used for services added via legacy methods, init on demand
+    private transient Map<ServiceKey,Service> legacyMap;
+
+    // Set<Service>
+    // Unmodifiable set of all services. Initialized on demand.
+    private transient Set<Service> serviceSet;
+
+    // register the id attributes for this provider
+    // this is to ensure that equals() and hashCode() do not incorrectly
+    // report to different provider objects as the same
+    private void putId() {
+        // note: name and info may be null
+        super.put("Provider.id name", String.valueOf(name));
+        super.put("Provider.id version", String.valueOf(version));
+        super.put("Provider.id info", String.valueOf(info));
+        super.put("Provider.id className", this.getClass().getName());
+    }
+
+    private void readObject(ObjectInputStream in)
+                throws IOException, ClassNotFoundException {
+        // Android-added: Provider registration
+        registered = false;
+        Map<Object,Object> copy = new HashMap<>();
+        for (Map.Entry<Object,Object> entry : super.entrySet()) {
+            copy.put(entry.getKey(), entry.getValue());
+        }
+        defaults = null;
+        in.defaultReadObject();
+        implClear();
+        initialized = true;
+        putAll(copy);
+    }
+
+    private boolean checkLegacy(Object key) {
+        // Android-added: Provider registration
+        if (registered) {
+            Security.increaseVersion();
+        }
+        String keyString = (String)key;
+        if (keyString.startsWith("Provider.")) {
+            return false;
+        }
+
+        legacyChanged = true;
+        if (legacyStrings == null) {
+            legacyStrings = new LinkedHashMap<String,String>();
+        }
+        return true;
+    }
+
+    /**
+     * Copies all of the mappings from the specified Map to this provider.
+     * Internal method to be called AFTER the security check has been
+     * performed.
+     */
+    private void implPutAll(Map<?,?> t) {
+        for (Map.Entry<?,?> e : t.entrySet()) {
+            implPut(e.getKey(), e.getValue());
+        }
+        // Android-added: Provider registration
+        if (registered) {
+            Security.increaseVersion();
+        }
+    }
+
+    private Object implRemove(Object key) {
+        if (key instanceof String) {
+            if (!checkLegacy(key)) {
+                return null;
+            }
+            legacyStrings.remove((String)key);
+        }
+        return super.remove(key);
+    }
+
+    private boolean implRemove(Object key, Object value) {
+        if (key instanceof String && value instanceof String) {
+            if (!checkLegacy(key)) {
+                return false;
+            }
+            legacyStrings.remove((String)key, value);
+        }
+        return super.remove(key, value);
+    }
+
+    private boolean implReplace(Object key, Object oldValue, Object newValue) {
+        if ((key instanceof String) && (oldValue instanceof String) &&
+                (newValue instanceof String)) {
+            if (!checkLegacy(key)) {
+                return false;
+            }
+            legacyStrings.replace((String)key, (String)oldValue,
+                    (String)newValue);
+        }
+        return super.replace(key, oldValue, newValue);
+    }
+
+    private Object implReplace(Object key, Object value) {
+        if ((key instanceof String) && (value instanceof String)) {
+            if (!checkLegacy(key)) {
+                return null;
+            }
+            legacyStrings.replace((String)key, (String)value);
+        }
+        return super.replace(key, value);
+    }
+
+    private void implReplaceAll(BiFunction<? super Object, ? super Object, ? extends Object> function) {
+        legacyChanged = true;
+        if (legacyStrings == null) {
+            legacyStrings = new LinkedHashMap<String,String>();
+        } else {
+            legacyStrings.replaceAll((BiFunction<? super String, ? super String, ? extends String>) function);
+        }
+        super.replaceAll(function);
+    }
+
+
+    private Object implMerge(Object key, Object value, BiFunction<? super Object, ? super Object, ? extends Object> remappingFunction) {
+        if ((key instanceof String) && (value instanceof String)) {
+            if (!checkLegacy(key)) {
+                return null;
+            }
+            legacyStrings.merge((String)key, (String)value,
+                    (BiFunction<? super String, ? super String, ? extends String>) remappingFunction);
+        }
+        return super.merge(key, value, remappingFunction);
+    }
+
+    private Object implCompute(Object key, BiFunction<? super Object, ? super Object, ? extends Object> remappingFunction) {
+        if (key instanceof String) {
+            if (!checkLegacy(key)) {
+                return null;
+            }
+            // BEGIN Android-changed: was
+            // legacyStrings.computeIfAbsent((String) key,
+            //         (Function<? super String, ? extends String>) remappingFunction);
+            // which cannot ever succeed as the cast from BiFunction to Function always fails
+            legacyStrings.compute((String) key,
+                    (BiFunction<? super String, ? super String, ? extends String>)
+                            remappingFunction);
+            // END Android-changed
+        }
+        return super.compute(key, remappingFunction);
+    }
+
+    private Object implComputeIfAbsent(Object key, Function<? super Object, ? extends Object> mappingFunction) {
+        if (key instanceof String) {
+            if (!checkLegacy(key)) {
+                return null;
+            }
+            legacyStrings.computeIfAbsent((String) key,
+                    (Function<? super String, ? extends String>) mappingFunction);
+        }
+        return super.computeIfAbsent(key, mappingFunction);
+    }
+
+    private Object implComputeIfPresent(Object key, BiFunction<? super Object, ? super Object, ? extends Object> remappingFunction) {
+        if (key instanceof String) {
+            if (!checkLegacy(key)) {
+                return null;
+            }
+            legacyStrings.computeIfPresent((String) key,
+                    (BiFunction<? super String, ? super String, ? extends String>) remappingFunction);
+        }
+        return super.computeIfPresent(key, remappingFunction);
+    }
+
+    private Object implPut(Object key, Object value) {
+        if ((key instanceof String) && (value instanceof String)) {
+            if (!checkLegacy(key)) {
+                return null;
+            }
+            legacyStrings.put((String)key, (String)value);
+        }
+        return super.put(key, value);
+    }
+
+    private Object implPutIfAbsent(Object key, Object value) {
+        if ((key instanceof String) && (value instanceof String)) {
+            if (!checkLegacy(key)) {
+                return null;
+            }
+            legacyStrings.putIfAbsent((String)key, (String)value);
+        }
+        return super.putIfAbsent(key, value);
+    }
+
+    private void implClear() {
+        if (legacyStrings != null) {
+            legacyStrings.clear();
+        }
+        if (legacyMap != null) {
+            legacyMap.clear();
+        }
+        if (serviceMap != null) {
+            serviceMap.clear();
+        }
+        legacyChanged = false;
+        servicesChanged = false;
+        serviceSet = null;
+        super.clear();
+        putId();
+        // Android-added: Provider registration
+        if (registered) {
+          Security.increaseVersion();
+        }
+    }
+
+    // used as key in the serviceMap and legacyMap HashMaps
+    private static class ServiceKey {
+        private final String type;
+        private final String algorithm;
+        private final String originalAlgorithm;
+        private ServiceKey(String type, String algorithm, boolean intern) {
+            this.type = type;
+            this.originalAlgorithm = algorithm;
+            algorithm = algorithm.toUpperCase(ENGLISH);
+            this.algorithm = intern ? algorithm.intern() : algorithm;
+        }
+        public int hashCode() {
+            return type.hashCode() + algorithm.hashCode();
+        }
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj instanceof ServiceKey == false) {
+                return false;
+            }
+            ServiceKey other = (ServiceKey)obj;
+            return this.type.equals(other.type)
+                && this.algorithm.equals(other.algorithm);
+        }
+        boolean matches(String type, String algorithm) {
+            return (this.type == type) && (this.originalAlgorithm == algorithm);
+        }
+    }
+
+    /**
+     * Ensure all the legacy String properties are fully parsed into
+     * service objects.
+     */
+    private void ensureLegacyParsed() {
+        if ((legacyChanged == false) || (legacyStrings == null)) {
+            return;
+        }
+        serviceSet = null;
+        if (legacyMap == null) {
+            legacyMap = new LinkedHashMap<ServiceKey,Service>();
+        } else {
+            legacyMap.clear();
+        }
+        for (Map.Entry<String,String> entry : legacyStrings.entrySet()) {
+            parseLegacyPut(entry.getKey(), entry.getValue());
+        }
+        removeInvalidServices(legacyMap);
+        legacyChanged = false;
+    }
+
+    /**
+     * Remove all invalid services from the Map. Invalid services can only
+     * occur if the legacy properties are inconsistent or incomplete.
+     */
+    private void removeInvalidServices(Map<ServiceKey,Service> map) {
+        for (Iterator<Map.Entry<ServiceKey, Service>> t =
+                map.entrySet().iterator(); t.hasNext(); ) {
+            Service s = t.next().getValue();
+            if (s.isValid() == false) {
+                t.remove();
+            }
+        }
+    }
+
+    private String[] getTypeAndAlgorithm(String key) {
+        int i = key.indexOf(".");
+        if (i < 1) {
+            if (debug != null) {
+                debug.println("Ignoring invalid entry in provider "
+                        + name + ":" + key);
+            }
+            return null;
+        }
+        String type = key.substring(0, i);
+        String alg = key.substring(i + 1);
+        return new String[] {type, alg};
+    }
+
+    private final static String ALIAS_PREFIX = "Alg.Alias.";
+    private final static String ALIAS_PREFIX_LOWER = "alg.alias.";
+    private final static int ALIAS_LENGTH = ALIAS_PREFIX.length();
+
+    private void parseLegacyPut(String name, String value) {
+        if (name.toLowerCase(ENGLISH).startsWith(ALIAS_PREFIX_LOWER)) {
+            // e.g. put("Alg.Alias.MessageDigest.SHA", "SHA-1");
+            // aliasKey ~ MessageDigest.SHA
+            String stdAlg = value;
+            String aliasKey = name.substring(ALIAS_LENGTH);
+            String[] typeAndAlg = getTypeAndAlgorithm(aliasKey);
+            if (typeAndAlg == null) {
+                return;
+            }
+            String type = getEngineName(typeAndAlg[0]);
+            String aliasAlg = typeAndAlg[1].intern();
+            ServiceKey key = new ServiceKey(type, stdAlg, true);
+            Service s = legacyMap.get(key);
+            if (s == null) {
+                s = new Service(this);
+                s.type = type;
+                s.algorithm = stdAlg;
+                legacyMap.put(key, s);
+            }
+            legacyMap.put(new ServiceKey(type, aliasAlg, true), s);
+            s.addAlias(aliasAlg);
+        } else {
+            String[] typeAndAlg = getTypeAndAlgorithm(name);
+            if (typeAndAlg == null) {
+                return;
+            }
+            int i = typeAndAlg[1].indexOf(' ');
+            if (i == -1) {
+                // e.g. put("MessageDigest.SHA-1", "sun.security.provider.SHA");
+                String type = getEngineName(typeAndAlg[0]);
+                String stdAlg = typeAndAlg[1].intern();
+                String className = value;
+                ServiceKey key = new ServiceKey(type, stdAlg, true);
+                Service s = legacyMap.get(key);
+                if (s == null) {
+                    s = new Service(this);
+                    s.type = type;
+                    s.algorithm = stdAlg;
+                    legacyMap.put(key, s);
+                }
+                s.className = className;
+            } else { // attribute
+                // e.g. put("MessageDigest.SHA-1 ImplementedIn", "Software");
+                String attributeValue = value;
+                String type = getEngineName(typeAndAlg[0]);
+                String attributeString = typeAndAlg[1];
+                String stdAlg = attributeString.substring(0, i).intern();
+                String attributeName = attributeString.substring(i + 1);
+                // kill additional spaces
+                while (attributeName.startsWith(" ")) {
+                    attributeName = attributeName.substring(1);
+                }
+                attributeName = attributeName.intern();
+                ServiceKey key = new ServiceKey(type, stdAlg, true);
+                Service s = legacyMap.get(key);
+                if (s == null) {
+                    s = new Service(this);
+                    s.type = type;
+                    s.algorithm = stdAlg;
+                    legacyMap.put(key, s);
+                }
+                s.addAttribute(attributeName, attributeValue);
+            }
+        }
+    }
+
+    /**
+     * Get the service describing this Provider's implementation of the
+     * specified type of this algorithm or alias. If no such
+     * implementation exists, this method returns null. If there are two
+     * matching services, one added to this provider using
+     * {@link #putService putService()} and one added via {@link #put put()},
+     * the service added via {@link #putService putService()} is returned.
+     *
+     * @param type the type of {@link Service service} requested
+     * (for example, {@code MessageDigest})
+     * @param algorithm the case insensitive algorithm name (or alternate
+     * alias) of the service requested (for example, {@code SHA-1})
+     *
+     * @return the service describing this Provider's matching service
+     * or null if no such service exists
+     *
+     * @throws NullPointerException if type or algorithm is null
+     *
+     * @since 1.5
+     */
+    public synchronized Service getService(String type, String algorithm) {
+        checkInitialized();
+        // avoid allocating a new key object if possible
+        ServiceKey key = previousKey;
+        if (key.matches(type, algorithm) == false) {
+            key = new ServiceKey(type, algorithm, false);
+            previousKey = key;
+        }
+        if (serviceMap != null) {
+            Service service = serviceMap.get(key);
+            if (service != null) {
+                return service;
+            }
+        }
+        ensureLegacyParsed();
+        return (legacyMap != null) ? legacyMap.get(key) : null;
+    }
+
+    // ServiceKey from previous getService() call
+    // by re-using it if possible we avoid allocating a new object
+    // and the toUpperCase() call.
+    // re-use will occur e.g. as the framework traverses the provider
+    // list and queries each provider with the same values until it finds
+    // a matching service
+    private static volatile ServiceKey previousKey =
+                                            new ServiceKey("", "", false);
+
+    /**
+     * Get an unmodifiable Set of all services supported by
+     * this Provider.
+     *
+     * @return an unmodifiable Set of all services supported by
+     * this Provider
+     *
+     * @since 1.5
+     */
+    public synchronized Set<Service> getServices() {
+        checkInitialized();
+        if (legacyChanged || servicesChanged) {
+            serviceSet = null;
+        }
+        if (serviceSet == null) {
+            ensureLegacyParsed();
+            Set<Service> set = new LinkedHashSet<>();
+            if (serviceMap != null) {
+                set.addAll(serviceMap.values());
+            }
+            if (legacyMap != null) {
+                set.addAll(legacyMap.values());
+            }
+            serviceSet = Collections.unmodifiableSet(set);
+            servicesChanged = false;
+        }
+        return serviceSet;
+    }
+
+    /**
+     * Add a service. If a service of the same type with the same algorithm
+     * name exists and it was added using {@link #putService putService()},
+     * it is replaced by the new service.
+     * This method also places information about this service
+     * in the provider's Hashtable values in the format described in the
+     * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/CryptoSpec.html">
+     * Java Cryptography Architecture API Specification &amp; Reference </a>.
+     *
+     * <p>Also, if there is a security manager, its
+     * {@code checkSecurityAccess} method is called with the string
+     * {@code "putProviderProperty."+name}, where {@code name} is
+     * the provider name, to see if it's ok to set this provider's property
+     * values. If the default implementation of {@code checkSecurityAccess}
+     * is used (that is, that method is not overriden), then this results in
+     * a call to the security manager's {@code checkPermission} method with
+     * a {@code SecurityPermission("putProviderProperty."+name)}
+     * permission.
+     *
+     * @param s the Service to add
+     *
+     * @throws SecurityException
+     *      if a security manager exists and its {@link
+     *      java.lang.SecurityManager#checkSecurityAccess} method denies
+     *      access to set property values.
+     * @throws NullPointerException if s is null
+     *
+     * @since 1.5
+     */
+    protected synchronized void putService(Service s) {
+        check("putProviderProperty." + name);
+        if (debug != null) {
+            debug.println(name + ".putService(): " + s);
+        }
+        if (s == null) {
+            throw new NullPointerException();
+        }
+        if (s.getProvider() != this) {
+            throw new IllegalArgumentException
+                    ("service.getProvider() must match this Provider object");
+        }
+        if (serviceMap == null) {
+            serviceMap = new LinkedHashMap<ServiceKey,Service>();
+        }
+        servicesChanged = true;
+        String type = s.getType();
+        String algorithm = s.getAlgorithm();
+        ServiceKey key = new ServiceKey(type, algorithm, true);
+        // remove existing service
+        implRemoveService(serviceMap.get(key));
+        serviceMap.put(key, s);
+        for (String alias : s.getAliases()) {
+            serviceMap.put(new ServiceKey(type, alias, true), s);
+        }
+        putPropertyStrings(s);
+    }
+
+    /**
+     * Put the string properties for this Service in this Provider's
+     * Hashtable.
+     */
+    private void putPropertyStrings(Service s) {
+        String type = s.getType();
+        String algorithm = s.getAlgorithm();
+        // use super() to avoid permission check and other processing
+        super.put(type + "." + algorithm, s.getClassName());
+        for (String alias : s.getAliases()) {
+            super.put(ALIAS_PREFIX + type + "." + alias, algorithm);
+        }
+        for (Map.Entry<UString,String> entry : s.attributes.entrySet()) {
+            String key = type + "." + algorithm + " " + entry.getKey();
+            super.put(key, entry.getValue());
+        }
+        // Android-added: Provider registration
+        if (registered) {
+            Security.increaseVersion();
+        }
+    }
+
+    /**
+     * Remove the string properties for this Service from this Provider's
+     * Hashtable.
+     */
+    private void removePropertyStrings(Service s) {
+        String type = s.getType();
+        String algorithm = s.getAlgorithm();
+        // use super() to avoid permission check and other processing
+        super.remove(type + "." + algorithm);
+        for (String alias : s.getAliases()) {
+            super.remove(ALIAS_PREFIX + type + "." + alias);
+        }
+        for (Map.Entry<UString,String> entry : s.attributes.entrySet()) {
+            String key = type + "." + algorithm + " " + entry.getKey();
+            super.remove(key);
+        }
+        // Android-added: Provider registration
+        if (registered) {
+          Security.increaseVersion();
+        }
+    }
+
+    /**
+     * Remove a service previously added using
+     * {@link #putService putService()}. The specified service is removed from
+     * this provider. It will no longer be returned by
+     * {@link #getService getService()} and its information will be removed
+     * from this provider's Hashtable.
+     *
+     * <p>Also, if there is a security manager, its
+     * {@code checkSecurityAccess} method is called with the string
+     * {@code "removeProviderProperty."+name}, where {@code name} is
+     * the provider name, to see if it's ok to remove this provider's
+     * properties. If the default implementation of
+     * {@code checkSecurityAccess} is used (that is, that method is not
+     * overriden), then this results in a call to the security manager's
+     * {@code checkPermission} method with a
+     * {@code SecurityPermission("removeProviderProperty."+name)}
+     * permission.
+     *
+     * @param s the Service to be removed
+     *
+     * @throws  SecurityException
+     *          if a security manager exists and its {@link
+     *          java.lang.SecurityManager#checkSecurityAccess} method denies
+     *          access to remove this provider's properties.
+     * @throws NullPointerException if s is null
+     *
+     * @since 1.5
+     */
+    protected synchronized void removeService(Service s) {
+        check("removeProviderProperty." + name);
+        if (debug != null) {
+            debug.println(name + ".removeService(): " + s);
+        }
+        if (s == null) {
+            throw new NullPointerException();
+        }
+        implRemoveService(s);
+    }
+
+    private void implRemoveService(Service s) {
+        if ((s == null) || (serviceMap == null)) {
+            return;
+        }
+        String type = s.getType();
+        String algorithm = s.getAlgorithm();
+        ServiceKey key = new ServiceKey(type, algorithm, false);
+        Service oldService = serviceMap.get(key);
+        if (s != oldService) {
+            return;
+        }
+        servicesChanged = true;
+        serviceMap.remove(key);
+        for (String alias : s.getAliases()) {
+            serviceMap.remove(new ServiceKey(type, alias, false));
+        }
+        removePropertyStrings(s);
+    }
+
+    // Wrapped String that behaves in a case insensitive way for equals/hashCode
+    private static class UString {
+        final String string;
+        final String lowerString;
+
+        UString(String s) {
+            this.string = s;
+            this.lowerString = s.toLowerCase(ENGLISH);
+        }
+
+        public int hashCode() {
+            return lowerString.hashCode();
+        }
+
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj instanceof UString == false) {
+                return false;
+            }
+            UString other = (UString)obj;
+            return lowerString.equals(other.lowerString);
+        }
+
+        public String toString() {
+            return string;
+        }
+    }
+
+    // describe relevant properties of a type of engine
+    private static class EngineDescription {
+        final String name;
+        final boolean supportsParameter;
+        final String constructorParameterClassName;
+        private volatile Class<?> constructorParameterClass;
+
+        EngineDescription(String name, boolean sp, String paramName) {
+            this.name = name;
+            this.supportsParameter = sp;
+            this.constructorParameterClassName = paramName;
+        }
+        Class<?> getConstructorParameterClass() throws ClassNotFoundException {
+            Class<?> clazz = constructorParameterClass;
+            if (clazz == null) {
+                clazz = Class.forName(constructorParameterClassName);
+                constructorParameterClass = clazz;
+            }
+            return clazz;
+        }
+    }
+
+    // built in knowledge of the engine types shipped as part of the JDK
+    private static final Map<String,EngineDescription> knownEngines;
+
+    private static void addEngine(String name, boolean sp, String paramName) {
+        EngineDescription ed = new EngineDescription(name, sp, paramName);
+        // also index by canonical name to avoid toLowerCase() for some lookups
+        knownEngines.put(name.toLowerCase(ENGLISH), ed);
+        knownEngines.put(name, ed);
+    }
+
+    static {
+        knownEngines = new HashMap<String,EngineDescription>();
+        // JCA
+        addEngine("AlgorithmParameterGenerator",        false, null);
+        addEngine("AlgorithmParameters",                false, null);
+        addEngine("KeyFactory",                         false, null);
+        addEngine("KeyPairGenerator",                   false, null);
+        addEngine("KeyStore",                           false, null);
+        addEngine("MessageDigest",                      false, null);
+        addEngine("SecureRandom",                       false, null);
+        addEngine("Signature",                          true,  null);
+        addEngine("CertificateFactory",                 false, null);
+        addEngine("CertPathBuilder",                    false, null);
+        addEngine("CertPathValidator",                  false, null);
+        addEngine("CertStore",                          false,
+                            "java.security.cert.CertStoreParameters");
+        // JCE
+        addEngine("Cipher",                             true,  null);
+        addEngine("ExemptionMechanism",                 false, null);
+        addEngine("Mac",                                true,  null);
+        addEngine("KeyAgreement",                       true,  null);
+        addEngine("KeyGenerator",                       false, null);
+        addEngine("SecretKeyFactory",                   false, null);
+        // JSSE
+        addEngine("KeyManagerFactory",                  false, null);
+        addEngine("SSLContext",                         false, null);
+        addEngine("TrustManagerFactory",                false, null);
+        // JGSS
+        addEngine("GssApiMechanism",                    false, null);
+        // SASL
+        addEngine("SaslClientFactory",                  false, null);
+        addEngine("SaslServerFactory",                  false, null);
+        // POLICY
+        addEngine("Policy",                             false,
+                            "java.security.Policy$Parameters");
+        // CONFIGURATION
+        addEngine("Configuration",                      false,
+                            "javax.security.auth.login.Configuration$Parameters");
+        // XML DSig
+        addEngine("XMLSignatureFactory",                false, null);
+        addEngine("KeyInfoFactory",                     false, null);
+        addEngine("TransformService",                   false, null);
+        // Smart Card I/O
+        addEngine("TerminalFactory",                    false,
+                            "java.lang.Object");
+    }
+
+    // get the "standard" (mixed-case) engine name for arbitary case engine name
+    // if there is no known engine by that name, return s
+    private static String getEngineName(String s) {
+        // try original case first, usually correct
+        EngineDescription e = knownEngines.get(s);
+        if (e == null) {
+            e = knownEngines.get(s.toLowerCase(ENGLISH));
+        }
+        return (e == null) ? s : e.name;
+    }
+
+    /**
+     * The description of a security service. It encapsulates the properties
+     * of a service and contains a factory method to obtain new implementation
+     * instances of this service.
+     *
+     * <p>Each service has a provider that offers the service, a type,
+     * an algorithm name, and the name of the class that implements the
+     * service. Optionally, it also includes a list of alternate algorithm
+     * names for this service (aliases) and attributes, which are a map of
+     * (name, value) String pairs.
+     *
+     * <p>This class defines the methods {@link #supportsParameter
+     * supportsParameter()} and {@link #newInstance newInstance()}
+     * which are used by the Java security framework when it searches for
+     * suitable services and instantiates them. The valid arguments to those
+     * methods depend on the type of service. For the service types defined
+     * within Java SE, see the
+     * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/CryptoSpec.html">
+     * Java Cryptography Architecture API Specification &amp; Reference </a>
+     * for the valid values.
+     * Note that components outside of Java SE can define additional types of
+     * services and their behavior.
+     *
+     * <p>Instances of this class are immutable.
+     *
+     * @since 1.5
+     */
+    public static class Service {
+
+        private String type, algorithm, className;
+        private final Provider provider;
+        private List<String> aliases;
+        private Map<UString,String> attributes;
+
+        // Reference to the cached implementation Class object
+        private volatile Reference<Class<?>> classRef;
+
+        // flag indicating whether this service has its attributes for
+        // supportedKeyFormats or supportedKeyClasses set
+        // if null, the values have not been initialized
+        // if TRUE, at least one of supportedFormats/Classes is non null
+        private volatile Boolean hasKeyAttributes;
+
+        // supported encoding formats
+        private String[] supportedFormats;
+
+        // names of the supported key (super) classes
+        private Class[] supportedClasses;
+
+        // whether this service has been registered with the Provider
+        private boolean registered;
+
+        private static final Class<?>[] CLASS0 = new Class<?>[0];
+
+        // this constructor and these methods are used for parsing
+        // the legacy string properties.
+
+        private Service(Provider provider) {
+            this.provider = provider;
+            aliases = Collections.<String>emptyList();
+            attributes = Collections.<UString,String>emptyMap();
+        }
+
+        private boolean isValid() {
+            return (type != null) && (algorithm != null) && (className != null);
+        }
+
+        private void addAlias(String alias) {
+            if (aliases.isEmpty()) {
+                aliases = new ArrayList<String>(2);
+            }
+            aliases.add(alias);
+        }
+
+        void addAttribute(String type, String value) {
+            if (attributes.isEmpty()) {
+                attributes = new HashMap<UString,String>(8);
+            }
+            attributes.put(new UString(type), value);
+        }
+
+        /**
+         * Construct a new service.
+         *
+         * @param provider the provider that offers this service
+         * @param type the type of this service
+         * @param algorithm the algorithm name
+         * @param className the name of the class implementing this service
+         * @param aliases List of aliases or null if algorithm has no aliases
+         * @param attributes Map of attributes or null if this implementation
+         *                   has no attributes
+         *
+         * @throws NullPointerException if provider, type, algorithm, or
+         * className is null
+         */
+        public Service(Provider provider, String type, String algorithm,
+                String className, List<String> aliases,
+                Map<String,String> attributes) {
+            if ((provider == null) || (type == null) ||
+                    (algorithm == null) || (className == null)) {
+                throw new NullPointerException();
+            }
+            this.provider = provider;
+            this.type = getEngineName(type);
+            this.algorithm = algorithm;
+            this.className = className;
+            if (aliases == null) {
+                this.aliases = Collections.<String>emptyList();
+            } else {
+                this.aliases = new ArrayList<String>(aliases);
+            }
+            if (attributes == null) {
+                this.attributes = Collections.<UString,String>emptyMap();
+            } else {
+                this.attributes = new HashMap<UString,String>();
+                for (Map.Entry<String,String> entry : attributes.entrySet()) {
+                    this.attributes.put(new UString(entry.getKey()), entry.getValue());
+                }
+            }
+        }
+
+        /**
+         * Get the type of this service. For example, {@code MessageDigest}.
+         *
+         * @return the type of this service
+         */
+        public final String getType() {
+            return type;
+        }
+
+        /**
+         * Return the name of the algorithm of this service. For example,
+         * {@code SHA-1}.
+         *
+         * @return the algorithm of this service
+         */
+        public final String getAlgorithm() {
+            return algorithm;
+        }
+
+        /**
+         * Return the Provider of this service.
+         *
+         * @return the Provider of this service
+         */
+        public final Provider getProvider() {
+            return provider;
+        }
+
+        /**
+         * Return the name of the class implementing this service.
+         *
+         * @return the name of the class implementing this service
+         */
+        public final String getClassName() {
+            return className;
+        }
+
+        // internal only
+        private final List<String> getAliases() {
+            return aliases;
+        }
+
+        /**
+         * Return the value of the specified attribute or null if this
+         * attribute is not set for this Service.
+         *
+         * @param name the name of the requested attribute
+         *
+         * @return the value of the specified attribute or null if the
+         *         attribute is not present
+         *
+         * @throws NullPointerException if name is null
+         */
+        public final String getAttribute(String name) {
+            if (name == null) {
+                throw new NullPointerException();
+            }
+            return attributes.get(new UString(name));
+        }
+
+        /**
+         * Return a new instance of the implementation described by this
+         * service. The security provider framework uses this method to
+         * construct implementations. Applications will typically not need
+         * to call it.
+         *
+         * <p>The default implementation uses reflection to invoke the
+         * standard constructor for this type of service.
+         * Security providers can override this method to implement
+         * instantiation in a different way.
+         * For details and the values of constructorParameter that are
+         * valid for the various types of services see the
+         * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/CryptoSpec.html">
+         * Java Cryptography Architecture API Specification &amp;
+         * Reference</a>.
+         *
+         * @param constructorParameter the value to pass to the constructor,
+         * or null if this type of service does not use a constructorParameter.
+         *
+         * @return a new implementation of this service
+         *
+         * @throws InvalidParameterException if the value of
+         * constructorParameter is invalid for this type of service.
+         * @throws NoSuchAlgorithmException if instantiation failed for
+         * any other reason.
+         */
+        public Object newInstance(Object constructorParameter)
+                throws NoSuchAlgorithmException {
+            if (registered == false) {
+                if (provider.getService(type, algorithm) != this) {
+                    throw new NoSuchAlgorithmException
+                        ("Service not registered with Provider "
+                        + provider.getName() + ": " + this);
+                }
+                registered = true;
+            }
+            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) {
+                    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) {
+                            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);
+                }
+            } catch (NoSuchAlgorithmException e) {
+                throw e;
+            } catch (InvocationTargetException e) {
+                throw new NoSuchAlgorithmException
+                    ("Error constructing implementation (algorithm: "
+                    + algorithm + ", provider: " + provider.getName()
+                    + ", class: " + className + ")", e.getCause());
+            } catch (Exception e) {
+                throw new NoSuchAlgorithmException
+                    ("Error constructing implementation (algorithm: "
+                    + algorithm + ", provider: " + provider.getName()
+                    + ", class: " + className + ")", e);
+            }
+        }
+
+        // return the implementation Class object for this service
+        private Class<?> getImplClass() throws NoSuchAlgorithmException {
+            try {
+                Reference<Class<?>> ref = classRef;
+                Class<?> clazz = (ref == null) ? null : ref.get();
+                if (clazz == null) {
+                    ClassLoader cl = provider.getClass().getClassLoader();
+                    if (cl == null) {
+                        clazz = Class.forName(className);
+                    } else {
+                        clazz = cl.loadClass(className);
+                    }
+                    if (!Modifier.isPublic(clazz.getModifiers())) {
+                        throw new NoSuchAlgorithmException
+                            ("class configured for " + type + " (provider: " +
+                            provider.getName() + ") is not public.");
+                    }
+                    classRef = new WeakReference<Class<?>>(clazz);
+                }
+                return clazz;
+            } catch (ClassNotFoundException e) {
+                throw new NoSuchAlgorithmException
+                    ("class configured for " + type + " (provider: " +
+                    provider.getName() + ") cannot be found.", e);
+            }
+        }
+
+        /**
+         * 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
+         * infeasible, or if the status is unknown.
+         *
+         * <p>The security provider framework uses this method with
+         * some types of services to quickly exclude non-matching
+         * implementations for consideration.
+         * Applications will typically not need to call it.
+         *
+         * <p>For details and the values of parameter that are valid for the
+         * various types of services see the top of this class and the
+         * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/CryptoSpec.html">
+         * Java Cryptography Architecture API Specification &amp;
+         * Reference</a>.
+         * Security providers can override it to implement their own test.
+         *
+         * @param parameter the parameter to test
+         *
+         * @return false if this this service cannot use the specified
+         * parameter; true if it can possibly use the parameter
+         *
+         * @throws InvalidParameterException if the value of parameter is
+         * invalid for this type of service or if this method cannot be
+         * used with this type of service
+         */
+        public boolean supportsParameter(Object parameter) {
+            EngineDescription cap = knownEngines.get(type);
+            if (cap == null) {
+                // unknown engine type, return true by default
+                return true;
+            }
+            if (cap.supportsParameter == false) {
+                throw new InvalidParameterException("supportsParameter() not "
+                    + "used with " + type + " engines");
+            }
+            // allow null for keys without attributes for compatibility
+            if ((parameter != null) && (parameter instanceof Key == false)) {
+                throw new InvalidParameterException
+                    ("Parameter must be instanceof Key for engine " + type);
+            }
+            if (hasKeyAttributes() == false) {
+                return true;
+            }
+            if (parameter == null) {
+                return false;
+            }
+            Key key = (Key)parameter;
+            if (supportsKeyFormat(key)) {
+                return true;
+            }
+            if (supportsKeyClass(key)) {
+                return true;
+            }
+            return false;
+        }
+
+        /**
+         * Return whether this service has its Supported* properties for
+         * keys defined. Parses the attributes if not yet initialized.
+         */
+        private boolean hasKeyAttributes() {
+            Boolean b = hasKeyAttributes;
+            if (b == null) {
+                synchronized (this) {
+                    String s;
+                    s = getAttribute("SupportedKeyFormats");
+                    if (s != null) {
+                        supportedFormats = s.split("\\|");
+                    }
+                    s = getAttribute("SupportedKeyClasses");
+                    if (s != null) {
+                        String[] classNames = s.split("\\|");
+                        List<Class<?>> classList =
+                            new ArrayList<>(classNames.length);
+                        for (String className : classNames) {
+                            Class<?> clazz = getKeyClass(className);
+                            if (clazz != null) {
+                                classList.add(clazz);
+                            }
+                        }
+                        supportedClasses = classList.toArray(CLASS0);
+                    }
+                    boolean bool = (supportedFormats != null)
+                        || (supportedClasses != null);
+                    b = Boolean.valueOf(bool);
+                    hasKeyAttributes = b;
+                }
+            }
+            return b.booleanValue();
+        }
+
+        // get the key class object of the specified name
+        private Class<?> getKeyClass(String name) {
+            try {
+                return Class.forName(name);
+            } catch (ClassNotFoundException e) {
+                // ignore
+            }
+            try {
+                ClassLoader cl = provider.getClass().getClassLoader();
+                if (cl != null) {
+                    return cl.loadClass(name);
+                }
+            } catch (ClassNotFoundException e) {
+                // ignore
+            }
+            return null;
+        }
+
+        private boolean supportsKeyFormat(Key key) {
+            if (supportedFormats == null) {
+                return false;
+            }
+            String format = key.getFormat();
+            if (format == null) {
+                return false;
+            }
+            for (String supportedFormat : supportedFormats) {
+                if (supportedFormat.equals(format)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        private boolean supportsKeyClass(Key key) {
+            if (supportedClasses == null) {
+                return false;
+            }
+            Class<?> keyClass = key.getClass();
+            for (Class<?> clazz : supportedClasses) {
+                if (clazz.isAssignableFrom(keyClass)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        /**
+         * Return a String representation of this service.
+         *
+         * @return a String representation of this service.
+         */
+        public String toString() {
+            String aString = aliases.isEmpty()
+                ? "" : "\r\n  aliases: " + aliases.toString();
+            String attrs = attributes.isEmpty()
+                ? "" : "\r\n  attributes: " + attributes.toString();
+            return provider.getName() + ": " + type + "." + algorithm
+                + " -> " + className + aString + attrs + "\r\n";
+        }
+
+    }
+
+    // BEGIN Android-added: Provider registration
+    /**
+     * @hide
+     */
+    public void setRegistered() {
+        registered = true;
+    }
+
+    /**
+     * @hide
+     */
+    public void setUnregistered() {
+        registered = false;
+    }
+
+    /**
+     * @hide
+     */
+    public boolean isRegistered() {
+        return registered;
+    }
+
+    /**
+     * Ensure the values cached by {@link #getServices} and {@link #getService} are already computed
+     *
+     * Used by the zygote so that initialization is performed during preload for the providers
+     * available at that point.
+     *
+     * @hide
+     */
+    public synchronized void warmUpServiceProvision() {
+        checkInitialized();
+        // Further calls do nothing if the services didn't change. If not called here, it would
+        // parse legacy strings the first time that a service is requested.
+        ensureLegacyParsed();
+        // This call to getServices will update fields so that further calls will just return a
+        // stored field, if the services didn't change in the meantime.
+        getServices();
+    }
+    // END Android-added: Provider registration
+}
diff --git a/java/security/ProviderException.java b/java/security/ProviderException.java
new file mode 100644
index 0000000..b372ee7
--- /dev/null
+++ b/java/security/ProviderException.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 1996, 2013, 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 java.security;
+
+/**
+ * A runtime exception for Provider exceptions (such as
+ * misconfiguration errors or unrecoverable internal errors),
+ * which may be subclassed by Providers to
+ * throw specialized, provider-specific runtime errors.
+ *
+ * @author Benjamin Renaud
+ */
+public class ProviderException extends RuntimeException {
+
+    private static final long serialVersionUID = 5256023526693665674L;
+
+    /**
+     * Constructs a ProviderException with no detail message. A
+     * detail message is a String that describes this particular
+     * exception.
+     */
+    public ProviderException() {
+        super();
+    }
+
+    /**
+     * Constructs a ProviderException with the specified detail
+     * message. A detail message is a String that describes this
+     * particular exception.
+     *
+     * @param s the detail message.
+     */
+    public ProviderException(String s) {
+        super(s);
+    }
+
+    /**
+     * Creates a {@code ProviderException} with the specified
+     * detail message and cause.
+     *
+     * @param message the detail message (which is saved for later retrieval
+     *        by the {@link #getMessage()} method).
+     * @param cause the cause (which is saved for later retrieval by the
+     *        {@link #getCause()} method).  (A {@code null} value is permitted,
+     *        and indicates that the cause is nonexistent or unknown.)
+     * @since 1.5
+     */
+    public ProviderException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Creates a {@code ProviderException} with the specified cause
+     * and a detail message of {@code (cause==null ? null : cause.toString())}
+     * (which typically contains the class and detail message of
+     * {@code cause}).
+     *
+     * @param cause the cause (which is saved for later retrieval by the
+     *        {@link #getCause()} method).  (A {@code null} value is permitted,
+     *        and indicates that the cause is nonexistent or unknown.)
+     * @since 1.5
+     */
+    public ProviderException(Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/java/security/PublicKey.java b/java/security/PublicKey.java
new file mode 100644
index 0000000..df49807
--- /dev/null
+++ b/java/security/PublicKey.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1996, 2013, 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 java.security;
+
+/**
+ * <p>A public key. This interface contains no methods or constants.
+ * It merely serves to group (and provide type safety for) all public key
+ * interfaces.
+ *
+ * Note: The specialized public key interfaces extend this interface.
+ * See, for example, the DSAPublicKey interface in
+ * {@code java.security.interfaces}.
+ *
+ * @see Key
+ * @see PrivateKey
+ * @see Certificate
+ * @see Signature#initVerify
+ * @see java.security.interfaces.DSAPublicKey
+ * @see java.security.interfaces.RSAPublicKey
+ *
+ */
+
+public interface PublicKey extends Key {
+    // Declare serialVersionUID to be compatible with JDK1.1
+    /**
+     * The class fingerprint that is set to indicate serialization
+     * compatibility with a previous version of the class.
+     */
+    static final long serialVersionUID = 7187392471159151072L;
+}
diff --git a/java/security/SecureClassLoader.java b/java/security/SecureClassLoader.java
new file mode 100644
index 0000000..145f4fc
--- /dev/null
+++ b/java/security/SecureClassLoader.java
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security;
+
+import java.util.HashMap;
+import java.util.ArrayList;
+import java.net.URL;
+
+import sun.security.util.Debug;
+
+/**
+ * This class extends ClassLoader with additional support for defining
+ * classes with an associated code source and permissions which are
+ * retrieved by the system policy by default.
+ *
+ * @author  Li Gong
+ * @author  Roland Schemers
+ */
+public class SecureClassLoader extends ClassLoader {
+    /*
+     * If initialization succeed this is set to true and security checks will
+     * succeed. Otherwise the object is not initialized and the object is
+     * useless.
+     */
+    private final boolean initialized;
+
+    // HashMap that maps CodeSource to ProtectionDomain
+    // @GuardedBy("pdcache")
+    private final HashMap<CodeSource, ProtectionDomain> pdcache =
+                        new HashMap<>(11);
+
+    private static final Debug debug = Debug.getInstance("scl");
+
+    static {
+        ClassLoader.registerAsParallelCapable();
+    }
+
+    /**
+     * Creates a new SecureClassLoader using the specified parent
+     * class loader for delegation.
+     *
+     * <p>If there is a security manager, this method first
+     * calls the security manager's {@code checkCreateClassLoader}
+     * method  to ensure creation of a class loader is allowed.
+     * <p>
+     * @param parent the parent ClassLoader
+     * @exception  SecurityException  if a security manager exists and its
+     *             {@code checkCreateClassLoader} method doesn't allow
+     *             creation of a class loader.
+     * @see SecurityManager#checkCreateClassLoader
+     */
+    protected SecureClassLoader(ClassLoader parent) {
+        super(parent);
+        // this is to make the stack depth consistent with 1.1
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkCreateClassLoader();
+        }
+        initialized = true;
+    }
+
+    /**
+     * Creates a new SecureClassLoader using the default parent class
+     * loader for delegation.
+     *
+     * <p>If there is a security manager, this method first
+     * calls the security manager's {@code checkCreateClassLoader}
+     * method  to ensure creation of a class loader is allowed.
+     *
+     * @exception  SecurityException  if a security manager exists and its
+     *             {@code checkCreateClassLoader} method doesn't allow
+     *             creation of a class loader.
+     * @see SecurityManager#checkCreateClassLoader
+     */
+    protected SecureClassLoader() {
+        super();
+        // this is to make the stack depth consistent with 1.1
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkCreateClassLoader();
+        }
+        initialized = true;
+    }
+
+    /**
+     * Converts an array of bytes into an instance of class Class,
+     * with an optional CodeSource. Before the
+     * class can be used it must be resolved.
+     * <p>
+     * If a non-null CodeSource is supplied a ProtectionDomain is
+     * constructed and associated with the class being defined.
+     * <p>
+     * @param      name the expected name of the class, or {@code null}
+     *                  if not known, using '.' and not '/' as the separator
+     *                  and without a trailing ".class" suffix.
+     * @param      b    the bytes that make up the class data. The bytes in
+     *             positions {@code off} through {@code off+len-1}
+     *             should have the format of a valid class file as defined by
+     *             <cite>The Java&trade; Virtual Machine Specification</cite>.
+     * @param      off  the start offset in {@code b} of the class data
+     * @param      len  the length of the class data
+     * @param      cs   the associated CodeSource, or {@code null} if none
+     * @return the {@code Class} object created from the data,
+     *         and optional CodeSource.
+     * @exception  ClassFormatError if the data did not contain a valid class
+     * @exception  IndexOutOfBoundsException if either {@code off} or
+     *             {@code len} is negative, or if
+     *             {@code off+len} is greater than {@code b.length}.
+     *
+     * @exception  SecurityException if an attempt is made to add this class
+     *             to a package that contains classes that were signed by
+     *             a different set of certificates than this class, or if
+     *             the class name begins with "java.".
+     */
+    protected final Class<?> defineClass(String name,
+                                         byte[] b, int off, int len,
+                                         CodeSource cs)
+    {
+        return defineClass(name, b, off, len, getProtectionDomain(cs));
+    }
+
+    /**
+     * Converts a {@link java.nio.ByteBuffer ByteBuffer}
+     * into an instance of class {@code Class}, with an optional CodeSource.
+     * Before the class can be used it must be resolved.
+     * <p>
+     * If a non-null CodeSource is supplied a ProtectionDomain is
+     * constructed and associated with the class being defined.
+     * <p>
+     * @param      name the expected name of the class, or {@code null}
+     *                  if not known, using '.' and not '/' as the separator
+     *                  and without a trailing ".class" suffix.
+     * @param      b    the bytes that make up the class data.  The bytes from positions
+     *                  {@code b.position()} through {@code b.position() + b.limit() -1}
+     *                  should have the format of a valid class file as defined by
+     *                  <cite>The Java&trade; Virtual Machine Specification</cite>.
+     * @param      cs   the associated CodeSource, or {@code null} if none
+     * @return the {@code Class} object created from the data,
+     *         and optional CodeSource.
+     * @exception  ClassFormatError if the data did not contain a valid class
+     * @exception  SecurityException if an attempt is made to add this class
+     *             to a package that contains classes that were signed by
+     *             a different set of certificates than this class, or if
+     *             the class name begins with "java.".
+     *
+     * @since  1.5
+     */
+    protected final Class<?> defineClass(String name, java.nio.ByteBuffer b,
+                                         CodeSource cs)
+    {
+        return defineClass(name, b, getProtectionDomain(cs));
+    }
+
+    /**
+     * Returns the permissions for the given CodeSource object.
+     * <p>
+     * This method is invoked by the defineClass method which takes
+     * a CodeSource as an argument when it is constructing the
+     * ProtectionDomain for the class being defined.
+     * <p>
+     * @param codesource the codesource.
+     *
+     * @return the permissions granted to the codesource.
+     *
+     */
+    protected PermissionCollection getPermissions(CodeSource codesource)
+    {
+        check();
+        return new Permissions(); // ProtectionDomain defers the binding
+    }
+
+    /*
+     * Returned cached ProtectionDomain for the specified CodeSource.
+     */
+    private ProtectionDomain getProtectionDomain(CodeSource cs) {
+        if (cs == null)
+            return null;
+
+        ProtectionDomain pd = null;
+        synchronized (pdcache) {
+            pd = pdcache.get(cs);
+            if (pd == null) {
+                PermissionCollection perms = getPermissions(cs);
+                pd = new ProtectionDomain(cs, perms, this, null);
+                pdcache.put(cs, pd);
+                if (debug != null) {
+                    debug.println(" getPermissions "+ pd);
+                    debug.println("");
+                }
+            }
+        }
+        return pd;
+    }
+
+    /*
+     * Check to make sure the class loader has been initialized.
+     */
+    private void check() {
+        if (!initialized) {
+            throw new SecurityException("ClassLoader object not initialized");
+        }
+    }
+
+}
diff --git a/java/security/SecureRandom.java b/java/security/SecureRandom.java
new file mode 100644
index 0000000..0852cbd
--- /dev/null
+++ b/java/security/SecureRandom.java
@@ -0,0 +1,777 @@
+/*
+ * Copyright (c) 1996, 2013, 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 java.security;
+
+import java.util.*;
+import java.util.regex.*;
+
+import java.security.Provider.Service;
+import java.util.function.Function;
+
+import dalvik.system.VMRuntime;
+import sun.security.jca.*;
+import sun.security.jca.GetInstance.Instance;
+
+/**
+ * This class provides a cryptographically strong random number
+ * generator (RNG).
+ *
+ * <p>A cryptographically strong random number
+ * minimally complies with the statistical random number generator tests
+ * specified in <a href="http://csrc.nist.gov/cryptval/140-2.htm">
+ * <i>FIPS 140-2, Security Requirements for Cryptographic Modules</i></a>,
+ * section 4.9.1.
+ * Additionally, SecureRandom must produce non-deterministic output.
+ * Therefore any seed material passed to a SecureRandom object must be
+ * unpredictable, and all SecureRandom output sequences must be
+ * cryptographically strong, as described in
+ * <a href="http://www.ietf.org/rfc/rfc1750.txt">
+ * <i>RFC 1750: Randomness Recommendations for Security</i></a>.
+ *
+ * <p>A caller obtains a SecureRandom instance via the
+ * no-argument constructor or one of the {@code getInstance} methods:
+ *
+ * <pre>
+ *      SecureRandom random = new SecureRandom();
+ * </pre>
+ *
+ * <p> Many SecureRandom implementations are in the form of a pseudo-random
+ * number generator (PRNG), which means they use a deterministic algorithm
+ * to produce a pseudo-random sequence from a true random seed.
+ * Other implementations may produce true random numbers,
+ * and yet others may use a combination of both techniques.
+ *
+ * <p> Typical callers of SecureRandom invoke the following methods
+ * to retrieve random bytes:
+ *
+ * <pre>
+ *      SecureRandom random = new SecureRandom();
+ *      byte bytes[] = new byte[20];
+ *      random.nextBytes(bytes);
+ * </pre>
+ *
+ * <p> Callers may also invoke the {@code generateSeed} method
+ * to generate a given number of seed bytes (to seed other random number
+ * generators, for example):
+ * <pre>
+ *      byte seed[] = random.generateSeed(20);
+ * </pre>
+ *
+ * Note: Depending on the implementation, the {@code generateSeed} and
+ * {@code nextBytes} methods may block as entropy is being gathered,
+ * for example, if they need to read from /dev/random on various Unix-like
+ * operating systems.
+ *
+ * The SHA1PRNG algorithm from the Crypto provider has been deprecated as it was insecure, and also
+ * incorrectly used by some apps as a key derivation function. See
+ * <a href="http://android-developers.blogspot.com/2016/06/security-crypto-provider-deprecated-in.html">
+ * Security &quot;Crypto&quot; provider deprecated in Android N</a> for details.
+ *
+ * @see java.security.SecureRandomSpi
+ * @see java.util.Random
+ *
+ * @author Benjamin Renaud
+ * @author Josh Bloch
+ */
+
+public class SecureRandom extends java.util.Random {
+
+    // Android-removed: this debugging mechanism is not used in Android.
+    /*
+    private static final Debug pdebug =
+                        Debug.getInstance("provider", "Provider");
+    private static final boolean skipDebug =
+        Debug.isOn("engine=") && !Debug.isOn("securerandom");
+    */
+    // END Android-removed
+
+    /**
+     * The provider.
+     *
+     * @serial
+     * @since 1.2
+     */
+    private Provider provider = null;
+
+    /**
+     * The provider implementation.
+     *
+     * @serial
+     * @since 1.2
+     */
+    private SecureRandomSpi secureRandomSpi = null;
+
+    /*
+     * The algorithm name of null if unknown.
+     *
+     * @serial
+     * @since 1.5
+     */
+    private String algorithm;
+
+    // Seed Generator
+    private static volatile SecureRandom seedGenerator = null;
+
+    /**
+     * Constructs a secure random number generator (RNG) implementing the
+     * default random number algorithm.
+     *
+     * <p> This constructor traverses the list of registered security Providers,
+     * starting with the most preferred Provider.
+     * A new SecureRandom object encapsulating the
+     * SecureRandomSpi implementation from the first
+     * Provider that supports a SecureRandom (RNG) algorithm is returned.
+     * If none of the Providers support a RNG algorithm,
+     * then an implementation-specific default is returned.
+     *
+     * <p> Note that the list of registered providers may be retrieved via
+     * the {@link Security#getProviders() Security.getProviders()} method.
+     *
+     * <p> See the SecureRandom section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#SecureRandom">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard RNG algorithm names.
+     *
+     * <p> The returned SecureRandom object has not been seeded.  To seed the
+     * returned object, call the {@code setSeed} method.
+     * If {@code setSeed} is not called, the first call to
+     * {@code nextBytes} will force the SecureRandom object to seed itself.
+     * This self-seeding will not occur if {@code setSeed} was
+     * previously called.
+     */
+    public SecureRandom() {
+        /*
+         * This call to our superclass constructor will result in a call
+         * to our own {@code setSeed} method, which will return
+         * immediately when it is passed zero.
+         */
+        super(0);
+        getDefaultPRNG(false, null);
+    }
+
+    /**
+     * Constructs a secure random number generator (RNG) implementing the
+     * default random number algorithm.
+     * The SecureRandom instance is seeded with the specified seed bytes.
+     *
+     * <p> This constructor traverses the list of registered security Providers,
+     * starting with the most preferred Provider.
+     * A new SecureRandom object encapsulating the
+     * SecureRandomSpi implementation from the first
+     * Provider that supports a SecureRandom (RNG) algorithm is returned.
+     * If none of the Providers support a RNG algorithm,
+     * then an implementation-specific default is returned.
+     *
+     * <p> Note that the list of registered providers may be retrieved via
+     * the {@link Security#getProviders() Security.getProviders()} method.
+     *
+     * <p> See the SecureRandom section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#SecureRandom">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard RNG algorithm names.
+     *
+     * @param seed the seed.
+     */
+    public SecureRandom(byte seed[]) {
+        super(0);
+        getDefaultPRNG(true, seed);
+    }
+
+    private void getDefaultPRNG(boolean setSeed, byte[] seed) {
+        String prng = getPrngAlgorithm();
+        if (prng == null) {
+            // Android-changed: This should never happen, we always provide a SecureRandom
+            throw new IllegalStateException("No SecureRandom implementation!");
+        } else {
+            try {
+                SecureRandom random = SecureRandom.getInstance(prng);
+                this.secureRandomSpi = random.getSecureRandomSpi();
+                this.provider = random.getProvider();
+                if (setSeed) {
+                    this.secureRandomSpi.engineSetSeed(seed);
+                }
+            } catch (NoSuchAlgorithmException nsae) {
+                // never happens, because we made sure the algorithm exists
+                throw new RuntimeException(nsae);
+            }
+        }
+        // JDK 1.1 based implementations subclass SecureRandom instead of
+        // SecureRandomSpi. They will also go through this code path because
+        // they must call a SecureRandom constructor as it is their superclass.
+        // If we are dealing with such an implementation, do not set the
+        // algorithm value as it would be inaccurate.
+        if (getClass() == SecureRandom.class) {
+            this.algorithm = prng;
+        }
+    }
+
+    /**
+     * Creates a SecureRandom object.
+     *
+     * @param secureRandomSpi the SecureRandom implementation.
+     * @param provider the provider.
+     */
+    protected SecureRandom(SecureRandomSpi secureRandomSpi,
+                           Provider provider) {
+        this(secureRandomSpi, provider, null);
+    }
+
+    private SecureRandom(SecureRandomSpi secureRandomSpi, Provider provider,
+            String algorithm) {
+        super(0);
+        this.secureRandomSpi = secureRandomSpi;
+        this.provider = provider;
+        this.algorithm = algorithm;
+
+        // BEGIN Android-removed: this debugging mechanism is not supported in Android.
+        /*
+        if (!skipDebug && pdebug != null) {
+            pdebug.println("SecureRandom." + algorithm +
+                " algorithm from: " + this.provider.getName());
+        }
+        */
+        // END Android-removed
+    }
+
+    /**
+     * Returns a SecureRandom object that implements the specified
+     * Random Number Generator (RNG) algorithm.
+     *
+     * <p> This method traverses the list of registered security Providers,
+     * starting with the most preferred Provider.
+     * A new SecureRandom object encapsulating the
+     * SecureRandomSpi implementation from the first
+     * Provider that supports the specified algorithm is returned.
+     *
+     * <p> Note that the list of registered providers may be retrieved via
+     * the {@link Security#getProviders() Security.getProviders()} method.
+     *
+     * <p> The returned SecureRandom object has not been seeded.  To seed the
+     * returned object, call the {@code setSeed} method.
+     * If {@code setSeed} is not called, the first call to
+     * {@code nextBytes} will force the SecureRandom object to seed itself.
+     * This self-seeding will not occur if {@code setSeed} was
+     * previously called.
+     *
+     * @param algorithm the name of the RNG algorithm.
+     * See the SecureRandom section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#SecureRandom">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard RNG algorithm names.
+     *
+     * @return the new SecureRandom object.
+     *
+     * @exception NoSuchAlgorithmException if no Provider supports a
+     *          SecureRandomSpi implementation for the
+     *          specified algorithm.
+     *
+     * @see Provider
+     *
+     * @since 1.2
+     */
+    public static SecureRandom getInstance(String algorithm)
+            throws NoSuchAlgorithmException {
+        Instance instance = GetInstance.getInstance("SecureRandom",
+            SecureRandomSpi.class, algorithm);
+        return new SecureRandom((SecureRandomSpi)instance.impl,
+            instance.provider, algorithm);
+    }
+
+    // BEGIN Android-added: Support for Crypto provider workaround
+    /**
+     * Maximum SDK version for which the workaround for the Crypto provider is in place.
+     *
+     * <p> We provide instances from the Crypto provider (although the provider is not installed) to
+     * apps targeting M or earlier versions of the SDK.
+     *
+     * <p> Default is 23 (M). We have it as a field for testability and it shouldn't be changed.
+     *
+     * @hide
+     */
+    public static final int DEFAULT_SDK_TARGET_FOR_CRYPTO_PROVIDER_WORKAROUND = 23;
+
+    private static int sdkTargetForCryptoProviderWorkaround =
+            DEFAULT_SDK_TARGET_FOR_CRYPTO_PROVIDER_WORKAROUND;
+
+    /**
+     * Only for testing.
+     *
+     * @hide
+     */
+    public static void setSdkTargetForCryptoProviderWorkaround(int sdkTargetVersion) {
+        sdkTargetForCryptoProviderWorkaround = sdkTargetVersion;
+    }
+
+    /**
+     * Only for testing.
+     *
+     * @hide
+     */
+    public static int getSdkTargetForCryptoProviderWorkaround() {
+        return sdkTargetForCryptoProviderWorkaround;
+    }
+    // END Android-added: Support for Crypto provider workaround
+
+    /**
+     * Returns a SecureRandom object that implements the specified
+     * Random Number Generator (RNG) algorithm.
+     *
+     * <p> A new SecureRandom object encapsulating the
+     * SecureRandomSpi implementation from the specified provider
+     * is returned.  The specified provider must be registered
+     * in the security provider list.
+     *
+     * <p> Note that the list of registered providers may be retrieved via
+     * the {@link Security#getProviders() Security.getProviders()} method.
+     *
+     * <p> The returned SecureRandom object has not been seeded.  To seed the
+     * returned object, call the {@code setSeed} method.
+     * If {@code setSeed} is not called, the first call to
+     * {@code nextBytes} will force the SecureRandom object to seed itself.
+     * This self-seeding will not occur if {@code setSeed} was
+     * previously called.
+     *
+     * @param algorithm the name of the RNG algorithm.
+     * See the SecureRandom section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#SecureRandom">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard RNG algorithm names.
+     *
+     * @param provider the name of the provider.
+     *
+     * @return the new SecureRandom object.
+     *
+     * @exception NoSuchAlgorithmException if a SecureRandomSpi
+     *          implementation for the specified algorithm is not
+     *          available from the specified provider.
+     *
+     * @exception NoSuchProviderException if the specified provider is not
+     *          registered in the security provider list.
+     *
+     * @exception IllegalArgumentException if the provider name is null
+     *          or empty.
+     *
+     * @see Provider
+     *
+     * @since 1.2
+     */
+    public static SecureRandom getInstance(String algorithm, String provider)
+            throws NoSuchAlgorithmException, NoSuchProviderException {
+        try {
+            Instance instance = GetInstance.getInstance("SecureRandom",
+                    SecureRandomSpi.class, algorithm, provider);
+            return new SecureRandom((SecureRandomSpi) instance.impl,
+                    instance.provider, algorithm);
+        // BEGIN Android-added: Crypto provider deprecation
+        } catch (NoSuchProviderException nspe) {
+            if ("Crypto".equals(provider)) {
+                System.logE(" ********** PLEASE READ ************ ");
+                System.logE(" * ");
+                System.logE(" * New versions of the Android SDK no longer support the Crypto provider.");
+                System.logE(" * If your app was relying on setSeed() to derive keys from strings, you");
+                System.logE(" * should switch to using SecretKeySpec to load raw key bytes directly OR");
+                System.logE(" * use a real key derivation function (KDF). See advice here : ");
+                System.logE(" * http://android-developers.blogspot.com/2016/06/security-crypto-provider-deprecated-in.html ");
+                System.logE(" *********************************** ");
+                if (VMRuntime.getRuntime().getTargetSdkVersion()
+                        <= sdkTargetForCryptoProviderWorkaround) {
+                    System.logE(" Returning an instance of SecureRandom from the Crypto provider");
+                    System.logE(" as a temporary measure so that the apps targeting earlier SDKs");
+                    System.logE(" keep working. Please do not rely on the presence of the Crypto");
+                    System.logE(" provider in the codebase, as our plan is to delete it");
+                    System.logE(" completely in the future.");
+                    return getInstanceFromCryptoProvider(algorithm);
+                }
+            }
+
+            throw nspe;
+        }
+    }
+
+    private static SecureRandom getInstanceFromCryptoProvider(String algorithm)
+            throws NoSuchAlgorithmException {
+        Provider cryptoProvider;
+        try {
+            cryptoProvider = (Provider) SecureRandom.class.getClassLoader()
+                    .loadClass(
+                            "org.apache.harmony.security.provider.crypto.CryptoProvider")
+                    .newInstance();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        Service service = cryptoProvider.getService("SecureRandom", algorithm);
+        Instance instance = GetInstance.getInstance(service, SecureRandomSpi.class);
+        return new SecureRandom(
+                (SecureRandomSpi) instance.impl, instance.provider, algorithm);
+    }
+    // END Android-added: Crypto provider deprecation
+
+    /**
+     * Returns a SecureRandom object that implements the specified
+     * Random Number Generator (RNG) algorithm.
+     *
+     * <p> A new SecureRandom object encapsulating the
+     * SecureRandomSpi implementation from the specified Provider
+     * object is returned.  Note that the specified Provider object
+     * does not have to be registered in the provider list.
+     *
+     * <p> The returned SecureRandom object has not been seeded.  To seed the
+     * returned object, call the {@code setSeed} method.
+     * If {@code setSeed} is not called, the first call to
+     * {@code nextBytes} will force the SecureRandom object to seed itself.
+     * This self-seeding will not occur if {@code setSeed} was
+     * previously called.
+     *
+     * @param algorithm the name of the RNG algorithm.
+     * See the SecureRandom section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#SecureRandom">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard RNG algorithm names.
+     *
+     * @param provider the provider.
+     *
+     * @return the new SecureRandom object.
+     *
+     * @exception NoSuchAlgorithmException if a SecureRandomSpi
+     *          implementation for the specified algorithm is not available
+     *          from the specified Provider object.
+     *
+     * @exception IllegalArgumentException if the specified provider is null.
+     *
+     * @see Provider
+     *
+     * @since 1.4
+     */
+    public static SecureRandom getInstance(String algorithm,
+            Provider provider) throws NoSuchAlgorithmException {
+        Instance instance = GetInstance.getInstance("SecureRandom",
+            SecureRandomSpi.class, algorithm, provider);
+        return new SecureRandom((SecureRandomSpi)instance.impl,
+            instance.provider, algorithm);
+    }
+
+    /**
+     * Returns the SecureRandomSpi of this SecureRandom object.
+     */
+    SecureRandomSpi getSecureRandomSpi() {
+        return secureRandomSpi;
+    }
+
+    /**
+     * Returns the provider of this SecureRandom object.
+     *
+     * @return the provider of this SecureRandom object.
+     */
+    public final Provider getProvider() {
+        return provider;
+    }
+
+    /**
+     * Returns the name of the algorithm implemented by this SecureRandom
+     * object.
+     *
+     * @return the name of the algorithm or {@code unknown}
+     *          if the algorithm name cannot be determined.
+     * @since 1.5
+     */
+    public String getAlgorithm() {
+        return (algorithm != null) ? algorithm : "unknown";
+    }
+
+    /**
+     * Reseeds this random object. The given seed supplements, rather than
+     * replaces, the existing seed. Thus, repeated calls are guaranteed
+     * never to reduce randomness.
+     *
+     * @param seed the seed.
+     *
+     * @see #getSeed
+     */
+    synchronized public void setSeed(byte[] seed) {
+        secureRandomSpi.engineSetSeed(seed);
+    }
+
+    /**
+     * Reseeds this random object, using the eight bytes contained
+     * in the given {@code long seed}. The given seed supplements,
+     * rather than replaces, the existing seed. Thus, repeated calls
+     * are guaranteed never to reduce randomness.
+     *
+     * <p>This method is defined for compatibility with
+     * {@code java.util.Random}.
+     *
+     * @param seed the seed.
+     *
+     * @see #getSeed
+     */
+    @Override
+    public void setSeed(long seed) {
+        /*
+         * Ignore call from super constructor (as well as any other calls
+         * unfortunate enough to be passing 0).  It's critical that we
+         * ignore call from superclass constructor, as digest has not
+         * yet been initialized at that point.
+         */
+        if (seed != 0) {
+            secureRandomSpi.engineSetSeed(longToByteArray(seed));
+        }
+    }
+
+    /**
+     * Generates a user-specified number of random bytes.
+     *
+     * <p> If a call to {@code setSeed} had not occurred previously,
+     * the first call to this method forces this SecureRandom object
+     * to seed itself.  This self-seeding will not occur if
+     * {@code setSeed} was previously called.
+     *
+     * @param bytes the array to be filled in with random bytes.
+     */
+    @Override
+    // Android-changed: Added synchronized
+    // This method has been synchronized at least since Cupcake, so it would probably
+    // lead to problems if it was removed.
+    synchronized public void nextBytes(byte[] bytes) {
+        secureRandomSpi.engineNextBytes(bytes);
+    }
+
+    /**
+     * Generates an integer containing the user-specified number of
+     * pseudo-random bits (right justified, with leading zeros).  This
+     * method overrides a {@code java.util.Random} method, and serves
+     * to provide a source of random bits to all of the methods inherited
+     * from that class (for example, {@code nextInt},
+     * {@code nextLong}, and {@code nextFloat}).
+     *
+     * @param numBits number of pseudo-random bits to be generated, where
+     * {@code 0 <= numBits <= 32}.
+     *
+     * @return an {@code int} containing the user-specified number
+     * of pseudo-random bits (right justified, with leading zeros).
+     */
+    @Override
+    final protected int next(int numBits) {
+        int numBytes = (numBits+7)/8;
+        byte b[] = new byte[numBytes];
+        int next = 0;
+
+        nextBytes(b);
+        for (int i = 0; i < numBytes; i++) {
+            next = (next << 8) + (b[i] & 0xFF);
+        }
+
+        return next >>> (numBytes*8 - numBits);
+    }
+
+    /**
+     * Returns the given number of seed bytes, computed using the seed
+     * generation algorithm that this class uses to seed itself.  This
+     * call may be used to seed other random number generators.
+     *
+     * <p>This method is only included for backwards compatibility.
+     * The caller is encouraged to use one of the alternative
+     * {@code getInstance} methods to obtain a SecureRandom object, and
+     * then call the {@code generateSeed} method to obtain seed bytes
+     * from that object.
+     *
+     * @param numBytes the number of seed bytes to generate.
+     *
+     * @return the seed bytes.
+     *
+     * @see #setSeed
+     */
+    public static byte[] getSeed(int numBytes) {
+        if (seedGenerator == null) {
+            seedGenerator = new SecureRandom();
+        }
+        return seedGenerator.generateSeed(numBytes);
+    }
+
+    /**
+     * Returns the given number of seed bytes, computed using the seed
+     * generation algorithm that this class uses to seed itself.  This
+     * call may be used to seed other random number generators.
+     *
+     * @param numBytes the number of seed bytes to generate.
+     *
+     * @return the seed bytes.
+     */
+    public byte[] generateSeed(int numBytes) {
+        return secureRandomSpi.engineGenerateSeed(numBytes);
+    }
+
+    /**
+     * Helper function to convert a long into a byte array (least significant
+     * byte first).
+     */
+    private static byte[] longToByteArray(long l) {
+        byte[] retVal = new byte[8];
+
+        for (int i = 0; i < 8; i++) {
+            retVal[i] = (byte) l;
+            l >>= 8;
+        }
+
+        return retVal;
+    }
+
+    /**
+     * Gets a default PRNG algorithm by looking through all registered
+     * providers. Returns the first PRNG algorithm of the first provider that
+     * has registered a SecureRandom implementation, or null if none of the
+     * registered providers supplies a SecureRandom implementation.
+     */
+    private static String getPrngAlgorithm() {
+        for (Provider p : Providers.getProviderList().providers()) {
+            for (Service s : p.getServices()) {
+                if (s.getType().equals("SecureRandom")) {
+                    return s.getAlgorithm();
+                }
+            }
+        }
+        return null;
+    }
+
+    /*
+     * Lazily initialize since Pattern.compile() is heavy.
+     * Effective Java (2nd Edition), Item 71.
+     */
+    private static final class StrongPatternHolder {
+        /*
+         * Entries are alg:prov separated by ,
+         * Allow for prepended/appended whitespace between entries.
+         *
+         * Capture groups:
+         *     1 - alg
+         *     2 - :prov (optional)
+         *     3 - prov (optional)
+         *     4 - ,nextEntry (optional)
+         *     5 - nextEntry (optional)
+         */
+        private static Pattern pattern =
+            Pattern.compile(
+                "\\s*([\\S&&[^:,]]*)(\\:([\\S&&[^,]]*))?\\s*(\\,(.*))?");
+    }
+
+    /**
+     * Returns a {@code SecureRandom} object.
+     *
+     * In Android this is equivalent to get a SHA1PRNG from OpenSSLProvider.
+     *
+     * Some situations require strong random values, such as when
+     * creating high-value/long-lived secrets like RSA public/private
+     * keys.  To help guide applications in selecting a suitable strong
+     * {@code SecureRandom} implementation, Java distributions
+     * include a list of known strong {@code SecureRandom}
+     * implementations in the {@code securerandom.strongAlgorithms}
+     * Security property.
+     * <p>
+     * Every implementation of the Java platform is required to
+     * support at least one strong {@code SecureRandom} implementation.
+     *
+     * @return a strong {@code SecureRandom} implementation
+     *
+     * @throws NoSuchAlgorithmException if no algorithm is available
+     *
+     * @see Security#getProperty(String)
+     *
+     * @since 1.8
+     */
+    public static SecureRandom getInstanceStrong()
+            throws NoSuchAlgorithmException {
+
+        String property = AccessController.doPrivileged(
+            new PrivilegedAction<String>() {
+                @Override
+                public String run() {
+                    return Security.getProperty(
+                        "securerandom.strongAlgorithms");
+                }
+            });
+
+        if ((property == null) || (property.length() == 0)) {
+            throw new NoSuchAlgorithmException(
+                "Null/empty securerandom.strongAlgorithms Security Property");
+        }
+
+        String remainder = property;
+        while (remainder != null) {
+            Matcher m;
+            if ((m = StrongPatternHolder.pattern.matcher(
+                    remainder)).matches()) {
+
+                String alg = m.group(1);
+                String prov = m.group(3);
+
+                try {
+                    if (prov == null) {
+                        return SecureRandom.getInstance(alg);
+                    } else {
+                        return SecureRandom.getInstance(alg, prov);
+                    }
+                } catch (NoSuchAlgorithmException |
+                        NoSuchProviderException e) {
+                }
+                remainder = m.group(5);
+            } else {
+                remainder = null;
+            }
+        }
+
+        throw new NoSuchAlgorithmException(
+            "No strong SecureRandom impls available: " + property);
+    }
+
+    // Declare serialVersionUID to be compatible with JDK1.1
+    static final long serialVersionUID = 4940670005562187L;
+
+    // Retain unused values serialized from JDK1.1
+    /**
+     * @serial
+     */
+    private byte[] state;
+    /**
+     * @serial
+     */
+    private MessageDigest digest = null;
+    /**
+     * @serial
+     *
+     * We know that the MessageDigest class does not implement
+     * java.io.Serializable.  However, since this field is no longer
+     * used, it will always be NULL and won't affect the serialization
+     * of the SecureRandom class itself.
+     */
+    private byte[] randomBytes;
+    /**
+     * @serial
+     */
+    private int randomBytesUsed;
+    /**
+     * @serial
+     */
+    private long counter;
+}
diff --git a/java/security/SecureRandomSpi.java b/java/security/SecureRandomSpi.java
new file mode 100644
index 0000000..ef6c243
--- /dev/null
+++ b/java/security/SecureRandomSpi.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1998, 2013, 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 java.security;
+
+/**
+ * This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
+ * for the {@code SecureRandom} class.
+ * All the abstract methods in this class must be implemented by each
+ * service provider who wishes to supply the implementation
+ * of a cryptographically strong pseudo-random number generator.
+ *
+ *
+ * @see SecureRandom
+ * @since 1.2
+ */
+
+public abstract class SecureRandomSpi implements java.io.Serializable {
+
+    private static final long serialVersionUID = -2991854161009191830L;
+
+    /**
+     * Reseeds this random object. The given seed supplements, rather than
+     * replaces, the existing seed. Thus, repeated calls are guaranteed
+     * never to reduce randomness.
+     *
+     * @param seed the seed.
+     */
+    protected abstract void engineSetSeed(byte[] seed);
+
+    /**
+     * Generates a user-specified number of random bytes.
+     *
+     * <p> If a call to {@code engineSetSeed} had not occurred previously,
+     * the first call to this method forces this SecureRandom implementation
+     * to seed itself.  This self-seeding will not occur if
+     * {@code engineSetSeed} was previously called.
+     *
+     * @param bytes the array to be filled in with random bytes.
+     */
+    protected abstract void engineNextBytes(byte[] bytes);
+
+    /**
+     * Returns the given number of seed bytes.  This call may be used to
+     * seed other random number generators.
+     *
+     * @param numBytes the number of seed bytes to generate.
+     *
+     * @return the seed bytes.
+     */
+     protected abstract byte[] engineGenerateSeed(int numBytes);
+}
diff --git a/java/security/Security.java b/java/security/Security.java
new file mode 100644
index 0000000..743cf36
--- /dev/null
+++ b/java/security/Security.java
@@ -0,0 +1,1081 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 2013, 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 java.security;
+
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.io.*;
+import sun.security.jca.GetInstance;
+import sun.security.jca.ProviderList;
+import sun.security.jca.Providers;
+
+/**
+ * <p>This class centralizes all security properties and common security
+ * methods. One of its primary uses is to manage providers.
+ *
+ * <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.
+ *
+ * @author Benjamin Renaud
+ */
+
+public final class Security {
+
+    // Android-added: Track the version to allow callers know when something has changed.
+    private static final AtomicInteger version = new AtomicInteger();
+
+    // Android-removed: Debug is stubbed and disabled on Android.
+    // /* Are we debugging? -- for developers */
+    // private static final Debug sdebug =
+    //                     Debug.getInstance("properties");
+
+    /* The java.security properties */
+    // Android-changed: Added final.
+    private static final Properties props;
+
+    // An element in the cache
+    private static class ProviderProperty {
+        String className;
+        Provider provider;
+    }
+
+    static {
+// BEGIN Android-changed: doPrivileged is stubbed on Android.
+// Also, because props is final it must be assigned in the static block, not a method.
+        /*
+        // doPrivileged here because there are multiple
+        // things in initialize that might require privs.
+        // (the FileInputStream call and the File.exists call,
+        // the securityPropFile call, etc)
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            public Void run() {
+                initialize();
+                return null;
+            }
+        });
+    }
+
+    private static void initialize() {
+        */
+// END Android-changed: doPrivileged is stubbed on Android.
+        props = new Properties();
+        boolean loadedProps = false;
+        // BEGIN Android-changed: Use a resource file, Android logging, and only one file.
+        InputStream is = null;
+        try {
+            /*
+             * Android keeps the property file in a resource file.
+             */
+            InputStream propStream = Security.class.getResourceAsStream("security.properties");
+            if (propStream == null) {
+                System.logE("Could not find 'security.properties'.");
+            } else {
+                is  = new BufferedInputStream(propStream);
+                props.load(is);
+                loadedProps = true;
+            }
+        } catch (IOException ex) {
+            System.logE("Could not load 'security.properties'", ex);
+        } finally {
+            if (is != null) {
+                try {
+                    is.close();
+                } catch (IOException ignored) {}
+            }
+        }
+        // END Android-changed: Use a resource file, Android logging, and only one file.
+
+        if (!loadedProps) {
+            initializeStatic();
+        }
+    }
+
+    /*
+     * Initialize to default values, if <java.home>/lib/java.security
+     * is not found.
+     */
+    private static void initializeStatic() {
+        // Android-changed: Use Conscrypt and BC, not the sun.security providers.
+        /*
+        props.put("security.provider.1", "sun.security.provider.Sun");
+        props.put("security.provider.2", "sun.security.rsa.SunRsaSign");
+        props.put("security.provider.3", "com.sun.net.ssl.internal.ssl.Provider");
+        props.put("security.provider.4", "com.sun.crypto.provider.SunJCE");
+        props.put("security.provider.5", "sun.security.jgss.SunProvider");
+        props.put("security.provider.6", "com.sun.security.sasl.Provider");
+        */
+        props.put("security.provider.1", "com.android.org.conscrypt.OpenSSLProvider");
+        props.put("security.provider.2", "sun.security.provider.CertPathProvider");
+        props.put("security.provider.3", "com.android.org.bouncycastle.jce.provider.BouncyCastleProvider");
+        props.put("security.provider.4", "com.android.org.conscrypt.JSSEProvider");
+    }
+
+    /**
+     * Don't let anyone instantiate this.
+     */
+    private Security() {
+    }
+
+    /**
+     * Looks up providers, and returns the property (and its associated
+     * provider) mapping the key, if any.
+     * The order in which the providers are looked up is the
+     * provider-preference order, as specificed in the security
+     * properties file.
+     */
+    private static ProviderProperty getProviderProperty(String key) {
+        ProviderProperty entry = null;
+
+        List<Provider> providers = Providers.getProviderList().providers();
+        for (int i = 0; i < providers.size(); i++) {
+
+            String matchKey = null;
+            Provider prov = providers.get(i);
+            String prop = prov.getProperty(key);
+
+            if (prop == null) {
+                // Is there a match if we do a case-insensitive property name
+                // comparison? Let's try ...
+                for (Enumeration<Object> e = prov.keys();
+                                e.hasMoreElements() && prop == null; ) {
+                    matchKey = (String)e.nextElement();
+                    if (key.equalsIgnoreCase(matchKey)) {
+                        prop = prov.getProperty(matchKey);
+                        break;
+                    }
+                }
+            }
+
+            if (prop != null) {
+                ProviderProperty newEntry = new ProviderProperty();
+                newEntry.className = prop;
+                newEntry.provider = prov;
+                return newEntry;
+            }
+        }
+
+        return entry;
+    }
+
+    /**
+     * Returns the property (if any) mapping the key for the given provider.
+     */
+    private static String getProviderProperty(String key, Provider provider) {
+        String prop = provider.getProperty(key);
+        if (prop == null) {
+            // Is there a match if we do a case-insensitive property name
+            // comparison? Let's try ...
+            for (Enumeration<Object> e = provider.keys();
+                                e.hasMoreElements() && prop == null; ) {
+                String matchKey = (String)e.nextElement();
+                if (key.equalsIgnoreCase(matchKey)) {
+                    prop = provider.getProperty(matchKey);
+                    break;
+                }
+            }
+        }
+        return prop;
+    }
+
+    /**
+     * Gets a specified property for an algorithm. The algorithm name
+     * should be a standard name. See the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard algorithm names.
+     *
+     * One possible use is by specialized algorithm parsers, which may map
+     * classes to algorithms which they understand (much like Key parsers
+     * do).
+     *
+     * @param algName the algorithm name.
+     *
+     * @param propName the name of the property to get.
+     *
+     * @return the value of the specified property.
+     *
+     * @deprecated This method used to return the value of a proprietary
+     * property in the master file of the "SUN" Cryptographic Service
+     * Provider in order to determine how to parse algorithm-specific
+     * parameters. Use the new provider-based and algorithm-independent
+     * {@code AlgorithmParameters} and {@code KeyFactory} engine
+     * classes (introduced in the J2SE version 1.2 platform) instead.
+     */
+    @Deprecated
+    public static String getAlgorithmProperty(String algName,
+                                              String propName) {
+        ProviderProperty entry = getProviderProperty("Alg." + propName
+                                                     + "." + algName);
+        if (entry != null) {
+            return entry.className;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Adds a new provider, at a specified position. The position is
+     * the preference order in which providers are searched for
+     * requested algorithms.  The position is 1-based, that is,
+     * 1 is most preferred, followed by 2, and so on.
+     *
+     * <p>If the given provider is installed at the requested position,
+     * the provider that used to be at that position, and all providers
+     * with a position greater than {@code position}, are shifted up
+     * one position (towards the end of the list of installed providers).
+     *
+     * <p>A provider cannot be added if it is already installed.
+     *
+     * <p>If there is a security manager, the
+     * {@link java.lang.SecurityManager#checkSecurityAccess} method is called
+     * with the {@code "insertProvider"} permission target name to see if
+     * it's ok to add a new provider. If this permission check is denied,
+     * {@code checkSecurityAccess} is called again with the
+     * {@code "insertProvider."+provider.getName()} permission target name. If
+     * both checks are denied, a {@code SecurityException} is thrown.
+     *
+     * @param provider the provider to be added.
+     *
+     * @param position the preference position that the caller would
+     * like for this provider.
+     *
+     * @return the actual preference position in which the provider was
+     * added, or -1 if the provider was not added because it is
+     * already installed.
+     *
+     * @throws  NullPointerException if provider is null
+     * @throws  SecurityException
+     *          if a security manager exists and its {@link
+     *          java.lang.SecurityManager#checkSecurityAccess} method
+     *          denies access to add a new provider
+     *
+     * @see #getProvider
+     * @see #removeProvider
+     * @see java.security.SecurityPermission
+     */
+    public static synchronized int insertProviderAt(Provider provider,
+            int position) {
+        String providerName = provider.getName();
+        // Android-removed: Checks using SecurityManager, which is not functional in Android.
+        // checkInsertProvider(providerName);
+        ProviderList list = Providers.getFullProviderList();
+        ProviderList newList = ProviderList.insertAt(list, provider, position - 1);
+        if (list == newList) {
+            return -1;
+        }
+        // Android-added: Version tracking call.
+        increaseVersion();
+        Providers.setProviderList(newList);
+        return newList.getIndex(providerName) + 1;
+    }
+
+    /**
+     * Adds a provider to the next position available.
+     *
+     * <p>If there is a security manager, the
+     * {@link java.lang.SecurityManager#checkSecurityAccess} method is called
+     * with the {@code "insertProvider"} permission target name to see if
+     * it's ok to add a new provider. If this permission check is denied,
+     * {@code checkSecurityAccess} is called again with the
+     * {@code "insertProvider."+provider.getName()} permission target name. If
+     * both checks are denied, a {@code SecurityException} is thrown.
+     *
+     * @param provider the provider to be added.
+     *
+     * @return the preference position in which the provider was
+     * added, or -1 if the provider was not added because it is
+     * already installed.
+     *
+     * @throws  NullPointerException if provider is null
+     * @throws  SecurityException
+     *          if a security manager exists and its {@link
+     *          java.lang.SecurityManager#checkSecurityAccess} method
+     *          denies access to add a new provider
+     *
+     * @see #getProvider
+     * @see #removeProvider
+     * @see java.security.SecurityPermission
+     */
+    public static int addProvider(Provider provider) {
+        /*
+         * We can't assign a position here because the statically
+         * registered providers may not have been installed yet.
+         * insertProviderAt() will fix that value after it has
+         * loaded the static providers.
+         */
+        return insertProviderAt(provider, 0);
+    }
+
+    /**
+     * Removes the provider with the specified name.
+     *
+     * <p>When the specified provider is removed, all providers located
+     * at a position greater than where the specified provider was are shifted
+     * down one position (towards the head of the list of installed
+     * providers).
+     *
+     * <p>This method returns silently if the provider is not installed or
+     * if name is null.
+     *
+     * <p>First, if there is a security manager, its
+     * {@code checkSecurityAccess}
+     * method is called with the string {@code "removeProvider."+name}
+     * to see if it's ok to remove the provider.
+     * If the default implementation of {@code checkSecurityAccess}
+     * is used (i.e., that method is not overriden), then this will result in
+     * a call to the security manager's {@code checkPermission} method
+     * with a {@code SecurityPermission("removeProvider."+name)}
+     * permission.
+     *
+     * @param name the name of the provider to remove.
+     *
+     * @throws  SecurityException
+     *          if a security manager exists and its {@link
+     *          java.lang.SecurityManager#checkSecurityAccess} method
+     *          denies
+     *          access to remove the provider
+     *
+     * @see #getProvider
+     * @see #addProvider
+     */
+    public static synchronized void removeProvider(String name) {
+        // Android-removed: Checks using SecurityManager, which is not functional in Android.
+        // check("removeProvider." + name);
+        ProviderList list = Providers.getFullProviderList();
+        ProviderList newList = ProviderList.remove(list, name);
+        Providers.setProviderList(newList);
+        // Android-added: Version tracking call.
+        increaseVersion();
+    }
+
+    /**
+     * Returns an array containing all the installed providers. The order of
+     * the providers in the array is their preference order.
+     *
+     * @return an array of all the installed providers.
+     */
+    public static Provider[] getProviders() {
+        return Providers.getFullProviderList().toArray();
+    }
+
+    /**
+     * Returns the provider installed with the specified name, if
+     * any. Returns null if no provider with the specified name is
+     * installed or if name is null.
+     *
+     * @param name the name of the provider to get.
+     *
+     * @return the provider of the specified name.
+     *
+     * @see #removeProvider
+     * @see #addProvider
+     */
+    public static Provider getProvider(String name) {
+        return Providers.getProviderList().getProvider(name);
+    }
+
+    /**
+     * Returns an array containing all installed providers that satisfy the
+     * specified selection criterion, or null if no such providers have been
+     * installed. The returned providers are ordered
+     * according to their
+     * {@linkplain #insertProviderAt(java.security.Provider, int) preference order}.
+     *
+     * <p> A cryptographic service is always associated with a particular
+     * algorithm or type. For example, a digital signature service is
+     * always associated with a particular algorithm (e.g., DSA),
+     * and a CertificateFactory service is always associated with
+     * a particular certificate type (e.g., X.509).
+     *
+     * <p>The selection criterion must be specified in one of the following two
+     * formats:
+     * <ul>
+     * <li> <i>{@literal <crypto_service>.<algorithm_or_type>}</i>
+     * <p> The cryptographic service name must not contain any dots.
+     * <p> A
+     * provider satisfies the specified selection criterion iff the provider
+     * implements the
+     * specified algorithm or type for the specified cryptographic service.
+     * <p> For example, "CertificateFactory.X.509"
+     * would be satisfied by any provider that supplied
+     * a CertificateFactory implementation for X.509 certificates.
+     * <li> <i>{@literal <crypto_service>.<algorithm_or_type>
+     * <attribute_name>:<attribute_value>}</i>
+     * <p> The cryptographic service name must not contain any dots. There
+     * must be one or more space characters between the
+     * <i>{@literal <algorithm_or_type>}</i> and the
+     * <i>{@literal <attribute_name>}</i>.
+     *  <p> A provider satisfies this selection criterion iff the
+     * provider implements the specified algorithm or type for the specified
+     * cryptographic service and its implementation meets the
+     * constraint expressed by the specified attribute name/value pair.
+     * <p> For example, "Signature.SHA1withDSA KeySize:1024" would be
+     * satisfied by any provider that implemented
+     * the SHA1withDSA signature algorithm with a keysize of 1024 (or larger).
+     *
+     * </ul>
+     *
+     * <p> See the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard cryptographic service names, standard
+     * algorithm names and standard attribute names.
+     *
+     * @param filter the criterion for selecting
+     * providers. The filter is case-insensitive.
+     *
+     * @return all the installed providers that satisfy the selection
+     * criterion, or null if no such providers have been installed.
+     *
+     * @throws InvalidParameterException
+     *         if the filter is not in the required format
+     * @throws NullPointerException if filter is null
+     *
+     * @see #getProviders(java.util.Map)
+     * @since 1.3
+     */
+    public static Provider[] getProviders(String filter) {
+        String key = null;
+        String value = null;
+        int index = filter.indexOf(':');
+
+        if (index == -1) {
+            key = filter;
+            value = "";
+        } else {
+            key = filter.substring(0, index);
+            value = filter.substring(index + 1);
+        }
+
+        Hashtable<String, String> hashtableFilter = new Hashtable<>(1);
+        hashtableFilter.put(key, value);
+
+        return (getProviders(hashtableFilter));
+    }
+
+    /**
+     * Returns an array containing all installed providers that satisfy the
+     * specified* selection criteria, or null if no such providers have been
+     * installed. The returned providers are ordered
+     * according to their
+     * {@linkplain #insertProviderAt(java.security.Provider, int)
+     * preference order}.
+     *
+     * <p>The selection criteria are represented by a map.
+     * Each map entry represents a selection criterion.
+     * A provider is selected iff it satisfies all selection
+     * criteria. The key for any entry in such a map must be in one of the
+     * following two formats:
+     * <ul>
+     * <li> <i>{@literal <crypto_service>.<algorithm_or_type>}</i>
+     * <p> The cryptographic service name must not contain any dots.
+     * <p> The value associated with the key must be an empty string.
+     * <p> A provider
+     * satisfies this selection criterion iff the provider implements the
+     * specified algorithm or type for the specified cryptographic service.
+     * <li>  <i>{@literal <crypto_service>}.
+     * {@literal <algorithm_or_type> <attribute_name>}</i>
+     * <p> The cryptographic service name must not contain any dots. There
+     * must be one or more space characters between the
+     * <i>{@literal <algorithm_or_type>}</i>
+     * and the <i>{@literal <attribute_name>}</i>.
+     * <p> The value associated with the key must be a non-empty string.
+     * A provider satisfies this selection criterion iff the
+     * provider implements the specified algorithm or type for the specified
+     * cryptographic service and its implementation meets the
+     * constraint expressed by the specified attribute name/value pair.
+     * </ul>
+     *
+     * <p> See the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard cryptographic service names, standard
+     * algorithm names and standard attribute names.
+     *
+     * @param filter the criteria for selecting
+     * providers. The filter is case-insensitive.
+     *
+     * @return all the installed providers that satisfy the selection
+     * criteria, or null if no such providers have been installed.
+     *
+     * @throws InvalidParameterException
+     *         if the filter is not in the required format
+     * @throws NullPointerException if filter is null
+     *
+     * @see #getProviders(java.lang.String)
+     * @since 1.3
+     */
+    public static Provider[] getProviders(Map<String,String> filter) {
+        // Get all installed providers first.
+        // Then only return those providers who satisfy the selection criteria.
+        Provider[] allProviders = Security.getProviders();
+        Set<String> keySet = filter.keySet();
+        LinkedHashSet<Provider> candidates = new LinkedHashSet<>(5);
+
+        // Returns all installed providers
+        // if the selection criteria is null.
+        if ((keySet == null) || (allProviders == null)) {
+            return allProviders;
+        }
+
+        boolean firstSearch = true;
+
+        // For each selection criterion, remove providers
+        // which don't satisfy the criterion from the candidate set.
+        for (Iterator<String> ite = keySet.iterator(); ite.hasNext(); ) {
+            String key = ite.next();
+            String value = filter.get(key);
+
+            LinkedHashSet<Provider> newCandidates = getAllQualifyingCandidates(key, value,
+                                                               allProviders);
+            if (firstSearch) {
+                candidates = newCandidates;
+                firstSearch = false;
+            }
+
+            if ((newCandidates != null) && !newCandidates.isEmpty()) {
+                // For each provider in the candidates set, if it
+                // isn't in the newCandidate set, we should remove
+                // it from the candidate set.
+                for (Iterator<Provider> cansIte = candidates.iterator();
+                     cansIte.hasNext(); ) {
+                    Provider prov = cansIte.next();
+                    if (!newCandidates.contains(prov)) {
+                        cansIte.remove();
+                    }
+                }
+            } else {
+                candidates = null;
+                break;
+            }
+        }
+
+        if ((candidates == null) || (candidates.isEmpty()))
+            return null;
+
+        Object[] candidatesArray = candidates.toArray();
+        Provider[] result = new Provider[candidatesArray.length];
+
+        for (int i = 0; i < result.length; i++) {
+            result[i] = (Provider)candidatesArray[i];
+        }
+
+        return result;
+    }
+
+    // Map containing cached Spi Class objects of the specified type
+    private static final Map<String, Class<?>> spiMap =
+            new ConcurrentHashMap<>();
+
+    /**
+     * Return the Class object for the given engine type
+     * (e.g. "MessageDigest"). Works for Spis in the java.security package
+     * only.
+     */
+    private static Class<?> getSpiClass(String type) {
+        Class<?> clazz = spiMap.get(type);
+        if (clazz != null) {
+            return clazz;
+        }
+        try {
+            clazz = Class.forName("java.security." + type + "Spi");
+            spiMap.put(type, clazz);
+            return clazz;
+        } catch (ClassNotFoundException e) {
+            throw new AssertionError("Spi class not found", e);
+        }
+    }
+
+    /*
+     * Returns an array of objects: the first object in the array is
+     * an instance of an implementation of the requested algorithm
+     * and type, and the second object in the array identifies the provider
+     * of that implementation.
+     * The {@code provider} argument can be null, in which case all
+     * configured providers will be searched in order of preference.
+     */
+    static Object[] getImpl(String algorithm, String type, String provider)
+            throws NoSuchAlgorithmException, NoSuchProviderException {
+        if (provider == null) {
+            return GetInstance.getInstance
+                (type, getSpiClass(type), algorithm).toArray();
+        } else {
+            return GetInstance.getInstance
+                (type, getSpiClass(type), algorithm, provider).toArray();
+        }
+    }
+
+    static Object[] getImpl(String algorithm, String type, String provider,
+            Object params) throws NoSuchAlgorithmException,
+            NoSuchProviderException, InvalidAlgorithmParameterException {
+        if (provider == null) {
+            return GetInstance.getInstance
+                (type, getSpiClass(type), algorithm, params).toArray();
+        } else {
+            return GetInstance.getInstance
+                (type, getSpiClass(type), algorithm, params, provider).toArray();
+        }
+    }
+
+    /*
+     * Returns an array of objects: the first object in the array is
+     * an instance of an implementation of the requested algorithm
+     * and type, and the second object in the array identifies the provider
+     * of that implementation.
+     * The {@code provider} argument cannot be null.
+     */
+    static Object[] getImpl(String algorithm, String type, Provider provider)
+            throws NoSuchAlgorithmException {
+        return GetInstance.getInstance
+            (type, getSpiClass(type), algorithm, provider).toArray();
+    }
+
+    static Object[] getImpl(String algorithm, String type, Provider provider,
+            Object params) throws NoSuchAlgorithmException,
+            InvalidAlgorithmParameterException {
+        return GetInstance.getInstance
+            (type, getSpiClass(type), algorithm, params, provider).toArray();
+    }
+
+    /**
+     * Gets a security property value.
+     *
+     * <p>First, if there is a security manager, its
+     * {@code checkPermission}  method is called with a
+     * {@code java.security.SecurityPermission("getProperty."+key)}
+     * permission to see if it's ok to retrieve the specified
+     * security property value..
+     *
+     * @param key the key of the property being retrieved.
+     *
+     * @return the value of the security property corresponding to key.
+     *
+     * @throws  SecurityException
+     *          if a security manager exists and its {@link
+     *          java.lang.SecurityManager#checkPermission} method
+     *          denies
+     *          access to retrieve the specified security property value
+     * @throws  NullPointerException is key is null
+     *
+     * @see #setProperty
+     * @see java.security.SecurityPermission
+     */
+    public static String getProperty(String key) {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new SecurityPermission("getProperty."+
+                                                      key));
+        }
+        String name = props.getProperty(key);
+        if (name != null)
+            name = name.trim(); // could be a class name with trailing ws
+        return name;
+    }
+
+    /**
+     * Sets a security property value.
+     *
+     * <p>First, if there is a security manager, its
+     * {@code checkPermission} method is called with a
+     * {@code java.security.SecurityPermission("setProperty."+key)}
+     * permission to see if it's ok to set the specified
+     * security property value.
+     *
+     * @param key the name of the property to be set.
+     *
+     * @param datum the value of the property to be set.
+     *
+     * @throws  SecurityException
+     *          if a security manager exists and its {@link
+     *          java.lang.SecurityManager#checkPermission} method
+     *          denies access to set the specified security property value
+     * @throws  NullPointerException if key or datum is null
+     *
+     * @see #getProperty
+     * @see java.security.SecurityPermission
+     */
+    public static void setProperty(String key, String datum) {
+        // Android-removed: Checks using SecurityManager, which is not functional in Android.
+        // check("setProperty."+key);
+        props.put(key, datum);
+        // Android-added: Version tracking call.
+        increaseVersion();
+        invalidateSMCache(key);  /* See below. */
+    }
+
+    /*
+     * Implementation detail:  If the property we just set in
+     * setProperty() was either "package.access" or
+     * "package.definition", we need to signal to the SecurityManager
+     * class that the value has just changed, and that it should
+     * invalidate it's local cache values.
+     *
+     * Rather than create a new API entry for this function,
+     * we use reflection to set a private variable.
+     */
+    private static void invalidateSMCache(String key) {
+
+        final boolean pa = key.equals("package.access");
+        final boolean pd = key.equals("package.definition");
+
+        if (pa || pd) {
+            AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                public Void run() {
+                    try {
+                        /* Get the class via the bootstrap class loader. */
+                        Class<?> cl = Class.forName(
+                            "java.lang.SecurityManager", false, null);
+                        Field f = null;
+                        boolean accessible = false;
+
+                        if (pa) {
+                            f = cl.getDeclaredField("packageAccessValid");
+                            accessible = f.isAccessible();
+                            f.setAccessible(true);
+                        } else {
+                            f = cl.getDeclaredField("packageDefinitionValid");
+                            accessible = f.isAccessible();
+                            f.setAccessible(true);
+                        }
+                        f.setBoolean(f, false);
+                        f.setAccessible(accessible);
+                    }
+                    catch (Exception e1) {
+                        /* If we couldn't get the class, it hasn't
+                         * been loaded yet.  If there is no such
+                         * field, we shouldn't try to set it.  There
+                         * shouldn't be a security execption, as we
+                         * are loaded by boot class loader, and we
+                         * are inside a doPrivileged() here.
+                         *
+                         * NOOP: don't do anything...
+                         */
+                    }
+                    return null;
+                }  /* run */
+            });  /* PrivilegedAction */
+        }  /* if */
+    }
+
+    // BEGIN Android-removed: SecurityManager is stubbed on Android.
+    /*
+    private static void check(String directive) {
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkSecurityAccess(directive);
+        }
+    }
+
+    private static void checkInsertProvider(String name) {
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            try {
+                security.checkSecurityAccess("insertProvider");
+            } catch (SecurityException se1) {
+                try {
+                    security.checkSecurityAccess("insertProvider." + name);
+                } catch (SecurityException se2) {
+                    // throw first exception, but add second to suppressed
+                    se1.addSuppressed(se2);
+                    throw se1;
+                }
+            }
+        }
+    }
+    */
+    // END Android-removed: SecurityManager is stubbed on Android.
+
+    /*
+    * Returns all providers who satisfy the specified
+    * criterion.
+    */
+    private static LinkedHashSet<Provider> getAllQualifyingCandidates(
+                                                String filterKey,
+                                                String filterValue,
+                                                Provider[] allProviders) {
+        String[] filterComponents = getFilterComponents(filterKey,
+                                                        filterValue);
+
+        // The first component is the service name.
+        // The second is the algorithm name.
+        // If the third isn't null, that is the attrinute name.
+        String serviceName = filterComponents[0];
+        String algName = filterComponents[1];
+        String attrName = filterComponents[2];
+
+        return getProvidersNotUsingCache(serviceName, algName, attrName,
+                                         filterValue, allProviders);
+    }
+
+    private static LinkedHashSet<Provider> getProvidersNotUsingCache(
+                                                String serviceName,
+                                                String algName,
+                                                String attrName,
+                                                String filterValue,
+                                                Provider[] allProviders) {
+        LinkedHashSet<Provider> candidates = new LinkedHashSet<>(5);
+        for (int i = 0; i < allProviders.length; i++) {
+            if (isCriterionSatisfied(allProviders[i], serviceName,
+                                     algName,
+                                     attrName, filterValue)) {
+                candidates.add(allProviders[i]);
+            }
+        }
+        return candidates;
+    }
+
+    /*
+     * Returns true if the given provider satisfies
+     * the selection criterion key:value.
+     */
+    private static boolean isCriterionSatisfied(Provider prov,
+                                                String serviceName,
+                                                String algName,
+                                                String attrName,
+                                                String filterValue) {
+        String key = serviceName + '.' + algName;
+
+        if (attrName != null) {
+            key += ' ' + attrName;
+        }
+        // Check whether the provider has a property
+        // whose key is the same as the given key.
+        String propValue = getProviderProperty(key, prov);
+
+        if (propValue == null) {
+            // Check whether we have an alias instead
+            // of a standard name in the key.
+            String standardName = getProviderProperty("Alg.Alias." +
+                                                      serviceName + "." +
+                                                      algName,
+                                                      prov);
+            if (standardName != null) {
+                key = serviceName + "." + standardName;
+
+                if (attrName != null) {
+                    key += ' ' + attrName;
+                }
+
+                propValue = getProviderProperty(key, prov);
+            }
+
+            if (propValue == null) {
+                // The provider doesn't have the given
+                // key in its property list.
+                return false;
+            }
+        }
+
+        // If the key is in the format of:
+        // <crypto_service>.<algorithm_or_type>,
+        // there is no need to check the value.
+
+        if (attrName == null) {
+            return true;
+        }
+
+        // If we get here, the key must be in the
+        // format of <crypto_service>.<algorithm_or_provider> <attribute_name>.
+        if (isStandardAttr(attrName)) {
+            return isConstraintSatisfied(attrName, filterValue, propValue);
+        } else {
+            return filterValue.equalsIgnoreCase(propValue);
+        }
+    }
+
+    /*
+     * Returns true if the attribute is a standard attribute;
+     * otherwise, returns false.
+     */
+    private static boolean isStandardAttr(String attribute) {
+        // For now, we just have two standard attributes:
+        // KeySize and ImplementedIn.
+        if (attribute.equalsIgnoreCase("KeySize"))
+            return true;
+
+        if (attribute.equalsIgnoreCase("ImplementedIn"))
+            return true;
+
+        return false;
+    }
+
+    /*
+     * Returns true if the requested attribute value is supported;
+     * otherwise, returns false.
+     */
+    private static boolean isConstraintSatisfied(String attribute,
+                                                 String value,
+                                                 String prop) {
+        // For KeySize, prop is the max key size the
+        // provider supports for a specific <crypto_service>.<algorithm>.
+        if (attribute.equalsIgnoreCase("KeySize")) {
+            int requestedSize = Integer.parseInt(value);
+            int maxSize = Integer.parseInt(prop);
+            if (requestedSize <= maxSize) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+
+        // For Type, prop is the type of the implementation
+        // for a specific <crypto service>.<algorithm>.
+        if (attribute.equalsIgnoreCase("ImplementedIn")) {
+            return value.equalsIgnoreCase(prop);
+        }
+
+        return false;
+    }
+
+    static String[] getFilterComponents(String filterKey, String filterValue) {
+        int algIndex = filterKey.indexOf('.');
+
+        if (algIndex < 0) {
+            // There must be a dot in the filter, and the dot
+            // shouldn't be at the beginning of this string.
+            throw new InvalidParameterException("Invalid filter");
+        }
+
+        String serviceName = filterKey.substring(0, algIndex);
+        String algName = null;
+        String attrName = null;
+
+        if (filterValue.length() == 0) {
+            // The filterValue is an empty string. So the filterKey
+            // should be in the format of <crypto_service>.<algorithm_or_type>.
+            algName = filterKey.substring(algIndex + 1).trim();
+            if (algName.length() == 0) {
+                // There must be a algorithm or type name.
+                throw new InvalidParameterException("Invalid filter");
+            }
+        } else {
+            // The filterValue is a non-empty string. So the filterKey must be
+            // in the format of
+            // <crypto_service>.<algorithm_or_type> <attribute_name>
+            int attrIndex = filterKey.indexOf(' ');
+
+            if (attrIndex == -1) {
+                // There is no attribute name in the filter.
+                throw new InvalidParameterException("Invalid filter");
+            } else {
+                attrName = filterKey.substring(attrIndex + 1).trim();
+                if (attrName.length() == 0) {
+                    // There is no attribute name in the filter.
+                    throw new InvalidParameterException("Invalid filter");
+                }
+            }
+
+            // There must be an algorithm name in the filter.
+            if ((attrIndex < algIndex) ||
+                (algIndex == attrIndex - 1)) {
+                throw new InvalidParameterException("Invalid filter");
+            } else {
+                algName = filterKey.substring(algIndex + 1, attrIndex);
+            }
+        }
+
+        String[] result = new String[3];
+        result[0] = serviceName;
+        result[1] = algName;
+        result[2] = attrName;
+
+        return result;
+    }
+
+    /**
+     * Returns a Set of Strings containing the names of all available
+     * algorithms or types for the specified Java cryptographic service
+     * (e.g., Signature, MessageDigest, Cipher, Mac, KeyStore). Returns
+     * an empty Set if there is no provider that supports the
+     * specified service or if serviceName is null. For a complete list
+     * of Java cryptographic services, please see the
+     * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/CryptoSpec.html">Java
+     * Cryptography Architecture API Specification &amp; Reference</a>.
+     * Note: the returned set is immutable.
+     *
+     * @param serviceName the name of the Java cryptographic
+     * service (e.g., Signature, MessageDigest, Cipher, Mac, KeyStore).
+     * Note: this parameter is case-insensitive.
+     *
+     * @return a Set of Strings containing the names of all available
+     * algorithms or types for the specified Java cryptographic service
+     * or an empty set if no provider supports the specified service.
+     *
+     * @since 1.4
+     **/
+    public static Set<String> getAlgorithms(String serviceName) {
+
+        if ((serviceName == null) || (serviceName.length() == 0) ||
+            (serviceName.endsWith("."))) {
+            return Collections.emptySet();
+        }
+
+        HashSet<String> result = new HashSet<>();
+        Provider[] providers = Security.getProviders();
+
+        for (int i = 0; i < providers.length; i++) {
+            // Check the keys for each provider.
+            for (Enumeration<Object> e = providers[i].keys();
+                                                e.hasMoreElements(); ) {
+                String currentKey =
+                        ((String)e.nextElement()).toUpperCase(Locale.ENGLISH);
+                if (currentKey.startsWith(
+                        serviceName.toUpperCase(Locale.ENGLISH))) {
+                    // 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) {
+                        result.add(currentKey.substring(
+                                                serviceName.length() + 1));
+                    }
+                }
+            }
+        }
+        return Collections.unmodifiableSet(result);
+    }
+
+    // BEGIN Android-added: Methods for version handling.
+    /**
+     * @hide
+     */
+    public static void increaseVersion() {
+        version.incrementAndGet();
+    }
+    /**
+     * @hide
+     */
+    public static int getVersion() {
+        return version.get();
+    }
+    // END Android-added: Methods for version handling.
+}
diff --git a/java/security/SecurityPermission.java b/java/security/SecurityPermission.java
new file mode 100644
index 0000000..f02755c
--- /dev/null
+++ b/java/security/SecurityPermission.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security;
+
+// Android-changed: Stubbed the implementation.  Android doesn't support SecurityManager.
+// See comments in java.lang.SecurityManager for details.
+/**
+ * Legacy security code; do not use.
+ */
+
+public final class SecurityPermission extends BasicPermission {
+
+    public SecurityPermission(String name) { super(""); }
+    public SecurityPermission(String name, String actions) { super("", ""); }
+}
diff --git a/java/security/Signature.java b/java/security/Signature.java
new file mode 100644
index 0000000..5a0e6a8
--- /dev/null
+++ b/java/security/Signature.java
@@ -0,0 +1,1560 @@
+/*
+ * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (C) 2014 The Android Open Source Project
+ * 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 java.security;
+
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.io.*;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+
+import java.nio.ByteBuffer;
+
+import java.security.Provider.Service;
+
+import javax.crypto.Cipher;
+import javax.crypto.CipherSpi;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.BadPaddingException;
+import javax.crypto.NoSuchPaddingException;
+import sun.security.jca.*;
+import sun.security.jca.GetInstance.Instance;
+
+/**
+ * The Signature class is used to provide applications the functionality
+ * of a digital signature algorithm. Digital signatures are used for
+ * authentication and integrity assurance of digital data.
+ *
+ * <p> The signature algorithm can be, among others, the NIST standard
+ * DSA, using DSA and SHA-1. The DSA algorithm using the
+ * SHA-1 message digest algorithm can be specified as {@code SHA1withDSA}.
+ * In the case of RSA, there are multiple choices for the message digest
+ * algorithm, so the signing algorithm could be specified as, for example,
+ * {@code MD2withRSA}, {@code MD5withRSA}, or {@code SHA1withRSA}.
+ * The algorithm name must be specified, as there is no default.
+ *
+ * <p> A Signature object can be used to generate and verify digital
+ * signatures.
+ *
+ * <p> There are three phases to the use of a Signature object for
+ * either signing data or verifying a signature:<ol>
+ *
+ * <li>Initialization, with either
+ *
+ *     <ul>
+ *
+ *     <li>a public key, which initializes the signature for
+ *     verification (see {@link #initVerify(PublicKey) initVerify}), or
+ *
+ *     <li>a private key (and optionally a Secure Random Number Generator),
+ *     which initializes the signature for signing
+ *     (see {@link #initSign(PrivateKey)}
+ *     and {@link #initSign(PrivateKey, SecureRandom)}).
+ *
+ *     </ul>
+ *
+ * <li>Updating
+ *
+ * <p>Depending on the type of initialization, this will update the
+ * bytes to be signed or verified. See the
+ * {@link #update(byte) update} methods.
+ *
+ * <li>Signing or Verifying a signature on all updated bytes. See the
+ * {@link #sign() sign} methods and the {@link #verify(byte[]) verify}
+ * method.
+ *
+ * </ol>
+ *
+ * <p>Note that this class is abstract and extends from
+ * {@code SignatureSpi} for historical reasons.
+ * Application developers should only take notice of the methods defined in
+ * this {@code Signature} class; all the methods in
+ * the superclass are intended for cryptographic service providers who wish to
+ * supply their own implementations of digital signature algorithms.
+ *
+ * <p> Android provides the following {@code Signature} algorithms:
+ * <table>
+ *   <thead>
+ *     <tr>
+ *       <th>Algorithm</th>
+ *       <th>Supported API Levels</th>
+ *     </tr>
+ *   </thead>
+ *   <tbody>
+ *     <tr>
+ *       <td>DSA</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>DSAwithSHA1</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>DSS</td>
+ *       <td>1-19</td>
+ *     </tr>
+ *     <tr>
+ *       <td>ECDSA</td>
+ *       <td>11+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>ECDSAwithSHA1</td>
+ *       <td>11+</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>MD2withRSA</td>
+ *       <td>1-3</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>MD4withRSA</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr>
+ *       <td>MD5withRSA</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>MD5withRSA/ISO9796-2</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr>
+ *       <td>NONEwithDSA</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>NONEwithECDSA</td>
+ *       <td>11+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>NONEwithRSA</td>
+ *       <td>17+</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>RSASSA-PSS</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA1withDSA</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA1withECDSA</td>
+ *       <td>11+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA1withRSA</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SHA1withRSA/ISO9796-2</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA1withRSA/PSS</td>
+ *       <td>23+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA224withDSA</td>
+ *       <td>20+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA224withECDSA</td>
+ *       <td>20+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA224withRSA</td>
+ *       <td>20+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA224withRSA/PSS</td>
+ *       <td>23+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA256withDSA</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA256withECDSA</td>
+ *       <td>11+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA256withRSA</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA256withRSA/PSS</td>
+ *       <td>23+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA384withECDSA</td>
+ *       <td>11+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA384withRSA</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA384withRSA/PSS</td>
+ *       <td>23+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA512withECDSA</td>
+ *       <td>11+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA512withRSA</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA512withRSA/PSS</td>
+ *       <td>23+</td>
+ *     </tr>
+ *   </tbody>
+ * </table>
+ *
+ * These algorithms are described in the <a href=
+ * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#Signature">
+ * Signature section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ *
+ * @author Benjamin Renaud
+ *
+ */
+
+public abstract class Signature extends SignatureSpi {
+
+    // BEGIN Android-removed: this debugging mechanism is not supported in Android.
+    /*
+    private static final Debug debug =
+                        Debug.getInstance("jca", "Signature");
+
+    private static final Debug pdebug =
+                        Debug.getInstance("provider", "Provider");
+    private static final boolean skipDebug =
+        Debug.isOn("engine=") && !Debug.isOn("signature");
+    // END Android-removed: this debugging mechanism is not supported in Android.
+    */
+
+    /*
+     * The algorithm for this signature object.
+     * This value is used to map an OID to the particular algorithm.
+     * The mapping is done in AlgorithmObject.algOID(String algorithm)
+     */
+    private String algorithm;
+
+    // The provider
+    Provider provider;
+
+    /**
+     * Possible {@link #state} value, signifying that
+     * this signature object has not yet been initialized.
+     */
+    protected final static int UNINITIALIZED = 0;
+
+    /**
+     * Possible {@link #state} value, signifying that
+     * this signature object has been initialized for signing.
+     */
+    protected final static int SIGN = 2;
+
+    /**
+     * Possible {@link #state} value, signifying that
+     * this signature object has been initialized for verification.
+     */
+    protected final static int VERIFY = 3;
+
+    /**
+     * Current state of this signature object.
+     */
+    protected int state = UNINITIALIZED;
+
+    /**
+     * Creates a Signature object for the specified algorithm.
+     *
+     * @param algorithm the standard string name of the algorithm.
+     * See the Signature section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#Signature">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard algorithm names.
+     */
+    protected Signature(String algorithm) {
+        this.algorithm = algorithm;
+    }
+
+    // name of the special signature alg
+    private final static String RSA_SIGNATURE = "NONEwithRSA";
+
+    // name of the equivalent cipher alg
+    private final static String RSA_CIPHER = "RSA/ECB/PKCS1Padding";
+
+    // all the services we need to lookup for compatibility with Cipher
+    private final static List<ServiceId> rsaIds = Arrays.asList(
+        new ServiceId[] {
+            new ServiceId("Signature", "NONEwithRSA"),
+            new ServiceId("Cipher", "RSA/ECB/PKCS1Padding"),
+            new ServiceId("Cipher", "RSA/ECB"),
+            new ServiceId("Cipher", "RSA//PKCS1Padding"),
+            new ServiceId("Cipher", "RSA"),
+        }
+    );
+
+    /**
+     * Returns a Signature object that implements the specified signature
+     * algorithm.
+     *
+     * <p> This method traverses the list of registered security Providers,
+     * starting with the most preferred Provider.
+     * A new Signature object encapsulating the
+     * SignatureSpi implementation from the first
+     * Provider that supports the specified algorithm is returned.
+     *
+     * <p> Note that the list of registered providers may be retrieved via
+     * the {@link Security#getProviders() Security.getProviders()} method.
+     *
+     * @param algorithm the standard name of the algorithm requested.
+     * See the Signature section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#Signature">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard algorithm names.
+     *
+     * @return the new Signature object.
+     *
+     * @exception NoSuchAlgorithmException if no Provider supports a
+     *          Signature implementation for the
+     *          specified algorithm.
+     *
+     * @see Provider
+     */
+    public static Signature getInstance(String algorithm)
+            throws NoSuchAlgorithmException {
+        List<Service> list;
+        if (algorithm.equalsIgnoreCase(RSA_SIGNATURE)) {
+            list = GetInstance.getServices(rsaIds);
+        } else {
+            list = GetInstance.getServices("Signature", algorithm);
+        }
+        Iterator<Service> t = list.iterator();
+        if (t.hasNext() == false) {
+            throw new NoSuchAlgorithmException
+                (algorithm + " Signature not available");
+        }
+        // try services until we find an Spi or a working Signature subclass
+        NoSuchAlgorithmException failure;
+        do {
+            Service s = t.next();
+            if (isSpi(s)) {
+                // Android-changed: Delegate constructor only takes algorithm.
+                // return new Delegate(s, t, algorithm);
+                return new Delegate(algorithm);
+            } else {
+                // must be a subclass of Signature, disable dynamic selection
+                try {
+                    Instance instance =
+                        GetInstance.getInstance(s, SignatureSpi.class);
+                    return getInstance(instance, algorithm);
+                } catch (NoSuchAlgorithmException e) {
+                    failure = e;
+                }
+            }
+        } while (t.hasNext());
+        throw failure;
+    }
+
+    private static Signature getInstance(Instance instance, String algorithm) {
+        Signature sig;
+        if (instance.impl instanceof Signature) {
+            sig = (Signature)instance.impl;
+            sig.algorithm = algorithm;
+        } else {
+            SignatureSpi spi = (SignatureSpi)instance.impl;
+            sig = new Delegate(spi, algorithm);
+        }
+        sig.provider = instance.provider;
+        return sig;
+    }
+
+    private final static Map<String,Boolean> signatureInfo;
+
+    static {
+        signatureInfo = new ConcurrentHashMap<String,Boolean>();
+        Boolean TRUE = Boolean.TRUE;
+        // pre-initialize with values for our SignatureSpi implementations
+        signatureInfo.put("sun.security.provider.DSA$RawDSA", TRUE);
+        signatureInfo.put("sun.security.provider.DSA$SHA1withDSA", TRUE);
+        signatureInfo.put("sun.security.rsa.RSASignature$MD2withRSA", TRUE);
+        signatureInfo.put("sun.security.rsa.RSASignature$MD5withRSA", TRUE);
+        signatureInfo.put("sun.security.rsa.RSASignature$SHA1withRSA", TRUE);
+        signatureInfo.put("sun.security.rsa.RSASignature$SHA256withRSA", TRUE);
+        signatureInfo.put("sun.security.rsa.RSASignature$SHA384withRSA", TRUE);
+        signatureInfo.put("sun.security.rsa.RSASignature$SHA512withRSA", TRUE);
+        signatureInfo.put("com.sun.net.ssl.internal.ssl.RSASignature", TRUE);
+        signatureInfo.put("sun.security.pkcs11.P11Signature", TRUE);
+    }
+
+    private static boolean isSpi(Service s) {
+        if (s.getType().equals("Cipher")) {
+            // must be a CipherSpi, which we can wrap with the CipherAdapter
+            return true;
+        }
+        String className = s.getClassName();
+        Boolean result = signatureInfo.get(className);
+        if (result == null) {
+            try {
+                Object instance = s.newInstance(null);
+                // Signature extends SignatureSpi
+                // so it is a "real" Spi if it is an
+                // instance of SignatureSpi but not Signature
+                boolean r = (instance instanceof SignatureSpi)
+                                && (instance instanceof Signature == false);
+                // BEGIN Android-removed: this debugging mechanism is not supported in Android.
+                /*
+                if ((debug != null) && (r == false)) {
+                    debug.println("Not a SignatureSpi " + className);
+                    debug.println("Delayed provider selection may not be "
+                        + "available for algorithm " + s.getAlgorithm());
+                }
+                */
+                // END Android-removed: this debugging mechanism is not supported in Android.
+                result = Boolean.valueOf(r);
+                signatureInfo.put(className, result);
+            } catch (Exception e) {
+                // something is wrong, assume not an SPI
+                return false;
+            }
+        }
+        return result.booleanValue();
+    }
+
+    /**
+     * Returns a Signature object that implements the specified signature
+     * algorithm.
+     *
+     * <p> A new Signature object encapsulating the
+     * SignatureSpi implementation from the specified provider
+     * is returned.  The specified provider must be registered
+     * in the security provider list.
+     *
+     * <p> Note that the list of registered providers may be retrieved via
+     * the {@link Security#getProviders() Security.getProviders()} method.
+     *
+     * @param algorithm the name of the algorithm requested.
+     * See the Signature section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#Signature">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard algorithm names.
+     *
+     * @param provider the name of the provider.
+     *
+     * @return the new Signature object.
+     *
+     * @exception NoSuchAlgorithmException if a SignatureSpi
+     *          implementation for the specified algorithm is not
+     *          available from the specified provider.
+     *
+     * @exception NoSuchProviderException if the specified provider is not
+     *          registered in the security provider list.
+     *
+     * @exception IllegalArgumentException if the provider name is null
+     *          or empty.
+     *
+     * @see Provider
+     */
+    public static Signature getInstance(String algorithm, String provider)
+            throws NoSuchAlgorithmException, NoSuchProviderException {
+        if (algorithm.equalsIgnoreCase(RSA_SIGNATURE)) {
+            // exception compatibility with existing code
+            if ((provider == null) || (provider.length() == 0)) {
+                throw new IllegalArgumentException("missing provider");
+            }
+            Provider p = Security.getProvider(provider);
+            if (p == null) {
+                throw new NoSuchProviderException
+                    ("no such provider: " + provider);
+            }
+            return getInstanceRSA(p);
+        }
+        Instance instance = GetInstance.getInstance
+                ("Signature", SignatureSpi.class, algorithm, provider);
+        return getInstance(instance, algorithm);
+    }
+
+    /**
+     * Returns a Signature object that implements the specified
+     * signature algorithm.
+     *
+     * <p> A new Signature object encapsulating the
+     * SignatureSpi implementation from the specified Provider
+     * object is returned.  Note that the specified Provider object
+     * does not have to be registered in the provider list.
+     *
+     * @param algorithm the name of the algorithm requested.
+     * See the Signature section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#Signature">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard algorithm names.
+     *
+     * @param provider the provider.
+     *
+     * @return the new Signature object.
+     *
+     * @exception NoSuchAlgorithmException if a SignatureSpi
+     *          implementation for the specified algorithm is not available
+     *          from the specified Provider object.
+     *
+     * @exception IllegalArgumentException if the provider is null.
+     *
+     * @see Provider
+     *
+     * @since 1.4
+     */
+    public static Signature getInstance(String algorithm, Provider provider)
+            throws NoSuchAlgorithmException {
+        if (algorithm.equalsIgnoreCase(RSA_SIGNATURE)) {
+            // exception compatibility with existing code
+            if (provider == null) {
+                throw new IllegalArgumentException("missing provider");
+            }
+            return getInstanceRSA(provider);
+        }
+        Instance instance = GetInstance.getInstance
+                ("Signature", SignatureSpi.class, algorithm, provider);
+        return getInstance(instance, algorithm);
+    }
+
+    // return an implementation for NONEwithRSA, which is a special case
+    // because of the Cipher.RSA/ECB/PKCS1Padding compatibility wrapper
+    private static Signature getInstanceRSA(Provider p)
+            throws NoSuchAlgorithmException {
+        // try Signature first
+        Service s = p.getService("Signature", RSA_SIGNATURE);
+        if (s != null) {
+            Instance instance = GetInstance.getInstance(s, SignatureSpi.class);
+            return getInstance(instance, RSA_SIGNATURE);
+        }
+        // check Cipher
+        try {
+            Cipher c = Cipher.getInstance(RSA_CIPHER, p);
+            return new Delegate(new CipherAdapter(c), RSA_SIGNATURE);
+        } catch (GeneralSecurityException e) {
+            // throw Signature style exception message to avoid confusion,
+            // but append Cipher exception as cause
+            throw new NoSuchAlgorithmException("no such algorithm: "
+                + RSA_SIGNATURE + " for provider " + p.getName(), e);
+        }
+    }
+
+    /**
+     * Returns the provider of this signature object.
+     *
+     * @return the provider of this signature object
+     */
+    public final Provider getProvider() {
+        chooseFirstProvider();
+        return this.provider;
+    }
+
+    void chooseFirstProvider() {
+        // empty, overridden in Delegate
+    }
+
+    /**
+     * Initializes this object for verification. If this method is called
+     * again with a different argument, it negates the effect
+     * of this call.
+     *
+     * @param publicKey the public key of the identity whose signature is
+     * going to be verified.
+     *
+     * @exception InvalidKeyException if the key is invalid.
+     */
+    public final void initVerify(PublicKey publicKey)
+            throws InvalidKeyException {
+        engineInitVerify(publicKey);
+        state = VERIFY;
+
+        // BEGIN Android-removed: this debugging mechanism is not supported in Android.
+        /*
+        if (!skipDebug && pdebug != null) {
+            pdebug.println("Signature." + algorithm +
+                " verification algorithm from: " + this.provider.getName());
+        }
+        */
+        // END Android-removed: this debugging mechanism is not supported in Android.
+    }
+
+    /**
+     * Initializes this object for verification, using the public key from
+     * the given certificate.
+     * <p>If the certificate is of type X.509 and has a <i>key usage</i>
+     * extension field marked as critical, and the value of the <i>key usage</i>
+     * extension field implies that the public key in
+     * the certificate and its corresponding private key are not
+     * supposed to be used for digital signatures, an
+     * {@code InvalidKeyException} is thrown.
+     *
+     * @param certificate the certificate of the identity whose signature is
+     * going to be verified.
+     *
+     * @exception InvalidKeyException  if the public key in the certificate
+     * is not encoded properly or does not include required  parameter
+     * information or cannot be used for digital signature purposes.
+     * @since 1.3
+     */
+    public final void initVerify(Certificate certificate)
+            throws InvalidKeyException {
+        // If the certificate is of type X509Certificate,
+        // we should check whether it has a Key Usage
+        // extension marked as critical.
+        if (certificate instanceof java.security.cert.X509Certificate) {
+            // Check whether the cert has a key usage extension
+            // marked as a critical extension.
+            // The OID for KeyUsage extension is 2.5.29.15.
+            X509Certificate cert = (X509Certificate)certificate;
+            Set<String> critSet = cert.getCriticalExtensionOIDs();
+
+            if (critSet != null && !critSet.isEmpty()
+                && critSet.contains("2.5.29.15")) {
+                boolean[] keyUsageInfo = cert.getKeyUsage();
+                // keyUsageInfo[0] is for digitalSignature.
+                if ((keyUsageInfo != null) && (keyUsageInfo[0] == false))
+                    throw new InvalidKeyException("Wrong key usage");
+            }
+        }
+
+        PublicKey publicKey = certificate.getPublicKey();
+        engineInitVerify(publicKey);
+        state = VERIFY;
+
+        // BEGIN Android-removed: this debugging mechanism is not supported in Android.
+        /*
+        if (!skipDebug && pdebug != null) {
+            pdebug.println("Signature." + algorithm +
+                " verification algorithm from: " + this.provider.getName());
+        }
+        */
+        // END Android-removed: this debugging mechanism is not supported in Android.
+    }
+
+    /**
+     * Initialize this object for signing. If this method is called
+     * again with a different argument, it negates the effect
+     * of this call.
+     *
+     * @param privateKey the private key of the identity whose signature
+     * is going to be generated.
+     *
+     * @exception InvalidKeyException if the key is invalid.
+     */
+    public final void initSign(PrivateKey privateKey)
+            throws InvalidKeyException {
+        engineInitSign(privateKey);
+        state = SIGN;
+
+        // BEGIN Android-removed: this debugging mechanism is not supported in Android.
+        /*
+        if (!skipDebug && pdebug != null) {
+            pdebug.println("Signature." + algorithm +
+                " signing algorithm from: " + this.provider.getName());
+        }
+        */
+        // END Android-removed: this debugging mechanism is not supported in Android.
+    }
+
+    /**
+     * Initialize this object for signing. If this method is called
+     * again with a different argument, it negates the effect
+     * of this call.
+     *
+     * @param privateKey the private key of the identity whose signature
+     * is going to be generated.
+     *
+     * @param random the source of randomness for this signature.
+     *
+     * @exception InvalidKeyException if the key is invalid.
+     */
+    public final void initSign(PrivateKey privateKey, SecureRandom random)
+            throws InvalidKeyException {
+        engineInitSign(privateKey, random);
+        state = SIGN;
+
+        // BEGIN Android-removed: this debugging mechanism is not supported in Android.
+        /*
+        if (!skipDebug && pdebug != null) {
+            pdebug.println("Signature." + algorithm +
+                " signing algorithm from: " + this.provider.getName());
+        }
+        */
+        // END Android-removed: this debugging mechanism is not supported in Android.
+    }
+
+    /**
+     * Returns the signature bytes of all the data updated.
+     * The format of the signature depends on the underlying
+     * signature scheme.
+     *
+     * <p>A call to this method resets this signature object to the state
+     * it was in when previously initialized for signing via a
+     * call to {@code initSign(PrivateKey)}. That is, the object is
+     * reset and available to generate another signature from the same
+     * signer, if desired, via new calls to {@code update} and
+     * {@code sign}.
+     *
+     * @return the signature bytes of the signing operation's result.
+     *
+     * @exception SignatureException if this signature object is not
+     * initialized properly or if this signature algorithm is unable to
+     * process the input data provided.
+     */
+    public final byte[] sign() throws SignatureException {
+        if (state == SIGN) {
+            return engineSign();
+        }
+        throw new SignatureException("object not initialized for " +
+                                     "signing");
+    }
+
+    /**
+     * Finishes the signature operation and stores the resulting signature
+     * bytes in the provided buffer {@code outbuf}, starting at
+     * {@code offset}.
+     * The format of the signature depends on the underlying
+     * signature scheme.
+     *
+     * <p>This signature object is reset to its initial state (the state it
+     * was in after a call to one of the {@code initSign} methods) and
+     * can be reused to generate further signatures with the same private key.
+     *
+     * @param outbuf buffer for the signature result.
+     *
+     * @param offset offset into {@code outbuf} where the signature is
+     * stored.
+     *
+     * @param len number of bytes within {@code outbuf} allotted for the
+     * signature.
+     *
+     * @return the number of bytes placed into {@code outbuf}.
+     *
+     * @exception SignatureException if this signature object is not
+     * initialized properly, if this signature algorithm is unable to
+     * process the input data provided, or if {@code len} is less
+     * than the actual signature length.
+     *
+     * @since 1.2
+     */
+    public final int sign(byte[] outbuf, int offset, int len)
+        throws SignatureException {
+        if (outbuf == null) {
+            throw new IllegalArgumentException("No output buffer given");
+        }
+        if (offset < 0 || len < 0) {
+            throw new IllegalArgumentException("offset or len is less than 0");
+        }
+        if (outbuf.length - offset < len) {
+            throw new IllegalArgumentException
+                ("Output buffer too small for specified offset and length");
+        }
+        if (state != SIGN) {
+            throw new SignatureException("object not initialized for " +
+                                         "signing");
+        }
+        return engineSign(outbuf, offset, len);
+    }
+
+    /**
+     * Verifies the passed-in signature.
+     *
+     * <p>A call to this method resets this signature object to the state
+     * it was in when previously initialized for verification via a
+     * call to {@code initVerify(PublicKey)}. That is, the object is
+     * reset and available to verify another signature from the identity
+     * whose public key was specified in the call to {@code initVerify}.
+     *
+     * @param signature the signature bytes to be verified.
+     *
+     * @return true if the signature was verified, false if not.
+     *
+     * @exception SignatureException if this signature object is not
+     * initialized properly, the passed-in signature is improperly
+     * encoded or of the wrong type, if this signature algorithm is unable to
+     * process the input data provided, etc.
+     */
+    public final boolean verify(byte[] signature) throws SignatureException {
+        if (state == VERIFY) {
+            return engineVerify(signature);
+        }
+        throw new SignatureException("object not initialized for " +
+                                     "verification");
+    }
+
+    /**
+     * Verifies the passed-in signature in the specified array
+     * of bytes, starting at the specified offset.
+     *
+     * <p>A call to this method resets this signature object to the state
+     * it was in when previously initialized for verification via a
+     * call to {@code initVerify(PublicKey)}. That is, the object is
+     * reset and available to verify another signature from the identity
+     * whose public key was specified in the call to {@code initVerify}.
+     *
+     *
+     * @param signature the signature bytes to be verified.
+     * @param offset the offset to start from in the array of bytes.
+     * @param length the number of bytes to use, starting at offset.
+     *
+     * @return true if the signature was verified, false if not.
+     *
+     * @exception SignatureException if this signature object is not
+     * initialized properly, the passed-in signature is improperly
+     * encoded or of the wrong type, if this signature algorithm is unable to
+     * process the input data provided, etc.
+     * @exception IllegalArgumentException if the {@code signature}
+     * byte array is null, or the {@code offset} or {@code length}
+     * is less than 0, or the sum of the {@code offset} and
+     * {@code length} is greater than the length of the
+     * {@code signature} byte array.
+     * @since 1.4
+     */
+    public final boolean verify(byte[] signature, int offset, int length)
+        throws SignatureException {
+        if (state == VERIFY) {
+            if (signature == null) {
+                throw new IllegalArgumentException("signature is null");
+            }
+            if (offset < 0 || length < 0) {
+                throw new IllegalArgumentException
+                    ("offset or length is less than 0");
+            }
+            if (signature.length - offset < length) {
+                throw new IllegalArgumentException
+                    ("signature too small for specified offset and length");
+            }
+
+            return engineVerify(signature, offset, length);
+        }
+        throw new SignatureException("object not initialized for " +
+                                     "verification");
+    }
+
+    /**
+     * Updates the data to be signed or verified by a byte.
+     *
+     * @param b the byte to use for the update.
+     *
+     * @exception SignatureException if this signature object is not
+     * initialized properly.
+     */
+    public final void update(byte b) throws SignatureException {
+        if (state == VERIFY || state == SIGN) {
+            engineUpdate(b);
+        } else {
+            throw new SignatureException("object not initialized for "
+                                         + "signature or verification");
+        }
+    }
+
+    /**
+     * Updates the data to be signed or verified, using the specified
+     * array of bytes.
+     *
+     * @param data the byte array to use for the update.
+     *
+     * @exception SignatureException if this signature object is not
+     * initialized properly.
+     */
+    public final void update(byte[] data) throws SignatureException {
+        update(data, 0, data.length);
+    }
+
+    /**
+     * Updates the data to be signed or verified, using the specified
+     * array of bytes, starting at the specified offset.
+     *
+     * @param data the array of bytes.
+     * @param off the offset to start from in the array of bytes.
+     * @param len the number of bytes to use, starting at offset.
+     *
+     * @exception SignatureException if this signature object is not
+     * initialized properly.
+     */
+    public final void update(byte[] data, int off, int len)
+            throws SignatureException {
+        if (state == SIGN || state == VERIFY) {
+            if (data == null) {
+                throw new IllegalArgumentException("data is null");
+            }
+            if (off < 0 || len < 0) {
+                throw new IllegalArgumentException("off or len is less than 0");
+            }
+            if (data.length - off < len) {
+                throw new IllegalArgumentException
+                    ("data too small for specified offset and length");
+            }
+            engineUpdate(data, off, len);
+        } else {
+            throw new SignatureException("object not initialized for "
+                                         + "signature or verification");
+        }
+    }
+
+    /**
+     * Updates the data to be signed or verified using the specified
+     * ByteBuffer. Processes the {@code data.remaining()} bytes
+     * starting at at {@code data.position()}.
+     * Upon return, the buffer's position will be equal to its limit;
+     * its limit will not have changed.
+     *
+     * @param data the ByteBuffer
+     *
+     * @exception SignatureException if this signature object is not
+     * initialized properly.
+     * @since 1.5
+     */
+    public final void update(ByteBuffer data) throws SignatureException {
+        if ((state != SIGN) && (state != VERIFY)) {
+            throw new SignatureException("object not initialized for "
+                                         + "signature or verification");
+        }
+        if (data == null) {
+            throw new NullPointerException();
+        }
+        engineUpdate(data);
+    }
+
+    /**
+     * Returns the name of the algorithm for this signature object.
+     *
+     * @return the name of the algorithm for this signature object.
+     */
+    public final String getAlgorithm() {
+        return this.algorithm;
+    }
+
+    /**
+     * Returns a string representation of this signature object,
+     * providing information that includes the state of the object
+     * and the name of the algorithm used.
+     *
+     * @return a string representation of this signature object.
+     */
+    public String toString() {
+        String initState = "";
+        switch (state) {
+        case UNINITIALIZED:
+            initState = "<not initialized>";
+            break;
+        case VERIFY:
+            initState = "<initialized for verifying>";
+            break;
+        case SIGN:
+            initState = "<initialized for signing>";
+            break;
+        }
+        return "Signature object: " + getAlgorithm() + initState;
+    }
+
+    /**
+     * Sets the specified algorithm parameter to the specified value.
+     * This method supplies a general-purpose mechanism through
+     * which it is possible to set the various parameters of this object.
+     * A parameter may be any settable parameter for the algorithm, such as
+     * a parameter size, or a source of random bits for signature generation
+     * (if appropriate), or an indication of whether or not to perform
+     * a specific but optional computation. A uniform algorithm-specific
+     * naming scheme for each parameter is desirable but left unspecified
+     * at this time.
+     *
+     * @param param the string identifier of the parameter.
+     * @param value the parameter value.
+     *
+     * @exception InvalidParameterException if {@code param} is an
+     * invalid parameter for this signature algorithm engine,
+     * the parameter is already set
+     * and cannot be set again, a security exception occurs, and so on.
+     *
+     * @see #getParameter
+     *
+     * @deprecated Use
+     * {@link #setParameter(java.security.spec.AlgorithmParameterSpec)
+     * setParameter}.
+     */
+    @Deprecated
+    public final void setParameter(String param, Object value)
+            throws InvalidParameterException {
+        engineSetParameter(param, value);
+    }
+
+    /**
+     * Initializes this signature engine with the specified parameter set.
+     *
+     * @param params the parameters
+     *
+     * @exception InvalidAlgorithmParameterException if the given parameters
+     * are inappropriate for this signature engine
+     *
+     * @see #getParameters
+     */
+    public final void setParameter(AlgorithmParameterSpec params)
+            throws InvalidAlgorithmParameterException {
+        engineSetParameter(params);
+    }
+
+    /**
+     * Returns the parameters used with this signature object.
+     *
+     * <p>The returned parameters may be the same that were used to initialize
+     * this signature, or may contain a combination of default and randomly
+     * generated parameter values used by the underlying signature
+     * implementation if this signature requires algorithm parameters but
+     * was not initialized with any.
+     *
+     * @return the parameters used with this signature, or null if this
+     * signature does not use any parameters.
+     *
+     * @see #setParameter(AlgorithmParameterSpec)
+     * @since 1.4
+     */
+    public final AlgorithmParameters getParameters() {
+        return engineGetParameters();
+    }
+
+    /**
+     * Gets the value of the specified algorithm parameter. This method
+     * supplies a general-purpose mechanism through which it is possible to
+     * get the various parameters of this object. A parameter may be any
+     * settable parameter for the algorithm, such as a parameter size, or
+     * a source of random bits for signature generation (if appropriate),
+     * or an indication of whether or not to perform a specific but optional
+     * computation. A uniform algorithm-specific naming scheme for each
+     * parameter is desirable but left unspecified at this time.
+     *
+     * @param param the string name of the parameter.
+     *
+     * @return the object that represents the parameter value, or null if
+     * there is none.
+     *
+     * @exception InvalidParameterException if {@code param} is an invalid
+     * parameter for this engine, or another exception occurs while
+     * trying to get this parameter.
+     *
+     * @see #setParameter(String, Object)
+     *
+     * @deprecated Deprecated.
+     */
+    @Deprecated
+    // Android-changed: add "Deprecated."
+    public final Object getParameter(String param)
+            throws InvalidParameterException {
+        return engineGetParameter(param);
+    }
+
+    /**
+     * Returns a clone if the implementation is cloneable.
+     *
+     * @return a clone if the implementation is cloneable.
+     *
+     * @exception CloneNotSupportedException if this is called
+     * on an implementation that does not support {@code Cloneable}.
+     */
+    public Object clone() throws CloneNotSupportedException {
+        if (this instanceof Cloneable) {
+            return super.clone();
+        } else {
+            throw new CloneNotSupportedException();
+        }
+    }
+
+    // BEGIN Android-added: Allow access to the current SPI for testing purposes.
+    /**
+     * Returns the {@code SignatureSpi} backing this {@code Signature}.
+     *
+     * @hide
+     */
+    public SignatureSpi getCurrentSpi() {
+      return null;
+    }
+    // END Android-added: Allow access to the current SPI for testing purposes.
+
+    /*
+     * The following class allows providers to extend from SignatureSpi
+     * rather than from Signature. It represents a Signature with an
+     * encapsulated, provider-supplied SPI object (of type SignatureSpi).
+     * If the provider implementation is an instance of SignatureSpi, the
+     * getInstance() methods above return an instance of this class, with
+     * the SPI object encapsulated.
+     *
+     * Note: All SPI methods from the original Signature class have been
+     * moved up the hierarchy into a new class (SignatureSpi), which has
+     * been interposed in the hierarchy between the API (Signature)
+     * and its original parent (Object).
+     */
+
+    @SuppressWarnings("deprecation")
+    private static class Delegate extends Signature {
+
+        // The provider implementation (delegate)
+        // filled in once the provider is selected
+        // BEGIN Android-note: Note on sigSpi invariants.
+        // (Not necessarily Android specific)
+        // Invariant to be preserved: sigSpi cannot be changed once it was assigned to something
+        // different than null and lock is null. That is only the case when sigSpi is specified
+        // in the constructor.
+        // END Android-note: Note on sigSpi invariants.
+        private SignatureSpi sigSpi;
+
+        // lock for mutex during provider selection
+        private final Object lock;
+
+        // BEGIN Android-removed: Redo the provider selection logic to allow reselecting provider.
+        // When only the algorithm is specified, we want to allow the Signature provider for that
+        // algorithm to change if multiple providers exist and they support different subsets of
+        // keys.  To that end, we don't hold an iterator and exhaust it when we need to choose
+        // a provider like the upstream implementation, we reestablish the list of providers
+        // each time.
+        /*
+        // next service to try in provider selection
+        // null once provider is selected
+        private Service firstService;
+
+        // remaining services to try in provider selection
+        // null once provider is selected
+        private Iterator<Service> serviceIterator;
+        */
+        // END Android-removed: Redo the provider selection logic to allow reselecting provider.
+
+        // constructor
+        Delegate(SignatureSpi sigSpi, String algorithm) {
+            super(algorithm);
+            this.sigSpi = sigSpi;
+            this.lock = null; // no lock needed
+        }
+
+        // used with delayed provider selection
+        // Android-changed: Remove Service and Iterator from constructor args.
+        Delegate(String algorithm) {
+            super(algorithm);
+            this.lock = new Object();
+        }
+
+        /**
+         * Returns a clone if the delegate is cloneable.
+         *
+         * @return a clone if the delegate is cloneable.
+         *
+         * @exception CloneNotSupportedException if this is called on a
+         * delegate that does not support {@code Cloneable}.
+         */
+        public Object clone() throws CloneNotSupportedException {
+            chooseFirstProvider();
+            if (sigSpi instanceof Cloneable) {
+                SignatureSpi sigSpiClone = (SignatureSpi)sigSpi.clone();
+                // Because 'algorithm' and 'provider' are private
+                // members of our supertype, we must perform a cast to
+                // access them.
+                Signature that =
+                    new Delegate(sigSpiClone, ((Signature)this).algorithm);
+                that.provider = ((Signature)this).provider;
+                return that;
+            } else {
+                throw new CloneNotSupportedException();
+            }
+        }
+
+        private static SignatureSpi newInstance(Service s)
+                throws NoSuchAlgorithmException {
+            if (s.getType().equals("Cipher")) {
+                // must be NONEwithRSA
+                try {
+                    Cipher c = Cipher.getInstance(RSA_CIPHER, s.getProvider());
+                    return new CipherAdapter(c);
+                } catch (NoSuchPaddingException e) {
+                    throw new NoSuchAlgorithmException(e);
+                }
+            } else {
+                Object o = s.newInstance(null);
+                if (o instanceof SignatureSpi == false) {
+                    throw new NoSuchAlgorithmException
+                        ("Not a SignatureSpi: " + o.getClass().getName());
+                }
+                return (SignatureSpi)o;
+            }
+        }
+
+        // max number of debug warnings to print from chooseFirstProvider()
+        private static int warnCount = 10;
+
+        /**
+         * Choose the Spi from the first provider available. Used if
+         * delayed provider selection is not possible because initSign()/
+         * initVerify() is not the first method called.
+         */
+        void chooseFirstProvider() {
+            if (sigSpi != null) {
+                return;
+            }
+            synchronized (lock) {
+                if (sigSpi != null) {
+                    return;
+                }
+                // BEGIN Android-removed: this debugging mechanism is not supported in Android.
+                /*
+                if (debug != null) {
+                    int w = --warnCount;
+                    if (w >= 0) {
+                        debug.println("Signature.init() not first method "
+                            + "called, disabling delayed provider selection");
+                        if (w == 0) {
+                            debug.println("Further warnings of this type will "
+                                + "be suppressed");
+                        }
+                        new Exception("Call trace").printStackTrace();
+                    }
+                }
+                */
+                // END Android-removed: this debugging mechanism is not supported in Android.
+                Exception lastException = null;
+// BEGIN Android-changed: Provider selection; loop over a new list each time.
+                List<Service> list;
+                if (((Signature)this).algorithm.equalsIgnoreCase(RSA_SIGNATURE)) {
+                    list = GetInstance.getServices(rsaIds);
+                } else {
+                    list = GetInstance.getServices("Signature",
+                            ((Signature)this).algorithm);
+                }
+                for (Service s : list) {
+// END Android-changed: Provider selection; loop over a new list each time.
+                    if (isSpi(s) == false) {
+                        continue;
+                    }
+                    try {
+                        sigSpi = newInstance(s);
+                        provider = s.getProvider();
+                        // Android-removed: Provider selection; loop over a new list each time.
+                        /*
+                        // not needed any more
+                        firstService = null;
+                        serviceIterator = null;
+                        */
+                        return;
+                    } catch (NoSuchAlgorithmException e) {
+                        lastException = e;
+                    }
+                }
+                ProviderException e = new ProviderException
+                        ("Could not construct SignatureSpi instance");
+                if (lastException != null) {
+                    e.initCause(lastException);
+                }
+                throw e;
+            }
+        }
+
+        private void chooseProvider(int type, Key key, SecureRandom random)
+                throws InvalidKeyException {
+            synchronized (lock) {
+                // Android-changed: Use the currently-selected provider only if no key was provided.
+                // if (sigSpi != null) {
+                if (sigSpi != null && key == null) {
+                    init(sigSpi, type, key, random);
+                    return;
+                }
+                Exception lastException = null;
+// BEGIN Android-changed: Provider selection; loop over a new list each time.
+                List<Service> list;
+                if (((Signature)this).algorithm.equalsIgnoreCase(RSA_SIGNATURE)) {
+                    list = GetInstance.getServices(rsaIds);
+                } else {
+                    list = GetInstance.getServices("Signature",
+                            ((Signature)this).algorithm);
+                }
+                for (Service s : list) {
+// END Android-changed: Provider selection; loop over a new list each time.
+                    // if provider says it does not support this key, ignore it
+                    if (s.supportsParameter(key) == false) {
+                        continue;
+                    }
+                    // if instance is not a SignatureSpi, ignore it
+                    if (isSpi(s) == false) {
+                        continue;
+                    }
+                    try {
+                        SignatureSpi spi = newInstance(s);
+                        init(spi, type, key, random);
+                        provider = s.getProvider();
+                        sigSpi = spi;
+                        // Android-removed: Provider selection; loop over a new list each time.
+                        /*
+                        firstService = null;
+                        serviceIterator = null;
+                        */
+                        return;
+                    } catch (Exception e) {
+                        // NoSuchAlgorithmException from newInstance()
+                        // InvalidKeyException from init()
+                        // RuntimeException (ProviderException) from init()
+                        if (lastException == null) {
+                            lastException = e;
+                        }
+                        // Android-added: Throw InvalidKeyException immediately.
+                        if (lastException instanceof InvalidKeyException) {
+                          throw (InvalidKeyException)lastException;
+                        }
+                    }
+                }
+                // no working provider found, fail
+                if (lastException instanceof InvalidKeyException) {
+                    throw (InvalidKeyException)lastException;
+                }
+                if (lastException instanceof RuntimeException) {
+                    throw (RuntimeException)lastException;
+                }
+                String k = (key != null) ? key.getClass().getName() : "(null)";
+                throw new InvalidKeyException
+                    ("No installed provider supports this key: "
+                    + k, lastException);
+            }
+        }
+
+        private final static int I_PUB     = 1;
+        private final static int I_PRIV    = 2;
+        private final static int I_PRIV_SR = 3;
+
+        private void init(SignatureSpi spi, int type, Key  key,
+                SecureRandom random) throws InvalidKeyException {
+            switch (type) {
+            case I_PUB:
+                spi.engineInitVerify((PublicKey)key);
+                break;
+            case I_PRIV:
+                spi.engineInitSign((PrivateKey)key);
+                break;
+            case I_PRIV_SR:
+                spi.engineInitSign((PrivateKey)key, random);
+                break;
+            default:
+                throw new AssertionError("Internal error: " + type);
+            }
+        }
+
+        protected void engineInitVerify(PublicKey publicKey)
+                throws InvalidKeyException {
+            // Android-changed: Use the currently-selected provider only if no key was provided.
+            // if (sigSpi != null) {
+            if (sigSpi != null && (lock == null || publicKey == null)) {
+                sigSpi.engineInitVerify(publicKey);
+            } else {
+                chooseProvider(I_PUB, publicKey, null);
+            }
+        }
+
+        protected void engineInitSign(PrivateKey privateKey)
+                throws InvalidKeyException {
+            // Android-changed: Use the currently-selected provider only if no key was provided.
+            // if (sigSpi != null) {
+            if (sigSpi != null && (lock == null || privateKey == null)) {
+                sigSpi.engineInitSign(privateKey);
+            } else {
+                chooseProvider(I_PRIV, privateKey, null);
+            }
+        }
+
+        protected void engineInitSign(PrivateKey privateKey, SecureRandom sr)
+                throws InvalidKeyException {
+            // Android-changed: Use the currently-selected provider only if no key was provided.
+            // if (sigSpi != null) {
+            if (sigSpi != null  && (lock == null || privateKey == null)) {
+                sigSpi.engineInitSign(privateKey, sr);
+            } else {
+                chooseProvider(I_PRIV_SR, privateKey, sr);
+            }
+        }
+
+        protected void engineUpdate(byte b) throws SignatureException {
+            chooseFirstProvider();
+            sigSpi.engineUpdate(b);
+        }
+
+        protected void engineUpdate(byte[] b, int off, int len)
+                throws SignatureException {
+            chooseFirstProvider();
+            sigSpi.engineUpdate(b, off, len);
+        }
+
+        protected void engineUpdate(ByteBuffer data) {
+            chooseFirstProvider();
+            sigSpi.engineUpdate(data);
+        }
+
+        protected byte[] engineSign() throws SignatureException {
+            chooseFirstProvider();
+            return sigSpi.engineSign();
+        }
+
+        protected int engineSign(byte[] outbuf, int offset, int len)
+                throws SignatureException {
+            chooseFirstProvider();
+            return sigSpi.engineSign(outbuf, offset, len);
+        }
+
+        protected boolean engineVerify(byte[] sigBytes)
+                throws SignatureException {
+            chooseFirstProvider();
+            return sigSpi.engineVerify(sigBytes);
+        }
+
+        protected boolean engineVerify(byte[] sigBytes, int offset, int length)
+                throws SignatureException {
+            chooseFirstProvider();
+            return sigSpi.engineVerify(sigBytes, offset, length);
+        }
+
+        protected void engineSetParameter(String param, Object value)
+                throws InvalidParameterException {
+            chooseFirstProvider();
+            sigSpi.engineSetParameter(param, value);
+        }
+
+        protected void engineSetParameter(AlgorithmParameterSpec params)
+                throws InvalidAlgorithmParameterException {
+            chooseFirstProvider();
+            sigSpi.engineSetParameter(params);
+        }
+
+        protected Object engineGetParameter(String param)
+                throws InvalidParameterException {
+            chooseFirstProvider();
+            return sigSpi.engineGetParameter(param);
+        }
+
+        protected AlgorithmParameters engineGetParameters() {
+            chooseFirstProvider();
+            return sigSpi.engineGetParameters();
+        }
+
+        // BEGIN Android-added: Allow access to the current SPI for testing purposes.
+        @Override
+        public SignatureSpi getCurrentSpi() {
+            if (lock == null) {
+                return sigSpi;
+            }
+            synchronized (lock) {
+                return sigSpi;
+            }
+        }
+        // END Android-added: Allow access to the current SPI for testing purposes.
+    }
+
+    // adapter for RSA/ECB/PKCS1Padding ciphers
+    @SuppressWarnings("deprecation")
+    private static class CipherAdapter extends SignatureSpi {
+
+        private final Cipher cipher;
+
+        private ByteArrayOutputStream data;
+
+        CipherAdapter(Cipher cipher) {
+            this.cipher = cipher;
+        }
+
+        protected void engineInitVerify(PublicKey publicKey)
+                throws InvalidKeyException {
+            cipher.init(Cipher.DECRYPT_MODE, publicKey);
+            if (data == null) {
+                data = new ByteArrayOutputStream(128);
+            } else {
+                data.reset();
+            }
+        }
+
+        protected void engineInitSign(PrivateKey privateKey)
+                throws InvalidKeyException {
+            cipher.init(Cipher.ENCRYPT_MODE, privateKey);
+            data = null;
+        }
+
+        protected void engineInitSign(PrivateKey privateKey,
+                SecureRandom random) throws InvalidKeyException {
+            cipher.init(Cipher.ENCRYPT_MODE, privateKey, random);
+            data = null;
+        }
+
+        protected void engineUpdate(byte b) throws SignatureException {
+            engineUpdate(new byte[] {b}, 0, 1);
+        }
+
+        protected void engineUpdate(byte[] b, int off, int len)
+                throws SignatureException {
+            if (data != null) {
+                data.write(b, off, len);
+                return;
+            }
+            byte[] out = cipher.update(b, off, len);
+            if ((out != null) && (out.length != 0)) {
+                throw new SignatureException
+                    ("Cipher unexpectedly returned data");
+            }
+        }
+
+        protected byte[] engineSign() throws SignatureException {
+            try {
+                return cipher.doFinal();
+            } catch (IllegalBlockSizeException e) {
+                throw new SignatureException("doFinal() failed", e);
+            } catch (BadPaddingException e) {
+                throw new SignatureException("doFinal() failed", e);
+            }
+        }
+
+        protected boolean engineVerify(byte[] sigBytes)
+                throws SignatureException {
+            try {
+                byte[] out = cipher.doFinal(sigBytes);
+                byte[] dataBytes = data.toByteArray();
+                data.reset();
+                return MessageDigest.isEqual(out, dataBytes);
+            } catch (BadPaddingException e) {
+                // e.g. wrong public key used
+                // return false rather than throwing exception
+                return false;
+            } catch (IllegalBlockSizeException e) {
+                throw new SignatureException("doFinal() failed", e);
+            }
+        }
+
+        protected void engineSetParameter(String param, Object value)
+                throws InvalidParameterException {
+            throw new InvalidParameterException("Parameters not supported");
+        }
+
+        protected Object engineGetParameter(String param)
+                throws InvalidParameterException {
+            throw new InvalidParameterException("Parameters not supported");
+        }
+
+    }
+
+}
diff --git a/java/security/SignatureException.java b/java/security/SignatureException.java
new file mode 100644
index 0000000..2e1fa59
--- /dev/null
+++ b/java/security/SignatureException.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 1996, 2013, 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 java.security;
+
+/**
+ * This is the generic Signature exception.
+ *
+ * @author Benjamin Renaud
+ */
+
+public class SignatureException extends GeneralSecurityException {
+
+    private static final long serialVersionUID = 7509989324975124438L;
+
+    /**
+     * Constructs a SignatureException with no detail message. A
+     * detail message is a String that describes this particular
+     * exception.
+     */
+    public SignatureException() {
+        super();
+    }
+
+    /**
+     * Constructs a SignatureException with the specified detail
+     * message.  A detail message is a String that describes this
+     * particular exception.
+     *
+     * @param msg the detail message.
+     */
+    public SignatureException(String msg) {
+        super(msg);
+    }
+
+    /**
+     * Creates a {@code SignatureException} with the specified
+     * detail message and cause.
+     *
+     * @param message the detail message (which is saved for later retrieval
+     *        by the {@link #getMessage()} method).
+     * @param cause the cause (which is saved for later retrieval by the
+     *        {@link #getCause()} method).  (A {@code null} value is permitted,
+     *        and indicates that the cause is nonexistent or unknown.)
+     * @since 1.5
+     */
+    public SignatureException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Creates a {@code SignatureException} with the specified cause
+     * and a detail message of {@code (cause==null ? null : cause.toString())}
+     * (which typically contains the class and detail message of
+     * {@code cause}).
+     *
+     * @param cause the cause (which is saved for later retrieval by the
+     *        {@link #getCause()} method).  (A {@code null} value is permitted,
+     *        and indicates that the cause is nonexistent or unknown.)
+     * @since 1.5
+     */
+    public SignatureException(Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/java/security/SignatureSpi.java b/java/security/SignatureSpi.java
new file mode 100644
index 0000000..86107a1
--- /dev/null
+++ b/java/security/SignatureSpi.java
@@ -0,0 +1,392 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1997, 2006, 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 java.security;
+
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.*;
+import java.io.*;
+
+import java.nio.ByteBuffer;
+
+import sun.security.jca.JCAUtil;
+
+/**
+ * This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
+ * for the {@code Signature} class, which is used to provide the
+ * functionality of a digital signature algorithm. Digital signatures are used
+ * for authentication and integrity assurance of digital data.
+ *.
+ * <p> All the abstract methods in this class must be implemented by each
+ * cryptographic service provider who wishes to supply the implementation
+ * of a particular signature algorithm.
+ *
+ * @author Benjamin Renaud
+ *
+ *
+ * @see Signature
+ */
+
+public abstract class SignatureSpi {
+
+    /**
+     * Application-specified source of randomness.
+     */
+    protected SecureRandom appRandom = null;
+
+    /**
+     * Initializes this signature object with the specified
+     * public key for verification operations.
+     *
+     * @param publicKey the public key of the identity whose signature is
+     * going to be verified.
+     *
+     * @exception InvalidKeyException if the key is improperly
+     * encoded, parameters are missing, and so on.
+     */
+    protected abstract void engineInitVerify(PublicKey publicKey)
+        throws InvalidKeyException;
+
+    /**
+     * Initializes this signature object with the specified
+     * private key for signing operations.
+     *
+     * @param privateKey the private key of the identity whose signature
+     * will be generated.
+     *
+     * @exception InvalidKeyException if the key is improperly
+     * encoded, parameters are missing, and so on.
+     */
+    protected abstract void engineInitSign(PrivateKey privateKey)
+        throws InvalidKeyException;
+
+    /**
+     * Initializes this signature object with the specified
+     * private key and source of randomness for signing operations.
+     *
+     * <p>This concrete method has been added to this previously-defined
+     * abstract class. (For backwards compatibility, it cannot be abstract.)
+     *
+     * @param privateKey the private key of the identity whose signature
+     * will be generated.
+     * @param random the source of randomness
+     *
+     * @exception InvalidKeyException if the key is improperly
+     * encoded, parameters are missing, and so on.
+     */
+    protected void engineInitSign(PrivateKey privateKey,
+                                  SecureRandom random)
+        throws InvalidKeyException {
+            this.appRandom = random;
+            engineInitSign(privateKey);
+    }
+
+    /**
+     * Updates the data to be signed or verified
+     * using the specified byte.
+     *
+     * @param b the byte to use for the update.
+     *
+     * @exception SignatureException if the engine is not initialized
+     * properly.
+     */
+    protected abstract void engineUpdate(byte b) throws SignatureException;
+
+    /**
+     * Updates the data to be signed or verified, using the
+     * specified array of bytes, starting at the specified offset.
+     *
+     * @param b the array of bytes
+     * @param off the offset to start from in the array of bytes
+     * @param len the number of bytes to use, starting at offset
+     *
+     * @exception SignatureException if the engine is not initialized
+     * properly
+     */
+    protected abstract void engineUpdate(byte[] b, int off, int len)
+        throws SignatureException;
+
+    /**
+     * Updates the data to be signed or verified using the specified
+     * ByteBuffer. Processes the {@code data.remaining()} bytes
+     * starting at at {@code data.position()}.
+     * Upon return, the buffer's position will be equal to its limit;
+     * its limit will not have changed.
+     *
+     * @param input the ByteBuffer
+     * @since 1.5
+     */
+    protected void engineUpdate(ByteBuffer input) {
+        if (input.hasRemaining() == false) {
+            return;
+        }
+        try {
+            if (input.hasArray()) {
+                byte[] b = input.array();
+                int ofs = input.arrayOffset();
+                int pos = input.position();
+                int lim = input.limit();
+                engineUpdate(b, ofs + pos, lim - pos);
+                input.position(lim);
+            } else {
+                int len = input.remaining();
+                byte[] b = new byte[JCAUtil.getTempArraySize(len)];
+                while (len > 0) {
+                    int chunk = Math.min(len, b.length);
+                    input.get(b, 0, chunk);
+                    engineUpdate(b, 0, chunk);
+                    len -= chunk;
+                }
+            }
+        } catch (SignatureException e) {
+            // is specified to only occur when the engine is not initialized
+            // this case should never occur as it is caught in Signature.java
+            throw new ProviderException("update() failed", e);
+        }
+    }
+
+    /**
+     * Returns the signature bytes of all the data
+     * updated so far.
+     * The format of the signature depends on the underlying
+     * signature scheme.
+     *
+     * @return the signature bytes of the signing operation's result.
+     *
+     * @exception SignatureException if the engine is not
+     * initialized properly or if this signature algorithm is unable to
+     * process the input data provided.
+     */
+    protected abstract byte[] engineSign() throws SignatureException;
+
+    /**
+     * Finishes this signature operation and stores the resulting signature
+     * bytes in the provided buffer {@code outbuf}, starting at
+     * {@code offset}.
+     * The format of the signature depends on the underlying
+     * signature scheme.
+     *
+     * <p>The signature implementation is reset to its initial state
+     * (the state it was in after a call to one of the
+     * {@code engineInitSign} methods)
+     * and can be reused to generate further signatures with the same private
+     * key.
+     *
+     * This method should be abstract, but we leave it concrete for
+     * binary compatibility.  Knowledgeable providers should override this
+     * method.
+     *
+     * @param outbuf buffer for the signature result.
+     *
+     * @param offset offset into {@code outbuf} where the signature is
+     * stored.
+     *
+     * @param len number of bytes within {@code outbuf} allotted for the
+     * signature.
+     * Both this default implementation and the SUN provider do not
+     * return partial digests. If the value of this parameter is less
+     * than the actual signature length, this method will throw a
+     * SignatureException.
+     * This parameter is ignored if its value is greater than or equal to
+     * the actual signature length.
+     *
+     * @return the number of bytes placed into {@code outbuf}
+     *
+     * @exception SignatureException if the engine is not
+     * initialized properly, if this signature algorithm is unable to
+     * process the input data provided, or if {@code len} is less
+     * than the actual signature length.
+     *
+     * @since 1.2
+     */
+    protected int engineSign(byte[] outbuf, int offset, int len)
+                        throws SignatureException {
+        byte[] sig = engineSign();
+        if (len < sig.length) {
+                throw new SignatureException
+                    ("partial signatures not returned");
+        }
+        if (outbuf.length - offset < sig.length) {
+                throw new SignatureException
+                    ("insufficient space in the output buffer to store the "
+                     + "signature");
+        }
+        System.arraycopy(sig, 0, outbuf, offset, sig.length);
+        return sig.length;
+    }
+
+    /**
+     * Verifies the passed-in signature.
+     *
+     * @param sigBytes the signature bytes to be verified.
+     *
+     * @return true if the signature was verified, false if not.
+     *
+     * @exception SignatureException if the engine is not
+     * initialized properly, the passed-in signature is improperly
+     * encoded or of the wrong type, if this signature algorithm is unable to
+     * process the input data provided, etc.
+     */
+    protected abstract boolean engineVerify(byte[] sigBytes)
+        throws SignatureException;
+
+    /**
+     * Verifies the passed-in signature in the specified array
+     * of bytes, starting at the specified offset.
+     *
+     * <p> Note: Subclasses should overwrite the default implementation.
+     *
+     *
+     * @param sigBytes the signature bytes to be verified.
+     * @param offset the offset to start from in the array of bytes.
+     * @param length the number of bytes to use, starting at offset.
+     *
+     * @return true if the signature was verified, false if not.
+     *
+     * @exception SignatureException if the engine is not
+     * initialized properly, the passed-in signature is improperly
+     * encoded or of the wrong type, if this signature algorithm is unable to
+     * process the input data provided, etc.
+     * @since 1.4
+     */
+    protected boolean engineVerify(byte[] sigBytes, int offset, int length)
+        throws SignatureException {
+        byte[] sigBytesCopy = new byte[length];
+        System.arraycopy(sigBytes, offset, sigBytesCopy, 0, length);
+        return engineVerify(sigBytesCopy);
+    }
+
+    /**
+     * Sets the specified algorithm parameter to the specified
+     * value. This method supplies a general-purpose mechanism through
+     * which it is possible to set the various parameters of this object.
+     * A parameter may be any settable parameter for the algorithm, such as
+     * a parameter size, or a source of random bits for signature generation
+     * (if appropriate), or an indication of whether or not to perform
+     * a specific but optional computation. A uniform algorithm-specific
+     * naming scheme for each parameter is desirable but left unspecified
+     * at this time.
+     *
+     * @param param the string identifier of the parameter.
+     *
+     * @param value the parameter value.
+     *
+     * @exception InvalidParameterException if {@code param} is an
+     * invalid parameter for this signature algorithm engine,
+     * the parameter is already set
+     * and cannot be set again, a security exception occurs, and so on.
+     *
+     * @deprecated Replaced by {@link
+     * #engineSetParameter(java.security.spec.AlgorithmParameterSpec)
+     * engineSetParameter}.
+     */
+    @Deprecated
+    protected abstract void engineSetParameter(String param, Object value)
+        throws InvalidParameterException;
+
+    /**
+     * <p>This method is overridden by providers to initialize
+     * this signature engine with the specified parameter set.
+     *
+     * @param params the parameters
+     *
+     * @exception UnsupportedOperationException if this method is not
+     * overridden by a provider
+     *
+     * @exception InvalidAlgorithmParameterException if this method is
+     * overridden by a provider and the given parameters
+     * are inappropriate for this signature engine
+     */
+    protected void engineSetParameter(AlgorithmParameterSpec params)
+        throws InvalidAlgorithmParameterException {
+            throw new UnsupportedOperationException();
+    }
+
+    /**
+     * <p>This method is overridden by providers to return the
+     * parameters used with this signature engine, or null
+     * if this signature engine does not use any parameters.
+     *
+     * <p>The returned parameters may be the same that were used to initialize
+     * this signature engine, or may contain a combination of default and
+     * randomly generated parameter values used by the underlying signature
+     * implementation if this signature engine requires algorithm parameters
+     * but was not initialized with any.
+     *
+     * @return the parameters used with this signature engine, or null if this
+     * signature engine does not use any parameters
+     *
+     * @exception UnsupportedOperationException if this method is
+     * not overridden by a provider
+     * @since 1.4
+     */
+    protected AlgorithmParameters engineGetParameters() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Gets the value of the specified algorithm parameter.
+     * This method supplies a general-purpose mechanism through which it
+     * is possible to get the various parameters of this object. A parameter
+     * may be any settable parameter for the algorithm, such as a parameter
+     * size, or  a source of random bits for signature generation (if
+     * appropriate), or an indication of whether or not to perform a
+     * specific but optional computation. A uniform algorithm-specific
+     * naming scheme for each parameter is desirable but left unspecified
+     * at this time.
+     *
+     * @param param the string name of the parameter.
+     *
+     * @return the object that represents the parameter value, or null if
+     * there is none.
+     *
+     * @exception InvalidParameterException if {@code param} is an
+     * invalid parameter for this engine, or another exception occurs while
+     * trying to get this parameter.
+     *
+     * @deprecated Deprecated.
+     */
+    @Deprecated
+    // Android-changed add "Deprecated."
+    protected abstract Object engineGetParameter(String param)
+        throws InvalidParameterException;
+
+    /**
+     * Returns a clone if the implementation is cloneable.
+     *
+     * @return a clone if the implementation is cloneable.
+     *
+     * @exception CloneNotSupportedException if this is called
+     * on an implementation that does not support {@code Cloneable}.
+     */
+    public Object clone() throws CloneNotSupportedException {
+        if (this instanceof Cloneable) {
+            return super.clone();
+        } else {
+            throw new CloneNotSupportedException();
+        }
+    }
+}
diff --git a/java/security/SignedObject.java b/java/security/SignedObject.java
new file mode 100644
index 0000000..9ac864e
--- /dev/null
+++ b/java/security/SignedObject.java
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security;
+
+import java.io.*;
+
+/**
+ * <p> SignedObject is a class for the purpose of creating authentic
+ * runtime objects whose integrity cannot be compromised without being
+ * detected.
+ *
+ * <p> More specifically, a SignedObject contains another Serializable
+ * object, the (to-be-)signed object and its signature.
+ *
+ * <p> The signed object is a "deep copy" (in serialized form) of an
+ * original object.  Once the copy is made, further manipulation of
+ * the original object has no side effect on the copy.
+ *
+ * <p> The underlying signing algorithm is designated by the Signature
+ * object passed to the constructor and the {@code verify} method.
+ * A typical usage for signing is the following:
+ *
+ * <pre>{@code
+ * Signature signingEngine = Signature.getInstance(algorithm,
+ *                                                 provider);
+ * SignedObject so = new SignedObject(myobject, signingKey,
+ *                                    signingEngine);
+ * }</pre>
+ *
+ * <p> A typical usage for verification is the following (having
+ * received SignedObject {@code so}):
+ *
+ * <pre>{@code
+ * Signature verificationEngine =
+ *     Signature.getInstance(algorithm, provider);
+ * if (so.verify(publickey, verificationEngine))
+ *     try {
+ *         Object myobj = so.getObject();
+ *     } catch (java.lang.ClassNotFoundException e) {};
+ * }</pre>
+ *
+ * <p> Several points are worth noting.  First, there is no need to
+ * initialize the signing or verification engine, as it will be
+ * re-initialized inside the constructor and the {@code verify}
+ * method. Secondly, for verification to succeed, the specified
+ * public key must be the public key corresponding to the private key
+ * used to generate the SignedObject.
+ *
+ * <p> More importantly, for flexibility reasons, the
+ * constructor and {@code verify} method allow for
+ * customized signature engines, which can implement signature
+ * algorithms that are not installed formally as part of a crypto
+ * provider.  However, it is crucial that the programmer writing the
+ * verifier code be aware what {@code Signature} engine is being
+ * used, as its own implementation of the {@code verify} method
+ * is invoked to verify a signature.  In other words, a malicious
+ * {@code Signature} may choose to always return true on
+ * verification in an attempt to bypass a security check.
+ *
+ * <p> The signature algorithm can be, among others, the NIST standard
+ * DSA, using DSA and SHA-1.  The algorithm is specified using the
+ * same convention as that for signatures. The DSA algorithm using the
+ * SHA-1 message digest algorithm can be specified, for example, as
+ * "SHA/DSA" or "SHA-1/DSA" (they are equivalent).  In the case of
+ * RSA, there are multiple choices for the message digest algorithm,
+ * so the signing algorithm could be specified as, for example,
+ * "MD2/RSA", "MD5/RSA" or "SHA-1/RSA".  The algorithm name must be
+ * specified, as there is no default.
+ *
+ * <p> The name of the Cryptography Package Provider is designated
+ * also by the Signature parameter to the constructor and the
+ * {@code verify} method.  If the provider is not
+ * specified, the default provider is used.  Each installation can
+ * be configured to use a particular provider as default.
+ *
+ * <p> Potential applications of SignedObject include:
+ * <ul>
+ * <li> It can be used
+ * internally to any Java runtime as an unforgeable authorization
+ * token -- one that can be passed around without the fear that the
+ * token can be maliciously modified without being detected.
+ * <li> It
+ * can be used to sign and serialize data/object for storage outside
+ * the Java runtime (e.g., storing critical access control data on
+ * disk).
+ * <li> Nested SignedObjects can be used to construct a logical
+ * sequence of signatures, resembling a chain of authorization and
+ * delegation.
+ * </ul>
+ *
+ * @see Signature
+ *
+ * @author Li Gong
+ */
+
+public final class SignedObject implements Serializable {
+
+    private static final long serialVersionUID = 720502720485447167L;
+
+    /*
+     * The original content is "deep copied" in its serialized format
+     * and stored in a byte array.  The signature field is also in the
+     * form of byte array.
+     */
+
+    private byte[] content;
+    private byte[] signature;
+    private String thealgorithm;
+
+    /**
+     * Constructs a SignedObject from any Serializable object.
+     * The given object is signed with the given signing key, using the
+     * designated signature engine.
+     *
+     * @param object the object to be signed.
+     * @param signingKey the private key for signing.
+     * @param signingEngine the signature signing engine.
+     *
+     * @exception IOException if an error occurs during serialization
+     * @exception InvalidKeyException if the key is invalid.
+     * @exception SignatureException if signing fails.
+     */
+    public SignedObject(Serializable object, PrivateKey signingKey,
+                        Signature signingEngine)
+        throws IOException, InvalidKeyException, SignatureException {
+            // creating a stream pipe-line, from a to b
+            ByteArrayOutputStream b = new ByteArrayOutputStream();
+            ObjectOutput a = new ObjectOutputStream(b);
+
+            // write and flush the object content to byte array
+            a.writeObject(object);
+            a.flush();
+            a.close();
+            this.content = b.toByteArray();
+            b.close();
+
+            // now sign the encapsulated object
+            this.sign(signingKey, signingEngine);
+    }
+
+    /**
+     * Retrieves the encapsulated object.
+     * The encapsulated object is de-serialized before it is returned.
+     *
+     * @return the encapsulated object.
+     *
+     * @exception IOException if an error occurs during de-serialization
+     * @exception ClassNotFoundException if an error occurs during
+     * de-serialization
+     */
+    public Object getObject()
+        throws IOException, ClassNotFoundException
+    {
+        // creating a stream pipe-line, from b to a
+        ByteArrayInputStream b = new ByteArrayInputStream(this.content);
+        ObjectInput a = new ObjectInputStream(b);
+        Object obj = a.readObject();
+        b.close();
+        a.close();
+        return obj;
+    }
+
+    /**
+     * Retrieves the signature on the signed object, in the form of a
+     * byte array.
+     *
+     * @return the signature. Returns a new array each time this
+     * method is called.
+     */
+    public byte[] getSignature() {
+        return this.signature.clone();
+    }
+
+    /**
+     * Retrieves the name of the signature algorithm.
+     *
+     * @return the signature algorithm name.
+     */
+    public String getAlgorithm() {
+        return this.thealgorithm;
+    }
+
+    /**
+     * Verifies that the signature in this SignedObject is the valid
+     * signature for the object stored inside, with the given
+     * verification key, using the designated verification engine.
+     *
+     * @param verificationKey the public key for verification.
+     * @param verificationEngine the signature verification engine.
+     *
+     * @exception SignatureException if signature verification failed.
+     * @exception InvalidKeyException if the verification key is invalid.
+     *
+     * @return {@code true} if the signature
+     * is valid, {@code false} otherwise
+     */
+    public boolean verify(PublicKey verificationKey,
+                          Signature verificationEngine)
+         throws InvalidKeyException, SignatureException {
+             verificationEngine.initVerify(verificationKey);
+             verificationEngine.update(this.content.clone());
+             return verificationEngine.verify(this.signature.clone());
+    }
+
+    /*
+     * Signs the encapsulated object with the given signing key, using the
+     * designated signature engine.
+     *
+     * @param signingKey the private key for signing.
+     * @param signingEngine the signature signing engine.
+     *
+     * @exception InvalidKeyException if the key is invalid.
+     * @exception SignatureException if signing fails.
+     */
+    private void sign(PrivateKey signingKey, Signature signingEngine)
+        throws InvalidKeyException, SignatureException {
+            // initialize the signing engine
+            signingEngine.initSign(signingKey);
+            signingEngine.update(this.content.clone());
+            this.signature = signingEngine.sign().clone();
+            this.thealgorithm = signingEngine.getAlgorithm();
+    }
+
+    /**
+     * readObject is called to restore the state of the SignedObject from
+     * a stream.
+     */
+    private void readObject(java.io.ObjectInputStream s)
+        throws java.io.IOException, ClassNotFoundException {
+            java.io.ObjectInputStream.GetField fields = s.readFields();
+            content = ((byte[])fields.get("content", null)).clone();
+            signature = ((byte[])fields.get("signature", null)).clone();
+            thealgorithm = (String)fields.get("thealgorithm", null);
+    }
+}
diff --git a/java/security/Signer.java b/java/security/Signer.java
new file mode 100644
index 0000000..077538d
--- /dev/null
+++ b/java/security/Signer.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 1996, 2013, 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 java.security;
+
+import java.io.*;
+
+/**
+ * This class is used to represent an Identity that can also digitally
+ * sign data.
+ *
+ * <p>The management of a signer's private keys is an important and
+ * sensitive issue that should be handled by subclasses as appropriate
+ * to their intended use.
+ *
+ * @see Identity
+ *
+ * @author Benjamin Renaud
+ *
+ * @deprecated This class is no longer used. Its functionality has been
+ * replaced by {@code java.security.KeyStore}, the
+ * {@code java.security.cert} package, and
+ * {@code java.security.Principal}.
+ */
+@Deprecated
+public abstract class Signer extends Identity {
+
+    private static final long serialVersionUID = -1763464102261361480L;
+
+    /**
+     * The signer's private key.
+     *
+     * @serial
+     */
+    private PrivateKey privateKey;
+
+    /**
+     * Creates a signer. This constructor should only be used for
+     * serialization.
+     */
+    protected Signer() {
+        super();
+    }
+
+
+    /**
+     * Creates a signer with the specified identity name.
+     *
+     * @param name the identity name.
+     */
+    public Signer(String name) {
+        super(name);
+    }
+
+    /**
+     * Creates a signer with the specified identity name and scope.
+     *
+     * @param name the identity name.
+     *
+     * @param scope the scope of the identity.
+     *
+     * @exception KeyManagementException if there is already an identity
+     * with the same name in the scope.
+     */
+    public Signer(String name, IdentityScope scope)
+    throws KeyManagementException {
+        super(name, scope);
+    }
+
+    /**
+     * Returns this signer's private key.
+     *
+     * <p>First, if there is a security manager, its {@code checkSecurityAccess}
+     * method is called with {@code "getSignerPrivateKey"}
+     * as its argument to see if it's ok to return the private key.
+     *
+     * @return this signer's private key, or null if the private key has
+     * not yet been set.
+     *
+     * @exception  SecurityException  if a security manager exists and its
+     * {@code checkSecurityAccess} method doesn't allow
+     * returning the private key.
+     *
+     * @see SecurityManager#checkSecurityAccess
+     */
+    public PrivateKey getPrivateKey() {
+        check("getSignerPrivateKey");
+        return privateKey;
+    }
+
+   /**
+     * Sets the key pair (public key and private key) for this signer.
+     *
+     * <p>First, if there is a security manager, its {@code checkSecurityAccess}
+     * method is called with {@code "setSignerKeyPair"}
+     * as its argument to see if it's ok to set the key pair.
+     *
+     * @param pair an initialized key pair.
+     *
+     * @exception InvalidParameterException if the key pair is not
+     * properly initialized.
+     * @exception KeyException if the key pair cannot be set for any
+     * other reason.
+     * @exception  SecurityException  if a security manager exists and its
+     * {@code checkSecurityAccess} method doesn't allow
+     * setting the key pair.
+     *
+     * @see SecurityManager#checkSecurityAccess
+     */
+    public final void setKeyPair(KeyPair pair)
+    throws InvalidParameterException, KeyException {
+        check("setSignerKeyPair");
+        final PublicKey pub = pair.getPublic();
+        PrivateKey priv = pair.getPrivate();
+
+        if (pub == null || priv == null) {
+            throw new InvalidParameterException();
+        }
+        try {
+            AccessController.doPrivileged(
+                new PrivilegedExceptionAction<Void>() {
+                public Void run() throws KeyManagementException {
+                    setPublicKey(pub);
+                    return null;
+                }
+            });
+        } catch (PrivilegedActionException pae) {
+            throw (KeyManagementException) pae.getException();
+        }
+        privateKey = priv;
+    }
+
+    String printKeys() {
+        String keys = "";
+        PublicKey publicKey = getPublicKey();
+        if (publicKey != null && privateKey != null) {
+            keys = "\tpublic and private keys initialized";
+
+        } else {
+            keys = "\tno keys";
+        }
+        return keys;
+    }
+
+    /**
+     * Returns a string of information about the signer.
+     *
+     * @return a string of information about the signer.
+     */
+    public String toString() {
+        return "[Signer]" + super.toString();
+    }
+
+    private static void check(String directive) {
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkSecurityAccess(directive);
+        }
+    }
+
+}
diff --git a/java/security/Timestamp.java b/java/security/Timestamp.java
new file mode 100644
index 0000000..f66d288
--- /dev/null
+++ b/java/security/Timestamp.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2003, 2011, 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 java.security;
+
+import java.io.*;
+import java.security.cert.Certificate;
+import java.security.cert.CertPath;
+import java.security.cert.X509Extension;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * This class encapsulates information about a signed timestamp.
+ * It is immutable.
+ * It includes the timestamp's date and time as well as information about the
+ * Timestamping Authority (TSA) which generated and signed the timestamp.
+ *
+ * @since 1.5
+ * @author Vincent Ryan
+ */
+
+public final class Timestamp implements Serializable {
+
+    private static final long serialVersionUID = -5502683707821851294L;
+
+    /**
+     * The timestamp's date and time
+     *
+     * @serial
+     */
+    private Date timestamp;
+
+    /**
+     * The TSA's certificate path.
+     *
+     * @serial
+     */
+    private CertPath signerCertPath;
+
+    /*
+     * Hash code for this timestamp.
+     */
+    private transient int myhash = -1;
+
+    /**
+     * Constructs a Timestamp.
+     *
+     * @param timestamp is the timestamp's date and time. It must not be null.
+     * @param signerCertPath is the TSA's certificate path. It must not be null.
+     * @throws NullPointerException if timestamp or signerCertPath is null.
+     */
+    public Timestamp(Date timestamp, CertPath signerCertPath) {
+        if (timestamp == null || signerCertPath == null) {
+            throw new NullPointerException();
+        }
+        this.timestamp = new Date(timestamp.getTime()); // clone
+        this.signerCertPath = signerCertPath;
+    }
+
+    /**
+     * Returns the date and time when the timestamp was generated.
+     *
+     * @return The timestamp's date and time.
+     */
+    public Date getTimestamp() {
+        return new Date(timestamp.getTime()); // clone
+    }
+
+    /**
+     * Returns the certificate path for the Timestamping Authority.
+     *
+     * @return The TSA's certificate path.
+     */
+    public CertPath getSignerCertPath() {
+        return signerCertPath;
+    }
+
+    /**
+     * Returns the hash code value for this timestamp.
+     * The hash code is generated using the date and time of the timestamp
+     * and the TSA's certificate path.
+     *
+     * @return a hash code value for this timestamp.
+     */
+    public int hashCode() {
+        if (myhash == -1) {
+            myhash = timestamp.hashCode() + signerCertPath.hashCode();
+        }
+        return myhash;
+    }
+
+    /**
+     * Tests for equality between the specified object and this
+     * timestamp. Two timestamps are considered equal if the date and time of
+     * their timestamp's and their signer's certificate paths are equal.
+     *
+     * @param obj the object to test for equality with this timestamp.
+     *
+     * @return true if the timestamp are considered equal, false otherwise.
+     */
+    public boolean equals(Object obj) {
+        if (obj == null || (!(obj instanceof Timestamp))) {
+            return false;
+        }
+        Timestamp that = (Timestamp)obj;
+
+        if (this == that) {
+            return true;
+        }
+        return (timestamp.equals(that.getTimestamp()) &&
+            signerCertPath.equals(that.getSignerCertPath()));
+    }
+
+    /**
+     * Returns a string describing this timestamp.
+     *
+     * @return A string comprising the date and time of the timestamp and
+     *         its signer's certificate.
+     */
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append("(");
+        sb.append("timestamp: " + timestamp);
+        List<? extends Certificate> certs = signerCertPath.getCertificates();
+        if (!certs.isEmpty()) {
+            sb.append("TSA: " + certs.get(0));
+        } else {
+            sb.append("TSA: <empty>");
+        }
+        sb.append(")");
+        return sb.toString();
+    }
+
+    // Explicitly reset hash code value to -1
+    private void readObject(ObjectInputStream ois)
+        throws IOException, ClassNotFoundException {
+        ois.defaultReadObject();
+        myhash = -1;
+        timestamp = new Date(timestamp.getTime());
+    }
+}
diff --git a/java/security/UnrecoverableEntryException.java b/java/security/UnrecoverableEntryException.java
new file mode 100644
index 0000000..0314e3d
--- /dev/null
+++ b/java/security/UnrecoverableEntryException.java
@@ -0,0 +1,56 @@
+/*
+ * 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.  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 java.security;
+
+/**
+ * This exception is thrown if an entry in the keystore cannot be recovered.
+ *
+ *
+ * @since 1.5
+ */
+
+public class UnrecoverableEntryException extends GeneralSecurityException {
+
+    private static final long serialVersionUID = -4527142945246286535L;
+
+    /**
+     * Constructs an UnrecoverableEntryException with no detail message.
+     */
+    public UnrecoverableEntryException() {
+        super();
+    }
+
+    /**
+     * Constructs an UnrecoverableEntryException with the specified detail
+     * message, which provides more information about why this exception
+     * has been thrown.
+     *
+     * @param msg the detail message.
+     */
+   public UnrecoverableEntryException(String msg) {
+       super(msg);
+    }
+}
diff --git a/java/security/UnrecoverableKeyException.java b/java/security/UnrecoverableKeyException.java
new file mode 100644
index 0000000..09fcc6e
--- /dev/null
+++ b/java/security/UnrecoverableKeyException.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1997, 2005, 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 java.security;
+
+/**
+ * This exception is thrown if a key in the keystore cannot be recovered.
+ *
+ *
+ * @since 1.2
+ */
+
+public class UnrecoverableKeyException extends UnrecoverableEntryException {
+
+    private static final long serialVersionUID = 7275063078190151277L;
+
+    /**
+     * Constructs an UnrecoverableKeyException with no detail message.
+     */
+    public UnrecoverableKeyException() {
+        super();
+    }
+
+    /**
+     * Constructs an UnrecoverableKeyException with the specified detail
+     * message, which provides more information about why this exception
+     * has been thrown.
+     *
+     * @param msg the detail message.
+     */
+   public UnrecoverableKeyException(String msg) {
+       super(msg);
+    }
+}
diff --git a/java/security/UnresolvedPermission.java b/java/security/UnresolvedPermission.java
new file mode 100644
index 0000000..6f3bf4a
--- /dev/null
+++ b/java/security/UnresolvedPermission.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security;
+
+import java.io.IOException;
+import java.io.ByteArrayInputStream;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+import java.lang.reflect.*;
+import java.security.cert.*;
+
+// Android-changed: Stubbed the implementation.  Android doesn't support SecurityManager.
+// See comments in java.lang.SecurityManager for details.
+/**
+ * Legacy security code; do not use.
+ */
+
+public final class UnresolvedPermission extends Permission
+implements java.io.Serializable
+{
+
+    public UnresolvedPermission(String type,
+                                String name,
+                                String actions,
+                                java.security.cert.Certificate certs[]) { super(""); }
+
+    public boolean implies(Permission p) { return false; }
+
+    public String getActions() { return null; }
+
+    public String getUnresolvedType() { return null; }
+
+    public String getUnresolvedName() { return null; }
+
+    public String getUnresolvedActions() { return null; }
+
+    public java.security.cert.Certificate[] getUnresolvedCerts() { return null; }
+}
diff --git a/java/security/UnresolvedPermissionCollection.java b/java/security/UnresolvedPermissionCollection.java
new file mode 100644
index 0000000..7633648
--- /dev/null
+++ b/java/security/UnresolvedPermissionCollection.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 1997, 2011, 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 java.security;
+
+import java.util.*;
+import java.io.ObjectStreamField;
+import java.io.ObjectOutputStream;
+import java.io.ObjectInputStream;
+import java.io.IOException;
+
+/**
+ * A UnresolvedPermissionCollection stores a collection
+ * of UnresolvedPermission permissions.
+ *
+ * @see java.security.Permission
+ * @see java.security.Permissions
+ * @see java.security.UnresolvedPermission
+ *
+ *
+ * @author Roland Schemers
+ *
+ * @serial include
+ */
+
+final class UnresolvedPermissionCollection
+extends PermissionCollection
+implements java.io.Serializable
+{
+    /**
+     * Key is permission type, value is a list of the UnresolvedPermissions
+     * of the same type.
+     * Not serialized; see serialization section at end of class.
+     */
+    private transient Map<String, List<UnresolvedPermission>> perms;
+
+    /**
+     * Create an empty UnresolvedPermissionCollection object.
+     *
+     */
+    public UnresolvedPermissionCollection() {
+        perms = new HashMap<String, List<UnresolvedPermission>>(11);
+    }
+
+    /**
+     * Adds a permission to this UnresolvedPermissionCollection.
+     * The key for the hash is the unresolved permission's type (class) name.
+     *
+     * @param permission the Permission object to add.
+     */
+
+    public void add(Permission permission)
+    {
+        if (! (permission instanceof UnresolvedPermission))
+            throw new IllegalArgumentException("invalid permission: "+
+                                               permission);
+        UnresolvedPermission up = (UnresolvedPermission) permission;
+
+        List<UnresolvedPermission> v;
+        synchronized (this) {
+            v = perms.get(up.getName());
+            if (v == null) {
+                v = new ArrayList<UnresolvedPermission>();
+                perms.put(up.getName(), v);
+            }
+        }
+        synchronized (v) {
+            v.add(up);
+        }
+    }
+
+    /**
+     * get any unresolved permissions of the same type as p,
+     * and return the List containing them.
+     */
+    List<UnresolvedPermission> getUnresolvedPermissions(Permission p) {
+        synchronized (this) {
+            return perms.get(p.getClass().getName());
+        }
+    }
+
+    /**
+     * always returns false for unresolved permissions
+     *
+     */
+    public boolean implies(Permission permission)
+    {
+        return false;
+    }
+
+    /**
+     * Returns an enumeration of all the UnresolvedPermission lists in the
+     * container.
+     *
+     * @return an enumeration of all the UnresolvedPermission objects.
+     */
+
+    public Enumeration<Permission> elements() {
+        List<Permission> results =
+            new ArrayList<>(); // where results are stored
+
+        // Get iterator of Map values (which are lists of permissions)
+        synchronized (this) {
+            for (List<UnresolvedPermission> l : perms.values()) {
+                synchronized (l) {
+                    results.addAll(l);
+                }
+            }
+        }
+
+        return Collections.enumeration(results);
+    }
+
+    private static final long serialVersionUID = -7176153071733132400L;
+
+    // Need to maintain serialization interoperability with earlier releases,
+    // which had the serializable field:
+    // private Hashtable permissions; // keyed on type
+
+    /**
+     * @serialField permissions java.util.Hashtable
+     *     A table of the UnresolvedPermissions keyed on type, value is Vector
+     *     of permissions
+     */
+    private static final ObjectStreamField[] serialPersistentFields = {
+        new ObjectStreamField("permissions", Hashtable.class),
+    };
+
+    /**
+     * @serialData Default field.
+     */
+    /*
+     * Writes the contents of the perms field out as a Hashtable
+     * in which the values are Vectors for
+     * serialization compatibility with earlier releases.
+     */
+    private void writeObject(ObjectOutputStream out) throws IOException {
+        // Don't call out.defaultWriteObject()
+
+        // Copy perms into a Hashtable
+        Hashtable<String, Vector<UnresolvedPermission>> permissions =
+            new Hashtable<>(perms.size()*2);
+
+        // Convert each entry (List) into a Vector
+        synchronized (this) {
+            Set<Map.Entry<String, List<UnresolvedPermission>>> set = perms.entrySet();
+            for (Map.Entry<String, List<UnresolvedPermission>> e : set) {
+                // Convert list into Vector
+                List<UnresolvedPermission> list = e.getValue();
+                Vector<UnresolvedPermission> vec = new Vector<>(list.size());
+                synchronized (list) {
+                    vec.addAll(list);
+                }
+
+                // Add to Hashtable being serialized
+                permissions.put(e.getKey(), vec);
+            }
+        }
+
+        // Write out serializable fields
+        ObjectOutputStream.PutField pfields = out.putFields();
+        pfields.put("permissions", permissions);
+        out.writeFields();
+    }
+
+    /*
+     * Reads in a Hashtable in which the values are Vectors of
+     * UnresolvedPermissions and saves them in the perms field.
+     */
+    private void readObject(ObjectInputStream in) throws IOException,
+    ClassNotFoundException {
+        // Don't call defaultReadObject()
+
+        // Read in serialized fields
+        ObjectInputStream.GetField gfields = in.readFields();
+
+        // Get permissions
+        @SuppressWarnings("unchecked")
+        // writeObject writes a Hashtable<String, Vector<UnresolvedPermission>>
+        // for the permissions key, so this cast is safe, unless the data is corrupt.
+        Hashtable<String, Vector<UnresolvedPermission>> permissions =
+                (Hashtable<String, Vector<UnresolvedPermission>>)
+                gfields.get("permissions", null);
+        perms = new HashMap<String, List<UnresolvedPermission>>(permissions.size()*2);
+
+        // Convert each entry (Vector) into a List
+        Set<Map.Entry<String, Vector<UnresolvedPermission>>> set = permissions.entrySet();
+        for (Map.Entry<String, Vector<UnresolvedPermission>> e : set) {
+            // Convert Vector into ArrayList
+            Vector<UnresolvedPermission> vec = e.getValue();
+            List<UnresolvedPermission> list = new ArrayList<>(vec.size());
+            list.addAll(vec);
+
+            // Add to Hashtable being serialized
+            perms.put(e.getKey(), list);
+        }
+    }
+}
diff --git a/java/security/acl/Acl.java b/java/security/acl/Acl.java
new file mode 100644
index 0000000..b9cf004
--- /dev/null
+++ b/java/security/acl/Acl.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 1996, 2013, 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 java.security.acl;
+
+import java.util.Enumeration;
+import java.security.Principal;
+
+/**
+ * Interface representing an Access Control List (ACL).  An Access
+ * Control List is a data structure used to guard access to
+ * resources.<p>
+ *
+ * An ACL can be thought of as a data structure with multiple ACL
+ * entries.  Each ACL entry, of interface type AclEntry, contains a
+ * set of permissions associated with a particular principal. (A
+ * principal represents an entity such as an individual user or a
+ * group). Additionally, each ACL entry is specified as being either
+ * positive or negative. If positive, the permissions are to be
+ * granted to the associated principal. If negative, the permissions
+ * are to be denied.<p>
+ *
+ * The ACL Entries in each ACL observe the following rules:
+ *
+ * <ul> <li>Each principal can have at most one positive ACL entry and
+ * one negative entry; that is, multiple positive or negative ACL
+ * entries are not allowed for any principal.  Each entry specifies
+ * the set of permissions that are to be granted (if positive) or
+ * denied (if negative).
+ *
+ * <li>If there is no entry for a particular principal, then the
+ * principal is considered to have a null (empty) permission set.
+ *
+ * <li>If there is a positive entry that grants a principal a
+ * particular permission, and a negative entry that denies the
+ * principal the same permission, the result is as though the
+ * permission was never granted or denied.
+ *
+ * <li>Individual permissions always override permissions of the
+ * group(s) to which the individual belongs. That is, individual
+ * negative permissions (specific denial of permissions) override the
+ * groups' positive permissions. And individual positive permissions
+ * override the groups' negative permissions.
+ *
+ * </ul>
+ *
+ * The {@code  java.security.acl } package provides the
+ * interfaces to the ACL and related data structures (ACL entries,
+ * groups, permissions, etc.), and the {@code  sun.security.acl }
+ * classes provide a default implementation of the interfaces. For
+ * example, {@code  java.security.acl.Acl } provides the
+ * interface to an ACL and the {@code  sun.security.acl.AclImpl }
+ * class provides the default implementation of the interface.<p>
+ *
+ * The {@code  java.security.acl.Acl } interface extends the
+ * {@code  java.security.acl.Owner } interface. The Owner
+ * interface is used to maintain a list of owners for each ACL.  Only
+ * owners are allowed to modify an ACL. For example, only an owner can
+ * call the ACL's {@code addEntry} method to add a new ACL entry
+ * to the ACL.
+ *
+ * @see java.security.acl.AclEntry
+ * @see java.security.acl.Owner
+ * @see java.security.acl.Acl#getPermissions
+ *
+ * @author Satish Dharmaraj
+ */
+
+public interface Acl extends Owner {
+
+    /**
+     * Sets the name of this ACL.
+     *
+     * @param caller the principal invoking this method. It must be an
+     * owner of this ACL.
+     *
+     * @param name the name to be given to this ACL.
+     *
+     * @exception NotOwnerException if the caller principal
+     * is not an owner of this ACL.
+     *
+     * @see #getName
+     */
+    public void setName(Principal caller, String name)
+      throws NotOwnerException;
+
+    /**
+     * Returns the name of this ACL.
+     *
+     * @return the name of this ACL.
+     *
+     * @see #setName
+     */
+    public String getName();
+
+    /**
+     * Adds an ACL entry to this ACL. An entry associates a principal
+     * (e.g., an individual or a group) with a set of
+     * permissions. Each principal can have at most one positive ACL
+     * entry (specifying permissions to be granted to the principal)
+     * and one negative ACL entry (specifying permissions to be
+     * denied). If there is already an ACL entry of the same type
+     * (negative or positive) already in the ACL, false is returned.
+     *
+     * @param caller the principal invoking this method. It must be an
+     * owner of this ACL.
+     *
+     * @param entry the ACL entry to be added to this ACL.
+     *
+     * @return true on success, false if an entry of the same type
+     * (positive or negative) for the same principal is already
+     * present in this ACL.
+     *
+     * @exception NotOwnerException if the caller principal
+     *  is not an owner of this ACL.
+     */
+    public boolean addEntry(Principal caller, AclEntry entry)
+      throws NotOwnerException;
+
+    /**
+     * Removes an ACL entry from this ACL.
+     *
+     * @param caller the principal invoking this method. It must be an
+     * owner of this ACL.
+     *
+     * @param entry the ACL entry to be removed from this ACL.
+     *
+     * @return true on success, false if the entry is not part of this ACL.
+     *
+     * @exception NotOwnerException if the caller principal is not
+     * an owner of this Acl.
+     */
+    public boolean removeEntry(Principal caller, AclEntry entry)
+          throws NotOwnerException;
+
+    /**
+     * Returns an enumeration for the set of allowed permissions for the
+     * specified principal (representing an entity such as an individual or
+     * a group). This set of allowed permissions is calculated as
+     * follows:
+     *
+     * <ul>
+     *
+     * <li>If there is no entry in this Access Control List for the
+     * specified principal, an empty permission set is returned.
+     *
+     * <li>Otherwise, the principal's group permission sets are determined.
+     * (A principal can belong to one or more groups, where a group is a
+     * group of principals, represented by the Group interface.)
+     * The group positive permission set is the union of all
+     * the positive permissions of each group that the principal belongs to.
+     * The group negative permission set is the union of all
+     * the negative permissions of each group that the principal belongs to.
+     * If there is a specific permission that occurs in both
+     * the positive permission set and the negative permission set,
+     * it is removed from both.<p>
+     *
+     * The individual positive and negative permission sets are also
+     * determined. The positive permission set contains the permissions
+     * specified in the positive ACL entry (if any) for the principal.
+     * Similarly, the negative permission set contains the permissions
+     * specified in the negative ACL entry (if any) for the principal.
+     * The individual positive (or negative) permission set is considered
+     * to be null if there is not a positive (negative) ACL entry for the
+     * principal in this ACL.<p>
+     *
+     * The set of permissions granted to the principal is then calculated
+     * using the simple rule that individual permissions always override
+     * the group permissions. That is, the principal's individual negative
+     * permission set (specific denial of permissions) overrides the group
+     * positive permission set, and the principal's individual positive
+     * permission set overrides the group negative permission set.
+     *
+     * </ul>
+     *
+     * @param user the principal whose permission set is to be returned.
+     *
+     * @return the permission set specifying the permissions the principal
+     * is allowed.
+     */
+    public Enumeration<Permission> getPermissions(Principal user);
+
+    /**
+     * Returns an enumeration of the entries in this ACL. Each element in
+     * the enumeration is of type AclEntry.
+     *
+     * @return an enumeration of the entries in this ACL.
+     */
+    public Enumeration<AclEntry> entries();
+
+    /**
+     * Checks whether or not the specified principal has the specified
+     * permission. If it does, true is returned, otherwise false is returned.
+     *
+     * More specifically, this method checks whether the passed permission
+     * is a member of the allowed permission set of the specified principal.
+     * The allowed permission set is determined by the same algorithm as is
+     * used by the {@code getPermissions} method.
+     *
+     * @param principal the principal, assumed to be a valid authenticated
+     * Principal.
+     *
+     * @param permission the permission to be checked for.
+     *
+     * @return true if the principal has the specified permission, false
+     * otherwise.
+     *
+     * @see #getPermissions
+     */
+    public boolean checkPermission(Principal principal, Permission permission);
+
+    /**
+     * Returns a string representation of the
+     * ACL contents.
+     *
+     * @return a string representation of the ACL contents.
+     */
+    public String toString();
+}
diff --git a/java/security/acl/AclEntry.java b/java/security/acl/AclEntry.java
new file mode 100644
index 0000000..cd9675f
--- /dev/null
+++ b/java/security/acl/AclEntry.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 1996, 2013, 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 java.security.acl;
+
+import java.util.Enumeration;
+import java.security.Principal;
+
+/**
+ * This is the interface used for representing one entry in an Access
+ * Control List (ACL).<p>
+ *
+ * An ACL can be thought of as a data structure with multiple ACL entry
+ * objects. Each ACL entry object contains a set of permissions associated
+ * with a particular principal. (A principal represents an entity such as
+ * an individual user or a group). Additionally, each ACL entry is specified
+ * as being either positive or negative. If positive, the permissions are
+ * to be granted to the associated principal. If negative, the permissions
+ * are to be denied. Each principal can have at most one positive ACL entry
+ * and one negative entry; that is, multiple positive or negative ACL
+ * entries are not allowed for any principal.
+ *
+ * Note: ACL entries are by default positive. An entry becomes a
+ * negative entry only if the
+ * {@link #setNegativePermissions() setNegativePermissions}
+ * method is called on it.
+ *
+ * @see java.security.acl.Acl
+ *
+ * @author      Satish Dharmaraj
+ */
+public interface AclEntry extends Cloneable {
+
+    /**
+     * Specifies the principal for which permissions are granted or denied
+     * by this ACL entry. If a principal was already set for this ACL entry,
+     * false is returned, otherwise true is returned.
+     *
+     * @param user the principal to be set for this entry.
+     *
+     * @return true if the principal is set, false if there was
+     * already a principal set for this entry.
+     *
+     * @see #getPrincipal
+     */
+    public boolean setPrincipal(Principal user);
+
+    /**
+     * Returns the principal for which permissions are granted or denied by
+     * this ACL entry. Returns null if there is no principal set for this
+     * entry yet.
+     *
+     * @return the principal associated with this entry.
+     *
+     * @see #setPrincipal
+     */
+    public Principal getPrincipal();
+
+    /**
+     * Sets this ACL entry to be a negative one. That is, the associated
+     * principal (e.g., a user or a group) will be denied the permission set
+     * specified in the entry.
+     *
+     * Note: ACL entries are by default positive. An entry becomes a
+     * negative entry only if this {@code setNegativePermissions}
+     * method is called on it.
+     */
+    public void setNegativePermissions();
+
+    /**
+     * Returns true if this is a negative ACL entry (one denying the
+     * associated principal the set of permissions in the entry), false
+     * otherwise.
+     *
+     * @return true if this is a negative ACL entry, false if it's not.
+     */
+    public boolean isNegative();
+
+    /**
+     * Adds the specified permission to this ACL entry. Note: An entry can
+     * have multiple permissions.
+     *
+     * @param permission the permission to be associated with
+     * the principal in this entry.
+     *
+     * @return true if the permission was added, false if the
+     * permission was already part of this entry's permission set.
+     */
+    public boolean addPermission(Permission permission);
+
+    /**
+     * Removes the specified permission from this ACL entry.
+     *
+     * @param permission the permission to be removed from this entry.
+     *
+     * @return true if the permission is removed, false if the
+     * permission was not part of this entry's permission set.
+     */
+    public boolean removePermission(Permission permission);
+
+    /**
+     * Checks if the specified permission is part of the
+     * permission set in this entry.
+     *
+     * @param permission the permission to be checked for.
+     *
+     * @return true if the permission is part of the
+     * permission set in this entry, false otherwise.
+     */
+    public boolean checkPermission(Permission permission);
+
+    /**
+     * Returns an enumeration of the permissions in this ACL entry.
+     *
+     * @return an enumeration of the permissions in this ACL entry.
+     */
+    public Enumeration<Permission> permissions();
+
+    /**
+     * Returns a string representation of the contents of this ACL entry.
+     *
+     * @return a string representation of the contents.
+     */
+    public String toString();
+
+    /**
+     * Clones this ACL entry.
+     *
+     * @return a clone of this ACL entry.
+     */
+    public Object clone();
+}
diff --git a/java/security/acl/AclNotFoundException.java b/java/security/acl/AclNotFoundException.java
new file mode 100644
index 0000000..6f08e17
--- /dev/null
+++ b/java/security/acl/AclNotFoundException.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 1996, 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.  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 java.security.acl;
+
+/**
+ * This is an exception that is thrown whenever a reference is made to a
+ * non-existent ACL (Access Control List).
+ *
+ * @author      Satish Dharmaraj
+ */
+public class AclNotFoundException extends Exception {
+
+    private static final long serialVersionUID = 5684295034092681791L;
+
+    /**
+     * Constructs an AclNotFoundException.
+     */
+    public AclNotFoundException() {
+    }
+
+}
diff --git a/java/security/acl/Group.java b/java/security/acl/Group.java
new file mode 100644
index 0000000..ebd9c44
--- /dev/null
+++ b/java/security/acl/Group.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 1996, 2013, 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 java.security.acl;
+
+import java.util.Enumeration;
+import java.security.Principal;
+
+/**
+ * This interface is used to represent a group of principals. (A principal
+ * represents an entity such as an individual user or a company). <p>
+ *
+ * Note that Group extends Principal. Thus, either a Principal or a Group can
+ * be passed as an argument to methods containing a Principal parameter. For
+ * example, you can add either a Principal or a Group to a Group object by
+ * calling the object's {@code addMember} method, passing it the
+ * Principal or Group.
+ *
+ * @author      Satish Dharmaraj
+ */
+public interface Group extends Principal {
+
+    /**
+     * Adds the specified member to the group.
+     *
+     * @param user the principal to add to this group.
+     *
+     * @return true if the member was successfully added,
+     * false if the principal was already a member.
+     */
+    public boolean addMember(Principal user);
+
+    /**
+     * Removes the specified member from the group.
+     *
+     * @param user the principal to remove from this group.
+     *
+     * @return true if the principal was removed, or
+     * false if the principal was not a member.
+     */
+    public boolean removeMember(Principal user);
+
+    /**
+     * Returns true if the passed principal is a member of the group.
+     * This method does a recursive search, so if a principal belongs to a
+     * group which is a member of this group, true is returned.
+     *
+     * @param member the principal whose membership is to be checked.
+     *
+     * @return true if the principal is a member of this group,
+     * false otherwise.
+     */
+    public boolean isMember(Principal member);
+
+
+    /**
+     * Returns an enumeration of the members in the group.
+     * The returned objects can be instances of either Principal
+     * or Group (which is a subclass of Principal).
+     *
+     * @return an enumeration of the group members.
+     */
+    public Enumeration<? extends Principal> members();
+
+}
diff --git a/java/security/acl/LastOwnerException.java b/java/security/acl/LastOwnerException.java
new file mode 100644
index 0000000..196c8f1
--- /dev/null
+++ b/java/security/acl/LastOwnerException.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1996, 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.  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 java.security.acl;
+
+/**
+ * This is an exception that is thrown whenever an attempt is made to delete
+ * the last owner of an Access Control List.
+ *
+ * @see java.security.acl.Owner#deleteOwner
+ *
+ * @author Satish Dharmaraj
+ */
+public class LastOwnerException extends Exception {
+
+    private static final long serialVersionUID = -5141997548211140359L;
+
+    /**
+     * Constructs a LastOwnerException.
+     */
+    public LastOwnerException() {
+    }
+}
diff --git a/java/security/acl/NotOwnerException.java b/java/security/acl/NotOwnerException.java
new file mode 100644
index 0000000..0a4b04b
--- /dev/null
+++ b/java/security/acl/NotOwnerException.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 1996, 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.  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 java.security.acl;
+
+/**
+ * This is an exception that is thrown whenever the modification of an object
+ * (such as an Access Control List) is only allowed to be done by an owner of
+ * the object, but the Principal attempting the modification is not an owner.
+ *
+ * @author      Satish Dharmaraj
+ */
+public class NotOwnerException extends Exception {
+
+    private static final long serialVersionUID = -5555597911163362399L;
+
+    /**
+     * Constructs a NotOwnerException.
+     */
+    public NotOwnerException() {
+    }
+}
diff --git a/java/security/acl/Owner.java b/java/security/acl/Owner.java
new file mode 100644
index 0000000..2f649d4
--- /dev/null
+++ b/java/security/acl/Owner.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 1996, 2013, 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 java.security.acl;
+
+import java.security.Principal;
+
+/**
+ * Interface for managing owners of Access Control Lists (ACLs) or ACL
+ * configurations. (Note that the Acl interface in the
+ * {@code  java.security.acl} package extends this Owner
+ * interface.) The initial owner Principal should be specified as an
+ * argument to the constructor of the class implementing this interface.
+ *
+ * @see java.security.acl.Acl
+ *
+ */
+public interface Owner {
+
+    /**
+     * Adds an owner. Only owners can modify ACL contents. The caller
+     * principal must be an owner of the ACL in order to invoke this method.
+     * That is, only an owner can add another owner. The initial owner is
+     * configured at ACL construction time.
+     *
+     * @param caller the principal invoking this method. It must be an owner
+     * of the ACL.
+     *
+     * @param owner the owner that should be added to the list of owners.
+     *
+     * @return true if successful, false if owner is already an owner.
+     * @exception NotOwnerException if the caller principal is not an owner
+     * of the ACL.
+     */
+    public boolean addOwner(Principal caller, Principal owner)
+      throws NotOwnerException;
+
+    /**
+     * Deletes an owner. If this is the last owner in the ACL, an exception is
+     * raised.<p>
+     *
+     * The caller principal must be an owner of the ACL in order to invoke
+     * this method.
+     *
+     * @param caller the principal invoking this method. It must be an owner
+     * of the ACL.
+     *
+     * @param owner the owner to be removed from the list of owners.
+     *
+     * @return true if the owner is removed, false if the owner is not part
+     * of the list of owners.
+     *
+     * @exception NotOwnerException if the caller principal is not an owner
+     * of the ACL.
+     *
+     * @exception LastOwnerException if there is only one owner left, so that
+     * deleteOwner would leave the ACL owner-less.
+     */
+    public boolean deleteOwner(Principal caller, Principal owner)
+      throws NotOwnerException, LastOwnerException;
+
+    /**
+     * Returns true if the given principal is an owner of the ACL.
+     *
+     * @param owner the principal to be checked to determine whether or not
+     * it is an owner.
+     *
+     * @return true if the passed principal is in the list of owners, false
+     * if not.
+     */
+    public boolean isOwner(Principal owner);
+
+}
diff --git a/java/security/acl/Permission.java b/java/security/acl/Permission.java
new file mode 100644
index 0000000..72412de
--- /dev/null
+++ b/java/security/acl/Permission.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 1996, 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 java.security.acl;
+
+// Android-changed: Stubbed the implementation.  Android doesn't support SecurityManager.
+// See comments in java.lang.SecurityManager for details.
+/**
+ * Legacy security code; do not use.
+ */
+public interface Permission {
+}
diff --git a/java/security/acl/package-info.java b/java/security/acl/package-info.java
new file mode 100644
index 0000000..356c102
--- /dev/null
+++ b/java/security/acl/package-info.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 1998, 2013, 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.
+ */
+
+/**
+ * The classes and interfaces in this package have been
+ * superseded by classes in the java.security package.
+ * See that package and, for example, java.security.Permission for details.
+ *
+ * @since JDK1.1
+ */
+package java.security.acl;
diff --git a/java/security/cert/CRL.java b/java/security/cert/CRL.java
new file mode 100644
index 0000000..725d7b5
--- /dev/null
+++ b/java/security/cert/CRL.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 1998, 2006, 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 java.security.cert;
+
+/**
+ * This class is an abstraction of certificate revocation lists (CRLs) that
+ * have different formats but important common uses. For example, all CRLs
+ * share the functionality of listing revoked certificates, and can be queried
+ * on whether or not they list a given certificate.
+ * <p>
+ * Specialized CRL types can be defined by subclassing off of this abstract
+ * class.
+ *
+ * @author Hemma Prafullchandra
+ *
+ *
+ * @see X509CRL
+ * @see CertificateFactory
+ *
+ * @since 1.2
+ */
+
+public abstract class CRL {
+
+    // the CRL type
+    private String type;
+
+    /**
+     * Creates a CRL of the specified type.
+     *
+     * @param type the standard name of the CRL type.
+     * See Appendix A in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/CryptoSpec.html#AppA">
+     * Java Cryptography Architecture API Specification &amp; Reference </a>
+     * for information about standard CRL types.
+     */
+    protected CRL(String type) {
+        this.type = type;
+    }
+
+    /**
+     * Returns the type of this CRL.
+     *
+     * @return the type of this CRL.
+     */
+    public final String getType() {
+        return this.type;
+    }
+
+    /**
+     * Returns a string representation of this CRL.
+     *
+     * @return a string representation of this CRL.
+     */
+    public abstract String toString();
+
+    /**
+     * Checks whether the given certificate is on this CRL.
+     *
+     * @param cert the certificate to check for.
+     * @return true if the given certificate is on this CRL,
+     * false otherwise.
+     */
+    public abstract boolean isRevoked(Certificate cert);
+}
diff --git a/java/security/cert/CRLException.java b/java/security/cert/CRLException.java
new file mode 100644
index 0000000..7a85431
--- /dev/null
+++ b/java/security/cert/CRLException.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security.cert;
+
+import java.security.GeneralSecurityException;
+
+/**
+ * CRL (Certificate Revocation List) Exception.
+ *
+ * @author Hemma Prafullchandra
+ */
+public class CRLException extends GeneralSecurityException {
+
+    private static final long serialVersionUID = -6694728944094197147L;
+
+   /**
+     * Constructs a CRLException with no detail message. A
+     * detail message is a String that describes this particular
+     * exception.
+     */
+    public CRLException() {
+        super();
+    }
+
+    /**
+     * Constructs a CRLException with the specified detail
+     * message. A detail message is a String that describes this
+     * particular exception.
+     *
+     * @param message the detail message.
+     */
+    public CRLException(String message) {
+        super(message);
+    }
+
+    /**
+     * Creates a {@code CRLException} with the specified
+     * detail message and cause.
+     *
+     * @param message the detail message (which is saved for later retrieval
+     *        by the {@link #getMessage()} method).
+     * @param cause the cause (which is saved for later retrieval by the
+     *        {@link #getCause()} method).  (A {@code null} value is permitted,
+     *        and indicates that the cause is nonexistent or unknown.)
+     * @since 1.5
+     */
+    public CRLException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Creates a {@code CRLException} with the specified cause
+     * and a detail message of {@code (cause==null ? null : cause.toString())}
+     * (which typically contains the class and detail message of
+     * {@code cause}).
+     *
+     * @param cause the cause (which is saved for later retrieval by the
+     *        {@link #getCause()} method).  (A {@code null} value is permitted,
+     *        and indicates that the cause is nonexistent or unknown.)
+     * @since 1.5
+     */
+    public CRLException(Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/java/security/cert/CRLReason.java b/java/security/cert/CRLReason.java
new file mode 100644
index 0000000..ac0b9e9
--- /dev/null
+++ b/java/security/cert/CRLReason.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2007, 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 java.security.cert;
+
+/**
+ * The CRLReason enumeration specifies the reason that a certificate
+ * is revoked, as defined in <a href="http://www.ietf.org/rfc/rfc3280.txt">
+ * RFC 3280: Internet X.509 Public Key Infrastructure Certificate and CRL
+ * Profile</a>.
+ *
+ * @author Sean Mullan
+ * @since 1.7
+ * @see X509CRLEntry#getRevocationReason
+ * @see CertificateRevokedException#getRevocationReason
+ */
+public enum CRLReason {
+    /**
+     * This reason indicates that it is unspecified as to why the
+     * certificate has been revoked.
+     */
+    UNSPECIFIED,
+
+    /**
+     * This reason indicates that it is known or suspected that the
+     * certificate subject's private key has been compromised. It applies
+     * to end-entity certificates only.
+     */
+    KEY_COMPROMISE,
+
+    /**
+     * This reason indicates that it is known or suspected that the
+     * certificate subject's private key has been compromised. It applies
+     * to certificate authority (CA) certificates only.
+     */
+    CA_COMPROMISE,
+
+    /**
+     * This reason indicates that the subject's name or other information
+     * has changed.
+     */
+    AFFILIATION_CHANGED,
+
+    /**
+     * This reason indicates that the certificate has been superseded.
+     */
+    SUPERSEDED,
+
+    /**
+     * This reason indicates that the certificate is no longer needed.
+     */
+    CESSATION_OF_OPERATION,
+
+    /**
+     * This reason indicates that the certificate has been put on hold.
+     */
+    CERTIFICATE_HOLD,
+
+    /**
+     * Unused reason.
+     */
+    UNUSED,
+
+    /**
+     * This reason indicates that the certificate was previously on hold
+     * and should be removed from the CRL. It is for use with delta CRLs.
+     */
+    REMOVE_FROM_CRL,
+
+    /**
+     * This reason indicates that the privileges granted to the subject of
+     * the certificate have been withdrawn.
+     */
+    PRIVILEGE_WITHDRAWN,
+
+    /**
+     * This reason indicates that it is known or suspected that the
+     * certificate subject's private key has been compromised. It applies
+     * to authority attribute (AA) certificates only.
+     */
+    AA_COMPROMISE
+}
diff --git a/java/security/cert/CRLSelector.java b/java/security/cert/CRLSelector.java
new file mode 100644
index 0000000..7ab181d
--- /dev/null
+++ b/java/security/cert/CRLSelector.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2000, 2013, 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 java.security.cert;
+
+/**
+ * A selector that defines a set of criteria for selecting {@code CRL}s.
+ * Classes that implement this interface are often used to specify
+ * which {@code CRL}s should be retrieved from a {@code CertStore}.
+ * <p>
+ * <b>Concurrent Access</b>
+ * <p>
+ * Unless otherwise specified, the methods defined in this interface are not
+ * thread-safe. Multiple threads that need to access a single
+ * object concurrently should synchronize amongst themselves and
+ * provide the necessary locking. Multiple threads each manipulating
+ * separate objects need not synchronize.
+ *
+ * @see CRL
+ * @see CertStore
+ * @see CertStore#getCRLs
+ *
+ * @author      Steve Hanna
+ * @since       1.4
+ */
+public interface CRLSelector extends Cloneable {
+
+    /**
+     * Decides whether a {@code CRL} should be selected.
+     *
+     * @param   crl     the {@code CRL} to be checked
+     * @return  {@code true} if the {@code CRL} should be selected,
+     * {@code false} otherwise
+     */
+    boolean match(CRL crl);
+
+    /**
+     * Makes a copy of this {@code CRLSelector}. Changes to the
+     * copy will not affect the original and vice versa.
+     *
+     * @return a copy of this {@code CRLSelector}
+     */
+    Object clone();
+}
diff --git a/java/security/cert/CertPath.java b/java/security/cert/CertPath.java
new file mode 100644
index 0000000..f742664
--- /dev/null
+++ b/java/security/cert/CertPath.java
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) 2000, 2013, 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 java.security.cert;
+
+import java.io.ByteArrayInputStream;
+import java.io.NotSerializableException;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * An immutable sequence of certificates (a certification path).
+ * <p>
+ * This is an abstract class that defines the methods common to all
+ * {@code CertPath}s. Subclasses can handle different kinds of
+ * certificates (X.509, PGP, etc.).
+ * <p>
+ * All {@code CertPath} objects have a type, a list of
+ * {@code Certificate}s, and one or more supported encodings. Because the
+ * {@code CertPath} class is immutable, a {@code CertPath} cannot
+ * change in any externally visible way after being constructed. This
+ * stipulation applies to all public fields and methods of this class and any
+ * added or overridden by subclasses.
+ * <p>
+ * The type is a {@code String} that identifies the type of
+ * {@code Certificate}s in the certification path. For each
+ * certificate {@code cert} in a certification path {@code certPath},
+ * {@code cert.getType().equals(certPath.getType())} must be
+ * {@code true}.
+ * <p>
+ * The list of {@code Certificate}s is an ordered {@code List} of
+ * zero or more {@code Certificate}s. This {@code List} and all
+ * of the {@code Certificate}s contained in it must be immutable.
+ * <p>
+ * Each {@code CertPath} object must support one or more encodings
+ * so that the object can be translated into a byte array for storage or
+ * transmission to other parties. Preferably, these encodings should be
+ * well-documented standards (such as PKCS#7). One of the encodings supported
+ * by a {@code CertPath} is considered the default encoding. This
+ * encoding is used if no encoding is explicitly requested (for the
+ * {@link #getEncoded() getEncoded()} method, for instance).
+ * <p>
+ * All {@code CertPath} objects are also {@code Serializable}.
+ * {@code CertPath} objects are resolved into an alternate
+ * {@link CertPathRep CertPathRep} object during serialization. This allows
+ * a {@code CertPath} object to be serialized into an equivalent
+ * representation regardless of its underlying implementation.
+ * <p>
+ * {@code CertPath} objects can be created with a
+ * {@code CertificateFactory} or they can be returned by other classes,
+ * such as a {@code CertPathBuilder}.
+ * <p>
+ * By convention, X.509 {@code CertPath}s (consisting of
+ * {@code X509Certificate}s), are ordered starting with the target
+ * certificate and ending with a certificate issued by the trust anchor. That
+ * is, the issuer of one certificate is the subject of the following one. The
+ * certificate representing the {@link TrustAnchor TrustAnchor} should not be
+ * included in the certification path. Unvalidated X.509 {@code CertPath}s
+ * may not follow these conventions. PKIX {@code CertPathValidator}s will
+ * detect any departure from these conventions that cause the certification
+ * path to be invalid and throw a {@code CertPathValidatorException}.
+ *
+ * <p> Every implementation of the Java platform is required to support the
+ * following standard {@code CertPath} encodings:
+ * <ul>
+ * <li>{@code PKCS7}</li>
+ * <li>{@code PkiPath}</li>
+ * </ul>
+ * These encodings are described in the <a href=
+ * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertPathEncodings">
+ * CertPath Encodings section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other encodings are supported.
+ * <p>
+ * <b>Concurrent Access</b>
+ * <p>
+ * All {@code CertPath} objects must be thread-safe. That is, multiple
+ * threads may concurrently invoke the methods defined in this class on a
+ * single {@code CertPath} object (or more than one) with no
+ * ill effects. This is also true for the {@code List} returned by
+ * {@code CertPath.getCertificates}.
+ * <p>
+ * Requiring {@code CertPath} objects to be immutable and thread-safe
+ * allows them to be passed around to various pieces of code without worrying
+ * about coordinating access.  Providing this thread-safety is
+ * generally not difficult, since the {@code CertPath} and
+ * {@code List} objects in question are immutable.
+ *
+ * @see CertificateFactory
+ * @see CertPathBuilder
+ *
+ * @author      Yassir Elley
+ * @since       1.4
+ */
+public abstract class CertPath implements Serializable {
+
+    private static final long serialVersionUID = 6068470306649138683L;
+
+    private String type;        // the type of certificates in this chain
+
+    /**
+     * Creates a {@code CertPath} of the specified type.
+     * <p>
+     * This constructor is protected because most users should use a
+     * {@code CertificateFactory} to create {@code CertPath}s.
+     *
+     * @param type the standard name of the type of
+     * {@code Certificate}s in this path
+     */
+    protected CertPath(String type) {
+        this.type = type;
+    }
+
+    /**
+     * Returns the type of {@code Certificate}s in this certification
+     * path. This is the same string that would be returned by
+     * {@link java.security.cert.Certificate#getType() cert.getType()}
+     * for all {@code Certificate}s in the certification path.
+     *
+     * @return the type of {@code Certificate}s in this certification
+     * path (never null)
+     */
+    public String getType() {
+        return type;
+    }
+
+    /**
+     * Returns an iteration of the encodings supported by this certification
+     * path, with the default encoding first. Attempts to modify the returned
+     * {@code Iterator} via its {@code remove} method result in an
+     * {@code UnsupportedOperationException}.
+     *
+     * @return an {@code Iterator} over the names of the supported
+     *         encodings (as Strings)
+     */
+    public abstract Iterator<String> getEncodings();
+
+    /**
+     * Compares this certification path for equality with the specified
+     * object. Two {@code CertPath}s are equal if and only if their
+     * types are equal and their certificate {@code List}s (and by
+     * implication the {@code Certificate}s in those {@code List}s)
+     * are equal. A {@code CertPath} is never equal to an object that is
+     * not a {@code CertPath}.
+     * <p>
+     * This algorithm is implemented by this method. If it is overridden,
+     * the behavior specified here must be maintained.
+     *
+     * @param other the object to test for equality with this certification path
+     * @return true if the specified object is equal to this certification path,
+     * false otherwise
+     */
+    public boolean equals(Object other) {
+        if (this == other)
+            return true;
+
+        if (! (other instanceof CertPath))
+            return false;
+
+        CertPath otherCP = (CertPath) other;
+        if (! otherCP.getType().equals(type))
+            return false;
+
+        List<? extends Certificate> thisCertList = this.getCertificates();
+        List<? extends Certificate> otherCertList = otherCP.getCertificates();
+        return(thisCertList.equals(otherCertList));
+    }
+
+    /**
+     * Returns the hashcode for this certification path. The hash code of
+     * a certification path is defined to be the result of the following
+     * calculation:
+     * <pre>{@code
+     *  hashCode = path.getType().hashCode();
+     *  hashCode = 31*hashCode + path.getCertificates().hashCode();
+     * }</pre>
+     * This ensures that {@code path1.equals(path2)} implies that
+     * {@code path1.hashCode()==path2.hashCode()} for any two certification
+     * paths, {@code path1} and {@code path2}, as required by the
+     * general contract of {@code Object.hashCode}.
+     *
+     * @return the hashcode value for this certification path
+     */
+    public int hashCode() {
+        int hashCode = type.hashCode();
+        hashCode = 31*hashCode + getCertificates().hashCode();
+        return hashCode;
+    }
+
+    /**
+     * Returns a string representation of this certification path.
+     * This calls the {@code toString} method on each of the
+     * {@code Certificate}s in the path.
+     *
+     * @return a string representation of this certification path
+     */
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        Iterator<? extends Certificate> stringIterator =
+                                        getCertificates().iterator();
+
+        sb.append("\n" + type + " Cert Path: length = "
+            + getCertificates().size() + ".\n");
+        sb.append("[\n");
+        int i = 1;
+        while (stringIterator.hasNext()) {
+            sb.append("=========================================="
+                + "===============Certificate " + i + " start.\n");
+            Certificate stringCert = stringIterator.next();
+            sb.append(stringCert.toString());
+            sb.append("\n========================================"
+                + "=================Certificate " + i + " end.\n\n\n");
+            i++;
+        }
+
+        sb.append("\n]");
+        return sb.toString();
+    }
+
+    /**
+     * Returns the encoded form of this certification path, using the default
+     * encoding.
+     *
+     * @return the encoded bytes
+     * @exception CertificateEncodingException if an encoding error occurs
+     */
+    public abstract byte[] getEncoded()
+        throws CertificateEncodingException;
+
+    /**
+     * Returns the encoded form of this certification path, using the
+     * specified encoding.
+     *
+     * @param encoding the name of the encoding to use
+     * @return the encoded bytes
+     * @exception CertificateEncodingException if an encoding error occurs or
+     *   the encoding requested is not supported
+     */
+    public abstract byte[] getEncoded(String encoding)
+        throws CertificateEncodingException;
+
+    /**
+     * Returns the list of certificates in this certification path.
+     * The {@code List} returned must be immutable and thread-safe.
+     *
+     * @return an immutable {@code List} of {@code Certificate}s
+     *         (may be empty, but not null)
+     */
+    public abstract List<? extends Certificate> getCertificates();
+
+    /**
+     * Replaces the {@code CertPath} to be serialized with a
+     * {@code CertPathRep} object.
+     *
+     * @return the {@code CertPathRep} to be serialized
+     *
+     * @throws ObjectStreamException if a {@code CertPathRep} object
+     * representing this certification path could not be created
+     */
+    protected Object writeReplace() throws ObjectStreamException {
+        try {
+            return new CertPathRep(type, getEncoded());
+        } catch (CertificateException ce) {
+            NotSerializableException nse =
+                new NotSerializableException
+                    ("java.security.cert.CertPath: " + type);
+            nse.initCause(ce);
+            throw nse;
+        }
+    }
+
+    /**
+     * Alternate {@code CertPath} class for serialization.
+     * @since 1.4
+     */
+    protected static class CertPathRep implements Serializable {
+
+        private static final long serialVersionUID = 3015633072427920915L;
+
+        /** The Certificate type */
+        private String type;
+        /** The encoded form of the cert path */
+        private byte[] data;
+
+        /**
+         * Creates a {@code CertPathRep} with the specified
+         * type and encoded form of a certification path.
+         *
+         * @param type the standard name of a {@code CertPath} type
+         * @param data the encoded form of the certification path
+         */
+        protected CertPathRep(String type, byte[] data) {
+            this.type = type;
+            this.data = data;
+        }
+
+        /**
+         * Returns a {@code CertPath} constructed from the type and data.
+         *
+         * @return the resolved {@code CertPath} object
+         *
+         * @throws ObjectStreamException if a {@code CertPath} could not
+         * be constructed
+         */
+        protected Object readResolve() throws ObjectStreamException {
+            try {
+                CertificateFactory cf = CertificateFactory.getInstance(type);
+                return cf.generateCertPath(new ByteArrayInputStream(data));
+            } catch (CertificateException ce) {
+                NotSerializableException nse =
+                    new NotSerializableException
+                        ("java.security.cert.CertPath: " + type);
+                nse.initCause(ce);
+                throw nse;
+            }
+        }
+    }
+}
diff --git a/java/security/cert/CertPathBuilder.java b/java/security/cert/CertPathBuilder.java
new file mode 100644
index 0000000..fd6cdc8
--- /dev/null
+++ b/java/security/cert/CertPathBuilder.java
@@ -0,0 +1,342 @@
+/*
+ * Copyright (c) 2000, 2013, 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 java.security.cert;
+
+import java.security.AccessController;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivilegedAction;
+import java.security.Provider;
+import java.security.Security;
+import sun.security.util.Debug;
+
+import sun.security.jca.*;
+import sun.security.jca.GetInstance.Instance;
+
+/**
+ * A class for building certification paths (also known as certificate chains).
+ * <p>
+ * This class uses a provider-based architecture.
+ * To create a {@code CertPathBuilder}, call
+ * one of the static {@code getInstance} methods, passing in the
+ * algorithm name of the {@code CertPathBuilder} desired and optionally
+ * the name of the provider desired.
+ *
+ * <p>Once a {@code CertPathBuilder} object has been created, certification
+ * paths can be constructed by calling the {@link #build build} method and
+ * passing it an algorithm-specific set of parameters. If successful, the
+ * result (including the {@code CertPath} that was built) is returned
+ * in an object that implements the {@code CertPathBuilderResult}
+ * interface.
+ *
+ * <p>The {@link #getRevocationChecker} method allows an application to specify
+ * additional algorithm-specific parameters and options used by the
+ * {@code CertPathBuilder} when checking the revocation status of certificates.
+ * Here is an example demonstrating how it is used with the PKIX algorithm:
+ *
+ * <pre>
+ * CertPathBuilder cpb = CertPathBuilder.getInstance("PKIX");
+ * PKIXRevocationChecker rc = (PKIXRevocationChecker)cpb.getRevocationChecker();
+ * rc.setOptions(EnumSet.of(Option.PREFER_CRLS));
+ * params.addCertPathChecker(rc);
+ * CertPathBuilderResult cpbr = cpb.build(params);
+ * </pre>
+ *
+ * <p> Android provides the following {@code CertPathBuilder} algorithms:
+ * <table>
+ *   <thead>
+ *     <tr>
+ *       <th>Algorithm</th>
+ *       <th>Supported API Levels</th>
+ *     </tr>
+ *   </thead>
+ *   <tbody>
+ *     <tr>
+ *       <td>PKIX</td>
+ *       <td>1+</td>
+ *     </tr>
+ *   </tbody>
+ * </table>
+ *
+ * This algorithm is described in the <a href=
+ * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertPathBuilder">
+ * CertPathBuilder section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other algorithms are supported.
+ *
+ * <p>
+ * <b>Concurrent Access</b>
+ * <p>
+ * The static methods of this class are guaranteed to be thread-safe.
+ * Multiple threads may concurrently invoke the static methods defined in
+ * this class with no ill effects.
+ * <p>
+ * However, this is not true for the non-static methods defined by this class.
+ * Unless otherwise documented by a specific provider, threads that need to
+ * access a single {@code CertPathBuilder} instance concurrently should
+ * synchronize amongst themselves and provide the necessary locking. Multiple
+ * threads each manipulating a different {@code CertPathBuilder} instance
+ * need not synchronize.
+ *
+ * @see CertPath
+ *
+ * @since       1.4
+ * @author      Sean Mullan
+ * @author      Yassir Elley
+ */
+public class CertPathBuilder {
+
+    /*
+     * Constant to lookup in the Security properties file to determine
+     * the default certpathbuilder type. In the Security properties file,
+     * the default certpathbuilder type is given as:
+     * <pre>
+     * certpathbuilder.type=PKIX
+     * </pre>
+     */
+    private static final String CPB_TYPE = "certpathbuilder.type";
+    private final CertPathBuilderSpi builderSpi;
+    private final Provider provider;
+    private final String algorithm;
+
+    /**
+     * Creates a {@code CertPathBuilder} object of the given algorithm,
+     * and encapsulates the given provider implementation (SPI object) in it.
+     *
+     * @param builderSpi the provider implementation
+     * @param provider the provider
+     * @param algorithm the algorithm name
+     */
+    protected CertPathBuilder(CertPathBuilderSpi builderSpi, Provider provider,
+        String algorithm)
+    {
+        this.builderSpi = builderSpi;
+        this.provider = provider;
+        this.algorithm = algorithm;
+    }
+
+    /**
+     * Returns a {@code CertPathBuilder} object that implements the
+     * specified algorithm.
+     *
+     * <p> This method traverses the list of registered security Providers,
+     * starting with the most preferred Provider.
+     * A new CertPathBuilder object encapsulating the
+     * CertPathBuilderSpi implementation from the first
+     * Provider that supports the specified algorithm is returned.
+     *
+     * <p> Note that the list of registered providers may be retrieved via
+     * the {@link Security#getProviders() Security.getProviders()} method.
+     *
+     * @param algorithm the name of the requested {@code CertPathBuilder}
+     *  algorithm.  See the CertPathBuilder section in the <a href=
+     *  "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertPathBuilder">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard algorithm names.
+     *
+     * @return a {@code CertPathBuilder} object that implements the
+     *          specified algorithm.
+     *
+     * @throws NoSuchAlgorithmException if no Provider supports a
+     *          CertPathBuilderSpi implementation for the
+     *          specified algorithm.
+     *
+     * @see java.security.Provider
+     */
+    public static CertPathBuilder getInstance(String algorithm)
+            throws NoSuchAlgorithmException {
+        Instance instance = GetInstance.getInstance("CertPathBuilder",
+            CertPathBuilderSpi.class, algorithm);
+        return new CertPathBuilder((CertPathBuilderSpi)instance.impl,
+            instance.provider, algorithm);
+    }
+
+    /**
+     * Returns a {@code CertPathBuilder} object that implements the
+     * specified algorithm.
+     *
+     * <p> A new CertPathBuilder object encapsulating the
+     * CertPathBuilderSpi implementation from the specified provider
+     * is returned.  The specified provider must be registered
+     * in the security provider list.
+     *
+     * <p> Note that the list of registered providers may be retrieved via
+     * the {@link Security#getProviders() Security.getProviders()} method.
+     *
+     * @param algorithm the name of the requested {@code CertPathBuilder}
+     *  algorithm.  See the CertPathBuilder section in the <a href=
+     *  "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertPathBuilder">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard algorithm names.
+     *
+     * @param provider the name of the provider.
+     *
+     * @return a {@code CertPathBuilder} object that implements the
+     *          specified algorithm.
+     *
+     * @throws NoSuchAlgorithmException if a CertPathBuilderSpi
+     *          implementation for the specified algorithm is not
+     *          available from the specified provider.
+     *
+     * @throws NoSuchProviderException if the specified provider is not
+     *          registered in the security provider list.
+     *
+     * @exception IllegalArgumentException if the {@code provider} is
+     *          null or empty.
+     *
+     * @see java.security.Provider
+     */
+    public static CertPathBuilder getInstance(String algorithm, String provider)
+           throws NoSuchAlgorithmException, NoSuchProviderException {
+        Instance instance = GetInstance.getInstance("CertPathBuilder",
+            CertPathBuilderSpi.class, algorithm, provider);
+        return new CertPathBuilder((CertPathBuilderSpi)instance.impl,
+            instance.provider, algorithm);
+    }
+
+    /**
+     * Returns a {@code CertPathBuilder} object that implements the
+     * specified algorithm.
+     *
+     * <p> A new CertPathBuilder object encapsulating the
+     * CertPathBuilderSpi implementation from the specified Provider
+     * object is returned.  Note that the specified Provider object
+     * does not have to be registered in the provider list.
+     *
+     * @param algorithm the name of the requested {@code CertPathBuilder}
+     *  algorithm.  See the CertPathBuilder section in the <a href=
+     *  "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertPathBuilder">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard algorithm names.
+     *
+     * @param provider the provider.
+     *
+     * @return a {@code CertPathBuilder} object that implements the
+     *          specified algorithm.
+     *
+     * @exception NoSuchAlgorithmException if a CertPathBuilderSpi
+     *          implementation for the specified algorithm is not available
+     *          from the specified Provider object.
+     *
+     * @exception IllegalArgumentException if the {@code provider} is
+     *          null.
+     *
+     * @see java.security.Provider
+     */
+    public static CertPathBuilder getInstance(String algorithm,
+            Provider provider) throws NoSuchAlgorithmException {
+        Instance instance = GetInstance.getInstance("CertPathBuilder",
+            CertPathBuilderSpi.class, algorithm, provider);
+        return new CertPathBuilder((CertPathBuilderSpi)instance.impl,
+            instance.provider, algorithm);
+    }
+
+    /**
+     * Returns the provider of this {@code CertPathBuilder}.
+     *
+     * @return the provider of this {@code CertPathBuilder}
+     */
+    public final Provider getProvider() {
+        return this.provider;
+    }
+
+    /**
+     * Returns the name of the algorithm of this {@code CertPathBuilder}.
+     *
+     * @return the name of the algorithm of this {@code CertPathBuilder}
+     */
+    public final String getAlgorithm() {
+        return this.algorithm;
+    }
+
+    /**
+     * Attempts to build a certification path using the specified algorithm
+     * parameter set.
+     *
+     * @param params the algorithm parameters
+     * @return the result of the build algorithm
+     * @throws CertPathBuilderException if the builder is unable to construct
+     *  a certification path that satisfies the specified parameters
+     * @throws InvalidAlgorithmParameterException if the specified parameters
+     * are inappropriate for this {@code CertPathBuilder}
+     */
+    public final CertPathBuilderResult build(CertPathParameters params)
+        throws CertPathBuilderException, InvalidAlgorithmParameterException
+    {
+        return builderSpi.engineBuild(params);
+    }
+
+    /**
+     * Returns the default {@code CertPathBuilder} type as specified by
+     * the {@code certpathbuilder.type} security property, or the string
+     * {@literal "PKIX"} if no such property exists.
+     *
+     * <p>The default {@code CertPathBuilder} type can be used by
+     * applications that do not want to use a hard-coded type when calling one
+     * of the {@code getInstance} methods, and want to provide a default
+     * type in case a user does not specify its own.
+     *
+     * <p>The default {@code CertPathBuilder} type can be changed by
+     * setting the value of the {@code certpathbuilder.type} security property
+     * to the desired type.
+     *
+     * @see java.security.Security security properties
+     * @return the default {@code CertPathBuilder} type as specified
+     * by the {@code certpathbuilder.type} security property, or the string
+     * {@literal "PKIX"} if no such property exists.
+     */
+    public final static String getDefaultType() {
+        String cpbtype =
+            AccessController.doPrivileged(new PrivilegedAction<String>() {
+                public String run() {
+                    return Security.getProperty(CPB_TYPE);
+                }
+            });
+        return (cpbtype == null) ? "PKIX" : cpbtype;
+    }
+
+    /**
+     * Returns a {@code CertPathChecker} that the encapsulated
+     * {@code CertPathBuilderSpi} implementation uses to check the revocation
+     * status of certificates. A PKIX implementation returns objects of
+     * type {@code PKIXRevocationChecker}. Each invocation of this method
+     * returns a new instance of {@code CertPathChecker}.
+     *
+     * <p>The primary purpose of this method is to allow callers to specify
+     * additional input parameters and options specific to revocation checking.
+     * See the class description for an example.
+     *
+     * @return a {@code CertPathChecker}
+     * @throws UnsupportedOperationException if the service provider does not
+     *         support this method
+     * @since 1.8
+     */
+    public final CertPathChecker getRevocationChecker() {
+        return builderSpi.engineGetRevocationChecker();
+    }
+}
diff --git a/java/security/cert/CertPathBuilderException.java b/java/security/cert/CertPathBuilderException.java
new file mode 100644
index 0000000..cf95847
--- /dev/null
+++ b/java/security/cert/CertPathBuilderException.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2000, 2013, 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 java.security.cert;
+
+import java.security.GeneralSecurityException;
+
+/**
+ * An exception indicating one of a variety of problems encountered when
+ * building a certification path with a {@code CertPathBuilder}.
+ * <p>
+ * A {@code CertPathBuilderException} provides support for wrapping
+ * exceptions. The {@link #getCause getCause} method returns the throwable,
+ * if any, that caused this exception to be thrown.
+ * <p>
+ * <b>Concurrent Access</b>
+ * <p>
+ * Unless otherwise specified, the methods defined in this class are not
+ * thread-safe. Multiple threads that need to access a single
+ * object concurrently should synchronize amongst themselves and
+ * provide the necessary locking. Multiple threads each manipulating
+ * separate objects need not synchronize.
+ *
+ * @see CertPathBuilder
+ *
+ * @since       1.4
+ * @author      Sean Mullan
+ */
+public class CertPathBuilderException extends GeneralSecurityException {
+
+    private static final long serialVersionUID = 5316471420178794402L;
+
+    /**
+     * Creates a {@code CertPathBuilderException} with {@code null}
+     * as its detail message.
+     */
+    public CertPathBuilderException() {
+        super();
+    }
+
+    /**
+     * Creates a {@code CertPathBuilderException} with the given
+     * detail message. The detail message is a {@code String} that
+     * describes this particular exception in more detail.
+     *
+     * @param msg the detail message
+     */
+    public CertPathBuilderException(String msg) {
+        super(msg);
+    }
+
+    /**
+     * Creates a {@code CertPathBuilderException} that wraps the specified
+     * throwable. This allows any exception to be converted into a
+     * {@code CertPathBuilderException}, while retaining information
+     * about the wrapped exception, which may be useful for debugging. The
+     * detail message is set to ({@code cause==null ? null : cause.toString()})
+     * (which typically contains the class and detail message of
+     * cause).
+     *
+     * @param cause the cause (which is saved for later retrieval by the
+     * {@link #getCause getCause()} method). (A {@code null} value is
+     * permitted, and indicates that the cause is nonexistent or unknown.)
+     */
+    public CertPathBuilderException(Throwable cause) {
+        super(cause);
+    }
+
+    /**
+     * Creates a {@code CertPathBuilderException} with the specified
+     * detail message and cause.
+     *
+     * @param msg the detail message
+     * @param  cause the cause (which is saved for later retrieval by the
+     * {@link #getCause getCause()} method). (A {@code null} value is
+     * permitted, and indicates that the cause is nonexistent or unknown.)
+     */
+    public CertPathBuilderException(String msg, Throwable cause) {
+        super(msg, cause);
+    }
+
+}
diff --git a/java/security/cert/CertPathBuilderResult.java b/java/security/cert/CertPathBuilderResult.java
new file mode 100644
index 0000000..ecf53bb
--- /dev/null
+++ b/java/security/cert/CertPathBuilderResult.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2000, 2013, 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 java.security.cert;
+
+/**
+ * A specification of the result of a certification path builder algorithm.
+ * All results returned by the {@link CertPathBuilder#build
+ * CertPathBuilder.build} method must implement this interface.
+ * <p>
+ * At a minimum, a {@code CertPathBuilderResult} contains the
+ * {@code CertPath} built by the {@code CertPathBuilder} instance.
+ * Implementations of this interface may add methods to return implementation
+ * or algorithm specific information, such as debugging information or
+ * certification path validation results.
+ * <p>
+ * <b>Concurrent Access</b>
+ * <p>
+ * Unless otherwise specified, the methods defined in this interface are not
+ * thread-safe. Multiple threads that need to access a single
+ * object concurrently should synchronize amongst themselves and
+ * provide the necessary locking. Multiple threads each manipulating
+ * separate objects need not synchronize.
+ *
+ * @see CertPathBuilder
+ *
+ * @since       1.4
+ * @author      Sean Mullan
+ */
+public interface CertPathBuilderResult extends Cloneable {
+
+    /**
+     * Returns the built certification path.
+     *
+     * @return the certification path (never {@code null})
+     */
+    CertPath getCertPath();
+
+    /**
+     * Makes a copy of this {@code CertPathBuilderResult}. Changes to the
+     * copy will not affect the original and vice versa.
+     *
+     * @return a copy of this {@code CertPathBuilderResult}
+     */
+    Object clone();
+}
diff --git a/java/security/cert/CertPathBuilderSpi.java b/java/security/cert/CertPathBuilderSpi.java
new file mode 100644
index 0000000..e775541
--- /dev/null
+++ b/java/security/cert/CertPathBuilderSpi.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2000, 2013, 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 java.security.cert;
+
+import java.security.InvalidAlgorithmParameterException;
+
+/**
+ * The <i>Service Provider Interface</i> (<b>SPI</b>)
+ * for the {@link CertPathBuilder CertPathBuilder} class. All
+ * {@code CertPathBuilder} implementations must include a class (the
+ * SPI class) that extends this class ({@code CertPathBuilderSpi}) and
+ * implements all of its methods. In general, instances of this class should
+ * only be accessed through the {@code CertPathBuilder} class. For
+ * details, see the Java Cryptography Architecture.
+ * <p>
+ * <b>Concurrent Access</b>
+ * <p>
+ * Instances of this class need not be protected against concurrent
+ * access from multiple threads. Threads that need to access a single
+ * {@code CertPathBuilderSpi} instance concurrently should synchronize
+ * amongst themselves and provide the necessary locking before calling the
+ * wrapping {@code CertPathBuilder} object.
+ * <p>
+ * However, implementations of {@code CertPathBuilderSpi} may still
+ * encounter concurrency issues, since multiple threads each
+ * manipulating a different {@code CertPathBuilderSpi} instance need not
+ * synchronize.
+ *
+ * @since       1.4
+ * @author      Sean Mullan
+ */
+public abstract class CertPathBuilderSpi {
+
+    /**
+     * The default constructor.
+     */
+    public CertPathBuilderSpi() { }
+
+    /**
+     * Attempts to build a certification path using the specified
+     * algorithm parameter set.
+     *
+     * @param params the algorithm parameters
+     * @return the result of the build algorithm
+     * @throws CertPathBuilderException if the builder is unable to construct
+     * a certification path that satisfies the specified parameters
+     * @throws InvalidAlgorithmParameterException if the specified parameters
+     * are inappropriate for this {@code CertPathBuilder}
+     */
+    public abstract CertPathBuilderResult engineBuild(CertPathParameters params)
+        throws CertPathBuilderException, InvalidAlgorithmParameterException;
+
+    /**
+     * Returns a {@code CertPathChecker} that this implementation uses to
+     * check the revocation status of certificates. A PKIX implementation
+     * returns objects of type {@code PKIXRevocationChecker}.
+     *
+     * <p>The primary purpose of this method is to allow callers to specify
+     * additional input parameters and options specific to revocation checking.
+     * See the class description of {@code CertPathBuilder} for an example.
+     *
+     * <p>This method was added to version 1.8 of the Java Platform Standard
+     * Edition. In order to maintain backwards compatibility with existing
+     * service providers, this method cannot be abstract and by default throws
+     * an {@code UnsupportedOperationException}.
+     *
+     * @return a {@code CertPathChecker} that this implementation uses to
+     * check the revocation status of certificates
+     * @throws UnsupportedOperationException if this method is not supported
+     * @since 1.8
+     */
+    public CertPathChecker engineGetRevocationChecker() {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/java/security/cert/CertPathChecker.java b/java/security/cert/CertPathChecker.java
new file mode 100644
index 0000000..c40a65b
--- /dev/null
+++ b/java/security/cert/CertPathChecker.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2012, 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 java.security.cert;
+
+/**
+ * <p>Performs one or more checks on each {@code Certificate} of a
+ * {@code CertPath}.
+ *
+ * <p>A {@code CertPathChecker} implementation is typically created to extend
+ * a certification path validation algorithm. For example, an implementation
+ * may check for and process a critical private extension of each certificate
+ * in a certification path.
+ *
+ * @since 1.8
+ */
+public interface CertPathChecker {
+
+    /**
+     * Initializes the internal state of this {@code CertPathChecker}.
+     *
+     * <p>The {@code forward} flag specifies the order that certificates will
+     * be passed to the {@link #check check} method (forward or reverse).
+     *
+     * @param forward the order that certificates are presented to the
+     *        {@code check} method. If {@code true}, certificates are
+     *        presented from target to trust anchor (forward); if
+     *        {@code false}, from trust anchor to target (reverse).
+     * @throws CertPathValidatorException if this {@code CertPathChecker} is
+     *         unable to check certificates in the specified order
+     */
+    void init(boolean forward) throws CertPathValidatorException;
+
+    /**
+     * Indicates if forward checking is supported. Forward checking refers
+     * to the ability of the {@code CertPathChecker} to perform its checks
+     * when certificates are presented to the {@code check} method in the
+     * forward direction (from target to trust anchor).
+     *
+     * @return {@code true} if forward checking is supported, {@code false}
+     *         otherwise
+     */
+    boolean isForwardCheckingSupported();
+
+    /**
+     * Performs the check(s) on the specified certificate using its internal
+     * state. The certificates are presented in the order specified by the
+     * {@code init} method.
+     *
+     * @param cert the {@code Certificate} to be checked
+     * @throws CertPathValidatorException if the specified certificate does
+     *         not pass the check
+     */
+    void check(Certificate cert) throws CertPathValidatorException;
+}
diff --git a/java/security/cert/CertPathHelperImpl.java b/java/security/cert/CertPathHelperImpl.java
new file mode 100644
index 0000000..fd9e111
--- /dev/null
+++ b/java/security/cert/CertPathHelperImpl.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2002, 2009, 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 java.security.cert;
+
+import java.util.*;
+
+import sun.security.provider.certpath.CertPathHelper;
+
+import sun.security.x509.GeneralNameInterface;
+
+/**
+ * Helper class that allows the Sun CertPath provider to access
+ * implementation dependent APIs in CertPath framework.
+ *
+ * @author Andreas Sterbenz
+ */
+class CertPathHelperImpl extends CertPathHelper {
+
+    private CertPathHelperImpl() {
+        // empty
+    }
+
+    /**
+     * Initialize the helper framework. This method must be called from
+     * the static initializer of each class that is the target of one of
+     * the methods in this class. This ensures that the helper is initialized
+     * prior to a tunneled call from the Sun provider.
+     */
+    synchronized static void initialize() {
+        if (CertPathHelper.instance == null) {
+            CertPathHelper.instance = new CertPathHelperImpl();
+        }
+    }
+
+    protected void implSetPathToNames(X509CertSelector sel,
+            Set<GeneralNameInterface> names) {
+        sel.setPathToNamesInternal(names);
+    }
+
+    protected void implSetDateAndTime(X509CRLSelector sel, Date date, long skew) {
+        sel.setDateAndTime(date, skew);
+    }
+}
diff --git a/java/security/cert/CertPathParameters.java b/java/security/cert/CertPathParameters.java
new file mode 100644
index 0000000..ace1b21
--- /dev/null
+++ b/java/security/cert/CertPathParameters.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2000, 2013, 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 java.security.cert;
+
+/**
+ * A specification of certification path algorithm parameters.
+ * The purpose of this interface is to group (and provide type safety for)
+ * all {@code CertPath} parameter specifications. All
+ * {@code CertPath} parameter specifications must implement this
+ * interface.
+ *
+ * @author      Yassir Elley
+ * @see         CertPathValidator#validate(CertPath, CertPathParameters)
+ * @see         CertPathBuilder#build(CertPathParameters)
+ * @since       1.4
+ */
+public interface CertPathParameters extends Cloneable {
+
+  /**
+   * Makes a copy of this {@code CertPathParameters}. Changes to the
+   * copy will not affect the original and vice versa.
+   *
+   * @return a copy of this {@code CertPathParameters}
+   */
+  Object clone();
+}
diff --git a/java/security/cert/CertPathValidator.java b/java/security/cert/CertPathValidator.java
new file mode 100644
index 0000000..3a4b053
--- /dev/null
+++ b/java/security/cert/CertPathValidator.java
@@ -0,0 +1,352 @@
+/*
+ * Copyright (c) 2000, 2013, 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 java.security.cert;
+
+import java.security.AccessController;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivilegedAction;
+import java.security.Provider;
+import java.security.Security;
+import sun.security.util.Debug;
+
+import sun.security.jca.*;
+import sun.security.jca.GetInstance.Instance;
+
+/**
+ * A class for validating certification paths (also known as certificate
+ * chains).
+ * <p>
+ * This class uses a provider-based architecture.
+ * To create a {@code CertPathValidator},
+ * call one of the static {@code getInstance} methods, passing in the
+ * algorithm name of the {@code CertPathValidator} desired and
+ * optionally the name of the provider desired.
+ *
+ * <p>Once a {@code CertPathValidator} object has been created, it can
+ * be used to validate certification paths by calling the {@link #validate
+ * validate} method and passing it the {@code CertPath} to be validated
+ * and an algorithm-specific set of parameters. If successful, the result is
+ * returned in an object that implements the
+ * {@code CertPathValidatorResult} interface.
+ *
+ * <p>The {@link #getRevocationChecker} method allows an application to specify
+ * additional algorithm-specific parameters and options used by the
+ * {@code CertPathValidator} when checking the revocation status of
+ * certificates. Here is an example demonstrating how it is used with the PKIX
+ * algorithm:
+ *
+ * <pre>
+ * CertPathValidator cpv = CertPathValidator.getInstance("PKIX");
+ * PKIXRevocationChecker rc = (PKIXRevocationChecker)cpv.getRevocationChecker();
+ * rc.setOptions(EnumSet.of(Option.SOFT_FAIL));
+ * params.addCertPathChecker(rc);
+ * CertPathValidatorResult cpvr = cpv.validate(path, params);
+ * </pre>
+ *
+ * <p> Android provides the following {@code CertPathValidator} algorithms:
+ * <table>
+ *   <thead>
+ *     <tr>
+ *       <th>Algorithm</th>
+ *       <th>Supported API Levels</th>
+ *     </tr>
+ *   </thead>
+ *   <tbody>
+ *     <tr>
+ *       <td>PKIX</td>
+ *       <td>1+</td>
+ *     </tr>
+ *   </tbody>
+ * </table>
+ *
+ * This algorithm is described in the <a href=
+ * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertPathValidator">
+ * CertPathValidator section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ *
+ * <p>
+ * <b>Concurrent Access</b>
+ * <p>
+ * The static methods of this class are guaranteed to be thread-safe.
+ * Multiple threads may concurrently invoke the static methods defined in
+ * this class with no ill effects.
+ * <p>
+ * However, this is not true for the non-static methods defined by this class.
+ * Unless otherwise documented by a specific provider, threads that need to
+ * access a single {@code CertPathValidator} instance concurrently should
+ * synchronize amongst themselves and provide the necessary locking. Multiple
+ * threads each manipulating a different {@code CertPathValidator}
+ * instance need not synchronize.
+ *
+ * @see CertPath
+ *
+ * @since       1.4
+ * @author      Yassir Elley
+ */
+public class CertPathValidator {
+
+    /*
+     * Constant to lookup in the Security properties file to determine
+     * the default certpathvalidator type. In the Security properties file,
+     * the default certpathvalidator type is given as:
+     * <pre>
+     * certpathvalidator.type=PKIX
+     * </pre>
+     */
+    private static final String CPV_TYPE = "certpathvalidator.type";
+    private final CertPathValidatorSpi validatorSpi;
+    private final Provider provider;
+    private final String algorithm;
+
+    /**
+     * Creates a {@code CertPathValidator} object of the given algorithm,
+     * and encapsulates the given provider implementation (SPI object) in it.
+     *
+     * @param validatorSpi the provider implementation
+     * @param provider the provider
+     * @param algorithm the algorithm name
+     */
+    protected CertPathValidator(CertPathValidatorSpi validatorSpi,
+        Provider provider, String algorithm)
+    {
+        this.validatorSpi = validatorSpi;
+        this.provider = provider;
+        this.algorithm = algorithm;
+    }
+
+    /**
+     * Returns a {@code CertPathValidator} object that implements the
+     * specified algorithm.
+     *
+     * <p> This method traverses the list of registered security Providers,
+     * starting with the most preferred Provider.
+     * A new CertPathValidator object encapsulating the
+     * CertPathValidatorSpi implementation from the first
+     * Provider that supports the specified algorithm is returned.
+     *
+     * <p> Note that the list of registered providers may be retrieved via
+     * the {@link Security#getProviders() Security.getProviders()} method.
+     *
+     * @param algorithm the name of the requested {@code CertPathValidator}
+     *  algorithm. See the CertPathValidator section in the <a href=
+     *  "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertPathValidator">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard algorithm names.
+     *
+     * @return a {@code CertPathValidator} object that implements the
+     *          specified algorithm.
+     *
+     * @exception NoSuchAlgorithmException if no Provider supports a
+     *          CertPathValidatorSpi implementation for the
+     *          specified algorithm.
+     *
+     * @see java.security.Provider
+     */
+    public static CertPathValidator getInstance(String algorithm)
+            throws NoSuchAlgorithmException {
+        Instance instance = GetInstance.getInstance("CertPathValidator",
+            CertPathValidatorSpi.class, algorithm);
+        return new CertPathValidator((CertPathValidatorSpi)instance.impl,
+            instance.provider, algorithm);
+    }
+
+    /**
+     * Returns a {@code CertPathValidator} object that implements the
+     * specified algorithm.
+     *
+     * <p> A new CertPathValidator object encapsulating the
+     * CertPathValidatorSpi implementation from the specified provider
+     * is returned.  The specified provider must be registered
+     * in the security provider list.
+     *
+     * <p> Note that the list of registered providers may be retrieved via
+     * the {@link Security#getProviders() Security.getProviders()} method.
+     *
+     * @param algorithm the name of the requested {@code CertPathValidator}
+     *  algorithm. See the CertPathValidator section in the <a href=
+     *  "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertPathValidator">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard algorithm names.
+     *
+     * @param provider the name of the provider.
+     *
+     * @return a {@code CertPathValidator} object that implements the
+     *          specified algorithm.
+     *
+     * @exception NoSuchAlgorithmException if a CertPathValidatorSpi
+     *          implementation for the specified algorithm is not
+     *          available from the specified provider.
+     *
+     * @exception NoSuchProviderException if the specified provider is not
+     *          registered in the security provider list.
+     *
+     * @exception IllegalArgumentException if the {@code provider} is
+     *          null or empty.
+     *
+     * @see java.security.Provider
+     */
+    public static CertPathValidator getInstance(String algorithm,
+            String provider) throws NoSuchAlgorithmException,
+            NoSuchProviderException {
+        Instance instance = GetInstance.getInstance("CertPathValidator",
+            CertPathValidatorSpi.class, algorithm, provider);
+        return new CertPathValidator((CertPathValidatorSpi)instance.impl,
+            instance.provider, algorithm);
+    }
+
+    /**
+     * Returns a {@code CertPathValidator} object that implements the
+     * specified algorithm.
+     *
+     * <p> A new CertPathValidator object encapsulating the
+     * CertPathValidatorSpi implementation from the specified Provider
+     * object is returned.  Note that the specified Provider object
+     * does not have to be registered in the provider list.
+     *
+     * @param algorithm the name of the requested {@code CertPathValidator}
+     * algorithm. See the CertPathValidator section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertPathValidator">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard algorithm names.
+     *
+     * @param provider the provider.
+     *
+     * @return a {@code CertPathValidator} object that implements the
+     *          specified algorithm.
+     *
+     * @exception NoSuchAlgorithmException if a CertPathValidatorSpi
+     *          implementation for the specified algorithm is not available
+     *          from the specified Provider object.
+     *
+     * @exception IllegalArgumentException if the {@code provider} is
+     *          null.
+     *
+     * @see java.security.Provider
+     */
+    public static CertPathValidator getInstance(String algorithm,
+            Provider provider) throws NoSuchAlgorithmException {
+        Instance instance = GetInstance.getInstance("CertPathValidator",
+            CertPathValidatorSpi.class, algorithm, provider);
+        return new CertPathValidator((CertPathValidatorSpi)instance.impl,
+            instance.provider, algorithm);
+    }
+
+    /**
+     * Returns the {@code Provider} of this
+     * {@code CertPathValidator}.
+     *
+     * @return the {@code Provider} of this {@code CertPathValidator}
+     */
+    public final Provider getProvider() {
+        return this.provider;
+    }
+
+    /**
+     * Returns the algorithm name of this {@code CertPathValidator}.
+     *
+     * @return the algorithm name of this {@code CertPathValidator}
+     */
+    public final String getAlgorithm() {
+        return this.algorithm;
+    }
+
+    /**
+     * Validates the specified certification path using the specified
+     * algorithm parameter set.
+     * <p>
+     * The {@code CertPath} specified must be of a type that is
+     * supported by the validation algorithm, otherwise an
+     * {@code InvalidAlgorithmParameterException} will be thrown. For
+     * example, a {@code CertPathValidator} that implements the PKIX
+     * algorithm validates {@code CertPath} objects of type X.509.
+     *
+     * @param certPath the {@code CertPath} to be validated
+     * @param params the algorithm parameters
+     * @return the result of the validation algorithm
+     * @exception CertPathValidatorException if the {@code CertPath}
+     * does not validate
+     * @exception InvalidAlgorithmParameterException if the specified
+     * parameters or the type of the specified {@code CertPath} are
+     * inappropriate for this {@code CertPathValidator}
+     */
+    public final CertPathValidatorResult validate(CertPath certPath,
+        CertPathParameters params)
+        throws CertPathValidatorException, InvalidAlgorithmParameterException
+    {
+        return validatorSpi.engineValidate(certPath, params);
+    }
+
+    /**
+     * Returns the default {@code CertPathValidator} type as specified by
+     * the {@code certpathvalidator.type} security property, or the string
+     * {@literal "PKIX"} if no such property exists.
+     *
+     * <p>The default {@code CertPathValidator} type can be used by
+     * applications that do not want to use a hard-coded type when calling one
+     * of the {@code getInstance} methods, and want to provide a default
+     * type in case a user does not specify its own.
+     *
+     * <p>The default {@code CertPathValidator} type can be changed by
+     * setting the value of the {@code certpathvalidator.type} security
+     * property to the desired type.
+     *
+     * @see java.security.Security security properties
+     * @return the default {@code CertPathValidator} type as specified
+     * by the {@code certpathvalidator.type} security property, or the string
+     * {@literal "PKIX"} if no such property exists.
+     */
+    public final static String getDefaultType() {
+        String cpvtype =
+            AccessController.doPrivileged(new PrivilegedAction<String>() {
+                public String run() {
+                    return Security.getProperty(CPV_TYPE);
+                }
+            });
+        return (cpvtype == null) ? "PKIX" : cpvtype;
+    }
+
+    /**
+     * Returns a {@code CertPathChecker} that the encapsulated
+     * {@code CertPathValidatorSpi} implementation uses to check the revocation
+     * status of certificates. A PKIX implementation returns objects of
+     * type {@code PKIXRevocationChecker}. Each invocation of this method
+     * returns a new instance of {@code CertPathChecker}.
+     *
+     * <p>The primary purpose of this method is to allow callers to specify
+     * additional input parameters and options specific to revocation checking.
+     * See the class description for an example.
+     *
+     * @return a {@code CertPathChecker}
+     * @throws UnsupportedOperationException if the service provider does not
+     *         support this method
+     * @since 1.8
+     */
+    public final CertPathChecker getRevocationChecker() {
+        return validatorSpi.engineGetRevocationChecker();
+    }
+}
diff --git a/java/security/cert/CertPathValidatorException.java b/java/security/cert/CertPathValidatorException.java
new file mode 100644
index 0000000..7e6b916
--- /dev/null
+++ b/java/security/cert/CertPathValidatorException.java
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 2000, 2013, 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 java.security.cert;
+
+import java.io.InvalidObjectException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.security.GeneralSecurityException;
+
+/**
+ * An exception indicating one of a variety of problems encountered when
+ * validating a certification path.
+ * <p>
+ * A {@code CertPathValidatorException} provides support for wrapping
+ * exceptions. The {@link #getCause getCause} method returns the throwable,
+ * if any, that caused this exception to be thrown.
+ * <p>
+ * A {@code CertPathValidatorException} may also include the
+ * certification path that was being validated when the exception was thrown,
+ * the index of the certificate in the certification path that caused the
+ * exception to be thrown, and the reason that caused the failure. Use the
+ * {@link #getCertPath getCertPath}, {@link #getIndex getIndex}, and
+ * {@link #getReason getReason} methods to retrieve this information.
+ *
+ * <p>
+ * <b>Concurrent Access</b>
+ * <p>
+ * Unless otherwise specified, the methods defined in this class are not
+ * thread-safe. Multiple threads that need to access a single
+ * object concurrently should synchronize amongst themselves and
+ * provide the necessary locking. Multiple threads each manipulating
+ * separate objects need not synchronize.
+ *
+ * @see CertPathValidator
+ *
+ * @since       1.4
+ * @author      Yassir Elley
+ */
+public class CertPathValidatorException extends GeneralSecurityException {
+
+    private static final long serialVersionUID = -3083180014971893139L;
+
+    /**
+     * @serial the index of the certificate in the certification path
+     * that caused the exception to be thrown
+     */
+    private int index = -1;
+
+    /**
+     * @serial the {@code CertPath} that was being validated when
+     * the exception was thrown
+     */
+    private CertPath certPath;
+
+    /**
+     * @serial the reason the validation failed
+     */
+    private Reason reason = BasicReason.UNSPECIFIED;
+
+    /**
+     * Creates a {@code CertPathValidatorException} with
+     * no detail message.
+     */
+    public CertPathValidatorException() {
+        this(null, null);
+    }
+
+    /**
+     * Creates a {@code CertPathValidatorException} with the given
+     * detail message. A detail message is a {@code String} that
+     * describes this particular exception.
+     *
+     * @param msg the detail message
+     */
+    public CertPathValidatorException(String msg) {
+        this(msg, null);
+    }
+
+    /**
+     * Creates a {@code CertPathValidatorException} that wraps the
+     * specified throwable. This allows any exception to be converted into a
+     * {@code CertPathValidatorException}, while retaining information
+     * about the wrapped exception, which may be useful for debugging. The
+     * detail message is set to ({@code cause==null ? null : cause.toString()})
+     * (which typically contains the class and detail message of
+     * cause).
+     *
+     * @param cause the cause (which is saved for later retrieval by the
+     * {@link #getCause getCause()} method). (A {@code null} value is
+     * permitted, and indicates that the cause is nonexistent or unknown.)
+     */
+    public CertPathValidatorException(Throwable cause) {
+        this((cause == null ? null : cause.toString()), cause);
+    }
+
+    /**
+     * Creates a {@code CertPathValidatorException} with the specified
+     * detail message and cause.
+     *
+     * @param msg the detail message
+     * @param cause the cause (which is saved for later retrieval by the
+     * {@link #getCause getCause()} method). (A {@code null} value is
+     * permitted, and indicates that the cause is nonexistent or unknown.)
+     */
+    public CertPathValidatorException(String msg, Throwable cause) {
+        this(msg, cause, null, -1);
+    }
+
+    /**
+     * Creates a {@code CertPathValidatorException} with the specified
+     * detail message, cause, certification path, and index.
+     *
+     * @param msg the detail message (or {@code null} if none)
+     * @param cause the cause (or {@code null} if none)
+     * @param certPath the certification path that was in the process of
+     * being validated when the error was encountered
+     * @param index the index of the certificate in the certification path
+     * that caused the error (or -1 if not applicable). Note that
+     * the list of certificates in a {@code CertPath} is zero based.
+     * @throws IndexOutOfBoundsException if the index is out of range
+     * {@code (index < -1 || (certPath != null && index >=
+     * certPath.getCertificates().size()) }
+     * @throws IllegalArgumentException if {@code certPath} is
+     * {@code null} and {@code index} is not -1
+     */
+    public CertPathValidatorException(String msg, Throwable cause,
+            CertPath certPath, int index) {
+        this(msg, cause, certPath, index, BasicReason.UNSPECIFIED);
+    }
+
+    /**
+     * Creates a {@code CertPathValidatorException} with the specified
+     * detail message, cause, certification path, index, and reason.
+     *
+     * @param msg the detail message (or {@code null} if none)
+     * @param cause the cause (or {@code null} if none)
+     * @param certPath the certification path that was in the process of
+     * being validated when the error was encountered
+     * @param index the index of the certificate in the certification path
+     * that caused the error (or -1 if not applicable). Note that
+     * the list of certificates in a {@code CertPath} is zero based.
+     * @param reason the reason the validation failed
+     * @throws IndexOutOfBoundsException if the index is out of range
+     * {@code (index < -1 || (certPath != null && index >=
+     * certPath.getCertificates().size()) }
+     * @throws IllegalArgumentException if {@code certPath} is
+     * {@code null} and {@code index} is not -1
+     * @throws NullPointerException if {@code reason} is {@code null}
+     *
+     * @since 1.7
+     */
+    public CertPathValidatorException(String msg, Throwable cause,
+            CertPath certPath, int index, Reason reason) {
+        super(msg, cause);
+        if (certPath == null && index != -1) {
+            throw new IllegalArgumentException();
+        }
+        if (index < -1 ||
+            (certPath != null && index >= certPath.getCertificates().size())) {
+            throw new IndexOutOfBoundsException();
+        }
+        if (reason == null) {
+            throw new NullPointerException("reason can't be null");
+        }
+        this.certPath = certPath;
+        this.index = index;
+        this.reason = reason;
+    }
+
+    /**
+     * Returns the certification path that was being validated when
+     * the exception was thrown.
+     *
+     * @return the {@code CertPath} that was being validated when
+     * the exception was thrown (or {@code null} if not specified)
+     */
+    public CertPath getCertPath() {
+        return this.certPath;
+    }
+
+    /**
+     * Returns the index of the certificate in the certification path
+     * that caused the exception to be thrown. Note that the list of
+     * certificates in a {@code CertPath} is zero based. If no
+     * index has been set, -1 is returned.
+     *
+     * @return the index that has been set, or -1 if none has been set
+     */
+    public int getIndex() {
+        return this.index;
+    }
+
+    /**
+     * Returns the reason that the validation failed. The reason is
+     * associated with the index of the certificate returned by
+     * {@link #getIndex}.
+     *
+     * @return the reason that the validation failed, or
+     *    {@code BasicReason.UNSPECIFIED} if a reason has not been
+     *    specified
+     *
+     * @since 1.7
+     */
+    public Reason getReason() {
+        return this.reason;
+    }
+
+    private void readObject(ObjectInputStream stream)
+        throws ClassNotFoundException, IOException {
+        stream.defaultReadObject();
+        if (reason == null) {
+            reason = BasicReason.UNSPECIFIED;
+        }
+        if (certPath == null && index != -1) {
+            throw new InvalidObjectException("certpath is null and index != -1");
+        }
+        if (index < -1 ||
+            (certPath != null && index >= certPath.getCertificates().size())) {
+            throw new InvalidObjectException("index out of range");
+        }
+    }
+
+    /**
+     * The reason the validation algorithm failed.
+     *
+     * @since 1.7
+     */
+    public static interface Reason extends java.io.Serializable { }
+
+
+    /**
+     * The BasicReason enumerates the potential reasons that a certification
+     * path of any type may be invalid.
+     *
+     * @since 1.7
+     */
+    public static enum BasicReason implements Reason {
+        /**
+         * Unspecified reason.
+         */
+        UNSPECIFIED,
+
+        /**
+         * The certificate is expired.
+         */
+        EXPIRED,
+
+        /**
+         * The certificate is not yet valid.
+         */
+        NOT_YET_VALID,
+
+        /**
+         * The certificate is revoked.
+         */
+        REVOKED,
+
+        /**
+         * The revocation status of the certificate could not be determined.
+         */
+        UNDETERMINED_REVOCATION_STATUS,
+
+        /**
+         * The signature is invalid.
+         */
+        INVALID_SIGNATURE,
+
+        /**
+         * The public key or the signature algorithm has been constrained.
+         */
+        ALGORITHM_CONSTRAINED
+    }
+}
diff --git a/java/security/cert/CertPathValidatorResult.java b/java/security/cert/CertPathValidatorResult.java
new file mode 100644
index 0000000..ae07dc4
--- /dev/null
+++ b/java/security/cert/CertPathValidatorResult.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2000, 2013, 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 java.security.cert;
+
+/**
+ * A specification of the result of a certification path validator algorithm.
+ * <p>
+ * The purpose of this interface is to group (and provide type safety
+ * for) all certification path validator results. All results returned
+ * by the {@link CertPathValidator#validate CertPathValidator.validate}
+ * method must implement this interface.
+ *
+ * @see CertPathValidator
+ *
+ * @since       1.4
+ * @author      Yassir Elley
+ */
+public interface CertPathValidatorResult extends Cloneable {
+
+    /**
+     * Makes a copy of this {@code CertPathValidatorResult}. Changes to the
+     * copy will not affect the original and vice versa.
+     *
+     * @return a copy of this {@code CertPathValidatorResult}
+     */
+    Object clone();
+}
diff --git a/java/security/cert/CertPathValidatorSpi.java b/java/security/cert/CertPathValidatorSpi.java
new file mode 100644
index 0000000..02d503c
--- /dev/null
+++ b/java/security/cert/CertPathValidatorSpi.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2000, 2013, 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 java.security.cert;
+
+import java.security.InvalidAlgorithmParameterException;
+
+/**
+ *
+ * The <i>Service Provider Interface</i> (<b>SPI</b>)
+ * for the {@link CertPathValidator CertPathValidator} class. All
+ * {@code CertPathValidator} implementations must include a class (the
+ * SPI class) that extends this class ({@code CertPathValidatorSpi})
+ * and implements all of its methods. In general, instances of this class
+ * should only be accessed through the {@code CertPathValidator} class.
+ * For details, see the Java Cryptography Architecture.
+ * <p>
+ * <b>Concurrent Access</b>
+ * <p>
+ * Instances of this class need not be protected against concurrent
+ * access from multiple threads. Threads that need to access a single
+ * {@code CertPathValidatorSpi} instance concurrently should synchronize
+ * amongst themselves and provide the necessary locking before calling the
+ * wrapping {@code CertPathValidator} object.
+ * <p>
+ * However, implementations of {@code CertPathValidatorSpi} may still
+ * encounter concurrency issues, since multiple threads each
+ * manipulating a different {@code CertPathValidatorSpi} instance need not
+ * synchronize.
+ *
+ * @since       1.4
+ * @author      Yassir Elley
+ */
+public abstract class CertPathValidatorSpi {
+
+    /**
+     * The default constructor.
+     */
+    public CertPathValidatorSpi() {}
+
+    /**
+     * Validates the specified certification path using the specified
+     * algorithm parameter set.
+     * <p>
+     * The {@code CertPath} specified must be of a type that is
+     * supported by the validation algorithm, otherwise an
+     * {@code InvalidAlgorithmParameterException} will be thrown. For
+     * example, a {@code CertPathValidator} that implements the PKIX
+     * algorithm validates {@code CertPath} objects of type X.509.
+     *
+     * @param certPath the {@code CertPath} to be validated
+     * @param params the algorithm parameters
+     * @return the result of the validation algorithm
+     * @exception CertPathValidatorException if the {@code CertPath}
+     * does not validate
+     * @exception InvalidAlgorithmParameterException if the specified
+     * parameters or the type of the specified {@code CertPath} are
+     * inappropriate for this {@code CertPathValidator}
+     */
+    public abstract CertPathValidatorResult
+        engineValidate(CertPath certPath, CertPathParameters params)
+        throws CertPathValidatorException, InvalidAlgorithmParameterException;
+
+    /**
+     * Returns a {@code CertPathChecker} that this implementation uses to
+     * check the revocation status of certificates. A PKIX implementation
+     * returns objects of type {@code PKIXRevocationChecker}.
+     *
+     * <p>The primary purpose of this method is to allow callers to specify
+     * additional input parameters and options specific to revocation checking.
+     * See the class description of {@code CertPathValidator} for an example.
+     *
+     * <p>This method was added to version 1.8 of the Java Platform Standard
+     * Edition. In order to maintain backwards compatibility with existing
+     * service providers, this method cannot be abstract and by default throws
+     * an {@code UnsupportedOperationException}.
+     *
+     * @return a {@code CertPathChecker} that this implementation uses to
+     * check the revocation status of certificates
+     * @throws UnsupportedOperationException if this method is not supported
+     * @since 1.8
+     */
+    public CertPathChecker engineGetRevocationChecker() {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/java/security/cert/CertSelector.java b/java/security/cert/CertSelector.java
new file mode 100644
index 0000000..a06cc84
--- /dev/null
+++ b/java/security/cert/CertSelector.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2000, 2013, 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 java.security.cert;
+
+/**
+ * A selector that defines a set of criteria for selecting
+ * {@code Certificate}s. Classes that implement this interface
+ * are often used to specify which {@code Certificate}s should
+ * be retrieved from a {@code CertStore}.
+ * <p>
+ * <b>Concurrent Access</b>
+ * <p>
+ * Unless otherwise specified, the methods defined in this interface are not
+ * thread-safe. Multiple threads that need to access a single
+ * object concurrently should synchronize amongst themselves and
+ * provide the necessary locking. Multiple threads each manipulating
+ * separate objects need not synchronize.
+ *
+ * @see Certificate
+ * @see CertStore
+ * @see CertStore#getCertificates
+ *
+ * @author      Steve Hanna
+ * @since       1.4
+ */
+public interface CertSelector extends Cloneable {
+
+    /**
+     * Decides whether a {@code Certificate} should be selected.
+     *
+     * @param   cert    the {@code Certificate} to be checked
+     * @return  {@code true} if the {@code Certificate}
+     * should be selected, {@code false} otherwise
+     */
+    boolean match(Certificate cert);
+
+    /**
+     * Makes a copy of this {@code CertSelector}. Changes to the
+     * copy will not affect the original and vice versa.
+     *
+     * @return a copy of this {@code CertSelector}
+     */
+    Object clone();
+}
diff --git a/java/security/cert/CertStore.java b/java/security/cert/CertStore.java
new file mode 100644
index 0000000..047af77
--- /dev/null
+++ b/java/security/cert/CertStore.java
@@ -0,0 +1,431 @@
+/*
+ * Copyright (c) 2000, 2013, 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 java.security.cert;
+
+import java.security.AccessController;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivilegedAction;
+import java.security.Provider;
+import java.security.Security;
+import java.util.Collection;
+
+import sun.security.jca.*;
+import sun.security.jca.GetInstance.Instance;
+
+/**
+ * A class for retrieving {@code Certificate}s and {@code CRL}s
+ * from a repository.
+ * <p>
+ * This class uses a provider-based architecture.
+ * To create a {@code CertStore}, call one of the static
+ * {@code getInstance} methods, passing in the type of
+ * {@code CertStore} desired, any applicable initialization parameters
+ * and optionally the name of the provider desired.
+ * <p>
+ * Once the {@code CertStore} has been created, it can be used to
+ * retrieve {@code Certificate}s and {@code CRL}s by calling its
+ * {@link #getCertificates(CertSelector selector) getCertificates} and
+ * {@link #getCRLs(CRLSelector selector) getCRLs} methods.
+ * <p>
+ * Unlike a {@link java.security.KeyStore KeyStore}, which provides access
+ * to a cache of private keys and trusted certificates, a
+ * {@code CertStore} is designed to provide access to a potentially
+ * vast repository of untrusted certificates and CRLs. For example, an LDAP
+ * implementation of {@code CertStore} provides access to certificates
+ * and CRLs stored in one or more directories using the LDAP protocol and the
+ * schema as defined in the RFC service attribute.
+ *
+ * <p> Android provides the following <code>CertStore</code> types:
+ * <table>
+ *   <thead>
+ *     <tr>
+ *       <th>Algorithm</th>
+ *       <th>Supported API Levels</th>
+ *     </tr>
+ *   </thead>
+ *   <tbody>
+ *     <tr>
+ *       <td>Collection</td>
+ *       <td>1+</td>
+ *     </tr>
+ *   </tbody>
+ * </table>
+ *
+ * This type is described in the <a href=
+ * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertStore">
+ * CertStore section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ *
+ * <p>
+ * <b>Concurrent Access</b>
+ * <p>
+ * All public methods of {@code CertStore} objects must be thread-safe.
+ * That is, multiple threads may concurrently invoke these methods on a
+ * single {@code CertStore} object (or more than one) with no
+ * ill effects. This allows a {@code CertPathBuilder} to search for a
+ * CRL while simultaneously searching for further certificates, for instance.
+ * <p>
+ * The static methods of this class are also guaranteed to be thread-safe.
+ * Multiple threads may concurrently invoke the static methods defined in
+ * this class with no ill effects.
+ *
+ * @since       1.4
+ * @author      Sean Mullan, Steve Hanna
+ */
+public class CertStore {
+    /*
+     * Constant to lookup in the Security properties file to determine
+     * the default certstore type. In the Security properties file, the
+     * default certstore type is given as:
+     * <pre>
+     * certstore.type=LDAP
+     * </pre>
+     */
+    private static final String CERTSTORE_TYPE = "certstore.type";
+    private CertStoreSpi storeSpi;
+    private Provider provider;
+    private String type;
+    private CertStoreParameters params;
+
+    /**
+     * Creates a {@code CertStore} object of the given type, and
+     * encapsulates the given provider implementation (SPI object) in it.
+     *
+     * @param storeSpi the provider implementation
+     * @param provider the provider
+     * @param type the type
+     * @param params the initialization parameters (may be {@code null})
+     */
+    protected CertStore(CertStoreSpi storeSpi, Provider provider,
+                        String type, CertStoreParameters params) {
+        this.storeSpi = storeSpi;
+        this.provider = provider;
+        this.type = type;
+        if (params != null)
+            this.params = (CertStoreParameters) params.clone();
+    }
+
+    /**
+     * Returns a {@code Collection} of {@code Certificate}s that
+     * match the specified selector. If no {@code Certificate}s
+     * match the selector, an empty {@code Collection} will be returned.
+     * <p>
+     * For some {@code CertStore} types, the resulting
+     * {@code Collection} may not contain <b>all</b> of the
+     * {@code Certificate}s that match the selector. For instance,
+     * an LDAP {@code CertStore} may not search all entries in the
+     * directory. Instead, it may just search entries that are likely to
+     * contain the {@code Certificate}s it is looking for.
+     * <p>
+     * Some {@code CertStore} implementations (especially LDAP
+     * {@code CertStore}s) may throw a {@code CertStoreException}
+     * unless a non-null {@code CertSelector} is provided that
+     * includes specific criteria that can be used to find the certificates.
+     * Issuer and/or subject names are especially useful criteria.
+     *
+     * @param selector A {@code CertSelector} used to select which
+     *  {@code Certificate}s should be returned. Specify {@code null}
+     *  to return all {@code Certificate}s (if supported).
+     * @return A {@code Collection} of {@code Certificate}s that
+     *         match the specified selector (never {@code null})
+     * @throws CertStoreException if an exception occurs
+     */
+    public final Collection<? extends Certificate> getCertificates
+            (CertSelector selector) throws CertStoreException {
+        return storeSpi.engineGetCertificates(selector);
+    }
+
+    /**
+     * Returns a {@code Collection} of {@code CRL}s that
+     * match the specified selector. If no {@code CRL}s
+     * match the selector, an empty {@code Collection} will be returned.
+     * <p>
+     * For some {@code CertStore} types, the resulting
+     * {@code Collection} may not contain <b>all</b> of the
+     * {@code CRL}s that match the selector. For instance,
+     * an LDAP {@code CertStore} may not search all entries in the
+     * directory. Instead, it may just search entries that are likely to
+     * contain the {@code CRL}s it is looking for.
+     * <p>
+     * Some {@code CertStore} implementations (especially LDAP
+     * {@code CertStore}s) may throw a {@code CertStoreException}
+     * unless a non-null {@code CRLSelector} is provided that
+     * includes specific criteria that can be used to find the CRLs.
+     * Issuer names and/or the certificate to be checked are especially useful.
+     *
+     * @param selector A {@code CRLSelector} used to select which
+     *  {@code CRL}s should be returned. Specify {@code null}
+     *  to return all {@code CRL}s (if supported).
+     * @return A {@code Collection} of {@code CRL}s that
+     *         match the specified selector (never {@code null})
+     * @throws CertStoreException if an exception occurs
+     */
+    public final Collection<? extends CRL> getCRLs(CRLSelector selector)
+            throws CertStoreException {
+        return storeSpi.engineGetCRLs(selector);
+    }
+
+    /**
+     * Returns a {@code CertStore} object that implements the specified
+     * {@code CertStore} type and is initialized with the specified
+     * parameters.
+     *
+     * <p> This method traverses the list of registered security Providers,
+     * starting with the most preferred Provider.
+     * A new CertStore object encapsulating the
+     * CertStoreSpi implementation from the first
+     * Provider that supports the specified type is returned.
+     *
+     * <p> Note that the list of registered providers may be retrieved via
+     * the {@link Security#getProviders() Security.getProviders()} method.
+     *
+     * <p>The {@code CertStore} that is returned is initialized with the
+     * specified {@code CertStoreParameters}. The type of parameters
+     * needed may vary between different types of {@code CertStore}s.
+     * Note that the specified {@code CertStoreParameters} object is
+     * cloned.
+     *
+     * @param type the name of the requested {@code CertStore} type.
+     * See the CertStore section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertStore">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard types.
+     *
+     * @param params the initialization parameters (may be {@code null}).
+     *
+     * @return a {@code CertStore} object that implements the specified
+     *          {@code CertStore} type.
+     *
+     * @throws NoSuchAlgorithmException if no Provider supports a
+     *          CertStoreSpi implementation for the specified type.
+     *
+     * @throws InvalidAlgorithmParameterException if the specified
+     *          initialization parameters are inappropriate for this
+     *          {@code CertStore}.
+     *
+     * @see java.security.Provider
+     */
+    public static CertStore getInstance(String type, CertStoreParameters params)
+            throws InvalidAlgorithmParameterException,
+            NoSuchAlgorithmException {
+        try {
+            Instance instance = GetInstance.getInstance("CertStore",
+                CertStoreSpi.class, type, params);
+            return new CertStore((CertStoreSpi)instance.impl,
+                instance.provider, type, params);
+        } catch (NoSuchAlgorithmException e) {
+            return handleException(e);
+        }
+    }
+
+    private static CertStore handleException(NoSuchAlgorithmException e)
+            throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
+        Throwable cause = e.getCause();
+        if (cause instanceof InvalidAlgorithmParameterException) {
+            throw (InvalidAlgorithmParameterException)cause;
+        }
+        throw e;
+    }
+
+    /**
+     * Returns a {@code CertStore} object that implements the specified
+     * {@code CertStore} type.
+     *
+     * <p> A new CertStore object encapsulating the
+     * CertStoreSpi implementation from the specified provider
+     * is returned.  The specified provider must be registered
+     * in the security provider list.
+     *
+     * <p> Note that the list of registered providers may be retrieved via
+     * the {@link Security#getProviders() Security.getProviders()} method.
+     *
+     * <p>The {@code CertStore} that is returned is initialized with the
+     * specified {@code CertStoreParameters}. The type of parameters
+     * needed may vary between different types of {@code CertStore}s.
+     * Note that the specified {@code CertStoreParameters} object is
+     * cloned.
+     *
+     * @param type the requested {@code CertStore} type.
+     * See the CertStore section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertStore">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard types.
+     *
+     * @param params the initialization parameters (may be {@code null}).
+     *
+     * @param provider the name of the provider.
+     *
+     * @return a {@code CertStore} object that implements the
+     *          specified type.
+     *
+     * @throws NoSuchAlgorithmException if a CertStoreSpi
+     *          implementation for the specified type is not
+     *          available from the specified provider.
+     *
+     * @throws InvalidAlgorithmParameterException if the specified
+     *          initialization parameters are inappropriate for this
+     *          {@code CertStore}.
+     *
+     * @throws NoSuchProviderException if the specified provider is not
+     *          registered in the security provider list.
+     *
+     * @exception IllegalArgumentException if the {@code provider} is
+     *          null or empty.
+     *
+     * @see java.security.Provider
+     */
+    public static CertStore getInstance(String type,
+            CertStoreParameters params, String provider)
+            throws InvalidAlgorithmParameterException,
+            NoSuchAlgorithmException, NoSuchProviderException {
+        try {
+            Instance instance = GetInstance.getInstance("CertStore",
+                CertStoreSpi.class, type, params, provider);
+            return new CertStore((CertStoreSpi)instance.impl,
+                instance.provider, type, params);
+        } catch (NoSuchAlgorithmException e) {
+            return handleException(e);
+        }
+    }
+
+    /**
+     * Returns a {@code CertStore} object that implements the specified
+     * {@code CertStore} type.
+     *
+     * <p> A new CertStore object encapsulating the
+     * CertStoreSpi implementation from the specified Provider
+     * object is returned.  Note that the specified Provider object
+     * does not have to be registered in the provider list.
+     *
+     * <p>The {@code CertStore} that is returned is initialized with the
+     * specified {@code CertStoreParameters}. The type of parameters
+     * needed may vary between different types of {@code CertStore}s.
+     * Note that the specified {@code CertStoreParameters} object is
+     * cloned.
+     *
+     * @param type the requested {@code CertStore} type.
+     * See the CertStore section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertStore">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard types.
+     *
+     * @param params the initialization parameters (may be {@code null}).
+     *
+     * @param provider the provider.
+     *
+     * @return a {@code CertStore} object that implements the
+     *          specified type.
+     *
+     * @exception NoSuchAlgorithmException if a CertStoreSpi
+     *          implementation for the specified type is not available
+     *          from the specified Provider object.
+     *
+     * @throws InvalidAlgorithmParameterException if the specified
+     *          initialization parameters are inappropriate for this
+     *          {@code CertStore}
+     *
+     * @exception IllegalArgumentException if the {@code provider} is
+     *          null.
+     *
+     * @see java.security.Provider
+     */
+    public static CertStore getInstance(String type, CertStoreParameters params,
+            Provider provider) throws NoSuchAlgorithmException,
+            InvalidAlgorithmParameterException {
+        try {
+            Instance instance = GetInstance.getInstance("CertStore",
+                CertStoreSpi.class, type, params, provider);
+            return new CertStore((CertStoreSpi)instance.impl,
+                instance.provider, type, params);
+        } catch (NoSuchAlgorithmException e) {
+            return handleException(e);
+        }
+    }
+
+    /**
+     * Returns the parameters used to initialize this {@code CertStore}.
+     * Note that the {@code CertStoreParameters} object is cloned before
+     * it is returned.
+     *
+     * @return the parameters used to initialize this {@code CertStore}
+     * (may be {@code null})
+     */
+    public final CertStoreParameters getCertStoreParameters() {
+        return (params == null ? null : (CertStoreParameters) params.clone());
+    }
+
+    /**
+     * Returns the type of this {@code CertStore}.
+     *
+     * @return the type of this {@code CertStore}
+     */
+    public final String getType() {
+        return this.type;
+    }
+
+    /**
+     * Returns the provider of this {@code CertStore}.
+     *
+     * @return the provider of this {@code CertStore}
+     */
+    public final Provider getProvider() {
+        return this.provider;
+    }
+
+    /**
+     * Returns the default {@code CertStore} type as specified by the
+     * {@code certstore.type} security property, or the string
+     * {@literal "LDAP"} if no such property exists.
+     *
+     * <p>The default {@code CertStore} type can be used by applications
+     * that do not want to use a hard-coded type when calling one of the
+     * {@code getInstance} methods, and want to provide a default
+     * {@code CertStore} type in case a user does not specify its own.
+     *
+     * <p>The default {@code CertStore} type can be changed by setting
+     * the value of the {@code certstore.type} security property to the
+     * desired type.
+     *
+     * @see java.security.Security security properties
+     * @return the default {@code CertStore} type as specified by the
+     * {@code certstore.type} security property, or the string
+     * {@literal "LDAP"} if no such property exists.
+     */
+    public final static String getDefaultType() {
+        String cstype;
+        cstype = AccessController.doPrivileged(new PrivilegedAction<String>() {
+            public String run() {
+                return Security.getProperty(CERTSTORE_TYPE);
+            }
+        });
+        if (cstype == null) {
+            cstype = "LDAP";
+        }
+        return cstype;
+    }
+}
diff --git a/java/security/cert/CertStoreException.java b/java/security/cert/CertStoreException.java
new file mode 100644
index 0000000..77b1c23
--- /dev/null
+++ b/java/security/cert/CertStoreException.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2000, 2013, 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 java.security.cert;
+
+import java.security.GeneralSecurityException;
+
+/**
+ * An exception indicating one of a variety of problems retrieving
+ * certificates and CRLs from a {@code CertStore}.
+ * <p>
+ * A {@code CertStoreException} provides support for wrapping
+ * exceptions. The {@link #getCause getCause} method returns the throwable,
+ * if any, that caused this exception to be thrown.
+ * <p>
+ * <b>Concurrent Access</b>
+ * <p>
+ * Unless otherwise specified, the methods defined in this class are not
+ * thread-safe. Multiple threads that need to access a single
+ * object concurrently should synchronize amongst themselves and
+ * provide the necessary locking. Multiple threads each manipulating
+ * separate objects need not synchronize.
+ *
+ * @see CertStore
+ *
+ * @since       1.4
+ * @author      Sean Mullan
+ */
+public class CertStoreException extends GeneralSecurityException {
+
+    private static final long serialVersionUID = 2395296107471573245L;
+
+    /**
+     * Creates a {@code CertStoreException} with {@code null} as
+     * its detail message.
+     */
+    public CertStoreException() {
+        super();
+    }
+
+    /**
+     * Creates a {@code CertStoreException} with the given detail
+     * message. A detail message is a {@code String} that describes this
+     * particular exception.
+     *
+     * @param msg the detail message
+     */
+    public CertStoreException(String msg) {
+        super(msg);
+    }
+
+    /**
+     * Creates a {@code CertStoreException} that wraps the specified
+     * throwable. This allows any exception to be converted into a
+     * {@code CertStoreException}, while retaining information about the
+     * cause, which may be useful for debugging. The detail message is
+     * set to ({@code cause==null ? null : cause.toString()}) (which
+     * typically contains the class and detail message of cause).
+     *
+     * @param cause the cause (which is saved for later retrieval by the
+     * {@link #getCause getCause()} method). (A {@code null} value is
+     * permitted, and indicates that the cause is nonexistent or unknown.)
+     */
+    public CertStoreException(Throwable cause) {
+        super(cause);
+    }
+
+    /**
+     * Creates a {@code CertStoreException} with the specified detail
+     * message and cause.
+     *
+     * @param msg the detail message
+     * @param cause the cause (which is saved for later retrieval by the
+     * {@link #getCause getCause()} method). (A {@code null} value is
+     * permitted, and indicates that the cause is nonexistent or unknown.)
+     */
+    public CertStoreException(String msg, Throwable cause) {
+        super(msg, cause);
+    }
+
+}
diff --git a/java/security/cert/CertStoreParameters.java b/java/security/cert/CertStoreParameters.java
new file mode 100644
index 0000000..9938ba2
--- /dev/null
+++ b/java/security/cert/CertStoreParameters.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2000, 2013, 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 java.security.cert;
+
+/**
+ * A specification of {@code CertStore} parameters.
+ * <p>
+ * The purpose of this interface is to group (and provide type safety for)
+ * all {@code CertStore} parameter specifications. All
+ * {@code CertStore} parameter specifications must implement this
+ * interface.
+ * <p>
+ * Typically, a {@code CertStoreParameters} object is passed as a parameter
+ * to one of the {@link CertStore#getInstance CertStore.getInstance} methods.
+ * The {@code getInstance} method returns a {@code CertStore} that
+ * is used for retrieving {@code Certificate}s and {@code CRL}s. The
+ * {@code CertStore} that is returned is initialized with the specified
+ * parameters. The type of parameters needed may vary between different types
+ * of {@code CertStore}s.
+ *
+ * @see CertStore#getInstance
+ *
+ * @since       1.4
+ * @author      Steve Hanna
+ */
+public interface CertStoreParameters extends Cloneable {
+
+    /**
+     * Makes a copy of this {@code CertStoreParameters}.
+     * <p>
+     * The precise meaning of "copy" may depend on the class of
+     * the {@code CertStoreParameters} object. A typical implementation
+     * performs a "deep copy" of this object, but this is not an absolute
+     * requirement. Some implementations may perform a "shallow copy" of some
+     * or all of the fields of this object.
+     * <p>
+     * Note that the {@code CertStore.getInstance} methods make a copy
+     * of the specified {@code CertStoreParameters}. A deep copy
+     * implementation of {@code clone} is safer and more robust, as it
+     * prevents the caller from corrupting a shared {@code CertStore} by
+     * subsequently modifying the contents of its initialization parameters.
+     * However, a shallow copy implementation of {@code clone} is more
+     * appropriate for applications that need to hold a reference to a
+     * parameter contained in the {@code CertStoreParameters}. For example,
+     * a shallow copy clone allows an application to release the resources of
+     * a particular {@code CertStore} initialization parameter immediately,
+     * rather than waiting for the garbage collection mechanism. This should
+     * be done with the utmost care, since the {@code CertStore} may still
+     * be in use by other threads.
+     * <p>
+     * Each subclass should state the precise behavior of this method so
+     * that users and developers know what to expect.
+     *
+     * @return a copy of this {@code CertStoreParameters}
+     */
+    Object clone();
+}
diff --git a/java/security/cert/CertStoreSpi.java b/java/security/cert/CertStoreSpi.java
new file mode 100644
index 0000000..fc98e9e
--- /dev/null
+++ b/java/security/cert/CertStoreSpi.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2000, 2013, 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 java.security.cert;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.util.Collection;
+
+/**
+ * The <i>Service Provider Interface</i> (<b>SPI</b>)
+ * for the {@link CertStore CertStore} class. All {@code CertStore}
+ * implementations must include a class (the SPI class) that extends
+ * this class ({@code CertStoreSpi}), provides a constructor with
+ * a single argument of type {@code CertStoreParameters}, and implements
+ * all of its methods. In general, instances of this class should only be
+ * accessed through the {@code CertStore} class.
+ * For details, see the Java Cryptography Architecture.
+ * <p>
+ * <b>Concurrent Access</b>
+ * <p>
+ * The public methods of all {@code CertStoreSpi} objects must be
+ * thread-safe. That is, multiple threads may concurrently invoke these
+ * methods on a single {@code CertStoreSpi} object (or more than one)
+ * with no ill effects. This allows a {@code CertPathBuilder} to search
+ * for a CRL while simultaneously searching for further certificates, for
+ * instance.
+ * <p>
+ * Simple {@code CertStoreSpi} implementations will probably ensure
+ * thread safety by adding a {@code synchronized} keyword to their
+ * {@code engineGetCertificates} and {@code engineGetCRLs} methods.
+ * More sophisticated ones may allow truly concurrent access.
+ *
+ * @since       1.4
+ * @author      Steve Hanna
+ */
+public abstract class CertStoreSpi {
+
+    /**
+     * The sole constructor.
+     *
+     * @param params the initialization parameters (may be {@code null})
+     * @throws InvalidAlgorithmParameterException if the initialization
+     * parameters are inappropriate for this {@code CertStoreSpi}
+     */
+    public CertStoreSpi(CertStoreParameters params)
+    throws InvalidAlgorithmParameterException { }
+
+    /**
+     * Returns a {@code Collection} of {@code Certificate}s that
+     * match the specified selector. If no {@code Certificate}s
+     * match the selector, an empty {@code Collection} will be returned.
+     * <p>
+     * For some {@code CertStore} types, the resulting
+     * {@code Collection} may not contain <b>all</b> of the
+     * {@code Certificate}s that match the selector. For instance,
+     * an LDAP {@code CertStore} may not search all entries in the
+     * directory. Instead, it may just search entries that are likely to
+     * contain the {@code Certificate}s it is looking for.
+     * <p>
+     * Some {@code CertStore} implementations (especially LDAP
+     * {@code CertStore}s) may throw a {@code CertStoreException}
+     * unless a non-null {@code CertSelector} is provided that includes
+     * specific criteria that can be used to find the certificates. Issuer
+     * and/or subject names are especially useful criteria.
+     *
+     * @param selector A {@code CertSelector} used to select which
+     *  {@code Certificate}s should be returned. Specify {@code null}
+     *  to return all {@code Certificate}s (if supported).
+     * @return A {@code Collection} of {@code Certificate}s that
+     *         match the specified selector (never {@code null})
+     * @throws CertStoreException if an exception occurs
+     */
+    public abstract Collection<? extends Certificate> engineGetCertificates
+            (CertSelector selector) throws CertStoreException;
+
+    /**
+     * Returns a {@code Collection} of {@code CRL}s that
+     * match the specified selector. If no {@code CRL}s
+     * match the selector, an empty {@code Collection} will be returned.
+     * <p>
+     * For some {@code CertStore} types, the resulting
+     * {@code Collection} may not contain <b>all</b> of the
+     * {@code CRL}s that match the selector. For instance,
+     * an LDAP {@code CertStore} may not search all entries in the
+     * directory. Instead, it may just search entries that are likely to
+     * contain the {@code CRL}s it is looking for.
+     * <p>
+     * Some {@code CertStore} implementations (especially LDAP
+     * {@code CertStore}s) may throw a {@code CertStoreException}
+     * unless a non-null {@code CRLSelector} is provided that includes
+     * specific criteria that can be used to find the CRLs. Issuer names
+     * and/or the certificate to be checked are especially useful.
+     *
+     * @param selector A {@code CRLSelector} used to select which
+     *  {@code CRL}s should be returned. Specify {@code null}
+     *  to return all {@code CRL}s (if supported).
+     * @return A {@code Collection} of {@code CRL}s that
+     *         match the specified selector (never {@code null})
+     * @throws CertStoreException if an exception occurs
+     */
+    public abstract Collection<? extends CRL> engineGetCRLs
+            (CRLSelector selector) throws CertStoreException;
+}
diff --git a/java/security/cert/Certificate.java b/java/security/cert/Certificate.java
new file mode 100644
index 0000000..5ded604
--- /dev/null
+++ b/java/security/cert/Certificate.java
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security.cert;
+
+import java.util.Arrays;
+
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.InvalidKeyException;
+import java.security.SignatureException;
+
+import sun.security.x509.X509CertImpl;
+
+/**
+ * <p>Abstract class for managing a variety of identity certificates.
+ * An identity certificate is a binding of a principal to a public key which
+ * is vouched for by another principal.  (A principal represents
+ * an entity such as an individual user, a group, or a corporation.)
+ *<p>
+ * This class is an abstraction for certificates that have different
+ * formats but important common uses.  For example, different types of
+ * certificates, such as X.509 and PGP, share general certificate
+ * functionality (like encoding and verifying) and
+ * some types of information (like a public key).
+ * <p>
+ * X.509, PGP, and SDSI certificates can all be implemented by
+ * subclassing the Certificate class, even though they contain different
+ * sets of information, and they store and retrieve the information in
+ * different ways.
+ *
+ * @see X509Certificate
+ * @see CertificateFactory
+ *
+ * @author Hemma Prafullchandra
+ */
+
+public abstract class Certificate implements java.io.Serializable {
+
+    private static final long serialVersionUID = -3585440601605666277L;
+
+    // the certificate type
+    private final String type;
+
+    /** Cache the hash code for the certiticate */
+    private int hash = -1; // Default to -1
+
+    /**
+     * Creates a certificate of the specified type.
+     *
+     * @param type the standard name of the certificate type.
+     * See the CertificateFactory section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertificateFactory">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard certificate types.
+     */
+    protected Certificate(String type) {
+        this.type = type;
+    }
+
+    /**
+     * Returns the type of this certificate.
+     *
+     * @return the type of this certificate.
+     */
+    public final String getType() {
+        return this.type;
+    }
+
+    /**
+     * Compares this certificate for equality with the specified
+     * object. If the {@code other} object is an
+     * {@code instanceof} {@code Certificate}, then
+     * its encoded form is retrieved and compared with the
+     * encoded form of this certificate.
+     *
+     * @param other the object to test for equality with this certificate.
+     * @return true iff the encoded forms of the two certificates
+     * match, false otherwise.
+     */
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        }
+        if (!(other instanceof Certificate)) {
+            return false;
+        }
+        try {
+            byte[] thisCert = X509CertImpl.getEncodedInternal(this);
+            byte[] otherCert = X509CertImpl.getEncodedInternal((Certificate)other);
+
+            return Arrays.equals(thisCert, otherCert);
+        } catch (CertificateException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Returns a hashcode value for this certificate from its
+     * encoded form.
+     *
+     * @return the hashcode value.
+     */
+    public int hashCode() {
+        int h = hash;
+        if (h == -1) {
+            try {
+                h = Arrays.hashCode(X509CertImpl.getEncodedInternal(this));
+            } catch (CertificateException e) {
+                h = 0;
+            }
+            hash = h;
+        }
+        return h;
+    }
+
+    /**
+     * Returns the encoded form of this certificate. It is
+     * assumed that each certificate type would have only a single
+     * form of encoding; for example, X.509 certificates would
+     * be encoded as ASN.1 DER.
+     *
+     * @return the encoded form of this certificate
+     *
+     * @exception CertificateEncodingException if an encoding error occurs.
+     */
+    public abstract byte[] getEncoded()
+        throws CertificateEncodingException;
+
+    /**
+     * Verifies that this certificate was signed using the
+     * private key that corresponds to the specified public key.
+     *
+     * @param key the PublicKey used to carry out the verification.
+     *
+     * @exception NoSuchAlgorithmException on unsupported signature
+     * algorithms.
+     * @exception InvalidKeyException on incorrect key.
+     * @exception NoSuchProviderException if there's no default provider.
+     * @exception SignatureException on signature errors.
+     * @exception CertificateException on encoding errors.
+     */
+    public abstract void verify(PublicKey key)
+        throws CertificateException, NoSuchAlgorithmException,
+        InvalidKeyException, NoSuchProviderException,
+        SignatureException;
+
+    /**
+     * Verifies that this certificate was signed using the
+     * private key that corresponds to the specified public key.
+     * This method uses the signature verification engine
+     * supplied by the specified provider.
+     *
+     * @param key the PublicKey used to carry out the verification.
+     * @param sigProvider the name of the signature provider.
+     *
+     * @exception NoSuchAlgorithmException on unsupported signature
+     * algorithms.
+     * @exception InvalidKeyException on incorrect key.
+     * @exception NoSuchProviderException on incorrect provider.
+     * @exception SignatureException on signature errors.
+     * @exception CertificateException on encoding errors.
+     */
+    public abstract void verify(PublicKey key, String sigProvider)
+        throws CertificateException, NoSuchAlgorithmException,
+        InvalidKeyException, NoSuchProviderException,
+        SignatureException;
+
+    /**
+     * Verifies that this certificate was signed using the
+     * private key that corresponds to the specified public key.
+     * This method uses the signature verification engine
+     * supplied by the specified provider. Note that the specified
+     * Provider object does not have to be registered in the provider list.
+     *
+     * <p> This method was added to version 1.8 of the Java Platform
+     * Standard Edition. In order to maintain backwards compatibility with
+     * existing service providers, this method cannot be {@code abstract}
+     * and by default throws an {@code UnsupportedOperationException}.
+     *
+     * @param key the PublicKey used to carry out the verification.
+     * @param sigProvider the signature provider.
+     *
+     * @exception NoSuchAlgorithmException on unsupported signature
+     * algorithms.
+     * @exception InvalidKeyException on incorrect key.
+     * @exception SignatureException on signature errors.
+     * @exception CertificateException on encoding errors.
+     * @exception UnsupportedOperationException if the method is not supported
+     * @since 1.8
+     */
+    public void verify(PublicKey key, Provider sigProvider)
+        throws CertificateException, NoSuchAlgorithmException,
+        InvalidKeyException, SignatureException {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Returns a string representation of this certificate.
+     *
+     * @return a string representation of this certificate.
+     */
+    public abstract String toString();
+
+    /**
+     * Gets the public key from this certificate.
+     *
+     * @return the public key.
+     */
+    public abstract PublicKey getPublicKey();
+
+    /**
+     * Alternate Certificate class for serialization.
+     * @since 1.3
+     */
+    protected static class CertificateRep implements java.io.Serializable {
+
+        private static final long serialVersionUID = -8563758940495660020L;
+
+        private String type;
+        private byte[] data;
+
+        /**
+         * Construct the alternate Certificate class with the Certificate
+         * type and Certificate encoding bytes.
+         *
+         * <p>
+         *
+         * @param type the standard name of the Certificate type. <p>
+         *
+         * @param data the Certificate data.
+         */
+        protected CertificateRep(String type, byte[] data) {
+            this.type = type;
+            this.data = data;
+        }
+
+        /**
+         * Resolve the Certificate Object.
+         *
+         * <p>
+         *
+         * @return the resolved Certificate Object
+         *
+         * @throws java.io.ObjectStreamException if the Certificate
+         *      could not be resolved
+         */
+        protected Object readResolve() throws java.io.ObjectStreamException {
+            try {
+                CertificateFactory cf = CertificateFactory.getInstance(type);
+                return cf.generateCertificate
+                        (new java.io.ByteArrayInputStream(data));
+            } catch (CertificateException e) {
+                throw new java.io.NotSerializableException
+                                ("java.security.cert.Certificate: " +
+                                type +
+                                ": " +
+                                e.getMessage());
+            }
+        }
+    }
+
+    /**
+     * Replace the Certificate to be serialized.
+     *
+     * @return the alternate Certificate object to be serialized
+     *
+     * @throws java.io.ObjectStreamException if a new object representing
+     * this Certificate could not be created
+     * @since 1.3
+     */
+    protected Object writeReplace() throws java.io.ObjectStreamException {
+        try {
+            return new CertificateRep(type, getEncoded());
+        } catch (CertificateException e) {
+            throw new java.io.NotSerializableException
+                                ("java.security.cert.Certificate: " +
+                                type +
+                                ": " +
+                                e.getMessage());
+        }
+    }
+}
diff --git a/java/security/cert/CertificateEncodingException.java b/java/security/cert/CertificateEncodingException.java
new file mode 100644
index 0000000..618ee0a
--- /dev/null
+++ b/java/security/cert/CertificateEncodingException.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security.cert;
+
+/**
+ * Certificate Encoding Exception. This is thrown whenever an error
+ * occurs while attempting to encode a certificate.
+ *
+ * @author Hemma Prafullchandra
+ */
+public class CertificateEncodingException extends CertificateException {
+
+    private static final long serialVersionUID = 6219492851589449162L;
+
+    /**
+     * Constructs a CertificateEncodingException with no detail message. A
+     * detail message is a String that describes this particular
+     * exception.
+     */
+    public CertificateEncodingException() {
+        super();
+    }
+
+    /**
+     * Constructs a CertificateEncodingException with the specified detail
+     * message. A detail message is a String that describes this
+     * particular exception.
+     *
+     * @param message the detail message.
+     */
+    public CertificateEncodingException(String message) {
+        super(message);
+    }
+
+    /**
+     * Creates a {@code CertificateEncodingException} with the specified
+     * detail message and cause.
+     *
+     * @param message the detail message (which is saved for later retrieval
+     *        by the {@link #getMessage()} method).
+     * @param cause the cause (which is saved for later retrieval by the
+     *        {@link #getCause()} method).  (A {@code null} value is permitted,
+     *        and indicates that the cause is nonexistent or unknown.)
+     * @since 1.5
+     */
+    public CertificateEncodingException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Creates a {@code CertificateEncodingException}
+     * with the specified cause and a detail message of
+     * {@code (cause==null ? null : cause.toString())}
+     * (which typically contains the class and detail message of
+     * {@code cause}).
+     *
+     * @param cause the cause (which is saved for later retrieval by the
+     *        {@link #getCause()} method).  (A {@code null} value is permitted,
+     *        and indicates that the cause is nonexistent or unknown.)
+     * @since 1.5
+     */
+    public CertificateEncodingException(Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/java/security/cert/CertificateException.java b/java/security/cert/CertificateException.java
new file mode 100644
index 0000000..f663054
--- /dev/null
+++ b/java/security/cert/CertificateException.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 1996, 2013, 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 java.security.cert;
+
+import java.security.GeneralSecurityException;
+
+/**
+ * This exception indicates one of a variety of certificate problems.
+ *
+ * @author Hemma Prafullchandra
+ * @see Certificate
+ */
+public class CertificateException extends GeneralSecurityException {
+
+    private static final long serialVersionUID = 3192535253797119798L;
+
+    /**
+     * Constructs a certificate exception with no detail message. A detail
+     * message is a String that describes this particular exception.
+     */
+    public CertificateException() {
+        super();
+    }
+
+    /**
+     * Constructs a certificate exception with the given detail
+     * message. A detail message is a String that describes this
+     * particular exception.
+     *
+     * @param msg the detail message.
+     */
+    public CertificateException(String msg) {
+        super(msg);
+    }
+
+    /**
+     * Creates a {@code CertificateException} with the specified
+     * detail message and cause.
+     *
+     * @param message the detail message (which is saved for later retrieval
+     *        by the {@link #getMessage()} method).
+     * @param cause the cause (which is saved for later retrieval by the
+     *        {@link #getCause()} method).  (A {@code null} value is permitted,
+     *        and indicates that the cause is nonexistent or unknown.)
+     * @since 1.5
+     */
+    public CertificateException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Creates a {@code CertificateException} with the specified cause
+     * and a detail message of {@code (cause==null ? null : cause.toString())}
+     * (which typically contains the class and detail message of
+     * {@code cause}).
+     *
+     * @param cause the cause (which is saved for later retrieval by the
+     *        {@link #getCause()} method).  (A {@code null} value is permitted,
+     *        and indicates that the cause is nonexistent or unknown.)
+     * @since 1.5
+     */
+    public CertificateException(Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/java/security/cert/CertificateExpiredException.java b/java/security/cert/CertificateExpiredException.java
new file mode 100644
index 0000000..9de0c23
--- /dev/null
+++ b/java/security/cert/CertificateExpiredException.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security.cert;
+
+/**
+ * Certificate Expired Exception. This is thrown whenever the current
+ * {@code Date} or the specified {@code Date} is after the
+ * {@code notAfter} date/time specified in the validity period
+ * of the certificate.
+ *
+ * @author Hemma Prafullchandra
+ */
+public class CertificateExpiredException extends CertificateException {
+
+    private static final long serialVersionUID = 9071001339691533771L;
+
+    /**
+     * Constructs a CertificateExpiredException with no detail message. A
+     * detail message is a String that describes this particular
+     * exception.
+     */
+    public CertificateExpiredException() {
+        super();
+    }
+
+    /**
+     * Constructs a CertificateExpiredException with the specified detail
+     * message. A detail message is a String that describes this
+     * particular exception.
+     *
+     * @param message the detail message.
+     */
+    public CertificateExpiredException(String message) {
+        super(message);
+    }
+}
diff --git a/java/security/cert/CertificateFactory.java b/java/security/cert/CertificateFactory.java
new file mode 100644
index 0000000..e74ff0a
--- /dev/null
+++ b/java/security/cert/CertificateFactory.java
@@ -0,0 +1,560 @@
+/*
+ * Copyright (c) 1998, 2013, 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 java.security.cert;
+
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.security.Provider;
+import java.security.Security;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+
+import sun.security.jca.*;
+import sun.security.jca.GetInstance.Instance;
+
+/**
+ * This class defines the functionality of a certificate factory, which is
+ * used to generate certificate, certification path ({@code CertPath})
+ * and certificate revocation list (CRL) objects from their encodings.
+ *
+ * <p>For encodings consisting of multiple certificates, use
+ * {@code generateCertificates} when you want to
+ * parse a collection of possibly unrelated certificates. Otherwise,
+ * use {@code generateCertPath} when you want to generate
+ * a {@code CertPath} (a certificate chain) and subsequently
+ * validate it with a {@code CertPathValidator}.
+ *
+ * <p>A certificate factory for X.509 must return certificates that are an
+ * instance of {@code java.security.cert.X509Certificate}, and CRLs
+ * that are an instance of {@code java.security.cert.X509CRL}.
+ *
+ * <p>The following example reads a file with Base64 encoded certificates,
+ * which are each bounded at the beginning by -----BEGIN CERTIFICATE-----, and
+ * bounded at the end by -----END CERTIFICATE-----. We convert the
+ * {@code FileInputStream} (which does not support {@code mark}
+ * and {@code reset}) to a {@code BufferedInputStream} (which
+ * supports those methods), so that each call to
+ * {@code generateCertificate} consumes only one certificate, and the
+ * read position of the input stream is positioned to the next certificate in
+ * the file:
+ *
+ * <pre>{@code
+ * FileInputStream fis = new FileInputStream(filename);
+ * BufferedInputStream bis = new BufferedInputStream(fis);
+ *
+ * CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ *
+ * while (bis.available() > 0) {
+ *    Certificate cert = cf.generateCertificate(bis);
+ *    System.out.println(cert.toString());
+ * }
+ * }</pre>
+ *
+ * <p>The following example parses a PKCS#7-formatted certificate reply stored
+ * in a file and extracts all the certificates from it:
+ *
+ * <pre>
+ * FileInputStream fis = new FileInputStream(filename);
+ * CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ * Collection c = cf.generateCertificates(fis);
+ * Iterator i = c.iterator();
+ * while (i.hasNext()) {
+ *    Certificate cert = (Certificate)i.next();
+ *    System.out.println(cert);
+ * }
+ * </pre>
+ *
+ * <p> Android provides the following <code>CertificateFactory</code> types:
+ * <table>
+ *   <thead>
+ *     <tr>
+ *       <th>Algorithm</th>
+ *       <th>Supported API Levels</th>
+ *     </tr>
+ *   </thead>
+ *   <tbody>
+ *     <tr>
+ *       <td>X.509</td>
+ *       <td>1+</td>
+ *     </tr>
+ *   </tbody>
+ * </table>
+ * and the following <code>CertPath</code> encodings:
+ * <table>
+ *     <thead>
+ *         <tr>
+ *             <th>Name</th>
+ *             <th>Supported (API Levels)</th>
+ *         </tr>
+ *     </thead>
+ *     <tbody>
+ *         <tr>
+ *             <td>PKCS7</td>
+ *             <td>1+</td>
+ *         </tr>
+ *         <tr>
+ *             <td>PkiPath</td>
+ *             <td>1+</td>
+ *         </tr>
+ *     </tbody>
+ * </table>
+ *
+ * The type and encodings are described in the <a href=
+ * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertificateFactory">
+ * CertificateFactory section</a> and the <a href=
+ * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertPathEncodings">
+ * CertPath Encodings section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ *
+ * @author Hemma Prafullchandra
+ * @author Jan Luehe
+ * @author Sean Mullan
+ *
+ * @see Certificate
+ * @see X509Certificate
+ * @see CertPath
+ * @see CRL
+ * @see X509CRL
+ *
+ * @since 1.2
+ */
+
+public class CertificateFactory {
+
+    // The certificate type
+    private String type;
+
+    // The provider
+    private Provider provider;
+
+    // The provider implementation
+    private CertificateFactorySpi certFacSpi;
+
+    /**
+     * Creates a CertificateFactory object of the given type, and encapsulates
+     * the given provider implementation (SPI object) in it.
+     *
+     * @param certFacSpi the provider implementation.
+     * @param provider the provider.
+     * @param type the certificate type.
+     */
+    protected CertificateFactory(CertificateFactorySpi certFacSpi,
+                                 Provider provider, String type)
+    {
+        this.certFacSpi = certFacSpi;
+        this.provider = provider;
+        this.type = type;
+    }
+
+    /**
+     * Returns a certificate factory object that implements the
+     * specified certificate type.
+     *
+     * <p> This method traverses the list of registered security Providers,
+     * starting with the most preferred Provider.
+     * A new CertificateFactory object encapsulating the
+     * CertificateFactorySpi implementation from the first
+     * Provider that supports the specified type is returned.
+     *
+     * <p> Note that the list of registered providers may be retrieved via
+     * the {@link Security#getProviders() Security.getProviders()} method.
+     *
+     * @param type the name of the requested certificate type.
+     * See the CertificateFactory section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertificateFactory">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard certificate types.
+     *
+     * @return a certificate factory object for the specified type.
+     *
+     * @exception CertificateException if no Provider supports a
+     *          CertificateFactorySpi implementation for the
+     *          specified type.
+     *
+     * @see java.security.Provider
+     */
+    public static final CertificateFactory getInstance(String type)
+            throws CertificateException {
+        try {
+            Instance instance = GetInstance.getInstance("CertificateFactory",
+                CertificateFactorySpi.class, type);
+            return new CertificateFactory((CertificateFactorySpi)instance.impl,
+                instance.provider, type);
+        } catch (NoSuchAlgorithmException e) {
+            throw new CertificateException(type + " not found", e);
+        }
+    }
+
+    /**
+     * Returns a certificate factory object for the specified
+     * certificate type.
+     *
+     * <p> A new CertificateFactory object encapsulating the
+     * CertificateFactorySpi implementation from the specified provider
+     * is returned.  The specified provider must be registered
+     * in the security provider list.
+     *
+     * <p> Note that the list of registered providers may be retrieved via
+     * the {@link Security#getProviders() Security.getProviders()} method.
+     *
+     * @param type the certificate type.
+     * See the CertificateFactory section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertificateFactory">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard certificate types.
+     *
+     * @param provider the name of the provider.
+     *
+     * @return a certificate factory object for the specified type.
+     *
+     * @exception CertificateException if a CertificateFactorySpi
+     *          implementation for the specified algorithm is not
+     *          available from the specified provider.
+     *
+     * @exception NoSuchProviderException if the specified provider is not
+     *          registered in the security provider list.
+     *
+     * @exception IllegalArgumentException if the provider name is null
+     *          or empty.
+     *
+     * @see java.security.Provider
+     */
+    public static final CertificateFactory getInstance(String type,
+            String provider) throws CertificateException,
+            NoSuchProviderException {
+        try {
+            Instance instance = GetInstance.getInstance("CertificateFactory",
+                CertificateFactorySpi.class, type, provider);
+            return new CertificateFactory((CertificateFactorySpi)instance.impl,
+                instance.provider, type);
+        } catch (NoSuchAlgorithmException e) {
+            throw new CertificateException(type + " not found", e);
+        }
+    }
+
+    /**
+     * Returns a certificate factory object for the specified
+     * certificate type.
+     *
+     * <p> A new CertificateFactory object encapsulating the
+     * CertificateFactorySpi implementation from the specified Provider
+     * object is returned.  Note that the specified Provider object
+     * does not have to be registered in the provider list.
+     *
+     * @param type the certificate type.
+     * See the CertificateFactory section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertificateFactory">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard certificate types.
+     * @param provider the provider.
+     *
+     * @return a certificate factory object for the specified type.
+     *
+     * @exception CertificateException if a CertificateFactorySpi
+     *          implementation for the specified algorithm is not available
+     *          from the specified Provider object.
+     *
+     * @exception IllegalArgumentException if the {@code provider} is
+     *          null.
+     *
+     * @see java.security.Provider
+     *
+     * @since 1.4
+     */
+    public static final CertificateFactory getInstance(String type,
+            Provider provider) throws CertificateException {
+        try {
+            Instance instance = GetInstance.getInstance("CertificateFactory",
+                CertificateFactorySpi.class, type, provider);
+            return new CertificateFactory((CertificateFactorySpi)instance.impl,
+                instance.provider, type);
+        } catch (NoSuchAlgorithmException e) {
+            throw new CertificateException(type + " not found", e);
+        }
+    }
+
+    /**
+     * Returns the provider of this certificate factory.
+     *
+     * @return the provider of this certificate factory.
+     */
+    public final Provider getProvider() {
+        return this.provider;
+    }
+
+    /**
+     * Returns the name of the certificate type associated with this
+     * certificate factory.
+     *
+     * @return the name of the certificate type associated with this
+     * certificate factory.
+     */
+    public final String getType() {
+        return this.type;
+    }
+
+    /**
+     * Generates a certificate object and initializes it with
+     * the data read from the input stream {@code inStream}.
+     *
+     * <p>In order to take advantage of the specialized certificate format
+     * supported by this certificate factory,
+     * the returned certificate object can be typecast to the corresponding
+     * certificate class. For example, if this certificate
+     * factory implements X.509 certificates, the returned certificate object
+     * can be typecast to the {@code X509Certificate} class.
+     *
+     * <p>In the case of a certificate factory for X.509 certificates, the
+     * certificate provided in {@code inStream} must be DER-encoded and
+     * may be supplied in binary or printable (Base64) encoding. If the
+     * certificate is provided in Base64 encoding, it must be bounded at
+     * the beginning by -----BEGIN CERTIFICATE-----, and must be bounded at
+     * the end by -----END CERTIFICATE-----.
+     *
+     * <p>Note that if the given input stream does not support
+     * {@link java.io.InputStream#mark(int) mark} and
+     * {@link java.io.InputStream#reset() reset}, this method will
+     * consume the entire input stream. Otherwise, each call to this
+     * method consumes one certificate and the read position of the
+     * input stream is positioned to the next available byte after
+     * the inherent end-of-certificate marker. If the data in the input stream
+     * does not contain an inherent end-of-certificate marker (other
+     * than EOF) and there is trailing data after the certificate is parsed, a
+     * {@code CertificateException} is thrown.
+     *
+     * @param inStream an input stream with the certificate data.
+     *
+     * @return a certificate object initialized with the data
+     * from the input stream.
+     *
+     * @exception CertificateException on parsing errors.
+     */
+    public final Certificate generateCertificate(InputStream inStream)
+        throws CertificateException
+    {
+        return certFacSpi.engineGenerateCertificate(inStream);
+    }
+
+    /**
+     * Returns an iteration of the {@code CertPath} encodings supported
+     * by this certificate factory, with the default encoding first. See
+     * the CertPath Encodings section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertPathEncodings">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard encoding names and their formats.
+     * <p>
+     * Attempts to modify the returned {@code Iterator} via its
+     * {@code remove} method result in an
+     * {@code UnsupportedOperationException}.
+     *
+     * @return an {@code Iterator} over the names of the supported
+     *         {@code CertPath} encodings (as {@code String}s)
+     * @since 1.4
+     */
+    public final Iterator<String> getCertPathEncodings() {
+        return(certFacSpi.engineGetCertPathEncodings());
+    }
+
+    /**
+     * Generates a {@code CertPath} object and initializes it with
+     * the data read from the {@code InputStream} inStream. The data
+     * is assumed to be in the default encoding. The name of the default
+     * encoding is the first element of the {@code Iterator} returned by
+     * the {@link #getCertPathEncodings getCertPathEncodings} method.
+     *
+     * @param inStream an {@code InputStream} containing the data
+     * @return a {@code CertPath} initialized with the data from the
+     *   {@code InputStream}
+     * @exception CertificateException if an exception occurs while decoding
+     * @since 1.4
+     */
+    public final CertPath generateCertPath(InputStream inStream)
+        throws CertificateException
+    {
+        return(certFacSpi.engineGenerateCertPath(inStream));
+    }
+
+    /**
+     * Generates a {@code CertPath} object and initializes it with
+     * the data read from the {@code InputStream} inStream. The data
+     * is assumed to be in the specified encoding. See
+     * the CertPath Encodings section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertPathEncodings">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard encoding names and their formats.
+     *
+     * @param inStream an {@code InputStream} containing the data
+     * @param encoding the encoding used for the data
+     * @return a {@code CertPath} initialized with the data from the
+     *   {@code InputStream}
+     * @exception CertificateException if an exception occurs while decoding or
+     *   the encoding requested is not supported
+     * @since 1.4
+     */
+    public final CertPath generateCertPath(InputStream inStream,
+        String encoding) throws CertificateException
+    {
+        return(certFacSpi.engineGenerateCertPath(inStream, encoding));
+    }
+
+    /**
+     * Generates a {@code CertPath} object and initializes it with
+     * a {@code List} of {@code Certificate}s.
+     * <p>
+     * The certificates supplied must be of a type supported by the
+     * {@code CertificateFactory}. They will be copied out of the supplied
+     * {@code List} object.
+     *
+     * @param certificates a {@code List} of {@code Certificate}s
+     * @return a {@code CertPath} initialized with the supplied list of
+     *   certificates
+     * @exception CertificateException if an exception occurs
+     * @since 1.4
+     */
+    public final CertPath
+        generateCertPath(List<? extends Certificate> certificates)
+        throws CertificateException
+    {
+        return(certFacSpi.engineGenerateCertPath(certificates));
+    }
+
+    /**
+     * Returns a (possibly empty) collection view of the certificates read
+     * from the given input stream {@code inStream}.
+     *
+     * <p>In order to take advantage of the specialized certificate format
+     * supported by this certificate factory, each element in
+     * the returned collection view can be typecast to the corresponding
+     * certificate class. For example, if this certificate
+     * factory implements X.509 certificates, the elements in the returned
+     * collection can be typecast to the {@code X509Certificate} class.
+     *
+     * <p>In the case of a certificate factory for X.509 certificates,
+     * {@code inStream} may contain a sequence of DER-encoded certificates
+     * in the formats described for
+     * {@link #generateCertificate(java.io.InputStream) generateCertificate}.
+     * In addition, {@code inStream} may contain a PKCS#7 certificate
+     * chain. This is a PKCS#7 <i>SignedData</i> object, with the only
+     * significant field being <i>certificates</i>. In particular, the
+     * signature and the contents are ignored. This format allows multiple
+     * certificates to be downloaded at once. If no certificates are present,
+     * an empty collection is returned.
+     *
+     * <p>Note that if the given input stream does not support
+     * {@link java.io.InputStream#mark(int) mark} and
+     * {@link java.io.InputStream#reset() reset}, this method will
+     * consume the entire input stream.
+     *
+     * @param inStream the input stream with the certificates.
+     *
+     * @return a (possibly empty) collection view of
+     * java.security.cert.Certificate objects
+     * initialized with the data from the input stream.
+     *
+     * @exception CertificateException on parsing errors.
+     */
+    public final Collection<? extends Certificate> generateCertificates
+            (InputStream inStream) throws CertificateException {
+        return certFacSpi.engineGenerateCertificates(inStream);
+    }
+
+    /**
+     * Generates a certificate revocation list (CRL) object and initializes it
+     * with the data read from the input stream {@code inStream}.
+     *
+     * <p>In order to take advantage of the specialized CRL format
+     * supported by this certificate factory,
+     * the returned CRL object can be typecast to the corresponding
+     * CRL class. For example, if this certificate
+     * factory implements X.509 CRLs, the returned CRL object
+     * can be typecast to the {@code X509CRL} class.
+     *
+     * <p>Note that if the given input stream does not support
+     * {@link java.io.InputStream#mark(int) mark} and
+     * {@link java.io.InputStream#reset() reset}, this method will
+     * consume the entire input stream. Otherwise, each call to this
+     * method consumes one CRL and the read position of the input stream
+     * is positioned to the next available byte after the inherent
+     * end-of-CRL marker. If the data in the
+     * input stream does not contain an inherent end-of-CRL marker (other
+     * than EOF) and there is trailing data after the CRL is parsed, a
+     * {@code CRLException} is thrown.
+     *
+     * @param inStream an input stream with the CRL data.
+     *
+     * @return a CRL object initialized with the data
+     * from the input stream.
+     *
+     * @exception CRLException on parsing errors.
+     */
+    public final CRL generateCRL(InputStream inStream)
+        throws CRLException
+    {
+        return certFacSpi.engineGenerateCRL(inStream);
+    }
+
+    /**
+     * Returns a (possibly empty) collection view of the CRLs read
+     * from the given input stream {@code inStream}.
+     *
+     * <p>In order to take advantage of the specialized CRL format
+     * supported by this certificate factory, each element in
+     * the returned collection view can be typecast to the corresponding
+     * CRL class. For example, if this certificate
+     * factory implements X.509 CRLs, the elements in the returned
+     * collection can be typecast to the {@code X509CRL} class.
+     *
+     * <p>In the case of a certificate factory for X.509 CRLs,
+     * {@code inStream} may contain a sequence of DER-encoded CRLs.
+     * In addition, {@code inStream} may contain a PKCS#7 CRL
+     * set. This is a PKCS#7 <i>SignedData</i> object, with the only
+     * significant field being <i>crls</i>. In particular, the
+     * signature and the contents are ignored. This format allows multiple
+     * CRLs to be downloaded at once. If no CRLs are present,
+     * an empty collection is returned.
+     *
+     * <p>Note that if the given input stream does not support
+     * {@link java.io.InputStream#mark(int) mark} and
+     * {@link java.io.InputStream#reset() reset}, this method will
+     * consume the entire input stream.
+     *
+     * @param inStream the input stream with the CRLs.
+     *
+     * @return a (possibly empty) collection view of
+     * java.security.cert.CRL objects initialized with the data from the input
+     * stream.
+     *
+     * @exception CRLException on parsing errors.
+     */
+    public final Collection<? extends CRL> generateCRLs(InputStream inStream)
+            throws CRLException {
+        return certFacSpi.engineGenerateCRLs(inStream);
+    }
+}
diff --git a/java/security/cert/CertificateFactorySpi.java b/java/security/cert/CertificateFactorySpi.java
new file mode 100644
index 0000000..5e13831
--- /dev/null
+++ b/java/security/cert/CertificateFactorySpi.java
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 1998, 2013, 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 java.security.cert;
+
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.security.Provider;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+
+/**
+ * This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
+ * for the {@code CertificateFactory} class.
+ * All the abstract methods in this class must be implemented by each
+ * cryptographic service provider who wishes to supply the implementation
+ * of a certificate factory for a particular certificate type, e.g., X.509.
+ *
+ * <p>Certificate factories are used to generate certificate, certification path
+ * ({@code CertPath}) and certificate revocation list (CRL) objects from
+ * their encodings.
+ *
+ * <p>A certificate factory for X.509 must return certificates that are an
+ * instance of {@code java.security.cert.X509Certificate}, and CRLs
+ * that are an instance of {@code java.security.cert.X509CRL}.
+ *
+ * @author Hemma Prafullchandra
+ * @author Jan Luehe
+ * @author Sean Mullan
+ *
+ *
+ * @see CertificateFactory
+ * @see Certificate
+ * @see X509Certificate
+ * @see CertPath
+ * @see CRL
+ * @see X509CRL
+ *
+ * @since 1.2
+ */
+
+public abstract class CertificateFactorySpi {
+
+    /**
+     * Generates a certificate object and initializes it with
+     * the data read from the input stream {@code inStream}.
+     *
+     * <p>In order to take advantage of the specialized certificate format
+     * supported by this certificate factory,
+     * the returned certificate object can be typecast to the corresponding
+     * certificate class. For example, if this certificate
+     * factory implements X.509 certificates, the returned certificate object
+     * can be typecast to the {@code X509Certificate} class.
+     *
+     * <p>In the case of a certificate factory for X.509 certificates, the
+     * certificate provided in {@code inStream} must be DER-encoded and
+     * may be supplied in binary or printable (Base64) encoding. If the
+     * certificate is provided in Base64 encoding, it must be bounded at
+     * the beginning by -----BEGIN CERTIFICATE-----, and must be bounded at
+     * the end by -----END CERTIFICATE-----.
+     *
+     * <p>Note that if the given input stream does not support
+     * {@link java.io.InputStream#mark(int) mark} and
+     * {@link java.io.InputStream#reset() reset}, this method will
+     * consume the entire input stream. Otherwise, each call to this
+     * method consumes one certificate and the read position of the input stream
+     * is positioned to the next available byte after the inherent
+     * end-of-certificate marker. If the data in the
+     * input stream does not contain an inherent end-of-certificate marker (other
+     * than EOF) and there is trailing data after the certificate is parsed, a
+     * {@code CertificateException} is thrown.
+     *
+     * @param inStream an input stream with the certificate data.
+     *
+     * @return a certificate object initialized with the data
+     * from the input stream.
+     *
+     * @exception CertificateException on parsing errors.
+     */
+    public abstract Certificate engineGenerateCertificate(InputStream inStream)
+        throws CertificateException;
+
+    /**
+     * Generates a {@code CertPath} object and initializes it with
+     * the data read from the {@code InputStream} inStream. The data
+     * is assumed to be in the default encoding.
+     *
+     * <p> This method was added to version 1.4 of the Java 2 Platform
+     * Standard Edition. In order to maintain backwards compatibility with
+     * existing service providers, this method cannot be {@code abstract}
+     * and by default throws an {@code UnsupportedOperationException}.
+     *
+     * @param inStream an {@code InputStream} containing the data
+     * @return a {@code CertPath} initialized with the data from the
+     *   {@code InputStream}
+     * @exception CertificateException if an exception occurs while decoding
+     * @exception UnsupportedOperationException if the method is not supported
+     * @since 1.4
+     */
+    public CertPath engineGenerateCertPath(InputStream inStream)
+        throws CertificateException
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Generates a {@code CertPath} object and initializes it with
+     * the data read from the {@code InputStream} inStream. The data
+     * is assumed to be in the specified encoding.
+     *
+     * <p> This method was added to version 1.4 of the Java 2 Platform
+     * Standard Edition. In order to maintain backwards compatibility with
+     * existing service providers, this method cannot be {@code abstract}
+     * and by default throws an {@code UnsupportedOperationException}.
+     *
+     * @param inStream an {@code InputStream} containing the data
+     * @param encoding the encoding used for the data
+     * @return a {@code CertPath} initialized with the data from the
+     *   {@code InputStream}
+     * @exception CertificateException if an exception occurs while decoding or
+     *   the encoding requested is not supported
+     * @exception UnsupportedOperationException if the method is not supported
+     * @since 1.4
+     */
+    public CertPath engineGenerateCertPath(InputStream inStream,
+        String encoding) throws CertificateException
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Generates a {@code CertPath} object and initializes it with
+     * a {@code List} of {@code Certificate}s.
+     * <p>
+     * The certificates supplied must be of a type supported by the
+     * {@code CertificateFactory}. They will be copied out of the supplied
+     * {@code List} object.
+     *
+     * <p> This method was added to version 1.4 of the Java 2 Platform
+     * Standard Edition. In order to maintain backwards compatibility with
+     * existing service providers, this method cannot be {@code abstract}
+     * and by default throws an {@code UnsupportedOperationException}.
+     *
+     * @param certificates a {@code List} of {@code Certificate}s
+     * @return a {@code CertPath} initialized with the supplied list of
+     *   certificates
+     * @exception CertificateException if an exception occurs
+     * @exception UnsupportedOperationException if the method is not supported
+     * @since 1.4
+     */
+    public CertPath
+        engineGenerateCertPath(List<? extends Certificate> certificates)
+        throws CertificateException
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Returns an iteration of the {@code CertPath} encodings supported
+     * by this certificate factory, with the default encoding first. See
+     * the CertPath Encodings section in the <a href=
+     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertPathEncodings">
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * for information about standard encoding names.
+     * <p>
+     * Attempts to modify the returned {@code Iterator} via its
+     * {@code remove} method result in an
+     * {@code UnsupportedOperationException}.
+     *
+     * <p> This method was added to version 1.4 of the Java 2 Platform
+     * Standard Edition. In order to maintain backwards compatibility with
+     * existing service providers, this method cannot be {@code abstract}
+     * and by default throws an {@code UnsupportedOperationException}.
+     *
+     * @return an {@code Iterator} over the names of the supported
+     *         {@code CertPath} encodings (as {@code String}s)
+     * @exception UnsupportedOperationException if the method is not supported
+     * @since 1.4
+     */
+    public Iterator<String> engineGetCertPathEncodings() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Returns a (possibly empty) collection view of the certificates read
+     * from the given input stream {@code inStream}.
+     *
+     * <p>In order to take advantage of the specialized certificate format
+     * supported by this certificate factory, each element in
+     * the returned collection view can be typecast to the corresponding
+     * certificate class. For example, if this certificate
+     * factory implements X.509 certificates, the elements in the returned
+     * collection can be typecast to the {@code X509Certificate} class.
+     *
+     * <p>In the case of a certificate factory for X.509 certificates,
+     * {@code inStream} may contain a single DER-encoded certificate
+     * in the formats described for
+     * {@link CertificateFactory#generateCertificate(java.io.InputStream)
+     * generateCertificate}.
+     * In addition, {@code inStream} may contain a PKCS#7 certificate
+     * chain. This is a PKCS#7 <i>SignedData</i> object, with the only
+     * significant field being <i>certificates</i>. In particular, the
+     * signature and the contents are ignored. This format allows multiple
+     * certificates to be downloaded at once. If no certificates are present,
+     * an empty collection is returned.
+     *
+     * <p>Note that if the given input stream does not support
+     * {@link java.io.InputStream#mark(int) mark} and
+     * {@link java.io.InputStream#reset() reset}, this method will
+     * consume the entire input stream.
+     *
+     * @param inStream the input stream with the certificates.
+     *
+     * @return a (possibly empty) collection view of
+     * java.security.cert.Certificate objects
+     * initialized with the data from the input stream.
+     *
+     * @exception CertificateException on parsing errors.
+     */
+    public abstract Collection<? extends Certificate>
+            engineGenerateCertificates(InputStream inStream)
+            throws CertificateException;
+
+    /**
+     * Generates a certificate revocation list (CRL) object and initializes it
+     * with the data read from the input stream {@code inStream}.
+     *
+     * <p>In order to take advantage of the specialized CRL format
+     * supported by this certificate factory,
+     * the returned CRL object can be typecast to the corresponding
+     * CRL class. For example, if this certificate
+     * factory implements X.509 CRLs, the returned CRL object
+     * can be typecast to the {@code X509CRL} class.
+     *
+     * <p>Note that if the given input stream does not support
+     * {@link java.io.InputStream#mark(int) mark} and
+     * {@link java.io.InputStream#reset() reset}, this method will
+     * consume the entire input stream. Otherwise, each call to this
+     * method consumes one CRL and the read position of the input stream
+     * is positioned to the next available byte after the inherent
+     * end-of-CRL marker. If the data in the
+     * input stream does not contain an inherent end-of-CRL marker (other
+     * than EOF) and there is trailing data after the CRL is parsed, a
+     * {@code CRLException} is thrown.
+     *
+     * @param inStream an input stream with the CRL data.
+     *
+     * @return a CRL object initialized with the data
+     * from the input stream.
+     *
+     * @exception CRLException on parsing errors.
+     */
+    public abstract CRL engineGenerateCRL(InputStream inStream)
+        throws CRLException;
+
+    /**
+     * Returns a (possibly empty) collection view of the CRLs read
+     * from the given input stream {@code inStream}.
+     *
+     * <p>In order to take advantage of the specialized CRL format
+     * supported by this certificate factory, each element in
+     * the returned collection view can be typecast to the corresponding
+     * CRL class. For example, if this certificate
+     * factory implements X.509 CRLs, the elements in the returned
+     * collection can be typecast to the {@code X509CRL} class.
+     *
+     * <p>In the case of a certificate factory for X.509 CRLs,
+     * {@code inStream} may contain a single DER-encoded CRL.
+     * In addition, {@code inStream} may contain a PKCS#7 CRL
+     * set. This is a PKCS#7 <i>SignedData</i> object, with the only
+     * significant field being <i>crls</i>. In particular, the
+     * signature and the contents are ignored. This format allows multiple
+     * CRLs to be downloaded at once. If no CRLs are present,
+     * an empty collection is returned.
+     *
+     * <p>Note that if the given input stream does not support
+     * {@link java.io.InputStream#mark(int) mark} and
+     * {@link java.io.InputStream#reset() reset}, this method will
+     * consume the entire input stream.
+     *
+     * @param inStream the input stream with the CRLs.
+     *
+     * @return a (possibly empty) collection view of
+     * java.security.cert.CRL objects initialized with the data from the input
+     * stream.
+     *
+     * @exception CRLException on parsing errors.
+     */
+    public abstract Collection<? extends CRL> engineGenerateCRLs
+            (InputStream inStream) throws CRLException;
+}
diff --git a/java/security/cert/CertificateNotYetValidException.java b/java/security/cert/CertificateNotYetValidException.java
new file mode 100644
index 0000000..e8722bd
--- /dev/null
+++ b/java/security/cert/CertificateNotYetValidException.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security.cert;
+
+/**
+ * Certificate is not yet valid exception. This is thrown whenever
+ * the current {@code Date} or the specified {@code Date}
+ * is before the {@code notBefore} date/time in the Certificate
+ * validity period.
+ *
+ * @author Hemma Prafullchandra
+ */
+public class CertificateNotYetValidException extends CertificateException {
+
+    static final long serialVersionUID = 4355919900041064702L;
+
+    /**
+     * Constructs a CertificateNotYetValidException with no detail message. A
+     * detail message is a String that describes this particular
+     * exception.
+     */
+    public CertificateNotYetValidException() {
+        super();
+    }
+
+    /**
+     * Constructs a CertificateNotYetValidException with the specified detail
+     * message. A detail message is a String that describes this
+     * particular exception.
+     *
+     * @param message the detail message.
+     */
+    public CertificateNotYetValidException(String message) {
+        super(message);
+    }
+}
diff --git a/java/security/cert/CertificateParsingException.java b/java/security/cert/CertificateParsingException.java
new file mode 100644
index 0000000..06a7d60
--- /dev/null
+++ b/java/security/cert/CertificateParsingException.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security.cert;
+
+/**
+ * Certificate Parsing Exception. This is thrown whenever an
+ * invalid DER-encoded certificate is parsed or unsupported DER features
+ * are found in the Certificate.
+ *
+ * @author Hemma Prafullchandra
+ */
+public class CertificateParsingException extends CertificateException {
+
+    private static final long serialVersionUID = -7989222416793322029L;
+
+    /**
+     * Constructs a CertificateParsingException with no detail message. A
+     * detail message is a String that describes this particular
+     * exception.
+     */
+    public CertificateParsingException() {
+        super();
+    }
+
+    /**
+     * Constructs a CertificateParsingException with the specified detail
+     * message. A detail message is a String that describes this
+     * particular exception.
+     *
+     * @param message the detail message.
+     */
+    public CertificateParsingException(String message) {
+        super(message);
+    }
+
+    /**
+     * Creates a {@code CertificateParsingException} with the specified
+     * detail message and cause.
+     *
+     * @param message the detail message (which is saved for later retrieval
+     *        by the {@link #getMessage()} method).
+     * @param cause the cause (which is saved for later retrieval by the
+     *        {@link #getCause()} method).  (A {@code null} value is permitted,
+     *        and indicates that the cause is nonexistent or unknown.)
+     * @since 1.5
+     */
+    public CertificateParsingException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Creates a {@code CertificateParsingException} with the
+     * specified cause and a detail message of
+     * {@code (cause==null ? null : cause.toString())}
+     * (which typically contains the class and detail message of
+     * {@code cause}).
+     *
+     * @param cause the cause (which is saved for later retrieval by the
+     *        {@link #getCause()} method).  (A {@code null} value is permitted,
+     *        and indicates that the cause is nonexistent or unknown.)
+     * @since 1.5
+     */
+    public CertificateParsingException(Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/java/security/cert/CertificateRevokedException.java b/java/security/cert/CertificateRevokedException.java
new file mode 100644
index 0000000..505a007
--- /dev/null
+++ b/java/security/cert/CertificateRevokedException.java
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2007, 2014, 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 java.security.cert;
+
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import javax.security.auth.x500.X500Principal;
+
+import sun.security.util.ObjectIdentifier;
+import sun.security.x509.InvalidityDateExtension;
+
+/**
+ * An exception that indicates an X.509 certificate is revoked. A
+ * {@code CertificateRevokedException} contains additional information
+ * about the revoked certificate, such as the date on which the
+ * certificate was revoked and the reason it was revoked.
+ *
+ * @author Sean Mullan
+ * @since 1.7
+ * @see CertPathValidatorException
+ */
+public class CertificateRevokedException extends CertificateException {
+
+    private static final long serialVersionUID = 7839996631571608627L;
+
+    /**
+     * @serial the date on which the certificate was revoked
+     */
+    private Date revocationDate;
+    /**
+     * @serial the revocation reason
+     */
+    private final CRLReason reason;
+    /**
+     * @serial the {@code X500Principal} that represents the name of the
+     * authority that signed the certificate's revocation status information
+     */
+    private final X500Principal authority;
+
+    private transient Map<String, Extension> extensions;
+
+    /**
+     * Constructs a {@code CertificateRevokedException} with
+     * the specified revocation date, reason code, authority name, and map
+     * of extensions.
+     *
+     * @param revocationDate the date on which the certificate was revoked. The
+     *    date is copied to protect against subsequent modification.
+     * @param reason the revocation reason
+     * @param extensions a map of X.509 Extensions. Each key is an OID String
+     *    that maps to the corresponding Extension. The map is copied to
+     *    prevent subsequent modification.
+     * @param authority the {@code X500Principal} that represents the name
+     *    of the authority that signed the certificate's revocation status
+     *    information
+     * @throws NullPointerException if {@code revocationDate},
+     *    {@code reason}, {@code authority}, or
+     *    {@code extensions} is {@code null}
+     */
+    public CertificateRevokedException(Date revocationDate, CRLReason reason,
+        X500Principal authority, Map<String, Extension> extensions) {
+        if (revocationDate == null || reason == null || authority == null ||
+            extensions == null) {
+            throw new NullPointerException();
+        }
+        this.revocationDate = new Date(revocationDate.getTime());
+        this.reason = reason;
+        this.authority = authority;
+        // make sure Map only contains correct types
+        this.extensions = Collections.checkedMap(new HashMap<>(),
+                                                 String.class, Extension.class);
+        this.extensions.putAll(extensions);
+    }
+
+    /**
+     * Returns the date on which the certificate was revoked. A new copy is
+     * returned each time the method is invoked to protect against subsequent
+     * modification.
+     *
+     * @return the revocation date
+     */
+    public Date getRevocationDate() {
+        return (Date) revocationDate.clone();
+    }
+
+    /**
+     * Returns the reason the certificate was revoked.
+     *
+     * @return the revocation reason
+     */
+    public CRLReason getRevocationReason() {
+        return reason;
+    }
+
+    /**
+     * Returns the name of the authority that signed the certificate's
+     * revocation status information.
+     *
+     * @return the {@code X500Principal} that represents the name of the
+     *     authority that signed the certificate's revocation status information
+     */
+    public X500Principal getAuthorityName() {
+        return authority;
+    }
+
+    /**
+     * Returns the invalidity date, as specified in the Invalidity Date
+     * extension of this {@code CertificateRevokedException}. The
+     * invalidity date is the date on which it is known or suspected that the
+     * private key was compromised or that the certificate otherwise became
+     * invalid. This implementation calls {@code getExtensions()} and
+     * checks the returned map for an entry for the Invalidity Date extension
+     * OID ("2.5.29.24"). If found, it returns the invalidity date in the
+     * extension; otherwise null. A new Date object is returned each time the
+     * method is invoked to protect against subsequent modification.
+     *
+     * @return the invalidity date, or {@code null} if not specified
+     */
+    public Date getInvalidityDate() {
+        Extension ext = getExtensions().get("2.5.29.24");
+        if (ext == null) {
+            return null;
+        } else {
+            try {
+                Date invalidity = InvalidityDateExtension.toImpl(ext).get("DATE");
+                return new Date(invalidity.getTime());
+            } catch (IOException ioe) {
+                return null;
+            }
+        }
+    }
+
+    /**
+     * Returns a map of X.509 extensions containing additional information
+     * about the revoked certificate, such as the Invalidity Date
+     * Extension. Each key is an OID String that maps to the corresponding
+     * Extension.
+     *
+     * @return an unmodifiable map of X.509 extensions, or an empty map
+     *    if there are no extensions
+     */
+    public Map<String, Extension> getExtensions() {
+        return Collections.unmodifiableMap(extensions);
+    }
+
+    @Override
+    public String getMessage() {
+        return "Certificate has been revoked, reason: "
+               + reason + ", revocation date: " + revocationDate
+               + ", authority: " + authority + ", extension OIDs: "
+               + extensions.keySet();
+    }
+
+    /**
+     * Serialize this {@code CertificateRevokedException} instance.
+     *
+     * @serialData the size of the extensions map (int), followed by all of
+     * the extensions in the map, in no particular order. For each extension,
+     * the following data is emitted: the OID String (Object), the criticality
+     * flag (boolean), the length of the encoded extension value byte array
+     * (int), and the encoded extension value bytes.
+     */
+    private void writeObject(ObjectOutputStream oos) throws IOException {
+        // Write out the non-transient fields
+        // (revocationDate, reason, authority)
+        oos.defaultWriteObject();
+
+        // Write out the size (number of mappings) of the extensions map
+        oos.writeInt(extensions.size());
+
+        // For each extension in the map, the following are emitted (in order):
+        // the OID String (Object), the criticality flag (boolean), the length
+        // of the encoded extension value byte array (int), and the encoded
+        // extension value byte array. The extensions themselves are emitted
+        // in no particular order.
+        for (Map.Entry<String, Extension> entry : extensions.entrySet()) {
+            Extension ext = entry.getValue();
+            oos.writeObject(ext.getId());
+            oos.writeBoolean(ext.isCritical());
+            byte[] extVal = ext.getValue();
+            oos.writeInt(extVal.length);
+            oos.write(extVal);
+        }
+    }
+
+    /**
+     * Deserialize the {@code CertificateRevokedException} instance.
+     */
+    private void readObject(ObjectInputStream ois)
+        throws IOException, ClassNotFoundException {
+        // Read in the non-transient fields
+        // (revocationDate, reason, authority)
+        ois.defaultReadObject();
+
+        // Defensively copy the revocation date
+        revocationDate = new Date(revocationDate.getTime());
+
+        // Read in the size (number of mappings) of the extensions map
+        // and create the extensions map
+        int size = ois.readInt();
+        if (size == 0) {
+            extensions = Collections.emptyMap();
+        } else {
+            extensions = new HashMap<String, Extension>(size);
+        }
+
+        // Read in the extensions and put the mappings in the extensions map
+        for (int i = 0; i < size; i++) {
+            String oid = (String) ois.readObject();
+            boolean critical = ois.readBoolean();
+            int length = ois.readInt();
+            byte[] extVal = new byte[length];
+            ois.readFully(extVal);
+            Extension ext = sun.security.x509.Extension.newExtension
+                (new ObjectIdentifier(oid), critical, extVal);
+            extensions.put(oid, ext);
+        }
+    }
+}
diff --git a/java/security/cert/CollectionCertStoreParameters.java b/java/security/cert/CollectionCertStoreParameters.java
new file mode 100644
index 0000000..12bd358
--- /dev/null
+++ b/java/security/cert/CollectionCertStoreParameters.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2000, 2013, 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 java.security.cert;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Collections;
+
+/**
+ * Parameters used as input for the Collection {@code CertStore}
+ * algorithm.
+ * <p>
+ * This class is used to provide necessary configuration parameters
+ * to implementations of the Collection {@code CertStore}
+ * algorithm. The only parameter included in this class is the
+ * {@code Collection} from which the {@code CertStore} will
+ * retrieve certificates and CRLs.
+ * <p>
+ * <b>Concurrent Access</b>
+ * <p>
+ * Unless otherwise specified, the methods defined in this class are not
+ * thread-safe. Multiple threads that need to access a single
+ * object concurrently should synchronize amongst themselves and
+ * provide the necessary locking. Multiple threads each manipulating
+ * separate objects need not synchronize.
+ *
+ * @since       1.4
+ * @author      Steve Hanna
+ * @see         java.util.Collection
+ * @see         CertStore
+ */
+public class CollectionCertStoreParameters
+    implements CertStoreParameters {
+
+    private Collection<?> coll;
+
+    /**
+     * Creates an instance of {@code CollectionCertStoreParameters}
+     * which will allow certificates and CRLs to be retrieved from the
+     * specified {@code Collection}. If the specified
+     * {@code Collection} contains an object that is not a
+     * {@code Certificate} or {@code CRL}, that object will be
+     * ignored by the Collection {@code CertStore}.
+     * <p>
+     * The {@code Collection} is <b>not</b> copied. Instead, a
+     * reference is used. This allows the caller to subsequently add or
+     * remove {@code Certificates} or {@code CRL}s from the
+     * {@code Collection}, thus changing the set of
+     * {@code Certificates} or {@code CRL}s available to the
+     * Collection {@code CertStore}. The Collection {@code CertStore}
+     * will not modify the contents of the {@code Collection}.
+     * <p>
+     * If the {@code Collection} will be modified by one thread while
+     * another thread is calling a method of a Collection {@code CertStore}
+     * that has been initialized with this {@code Collection}, the
+     * {@code Collection} must have fail-fast iterators.
+     *
+     * @param collection a {@code Collection} of
+     *        {@code Certificate}s and {@code CRL}s
+     * @exception NullPointerException if {@code collection} is
+     * {@code null}
+     */
+    public CollectionCertStoreParameters(Collection<?> collection) {
+        if (collection == null)
+            throw new NullPointerException();
+        coll = collection;
+    }
+
+    /**
+     * Creates an instance of {@code CollectionCertStoreParameters} with
+     * the default parameter values (an empty and immutable
+     * {@code Collection}).
+     */
+    public CollectionCertStoreParameters() {
+        coll = Collections.EMPTY_SET;
+    }
+
+    /**
+     * Returns the {@code Collection} from which {@code Certificate}s
+     * and {@code CRL}s are retrieved. This is <b>not</b> a copy of the
+     * {@code Collection}, it is a reference. This allows the caller to
+     * subsequently add or remove {@code Certificates} or
+     * {@code CRL}s from the {@code Collection}.
+     *
+     * @return the {@code Collection} (never null)
+     */
+    public Collection<?> getCollection() {
+        return coll;
+    }
+
+    /**
+     * Returns a copy of this object. Note that only a reference to the
+     * {@code Collection} is copied, and not the contents.
+     *
+     * @return the copy
+     */
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            /* Cannot happen */
+            throw new InternalError(e.toString(), e);
+        }
+    }
+
+    /**
+     * Returns a formatted string describing the parameters.
+     *
+     * @return a formatted string describing the parameters
+     */
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append("CollectionCertStoreParameters: [\n");
+        sb.append("  collection: " + coll + "\n");
+        sb.append("]");
+        return sb.toString();
+    }
+}
diff --git a/java/security/cert/Extension.java b/java/security/cert/Extension.java
new file mode 100644
index 0000000..98e827c
--- /dev/null
+++ b/java/security/cert/Extension.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2007, 2013, 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 java.security.cert;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Serializable;
+
+/**
+ * This interface represents an X.509 extension.
+ *
+ * <p>
+ * Extensions provide a means of associating additional attributes with users
+ * or public keys and for managing a certification hierarchy.  The extension
+ * format also allows communities to define private extensions to carry
+ * information unique to those communities.
+ *
+ * <p>
+ * Each extension contains an object identifier, a criticality setting
+ * indicating whether it is a critical or a non-critical extension, and
+ * and an ASN.1 DER-encoded value. Its ASN.1 definition is:
+ *
+ * <pre>
+ *
+ *     Extension ::= SEQUENCE {
+ *         extnId        OBJECT IDENTIFIER,
+ *         critical      BOOLEAN DEFAULT FALSE,
+ *         extnValue     OCTET STRING
+ *                 -- contains a DER encoding of a value
+ *                 -- of the type registered for use with
+ *                 -- the extnId object identifier value
+ *     }
+ *
+ * </pre>
+ *
+ * <p>
+ * This interface is designed to provide access to a single extension,
+ * unlike {@link java.security.cert.X509Extension} which is more suitable
+ * for accessing a set of extensions.
+ *
+ * @since 1.7
+ */
+public interface Extension {
+
+    /**
+     * Gets the extensions's object identifier.
+     *
+     * @return the object identifier as a String
+     */
+    String getId();
+
+    /**
+     * Gets the extension's criticality setting.
+     *
+     * @return true if this is a critical extension.
+     */
+    boolean isCritical();
+
+    /**
+     * Gets the extensions's DER-encoded value. Note, this is the bytes
+     * that are encoded as an OCTET STRING. It does not include the OCTET
+     * STRING tag and length.
+     *
+     * @return a copy of the extension's value, or {@code null} if no
+     *    extension value is present.
+     */
+    byte[] getValue();
+
+    /**
+     * Generates the extension's DER encoding and writes it to the output
+     * stream.
+     *
+     * @param out the output stream
+     * @exception IOException on encoding or output error.
+     * @exception NullPointerException if {@code out} is {@code null}.
+     */
+    void encode(OutputStream out) throws IOException;
+}
diff --git a/java/security/cert/LDAPCertStoreParameters.java b/java/security/cert/LDAPCertStoreParameters.java
new file mode 100644
index 0000000..96fe9cd
--- /dev/null
+++ b/java/security/cert/LDAPCertStoreParameters.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2000, 2013, 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 java.security.cert;
+
+/**
+ * Parameters used as input for the LDAP {@code CertStore} algorithm.
+ * <p>
+ * This class is used to provide necessary configuration parameters (server
+ * name and port number) to implementations of the LDAP {@code CertStore}
+ * algorithm.
+ * <p>
+ * <b>Concurrent Access</b>
+ * <p>
+ * Unless otherwise specified, the methods defined in this class are not
+ * thread-safe. Multiple threads that need to access a single
+ * object concurrently should synchronize amongst themselves and
+ * provide the necessary locking. Multiple threads each manipulating
+ * separate objects need not synchronize.
+ *
+ * @since       1.4
+ * @author      Steve Hanna
+ * @see         CertStore
+ */
+public class LDAPCertStoreParameters implements CertStoreParameters {
+
+    private static final int LDAP_DEFAULT_PORT = 389;
+
+    /**
+     * the port number of the LDAP server
+     */
+    private int port;
+
+    /**
+     * the DNS name of the LDAP server
+     */
+    private String serverName;
+
+    /**
+     * Creates an instance of {@code LDAPCertStoreParameters} with the
+     * specified parameter values.
+     *
+     * @param serverName the DNS name of the LDAP server
+     * @param port the port number of the LDAP server
+     * @exception NullPointerException if {@code serverName} is
+     * {@code null}
+     */
+    public LDAPCertStoreParameters(String serverName, int port) {
+        if (serverName == null)
+            throw new NullPointerException();
+        this.serverName = serverName;
+        this.port = port;
+    }
+
+    /**
+     * Creates an instance of {@code LDAPCertStoreParameters} with the
+     * specified server name and a default port of 389.
+     *
+     * @param serverName the DNS name of the LDAP server
+     * @exception NullPointerException if {@code serverName} is
+     * {@code null}
+     */
+    public LDAPCertStoreParameters(String serverName) {
+        this(serverName, LDAP_DEFAULT_PORT);
+    }
+
+    /**
+     * Creates an instance of {@code LDAPCertStoreParameters} with the
+     * default parameter values (server name "localhost", port 389).
+     */
+    public LDAPCertStoreParameters() {
+        this("localhost", LDAP_DEFAULT_PORT);
+    }
+
+    /**
+     * Returns the DNS name of the LDAP server.
+     *
+     * @return the name (not {@code null})
+     */
+    public String getServerName() {
+        return serverName;
+    }
+
+    /**
+     * Returns the port number of the LDAP server.
+     *
+     * @return the port number
+     */
+    public int getPort() {
+        return port;
+    }
+
+    /**
+     * Returns a copy of this object. Changes to the copy will not affect
+     * the original and vice versa.
+     * <p>
+     * Note: this method currently performs a shallow copy of the object
+     * (simply calls {@code Object.clone()}). This may be changed in a
+     * future revision to perform a deep copy if new parameters are added
+     * that should not be shared.
+     *
+     * @return the copy
+     */
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            /* Cannot happen */
+            throw new InternalError(e.toString(), e);
+        }
+    }
+
+    /**
+     * Returns a formatted string describing the parameters.
+     *
+     * @return a formatted string describing the parameters
+     */
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append("LDAPCertStoreParameters: [\n");
+
+        sb.append("  serverName: " + serverName + "\n");
+        sb.append("  port: " + port + "\n");
+        sb.append("]");
+        return sb.toString();
+    }
+}
diff --git a/java/security/cert/PKIXBuilderParameters.java b/java/security/cert/PKIXBuilderParameters.java
new file mode 100644
index 0000000..b33e1f8
--- /dev/null
+++ b/java/security/cert/PKIXBuilderParameters.java
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2000, 2013, 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 java.security.cert;
+
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidParameterException;
+import java.util.Set;
+
+/**
+ * Parameters used as input for the PKIX {@code CertPathBuilder}
+ * algorithm.
+ * <p>
+ * A PKIX {@code CertPathBuilder} uses these parameters to {@link
+ * CertPathBuilder#build build} a {@code CertPath} which has been
+ * validated according to the PKIX certification path validation algorithm.
+ *
+ * <p>To instantiate a {@code PKIXBuilderParameters} object, an
+ * application must specify one or more <i>most-trusted CAs</i> as defined by
+ * the PKIX certification path validation algorithm. The most-trusted CA
+ * can be specified using one of two constructors. An application
+ * can call {@link #PKIXBuilderParameters(Set, CertSelector)
+ * PKIXBuilderParameters(Set, CertSelector)}, specifying a
+ * {@code Set} of {@code TrustAnchor} objects, each of which
+ * identifies a most-trusted CA. Alternatively, an application can call
+ * {@link #PKIXBuilderParameters(KeyStore, CertSelector)
+ * PKIXBuilderParameters(KeyStore, CertSelector)}, specifying a
+ * {@code KeyStore} instance containing trusted certificate entries, each
+ * of which will be considered as a most-trusted CA.
+ *
+ * <p>In addition, an application must specify constraints on the target
+ * certificate that the {@code CertPathBuilder} will attempt
+ * to build a path to. The constraints are specified as a
+ * {@code CertSelector} object. These constraints should provide the
+ * {@code CertPathBuilder} with enough search criteria to find the target
+ * certificate. Minimal criteria for an {@code X509Certificate} usually
+ * include the subject name and/or one or more subject alternative names.
+ * If enough criteria is not specified, the {@code CertPathBuilder}
+ * may throw a {@code CertPathBuilderException}.
+ * <p>
+ * <b>Concurrent Access</b>
+ * <p>
+ * Unless otherwise specified, the methods defined in this class are not
+ * thread-safe. Multiple threads that need to access a single
+ * object concurrently should synchronize amongst themselves and
+ * provide the necessary locking. Multiple threads each manipulating
+ * separate objects need not synchronize.
+ *
+ * @see CertPathBuilder
+ *
+ * @since       1.4
+ * @author      Sean Mullan
+ */
+public class PKIXBuilderParameters extends PKIXParameters {
+
+    private int maxPathLength = 5;
+
+    /**
+     * Creates an instance of {@code PKIXBuilderParameters} with
+     * the specified {@code Set} of most-trusted CAs.
+     * Each element of the set is a {@link TrustAnchor TrustAnchor}.
+     *
+     * <p>Note that the {@code Set} is copied to protect against
+     * subsequent modifications.
+     *
+     * @param trustAnchors a {@code Set} of {@code TrustAnchor}s
+     * @param targetConstraints a {@code CertSelector} specifying the
+     * constraints on the target certificate
+     * @throws InvalidAlgorithmParameterException if {@code trustAnchors}
+     * is empty {@code (trustAnchors.isEmpty() == true)}
+     * @throws NullPointerException if {@code trustAnchors} is
+     * {@code null}
+     * @throws ClassCastException if any of the elements of
+     * {@code trustAnchors} are not of type
+     * {@code java.security.cert.TrustAnchor}
+     */
+    public PKIXBuilderParameters(Set<TrustAnchor> trustAnchors, CertSelector
+        targetConstraints) throws InvalidAlgorithmParameterException
+    {
+        super(trustAnchors);
+        setTargetCertConstraints(targetConstraints);
+    }
+
+    /**
+     * Creates an instance of {@code PKIXBuilderParameters} that
+     * populates the set of most-trusted CAs from the trusted
+     * certificate entries contained in the specified {@code KeyStore}.
+     * Only keystore entries that contain trusted {@code X509Certificate}s
+     * are considered; all other certificate types are ignored.
+     *
+     * @param keystore a {@code KeyStore} from which the set of
+     * most-trusted CAs will be populated
+     * @param targetConstraints a {@code CertSelector} specifying the
+     * constraints on the target certificate
+     * @throws KeyStoreException if {@code keystore} has not been
+     * initialized
+     * @throws InvalidAlgorithmParameterException if {@code keystore} does
+     * not contain at least one trusted certificate entry
+     * @throws NullPointerException if {@code keystore} is
+     * {@code null}
+     */
+    public PKIXBuilderParameters(KeyStore keystore,
+        CertSelector targetConstraints)
+        throws KeyStoreException, InvalidAlgorithmParameterException
+    {
+        super(keystore);
+        setTargetCertConstraints(targetConstraints);
+    }
+
+    /**
+     * Sets the value of the maximum number of non-self-issued intermediate
+     * certificates that may exist in a certification path. A certificate
+     * is self-issued if the DNs that appear in the subject and issuer
+     * fields are identical and are not empty. Note that the last certificate
+     * in a certification path is not an intermediate certificate, and is not
+     * included in this limit. Usually the last certificate is an end entity
+     * certificate, but it can be a CA certificate. A PKIX
+     * {@code CertPathBuilder} instance must not build
+     * paths longer than the length specified.
+     *
+     * <p> A value of 0 implies that the path can only contain
+     * a single certificate. A value of -1 implies that the
+     * path length is unconstrained (i.e. there is no maximum).
+     * The default maximum path length, if not specified, is 5.
+     * Setting a value less than -1 will cause an exception to be thrown.
+     *
+     * <p> If any of the CA certificates contain the
+     * {@code BasicConstraintsExtension}, the value of the
+     * {@code pathLenConstraint} field of the extension overrides
+     * the maximum path length parameter whenever the result is a
+     * certification path of smaller length.
+     *
+     * @param maxPathLength the maximum number of non-self-issued intermediate
+     *  certificates that may exist in a certification path
+     * @throws InvalidParameterException if {@code maxPathLength} is set
+     *  to a value less than -1
+     *
+     * @see #getMaxPathLength
+     */
+    public void setMaxPathLength(int maxPathLength) {
+        if (maxPathLength < -1) {
+            throw new InvalidParameterException("the maximum path "
+                + "length parameter can not be less than -1");
+        }
+        this.maxPathLength = maxPathLength;
+    }
+
+    /**
+     * Returns the value of the maximum number of intermediate non-self-issued
+     * certificates that may exist in a certification path. See
+     * the {@link #setMaxPathLength} method for more details.
+     *
+     * @return the maximum number of non-self-issued intermediate certificates
+     *  that may exist in a certification path, or -1 if there is no limit
+     *
+     * @see #setMaxPathLength
+     */
+    public int getMaxPathLength() {
+        return maxPathLength;
+    }
+
+    /**
+     * Returns a formatted string describing the parameters.
+     *
+     * @return a formatted string describing the parameters
+     */
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append("[\n");
+        sb.append(super.toString());
+        sb.append("  Maximum Path Length: " + maxPathLength + "\n");
+        sb.append("]\n");
+        return sb.toString();
+    }
+}
diff --git a/java/security/cert/PKIXCertPathBuilderResult.java b/java/security/cert/PKIXCertPathBuilderResult.java
new file mode 100644
index 0000000..3255a3b
--- /dev/null
+++ b/java/security/cert/PKIXCertPathBuilderResult.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2000, 2013, 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 java.security.cert;
+
+import java.security.PublicKey;
+
+/**
+ * This class represents the successful result of the PKIX certification
+ * path builder algorithm. All certification paths that are built and
+ * returned using this algorithm are also validated according to the PKIX
+ * certification path validation algorithm.
+ *
+ * <p>Instances of {@code PKIXCertPathBuilderResult} are returned by
+ * the {@code build} method of {@code CertPathBuilder}
+ * objects implementing the PKIX algorithm.
+ *
+ * <p>All {@code PKIXCertPathBuilderResult} objects contain the
+ * certification path constructed by the build algorithm, the
+ * valid policy tree and subject public key resulting from the build
+ * algorithm, and a {@code TrustAnchor} describing the certification
+ * authority (CA) that served as a trust anchor for the certification path.
+ * <p>
+ * <b>Concurrent Access</b>
+ * <p>
+ * Unless otherwise specified, the methods defined in this class are not
+ * thread-safe. Multiple threads that need to access a single
+ * object concurrently should synchronize amongst themselves and
+ * provide the necessary locking. Multiple threads each manipulating
+ * separate objects need not synchronize.
+ *
+ * @see CertPathBuilderResult
+ *
+ * @since       1.4
+ * @author      Anne Anderson
+ */
+public class PKIXCertPathBuilderResult extends PKIXCertPathValidatorResult
+    implements CertPathBuilderResult {
+
+    private CertPath certPath;
+
+    /**
+     * Creates an instance of {@code PKIXCertPathBuilderResult}
+     * containing the specified parameters.
+     *
+     * @param certPath the validated {@code CertPath}
+     * @param trustAnchor a {@code TrustAnchor} describing the CA that
+     * served as a trust anchor for the certification path
+     * @param policyTree the immutable valid policy tree, or {@code null}
+     * if there are no valid policies
+     * @param subjectPublicKey the public key of the subject
+     * @throws NullPointerException if the {@code certPath},
+     * {@code trustAnchor} or {@code subjectPublicKey} parameters
+     * are {@code null}
+     */
+    public PKIXCertPathBuilderResult(CertPath certPath,
+        TrustAnchor trustAnchor, PolicyNode policyTree,
+        PublicKey subjectPublicKey)
+    {
+        super(trustAnchor, policyTree, subjectPublicKey);
+        if (certPath == null)
+            throw new NullPointerException("certPath must be non-null");
+        this.certPath = certPath;
+    }
+
+    /**
+     * Returns the built and validated certification path. The
+     * {@code CertPath} object does not include the trust anchor.
+     * Instead, use the {@link #getTrustAnchor() getTrustAnchor()} method to
+     * obtain the {@code TrustAnchor} that served as the trust anchor
+     * for the certification path.
+     *
+     * @return the built and validated {@code CertPath} (never
+     * {@code null})
+     */
+    public CertPath getCertPath() {
+        return certPath;
+    }
+
+    /**
+     * Return a printable representation of this
+     * {@code PKIXCertPathBuilderResult}.
+     *
+     * @return a {@code String} describing the contents of this
+     *         {@code PKIXCertPathBuilderResult}
+     */
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append("PKIXCertPathBuilderResult: [\n");
+        sb.append("  Certification Path: " + certPath + "\n");
+        sb.append("  Trust Anchor: " + getTrustAnchor().toString() + "\n");
+        sb.append("  Policy Tree: " + String.valueOf(getPolicyTree()) + "\n");
+        sb.append("  Subject Public Key: " + getPublicKey() + "\n");
+        sb.append("]");
+        return sb.toString();
+    }
+}
diff --git a/java/security/cert/PKIXCertPathChecker.java b/java/security/cert/PKIXCertPathChecker.java
new file mode 100644
index 0000000..21e01bf
--- /dev/null
+++ b/java/security/cert/PKIXCertPathChecker.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2000, 2013, 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 java.security.cert;
+
+import java.util.Collection;
+import java.util.Set;
+
+/**
+ * An abstract class that performs one or more checks on an
+ * {@code X509Certificate}.
+ *
+ * <p>A concrete implementation of the {@code PKIXCertPathChecker} class
+ * can be created to extend the PKIX certification path validation algorithm.
+ * For example, an implementation may check for and process a critical private
+ * extension of each certificate in a certification path.
+ *
+ * <p>Instances of {@code PKIXCertPathChecker} are passed as parameters
+ * using the {@link PKIXParameters#setCertPathCheckers setCertPathCheckers}
+ * or {@link PKIXParameters#addCertPathChecker addCertPathChecker} methods
+ * of the {@code PKIXParameters} and {@code PKIXBuilderParameters}
+ * class. Each of the {@code PKIXCertPathChecker}s {@link #check check}
+ * methods will be called, in turn, for each certificate processed by a PKIX
+ * {@code CertPathValidator} or {@code CertPathBuilder}
+ * implementation.
+ *
+ * <p>A {@code PKIXCertPathChecker} may be called multiple times on
+ * successive certificates in a certification path. Concrete subclasses
+ * are expected to maintain any internal state that may be necessary to
+ * check successive certificates. The {@link #init init} method is used
+ * to initialize the internal state of the checker so that the certificates
+ * of a new certification path may be checked. A stateful implementation
+ * <b>must</b> override the {@link #clone clone} method if necessary in
+ * order to allow a PKIX {@code CertPathBuilder} to efficiently
+ * backtrack and try other paths. In these situations, the
+ * {@code CertPathBuilder} is able to restore prior path validation
+ * states by restoring the cloned {@code PKIXCertPathChecker}s.
+ *
+ * <p>The order in which the certificates are presented to the
+ * {@code PKIXCertPathChecker} may be either in the forward direction
+ * (from target to most-trusted CA) or in the reverse direction (from
+ * most-trusted CA to target). A {@code PKIXCertPathChecker} implementation
+ * <b>must</b> support reverse checking (the ability to perform its checks when
+ * it is presented with certificates in the reverse direction) and <b>may</b>
+ * support forward checking (the ability to perform its checks when it is
+ * presented with certificates in the forward direction). The
+ * {@link #isForwardCheckingSupported isForwardCheckingSupported} method
+ * indicates whether forward checking is supported.
+ * <p>
+ * Additional input parameters required for executing the check may be
+ * specified through constructors of concrete implementations of this class.
+ * <p>
+ * <b>Concurrent Access</b>
+ * <p>
+ * Unless otherwise specified, the methods defined in this class are not
+ * thread-safe. Multiple threads that need to access a single
+ * object concurrently should synchronize amongst themselves and
+ * provide the necessary locking. Multiple threads each manipulating
+ * separate objects need not synchronize.
+ *
+ * @see PKIXParameters
+ * @see PKIXBuilderParameters
+ *
+ * @since       1.4
+ * @author      Yassir Elley
+ * @author      Sean Mullan
+ */
+public abstract class PKIXCertPathChecker
+    implements CertPathChecker, Cloneable {
+
+    /**
+     * Default constructor.
+     */
+    protected PKIXCertPathChecker() {}
+
+    /**
+     * Initializes the internal state of this {@code PKIXCertPathChecker}.
+     * <p>
+     * The {@code forward} flag specifies the order that
+     * certificates will be passed to the {@link #check check} method
+     * (forward or reverse). A {@code PKIXCertPathChecker} <b>must</b>
+     * support reverse checking and <b>may</b> support forward checking.
+     *
+     * @param forward the order that certificates are presented to
+     * the {@code check} method. If {@code true}, certificates
+     * are presented from target to most-trusted CA (forward); if
+     * {@code false}, from most-trusted CA to target (reverse).
+     * @throws CertPathValidatorException if this
+     * {@code PKIXCertPathChecker} is unable to check certificates in
+     * the specified order; it should never be thrown if the forward flag
+     * is false since reverse checking must be supported
+     */
+    @Override
+    public abstract void init(boolean forward)
+        throws CertPathValidatorException;
+
+    /**
+     * Indicates if forward checking is supported. Forward checking refers
+     * to the ability of the {@code PKIXCertPathChecker} to perform
+     * its checks when certificates are presented to the {@code check}
+     * method in the forward direction (from target to most-trusted CA).
+     *
+     * @return {@code true} if forward checking is supported,
+     * {@code false} otherwise
+     */
+    @Override
+    public abstract boolean isForwardCheckingSupported();
+
+    /**
+     * Returns an immutable {@code Set} of X.509 certificate extensions
+     * that this {@code PKIXCertPathChecker} supports (i.e. recognizes, is
+     * able to process), or {@code null} if no extensions are supported.
+     * <p>
+     * Each element of the set is a {@code String} representing the
+     * Object Identifier (OID) of the X.509 extension that is supported.
+     * The OID is represented by a set of nonnegative integers separated by
+     * periods.
+     * <p>
+     * All X.509 certificate extensions that a {@code PKIXCertPathChecker}
+     * might possibly be able to process should be included in the set.
+     *
+     * @return an immutable {@code Set} of X.509 extension OIDs (in
+     * {@code String} format) supported by this
+     * {@code PKIXCertPathChecker}, or {@code null} if no
+     * extensions are supported
+     */
+    public abstract Set<String> getSupportedExtensions();
+
+    /**
+     * Performs the check(s) on the specified certificate using its internal
+     * state and removes any critical extensions that it processes from the
+     * specified collection of OID strings that represent the unresolved
+     * critical extensions. The certificates are presented in the order
+     * specified by the {@code init} method.
+     *
+     * @param cert the {@code Certificate} to be checked
+     * @param unresolvedCritExts a {@code Collection} of OID strings
+     * representing the current set of unresolved critical extensions
+     * @exception CertPathValidatorException if the specified certificate does
+     * not pass the check
+     */
+    public abstract void check(Certificate cert,
+            Collection<String> unresolvedCritExts)
+            throws CertPathValidatorException;
+
+    /**
+     * {@inheritDoc}
+     *
+     * <p>This implementation calls
+     * {@code check(cert, java.util.Collections.<String>emptySet())}.
+     */
+    @Override
+    public void check(Certificate cert) throws CertPathValidatorException {
+        check(cert, java.util.Collections.<String>emptySet());
+    }
+
+    /**
+     * Returns a clone of this object. Calls the {@code Object.clone()}
+     * method.
+     * All subclasses which maintain state must support and
+     * override this method, if necessary.
+     *
+     * @return a copy of this {@code PKIXCertPathChecker}
+     */
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            /* Cannot happen */
+            throw new InternalError(e.toString(), e);
+        }
+    }
+}
diff --git a/java/security/cert/PKIXCertPathValidatorResult.java b/java/security/cert/PKIXCertPathValidatorResult.java
new file mode 100644
index 0000000..b40cd39
--- /dev/null
+++ b/java/security/cert/PKIXCertPathValidatorResult.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2000, 2013, 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 java.security.cert;
+
+import java.security.PublicKey;
+
+/**
+ * This class represents the successful result of the PKIX certification
+ * path validation algorithm.
+ *
+ * <p>Instances of {@code PKIXCertPathValidatorResult} are returned by the
+ * {@link CertPathValidator#validate validate} method of
+ * {@code CertPathValidator} objects implementing the PKIX algorithm.
+ *
+ * <p> All {@code PKIXCertPathValidatorResult} objects contain the
+ * valid policy tree and subject public key resulting from the
+ * validation algorithm, as well as a {@code TrustAnchor} describing
+ * the certification authority (CA) that served as a trust anchor for the
+ * certification path.
+ * <p>
+ * <b>Concurrent Access</b>
+ * <p>
+ * Unless otherwise specified, the methods defined in this class are not
+ * thread-safe. Multiple threads that need to access a single
+ * object concurrently should synchronize amongst themselves and
+ * provide the necessary locking. Multiple threads each manipulating
+ * separate objects need not synchronize.
+ *
+ * @see CertPathValidatorResult
+ *
+ * @since       1.4
+ * @author      Yassir Elley
+ * @author      Sean Mullan
+ */
+public class PKIXCertPathValidatorResult implements CertPathValidatorResult {
+
+    private TrustAnchor trustAnchor;
+    private PolicyNode policyTree;
+    private PublicKey subjectPublicKey;
+
+    /**
+     * Creates an instance of {@code PKIXCertPathValidatorResult}
+     * containing the specified parameters.
+     *
+     * @param trustAnchor a {@code TrustAnchor} describing the CA that
+     * served as a trust anchor for the certification path
+     * @param policyTree the immutable valid policy tree, or {@code null}
+     * if there are no valid policies
+     * @param subjectPublicKey the public key of the subject
+     * @throws NullPointerException if the {@code subjectPublicKey} or
+     * {@code trustAnchor} parameters are {@code null}
+     */
+    public PKIXCertPathValidatorResult(TrustAnchor trustAnchor,
+        PolicyNode policyTree, PublicKey subjectPublicKey)
+    {
+        if (subjectPublicKey == null)
+            throw new NullPointerException("subjectPublicKey must be non-null");
+        if (trustAnchor == null)
+            throw new NullPointerException("trustAnchor must be non-null");
+        this.trustAnchor = trustAnchor;
+        this.policyTree = policyTree;
+        this.subjectPublicKey = subjectPublicKey;
+    }
+
+    /**
+     * Returns the {@code TrustAnchor} describing the CA that served
+     * as a trust anchor for the certification path.
+     *
+     * @return the {@code TrustAnchor} (never {@code null})
+     */
+    public TrustAnchor getTrustAnchor() {
+        return trustAnchor;
+    }
+
+    /**
+     * Returns the root node of the valid policy tree resulting from the
+     * PKIX certification path validation algorithm. The
+     * {@code PolicyNode} object that is returned and any objects that
+     * it returns through public methods are immutable.
+     *
+     * <p>Most applications will not need to examine the valid policy tree.
+     * They can achieve their policy processing goals by setting the
+     * policy-related parameters in {@code PKIXParameters}. However, more
+     * sophisticated applications, especially those that process policy
+     * qualifiers, may need to traverse the valid policy tree using the
+     * {@link PolicyNode#getParent PolicyNode.getParent} and
+     * {@link PolicyNode#getChildren PolicyNode.getChildren} methods.
+     *
+     * @return the root node of the valid policy tree, or {@code null}
+     * if there are no valid policies
+     */
+    public PolicyNode getPolicyTree() {
+        return policyTree;
+    }
+
+    /**
+     * Returns the public key of the subject (target) of the certification
+     * path, including any inherited public key parameters if applicable.
+     *
+     * @return the public key of the subject (never {@code null})
+     */
+    public PublicKey getPublicKey() {
+        return subjectPublicKey;
+    }
+
+    /**
+     * Returns a copy of this object.
+     *
+     * @return the copy
+     */
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            /* Cannot happen */
+            throw new InternalError(e.toString(), e);
+        }
+    }
+
+    /**
+     * Return a printable representation of this
+     * {@code PKIXCertPathValidatorResult}.
+     *
+     * @return a {@code String} describing the contents of this
+     *         {@code PKIXCertPathValidatorResult}
+     */
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append("PKIXCertPathValidatorResult: [\n");
+        sb.append("  Trust Anchor: " + trustAnchor.toString() + "\n");
+        sb.append("  Policy Tree: " + String.valueOf(policyTree) + "\n");
+        sb.append("  Subject Public Key: " + subjectPublicKey + "\n");
+        sb.append("]");
+        return sb.toString();
+    }
+}
diff --git a/java/security/cert/PKIXParameters.java b/java/security/cert/PKIXParameters.java
new file mode 100644
index 0000000..4d8a344
--- /dev/null
+++ b/java/security/cert/PKIXParameters.java
@@ -0,0 +1,736 @@
+/*
+ * Copyright (c) 2000, 2013, 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 java.security.cert;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Parameters used as input for the PKIX {@code CertPathValidator}
+ * algorithm.
+ * <p>
+ * A PKIX {@code CertPathValidator} uses these parameters to
+ * validate a {@code CertPath} according to the PKIX certification path
+ * validation algorithm.
+ *
+ * <p>To instantiate a {@code PKIXParameters} object, an
+ * application must specify one or more <i>most-trusted CAs</i> as defined by
+ * the PKIX certification path validation algorithm. The most-trusted CAs
+ * can be specified using one of two constructors. An application
+ * can call {@link #PKIXParameters(Set) PKIXParameters(Set)},
+ * specifying a {@code Set} of {@code TrustAnchor} objects, each
+ * of which identify a most-trusted CA. Alternatively, an application can call
+ * {@link #PKIXParameters(KeyStore) PKIXParameters(KeyStore)}, specifying a
+ * {@code KeyStore} instance containing trusted certificate entries, each
+ * of which will be considered as a most-trusted CA.
+ * <p>
+ * Once a {@code PKIXParameters} object has been created, other parameters
+ * can be specified (by calling {@link #setInitialPolicies setInitialPolicies}
+ * or {@link #setDate setDate}, for instance) and then the
+ * {@code PKIXParameters} is passed along with the {@code CertPath}
+ * to be validated to {@link CertPathValidator#validate
+ * CertPathValidator.validate}.
+ * <p>
+ * Any parameter that is not set (or is set to {@code null}) will
+ * be set to the default value for that parameter. The default value for the
+ * {@code date} parameter is {@code null}, which indicates
+ * the current time when the path is validated. The default for the
+ * remaining parameters is the least constrained.
+ * <p>
+ * <b>Concurrent Access</b>
+ * <p>
+ * Unless otherwise specified, the methods defined in this class are not
+ * thread-safe. Multiple threads that need to access a single
+ * object concurrently should synchronize amongst themselves and
+ * provide the necessary locking. Multiple threads each manipulating
+ * separate objects need not synchronize.
+ *
+ * @see CertPathValidator
+ *
+ * @since       1.4
+ * @author      Sean Mullan
+ * @author      Yassir Elley
+ */
+public class PKIXParameters implements CertPathParameters {
+
+    private Set<TrustAnchor> unmodTrustAnchors;
+    private Date date;
+    private List<PKIXCertPathChecker> certPathCheckers;
+    private String sigProvider;
+    private boolean revocationEnabled = true;
+    private Set<String> unmodInitialPolicies;
+    private boolean explicitPolicyRequired = false;
+    private boolean policyMappingInhibited = false;
+    private boolean anyPolicyInhibited = false;
+    private boolean policyQualifiersRejected = true;
+    private List<CertStore> certStores;
+    private CertSelector certSelector;
+
+    /**
+     * Creates an instance of {@code PKIXParameters} with the specified
+     * {@code Set} of most-trusted CAs. Each element of the
+     * set is a {@link TrustAnchor TrustAnchor}.
+     * <p>
+     * Note that the {@code Set} is copied to protect against
+     * subsequent modifications.
+     *
+     * @param trustAnchors a {@code Set} of {@code TrustAnchor}s
+     * @throws InvalidAlgorithmParameterException if the specified
+     * {@code Set} is empty {@code (trustAnchors.isEmpty() == true)}
+     * @throws NullPointerException if the specified {@code Set} is
+     * {@code null}
+     * @throws ClassCastException if any of the elements in the {@code Set}
+     * are not of type {@code java.security.cert.TrustAnchor}
+     */
+    public PKIXParameters(Set<TrustAnchor> trustAnchors)
+        throws InvalidAlgorithmParameterException
+    {
+        setTrustAnchors(trustAnchors);
+
+        this.unmodInitialPolicies = Collections.<String>emptySet();
+        this.certPathCheckers = new ArrayList<PKIXCertPathChecker>();
+        this.certStores = new ArrayList<CertStore>();
+    }
+
+    /**
+     * Creates an instance of {@code PKIXParameters} that
+     * populates the set of most-trusted CAs from the trusted
+     * certificate entries contained in the specified {@code KeyStore}.
+     * Only keystore entries that contain trusted {@code X509Certificates}
+     * are considered; all other certificate types are ignored.
+     *
+     * @param keystore a {@code KeyStore} from which the set of
+     * most-trusted CAs will be populated
+     * @throws KeyStoreException if the keystore has not been initialized
+     * @throws InvalidAlgorithmParameterException if the keystore does
+     * not contain at least one trusted certificate entry
+     * @throws NullPointerException if the keystore is {@code null}
+     */
+    public PKIXParameters(KeyStore keystore)
+        throws KeyStoreException, InvalidAlgorithmParameterException
+    {
+        if (keystore == null)
+            throw new NullPointerException("the keystore parameter must be " +
+                "non-null");
+        Set<TrustAnchor> hashSet = new HashSet<TrustAnchor>();
+        Enumeration<String> aliases = keystore.aliases();
+        while (aliases.hasMoreElements()) {
+            String alias = aliases.nextElement();
+            if (keystore.isCertificateEntry(alias)) {
+                Certificate cert = keystore.getCertificate(alias);
+                if (cert instanceof X509Certificate)
+                    hashSet.add(new TrustAnchor((X509Certificate)cert, null));
+            }
+        }
+        setTrustAnchors(hashSet);
+        this.unmodInitialPolicies = Collections.<String>emptySet();
+        this.certPathCheckers = new ArrayList<PKIXCertPathChecker>();
+        this.certStores = new ArrayList<CertStore>();
+    }
+
+    /**
+     * Returns an immutable {@code Set} of the most-trusted
+     * CAs.
+     *
+     * @return an immutable {@code Set} of {@code TrustAnchor}s
+     * (never {@code null})
+     *
+     * @see #setTrustAnchors
+     */
+    public Set<TrustAnchor> getTrustAnchors() {
+        return this.unmodTrustAnchors;
+    }
+
+    /**
+     * Sets the {@code Set} of most-trusted CAs.
+     * <p>
+     * Note that the {@code Set} is copied to protect against
+     * subsequent modifications.
+     *
+     * @param trustAnchors a {@code Set} of {@code TrustAnchor}s
+     * @throws InvalidAlgorithmParameterException if the specified
+     * {@code Set} is empty {@code (trustAnchors.isEmpty() == true)}
+     * @throws NullPointerException if the specified {@code Set} is
+     * {@code null}
+     * @throws ClassCastException if any of the elements in the set
+     * are not of type {@code java.security.cert.TrustAnchor}
+     *
+     * @see #getTrustAnchors
+     */
+    public void setTrustAnchors(Set<TrustAnchor> trustAnchors)
+        throws InvalidAlgorithmParameterException
+    {
+        if (trustAnchors == null) {
+            throw new NullPointerException("the trustAnchors parameters must" +
+                " be non-null");
+        }
+        if (trustAnchors.isEmpty()) {
+            throw new InvalidAlgorithmParameterException("the trustAnchors " +
+                "parameter must be non-empty");
+        }
+        for (Iterator<TrustAnchor> i = trustAnchors.iterator(); i.hasNext(); ) {
+            if (!(i.next() instanceof TrustAnchor)) {
+                throw new ClassCastException("all elements of set must be "
+                    + "of type java.security.cert.TrustAnchor");
+            }
+        }
+        this.unmodTrustAnchors = Collections.unmodifiableSet
+                (new HashSet<TrustAnchor>(trustAnchors));
+    }
+
+    /**
+     * Returns an immutable {@code Set} of initial
+     * policy identifiers (OID strings), indicating that any one of these
+     * policies would be acceptable to the certificate user for the purposes of
+     * certification path processing. The default return value is an empty
+     * {@code Set}, which is interpreted as meaning that any policy would
+     * be acceptable.
+     *
+     * @return an immutable {@code Set} of initial policy OIDs in
+     * {@code String} format, or an empty {@code Set} (implying any
+     * policy is acceptable). Never returns {@code null}.
+     *
+     * @see #setInitialPolicies
+     */
+    public Set<String> getInitialPolicies() {
+        return this.unmodInitialPolicies;
+    }
+
+    /**
+     * Sets the {@code Set} of initial policy identifiers
+     * (OID strings), indicating that any one of these
+     * policies would be acceptable to the certificate user for the purposes of
+     * certification path processing. By default, any policy is acceptable
+     * (i.e. all policies), so a user that wants to allow any policy as
+     * acceptable does not need to call this method, or can call it
+     * with an empty {@code Set} (or {@code null}).
+     * <p>
+     * Note that the {@code Set} is copied to protect against
+     * subsequent modifications.
+     *
+     * @param initialPolicies a {@code Set} of initial policy
+     * OIDs in {@code String} format (or {@code null})
+     * @throws ClassCastException if any of the elements in the set are
+     * not of type {@code String}
+     *
+     * @see #getInitialPolicies
+     */
+    public void setInitialPolicies(Set<String> initialPolicies) {
+        if (initialPolicies != null) {
+            for (Iterator<String> i = initialPolicies.iterator();
+                        i.hasNext();) {
+                if (!(i.next() instanceof String))
+                    throw new ClassCastException("all elements of set must be "
+                        + "of type java.lang.String");
+            }
+            this.unmodInitialPolicies =
+                Collections.unmodifiableSet(new HashSet<String>(initialPolicies));
+        } else
+            this.unmodInitialPolicies = Collections.<String>emptySet();
+    }
+
+    /**
+     * Sets the list of {@code CertStore}s to be used in finding
+     * certificates and CRLs. May be {@code null}, in which case
+     * no {@code CertStore}s will be used. The first
+     * {@code CertStore}s in the list may be preferred to those that
+     * appear later.
+     * <p>
+     * Note that the {@code List} is copied to protect against
+     * subsequent modifications.
+     *
+     * @param stores a {@code List} of {@code CertStore}s (or
+     * {@code null})
+     * @throws ClassCastException if any of the elements in the list are
+     * not of type {@code java.security.cert.CertStore}
+     *
+     * @see #getCertStores
+     */
+    public void setCertStores(List<CertStore> stores) {
+        if (stores == null) {
+            this.certStores = new ArrayList<CertStore>();
+        } else {
+            for (Iterator<CertStore> i = stores.iterator(); i.hasNext();) {
+                if (!(i.next() instanceof CertStore)) {
+                    throw new ClassCastException("all elements of list must be "
+                        + "of type java.security.cert.CertStore");
+                }
+            }
+            this.certStores = new ArrayList<CertStore>(stores);
+        }
+    }
+
+    /**
+     * Adds a {@code CertStore} to the end of the list of
+     * {@code CertStore}s used in finding certificates and CRLs.
+     *
+     * @param store the {@code CertStore} to add. If {@code null},
+     * the store is ignored (not added to list).
+     */
+    public void addCertStore(CertStore store) {
+        if (store != null) {
+            this.certStores.add(store);
+        }
+    }
+
+    /**
+     * Returns an immutable {@code List} of {@code CertStore}s that
+     * are used to find certificates and CRLs.
+     *
+     * @return an immutable {@code List} of {@code CertStore}s
+     * (may be empty, but never {@code null})
+     *
+     * @see #setCertStores
+     */
+    public List<CertStore> getCertStores() {
+        return Collections.unmodifiableList
+                (new ArrayList<CertStore>(this.certStores));
+    }
+
+    /**
+     * Sets the RevocationEnabled flag. If this flag is true, the default
+     * revocation checking mechanism of the underlying PKIX service provider
+     * will be used. If this flag is false, the default revocation checking
+     * mechanism will be disabled (not used).
+     * <p>
+     * When a {@code PKIXParameters} object is created, this flag is set
+     * to true. This setting reflects the most common strategy for checking
+     * revocation, since each service provider must support revocation
+     * checking to be PKIX compliant. Sophisticated applications should set
+     * this flag to false when it is not practical to use a PKIX service
+     * provider's default revocation checking mechanism or when an alternative
+     * revocation checking mechanism is to be substituted (by also calling the
+     * {@link #addCertPathChecker addCertPathChecker} or {@link
+     * #setCertPathCheckers setCertPathCheckers} methods).
+     *
+     * @param val the new value of the RevocationEnabled flag
+     */
+    public void setRevocationEnabled(boolean val) {
+        revocationEnabled = val;
+    }
+
+    /**
+     * Checks the RevocationEnabled flag. If this flag is true, the default
+     * revocation checking mechanism of the underlying PKIX service provider
+     * will be used. If this flag is false, the default revocation checking
+     * mechanism will be disabled (not used). See the {@link
+     * #setRevocationEnabled setRevocationEnabled} method for more details on
+     * setting the value of this flag.
+     *
+     * @return the current value of the RevocationEnabled flag
+     */
+    public boolean isRevocationEnabled() {
+        return revocationEnabled;
+    }
+
+    /**
+     * Sets the ExplicitPolicyRequired flag. If this flag is true, an
+     * acceptable policy needs to be explicitly identified in every certificate.
+     * By default, the ExplicitPolicyRequired flag is false.
+     *
+     * @param val {@code true} if explicit policy is to be required,
+     * {@code false} otherwise
+     */
+    public void setExplicitPolicyRequired(boolean val) {
+        explicitPolicyRequired = val;
+    }
+
+    /**
+     * Checks if explicit policy is required. If this flag is true, an
+     * acceptable policy needs to be explicitly identified in every certificate.
+     * By default, the ExplicitPolicyRequired flag is false.
+     *
+     * @return {@code true} if explicit policy is required,
+     * {@code false} otherwise
+     */
+    public boolean isExplicitPolicyRequired() {
+        return explicitPolicyRequired;
+    }
+
+    /**
+     * Sets the PolicyMappingInhibited flag. If this flag is true, policy
+     * mapping is inhibited. By default, policy mapping is not inhibited (the
+     * flag is false).
+     *
+     * @param val {@code true} if policy mapping is to be inhibited,
+     * {@code false} otherwise
+     */
+    public void setPolicyMappingInhibited(boolean val) {
+        policyMappingInhibited = val;
+    }
+
+    /**
+     * Checks if policy mapping is inhibited. If this flag is true, policy
+     * mapping is inhibited. By default, policy mapping is not inhibited (the
+     * flag is false).
+     *
+     * @return true if policy mapping is inhibited, false otherwise
+     */
+    public boolean isPolicyMappingInhibited() {
+        return policyMappingInhibited;
+    }
+
+    /**
+     * Sets state to determine if the any policy OID should be processed
+     * if it is included in a certificate. By default, the any policy OID
+     * is not inhibited ({@link #isAnyPolicyInhibited isAnyPolicyInhibited()}
+     * returns {@code false}).
+     *
+     * @param val {@code true} if the any policy OID is to be
+     * inhibited, {@code false} otherwise
+     */
+    public void setAnyPolicyInhibited(boolean val) {
+        anyPolicyInhibited = val;
+    }
+
+    /**
+     * Checks whether the any policy OID should be processed if it
+     * is included in a certificate.
+     *
+     * @return {@code true} if the any policy OID is inhibited,
+     * {@code false} otherwise
+     */
+    public boolean isAnyPolicyInhibited() {
+        return anyPolicyInhibited;
+    }
+
+    /**
+     * Sets the PolicyQualifiersRejected flag. If this flag is true,
+     * certificates that include policy qualifiers in a certificate
+     * policies extension that is marked critical are rejected.
+     * If the flag is false, certificates are not rejected on this basis.
+     *
+     * <p> When a {@code PKIXParameters} object is created, this flag is
+     * set to true. This setting reflects the most common (and simplest)
+     * strategy for processing policy qualifiers. Applications that want to use
+     * a more sophisticated policy must set this flag to false.
+     * <p>
+     * Note that the PKIX certification path validation algorithm specifies
+     * that any policy qualifier in a certificate policies extension that is
+     * marked critical must be processed and validated. Otherwise the
+     * certification path must be rejected. If the policyQualifiersRejected flag
+     * is set to false, it is up to the application to validate all policy
+     * qualifiers in this manner in order to be PKIX compliant.
+     *
+     * @param qualifiersRejected the new value of the PolicyQualifiersRejected
+     * flag
+     * @see #getPolicyQualifiersRejected
+     * @see PolicyQualifierInfo
+     */
+    public void setPolicyQualifiersRejected(boolean qualifiersRejected) {
+        policyQualifiersRejected = qualifiersRejected;
+    }
+
+    /**
+     * Gets the PolicyQualifiersRejected flag. If this flag is true,
+     * certificates that include policy qualifiers in a certificate policies
+     * extension that is marked critical are rejected.
+     * If the flag is false, certificates are not rejected on this basis.
+     *
+     * <p> When a {@code PKIXParameters} object is created, this flag is
+     * set to true. This setting reflects the most common (and simplest)
+     * strategy for processing policy qualifiers. Applications that want to use
+     * a more sophisticated policy must set this flag to false.
+     *
+     * @return the current value of the PolicyQualifiersRejected flag
+     * @see #setPolicyQualifiersRejected
+     */
+    public boolean getPolicyQualifiersRejected() {
+        return policyQualifiersRejected;
+    }
+
+    /**
+     * Returns the time for which the validity of the certification path
+     * should be determined. If {@code null}, the current time is used.
+     * <p>
+     * Note that the {@code Date} returned is copied to protect against
+     * subsequent modifications.
+     *
+     * @return the {@code Date}, or {@code null} if not set
+     * @see #setDate
+     */
+    public Date getDate() {
+        if (date == null)
+            return null;
+        else
+            return (Date) this.date.clone();
+    }
+
+    /**
+     * Sets the time for which the validity of the certification path
+     * should be determined. If {@code null}, the current time is used.
+     * <p>
+     * Note that the {@code Date} supplied here is copied to protect
+     * against subsequent modifications.
+     *
+     * @param date the {@code Date}, or {@code null} for the
+     * current time
+     * @see #getDate
+     */
+    public void setDate(Date date) {
+        if (date != null)
+            this.date = (Date) date.clone();
+        else
+            date = null;
+    }
+
+    /**
+     * Sets a {@code List} of additional certification path checkers. If
+     * the specified {@code List} contains an object that is not a
+     * {@code PKIXCertPathChecker}, it is ignored.
+     * <p>
+     * Each {@code PKIXCertPathChecker} specified implements
+     * additional checks on a certificate. Typically, these are checks to
+     * process and verify private extensions contained in certificates.
+     * Each {@code PKIXCertPathChecker} should be instantiated with any
+     * initialization parameters needed to execute the check.
+     * <p>
+     * This method allows sophisticated applications to extend a PKIX
+     * {@code CertPathValidator} or {@code CertPathBuilder}.
+     * Each of the specified {@code PKIXCertPathChecker}s will be called,
+     * in turn, by a PKIX {@code CertPathValidator} or
+     * {@code CertPathBuilder} for each certificate processed or
+     * validated.
+     * <p>
+     * Regardless of whether these additional {@code PKIXCertPathChecker}s
+     * are set, a PKIX {@code CertPathValidator} or
+     * {@code CertPathBuilder} must perform all of the required PKIX
+     * checks on each certificate. The one exception to this rule is if the
+     * RevocationEnabled flag is set to false (see the {@link
+     * #setRevocationEnabled setRevocationEnabled} method).
+     * <p>
+     * Note that the {@code List} supplied here is copied and each
+     * {@code PKIXCertPathChecker} in the list is cloned to protect
+     * against subsequent modifications.
+     *
+     * @param checkers a {@code List} of {@code PKIXCertPathChecker}s.
+     * May be {@code null}, in which case no additional checkers will be
+     * used.
+     * @throws ClassCastException if any of the elements in the list
+     * are not of type {@code java.security.cert.PKIXCertPathChecker}
+     * @see #getCertPathCheckers
+     */
+    public void setCertPathCheckers(List<PKIXCertPathChecker> checkers) {
+        if (checkers != null) {
+            List<PKIXCertPathChecker> tmpList =
+                        new ArrayList<PKIXCertPathChecker>();
+            for (PKIXCertPathChecker checker : checkers) {
+                tmpList.add((PKIXCertPathChecker)checker.clone());
+            }
+            this.certPathCheckers = tmpList;
+        } else {
+            this.certPathCheckers = new ArrayList<PKIXCertPathChecker>();
+        }
+    }
+
+    /**
+     * Returns the {@code List} of certification path checkers.
+     * The returned {@code List} is immutable, and each
+     * {@code PKIXCertPathChecker} in the {@code List} is cloned
+     * to protect against subsequent modifications.
+     *
+     * @return an immutable {@code List} of
+     * {@code PKIXCertPathChecker}s (may be empty, but not
+     * {@code null})
+     * @see #setCertPathCheckers
+     */
+    public List<PKIXCertPathChecker> getCertPathCheckers() {
+        List<PKIXCertPathChecker> tmpList = new ArrayList<PKIXCertPathChecker>();
+        for (PKIXCertPathChecker ck : certPathCheckers) {
+            tmpList.add((PKIXCertPathChecker)ck.clone());
+        }
+        return Collections.unmodifiableList(tmpList);
+    }
+
+    /**
+     * Adds a {@code PKIXCertPathChecker} to the list of certification
+     * path checkers. See the {@link #setCertPathCheckers setCertPathCheckers}
+     * method for more details.
+     * <p>
+     * Note that the {@code PKIXCertPathChecker} is cloned to protect
+     * against subsequent modifications.
+     *
+     * @param checker a {@code PKIXCertPathChecker} to add to the list of
+     * checks. If {@code null}, the checker is ignored (not added to list).
+     */
+    public void addCertPathChecker(PKIXCertPathChecker checker) {
+        if (checker != null) {
+            certPathCheckers.add((PKIXCertPathChecker)checker.clone());
+        }
+    }
+
+    /**
+     * Returns the signature provider's name, or {@code null}
+     * if not set.
+     *
+     * @return the signature provider's name (or {@code null})
+     * @see #setSigProvider
+     */
+    public String getSigProvider() {
+        return this.sigProvider;
+    }
+
+    /**
+     * Sets the signature provider's name. The specified provider will be
+     * preferred when creating {@link java.security.Signature Signature}
+     * objects. If {@code null} or not set, the first provider found
+     * supporting the algorithm will be used.
+     *
+     * @param sigProvider the signature provider's name (or {@code null})
+     * @see #getSigProvider
+    */
+    public void setSigProvider(String sigProvider) {
+        this.sigProvider = sigProvider;
+    }
+
+    /**
+     * Returns the required constraints on the target certificate.
+     * The constraints are returned as an instance of {@code CertSelector}.
+     * If {@code null}, no constraints are defined.
+     *
+     * <p>Note that the {@code CertSelector} returned is cloned
+     * to protect against subsequent modifications.
+     *
+     * @return a {@code CertSelector} specifying the constraints
+     * on the target certificate (or {@code null})
+     * @see #setTargetCertConstraints
+     */
+    public CertSelector getTargetCertConstraints() {
+        if (certSelector != null) {
+            return (CertSelector) certSelector.clone();
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Sets the required constraints on the target certificate.
+     * The constraints are specified as an instance of
+     * {@code CertSelector}. If {@code null}, no constraints are
+     * defined.
+     *
+     * <p>Note that the {@code CertSelector} specified is cloned
+     * to protect against subsequent modifications.
+     *
+     * @param selector a {@code CertSelector} specifying the constraints
+     * on the target certificate (or {@code null})
+     * @see #getTargetCertConstraints
+     */
+    public void setTargetCertConstraints(CertSelector selector) {
+        if (selector != null)
+            certSelector = (CertSelector) selector.clone();
+        else
+            certSelector = null;
+    }
+
+    /**
+     * Makes a copy of this {@code PKIXParameters} object. Changes
+     * to the copy will not affect the original and vice versa.
+     *
+     * @return a copy of this {@code PKIXParameters} object
+     */
+    public Object clone() {
+        try {
+            PKIXParameters copy = (PKIXParameters)super.clone();
+
+            // must clone these because addCertStore, et al. modify them
+            if (certStores != null) {
+                copy.certStores = new ArrayList<CertStore>(certStores);
+            }
+            if (certPathCheckers != null) {
+                copy.certPathCheckers =
+                    new ArrayList<PKIXCertPathChecker>(certPathCheckers.size());
+                for (PKIXCertPathChecker checker : certPathCheckers) {
+                    copy.certPathCheckers.add(
+                                    (PKIXCertPathChecker)checker.clone());
+                }
+            }
+
+            // other class fields are immutable to public, don't bother
+            // to clone the read-only fields.
+            return copy;
+        } catch (CloneNotSupportedException e) {
+            /* Cannot happen */
+            throw new InternalError(e.toString(), e);
+        }
+    }
+
+    /**
+     * Returns a formatted string describing the parameters.
+     *
+     * @return a formatted string describing the parameters.
+     */
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append("[\n");
+
+        /* start with trusted anchor info */
+        if (unmodTrustAnchors != null) {
+            sb.append("  Trust Anchors: " + unmodTrustAnchors.toString()
+                + "\n");
+        }
+
+        /* now, append initial state information */
+        if (unmodInitialPolicies != null) {
+            if (unmodInitialPolicies.isEmpty()) {
+                sb.append("  Initial Policy OIDs: any\n");
+            } else {
+                sb.append("  Initial Policy OIDs: ["
+                    + unmodInitialPolicies.toString() + "]\n");
+            }
+        }
+
+        /* now, append constraints on all certificates in the path */
+        sb.append("  Validity Date: " + String.valueOf(date) + "\n");
+        sb.append("  Signature Provider: " + String.valueOf(sigProvider) + "\n");
+        sb.append("  Default Revocation Enabled: " + revocationEnabled + "\n");
+        sb.append("  Explicit Policy Required: " + explicitPolicyRequired + "\n");
+        sb.append("  Policy Mapping Inhibited: " + policyMappingInhibited + "\n");
+        sb.append("  Any Policy Inhibited: " + anyPolicyInhibited + "\n");
+        sb.append("  Policy Qualifiers Rejected: " + policyQualifiersRejected + "\n");
+
+        /* now, append target cert requirements */
+        sb.append("  Target Cert Constraints: " + String.valueOf(certSelector) + "\n");
+
+        /* finally, append miscellaneous parameters */
+        if (certPathCheckers != null)
+            sb.append("  Certification Path Checkers: ["
+                + certPathCheckers.toString() + "]\n");
+        if (certStores != null)
+            sb.append("  CertStores: [" + certStores.toString() + "]\n");
+        sb.append("]");
+        return sb.toString();
+    }
+}
diff --git a/java/security/cert/PKIXReason.java b/java/security/cert/PKIXReason.java
new file mode 100644
index 0000000..d58ded9
--- /dev/null
+++ b/java/security/cert/PKIXReason.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2008, 2013, 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 java.security.cert;
+
+/**
+ * The {@code PKIXReason} enumerates the potential PKIX-specific reasons
+ * that an X.509 certification path may be invalid according to the PKIX
+ * (RFC 3280) standard. These reasons are in addition to those of the
+ * {@code CertPathValidatorException.BasicReason} enumeration.
+ *
+ * @since 1.7
+ */
+public enum PKIXReason implements CertPathValidatorException.Reason {
+    /**
+     * The certificate does not chain correctly.
+     */
+    NAME_CHAINING,
+
+    /**
+     * The certificate's key usage is invalid.
+     */
+    INVALID_KEY_USAGE,
+
+    /**
+     * The policy constraints have been violated.
+     */
+    INVALID_POLICY,
+
+    /**
+     * No acceptable trust anchor found.
+     */
+    NO_TRUST_ANCHOR,
+
+    /**
+     * The certificate contains one or more unrecognized critical
+     * extensions.
+     */
+    UNRECOGNIZED_CRIT_EXT,
+
+    /**
+     * The certificate is not a CA certificate.
+     */
+    NOT_CA_CERT,
+
+    /**
+     * The path length constraint has been violated.
+     */
+    PATH_TOO_LONG,
+
+    /**
+     * The name constraints have been violated.
+     */
+    INVALID_NAME
+}
diff --git a/java/security/cert/PKIXRevocationChecker.java b/java/security/cert/PKIXRevocationChecker.java
new file mode 100644
index 0000000..620291e
--- /dev/null
+++ b/java/security/cert/PKIXRevocationChecker.java
@@ -0,0 +1,317 @@
+/*
+ * Copyright (c) 2012, 2013, 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 java.security.cert;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+/**
+ * A {@code PKIXCertPathChecker} for checking the revocation status of
+ * certificates with the PKIX algorithm.
+ *
+ * <p>A {@code PKIXRevocationChecker} checks the revocation status of
+ * certificates with the Online Certificate Status Protocol (OCSP) or
+ * Certificate Revocation Lists (CRLs). OCSP is described in RFC 2560 and
+ * is a network protocol for determining the status of a certificate. A CRL
+ * is a time-stamped list identifying revoked certificates, and RFC 5280
+ * describes an algorithm for determining the revocation status of certificates
+ * using CRLs.
+ *
+ * <p>Each {@code PKIXRevocationChecker} must be able to check the revocation
+ * status of certificates with OCSP and CRLs. By default, OCSP is the
+ * preferred mechanism for checking revocation status, with CRLs as the
+ * fallback mechanism. However, this preference can be switched to CRLs with
+ * the {@link Option#PREFER_CRLS PREFER_CRLS} option. In addition, the fallback
+ * mechanism can be disabled with the {@link Option#NO_FALLBACK NO_FALLBACK}
+ * option.
+ *
+ * <p>A {@code PKIXRevocationChecker} is obtained by calling the
+ * {@link CertPathValidator#getRevocationChecker getRevocationChecker} method
+ * of a PKIX {@code CertPathValidator}. Additional parameters and options
+ * specific to revocation can be set (by calling the
+ * {@link #setOcspResponder setOcspResponder} method for instance). The
+ * {@code PKIXRevocationChecker} is added to a {@code PKIXParameters} object
+ * using the {@link PKIXParameters#addCertPathChecker addCertPathChecker}
+ * or {@link PKIXParameters#setCertPathCheckers setCertPathCheckers} method,
+ * and then the {@code PKIXParameters} is passed along with the {@code CertPath}
+ * to be validated to the {@link CertPathValidator#validate validate} method
+ * of a PKIX {@code CertPathValidator}. When supplying a revocation checker in
+ * this manner, it will be used to check revocation irrespective of the setting
+ * of the {@link PKIXParameters#isRevocationEnabled RevocationEnabled} flag.
+ * Similarly, a {@code PKIXRevocationChecker} may be added to a
+ * {@code PKIXBuilderParameters} object for use with a PKIX
+ * {@code CertPathBuilder}.
+ *
+ * <p>Note that when a {@code PKIXRevocationChecker} is added to
+ * {@code PKIXParameters}, it clones the {@code PKIXRevocationChecker};
+ * thus any subsequent modifications to the {@code PKIXRevocationChecker}
+ * have no effect.
+ *
+ * <p>Any parameter that is not set (or is set to {@code null}) will be set to
+ * the default value for that parameter.
+ *
+ * <p><b>Concurrent Access</b>
+ *
+ * <p>Unless otherwise specified, the methods defined in this class are not
+ * thread-safe. Multiple threads that need to access a single object
+ * concurrently should synchronize amongst themselves and provide the
+ * necessary locking. Multiple threads each manipulating separate objects
+ * need not synchronize.
+ *
+ * <p>See RFC 2560: X.509 Internet Public Key Infrastructure Online Certificate Status Protocol -
+ * OCSP, RFC 5280: Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation
+ * List (CRL) Profile (Android note: this paragraph was originally in a malformed "see" tag below,
+ * moved here for correct construction of the docs).
+ *
+ * @since 1.8
+
+ */
+public abstract class PKIXRevocationChecker extends PKIXCertPathChecker {
+    private URI ocspResponder;
+    private X509Certificate ocspResponderCert;
+    private List<Extension> ocspExtensions = Collections.<Extension>emptyList();
+    private Map<X509Certificate, byte[]> ocspResponses = Collections.emptyMap();
+    private Set<Option> options = Collections.emptySet();
+
+    /**
+     * Default constructor.
+     */
+    protected PKIXRevocationChecker() {}
+
+    /**
+     * Sets the URI that identifies the location of the OCSP responder. This
+     * overrides the {@code ocsp.responderURL} security property and any
+     * responder specified in a certificate's Authority Information Access
+     * Extension, as defined in RFC 5280.
+     *
+     * @param uri the responder URI
+     */
+    public void setOcspResponder(URI uri) {
+        this.ocspResponder = uri;
+    }
+
+    /**
+     * Gets the URI that identifies the location of the OCSP responder. This
+     * overrides the {@code ocsp.responderURL} security property. If this
+     * parameter or the {@code ocsp.responderURL} property is not set, the
+     * location is determined from the certificate's Authority Information
+     * Access Extension, as defined in RFC 5280.
+     *
+     * @return the responder URI, or {@code null} if not set
+     */
+    public URI getOcspResponder() {
+        return ocspResponder;
+    }
+
+    /**
+     * Sets the OCSP responder's certificate. This overrides the
+     * {@code ocsp.responderCertSubjectName},
+     * {@code ocsp.responderCertIssuerName},
+     * and {@code ocsp.responderCertSerialNumber} security properties.
+     *
+     * @param cert the responder's certificate
+     */
+    public void setOcspResponderCert(X509Certificate cert) {
+        this.ocspResponderCert = cert;
+    }
+
+    /**
+     * Gets the OCSP responder's certificate. This overrides the
+     * {@code ocsp.responderCertSubjectName},
+     * {@code ocsp.responderCertIssuerName},
+     * and {@code ocsp.responderCertSerialNumber} security properties. If this
+     * parameter or the aforementioned properties are not set, then the
+     * responder's certificate is determined as specified in RFC 2560.
+     *
+     * @return the responder's certificate, or {@code null} if not set
+     */
+    public X509Certificate getOcspResponderCert() {
+        return ocspResponderCert;
+    }
+
+    // request extensions; single extensions not supported
+    /**
+     * Sets the optional OCSP request extensions.
+     *
+     * @param extensions a list of extensions. The list is copied to protect
+     *        against subsequent modification.
+     */
+    public void setOcspExtensions(List<Extension> extensions)
+    {
+        this.ocspExtensions = (extensions == null)
+                              ? Collections.<Extension>emptyList()
+                              : new ArrayList<Extension>(extensions);
+    }
+
+    /**
+     * Gets the optional OCSP request extensions.
+     *
+     * @return an unmodifiable list of extensions. The list is empty if no
+     *         extensions have been specified.
+     */
+    public List<Extension> getOcspExtensions() {
+        return Collections.unmodifiableList(ocspExtensions);
+    }
+
+    /**
+     * Sets the OCSP responses. These responses are used to determine
+     * the revocation status of the specified certificates when OCSP is used.
+     *
+     * @param responses a map of OCSP responses. Each key is an
+     *        {@code X509Certificate} that maps to the corresponding
+     *        DER-encoded OCSP response for that certificate. A deep copy of
+     *        the map is performed to protect against subsequent modification.
+     */
+    public void setOcspResponses(Map<X509Certificate, byte[]> responses)
+    {
+        if (responses == null) {
+            this.ocspResponses = Collections.<X509Certificate, byte[]>emptyMap();
+        } else {
+            Map<X509Certificate, byte[]> copy = new HashMap<>(responses.size());
+            for (Map.Entry<X509Certificate, byte[]> e : responses.entrySet()) {
+                copy.put(e.getKey(), e.getValue().clone());
+            }
+            this.ocspResponses = copy;
+        }
+    }
+
+    /**
+     * Gets the OCSP responses. These responses are used to determine
+     * the revocation status of the specified certificates when OCSP is used.
+     *
+     * @return a map of OCSP responses. Each key is an
+     *        {@code X509Certificate} that maps to the corresponding
+     *        DER-encoded OCSP response for that certificate. A deep copy of
+     *        the map is returned to protect against subsequent modification.
+     *        Returns an empty map if no responses have been specified.
+     */
+    public Map<X509Certificate, byte[]> getOcspResponses() {
+        Map<X509Certificate, byte[]> copy = new HashMap<>(ocspResponses.size());
+        for (Map.Entry<X509Certificate, byte[]> e : ocspResponses.entrySet()) {
+            copy.put(e.getKey(), e.getValue().clone());
+        }
+        return copy;
+    }
+
+    /**
+     * Sets the revocation options.
+     *
+     * @param options a set of revocation options. The set is copied to protect
+     *        against subsequent modification.
+     */
+    public void setOptions(Set<Option> options) {
+        this.options = (options == null)
+                       ? Collections.<Option>emptySet()
+                       : new HashSet<Option>(options);
+    }
+
+    /**
+     * Gets the revocation options.
+     *
+     * @return an unmodifiable set of revocation options. The set is empty if
+     *         no options have been specified.
+     */
+    public Set<Option> getOptions() {
+        return Collections.unmodifiableSet(options);
+    }
+
+    /**
+     * Returns a list containing the exceptions that are ignored by the
+     * revocation checker when the {@link Option#SOFT_FAIL SOFT_FAIL} option
+     * is set. The list is cleared each time {@link #init init} is called.
+     * The list is ordered in ascending order according to the certificate
+     * index returned by {@link CertPathValidatorException#getIndex getIndex}
+     * method of each entry.
+     * <p>
+     * An implementation of {@code PKIXRevocationChecker} is responsible for
+     * adding the ignored exceptions to the list.
+     *
+     * @return an unmodifiable list containing the ignored exceptions. The list
+     *         is empty if no exceptions have been ignored.
+     */
+    public abstract List<CertPathValidatorException> getSoftFailExceptions();
+
+    @Override
+    public PKIXRevocationChecker clone() {
+        PKIXRevocationChecker copy = (PKIXRevocationChecker)super.clone();
+        copy.ocspExtensions = new ArrayList<>(ocspExtensions);
+        copy.ocspResponses = new HashMap<>(ocspResponses);
+        // deep-copy the encoded responses, since they are mutable
+        for (Map.Entry<X509Certificate, byte[]> entry :
+                 copy.ocspResponses.entrySet())
+        {
+            byte[] encoded = entry.getValue();
+            entry.setValue(encoded.clone());
+        }
+        copy.options = new HashSet<>(options);
+        return copy;
+    }
+
+    /**
+     * Various revocation options that can be specified for the revocation
+     * checking mechanism.
+     */
+    public enum Option {
+        /**
+         * Only check the revocation status of end-entity certificates.
+         */
+        ONLY_END_ENTITY,
+        /**
+         * Prefer CRLs to OSCP. The default behavior is to prefer OCSP. Each
+         * PKIX implementation should document further details of their
+         * specific preference rules and fallback policies.
+         */
+        PREFER_CRLS,
+        /**
+         * Disable the fallback mechanism.
+         */
+        NO_FALLBACK,
+        /**
+         * Allow revocation check to succeed if the revocation status cannot be
+         * determined for one of the following reasons:
+         * <ul>
+         *  <li>The CRL or OCSP response cannot be obtained because of a
+         *      network error.
+         *  <li>The OCSP responder returns one of the following errors
+         *      specified in section 2.3 of RFC 2560: internalError or tryLater.
+         * </ul><br>
+         * Note that these conditions apply to both OCSP and CRLs, and unless
+         * the {@code NO_FALLBACK} option is set, the revocation check is
+         * allowed to succeed only if both mechanisms fail under one of the
+         * conditions as stated above.
+         * Exceptions that cause the network errors are ignored but can be
+         * later retrieved by calling the
+         * {@link #getSoftFailExceptions getSoftFailExceptions} method.
+         */
+        SOFT_FAIL
+    }
+}
diff --git a/java/security/cert/PolicyNode.java b/java/security/cert/PolicyNode.java
new file mode 100644
index 0000000..1633dcb
--- /dev/null
+++ b/java/security/cert/PolicyNode.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2000, 2013, 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 java.security.cert;
+
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * An immutable valid policy tree node as defined by the PKIX certification
+ * path validation algorithm.
+ *
+ * <p>One of the outputs of the PKIX certification path validation
+ * algorithm is a valid policy tree, which includes the policies that
+ * were determined to be valid, how this determination was reached,
+ * and any policy qualifiers encountered. This tree is of depth
+ * <i>n</i>, where <i>n</i> is the length of the certification
+ * path that has been validated.
+ *
+ * <p>Most applications will not need to examine the valid policy tree.
+ * They can achieve their policy processing goals by setting the
+ * policy-related parameters in {@code PKIXParameters}. However,
+ * the valid policy tree is available for more sophisticated applications,
+ * especially those that process policy qualifiers.
+ *
+ * <p>{@link PKIXCertPathValidatorResult#getPolicyTree()
+ * PKIXCertPathValidatorResult.getPolicyTree} returns the root node of the
+ * valid policy tree. The tree can be traversed using the
+ * {@link #getChildren getChildren} and {@link #getParent getParent} methods.
+ * Data about a particular node can be retrieved using other methods of
+ * {@code PolicyNode}.
+ *
+ * <p><b>Concurrent Access</b>
+ * <p>All {@code PolicyNode} objects must be immutable and
+ * thread-safe. Multiple threads may concurrently invoke the methods defined
+ * in this class on a single {@code PolicyNode} object (or more than one)
+ * with no ill effects. This stipulation applies to all public fields and
+ * methods of this class and any added or overridden by subclasses.
+ *
+ * @since       1.4
+ * @author      Sean Mullan
+ */
+public interface PolicyNode {
+
+    /**
+     * Returns the parent of this node, or {@code null} if this is the
+     * root node.
+     *
+     * @return the parent of this node, or {@code null} if this is the
+     * root node
+     */
+    PolicyNode getParent();
+
+    /**
+     * Returns an iterator over the children of this node. Any attempts to
+     * modify the children of this node through the
+     * {@code Iterator}'s remove method must throw an
+     * {@code UnsupportedOperationException}.
+     *
+     * @return an iterator over the children of this node
+     */
+    Iterator<? extends PolicyNode> getChildren();
+
+    /**
+     * Returns the depth of this node in the valid policy tree.
+     *
+     * @return the depth of this node (0 for the root node, 1 for its
+     * children, and so on)
+     */
+    int getDepth();
+
+    /**
+     * Returns the valid policy represented by this node.
+     *
+     * @return the {@code String} OID of the valid policy
+     * represented by this node. For the root node, this method always returns
+     * the special anyPolicy OID: "2.5.29.32.0".
+     */
+    String getValidPolicy();
+
+    /**
+     * Returns the set of policy qualifiers associated with the
+     * valid policy represented by this node.
+     *
+     * @return an immutable {@code Set} of
+     * {@code PolicyQualifierInfo}s. For the root node, this
+     * is always an empty {@code Set}.
+     */
+    Set<? extends PolicyQualifierInfo> getPolicyQualifiers();
+
+    /**
+     * Returns the set of expected policies that would satisfy this
+     * node's valid policy in the next certificate to be processed.
+     *
+     * @return an immutable {@code Set} of expected policy
+     * {@code String} OIDs. For the root node, this method
+     * always returns a {@code Set} with one element, the
+     * special anyPolicy OID: "2.5.29.32.0".
+     */
+    Set<String> getExpectedPolicies();
+
+    /**
+     * Returns the criticality indicator of the certificate policy extension
+     * in the most recently processed certificate.
+     *
+     * @return {@code true} if extension marked critical,
+     * {@code false} otherwise. For the root node, {@code false}
+     * is always returned.
+     */
+    boolean isCritical();
+}
diff --git a/java/security/cert/PolicyQualifierInfo.java b/java/security/cert/PolicyQualifierInfo.java
new file mode 100644
index 0000000..ec06a88
--- /dev/null
+++ b/java/security/cert/PolicyQualifierInfo.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2000, 2013, 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 java.security.cert;
+
+import java.io.IOException;
+
+import sun.misc.HexDumpEncoder;
+import sun.security.util.DerValue;
+
+/**
+ * An immutable policy qualifier represented by the ASN.1 PolicyQualifierInfo
+ * structure.
+ *
+ * <p>The ASN.1 definition is as follows:
+ * <pre>
+ *   PolicyQualifierInfo ::= SEQUENCE {
+ *        policyQualifierId       PolicyQualifierId,
+ *        qualifier               ANY DEFINED BY policyQualifierId }
+ * </pre>
+ * <p>
+ * A certificate policies extension, if present in an X.509 version 3
+ * certificate, contains a sequence of one or more policy information terms,
+ * each of which consists of an object identifier (OID) and optional
+ * qualifiers. In an end-entity certificate, these policy information terms
+ * indicate the policy under which the certificate has been issued and the
+ * purposes for which the certificate may be used. In a CA certificate, these
+ * policy information terms limit the set of policies for certification paths
+ * which include this certificate.
+ * <p>
+ * A {@code Set} of {@code PolicyQualifierInfo} objects are returned
+ * by the {@link PolicyNode#getPolicyQualifiers PolicyNode.getPolicyQualifiers}
+ * method. This allows applications with specific policy requirements to
+ * process and validate each policy qualifier. Applications that need to
+ * process policy qualifiers should explicitly set the
+ * {@code policyQualifiersRejected} flag to false (by calling the
+ * {@link PKIXParameters#setPolicyQualifiersRejected
+ * PKIXParameters.setPolicyQualifiersRejected} method) before validating
+ * a certification path.
+ *
+ * <p>Note that the PKIX certification path validation algorithm specifies
+ * that any policy qualifier in a certificate policies extension that is
+ * marked critical must be processed and validated. Otherwise the
+ * certification path must be rejected. If the
+ * {@code policyQualifiersRejected} flag is set to false, it is up to
+ * the application to validate all policy qualifiers in this manner in order
+ * to be PKIX compliant.
+ *
+ * <p><b>Concurrent Access</b>
+ *
+ * <p>All {@code PolicyQualifierInfo} objects must be immutable and
+ * thread-safe. That is, multiple threads may concurrently invoke the
+ * methods defined in this class on a single {@code PolicyQualifierInfo}
+ * object (or more than one) with no ill effects. Requiring
+ * {@code PolicyQualifierInfo} objects to be immutable and thread-safe
+ * allows them to be passed around to various pieces of code without
+ * worrying about coordinating access.
+ *
+ * @author      seth proctor
+ * @author      Sean Mullan
+ * @since       1.4
+ */
+public class PolicyQualifierInfo {
+
+    private byte [] mEncoded;
+    private String mId;
+    private byte [] mData;
+    private String pqiString;
+
+    /**
+     * Creates an instance of {@code PolicyQualifierInfo} from the
+     * encoded bytes. The encoded byte array is copied on construction.
+     *
+     * @param encoded a byte array containing the qualifier in DER encoding
+     * @exception IOException thrown if the byte array does not represent a
+     * valid and parsable policy qualifier
+     */
+    public PolicyQualifierInfo(byte[] encoded) throws IOException {
+        mEncoded = encoded.clone();
+
+        DerValue val = new DerValue(mEncoded);
+        if (val.tag != DerValue.tag_Sequence)
+            throw new IOException("Invalid encoding for PolicyQualifierInfo");
+
+        mId = (val.data.getDerValue()).getOID().toString();
+        byte [] tmp = val.data.toByteArray();
+        if (tmp == null) {
+            mData = null;
+        } else {
+            mData = new byte[tmp.length];
+            System.arraycopy(tmp, 0, mData, 0, tmp.length);
+        }
+    }
+
+    /**
+     * Returns the {@code policyQualifierId} field of this
+     * {@code PolicyQualifierInfo}. The {@code policyQualifierId}
+     * is an Object Identifier (OID) represented by a set of nonnegative
+     * integers separated by periods.
+     *
+     * @return the OID (never {@code null})
+     */
+    public final String getPolicyQualifierId() {
+        return mId;
+    }
+
+    /**
+     * Returns the ASN.1 DER encoded form of this
+     * {@code PolicyQualifierInfo}.
+     *
+     * @return the ASN.1 DER encoded bytes (never {@code null}).
+     * Note that a copy is returned, so the data is cloned each time
+     * this method is called.
+     */
+    public final byte[] getEncoded() {
+        return mEncoded.clone();
+    }
+
+    /**
+     * Returns the ASN.1 DER encoded form of the {@code qualifier}
+     * field of this {@code PolicyQualifierInfo}.
+     *
+     * @return the ASN.1 DER encoded bytes of the {@code qualifier}
+     * field. Note that a copy is returned, so the data is cloned each
+     * time this method is called.
+     */
+    public final byte[] getPolicyQualifier() {
+        return (mData == null ? null : mData.clone());
+    }
+
+    /**
+     * Return a printable representation of this
+     * {@code PolicyQualifierInfo}.
+     *
+     * @return a {@code String} describing the contents of this
+     *         {@code PolicyQualifierInfo}
+     */
+    public String toString() {
+        if (pqiString != null)
+            return pqiString;
+        HexDumpEncoder enc = new HexDumpEncoder();
+        StringBuffer sb = new StringBuffer();
+        sb.append("PolicyQualifierInfo: [\n");
+        sb.append("  qualifierID: " + mId + "\n");
+        sb.append("  qualifier: " +
+            (mData == null ? "null" : enc.encodeBuffer(mData)) + "\n");
+        sb.append("]");
+        pqiString = sb.toString();
+        return pqiString;
+    }
+}
diff --git a/java/security/cert/TrustAnchor.java b/java/security/cert/TrustAnchor.java
new file mode 100644
index 0000000..c98bf81
--- /dev/null
+++ b/java/security/cert/TrustAnchor.java
@@ -0,0 +1,333 @@
+/*
+ * Copyright (c) 2001, 2013, 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 java.security.cert;
+
+import java.io.IOException;
+import java.security.PublicKey;
+
+import javax.security.auth.x500.X500Principal;
+
+import sun.security.x509.NameConstraintsExtension;
+import sun.security.x509.X500Name;
+
+/**
+ * A trust anchor or most-trusted Certification Authority (CA).
+ * <p>
+ * This class represents a "most-trusted CA", which is used as a trust anchor
+ * for validating X.509 certification paths. A most-trusted CA includes the
+ * public key of the CA, the CA's name, and any constraints upon the set of
+ * paths which may be validated using this key. These parameters can be
+ * specified in the form of a trusted {@code X509Certificate} or as
+ * individual parameters.
+ * <p>
+ * <b>Concurrent Access</b>
+ * <p>All {@code TrustAnchor} objects must be immutable and
+ * thread-safe. That is, multiple threads may concurrently invoke the
+ * methods defined in this class on a single {@code TrustAnchor}
+ * object (or more than one) with no ill effects. Requiring
+ * {@code TrustAnchor} objects to be immutable and thread-safe
+ * allows them to be passed around to various pieces of code without
+ * worrying about coordinating access. This stipulation applies to all
+ * public fields and methods of this class and any added or overridden
+ * by subclasses.
+ *
+ * @see PKIXParameters#PKIXParameters(Set)
+ * @see PKIXBuilderParameters#PKIXBuilderParameters(Set, CertSelector)
+ *
+ * @since       1.4
+ * @author      Sean Mullan
+ */
+public class TrustAnchor {
+
+    private final PublicKey pubKey;
+    private final String caName;
+    private final X500Principal caPrincipal;
+    private final X509Certificate trustedCert;
+    private byte[] ncBytes;
+    private NameConstraintsExtension nc;
+
+    /**
+     * Creates an instance of {@code TrustAnchor} with the specified
+     * {@code X509Certificate} and optional name constraints, which
+     * are intended to be used as additional constraints when validating
+     * an X.509 certification path.
+     * <p>
+     * The name constraints are specified as a byte array. This byte array
+     * should contain the DER encoded form of the name constraints, as they
+     * would appear in the NameConstraints structure defined in
+     * <a href="http://www.ietf.org/rfc/rfc3280">RFC 3280</a>
+     * and X.509. The ASN.1 definition of this structure appears below.
+     *
+     * <pre>{@code
+     *  NameConstraints ::= SEQUENCE {
+     *       permittedSubtrees       [0]     GeneralSubtrees OPTIONAL,
+     *       excludedSubtrees        [1]     GeneralSubtrees OPTIONAL }
+     *
+     *  GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
+     *
+     *  GeneralSubtree ::= SEQUENCE {
+     *       base                    GeneralName,
+     *       minimum         [0]     BaseDistance DEFAULT 0,
+     *       maximum         [1]     BaseDistance OPTIONAL }
+     *
+     *  BaseDistance ::= INTEGER (0..MAX)
+     *
+     *  GeneralName ::= CHOICE {
+     *       otherName                       [0]     OtherName,
+     *       rfc822Name                      [1]     IA5String,
+     *       dNSName                         [2]     IA5String,
+     *       x400Address                     [3]     ORAddress,
+     *       directoryName                   [4]     Name,
+     *       ediPartyName                    [5]     EDIPartyName,
+     *       uniformResourceIdentifier       [6]     IA5String,
+     *       iPAddress                       [7]     OCTET STRING,
+     *       registeredID                    [8]     OBJECT IDENTIFIER}
+     * }</pre>
+     * <p>
+     * Note that the name constraints byte array supplied is cloned to protect
+     * against subsequent modifications.
+     *
+     * @param trustedCert a trusted {@code X509Certificate}
+     * @param nameConstraints a byte array containing the ASN.1 DER encoding of
+     * a NameConstraints extension to be used for checking name constraints.
+     * Only the value of the extension is included, not the OID or criticality
+     * flag. Specify {@code null} to omit the parameter.
+     * @throws IllegalArgumentException if the name constraints cannot be
+     * decoded
+     * @throws NullPointerException if the specified
+     * {@code X509Certificate} is {@code null}
+     */
+    public TrustAnchor(X509Certificate trustedCert, byte[] nameConstraints)
+    {
+        if (trustedCert == null)
+            throw new NullPointerException("the trustedCert parameter must " +
+                "be non-null");
+        this.trustedCert = trustedCert;
+        this.pubKey = null;
+        this.caName = null;
+        this.caPrincipal = null;
+        setNameConstraints(nameConstraints);
+    }
+
+    /**
+     * Creates an instance of {@code TrustAnchor} where the
+     * most-trusted CA is specified as an X500Principal and public key.
+     * Name constraints are an optional parameter, and are intended to be used
+     * as additional constraints when validating an X.509 certification path.
+     * <p>
+     * The name constraints are specified as a byte array. This byte array
+     * contains the DER encoded form of the name constraints, as they
+     * would appear in the NameConstraints structure defined in RFC 3280
+     * and X.509. The ASN.1 notation for this structure is supplied in the
+     * documentation for
+     * {@link #TrustAnchor(X509Certificate, byte[])
+     * TrustAnchor(X509Certificate trustedCert, byte[] nameConstraints) }.
+     * <p>
+     * Note that the name constraints byte array supplied here is cloned to
+     * protect against subsequent modifications.
+     *
+     * @param caPrincipal the name of the most-trusted CA as X500Principal
+     * @param pubKey the public key of the most-trusted CA
+     * @param nameConstraints a byte array containing the ASN.1 DER encoding of
+     * a NameConstraints extension to be used for checking name constraints.
+     * Only the value of the extension is included, not the OID or criticality
+     * flag. Specify {@code null} to omit the parameter.
+     * @throws NullPointerException if the specified {@code caPrincipal} or
+     * {@code pubKey} parameter is {@code null}
+     * @since 1.5
+     */
+    public TrustAnchor(X500Principal caPrincipal, PublicKey pubKey,
+            byte[] nameConstraints) {
+        if ((caPrincipal == null) || (pubKey == null)) {
+            throw new NullPointerException();
+        }
+        this.trustedCert = null;
+        this.caPrincipal = caPrincipal;
+        this.caName = caPrincipal.getName();
+        this.pubKey = pubKey;
+        setNameConstraints(nameConstraints);
+    }
+
+    /**
+     * Creates an instance of {@code TrustAnchor} where the
+     * most-trusted CA is specified as a distinguished name and public key.
+     * Name constraints are an optional parameter, and are intended to be used
+     * as additional constraints when validating an X.509 certification path.
+     * <p>
+     * The name constraints are specified as a byte array. This byte array
+     * contains the DER encoded form of the name constraints, as they
+     * would appear in the NameConstraints structure defined in RFC 3280
+     * and X.509. The ASN.1 notation for this structure is supplied in the
+     * documentation for
+     * {@link #TrustAnchor(X509Certificate, byte[])
+     * TrustAnchor(X509Certificate trustedCert, byte[] nameConstraints) }.
+     * <p>
+     * Note that the name constraints byte array supplied here is cloned to
+     * protect against subsequent modifications.
+     *
+     * @param caName the X.500 distinguished name of the most-trusted CA in
+     * <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a>
+     * {@code String} format
+     * @param pubKey the public key of the most-trusted CA
+     * @param nameConstraints a byte array containing the ASN.1 DER encoding of
+     * a NameConstraints extension to be used for checking name constraints.
+     * Only the value of the extension is included, not the OID or criticality
+     * flag. Specify {@code null} to omit the parameter.
+     * @throws IllegalArgumentException if the specified
+     * {@code caName} parameter is empty {@code (caName.length() == 0)}
+     * or incorrectly formatted or the name constraints cannot be decoded
+     * @throws NullPointerException if the specified {@code caName} or
+     * {@code pubKey} parameter is {@code null}
+     */
+    public TrustAnchor(String caName, PublicKey pubKey, byte[] nameConstraints)
+    {
+        if (pubKey == null)
+            throw new NullPointerException("the pubKey parameter must be " +
+                "non-null");
+        if (caName == null)
+            throw new NullPointerException("the caName parameter must be " +
+                "non-null");
+        if (caName.length() == 0)
+            throw new IllegalArgumentException("the caName " +
+                "parameter must be a non-empty String");
+        // check if caName is formatted correctly
+        this.caPrincipal = new X500Principal(caName);
+        this.pubKey = pubKey;
+        this.caName = caName;
+        this.trustedCert = null;
+        setNameConstraints(nameConstraints);
+    }
+
+    /**
+     * Returns the most-trusted CA certificate.
+     *
+     * @return a trusted {@code X509Certificate} or {@code null}
+     * if the trust anchor was not specified as a trusted certificate
+     */
+    public final X509Certificate getTrustedCert() {
+        return this.trustedCert;
+    }
+
+    /**
+     * Returns the name of the most-trusted CA as an X500Principal.
+     *
+     * @return the X.500 distinguished name of the most-trusted CA, or
+     * {@code null} if the trust anchor was not specified as a trusted
+     * public key and name or X500Principal pair
+     * @since 1.5
+     */
+    public final X500Principal getCA() {
+        return this.caPrincipal;
+    }
+
+    /**
+     * Returns the name of the most-trusted CA in RFC 2253 {@code String}
+     * format.
+     *
+     * @return the X.500 distinguished name of the most-trusted CA, or
+     * {@code null} if the trust anchor was not specified as a trusted
+     * public key and name or X500Principal pair
+     */
+    public final String getCAName() {
+        return this.caName;
+    }
+
+    /**
+     * Returns the public key of the most-trusted CA.
+     *
+     * @return the public key of the most-trusted CA, or {@code null}
+     * if the trust anchor was not specified as a trusted public key and name
+     * or X500Principal pair
+     */
+    public final PublicKey getCAPublicKey() {
+        return this.pubKey;
+    }
+
+    /**
+     * Decode the name constraints and clone them if not null.
+     */
+    private void setNameConstraints(byte[] bytes) {
+        if (bytes == null) {
+            ncBytes = null;
+            nc = null;
+        } else {
+            ncBytes = bytes.clone();
+            // validate DER encoding
+            try {
+                nc = new NameConstraintsExtension(Boolean.FALSE, bytes);
+            } catch (IOException ioe) {
+                IllegalArgumentException iae =
+                    new IllegalArgumentException(ioe.getMessage());
+                iae.initCause(ioe);
+                throw iae;
+            }
+        }
+    }
+
+    /**
+     * Returns the name constraints parameter. The specified name constraints
+     * are associated with this trust anchor and are intended to be used
+     * as additional constraints when validating an X.509 certification path.
+     * <p>
+     * The name constraints are returned as a byte array. This byte array
+     * contains the DER encoded form of the name constraints, as they
+     * would appear in the NameConstraints structure defined in RFC 3280
+     * and X.509. The ASN.1 notation for this structure is supplied in the
+     * documentation for
+     * {@link #TrustAnchor(X509Certificate, byte[])
+     * TrustAnchor(X509Certificate trustedCert, byte[] nameConstraints) }.
+     * <p>
+     * Note that the byte array returned is cloned to protect against
+     * subsequent modifications.
+     *
+     * @return a byte array containing the ASN.1 DER encoding of
+     *         a NameConstraints extension used for checking name constraints,
+     *         or {@code null} if not set.
+     */
+    public final byte [] getNameConstraints() {
+        return ncBytes == null ? null : ncBytes.clone();
+    }
+
+    /**
+     * Returns a formatted string describing the {@code TrustAnchor}.
+     *
+     * @return a formatted string describing the {@code TrustAnchor}
+     */
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append("[\n");
+        if (pubKey != null) {
+            sb.append("  Trusted CA Public Key: " + pubKey.toString() + "\n");
+            sb.append("  Trusted CA Issuer Name: "
+                + String.valueOf(caName) + "\n");
+        } else {
+            sb.append("  Trusted CA cert: " + trustedCert.toString() + "\n");
+        }
+        if (nc != null)
+            sb.append("  Name Constraints: " + nc.toString() + "\n");
+        return sb.toString();
+    }
+}
diff --git a/java/security/cert/X509CRL.java b/java/security/cert/X509CRL.java
new file mode 100644
index 0000000..a233b44
--- /dev/null
+++ b/java/security/cert/X509CRL.java
@@ -0,0 +1,477 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security.cert;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.InvalidKeyException;
+import java.security.SignatureException;
+import java.security.Principal;
+import java.security.Provider;
+import java.security.PublicKey;
+import javax.security.auth.x500.X500Principal;
+
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.Set;
+import java.util.Arrays;
+
+import sun.security.x509.X509CRLImpl;
+
+/**
+ * <p>
+ * Abstract class for an X.509 Certificate Revocation List (CRL).
+ * A CRL is a time-stamped list identifying revoked certificates.
+ * It is signed by a Certificate Authority (CA) and made freely
+ * available in a public repository.
+ *
+ * <p>Each revoked certificate is
+ * identified in a CRL by its certificate serial number. When a
+ * certificate-using system uses a certificate (e.g., for verifying a
+ * remote user's digital signature), that system not only checks the
+ * certificate signature and validity but also acquires a suitably-
+ * recent CRL and checks that the certificate serial number is not on
+ * that CRL.  The meaning of "suitably-recent" may vary with local
+ * policy, but it usually means the most recently-issued CRL.  A CA
+ * issues a new CRL on a regular periodic basis (e.g., hourly, daily, or
+ * weekly).  Entries are added to CRLs as revocations occur, and an
+ * entry may be removed when the certificate expiration date is reached.
+ * <p>
+ * The X.509 v2 CRL format is described below in ASN.1:
+ * <pre>
+ * CertificateList  ::=  SEQUENCE  {
+ *     tbsCertList          TBSCertList,
+ *     signatureAlgorithm   AlgorithmIdentifier,
+ *     signature            BIT STRING  }
+ * </pre>
+ * <p>
+ * More information can be found in
+ * <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280: Internet X.509
+ * Public Key Infrastructure Certificate and CRL Profile</a>.
+ * <p>
+ * The ASN.1 definition of {@code tbsCertList} is:
+ * <pre>
+ * TBSCertList  ::=  SEQUENCE  {
+ *     version                 Version OPTIONAL,
+ *                             -- if present, must be v2
+ *     signature               AlgorithmIdentifier,
+ *     issuer                  Name,
+ *     thisUpdate              ChoiceOfTime,
+ *     nextUpdate              ChoiceOfTime OPTIONAL,
+ *     revokedCertificates     SEQUENCE OF SEQUENCE  {
+ *         userCertificate         CertificateSerialNumber,
+ *         revocationDate          ChoiceOfTime,
+ *         crlEntryExtensions      Extensions OPTIONAL
+ *                                 -- if present, must be v2
+ *         }  OPTIONAL,
+ *     crlExtensions           [0]  EXPLICIT Extensions OPTIONAL
+ *                                  -- if present, must be v2
+ *     }
+ * </pre>
+ * <p>
+ * CRLs are instantiated using a certificate factory. The following is an
+ * example of how to instantiate an X.509 CRL:
+ * <pre>{@code
+ * try (InputStream inStream = new FileInputStream("fileName-of-crl")) {
+ *     CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ *     X509CRL crl = (X509CRL)cf.generateCRL(inStream);
+ * }
+ * }</pre>
+ *
+ * @author Hemma Prafullchandra
+ *
+ *
+ * @see CRL
+ * @see CertificateFactory
+ * @see X509Extension
+ */
+
+public abstract class X509CRL extends CRL implements X509Extension {
+
+    private transient X500Principal issuerPrincipal;
+
+    /**
+     * Constructor for X.509 CRLs.
+     */
+    protected X509CRL() {
+        super("X.509");
+    }
+
+    /**
+     * Compares this CRL for equality with the given
+     * object. If the {@code other} object is an
+     * {@code instanceof} {@code X509CRL}, then
+     * its encoded form is retrieved and compared with the
+     * encoded form of this CRL.
+     *
+     * @param other the object to test for equality with this CRL.
+     *
+     * @return true iff the encoded forms of the two CRLs
+     * match, false otherwise.
+     */
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        }
+        if (!(other instanceof X509CRL)) {
+            return false;
+        }
+        try {
+            byte[] thisCRL = X509CRLImpl.getEncodedInternal(this);
+            byte[] otherCRL = X509CRLImpl.getEncodedInternal((X509CRL)other);
+
+            return Arrays.equals(thisCRL, otherCRL);
+        } catch (CRLException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Returns a hashcode value for this CRL from its
+     * encoded form.
+     *
+     * @return the hashcode value.
+     */
+    public int hashCode() {
+        int retval = 0;
+        try {
+            byte[] crlData = X509CRLImpl.getEncodedInternal(this);
+            for (int i = 1; i < crlData.length; i++) {
+                 retval += crlData[i] * i;
+            }
+            return retval;
+        } catch (CRLException e) {
+            return retval;
+        }
+    }
+
+    /**
+     * Returns the ASN.1 DER-encoded form of this CRL.
+     *
+     * @return the encoded form of this certificate
+     * @exception CRLException if an encoding error occurs.
+     */
+    public abstract byte[] getEncoded()
+        throws CRLException;
+
+    /**
+     * Verifies that this CRL was signed using the
+     * private key that corresponds to the given public key.
+     *
+     * @param key the PublicKey used to carry out the verification.
+     *
+     * @exception NoSuchAlgorithmException on unsupported signature
+     * algorithms.
+     * @exception InvalidKeyException on incorrect key.
+     * @exception NoSuchProviderException if there's no default provider.
+     * @exception SignatureException on signature errors.
+     * @exception CRLException on encoding errors.
+     */
+    public abstract void verify(PublicKey key)
+        throws CRLException,  NoSuchAlgorithmException,
+        InvalidKeyException, NoSuchProviderException,
+        SignatureException;
+
+    /**
+     * Verifies that this CRL was signed using the
+     * private key that corresponds to the given public key.
+     * This method uses the signature verification engine
+     * supplied by the given provider.
+     *
+     * @param key the PublicKey used to carry out the verification.
+     * @param sigProvider the name of the signature provider.
+     *
+     * @exception NoSuchAlgorithmException on unsupported signature
+     * algorithms.
+     * @exception InvalidKeyException on incorrect key.
+     * @exception NoSuchProviderException on incorrect provider.
+     * @exception SignatureException on signature errors.
+     * @exception CRLException on encoding errors.
+     */
+    public abstract void verify(PublicKey key, String sigProvider)
+        throws CRLException, NoSuchAlgorithmException,
+        InvalidKeyException, NoSuchProviderException,
+        SignatureException;
+
+    /**
+     * Verifies that this CRL was signed using the
+     * private key that corresponds to the given public key.
+     * This method uses the signature verification engine
+     * supplied by the given provider. Note that the specified Provider object
+     * does not have to be registered in the provider list.
+     *
+     * This method was added to version 1.8 of the Java Platform Standard
+     * Edition. In order to maintain backwards compatibility with existing
+     * service providers, this method is not {@code abstract}
+     * and it provides a default implementation.
+     *
+     * @param key the PublicKey used to carry out the verification.
+     * @param sigProvider the signature provider.
+     *
+     * @exception NoSuchAlgorithmException on unsupported signature
+     * algorithms.
+     * @exception InvalidKeyException on incorrect key.
+     * @exception SignatureException on signature errors.
+     * @exception CRLException on encoding errors.
+     * @since 1.8
+     */
+    public void verify(PublicKey key, Provider sigProvider)
+        throws CRLException, NoSuchAlgorithmException,
+        InvalidKeyException, SignatureException {
+        // BEGIN Android-changed
+        // TODO(31294527): was X509CRLImpl.verify(this, key, sigProvider);
+        // As the javadoc says, this "default implementation" was introduced as to avoid breaking
+        // providers that generate concrete subclasses of this class.
+        // The method X509Impl in the original definition calls this method, thus entering an
+        // infinite loop. This strange behaviour was checked to be not specific to libcore by
+        // running a test with vogar --mode=jvm .
+        throw new UnsupportedOperationException(
+                "X509CRL instance doesn't not support X509CRL#verify(PublicKey, Provider)");
+        // END Android-changed
+    }
+
+    /**
+     * Gets the {@code version} (version number) value from the CRL.
+     * The ASN.1 definition for this is:
+     * <pre>
+     * version    Version OPTIONAL,
+     *             -- if present, must be v2
+     *
+     * Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
+     *             -- v3 does not apply to CRLs but appears for consistency
+     *             -- with definition of Version for certs
+     * </pre>
+     *
+     * @return the version number, i.e. 1 or 2.
+     */
+    public abstract int getVersion();
+
+    /**
+     * <strong>Denigrated</strong>, replaced by {@linkplain
+     * #getIssuerX500Principal()}. This method returns the {@code issuer}
+     * as an implementation specific Principal object, which should not be
+     * relied upon by portable code.
+     *
+     * <p>
+     * Gets the {@code issuer} (issuer distinguished name) value from
+     * the CRL. The issuer name identifies the entity that signed (and
+     * issued) the CRL.
+     *
+     * <p>The issuer name field contains an
+     * X.500 distinguished name (DN).
+     * The ASN.1 definition for this is:
+     * <pre>
+     * issuer    Name
+     *
+     * Name ::= CHOICE { RDNSequence }
+     * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+     * RelativeDistinguishedName ::=
+     *     SET OF AttributeValueAssertion
+     *
+     * AttributeValueAssertion ::= SEQUENCE {
+     *                               AttributeType,
+     *                               AttributeValue }
+     * AttributeType ::= OBJECT IDENTIFIER
+     * AttributeValue ::= ANY
+     * </pre>
+     * The {@code Name} describes a hierarchical name composed of
+     * attributes,
+     * such as country name, and corresponding values, such as US.
+     * The type of the {@code AttributeValue} component is determined by
+     * the {@code AttributeType}; in general it will be a
+     * {@code directoryString}. A {@code directoryString} is usually
+     * one of {@code PrintableString},
+     * {@code TeletexString} or {@code UniversalString}.
+     *
+     * @return a Principal whose name is the issuer distinguished name.
+     */
+    public abstract Principal getIssuerDN();
+
+    /**
+     * Returns the issuer (issuer distinguished name) value from the
+     * CRL as an {@code X500Principal}.
+     * <p>
+     * It is recommended that subclasses override this method.
+     *
+     * @return an {@code X500Principal} representing the issuer
+     *          distinguished name
+     * @since 1.4
+     */
+    public X500Principal getIssuerX500Principal() {
+        if (issuerPrincipal == null) {
+            issuerPrincipal = X509CRLImpl.getIssuerX500Principal(this);
+        }
+        return issuerPrincipal;
+    }
+
+    /**
+     * Gets the {@code thisUpdate} date from the CRL.
+     * The ASN.1 definition for this is:
+     * <pre>
+     * thisUpdate   ChoiceOfTime
+     * ChoiceOfTime ::= CHOICE {
+     *     utcTime        UTCTime,
+     *     generalTime    GeneralizedTime }
+     * </pre>
+     *
+     * @return the {@code thisUpdate} date from the CRL.
+     */
+    public abstract Date getThisUpdate();
+
+    /**
+     * Gets the {@code nextUpdate} date from the CRL.
+     *
+     * @return the {@code nextUpdate} date from the CRL, or null if
+     * not present.
+     */
+    public abstract Date getNextUpdate();
+
+    /**
+     * Gets the CRL entry, if any, with the given certificate serialNumber.
+     *
+     * @param serialNumber the serial number of the certificate for which a CRL entry
+     * is to be looked up
+     * @return the entry with the given serial number, or null if no such entry
+     * exists in this CRL.
+     * @see X509CRLEntry
+     */
+    public abstract X509CRLEntry
+        getRevokedCertificate(BigInteger serialNumber);
+
+    /**
+     * Get the CRL entry, if any, for the given certificate.
+     *
+     * <p>This method can be used to lookup CRL entries in indirect CRLs,
+     * that means CRLs that contain entries from issuers other than the CRL
+     * issuer. The default implementation will only return entries for
+     * certificates issued by the CRL issuer. Subclasses that wish to
+     * support indirect CRLs should override this method.
+     *
+     * @param certificate the certificate for which a CRL entry is to be looked
+     *   up
+     * @return the entry for the given certificate, or null if no such entry
+     *   exists in this CRL.
+     * @exception NullPointerException if certificate is null
+     *
+     * @since 1.5
+     */
+    public X509CRLEntry getRevokedCertificate(X509Certificate certificate) {
+        X500Principal certIssuer = certificate.getIssuerX500Principal();
+        X500Principal crlIssuer = getIssuerX500Principal();
+        if (certIssuer.equals(crlIssuer) == false) {
+            return null;
+        }
+        return getRevokedCertificate(certificate.getSerialNumber());
+    }
+
+    /**
+     * Gets all the entries from this CRL.
+     * This returns a Set of X509CRLEntry objects.
+     *
+     * @return all the entries or null if there are none present.
+     * @see X509CRLEntry
+     */
+    public abstract Set<? extends X509CRLEntry> getRevokedCertificates();
+
+    /**
+     * Gets the DER-encoded CRL information, the
+     * {@code tbsCertList} from this CRL.
+     * This can be used to verify the signature independently.
+     *
+     * @return the DER-encoded CRL information.
+     * @exception CRLException if an encoding error occurs.
+     */
+    public abstract byte[] getTBSCertList() throws CRLException;
+
+    /**
+     * Gets the {@code signature} value (the raw signature bits) from
+     * the CRL.
+     * The ASN.1 definition for this is:
+     * <pre>
+     * signature     BIT STRING
+     * </pre>
+     *
+     * @return the signature.
+     */
+    public abstract byte[] getSignature();
+
+    /**
+     * Gets the signature algorithm name for the CRL
+     * signature algorithm. An example is the string "SHA256withRSA".
+     * The ASN.1 definition for this is:
+     * <pre>
+     * signatureAlgorithm   AlgorithmIdentifier
+     *
+     * AlgorithmIdentifier  ::=  SEQUENCE  {
+     *     algorithm               OBJECT IDENTIFIER,
+     *     parameters              ANY DEFINED BY algorithm OPTIONAL  }
+     *                             -- contains a value of the type
+     *                             -- registered for use with the
+     *                             -- algorithm object identifier value
+     * </pre>
+     *
+     * <p>The algorithm name is determined from the {@code algorithm}
+     * OID string.
+     *
+     * @return the signature algorithm name.
+     */
+    public abstract String getSigAlgName();
+
+    /**
+     * Gets the signature algorithm OID string from the CRL.
+     * An OID is represented by a set of nonnegative whole numbers separated
+     * by periods.
+     * For example, the string "1.2.840.10040.4.3" identifies the SHA-1
+     * with DSA signature algorithm defined in
+     * <a href="http://www.ietf.org/rfc/rfc3279.txt">RFC 3279: Algorithms and
+     * Identifiers for the Internet X.509 Public Key Infrastructure Certificate
+     * and CRL Profile</a>.
+     *
+     * <p>See {@link #getSigAlgName() getSigAlgName} for
+     * relevant ASN.1 definitions.
+     *
+     * @return the signature algorithm OID string.
+     */
+    public abstract String getSigAlgOID();
+
+    /**
+     * Gets the DER-encoded signature algorithm parameters from this
+     * CRL's signature algorithm. In most cases, the signature
+     * algorithm parameters are null; the parameters are usually
+     * supplied with the public key.
+     * If access to individual parameter values is needed then use
+     * {@link java.security.AlgorithmParameters AlgorithmParameters}
+     * and instantiate with the name returned by
+     * {@link #getSigAlgName() getSigAlgName}.
+     *
+     * <p>See {@link #getSigAlgName() getSigAlgName} for
+     * relevant ASN.1 definitions.
+     *
+     * @return the DER-encoded signature algorithm parameters, or
+     *         null if no parameters are present.
+     */
+    public abstract byte[] getSigAlgParams();
+}
diff --git a/java/security/cert/X509CRLEntry.java b/java/security/cert/X509CRLEntry.java
new file mode 100644
index 0000000..268fa81
--- /dev/null
+++ b/java/security/cert/X509CRLEntry.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security.cert;
+
+import java.math.BigInteger;
+import java.util.Date;
+import javax.security.auth.x500.X500Principal;
+
+import sun.security.x509.X509CRLEntryImpl;
+
+/**
+ * <p>Abstract class for a revoked certificate in a CRL (Certificate
+ * Revocation List).
+ *
+ * The ASN.1 definition for <em>revokedCertificates</em> is:
+ * <pre>
+ * revokedCertificates    SEQUENCE OF SEQUENCE  {
+ *     userCertificate    CertificateSerialNumber,
+ *     revocationDate     ChoiceOfTime,
+ *     crlEntryExtensions Extensions OPTIONAL
+ *                        -- if present, must be v2
+ * }  OPTIONAL
+ *
+ * CertificateSerialNumber  ::=  INTEGER
+ *
+ * Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
+ *
+ * Extension  ::=  SEQUENCE  {
+ *     extnId        OBJECT IDENTIFIER,
+ *     critical      BOOLEAN DEFAULT FALSE,
+ *     extnValue     OCTET STRING
+ *                   -- contains a DER encoding of a value
+ *                   -- of the type registered for use with
+ *                   -- the extnId object identifier value
+ * }
+ * </pre>
+ *
+ * @see X509CRL
+ * @see X509Extension
+ *
+ * @author Hemma Prafullchandra
+ */
+
+public abstract class X509CRLEntry implements X509Extension {
+
+    /**
+     * Compares this CRL entry for equality with the given
+     * object. If the {@code other} object is an
+     * {@code instanceof} {@code X509CRLEntry}, then
+     * its encoded form (the inner SEQUENCE) is retrieved and compared
+     * with the encoded form of this CRL entry.
+     *
+     * @param other the object to test for equality with this CRL entry.
+     * @return true iff the encoded forms of the two CRL entries
+     * match, false otherwise.
+     */
+    public boolean equals(Object other) {
+        if (this == other)
+            return true;
+        if (!(other instanceof X509CRLEntry))
+            return false;
+        try {
+            byte[] thisCRLEntry = this.getEncoded();
+            byte[] otherCRLEntry = ((X509CRLEntry)other).getEncoded();
+
+            if (thisCRLEntry.length != otherCRLEntry.length)
+                return false;
+            for (int i = 0; i < thisCRLEntry.length; i++)
+                 if (thisCRLEntry[i] != otherCRLEntry[i])
+                     return false;
+        } catch (CRLException ce) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Returns a hashcode value for this CRL entry from its
+     * encoded form.
+     *
+     * @return the hashcode value.
+     */
+    public int hashCode() {
+        int     retval = 0;
+        try {
+            byte[] entryData = this.getEncoded();
+            for (int i = 1; i < entryData.length; i++)
+                 retval += entryData[i] * i;
+
+        } catch (CRLException ce) {
+            return(retval);
+        }
+        return(retval);
+    }
+
+    /**
+     * Returns the ASN.1 DER-encoded form of this CRL Entry,
+     * that is the inner SEQUENCE.
+     *
+     * @return the encoded form of this certificate
+     * @exception CRLException if an encoding error occurs.
+     */
+    public abstract byte[] getEncoded() throws CRLException;
+
+    /**
+     * Gets the serial number from this X509CRLEntry,
+     * the <em>userCertificate</em>.
+     *
+     * @return the serial number.
+     */
+    public abstract BigInteger getSerialNumber();
+
+    /**
+     * Get the issuer of the X509Certificate described by this entry. If
+     * the certificate issuer is also the CRL issuer, this method returns
+     * null.
+     *
+     * <p>This method is used with indirect CRLs. The default implementation
+     * always returns null. Subclasses that wish to support indirect CRLs
+     * should override it.
+     *
+     * @return the issuer of the X509Certificate described by this entry
+     * or null if it is issued by the CRL issuer.
+     *
+     * @since 1.5
+     */
+    public X500Principal getCertificateIssuer() {
+        return null;
+    }
+
+    /**
+     * Gets the revocation date from this X509CRLEntry,
+     * the <em>revocationDate</em>.
+     *
+     * @return the revocation date.
+     */
+    public abstract Date getRevocationDate();
+
+    /**
+     * Returns true if this CRL entry has extensions.
+     *
+     * @return true if this entry has extensions, false otherwise.
+     */
+    public abstract boolean hasExtensions();
+
+    /**
+     * Returns a string representation of this CRL entry.
+     *
+     * @return a string representation of this CRL entry.
+     */
+    public abstract String toString();
+
+    /**
+     * Returns the reason the certificate has been revoked, as specified
+     * in the Reason Code extension of this CRL entry.
+     *
+     * @return the reason the certificate has been revoked, or
+     *    {@code null} if this CRL entry does not have
+     *    a Reason Code extension
+     * @since 1.7
+     */
+    public CRLReason getRevocationReason() {
+        if (!hasExtensions()) {
+            return null;
+        }
+        return X509CRLEntryImpl.getRevocationReason(this);
+    }
+}
diff --git a/java/security/cert/X509CRLSelector.java b/java/security/cert/X509CRLSelector.java
new file mode 100644
index 0000000..face5ff
--- /dev/null
+++ b/java/security/cert/X509CRLSelector.java
@@ -0,0 +1,718 @@
+/*
+ * 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
+ * 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 java.security.cert;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.*;
+
+import javax.security.auth.x500.X500Principal;
+
+import sun.security.util.Debug;
+import sun.security.util.DerInputStream;
+import sun.security.x509.CRLNumberExtension;
+import sun.security.x509.X500Name;
+
+/**
+ * A {@code CRLSelector} that selects {@code X509CRLs} that
+ * match all specified criteria. This class is particularly useful when
+ * selecting CRLs from a {@code CertStore} to check revocation status
+ * of a particular certificate.
+ * <p>
+ * When first constructed, an {@code X509CRLSelector} has no criteria
+ * enabled and each of the {@code get} methods return a default
+ * value ({@code null}). Therefore, the {@link #match match} method
+ * would return {@code true} for any {@code X509CRL}. Typically,
+ * several criteria are enabled (by calling {@link #setIssuers setIssuers}
+ * or {@link #setDateAndTime setDateAndTime}, for instance) and then the
+ * {@code X509CRLSelector} is passed to
+ * {@link CertStore#getCRLs CertStore.getCRLs} or some similar
+ * method.
+ * <p>
+ * Please refer to <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280:
+ * Internet X.509 Public Key Infrastructure Certificate and CRL Profile</a>
+ * for definitions of the X.509 CRL fields and extensions mentioned below.
+ * <p>
+ * <b>Concurrent Access</b>
+ * <p>
+ * Unless otherwise specified, the methods defined in this class are not
+ * thread-safe. Multiple threads that need to access a single
+ * object concurrently should synchronize amongst themselves and
+ * provide the necessary locking. Multiple threads each manipulating
+ * separate objects need not synchronize.
+ *
+ * @see CRLSelector
+ * @see X509CRL
+ *
+ * @since       1.4
+ * @author      Steve Hanna
+ */
+public class X509CRLSelector implements CRLSelector {
+
+    static {
+        CertPathHelperImpl.initialize();
+    }
+
+    private static final Debug debug = Debug.getInstance("certpath");
+    private HashSet<Object> issuerNames;
+    private HashSet<X500Principal> issuerX500Principals;
+    private BigInteger minCRL;
+    private BigInteger maxCRL;
+    private Date dateAndTime;
+    private X509Certificate certChecking;
+    private long skew = 0;
+
+    /**
+     * Creates an {@code X509CRLSelector}. Initially, no criteria are set
+     * so any {@code X509CRL} will match.
+     */
+    public X509CRLSelector() {}
+
+    /**
+     * Sets the issuerNames criterion. The issuer distinguished name in the
+     * {@code X509CRL} must match at least one of the specified
+     * distinguished names. If {@code null}, any issuer distinguished name
+     * will do.
+     * <p>
+     * This method allows the caller to specify, with a single method call,
+     * the complete set of issuer names which {@code X509CRLs} may contain.
+     * The specified value replaces the previous value for the issuerNames
+     * criterion.
+     * <p>
+     * The {@code names} parameter (if not {@code null}) is a
+     * {@code Collection} of {@code X500Principal}s.
+     * <p>
+     * Note that the {@code names} parameter can contain duplicate
+     * distinguished names, but they may be removed from the
+     * {@code Collection} of names returned by the
+     * {@link #getIssuers getIssuers} method.
+     * <p>
+     * Note that a copy is performed on the {@code Collection} to
+     * protect against subsequent modifications.
+     *
+     * @param issuers a {@code Collection} of X500Principals
+     *   (or {@code null})
+     * @see #getIssuers
+     * @since 1.5
+     */
+    public void setIssuers(Collection<X500Principal> issuers) {
+        if ((issuers == null) || issuers.isEmpty()) {
+            issuerNames = null;
+            issuerX500Principals = null;
+        } else {
+            // clone
+            issuerX500Principals = new HashSet<X500Principal>(issuers);
+            issuerNames = new HashSet<Object>();
+            for (X500Principal p : issuerX500Principals) {
+                issuerNames.add(p.getEncoded());
+            }
+        }
+    }
+
+    /**
+     * <strong>Note:</strong> use {@linkplain #setIssuers(Collection)} instead
+     * or only specify the byte array form of distinguished names when using
+     * this method. See {@link #addIssuerName(String)} for more information.
+     * <p>
+     * Sets the issuerNames criterion. The issuer distinguished name in the
+     * {@code X509CRL} must match at least one of the specified
+     * distinguished names. If {@code null}, any issuer distinguished name
+     * will do.
+     * <p>
+     * This method allows the caller to specify, with a single method call,
+     * the complete set of issuer names which {@code X509CRLs} may contain.
+     * The specified value replaces the previous value for the issuerNames
+     * criterion.
+     * <p>
+     * The {@code names} parameter (if not {@code null}) is a
+     * {@code Collection} of names. Each name is a {@code String}
+     * or a byte array representing a distinguished name (in
+     * <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a> or
+     * ASN.1 DER encoded form, respectively). If {@code null} is supplied
+     * as the value for this argument, no issuerNames check will be performed.
+     * <p>
+     * Note that the {@code names} parameter can contain duplicate
+     * distinguished names, but they may be removed from the
+     * {@code Collection} of names returned by the
+     * {@link #getIssuerNames getIssuerNames} method.
+     * <p>
+     * If a name is specified as a byte array, it should contain a single DER
+     * encoded distinguished name, as defined in X.501. The ASN.1 notation for
+     * this structure is as follows.
+     * <pre>{@code
+     * Name ::= CHOICE {
+     *   RDNSequence }
+     *
+     * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+     *
+     * RelativeDistinguishedName ::=
+     *   SET SIZE (1 .. MAX) OF AttributeTypeAndValue
+     *
+     * AttributeTypeAndValue ::= SEQUENCE {
+     *   type     AttributeType,
+     *   value    AttributeValue }
+     *
+     * AttributeType ::= OBJECT IDENTIFIER
+     *
+     * AttributeValue ::= ANY DEFINED BY AttributeType
+     * ....
+     * DirectoryString ::= CHOICE {
+     *       teletexString           TeletexString (SIZE (1..MAX)),
+     *       printableString         PrintableString (SIZE (1..MAX)),
+     *       universalString         UniversalString (SIZE (1..MAX)),
+     *       utf8String              UTF8String (SIZE (1.. MAX)),
+     *       bmpString               BMPString (SIZE (1..MAX)) }
+     * }</pre>
+     * <p>
+     * Note that a deep copy is performed on the {@code Collection} to
+     * protect against subsequent modifications.
+     *
+     * @param names a {@code Collection} of names (or {@code null})
+     * @throws IOException if a parsing error occurs
+     * @see #getIssuerNames
+     */
+    public void setIssuerNames(Collection<?> names) throws IOException {
+        if (names == null || names.size() == 0) {
+            issuerNames = null;
+            issuerX500Principals = null;
+        } else {
+            HashSet<Object> tempNames = cloneAndCheckIssuerNames(names);
+            // Ensure that we either set both of these or neither
+            issuerX500Principals = parseIssuerNames(tempNames);
+            issuerNames = tempNames;
+        }
+    }
+
+    /**
+     * Adds a name to the issuerNames criterion. The issuer distinguished
+     * name in the {@code X509CRL} must match at least one of the specified
+     * distinguished names.
+     * <p>
+     * This method allows the caller to add a name to the set of issuer names
+     * which {@code X509CRLs} may contain. The specified name is added to
+     * any previous value for the issuerNames criterion.
+     * If the specified name is a duplicate, it may be ignored.
+     *
+     * @param issuer the issuer as X500Principal
+     * @since 1.5
+     */
+    public void addIssuer(X500Principal issuer) {
+        addIssuerNameInternal(issuer.getEncoded(), issuer);
+    }
+
+    /**
+     * <strong>Denigrated</strong>, use
+     * {@linkplain #addIssuer(X500Principal)} or
+     * {@linkplain #addIssuerName(byte[])} instead. This method should not be
+     * relied on as it can fail to match some CRLs because of a loss of
+     * encoding information in the RFC 2253 String form of some distinguished
+     * names.
+     * <p>
+     * Adds a name to the issuerNames criterion. The issuer distinguished
+     * name in the {@code X509CRL} must match at least one of the specified
+     * distinguished names.
+     * <p>
+     * This method allows the caller to add a name to the set of issuer names
+     * which {@code X509CRLs} may contain. The specified name is added to
+     * any previous value for the issuerNames criterion.
+     * If the specified name is a duplicate, it may be ignored.
+     *
+     * @param name the name in RFC 2253 form
+     * @throws IOException if a parsing error occurs
+     */
+    public void addIssuerName(String name) throws IOException {
+        addIssuerNameInternal(name, new X500Name(name).asX500Principal());
+    }
+
+    /**
+     * Adds a name to the issuerNames criterion. The issuer distinguished
+     * name in the {@code X509CRL} must match at least one of the specified
+     * distinguished names.
+     * <p>
+     * This method allows the caller to add a name to the set of issuer names
+     * which {@code X509CRLs} may contain. The specified name is added to
+     * any previous value for the issuerNames criterion. If the specified name
+     * is a duplicate, it may be ignored.
+     * If a name is specified as a byte array, it should contain a single DER
+     * encoded distinguished name, as defined in X.501. The ASN.1 notation for
+     * this structure is as follows.
+     * <p>
+     * The name is provided as a byte array. This byte array should contain
+     * a single DER encoded distinguished name, as defined in X.501. The ASN.1
+     * notation for this structure appears in the documentation for
+     * {@link #setIssuerNames setIssuerNames(Collection names)}.
+     * <p>
+     * Note that the byte array supplied here is cloned to protect against
+     * subsequent modifications.
+     *
+     * @param name a byte array containing the name in ASN.1 DER encoded form
+     * @throws IOException if a parsing error occurs
+     */
+    public void addIssuerName(byte[] name) throws IOException {
+        // clone because byte arrays are modifiable
+        addIssuerNameInternal(name.clone(), new X500Name(name).asX500Principal());
+    }
+
+    /**
+     * A private method that adds a name (String or byte array) to the
+     * issuerNames criterion. The issuer distinguished
+     * name in the {@code X509CRL} must match at least one of the specified
+     * distinguished names.
+     *
+     * @param name the name in string or byte array form
+     * @param principal the name in X500Principal form
+     * @throws IOException if a parsing error occurs
+     */
+    private void addIssuerNameInternal(Object name, X500Principal principal) {
+        if (issuerNames == null) {
+            issuerNames = new HashSet<Object>();
+        }
+        if (issuerX500Principals == null) {
+            issuerX500Principals = new HashSet<X500Principal>();
+        }
+        issuerNames.add(name);
+        issuerX500Principals.add(principal);
+    }
+
+    /**
+     * Clone and check an argument of the form passed to
+     * setIssuerNames. Throw an IOException if the argument is malformed.
+     *
+     * @param names a {@code Collection} of names. Each entry is a
+     *              String or a byte array (the name, in string or ASN.1
+     *              DER encoded form, respectively). {@code null} is
+     *              not an acceptable value.
+     * @return a deep copy of the specified {@code Collection}
+     * @throws IOException if a parsing error occurs
+     */
+    private static HashSet<Object> cloneAndCheckIssuerNames(Collection<?> names)
+        throws IOException
+    {
+        HashSet<Object> namesCopy = new HashSet<Object>();
+        Iterator<?> i = names.iterator();
+        while (i.hasNext()) {
+            Object nameObject = i.next();
+            if (!(nameObject instanceof byte []) &&
+                !(nameObject instanceof String))
+                throw new IOException("name not byte array or String");
+            if (nameObject instanceof byte [])
+                namesCopy.add(((byte []) nameObject).clone());
+            else
+                namesCopy.add(nameObject);
+        }
+        return(namesCopy);
+    }
+
+    /**
+     * Clone an argument of the form passed to setIssuerNames.
+     * Throw a RuntimeException if the argument is malformed.
+     * <p>
+     * This method wraps cloneAndCheckIssuerNames, changing any IOException
+     * into a RuntimeException. This method should be used when the object being
+     * cloned has already been checked, so there should never be any exceptions.
+     *
+     * @param names a {@code Collection} of names. Each entry is a
+     *              String or a byte array (the name, in string or ASN.1
+     *              DER encoded form, respectively). {@code null} is
+     *              not an acceptable value.
+     * @return a deep copy of the specified {@code Collection}
+     * @throws RuntimeException if a parsing error occurs
+     */
+    private static HashSet<Object> cloneIssuerNames(Collection<Object> names) {
+        try {
+            return cloneAndCheckIssuerNames(names);
+        } catch (IOException ioe) {
+            throw new RuntimeException(ioe);
+        }
+    }
+
+    /**
+     * Parse an argument of the form passed to setIssuerNames,
+     * returning a Collection of issuerX500Principals.
+     * Throw an IOException if the argument is malformed.
+     *
+     * @param names a {@code Collection} of names. Each entry is a
+     *              String or a byte array (the name, in string or ASN.1
+     *              DER encoded form, respectively). <Code>Null</Code> is
+     *              not an acceptable value.
+     * @return a HashSet of issuerX500Principals
+     * @throws IOException if a parsing error occurs
+     */
+    private static HashSet<X500Principal> parseIssuerNames(Collection<Object> names)
+    throws IOException {
+        HashSet<X500Principal> x500Principals = new HashSet<X500Principal>();
+        for (Iterator<Object> t = names.iterator(); t.hasNext(); ) {
+            Object nameObject = t.next();
+            if (nameObject instanceof String) {
+                x500Principals.add(new X500Name((String)nameObject).asX500Principal());
+            } else {
+                try {
+                    x500Principals.add(new X500Principal((byte[])nameObject));
+                } catch (IllegalArgumentException e) {
+                    throw (IOException)new IOException("Invalid name").initCause(e);
+                }
+            }
+        }
+        return x500Principals;
+    }
+
+    /**
+     * Sets the minCRLNumber criterion. The {@code X509CRL} must have a
+     * CRL number extension whose value is greater than or equal to the
+     * specified value. If {@code null}, no minCRLNumber check will be
+     * done.
+     *
+     * @param minCRL the minimum CRL number accepted (or {@code null})
+     */
+    public void setMinCRLNumber(BigInteger minCRL) {
+        this.minCRL = minCRL;
+    }
+
+    /**
+     * Sets the maxCRLNumber criterion. The {@code X509CRL} must have a
+     * CRL number extension whose value is less than or equal to the
+     * specified value. If {@code null}, no maxCRLNumber check will be
+     * done.
+     *
+     * @param maxCRL the maximum CRL number accepted (or {@code null})
+     */
+    public void setMaxCRLNumber(BigInteger maxCRL) {
+        this.maxCRL = maxCRL;
+    }
+
+    /**
+     * Sets the dateAndTime criterion. The specified date must be
+     * equal to or later than the value of the thisUpdate component
+     * of the {@code X509CRL} and earlier than the value of the
+     * nextUpdate component. There is no match if the {@code X509CRL}
+     * does not contain a nextUpdate component.
+     * If {@code null}, no dateAndTime check will be done.
+     * <p>
+     * Note that the {@code Date} supplied here is cloned to protect
+     * against subsequent modifications.
+     *
+     * @param dateAndTime the {@code Date} to match against
+     *                    (or {@code null})
+     * @see #getDateAndTime
+     */
+    public void setDateAndTime(Date dateAndTime) {
+        if (dateAndTime == null)
+            this.dateAndTime = null;
+        else
+            this.dateAndTime = new Date(dateAndTime.getTime());
+        this.skew = 0;
+    }
+
+    /**
+     * Sets the dateAndTime criterion and allows for the specified clock skew
+     * (in milliseconds) when checking against the validity period of the CRL.
+     */
+    void setDateAndTime(Date dateAndTime, long skew) {
+        this.dateAndTime =
+            (dateAndTime == null ? null : new Date(dateAndTime.getTime()));
+        this.skew = skew;
+    }
+
+    /**
+     * Sets the certificate being checked. This is not a criterion. Rather,
+     * it is optional information that may help a {@code CertStore}
+     * find CRLs that would be relevant when checking revocation for the
+     * specified certificate. If {@code null} is specified, then no
+     * such optional information is provided.
+     *
+     * @param cert the {@code X509Certificate} being checked
+     *             (or {@code null})
+     * @see #getCertificateChecking
+     */
+    public void setCertificateChecking(X509Certificate cert) {
+        certChecking = cert;
+    }
+
+    /**
+     * Returns the issuerNames criterion. The issuer distinguished
+     * name in the {@code X509CRL} must match at least one of the specified
+     * distinguished names. If the value returned is {@code null}, any
+     * issuer distinguished name will do.
+     * <p>
+     * If the value returned is not {@code null}, it is a
+     * unmodifiable {@code Collection} of {@code X500Principal}s.
+     *
+     * @return an unmodifiable {@code Collection} of names
+     *   (or {@code null})
+     * @see #setIssuers
+     * @since 1.5
+     */
+    public Collection<X500Principal> getIssuers() {
+        if (issuerX500Principals == null) {
+            return null;
+        }
+        return Collections.unmodifiableCollection(issuerX500Principals);
+    }
+
+    /**
+     * Returns a copy of the issuerNames criterion. The issuer distinguished
+     * name in the {@code X509CRL} must match at least one of the specified
+     * distinguished names. If the value returned is {@code null}, any
+     * issuer distinguished name will do.
+     * <p>
+     * If the value returned is not {@code null}, it is a
+     * {@code Collection} of names. Each name is a {@code String}
+     * or a byte array representing a distinguished name (in RFC 2253 or
+     * ASN.1 DER encoded form, respectively).  Note that the
+     * {@code Collection} returned may contain duplicate names.
+     * <p>
+     * If a name is specified as a byte array, it should contain a single DER
+     * encoded distinguished name, as defined in X.501. The ASN.1 notation for
+     * this structure is given in the documentation for
+     * {@link #setIssuerNames setIssuerNames(Collection names)}.
+     * <p>
+     * Note that a deep copy is performed on the {@code Collection} to
+     * protect against subsequent modifications.
+     *
+     * @return a {@code Collection} of names (or {@code null})
+     * @see #setIssuerNames
+     */
+    public Collection<Object> getIssuerNames() {
+        if (issuerNames == null) {
+            return null;
+        }
+        return cloneIssuerNames(issuerNames);
+    }
+
+    /**
+     * Returns the minCRLNumber criterion. The {@code X509CRL} must have a
+     * CRL number extension whose value is greater than or equal to the
+     * specified value. If {@code null}, no minCRLNumber check will be done.
+     *
+     * @return the minimum CRL number accepted (or {@code null})
+     */
+    public BigInteger getMinCRL() {
+        return minCRL;
+    }
+
+    /**
+     * Returns the maxCRLNumber criterion. The {@code X509CRL} must have a
+     * CRL number extension whose value is less than or equal to the
+     * specified value. If {@code null}, no maxCRLNumber check will be
+     * done.
+     *
+     * @return the maximum CRL number accepted (or {@code null})
+     */
+    public BigInteger getMaxCRL() {
+        return maxCRL;
+    }
+
+    /**
+     * Returns the dateAndTime criterion. The specified date must be
+     * equal to or later than the value of the thisUpdate component
+     * of the {@code X509CRL} and earlier than the value of the
+     * nextUpdate component. There is no match if the
+     * {@code X509CRL} does not contain a nextUpdate component.
+     * If {@code null}, no dateAndTime check will be done.
+     * <p>
+     * Note that the {@code Date} returned is cloned to protect against
+     * subsequent modifications.
+     *
+     * @return the {@code Date} to match against (or {@code null})
+     * @see #setDateAndTime
+     */
+    public Date getDateAndTime() {
+        if (dateAndTime == null)
+            return null;
+        return (Date) dateAndTime.clone();
+    }
+
+    /**
+     * Returns the certificate being checked. This is not a criterion. Rather,
+     * it is optional information that may help a {@code CertStore}
+     * find CRLs that would be relevant when checking revocation for the
+     * specified certificate. If the value returned is {@code null}, then
+     * no such optional information is provided.
+     *
+     * @return the certificate being checked (or {@code null})
+     * @see #setCertificateChecking
+     */
+    public X509Certificate getCertificateChecking() {
+        return certChecking;
+    }
+
+    /**
+     * Returns a printable representation of the {@code X509CRLSelector}.
+     *
+     * @return a {@code String} describing the contents of the
+     *         {@code X509CRLSelector}.
+     */
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append("X509CRLSelector: [\n");
+        if (issuerNames != null) {
+            sb.append("  IssuerNames:\n");
+            Iterator<Object> i = issuerNames.iterator();
+            while (i.hasNext())
+                sb.append("    " + i.next() + "\n");
+        }
+        if (minCRL != null)
+            sb.append("  minCRLNumber: " + minCRL + "\n");
+        if (maxCRL != null)
+            sb.append("  maxCRLNumber: " + maxCRL + "\n");
+        if (dateAndTime != null)
+            sb.append("  dateAndTime: " + dateAndTime + "\n");
+        if (certChecking != null)
+            sb.append("  Certificate being checked: " + certChecking + "\n");
+        sb.append("]");
+        return sb.toString();
+    }
+
+    /**
+     * Decides whether a {@code CRL} should be selected.
+     *
+     * @param crl the {@code CRL} to be checked
+     * @return {@code true} if the {@code CRL} should be selected,
+     *         {@code false} otherwise
+     */
+    public boolean match(CRL crl) {
+        if (!(crl instanceof X509CRL)) {
+            return false;
+        }
+        X509CRL xcrl = (X509CRL)crl;
+
+        /* match on issuer name */
+        if (issuerNames != null) {
+            X500Principal issuer = xcrl.getIssuerX500Principal();
+            Iterator<X500Principal> i = issuerX500Principals.iterator();
+            boolean found = false;
+            while (!found && i.hasNext()) {
+                if (i.next().equals(issuer)) {
+                    found = true;
+                }
+            }
+            if (!found) {
+                if (debug != null) {
+                    debug.println("X509CRLSelector.match: issuer DNs "
+                        + "don't match");
+                }
+                return false;
+            }
+        }
+
+        if ((minCRL != null) || (maxCRL != null)) {
+            /* Get CRL number extension from CRL */
+            byte[] crlNumExtVal = xcrl.getExtensionValue("2.5.29.20");
+            if (crlNumExtVal == null) {
+                if (debug != null) {
+                    debug.println("X509CRLSelector.match: no CRLNumber");
+                }
+            }
+            BigInteger crlNum;
+            try {
+                DerInputStream in = new DerInputStream(crlNumExtVal);
+                byte[] encoded = in.getOctetString();
+                CRLNumberExtension crlNumExt =
+                    new CRLNumberExtension(Boolean.FALSE, encoded);
+                crlNum = crlNumExt.get(CRLNumberExtension.NUMBER);
+            } catch (IOException ex) {
+                if (debug != null) {
+                    debug.println("X509CRLSelector.match: exception in "
+                        + "decoding CRL number");
+                }
+                return false;
+            }
+
+            /* match on minCRLNumber */
+            if (minCRL != null) {
+                if (crlNum.compareTo(minCRL) < 0) {
+                    if (debug != null) {
+                        debug.println("X509CRLSelector.match: CRLNumber too small");
+                    }
+                    return false;
+                }
+            }
+
+            /* match on maxCRLNumber */
+            if (maxCRL != null) {
+                if (crlNum.compareTo(maxCRL) > 0) {
+                    if (debug != null) {
+                        debug.println("X509CRLSelector.match: CRLNumber too large");
+                    }
+                    return false;
+                }
+            }
+        }
+
+
+        /* match on dateAndTime */
+        if (dateAndTime != null) {
+            Date crlThisUpdate = xcrl.getThisUpdate();
+            Date nextUpdate = xcrl.getNextUpdate();
+            if (nextUpdate == null) {
+                if (debug != null) {
+                    debug.println("X509CRLSelector.match: nextUpdate null");
+                }
+                return false;
+            }
+            Date nowPlusSkew = dateAndTime;
+            Date nowMinusSkew = dateAndTime;
+            if (skew > 0) {
+                nowPlusSkew = new Date(dateAndTime.getTime() + skew);
+                nowMinusSkew = new Date(dateAndTime.getTime() - skew);
+            }
+
+            // Check that the test date is within the validity interval:
+            //   [ thisUpdate - MAX_CLOCK_SKEW,
+            //     nextUpdate + MAX_CLOCK_SKEW ]
+            if (nowMinusSkew.after(nextUpdate)
+                || nowPlusSkew.before(crlThisUpdate)) {
+                if (debug != null) {
+                    debug.println("X509CRLSelector.match: update out-of-range");
+                }
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Returns a copy of this object.
+     *
+     * @return the copy
+     */
+    public Object clone() {
+        try {
+            X509CRLSelector copy = (X509CRLSelector)super.clone();
+            if (issuerNames != null) {
+                copy.issuerNames =
+                        new HashSet<Object>(issuerNames);
+                copy.issuerX500Principals =
+                        new HashSet<X500Principal>(issuerX500Principals);
+            }
+            return copy;
+        } catch (CloneNotSupportedException e) {
+            /* Cannot happen */
+            throw new InternalError(e.toString(), e);
+        }
+    }
+}
diff --git a/java/security/cert/X509CertSelector.java b/java/security/cert/X509CertSelector.java
new file mode 100644
index 0000000..d4952da
--- /dev/null
+++ b/java/security/cert/X509CertSelector.java
@@ -0,0 +1,2624 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2013, 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 java.security.cert;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.PublicKey;
+import java.util.*;
+import javax.security.auth.x500.X500Principal;
+
+import sun.misc.HexDumpEncoder;
+import sun.security.util.Debug;
+import sun.security.util.DerInputStream;
+import sun.security.util.DerValue;
+import sun.security.util.ObjectIdentifier;
+import sun.security.x509.*;
+
+/**
+ * A {@code CertSelector} that selects {@code X509Certificates} that
+ * match all specified criteria. This class is particularly useful when
+ * selecting certificates from a {@code CertStore} to build a
+ * PKIX-compliant certification path.
+ * <p>
+ * When first constructed, an {@code X509CertSelector} has no criteria
+ * enabled and each of the {@code get} methods return a default value
+ * ({@code null}, or {@code -1} for the {@link #getBasicConstraints
+ * getBasicConstraints} method). Therefore, the {@link #match match}
+ * method would return {@code true} for any {@code X509Certificate}.
+ * Typically, several criteria are enabled (by calling
+ * {@link #setIssuer setIssuer} or
+ * {@link #setKeyUsage setKeyUsage}, for instance) and then the
+ * {@code X509CertSelector} is passed to
+ * {@link CertStore#getCertificates CertStore.getCertificates} or some similar
+ * method.
+ * <p>
+ * Several criteria can be enabled (by calling {@link #setIssuer setIssuer}
+ * and {@link #setSerialNumber setSerialNumber},
+ * for example) such that the {@code match} method
+ * usually uniquely matches a single {@code X509Certificate}. We say
+ * usually, since it is possible for two issuing CAs to have the same
+ * distinguished name and each issue a certificate with the same serial
+ * number. Other unique combinations include the issuer, subject,
+ * subjectKeyIdentifier and/or the subjectPublicKey criteria.
+ * <p>
+ * Please refer to <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280:
+ * Internet X.509 Public Key Infrastructure Certificate and CRL Profile</a> for
+ * definitions of the X.509 certificate extensions mentioned below.
+ * <p>
+ * <b>Concurrent Access</b>
+ * <p>
+ * Unless otherwise specified, the methods defined in this class are not
+ * thread-safe. Multiple threads that need to access a single
+ * object concurrently should synchronize amongst themselves and
+ * provide the necessary locking. Multiple threads each manipulating
+ * separate objects need not synchronize.
+ *
+ * @see CertSelector
+ * @see X509Certificate
+ *
+ * @since       1.4
+ * @author      Steve Hanna
+ */
+public class X509CertSelector implements CertSelector {
+
+    private static final Debug debug = Debug.getInstance("certpath");
+
+    private final static ObjectIdentifier ANY_EXTENDED_KEY_USAGE =
+        ObjectIdentifier.newInternal(new int[] {2, 5, 29, 37, 0});
+
+    static {
+        CertPathHelperImpl.initialize();
+    }
+
+    private BigInteger serialNumber;
+    private X500Principal issuer;
+    private X500Principal subject;
+    private byte[] subjectKeyID;
+    private byte[] authorityKeyID;
+    private Date certificateValid;
+    private Date privateKeyValid;
+    private ObjectIdentifier subjectPublicKeyAlgID;
+    private PublicKey subjectPublicKey;
+    private byte[] subjectPublicKeyBytes;
+    private boolean[] keyUsage;
+    private Set<String> keyPurposeSet;
+    private Set<ObjectIdentifier> keyPurposeOIDSet;
+    private Set<List<?>> subjectAlternativeNames;
+    private Set<GeneralNameInterface> subjectAlternativeGeneralNames;
+    private CertificatePolicySet policy;
+    private Set<String> policySet;
+    private Set<List<?>> pathToNames;
+    private Set<GeneralNameInterface> pathToGeneralNames;
+    private NameConstraintsExtension nc;
+    private byte[] ncBytes;
+    private int basicConstraints = -1;
+    private X509Certificate x509Cert;
+    private boolean matchAllSubjectAltNames = true;
+
+    private static final Boolean FALSE = Boolean.FALSE;
+
+    private static final int PRIVATE_KEY_USAGE_ID = 0;
+    private static final int SUBJECT_ALT_NAME_ID = 1;
+    private static final int NAME_CONSTRAINTS_ID = 2;
+    private static final int CERT_POLICIES_ID = 3;
+    private static final int EXTENDED_KEY_USAGE_ID = 4;
+    private static final int NUM_OF_EXTENSIONS = 5;
+    private static final String[] EXTENSION_OIDS = new String[NUM_OF_EXTENSIONS];
+
+    static {
+        EXTENSION_OIDS[PRIVATE_KEY_USAGE_ID]  = "2.5.29.16";
+        EXTENSION_OIDS[SUBJECT_ALT_NAME_ID]   = "2.5.29.17";
+        EXTENSION_OIDS[NAME_CONSTRAINTS_ID]   = "2.5.29.30";
+        EXTENSION_OIDS[CERT_POLICIES_ID]      = "2.5.29.32";
+        EXTENSION_OIDS[EXTENDED_KEY_USAGE_ID] = "2.5.29.37";
+    };
+
+    /* Constants representing the GeneralName types */
+    static final int NAME_ANY = 0;
+    static final int NAME_RFC822 = 1;
+    static final int NAME_DNS = 2;
+    static final int NAME_X400 = 3;
+    static final int NAME_DIRECTORY = 4;
+    static final int NAME_EDI = 5;
+    static final int NAME_URI = 6;
+    static final int NAME_IP = 7;
+    static final int NAME_OID = 8;
+
+    /**
+     * Creates an {@code X509CertSelector}. Initially, no criteria are set
+     * so any {@code X509Certificate} will match.
+     */
+    public X509CertSelector() {
+        // empty
+    }
+
+    /**
+     * Sets the certificateEquals criterion. The specified
+     * {@code X509Certificate} must be equal to the
+     * {@code X509Certificate} passed to the {@code match} method.
+     * If {@code null}, then this check is not applied.
+     *
+     * <p>This method is particularly useful when it is necessary to
+     * match a single certificate. Although other criteria can be specified
+     * in conjunction with the certificateEquals criterion, it is usually not
+     * practical or necessary.
+     *
+     * @param cert the {@code X509Certificate} to match (or
+     * {@code null})
+     * @see #getCertificate
+     */
+    public void setCertificate(X509Certificate cert) {
+        x509Cert = cert;
+    }
+
+    /**
+     * Sets the serialNumber criterion. The specified serial number
+     * must match the certificate serial number in the
+     * {@code X509Certificate}. If {@code null}, any certificate
+     * serial number will do.
+     *
+     * @param serial the certificate serial number to match
+     *        (or {@code null})
+     * @see #getSerialNumber
+     */
+    public void setSerialNumber(BigInteger serial) {
+        serialNumber = serial;
+    }
+
+    /**
+     * Sets the issuer criterion. The specified distinguished name
+     * must match the issuer distinguished name in the
+     * {@code X509Certificate}. If {@code null}, any issuer
+     * distinguished name will do.
+     *
+     * @param issuer a distinguished name as X500Principal
+     *                 (or {@code null})
+     * @since 1.5
+     */
+    public void setIssuer(X500Principal issuer) {
+        this.issuer = issuer;
+    }
+
+    /**
+     * <strong>Denigrated</strong>, use {@linkplain #setIssuer(X500Principal)}
+     * or {@linkplain #setIssuer(byte[])} instead. This method should not be
+     * relied on as it can fail to match some certificates because of a loss of
+     * encoding information in the
+     * <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a> String form
+     * of some distinguished names.
+     * <p>
+     * Sets the issuer criterion. The specified distinguished name
+     * must match the issuer distinguished name in the
+     * {@code X509Certificate}. If {@code null}, any issuer
+     * distinguished name will do.
+     * <p>
+     * If {@code issuerDN} is not {@code null}, it should contain a
+     * distinguished name, in RFC 2253 format.
+     *
+     * @param issuerDN a distinguished name in RFC 2253 format
+     *                 (or {@code null})
+     * @throws IOException if a parsing error occurs (incorrect form for DN)
+     */
+    public void setIssuer(String issuerDN) throws IOException {
+        if (issuerDN == null) {
+            issuer = null;
+        } else {
+            issuer = new X500Name(issuerDN).asX500Principal();
+        }
+    }
+
+    /**
+     * Sets the issuer criterion. The specified distinguished name
+     * must match the issuer distinguished name in the
+     * {@code X509Certificate}. If {@code null} is specified,
+     * the issuer criterion is disabled and any issuer distinguished name will
+     * do.
+     * <p>
+     * If {@code issuerDN} is not {@code null}, it should contain a
+     * single DER encoded distinguished name, as defined in X.501. The ASN.1
+     * notation for this structure is as follows.
+     * <pre>{@code
+     * Name ::= CHOICE {
+     *   RDNSequence }
+     *
+     * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+     *
+     * RelativeDistinguishedName ::=
+     *   SET SIZE (1 .. MAX) OF AttributeTypeAndValue
+     *
+     * AttributeTypeAndValue ::= SEQUENCE {
+     *   type     AttributeType,
+     *   value    AttributeValue }
+     *
+     * AttributeType ::= OBJECT IDENTIFIER
+     *
+     * AttributeValue ::= ANY DEFINED BY AttributeType
+     * ....
+     * DirectoryString ::= CHOICE {
+     *       teletexString           TeletexString (SIZE (1..MAX)),
+     *       printableString         PrintableString (SIZE (1..MAX)),
+     *       universalString         UniversalString (SIZE (1..MAX)),
+     *       utf8String              UTF8String (SIZE (1.. MAX)),
+     *       bmpString               BMPString (SIZE (1..MAX)) }
+     * }</pre>
+     * <p>
+     * Note that the byte array specified here is cloned to protect against
+     * subsequent modifications.
+     *
+     * @param issuerDN a byte array containing the distinguished name
+     *                 in ASN.1 DER encoded form (or {@code null})
+     * @throws IOException if an encoding error occurs (incorrect form for DN)
+     */
+    public void setIssuer(byte[] issuerDN) throws IOException {
+        try {
+            issuer = (issuerDN == null ? null : new X500Principal(issuerDN));
+        } catch (IllegalArgumentException e) {
+            throw new IOException("Invalid name", e);
+        }
+    }
+
+    /**
+     * Sets the subject criterion. The specified distinguished name
+     * must match the subject distinguished name in the
+     * {@code X509Certificate}. If {@code null}, any subject
+     * distinguished name will do.
+     *
+     * @param subject a distinguished name as X500Principal
+     *                  (or {@code null})
+     * @since 1.5
+     */
+    public void setSubject(X500Principal subject) {
+        this.subject = subject;
+    }
+
+    /**
+     * <strong>Denigrated</strong>, use {@linkplain #setSubject(X500Principal)}
+     * or {@linkplain #setSubject(byte[])} instead. This method should not be
+     * relied on as it can fail to match some certificates because of a loss of
+     * encoding information in the RFC 2253 String form of some distinguished
+     * names.
+     * <p>
+     * Sets the subject criterion. The specified distinguished name
+     * must match the subject distinguished name in the
+     * {@code X509Certificate}. If {@code null}, any subject
+     * distinguished name will do.
+     * <p>
+     * If {@code subjectDN} is not {@code null}, it should contain a
+     * distinguished name, in RFC 2253 format.
+     *
+     * @param subjectDN a distinguished name in RFC 2253 format
+     *                  (or {@code null})
+     * @throws IOException if a parsing error occurs (incorrect form for DN)
+     */
+    public void setSubject(String subjectDN) throws IOException {
+        if (subjectDN == null) {
+            subject = null;
+        } else {
+            subject = new X500Name(subjectDN).asX500Principal();
+        }
+    }
+
+    /**
+     * Sets the subject criterion. The specified distinguished name
+     * must match the subject distinguished name in the
+     * {@code X509Certificate}. If {@code null}, any subject
+     * distinguished name will do.
+     * <p>
+     * If {@code subjectDN} is not {@code null}, it should contain a
+     * single DER encoded distinguished name, as defined in X.501. For the ASN.1
+     * notation for this structure, see
+     * {@link #setIssuer(byte [] issuerDN) setIssuer(byte [] issuerDN)}.
+     *
+     * @param subjectDN a byte array containing the distinguished name in
+     *                  ASN.1 DER format (or {@code null})
+     * @throws IOException if an encoding error occurs (incorrect form for DN)
+     */
+    public void setSubject(byte[] subjectDN) throws IOException {
+        try {
+            subject = (subjectDN == null ? null : new X500Principal(subjectDN));
+        } catch (IllegalArgumentException e) {
+            throw new IOException("Invalid name", e);
+        }
+    }
+
+    /**
+     * Sets the subjectKeyIdentifier criterion. The
+     * {@code X509Certificate} must contain a SubjectKeyIdentifier
+     * extension for which the contents of the extension
+     * matches the specified criterion value.
+     * If the criterion value is {@code null}, no
+     * subjectKeyIdentifier check will be done.
+     * <p>
+     * If {@code subjectKeyID} is not {@code null}, it
+     * should contain a single DER encoded value corresponding to the contents
+     * of the extension value (not including the object identifier,
+     * criticality setting, and encapsulating OCTET STRING)
+     * for a SubjectKeyIdentifier extension.
+     * The ASN.1 notation for this structure follows.
+     *
+     * <pre>{@code
+     * SubjectKeyIdentifier ::= KeyIdentifier
+     *
+     * KeyIdentifier ::= OCTET STRING
+     * }</pre>
+     * <p>
+     * Since the format of subject key identifiers is not mandated by
+     * any standard, subject key identifiers are not parsed by the
+     * {@code X509CertSelector}. Instead, the values are compared using
+     * a byte-by-byte comparison.
+     * <p>
+     * Note that the byte array supplied here is cloned to protect against
+     * subsequent modifications.
+     *
+     * @param subjectKeyID the subject key identifier (or {@code null})
+     * @see #getSubjectKeyIdentifier
+     */
+    public void setSubjectKeyIdentifier(byte[] subjectKeyID) {
+        if (subjectKeyID == null) {
+            this.subjectKeyID = null;
+        } else {
+            this.subjectKeyID = subjectKeyID.clone();
+        }
+    }
+
+    /**
+     * Sets the authorityKeyIdentifier criterion. The
+     * {@code X509Certificate} must contain an
+     * AuthorityKeyIdentifier extension for which the contents of the
+     * extension value matches the specified criterion value.
+     * If the criterion value is {@code null}, no
+     * authorityKeyIdentifier check will be done.
+     * <p>
+     * If {@code authorityKeyID} is not {@code null}, it
+     * should contain a single DER encoded value corresponding to the contents
+     * of the extension value (not including the object identifier,
+     * criticality setting, and encapsulating OCTET STRING)
+     * for an AuthorityKeyIdentifier extension.
+     * The ASN.1 notation for this structure follows.
+     *
+     * <pre>{@code
+     * AuthorityKeyIdentifier ::= SEQUENCE {
+     *    keyIdentifier             [0] KeyIdentifier           OPTIONAL,
+     *    authorityCertIssuer       [1] GeneralNames            OPTIONAL,
+     *    authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL  }
+     *
+     * KeyIdentifier ::= OCTET STRING
+     * }</pre>
+     * <p>
+     * Authority key identifiers are not parsed by the
+     * {@code X509CertSelector}.  Instead, the values are
+     * compared using a byte-by-byte comparison.
+     * <p>
+     * When the {@code keyIdentifier} field of
+     * {@code AuthorityKeyIdentifier} is populated, the value is
+     * usually taken from the {@code SubjectKeyIdentifier} extension
+     * in the issuer's certificate.  Note, however, that the result of
+     * {@code X509Certificate.getExtensionValue(<SubjectKeyIdentifier Object
+     * Identifier>)} on the issuer's certificate may NOT be used
+     * directly as the input to {@code setAuthorityKeyIdentifier}.
+     * This is because the SubjectKeyIdentifier contains
+     * only a KeyIdentifier OCTET STRING, and not a SEQUENCE of
+     * KeyIdentifier, GeneralNames, and CertificateSerialNumber.
+     * In order to use the extension value of the issuer certificate's
+     * {@code SubjectKeyIdentifier}
+     * extension, it will be necessary to extract the value of the embedded
+     * {@code KeyIdentifier} OCTET STRING, then DER encode this OCTET
+     * STRING inside a SEQUENCE.
+     * For more details on SubjectKeyIdentifier, see
+     * {@link #setSubjectKeyIdentifier(byte[] subjectKeyID)}.
+     * <p>
+     * Note also that the byte array supplied here is cloned to protect against
+     * subsequent modifications.
+     *
+     * @param authorityKeyID the authority key identifier
+     *        (or {@code null})
+     * @see #getAuthorityKeyIdentifier
+     */
+    public void setAuthorityKeyIdentifier(byte[] authorityKeyID) {
+        if (authorityKeyID == null) {
+            this.authorityKeyID = null;
+        } else {
+            this.authorityKeyID = authorityKeyID.clone();
+        }
+    }
+
+    /**
+     * Sets the certificateValid criterion. The specified date must fall
+     * within the certificate validity period for the
+     * {@code X509Certificate}. If {@code null}, no certificateValid
+     * check will be done.
+     * <p>
+     * Note that the {@code Date} supplied here is cloned to protect
+     * against subsequent modifications.
+     *
+     * @param certValid the {@code Date} to check (or {@code null})
+     * @see #getCertificateValid
+     */
+    public void setCertificateValid(Date certValid) {
+        if (certValid == null) {
+            certificateValid = null;
+        } else {
+            certificateValid = (Date)certValid.clone();
+        }
+    }
+
+    /**
+     * Sets the privateKeyValid criterion. The specified date must fall
+     * within the private key validity period for the
+     * {@code X509Certificate}. If {@code null}, no privateKeyValid
+     * check will be done.
+     * <p>
+     * Note that the {@code Date} supplied here is cloned to protect
+     * against subsequent modifications.
+     *
+     * @param privateKeyValid the {@code Date} to check (or
+     *                        {@code null})
+     * @see #getPrivateKeyValid
+     */
+    public void setPrivateKeyValid(Date privateKeyValid) {
+        if (privateKeyValid == null) {
+            this.privateKeyValid = null;
+        } else {
+            this.privateKeyValid = (Date)privateKeyValid.clone();
+        }
+    }
+
+    /**
+     * Sets the subjectPublicKeyAlgID criterion. The
+     * {@code X509Certificate} must contain a subject public key
+     * with the specified algorithm. If {@code null}, no
+     * subjectPublicKeyAlgID check will be done.
+     *
+     * @param oid The object identifier (OID) of the algorithm to check
+     *            for (or {@code null}). An OID is represented by a
+     *            set of nonnegative integers separated by periods.
+     * @throws IOException if the OID is invalid, such as
+     * the first component being not 0, 1 or 2 or the second component
+     * being greater than 39.
+     *
+     * @see #getSubjectPublicKeyAlgID
+     */
+    public void setSubjectPublicKeyAlgID(String oid) throws IOException {
+        if (oid == null) {
+            subjectPublicKeyAlgID = null;
+        } else {
+            subjectPublicKeyAlgID = new ObjectIdentifier(oid);
+        }
+    }
+
+    /**
+     * Sets the subjectPublicKey criterion. The
+     * {@code X509Certificate} must contain the specified subject public
+     * key. If {@code null}, no subjectPublicKey check will be done.
+     *
+     * @param key the subject public key to check for (or {@code null})
+     * @see #getSubjectPublicKey
+     */
+    public void setSubjectPublicKey(PublicKey key) {
+        if (key == null) {
+            subjectPublicKey = null;
+            subjectPublicKeyBytes = null;
+        } else {
+            subjectPublicKey = key;
+            subjectPublicKeyBytes = key.getEncoded();
+        }
+    }
+
+    /**
+     * Sets the subjectPublicKey criterion. The {@code X509Certificate}
+     * must contain the specified subject public key. If {@code null},
+     * no subjectPublicKey check will be done.
+     * <p>
+     * Because this method allows the public key to be specified as a byte
+     * array, it may be used for unknown key types.
+     * <p>
+     * If {@code key} is not {@code null}, it should contain a
+     * single DER encoded SubjectPublicKeyInfo structure, as defined in X.509.
+     * The ASN.1 notation for this structure is as follows.
+     * <pre>{@code
+     * SubjectPublicKeyInfo  ::=  SEQUENCE  {
+     *   algorithm            AlgorithmIdentifier,
+     *   subjectPublicKey     BIT STRING  }
+     *
+     * AlgorithmIdentifier  ::=  SEQUENCE  {
+     *   algorithm               OBJECT IDENTIFIER,
+     *   parameters              ANY DEFINED BY algorithm OPTIONAL  }
+     *                              -- contains a value of the type
+     *                              -- registered for use with the
+     *                              -- algorithm object identifier value
+     * }</pre>
+     * <p>
+     * Note that the byte array supplied here is cloned to protect against
+     * subsequent modifications.
+     *
+     * @param key a byte array containing the subject public key in ASN.1 DER
+     *            form (or {@code null})
+     * @throws IOException if an encoding error occurs (incorrect form for
+     * subject public key)
+     * @see #getSubjectPublicKey
+     */
+    public void setSubjectPublicKey(byte[] key) throws IOException {
+        if (key == null) {
+            subjectPublicKey = null;
+            subjectPublicKeyBytes = null;
+        } else {
+            subjectPublicKeyBytes = key.clone();
+            subjectPublicKey = X509Key.parse(new DerValue(subjectPublicKeyBytes));
+        }
+    }
+
+    /**
+     * Sets the keyUsage criterion. The {@code X509Certificate}
+     * must allow the specified keyUsage values. If {@code null}, no
+     * keyUsage check will be done. Note that an {@code X509Certificate}
+     * that has no keyUsage extension implicitly allows all keyUsage values.
+     * <p>
+     * Note that the boolean array supplied here is cloned to protect against
+     * subsequent modifications.
+     *
+     * @param keyUsage a boolean array in the same format as the boolean
+     *                 array returned by
+     * {@link X509Certificate#getKeyUsage() X509Certificate.getKeyUsage()}.
+     *                 Or {@code null}.
+     * @see #getKeyUsage
+     */
+    public void setKeyUsage(boolean[] keyUsage) {
+        if (keyUsage == null) {
+            this.keyUsage = null;
+        } else {
+            this.keyUsage = keyUsage.clone();
+        }
+    }
+
+    /**
+     * Sets the extendedKeyUsage criterion. The {@code X509Certificate}
+     * must allow the specified key purposes in its extended key usage
+     * extension. If {@code keyPurposeSet} is empty or {@code null},
+     * no extendedKeyUsage check will be done. Note that an
+     * {@code X509Certificate} that has no extendedKeyUsage extension
+     * implicitly allows all key purposes.
+     * <p>
+     * Note that the {@code Set} is cloned to protect against
+     * subsequent modifications.
+     *
+     * @param keyPurposeSet a {@code Set} of key purpose OIDs in string
+     * format (or {@code null}). Each OID is represented by a set of
+     * nonnegative integers separated by periods.
+     * @throws IOException if the OID is invalid, such as
+     * the first component being not 0, 1 or 2 or the second component
+     * being greater than 39.
+     * @see #getExtendedKeyUsage
+     */
+    public void setExtendedKeyUsage(Set<String> keyPurposeSet) throws IOException {
+        if ((keyPurposeSet == null) || keyPurposeSet.isEmpty()) {
+            this.keyPurposeSet = null;
+            keyPurposeOIDSet = null;
+        } else {
+            this.keyPurposeSet =
+                Collections.unmodifiableSet(new HashSet<String>(keyPurposeSet));
+            keyPurposeOIDSet = new HashSet<ObjectIdentifier>();
+            for (String s : this.keyPurposeSet) {
+                keyPurposeOIDSet.add(new ObjectIdentifier(s));
+            }
+        }
+    }
+
+    /**
+     * Enables/disables matching all of the subjectAlternativeNames
+     * specified in the {@link #setSubjectAlternativeNames
+     * setSubjectAlternativeNames} or {@link #addSubjectAlternativeName
+     * addSubjectAlternativeName} methods. If enabled,
+     * the {@code X509Certificate} must contain all of the
+     * specified subject alternative names. If disabled, the
+     * {@code X509Certificate} must contain at least one of the
+     * specified subject alternative names.
+     *
+     * <p>The matchAllNames flag is {@code true} by default.
+     *
+     * @param matchAllNames if {@code true}, the flag is enabled;
+     * if {@code false}, the flag is disabled.
+     * @see #getMatchAllSubjectAltNames
+     */
+    public void setMatchAllSubjectAltNames(boolean matchAllNames) {
+        this.matchAllSubjectAltNames = matchAllNames;
+    }
+
+    /**
+     * Sets the subjectAlternativeNames criterion. The
+     * {@code X509Certificate} must contain all or at least one of the
+     * specified subjectAlternativeNames, depending on the value of
+     * the matchAllNames flag (see {@link #setMatchAllSubjectAltNames
+     * setMatchAllSubjectAltNames}).
+     * <p>
+     * This method allows the caller to specify, with a single method call,
+     * the complete set of subject alternative names for the
+     * subjectAlternativeNames criterion. The specified value replaces
+     * the previous value for the subjectAlternativeNames criterion.
+     * <p>
+     * The {@code names} parameter (if not {@code null}) is a
+     * {@code Collection} with one
+     * entry for each name to be included in the subject alternative name
+     * criterion. Each entry is a {@code List} whose first entry is an
+     * {@code Integer} (the name type, 0-8) and whose second
+     * entry is a {@code String} or a byte array (the name, in
+     * string or ASN.1 DER encoded form, respectively).
+     * There can be multiple names of the same type. If {@code null}
+     * is supplied as the value for this argument, no
+     * subjectAlternativeNames check will be performed.
+     * <p>
+     * Each subject alternative name in the {@code Collection}
+     * may be specified either as a {@code String} or as an ASN.1 encoded
+     * byte array. For more details about the formats used, see
+     * {@link #addSubjectAlternativeName(int type, String name)
+     * addSubjectAlternativeName(int type, String name)} and
+     * {@link #addSubjectAlternativeName(int type, byte [] name)
+     * addSubjectAlternativeName(int type, byte [] name)}.
+     * <p>
+     * <strong>Note:</strong> for distinguished names, specify the byte
+     * array form instead of the String form. See the note in
+     * {@link #addSubjectAlternativeName(int, String)} for more information.
+     * <p>
+     * Note that the {@code names} parameter can contain duplicate
+     * names (same name and name type), but they may be removed from the
+     * {@code Collection} of names returned by the
+     * {@link #getSubjectAlternativeNames getSubjectAlternativeNames} method.
+     * <p>
+     * Note that a deep copy is performed on the {@code Collection} to
+     * protect against subsequent modifications.
+     *
+     * @param names a {@code Collection} of names (or {@code null})
+     * @throws IOException if a parsing error occurs
+     * @see #getSubjectAlternativeNames
+     */
+    public void setSubjectAlternativeNames(Collection<List<?>> names)
+            throws IOException {
+        if (names == null) {
+            subjectAlternativeNames = null;
+            subjectAlternativeGeneralNames = null;
+        } else {
+            if (names.isEmpty()) {
+                subjectAlternativeNames = null;
+                subjectAlternativeGeneralNames = null;
+                return;
+            }
+            Set<List<?>> tempNames = cloneAndCheckNames(names);
+            // Ensure that we either set both of these or neither
+            subjectAlternativeGeneralNames = parseNames(tempNames);
+            subjectAlternativeNames = tempNames;
+        }
+    }
+
+    /**
+     * Adds a name to the subjectAlternativeNames criterion. The
+     * {@code X509Certificate} must contain all or at least one
+     * of the specified subjectAlternativeNames, depending on the value of
+     * the matchAllNames flag (see {@link #setMatchAllSubjectAltNames
+     * setMatchAllSubjectAltNames}).
+     * <p>
+     * This method allows the caller to add a name to the set of subject
+     * alternative names.
+     * The specified name is added to any previous value for the
+     * subjectAlternativeNames criterion. If the specified name is a
+     * duplicate, it may be ignored.
+     * <p>
+     * The name is provided in string format.
+     * <a href="http://www.ietf.org/rfc/rfc822.txt">RFC 822</a>, DNS, and URI
+     * names use the well-established string formats for those types (subject to
+     * the restrictions included in RFC 3280). IPv4 address names are
+     * supplied using dotted quad notation. OID address names are represented
+     * as a series of nonnegative integers separated by periods. And
+     * directory names (distinguished names) are supplied in RFC 2253 format.
+     * No standard string format is defined for otherNames, X.400 names,
+     * EDI party names, IPv6 address names, or any other type of names. They
+     * should be specified using the
+     * {@link #addSubjectAlternativeName(int type, byte [] name)
+     * addSubjectAlternativeName(int type, byte [] name)}
+     * method.
+     * <p>
+     * <strong>Note:</strong> for distinguished names, use
+     * {@linkplain #addSubjectAlternativeName(int, byte[])} instead.
+     * This method should not be relied on as it can fail to match some
+     * certificates because of a loss of encoding information in the RFC 2253
+     * String form of some distinguished names.
+     *
+     * @param type the name type (0-8, as specified in
+     *             RFC 3280, section 4.2.1.7)
+     * @param name the name in string form (not {@code null})
+     * @throws IOException if a parsing error occurs
+     */
+    public void addSubjectAlternativeName(int type, String name)
+            throws IOException {
+        addSubjectAlternativeNameInternal(type, name);
+    }
+
+    /**
+     * Adds a name to the subjectAlternativeNames criterion. The
+     * {@code X509Certificate} must contain all or at least one
+     * of the specified subjectAlternativeNames, depending on the value of
+     * the matchAllNames flag (see {@link #setMatchAllSubjectAltNames
+     * setMatchAllSubjectAltNames}).
+     * <p>
+     * This method allows the caller to add a name to the set of subject
+     * alternative names.
+     * The specified name is added to any previous value for the
+     * subjectAlternativeNames criterion. If the specified name is a
+     * duplicate, it may be ignored.
+     * <p>
+     * The name is provided as a byte array. This byte array should contain
+     * the DER encoded name, as it would appear in the GeneralName structure
+     * defined in RFC 3280 and X.509. The encoded byte array should only contain
+     * the encoded value of the name, and should not include the tag associated
+     * with the name in the GeneralName structure. The ASN.1 definition of this
+     * structure appears below.
+     * <pre>{@code
+     *  GeneralName ::= CHOICE {
+     *       otherName                       [0]     OtherName,
+     *       rfc822Name                      [1]     IA5String,
+     *       dNSName                         [2]     IA5String,
+     *       x400Address                     [3]     ORAddress,
+     *       directoryName                   [4]     Name,
+     *       ediPartyName                    [5]     EDIPartyName,
+     *       uniformResourceIdentifier       [6]     IA5String,
+     *       iPAddress                       [7]     OCTET STRING,
+     *       registeredID                    [8]     OBJECT IDENTIFIER}
+     * }</pre>
+     * <p>
+     * Note that the byte array supplied here is cloned to protect against
+     * subsequent modifications.
+     *
+     * @param type the name type (0-8, as listed above)
+     * @param name a byte array containing the name in ASN.1 DER encoded form
+     * @throws IOException if a parsing error occurs
+     */
+    public void addSubjectAlternativeName(int type, byte[] name)
+            throws IOException {
+        // clone because byte arrays are modifiable
+        addSubjectAlternativeNameInternal(type, name.clone());
+    }
+
+    /**
+     * A private method that adds a name (String or byte array) to the
+     * subjectAlternativeNames criterion. The {@code X509Certificate}
+     * must contain the specified subjectAlternativeName.
+     *
+     * @param type the name type (0-8, as specified in
+     *             RFC 3280, section 4.2.1.7)
+     * @param name the name in string or byte array form
+     * @throws IOException if a parsing error occurs
+     */
+    private void addSubjectAlternativeNameInternal(int type, Object name)
+            throws IOException {
+        // First, ensure that the name parses
+        GeneralNameInterface tempName = makeGeneralNameInterface(type, name);
+        if (subjectAlternativeNames == null) {
+            subjectAlternativeNames = new HashSet<List<?>>();
+        }
+        if (subjectAlternativeGeneralNames == null) {
+            subjectAlternativeGeneralNames = new HashSet<GeneralNameInterface>();
+        }
+        List<Object> list = new ArrayList<Object>(2);
+        list.add(Integer.valueOf(type));
+        list.add(name);
+        subjectAlternativeNames.add(list);
+        subjectAlternativeGeneralNames.add(tempName);
+    }
+
+    /**
+     * Parse an argument of the form passed to setSubjectAlternativeNames,
+     * returning a {@code Collection} of
+     * {@code GeneralNameInterface}s.
+     * Throw an IllegalArgumentException or a ClassCastException
+     * if the argument is malformed.
+     *
+     * @param names a Collection with one entry per name.
+     *              Each entry is a {@code List} whose first entry
+     *              is an Integer (the name type, 0-8) and whose second
+     *              entry is a String or a byte array (the name, in
+     *              string or ASN.1 DER encoded form, respectively).
+     *              There can be multiple names of the same type. Null is
+     *              not an acceptable value.
+     * @return a Set of {@code GeneralNameInterface}s
+     * @throws IOException if a parsing error occurs
+     */
+    private static Set<GeneralNameInterface> parseNames(Collection<List<?>> names) throws IOException {
+        Set<GeneralNameInterface> genNames = new HashSet<GeneralNameInterface>();
+        for (List<?> nameList : names) {
+            if (nameList.size() != 2) {
+                throw new IOException("name list size not 2");
+            }
+            Object o =  nameList.get(0);
+            if (!(o instanceof Integer)) {
+                throw new IOException("expected an Integer");
+            }
+            int nameType = ((Integer)o).intValue();
+            o = nameList.get(1);
+            genNames.add(makeGeneralNameInterface(nameType, o));
+        }
+
+        return genNames;
+    }
+
+    /**
+     * Compare for equality two objects of the form passed to
+     * setSubjectAlternativeNames (or X509CRLSelector.setIssuerNames).
+     * Throw an {@code IllegalArgumentException} or a
+     * {@code ClassCastException} if one of the objects is malformed.
+     *
+     * @param object1 a Collection containing the first object to compare
+     * @param object2 a Collection containing the second object to compare
+     * @return true if the objects are equal, false otherwise
+     */
+    static boolean equalNames(Collection<?> object1, Collection<?> object2) {
+        if ((object1 == null) || (object2 == null)) {
+            return object1 == object2;
+        }
+        return object1.equals(object2);
+    }
+
+    /**
+     * Make a {@code GeneralNameInterface} out of a name type (0-8) and an
+     * Object that may be a byte array holding the ASN.1 DER encoded
+     * name or a String form of the name.  Except for X.509
+     * Distinguished Names, the String form of the name must not be the
+     * result from calling toString on an existing GeneralNameInterface
+     * implementing class.  The output of toString is not compatible
+     * with the String constructors for names other than Distinguished
+     * Names.
+     *
+     * @param type name type (0-8)
+     * @param name name as ASN.1 Der-encoded byte array or String
+     * @return a GeneralNameInterface name
+     * @throws IOException if a parsing error occurs
+     */
+    static GeneralNameInterface makeGeneralNameInterface(int type, Object name)
+            throws IOException {
+        GeneralNameInterface result;
+        if (debug != null) {
+            debug.println("X509CertSelector.makeGeneralNameInterface("
+                + type + ")...");
+        }
+
+        if (name instanceof String) {
+            if (debug != null) {
+                debug.println("X509CertSelector.makeGeneralNameInterface() "
+                    + "name is String: " + name);
+            }
+            switch (type) {
+            case NAME_RFC822:
+                result = new RFC822Name((String)name);
+                break;
+            case NAME_DNS:
+                result = new DNSName((String)name);
+                break;
+            case NAME_DIRECTORY:
+                result = new X500Name((String)name);
+                break;
+            case NAME_URI:
+                result = new URIName((String)name);
+                break;
+            case NAME_IP:
+                result = new IPAddressName((String)name);
+                break;
+            case NAME_OID:
+                result = new OIDName((String)name);
+                break;
+            default:
+                throw new IOException("unable to parse String names of type "
+                                      + type);
+            }
+            if (debug != null) {
+                debug.println("X509CertSelector.makeGeneralNameInterface() "
+                    + "result: " + result.toString());
+            }
+        } else if (name instanceof byte[]) {
+            DerValue val = new DerValue((byte[]) name);
+            if (debug != null) {
+                debug.println
+                    ("X509CertSelector.makeGeneralNameInterface() is byte[]");
+            }
+
+            switch (type) {
+            case NAME_ANY:
+                result = new OtherName(val);
+                break;
+            case NAME_RFC822:
+                result = new RFC822Name(val);
+                break;
+            case NAME_DNS:
+                result = new DNSName(val);
+                break;
+            case NAME_X400:
+                result = new X400Address(val);
+                break;
+            case NAME_DIRECTORY:
+                result = new X500Name(val);
+                break;
+            case NAME_EDI:
+                result = new EDIPartyName(val);
+                break;
+            case NAME_URI:
+                result = new URIName(val);
+                break;
+            case NAME_IP:
+                result = new IPAddressName(val);
+                break;
+            case NAME_OID:
+                result = new OIDName(val);
+                break;
+            default:
+                throw new IOException("unable to parse byte array names of "
+                    + "type " + type);
+            }
+            if (debug != null) {
+                debug.println("X509CertSelector.makeGeneralNameInterface() result: "
+                    + result.toString());
+            }
+        } else {
+            if (debug != null) {
+                debug.println("X509CertSelector.makeGeneralName() input name "
+                    + "not String or byte array");
+            }
+            throw new IOException("name not String or byte array");
+        }
+        return result;
+    }
+
+
+    /**
+     * Sets the name constraints criterion. The {@code X509Certificate}
+     * must have subject and subject alternative names that
+     * meet the specified name constraints.
+     * <p>
+     * The name constraints are specified as a byte array. This byte array
+     * should contain the DER encoded form of the name constraints, as they
+     * would appear in the NameConstraints structure defined in RFC 3280
+     * and X.509. The ASN.1 definition of this structure appears below.
+     *
+     * <pre>{@code
+     *  NameConstraints ::= SEQUENCE {
+     *       permittedSubtrees       [0]     GeneralSubtrees OPTIONAL,
+     *       excludedSubtrees        [1]     GeneralSubtrees OPTIONAL }
+     *
+     *  GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
+     *
+     *  GeneralSubtree ::= SEQUENCE {
+     *       base                    GeneralName,
+     *       minimum         [0]     BaseDistance DEFAULT 0,
+     *       maximum         [1]     BaseDistance OPTIONAL }
+     *
+     *  BaseDistance ::= INTEGER (0..MAX)
+     *
+     *  GeneralName ::= CHOICE {
+     *       otherName                       [0]     OtherName,
+     *       rfc822Name                      [1]     IA5String,
+     *       dNSName                         [2]     IA5String,
+     *       x400Address                     [3]     ORAddress,
+     *       directoryName                   [4]     Name,
+     *       ediPartyName                    [5]     EDIPartyName,
+     *       uniformResourceIdentifier       [6]     IA5String,
+     *       iPAddress                       [7]     OCTET STRING,
+     *       registeredID                    [8]     OBJECT IDENTIFIER}
+     * }</pre>
+     * <p>
+     * Note that the byte array supplied here is cloned to protect against
+     * subsequent modifications.
+     *
+     * @param bytes a byte array containing the ASN.1 DER encoding of
+     *              a NameConstraints extension to be used for checking
+     *              name constraints. Only the value of the extension is
+     *              included, not the OID or criticality flag. Can be
+     *              {@code null},
+     *              in which case no name constraints check will be performed.
+     * @throws IOException if a parsing error occurs
+     * @see #getNameConstraints
+     */
+    public void setNameConstraints(byte[] bytes) throws IOException {
+        if (bytes == null) {
+            ncBytes = null;
+            nc = null;
+        } else {
+            ncBytes = bytes.clone();
+            nc = new NameConstraintsExtension(FALSE, bytes);
+        }
+    }
+
+    /**
+     * Sets the basic constraints constraint. If the value is greater than or
+     * equal to zero, {@code X509Certificates} must include a
+     * basicConstraints extension with
+     * a pathLen of at least this value. If the value is -2, only end-entity
+     * certificates are accepted. If the value is -1, no check is done.
+     * <p>
+     * This constraint is useful when building a certification path forward
+     * (from the target toward the trust anchor. If a partial path has been
+     * built, any candidate certificate must have a maxPathLen value greater
+     * than or equal to the number of certificates in the partial path.
+     *
+     * @param minMaxPathLen the value for the basic constraints constraint
+     * @throws IllegalArgumentException if the value is less than -2
+     * @see #getBasicConstraints
+     */
+    public void setBasicConstraints(int minMaxPathLen) {
+        if (minMaxPathLen < -2) {
+            throw new IllegalArgumentException("basic constraints less than -2");
+        }
+        basicConstraints = minMaxPathLen;
+    }
+
+    /**
+     * Sets the policy constraint. The {@code X509Certificate} must
+     * include at least one of the specified policies in its certificate
+     * policies extension. If {@code certPolicySet} is empty, then the
+     * {@code X509Certificate} must include at least some specified policy
+     * in its certificate policies extension. If {@code certPolicySet} is
+     * {@code null}, no policy check will be performed.
+     * <p>
+     * Note that the {@code Set} is cloned to protect against
+     * subsequent modifications.
+     *
+     * @param certPolicySet a {@code Set} of certificate policy OIDs in
+     *                      string format (or {@code null}). Each OID is
+     *                      represented by a set of nonnegative integers
+     *                    separated by periods.
+     * @throws IOException if a parsing error occurs on the OID such as
+     * the first component is not 0, 1 or 2 or the second component is
+     * greater than 39.
+     * @see #getPolicy
+     */
+    public void setPolicy(Set<String> certPolicySet) throws IOException {
+        if (certPolicySet == null) {
+            policySet = null;
+            policy = null;
+        } else {
+            // Snapshot set and parse it
+            Set<String> tempSet = Collections.unmodifiableSet
+                                        (new HashSet<String>(certPolicySet));
+            /* Convert to Vector of ObjectIdentifiers */
+            Iterator<String> i = tempSet.iterator();
+            Vector<CertificatePolicyId> polIdVector = new Vector<CertificatePolicyId>();
+            while (i.hasNext()) {
+                Object o = i.next();
+                if (!(o instanceof String)) {
+                    throw new IOException("non String in certPolicySet");
+                }
+                polIdVector.add(new CertificatePolicyId(new ObjectIdentifier(
+                  (String)o)));
+            }
+            // If everything went OK, make the changes
+            policySet = tempSet;
+            policy = new CertificatePolicySet(polIdVector);
+        }
+    }
+
+    /**
+     * Sets the pathToNames criterion. The {@code X509Certificate} must
+     * not include name constraints that would prohibit building a
+     * path to the specified names.
+     * <p>
+     * This method allows the caller to specify, with a single method call,
+     * the complete set of names which the {@code X509Certificates}'s
+     * name constraints must permit. The specified value replaces
+     * the previous value for the pathToNames criterion.
+     * <p>
+     * This constraint is useful when building a certification path forward
+     * (from the target toward the trust anchor. If a partial path has been
+     * built, any candidate certificate must not include name constraints that
+     * would prohibit building a path to any of the names in the partial path.
+     * <p>
+     * The {@code names} parameter (if not {@code null}) is a
+     * {@code Collection} with one
+     * entry for each name to be included in the pathToNames
+     * criterion. Each entry is a {@code List} whose first entry is an
+     * {@code Integer} (the name type, 0-8) and whose second
+     * entry is a {@code String} or a byte array (the name, in
+     * string or ASN.1 DER encoded form, respectively).
+     * There can be multiple names of the same type. If {@code null}
+     * is supplied as the value for this argument, no
+     * pathToNames check will be performed.
+     * <p>
+     * Each name in the {@code Collection}
+     * may be specified either as a {@code String} or as an ASN.1 encoded
+     * byte array. For more details about the formats used, see
+     * {@link #addPathToName(int type, String name)
+     * addPathToName(int type, String name)} and
+     * {@link #addPathToName(int type, byte [] name)
+     * addPathToName(int type, byte [] name)}.
+     * <p>
+     * <strong>Note:</strong> for distinguished names, specify the byte
+     * array form instead of the String form. See the note in
+     * {@link #addPathToName(int, String)} for more information.
+     * <p>
+     * Note that the {@code names} parameter can contain duplicate
+     * names (same name and name type), but they may be removed from the
+     * {@code Collection} of names returned by the
+     * {@link #getPathToNames getPathToNames} method.
+     * <p>
+     * Note that a deep copy is performed on the {@code Collection} to
+     * protect against subsequent modifications.
+     *
+     * @param names a {@code Collection} with one entry per name
+     *              (or {@code null})
+     * @throws IOException if a parsing error occurs
+     * @see #getPathToNames
+     */
+    public void setPathToNames(Collection<List<?>> names) throws IOException {
+        if ((names == null) || names.isEmpty()) {
+            pathToNames = null;
+            pathToGeneralNames = null;
+        } else {
+            Set<List<?>> tempNames = cloneAndCheckNames(names);
+            pathToGeneralNames = parseNames(tempNames);
+            // Ensure that we either set both of these or neither
+            pathToNames = tempNames;
+        }
+    }
+
+    // called from CertPathHelper
+    void setPathToNamesInternal(Set<GeneralNameInterface> names) {
+        // set names to non-null dummy value
+        // this breaks getPathToNames()
+        pathToNames = Collections.<List<?>>emptySet();
+        pathToGeneralNames = names;
+    }
+
+    /**
+     * Adds a name to the pathToNames criterion. The {@code X509Certificate}
+     * must not include name constraints that would prohibit building a
+     * path to the specified name.
+     * <p>
+     * This method allows the caller to add a name to the set of names which
+     * the {@code X509Certificates}'s name constraints must permit.
+     * The specified name is added to any previous value for the
+     * pathToNames criterion.  If the name is a duplicate, it may be ignored.
+     * <p>
+     * The name is provided in string format. RFC 822, DNS, and URI names
+     * use the well-established string formats for those types (subject to
+     * the restrictions included in RFC 3280). IPv4 address names are
+     * supplied using dotted quad notation. OID address names are represented
+     * as a series of nonnegative integers separated by periods. And
+     * directory names (distinguished names) are supplied in RFC 2253 format.
+     * No standard string format is defined for otherNames, X.400 names,
+     * EDI party names, IPv6 address names, or any other type of names. They
+     * should be specified using the
+     * {@link #addPathToName(int type, byte [] name)
+     * addPathToName(int type, byte [] name)} method.
+     * <p>
+     * <strong>Note:</strong> for distinguished names, use
+     * {@linkplain #addPathToName(int, byte[])} instead.
+     * This method should not be relied on as it can fail to match some
+     * certificates because of a loss of encoding information in the RFC 2253
+     * String form of some distinguished names.
+     *
+     * @param type the name type (0-8, as specified in
+     *             RFC 3280, section 4.2.1.7)
+     * @param name the name in string form
+     * @throws IOException if a parsing error occurs
+     */
+    public void addPathToName(int type, String name) throws IOException {
+        addPathToNameInternal(type, name);
+    }
+
+    /**
+     * Adds a name to the pathToNames criterion. The {@code X509Certificate}
+     * must not include name constraints that would prohibit building a
+     * path to the specified name.
+     * <p>
+     * This method allows the caller to add a name to the set of names which
+     * the {@code X509Certificates}'s name constraints must permit.
+     * The specified name is added to any previous value for the
+     * pathToNames criterion. If the name is a duplicate, it may be ignored.
+     * <p>
+     * The name is provided as a byte array. This byte array should contain
+     * the DER encoded name, as it would appear in the GeneralName structure
+     * defined in RFC 3280 and X.509. The ASN.1 definition of this structure
+     * appears in the documentation for
+     * {@link #addSubjectAlternativeName(int type, byte [] name)
+     * addSubjectAlternativeName(int type, byte [] name)}.
+     * <p>
+     * Note that the byte array supplied here is cloned to protect against
+     * subsequent modifications.
+     *
+     * @param type the name type (0-8, as specified in
+     *             RFC 3280, section 4.2.1.7)
+     * @param name a byte array containing the name in ASN.1 DER encoded form
+     * @throws IOException if a parsing error occurs
+     */
+    public void addPathToName(int type, byte [] name) throws IOException {
+        // clone because byte arrays are modifiable
+        addPathToNameInternal(type, name.clone());
+    }
+
+    /**
+     * A private method that adds a name (String or byte array) to the
+     * pathToNames criterion. The {@code X509Certificate} must contain
+     * the specified pathToName.
+     *
+     * @param type the name type (0-8, as specified in
+     *             RFC 3280, section 4.2.1.7)
+     * @param name the name in string or byte array form
+     * @throws IOException if an encoding error occurs (incorrect form for DN)
+     */
+    private void addPathToNameInternal(int type, Object name)
+            throws IOException {
+        // First, ensure that the name parses
+        GeneralNameInterface tempName = makeGeneralNameInterface(type, name);
+        if (pathToGeneralNames == null) {
+            pathToNames = new HashSet<List<?>>();
+            pathToGeneralNames = new HashSet<GeneralNameInterface>();
+        }
+        List<Object> list = new ArrayList<Object>(2);
+        list.add(Integer.valueOf(type));
+        list.add(name);
+        pathToNames.add(list);
+        pathToGeneralNames.add(tempName);
+    }
+
+    /**
+     * Returns the certificateEquals criterion. The specified
+     * {@code X509Certificate} must be equal to the
+     * {@code X509Certificate} passed to the {@code match} method.
+     * If {@code null}, this check is not applied.
+     *
+     * @return the {@code X509Certificate} to match (or {@code null})
+     * @see #setCertificate
+     */
+    public X509Certificate getCertificate() {
+        return x509Cert;
+    }
+
+    /**
+     * Returns the serialNumber criterion. The specified serial number
+     * must match the certificate serial number in the
+     * {@code X509Certificate}. If {@code null}, any certificate
+     * serial number will do.
+     *
+     * @return the certificate serial number to match
+     *                (or {@code null})
+     * @see #setSerialNumber
+     */
+    public BigInteger getSerialNumber() {
+        return serialNumber;
+    }
+
+    /**
+     * Returns the issuer criterion as an {@code X500Principal}. This
+     * distinguished name must match the issuer distinguished name in the
+     * {@code X509Certificate}. If {@code null}, the issuer criterion
+     * is disabled and any issuer distinguished name will do.
+     *
+     * @return the required issuer distinguished name as X500Principal
+     *         (or {@code null})
+     * @since 1.5
+     */
+    public X500Principal getIssuer() {
+        return issuer;
+    }
+
+    /**
+     * <strong>Denigrated</strong>, use {@linkplain #getIssuer()} or
+     * {@linkplain #getIssuerAsBytes()} instead. This method should not be
+     * relied on as it can fail to match some certificates because of a loss of
+     * encoding information in the RFC 2253 String form of some distinguished
+     * names.
+     * <p>
+     * Returns the issuer criterion as a {@code String}. This
+     * distinguished name must match the issuer distinguished name in the
+     * {@code X509Certificate}. If {@code null}, the issuer criterion
+     * is disabled and any issuer distinguished name will do.
+     * <p>
+     * If the value returned is not {@code null}, it is a
+     * distinguished name, in RFC 2253 format.
+     *
+     * @return the required issuer distinguished name in RFC 2253 format
+     *         (or {@code null})
+     */
+    public String getIssuerAsString() {
+        return (issuer == null ? null : issuer.getName());
+    }
+
+    /**
+     * Returns the issuer criterion as a byte array. This distinguished name
+     * must match the issuer distinguished name in the
+     * {@code X509Certificate}. If {@code null}, the issuer criterion
+     * is disabled and any issuer distinguished name will do.
+     * <p>
+     * If the value returned is not {@code null}, it is a byte
+     * array containing a single DER encoded distinguished name, as defined in
+     * X.501. The ASN.1 notation for this structure is supplied in the
+     * documentation for
+     * {@link #setIssuer(byte [] issuerDN) setIssuer(byte [] issuerDN)}.
+     * <p>
+     * Note that the byte array returned is cloned to protect against
+     * subsequent modifications.
+     *
+     * @return a byte array containing the required issuer distinguished name
+     *         in ASN.1 DER format (or {@code null})
+     * @throws IOException if an encoding error occurs
+     */
+    public byte[] getIssuerAsBytes() throws IOException {
+        return (issuer == null ? null: issuer.getEncoded());
+    }
+
+    /**
+     * Returns the subject criterion as an {@code X500Principal}. This
+     * distinguished name must match the subject distinguished name in the
+     * {@code X509Certificate}. If {@code null}, the subject criterion
+     * is disabled and any subject distinguished name will do.
+     *
+     * @return the required subject distinguished name as X500Principal
+     *         (or {@code null})
+     * @since 1.5
+     */
+    public X500Principal getSubject() {
+        return subject;
+    }
+
+    /**
+     * <strong>Denigrated</strong>, use {@linkplain #getSubject()} or
+     * {@linkplain #getSubjectAsBytes()} instead. This method should not be
+     * relied on as it can fail to match some certificates because of a loss of
+     * encoding information in the RFC 2253 String form of some distinguished
+     * names.
+     * <p>
+     * Returns the subject criterion as a {@code String}. This
+     * distinguished name must match the subject distinguished name in the
+     * {@code X509Certificate}. If {@code null}, the subject criterion
+     * is disabled and any subject distinguished name will do.
+     * <p>
+     * If the value returned is not {@code null}, it is a
+     * distinguished name, in RFC 2253 format.
+     *
+     * @return the required subject distinguished name in RFC 2253 format
+     *         (or {@code null})
+     */
+    public String getSubjectAsString() {
+        return (subject == null ? null : subject.getName());
+    }
+
+    /**
+     * Returns the subject criterion as a byte array. This distinguished name
+     * must match the subject distinguished name in the
+     * {@code X509Certificate}. If {@code null}, the subject criterion
+     * is disabled and any subject distinguished name will do.
+     * <p>
+     * If the value returned is not {@code null}, it is a byte
+     * array containing a single DER encoded distinguished name, as defined in
+     * X.501. The ASN.1 notation for this structure is supplied in the
+     * documentation for
+     * {@link #setSubject(byte [] subjectDN) setSubject(byte [] subjectDN)}.
+     * <p>
+     * Note that the byte array returned is cloned to protect against
+     * subsequent modifications.
+     *
+     * @return a byte array containing the required subject distinguished name
+     *         in ASN.1 DER format (or {@code null})
+     * @throws IOException if an encoding error occurs
+     */
+    public byte[] getSubjectAsBytes() throws IOException {
+        return (subject == null ? null : subject.getEncoded());
+    }
+
+    /**
+     * Returns the subjectKeyIdentifier criterion. The
+     * {@code X509Certificate} must contain a SubjectKeyIdentifier
+     * extension with the specified value. If {@code null}, no
+     * subjectKeyIdentifier check will be done.
+     * <p>
+     * Note that the byte array returned is cloned to protect against
+     * subsequent modifications.
+     *
+     * @return the key identifier (or {@code null})
+     * @see #setSubjectKeyIdentifier
+     */
+    public byte[] getSubjectKeyIdentifier() {
+        if (subjectKeyID == null) {
+            return null;
+        }
+        return subjectKeyID.clone();
+    }
+
+    /**
+     * Returns the authorityKeyIdentifier criterion. The
+     * {@code X509Certificate} must contain a AuthorityKeyIdentifier
+     * extension with the specified value. If {@code null}, no
+     * authorityKeyIdentifier check will be done.
+     * <p>
+     * Note that the byte array returned is cloned to protect against
+     * subsequent modifications.
+     *
+     * @return the key identifier (or {@code null})
+     * @see #setAuthorityKeyIdentifier
+     */
+    public byte[] getAuthorityKeyIdentifier() {
+        if (authorityKeyID == null) {
+          return null;
+        }
+        return authorityKeyID.clone();
+    }
+
+    /**
+     * Returns the certificateValid criterion. The specified date must fall
+     * within the certificate validity period for the
+     * {@code X509Certificate}. If {@code null}, no certificateValid
+     * check will be done.
+     * <p>
+     * Note that the {@code Date} returned is cloned to protect against
+     * subsequent modifications.
+     *
+     * @return the {@code Date} to check (or {@code null})
+     * @see #setCertificateValid
+     */
+    public Date getCertificateValid() {
+        if (certificateValid == null) {
+            return null;
+        }
+        return (Date)certificateValid.clone();
+    }
+
+    /**
+     * Returns the privateKeyValid criterion. The specified date must fall
+     * within the private key validity period for the
+     * {@code X509Certificate}. If {@code null}, no privateKeyValid
+     * check will be done.
+     * <p>
+     * Note that the {@code Date} returned is cloned to protect against
+     * subsequent modifications.
+     *
+     * @return the {@code Date} to check (or {@code null})
+     * @see #setPrivateKeyValid
+     */
+    public Date getPrivateKeyValid() {
+        if (privateKeyValid == null) {
+            return null;
+        }
+        return (Date)privateKeyValid.clone();
+    }
+
+    /**
+     * Returns the subjectPublicKeyAlgID criterion. The
+     * {@code X509Certificate} must contain a subject public key
+     * with the specified algorithm. If {@code null}, no
+     * subjectPublicKeyAlgID check will be done.
+     *
+     * @return the object identifier (OID) of the signature algorithm to check
+     *         for (or {@code null}). An OID is represented by a set of
+     *         nonnegative integers separated by periods.
+     * @see #setSubjectPublicKeyAlgID
+     */
+    public String getSubjectPublicKeyAlgID() {
+        if (subjectPublicKeyAlgID == null) {
+            return null;
+        }
+        return subjectPublicKeyAlgID.toString();
+    }
+
+    /**
+     * Returns the subjectPublicKey criterion. The
+     * {@code X509Certificate} must contain the specified subject
+     * public key. If {@code null}, no subjectPublicKey check will be done.
+     *
+     * @return the subject public key to check for (or {@code null})
+     * @see #setSubjectPublicKey
+     */
+    public PublicKey getSubjectPublicKey() {
+        return subjectPublicKey;
+    }
+
+    /**
+     * Returns the keyUsage criterion. The {@code X509Certificate}
+     * must allow the specified keyUsage values. If null, no keyUsage
+     * check will be done.
+     * <p>
+     * Note that the boolean array returned is cloned to protect against
+     * subsequent modifications.
+     *
+     * @return a boolean array in the same format as the boolean
+     *                 array returned by
+     * {@link X509Certificate#getKeyUsage() X509Certificate.getKeyUsage()}.
+     *                 Or {@code null}.
+     * @see #setKeyUsage
+     */
+    public boolean[] getKeyUsage() {
+        if (keyUsage == null) {
+            return null;
+        }
+        return keyUsage.clone();
+    }
+
+    /**
+     * Returns the extendedKeyUsage criterion. The {@code X509Certificate}
+     * must allow the specified key purposes in its extended key usage
+     * extension. If the {@code keyPurposeSet} returned is empty or
+     * {@code null}, no extendedKeyUsage check will be done. Note that an
+     * {@code X509Certificate} that has no extendedKeyUsage extension
+     * implicitly allows all key purposes.
+     *
+     * @return an immutable {@code Set} of key purpose OIDs in string
+     * format (or {@code null})
+     * @see #setExtendedKeyUsage
+     */
+    public Set<String> getExtendedKeyUsage() {
+        return keyPurposeSet;
+    }
+
+    /**
+     * Indicates if the {@code X509Certificate} must contain all
+     * or at least one of the subjectAlternativeNames
+     * specified in the {@link #setSubjectAlternativeNames
+     * setSubjectAlternativeNames} or {@link #addSubjectAlternativeName
+     * addSubjectAlternativeName} methods. If {@code true},
+     * the {@code X509Certificate} must contain all of the
+     * specified subject alternative names. If {@code false}, the
+     * {@code X509Certificate} must contain at least one of the
+     * specified subject alternative names.
+     *
+     * @return {@code true} if the flag is enabled;
+     * {@code false} if the flag is disabled. The flag is
+     * {@code true} by default.
+     * @see #setMatchAllSubjectAltNames
+     */
+    public boolean getMatchAllSubjectAltNames() {
+        return matchAllSubjectAltNames;
+    }
+
+    /**
+     * Returns a copy of the subjectAlternativeNames criterion.
+     * The {@code X509Certificate} must contain all or at least one
+     * of the specified subjectAlternativeNames, depending on the value
+     * of the matchAllNames flag (see {@link #getMatchAllSubjectAltNames
+     * getMatchAllSubjectAltNames}). If the value returned is
+     * {@code null}, no subjectAlternativeNames check will be performed.
+     * <p>
+     * If the value returned is not {@code null}, it is a
+     * {@code Collection} with
+     * one entry for each name to be included in the subject alternative name
+     * criterion. Each entry is a {@code List} whose first entry is an
+     * {@code Integer} (the name type, 0-8) and whose second
+     * entry is a {@code String} or a byte array (the name, in
+     * string or ASN.1 DER encoded form, respectively).
+     * There can be multiple names of the same type.  Note that the
+     * {@code Collection} returned may contain duplicate names (same name
+     * and name type).
+     * <p>
+     * Each subject alternative name in the {@code Collection}
+     * may be specified either as a {@code String} or as an ASN.1 encoded
+     * byte array. For more details about the formats used, see
+     * {@link #addSubjectAlternativeName(int type, String name)
+     * addSubjectAlternativeName(int type, String name)} and
+     * {@link #addSubjectAlternativeName(int type, byte [] name)
+     * addSubjectAlternativeName(int type, byte [] name)}.
+     * <p>
+     * Note that a deep copy is performed on the {@code Collection} to
+     * protect against subsequent modifications.
+     *
+     * @return a {@code Collection} of names (or {@code null})
+     * @see #setSubjectAlternativeNames
+     */
+    public Collection<List<?>> getSubjectAlternativeNames() {
+        if (subjectAlternativeNames == null) {
+            return null;
+        }
+        return cloneNames(subjectAlternativeNames);
+    }
+
+    /**
+     * Clone an object of the form passed to
+     * setSubjectAlternativeNames and setPathToNames.
+     * Throw a {@code RuntimeException} if the argument is malformed.
+     * <p>
+     * This method wraps cloneAndCheckNames, changing any
+     * {@code IOException} into a {@code RuntimeException}. This
+     * method should be used when the object being
+     * cloned has already been checked, so there should never be any exceptions.
+     *
+     * @param names a {@code Collection} with one entry per name.
+     *              Each entry is a {@code List} whose first entry
+     *              is an Integer (the name type, 0-8) and whose second
+     *              entry is a String or a byte array (the name, in
+     *              string or ASN.1 DER encoded form, respectively).
+     *              There can be multiple names of the same type. Null
+     *              is not an acceptable value.
+     * @return a deep copy of the specified {@code Collection}
+     * @throws RuntimeException if a parsing error occurs
+     */
+    private static Set<List<?>> cloneNames(Collection<List<?>> names) {
+        try {
+            return cloneAndCheckNames(names);
+        } catch (IOException e) {
+            throw new RuntimeException("cloneNames encountered IOException: " +
+                                       e.getMessage());
+        }
+    }
+
+    /**
+     * Clone and check an argument of the form passed to
+     * setSubjectAlternativeNames and setPathToNames.
+     * Throw an {@code IOException} if the argument is malformed.
+     *
+     * @param names a {@code Collection} with one entry per name.
+     *              Each entry is a {@code List} whose first entry
+     *              is an Integer (the name type, 0-8) and whose second
+     *              entry is a String or a byte array (the name, in
+     *              string or ASN.1 DER encoded form, respectively).
+     *              There can be multiple names of the same type.
+     *              {@code null} is not an acceptable value.
+     * @return a deep copy of the specified {@code Collection}
+     * @throws IOException if a parsing error occurs
+     */
+    private static Set<List<?>> cloneAndCheckNames(Collection<List<?>> names) throws IOException {
+        // Copy the Lists and Collection
+        Set<List<?>> namesCopy = new HashSet<List<?>>();
+        for (List<?> o : names)
+        {
+            namesCopy.add(new ArrayList<Object>(o));
+        }
+
+        // Check the contents of the Lists and clone any byte arrays
+        for (List<?> list : namesCopy) {
+            @SuppressWarnings("unchecked") // See javadoc for parameter "names".
+            List<Object> nameList = (List<Object>)list;
+            if (nameList.size() != 2) {
+                throw new IOException("name list size not 2");
+            }
+            Object o = nameList.get(0);
+            if (!(o instanceof Integer)) {
+                throw new IOException("expected an Integer");
+            }
+            int nameType = ((Integer)o).intValue();
+            if ((nameType < 0) || (nameType > 8)) {
+                throw new IOException("name type not 0-8");
+            }
+            Object nameObject = nameList.get(1);
+            if (!(nameObject instanceof byte[]) &&
+                !(nameObject instanceof String)) {
+                if (debug != null) {
+                    debug.println("X509CertSelector.cloneAndCheckNames() "
+                        + "name not byte array");
+                }
+                throw new IOException("name not byte array or String");
+            }
+            if (nameObject instanceof byte[]) {
+                nameList.set(1, ((byte[]) nameObject).clone());
+            }
+        }
+        return namesCopy;
+    }
+
+    /**
+     * Returns the name constraints criterion. The {@code X509Certificate}
+     * must have subject and subject alternative names that
+     * meet the specified name constraints.
+     * <p>
+     * The name constraints are returned as a byte array. This byte array
+     * contains the DER encoded form of the name constraints, as they
+     * would appear in the NameConstraints structure defined in RFC 3280
+     * and X.509. The ASN.1 notation for this structure is supplied in the
+     * documentation for
+     * {@link #setNameConstraints(byte [] bytes) setNameConstraints(byte [] bytes)}.
+     * <p>
+     * Note that the byte array returned is cloned to protect against
+     * subsequent modifications.
+     *
+     * @return a byte array containing the ASN.1 DER encoding of
+     *         a NameConstraints extension used for checking name constraints.
+     *         {@code null} if no name constraints check will be performed.
+     * @see #setNameConstraints
+     */
+    public byte[] getNameConstraints() {
+        if (ncBytes == null) {
+            return null;
+        } else {
+            return ncBytes.clone();
+        }
+    }
+
+    /**
+     * Returns the basic constraints constraint. If the value is greater than
+     * or equal to zero, the {@code X509Certificates} must include a
+     * basicConstraints extension with a pathLen of at least this value.
+     * If the value is -2, only end-entity certificates are accepted. If
+     * the value is -1, no basicConstraints check is done.
+     *
+     * @return the value for the basic constraints constraint
+     * @see #setBasicConstraints
+     */
+    public int getBasicConstraints() {
+        return basicConstraints;
+    }
+
+    /**
+     * Returns the policy criterion. The {@code X509Certificate} must
+     * include at least one of the specified policies in its certificate policies
+     * extension. If the {@code Set} returned is empty, then the
+     * {@code X509Certificate} must include at least some specified policy
+     * in its certificate policies extension. If the {@code Set} returned is
+     * {@code null}, no policy check will be performed.
+     *
+     * @return an immutable {@code Set} of certificate policy OIDs in
+     *         string format (or {@code null})
+     * @see #setPolicy
+     */
+    public Set<String> getPolicy() {
+        return policySet;
+    }
+
+    /**
+     * Returns a copy of the pathToNames criterion. The
+     * {@code X509Certificate} must not include name constraints that would
+     * prohibit building a path to the specified names. If the value
+     * returned is {@code null}, no pathToNames check will be performed.
+     * <p>
+     * If the value returned is not {@code null}, it is a
+     * {@code Collection} with one
+     * entry for each name to be included in the pathToNames
+     * criterion. Each entry is a {@code List} whose first entry is an
+     * {@code Integer} (the name type, 0-8) and whose second
+     * entry is a {@code String} or a byte array (the name, in
+     * string or ASN.1 DER encoded form, respectively).
+     * There can be multiple names of the same type. Note that the
+     * {@code Collection} returned may contain duplicate names (same
+     * name and name type).
+     * <p>
+     * Each name in the {@code Collection}
+     * may be specified either as a {@code String} or as an ASN.1 encoded
+     * byte array. For more details about the formats used, see
+     * {@link #addPathToName(int type, String name)
+     * addPathToName(int type, String name)} and
+     * {@link #addPathToName(int type, byte [] name)
+     * addPathToName(int type, byte [] name)}.
+     * <p>
+     * Note that a deep copy is performed on the {@code Collection} to
+     * protect against subsequent modifications.
+     *
+     * @return a {@code Collection} of names (or {@code null})
+     * @see #setPathToNames
+     */
+    public Collection<List<?>> getPathToNames() {
+        if (pathToNames == null) {
+            return null;
+        }
+        return cloneNames(pathToNames);
+    }
+
+    /**
+     * Return a printable representation of the {@code CertSelector}.
+     *
+     * @return a {@code String} describing the contents of the
+     *         {@code CertSelector}
+     */
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append("X509CertSelector: [\n");
+        if (x509Cert != null) {
+            sb.append("  Certificate: " + x509Cert.toString() + "\n");
+        }
+        if (serialNumber != null) {
+            sb.append("  Serial Number: " + serialNumber.toString() + "\n");
+        }
+        if (issuer != null) {
+            sb.append("  Issuer: " + getIssuerAsString() + "\n");
+        }
+        if (subject != null) {
+            sb.append("  Subject: " + getSubjectAsString() + "\n");
+        }
+        sb.append("  matchAllSubjectAltNames flag: "
+                  + String.valueOf(matchAllSubjectAltNames) + "\n");
+        if (subjectAlternativeNames != null) {
+            sb.append("  SubjectAlternativeNames:\n");
+            Iterator<List<?>> i = subjectAlternativeNames.iterator();
+            while (i.hasNext()) {
+                List<?> list = i.next();
+                sb.append("    type " + list.get(0) +
+                          ", name " + list.get(1) + "\n");
+            }
+        }
+        if (subjectKeyID != null) {
+            HexDumpEncoder enc = new HexDumpEncoder();
+            sb.append("  Subject Key Identifier: " +
+                      enc.encodeBuffer(subjectKeyID) + "\n");
+        }
+        if (authorityKeyID != null) {
+            HexDumpEncoder enc = new HexDumpEncoder();
+            sb.append("  Authority Key Identifier: " +
+                      enc.encodeBuffer(authorityKeyID) + "\n");
+        }
+        if (certificateValid != null) {
+            sb.append("  Certificate Valid: " +
+                      certificateValid.toString() + "\n");
+        }
+        if (privateKeyValid != null) {
+            sb.append("  Private Key Valid: " +
+                      privateKeyValid.toString() + "\n");
+        }
+        if (subjectPublicKeyAlgID != null) {
+            sb.append("  Subject Public Key AlgID: " +
+                      subjectPublicKeyAlgID.toString() + "\n");
+        }
+        if (subjectPublicKey != null) {
+            sb.append("  Subject Public Key: " +
+                      subjectPublicKey.toString() + "\n");
+        }
+        if (keyUsage != null) {
+            sb.append("  Key Usage: " + keyUsageToString(keyUsage) + "\n");
+        }
+        if (keyPurposeSet != null) {
+            sb.append("  Extended Key Usage: " +
+                      keyPurposeSet.toString() + "\n");
+        }
+        if (policy != null) {
+            sb.append("  Policy: " + policy.toString() + "\n");
+        }
+        if (pathToGeneralNames != null) {
+            sb.append("  Path to names:\n");
+            Iterator<GeneralNameInterface> i = pathToGeneralNames.iterator();
+            while (i.hasNext()) {
+                sb.append("    " + i.next() + "\n");
+            }
+        }
+        sb.append("]");
+        return sb.toString();
+    }
+
+    // Copied from sun.security.x509.KeyUsageExtension
+    // (without calling the superclass)
+    /**
+     * Returns a printable representation of the KeyUsage.
+     */
+    private static String keyUsageToString(boolean[] k) {
+        String s = "KeyUsage [\n";
+        try {
+            if (k[0]) {
+                s += "  DigitalSignature\n";
+            }
+            if (k[1]) {
+                s += "  Non_repudiation\n";
+            }
+            if (k[2]) {
+                s += "  Key_Encipherment\n";
+            }
+            if (k[3]) {
+                s += "  Data_Encipherment\n";
+            }
+            if (k[4]) {
+                s += "  Key_Agreement\n";
+            }
+            if (k[5]) {
+                s += "  Key_CertSign\n";
+            }
+            if (k[6]) {
+                s += "  Crl_Sign\n";
+            }
+            if (k[7]) {
+                s += "  Encipher_Only\n";
+            }
+            if (k[8]) {
+                s += "  Decipher_Only\n";
+            }
+        } catch (ArrayIndexOutOfBoundsException ex) {}
+
+        s += "]\n";
+
+        return (s);
+    }
+
+    /**
+     * Returns an Extension object given any X509Certificate and extension oid.
+     * Throw an {@code IOException} if the extension byte value is
+     * malformed.
+     *
+     * @param cert a {@code X509Certificate}
+     * @param extId an {@code integer} which specifies the extension index.
+     * Currently, the supported extensions are as follows:
+     * index 0 - PrivateKeyUsageExtension
+     * index 1 - SubjectAlternativeNameExtension
+     * index 2 - NameConstraintsExtension
+     * index 3 - CertificatePoliciesExtension
+     * index 4 - ExtendedKeyUsageExtension
+     * @return an {@code Extension} object whose real type is as specified
+     * by the extension oid.
+     * @throws IOException if cannot construct the {@code Extension}
+     * object with the extension encoding retrieved from the passed in
+     * {@code X509Certificate}.
+     */
+    private static Extension getExtensionObject(X509Certificate cert, int extId)
+            throws IOException {
+        if (cert instanceof X509CertImpl) {
+            X509CertImpl impl = (X509CertImpl)cert;
+            switch (extId) {
+            case PRIVATE_KEY_USAGE_ID:
+                return impl.getPrivateKeyUsageExtension();
+            case SUBJECT_ALT_NAME_ID:
+                return impl.getSubjectAlternativeNameExtension();
+            case NAME_CONSTRAINTS_ID:
+                return impl.getNameConstraintsExtension();
+            case CERT_POLICIES_ID:
+                return impl.getCertificatePoliciesExtension();
+            case EXTENDED_KEY_USAGE_ID:
+                return impl.getExtendedKeyUsageExtension();
+            default:
+                return null;
+            }
+        }
+        byte[] rawExtVal = cert.getExtensionValue(EXTENSION_OIDS[extId]);
+        if (rawExtVal == null) {
+            return null;
+        }
+        DerInputStream in = new DerInputStream(rawExtVal);
+        byte[] encoded = in.getOctetString();
+        switch (extId) {
+        case PRIVATE_KEY_USAGE_ID:
+            try {
+                return new PrivateKeyUsageExtension(FALSE, encoded);
+            } catch (CertificateException ex) {
+                throw new IOException(ex.getMessage());
+            }
+        case SUBJECT_ALT_NAME_ID:
+            return new SubjectAlternativeNameExtension(FALSE, encoded);
+        case NAME_CONSTRAINTS_ID:
+            return new NameConstraintsExtension(FALSE, encoded);
+        case CERT_POLICIES_ID:
+            return new CertificatePoliciesExtension(FALSE, encoded);
+        case EXTENDED_KEY_USAGE_ID:
+            return new ExtendedKeyUsageExtension(FALSE, encoded);
+        default:
+            return null;
+        }
+    }
+
+    /**
+     * Decides whether a {@code Certificate} should be selected.
+     *
+     * @param cert the {@code Certificate} to be checked
+     * @return {@code true} if the {@code Certificate} should be
+     *         selected, {@code false} otherwise
+     */
+    public boolean match(Certificate cert) {
+        if (!(cert instanceof X509Certificate)) {
+            return false;
+        }
+        X509Certificate xcert = (X509Certificate)cert;
+
+        if (debug != null) {
+            debug.println("X509CertSelector.match(SN: "
+                + (xcert.getSerialNumber()).toString(16) + "\n  Issuer: "
+                + xcert.getIssuerDN() + "\n  Subject: " + xcert.getSubjectDN()
+                + ")");
+        }
+
+        /* match on X509Certificate */
+        if (x509Cert != null) {
+            if (!x509Cert.equals(xcert)) {
+                if (debug != null) {
+                    debug.println("X509CertSelector.match: "
+                        + "certs don't match");
+                }
+                return false;
+            }
+        }
+
+        /* match on serial number */
+        if (serialNumber != null) {
+            if (!serialNumber.equals(xcert.getSerialNumber())) {
+                if (debug != null) {
+                    debug.println("X509CertSelector.match: "
+                        + "serial numbers don't match");
+                }
+                return false;
+            }
+        }
+
+        /* match on issuer name */
+        if (issuer != null) {
+            if (!issuer.equals(xcert.getIssuerX500Principal())) {
+                if (debug != null) {
+                    debug.println("X509CertSelector.match: "
+                        + "issuer DNs don't match");
+                }
+                return false;
+            }
+        }
+
+        /* match on subject name */
+        if (subject != null) {
+            if (!subject.equals(xcert.getSubjectX500Principal())) {
+                if (debug != null) {
+                    debug.println("X509CertSelector.match: "
+                        + "subject DNs don't match");
+                }
+                return false;
+            }
+        }
+
+        /* match on certificate validity range */
+        if (certificateValid != null) {
+            try {
+                xcert.checkValidity(certificateValid);
+            } catch (CertificateException e) {
+                if (debug != null) {
+                    debug.println("X509CertSelector.match: "
+                        + "certificate not within validity period");
+                }
+                return false;
+            }
+        }
+
+        /* match on subject public key */
+        if (subjectPublicKeyBytes != null) {
+            byte[] certKey = xcert.getPublicKey().getEncoded();
+            if (!Arrays.equals(subjectPublicKeyBytes, certKey)) {
+                if (debug != null) {
+                    debug.println("X509CertSelector.match: "
+                        + "subject public keys don't match");
+                }
+                return false;
+            }
+        }
+
+        boolean result = matchBasicConstraints(xcert)
+                      && matchKeyUsage(xcert)
+                      && matchExtendedKeyUsage(xcert)
+                      && matchSubjectKeyID(xcert)
+                      && matchAuthorityKeyID(xcert)
+                      && matchPrivateKeyValid(xcert)
+                      && matchSubjectPublicKeyAlgID(xcert)
+                      && matchPolicy(xcert)
+                      && matchSubjectAlternativeNames(xcert)
+                      && matchPathToNames(xcert)
+                      && matchNameConstraints(xcert);
+
+        if (result && (debug != null)) {
+            debug.println("X509CertSelector.match returning: true");
+        }
+        return result;
+    }
+
+    /* match on subject key identifier extension value */
+    private boolean matchSubjectKeyID(X509Certificate xcert) {
+        if (subjectKeyID == null) {
+            return true;
+        }
+        try {
+            byte[] extVal = xcert.getExtensionValue("2.5.29.14");
+            if (extVal == null) {
+                if (debug != null) {
+                    debug.println("X509CertSelector.match: "
+                        + "no subject key ID extension");
+                }
+                return false;
+            }
+            DerInputStream in = new DerInputStream(extVal);
+            byte[] certSubjectKeyID = in.getOctetString();
+            if (certSubjectKeyID == null ||
+                    !Arrays.equals(subjectKeyID, certSubjectKeyID)) {
+                if (debug != null) {
+                    debug.println("X509CertSelector.match: "
+                        + "subject key IDs don't match");
+                }
+                return false;
+            }
+        } catch (IOException ex) {
+            if (debug != null) {
+                debug.println("X509CertSelector.match: "
+                    + "exception in subject key ID check");
+            }
+            return false;
+        }
+        return true;
+    }
+
+    /* match on authority key identifier extension value */
+    private boolean matchAuthorityKeyID(X509Certificate xcert) {
+        if (authorityKeyID == null) {
+            return true;
+        }
+        try {
+            byte[] extVal = xcert.getExtensionValue("2.5.29.35");
+            if (extVal == null) {
+                if (debug != null) {
+                    debug.println("X509CertSelector.match: "
+                        + "no authority key ID extension");
+                }
+                return false;
+            }
+            DerInputStream in = new DerInputStream(extVal);
+            byte[] certAuthKeyID = in.getOctetString();
+            if (certAuthKeyID == null ||
+                    !Arrays.equals(authorityKeyID, certAuthKeyID)) {
+                if (debug != null) {
+                    debug.println("X509CertSelector.match: "
+                        + "authority key IDs don't match");
+                }
+                return false;
+            }
+        } catch (IOException ex) {
+            if (debug != null) {
+                debug.println("X509CertSelector.match: "
+                    + "exception in authority key ID check");
+            }
+            return false;
+        }
+        return true;
+    }
+
+    /* match on private key usage range */
+    private boolean matchPrivateKeyValid(X509Certificate xcert) {
+        if (privateKeyValid == null) {
+            return true;
+        }
+        PrivateKeyUsageExtension ext = null;
+        try {
+            ext = (PrivateKeyUsageExtension)
+                getExtensionObject(xcert, PRIVATE_KEY_USAGE_ID);
+            if (ext != null) {
+                ext.valid(privateKeyValid);
+            }
+        } catch (CertificateExpiredException e1) {
+            if (debug != null) {
+                String time = "n/a";
+                try {
+                    Date notAfter = ext.get(PrivateKeyUsageExtension.NOT_AFTER);
+                    time = notAfter.toString();
+                } catch (CertificateException ex) {
+                    // not able to retrieve notAfter value
+                }
+                debug.println("X509CertSelector.match: private key usage not "
+                    + "within validity date; ext.NOT_After: "
+                    + time + "; X509CertSelector: "
+                    + this.toString());
+                e1.printStackTrace();
+            }
+            return false;
+        } catch (CertificateNotYetValidException e2) {
+            if (debug != null) {
+                String time = "n/a";
+                try {
+                    Date notBefore = ext.get(PrivateKeyUsageExtension.NOT_BEFORE);
+                    time = notBefore.toString();
+                } catch (CertificateException ex) {
+                    // not able to retrieve notBefore value
+                }
+                debug.println("X509CertSelector.match: private key usage not "
+                    + "within validity date; ext.NOT_BEFORE: "
+                    + time + "; X509CertSelector: "
+                    + this.toString());
+                e2.printStackTrace();
+            }
+            return false;
+        } catch (IOException e4) {
+            if (debug != null) {
+                debug.println("X509CertSelector.match: IOException in "
+                    + "private key usage check; X509CertSelector: "
+                    + this.toString());
+                e4.printStackTrace();
+            }
+            return false;
+        }
+        return true;
+    }
+
+    /* match on subject public key algorithm OID */
+    private boolean matchSubjectPublicKeyAlgID(X509Certificate xcert) {
+        if (subjectPublicKeyAlgID == null) {
+            return true;
+        }
+        try {
+            byte[] encodedKey = xcert.getPublicKey().getEncoded();
+            DerValue val = new DerValue(encodedKey);
+            if (val.tag != DerValue.tag_Sequence) {
+                throw new IOException("invalid key format");
+            }
+
+            AlgorithmId algID = AlgorithmId.parse(val.data.getDerValue());
+            if (debug != null) {
+                debug.println("X509CertSelector.match: subjectPublicKeyAlgID = "
+                    + subjectPublicKeyAlgID + ", xcert subjectPublicKeyAlgID = "
+                    + algID.getOID());
+            }
+            if (!subjectPublicKeyAlgID.equals((Object)algID.getOID())) {
+                if (debug != null) {
+                    debug.println("X509CertSelector.match: "
+                        + "subject public key alg IDs don't match");
+                }
+                return false;
+            }
+        } catch (IOException e5) {
+            if (debug != null) {
+                debug.println("X509CertSelector.match: IOException in subject "
+                    + "public key algorithm OID check");
+            }
+            return false;
+        }
+        return true;
+    }
+
+    /* match on key usage extension value */
+    private boolean matchKeyUsage(X509Certificate xcert) {
+        if (keyUsage == null) {
+            return true;
+        }
+        boolean[] certKeyUsage = xcert.getKeyUsage();
+        if (certKeyUsage != null) {
+            for (int keyBit = 0; keyBit < keyUsage.length; keyBit++) {
+                if (keyUsage[keyBit] &&
+                    ((keyBit >= certKeyUsage.length) || !certKeyUsage[keyBit])) {
+                    if (debug != null) {
+                        debug.println("X509CertSelector.match: "
+                            + "key usage bits don't match");
+                    }
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    /* match on extended key usage purpose OIDs */
+    private boolean matchExtendedKeyUsage(X509Certificate xcert) {
+        if ((keyPurposeSet == null) || keyPurposeSet.isEmpty()) {
+            return true;
+        }
+        try {
+            ExtendedKeyUsageExtension ext =
+                (ExtendedKeyUsageExtension)getExtensionObject(xcert,
+                                                EXTENDED_KEY_USAGE_ID);
+            if (ext != null) {
+                Vector<ObjectIdentifier> certKeyPurposeVector =
+                    ext.get(ExtendedKeyUsageExtension.USAGES);
+                if (!certKeyPurposeVector.contains(ANY_EXTENDED_KEY_USAGE)
+                        && !certKeyPurposeVector.containsAll(keyPurposeOIDSet)) {
+                    if (debug != null) {
+                        debug.println("X509CertSelector.match: cert failed "
+                            + "extendedKeyUsage criterion");
+                    }
+                    return false;
+                }
+            }
+        } catch (IOException ex) {
+            if (debug != null) {
+                debug.println("X509CertSelector.match: "
+                    + "IOException in extended key usage check");
+            }
+            return false;
+        }
+        return true;
+    }
+
+    /* match on subject alternative name extension names */
+    private boolean matchSubjectAlternativeNames(X509Certificate xcert) {
+        if ((subjectAlternativeNames == null) || subjectAlternativeNames.isEmpty()) {
+            return true;
+        }
+        try {
+            SubjectAlternativeNameExtension sanExt =
+                (SubjectAlternativeNameExtension) getExtensionObject(xcert,
+                                                      SUBJECT_ALT_NAME_ID);
+            if (sanExt == null) {
+                if (debug != null) {
+                  debug.println("X509CertSelector.match: "
+                      + "no subject alternative name extension");
+                }
+                return false;
+            }
+            GeneralNames certNames =
+                    sanExt.get(SubjectAlternativeNameExtension.SUBJECT_NAME);
+            Iterator<GeneralNameInterface> i =
+                                subjectAlternativeGeneralNames.iterator();
+            while (i.hasNext()) {
+                GeneralNameInterface matchName = i.next();
+                boolean found = false;
+                for (Iterator<GeneralName> t = certNames.iterator();
+                                                t.hasNext() && !found; ) {
+                    GeneralNameInterface certName = (t.next()).getName();
+                    found = certName.equals(matchName);
+                }
+                if (!found && (matchAllSubjectAltNames || !i.hasNext())) {
+                    if (debug != null) {
+                      debug.println("X509CertSelector.match: subject alternative "
+                          + "name " + matchName + " not found");
+                    }
+                    return false;
+                } else if (found && !matchAllSubjectAltNames) {
+                    break;
+                }
+            }
+        } catch (IOException ex) {
+            if (debug != null)
+                debug.println("X509CertSelector.match: IOException in subject "
+                    + "alternative name check");
+            return false;
+        }
+        return true;
+    }
+
+    /* match on name constraints */
+    private boolean matchNameConstraints(X509Certificate xcert) {
+        if (nc == null) {
+            return true;
+        }
+        try {
+            if (!nc.verify(xcert)) {
+                if (debug != null) {
+                    debug.println("X509CertSelector.match: "
+                        + "name constraints not satisfied");
+                }
+                return false;
+            }
+        } catch (IOException e) {
+            if (debug != null) {
+                debug.println("X509CertSelector.match: "
+                    + "IOException in name constraints check");
+            }
+            return false;
+        }
+        return true;
+    }
+
+    /* match on policy OIDs */
+    private boolean matchPolicy(X509Certificate xcert) {
+        if (policy == null) {
+            return true;
+        }
+        try {
+            CertificatePoliciesExtension ext = (CertificatePoliciesExtension)
+                getExtensionObject(xcert, CERT_POLICIES_ID);
+            if (ext == null) {
+                if (debug != null) {
+                  debug.println("X509CertSelector.match: "
+                      + "no certificate policy extension");
+                }
+                return false;
+            }
+            List<PolicyInformation> policies = ext.get(CertificatePoliciesExtension.POLICIES);
+            /*
+             * Convert the Vector of PolicyInformation to a Vector
+             * of CertificatePolicyIds for easier comparison.
+             */
+            List<CertificatePolicyId> policyIDs = new ArrayList<CertificatePolicyId>(policies.size());
+            for (PolicyInformation info : policies) {
+                policyIDs.add(info.getPolicyIdentifier());
+            }
+            if (policy != null) {
+                boolean foundOne = false;
+                /*
+                 * if the user passes in an empty policy Set, then
+                 * we just want to make sure that the candidate certificate
+                 * has some policy OID in its CertPoliciesExtension
+                 */
+                if (policy.getCertPolicyIds().isEmpty()) {
+                    if (policyIDs.isEmpty()) {
+                        if (debug != null) {
+                            debug.println("X509CertSelector.match: "
+                                + "cert failed policyAny criterion");
+                        }
+                        return false;
+                    }
+                } else {
+                    for (CertificatePolicyId id : policy.getCertPolicyIds()) {
+                        if (policyIDs.contains(id)) {
+                            foundOne = true;
+                            break;
+                        }
+                    }
+                    if (!foundOne) {
+                        if (debug != null) {
+                            debug.println("X509CertSelector.match: "
+                                + "cert failed policyAny criterion");
+                        }
+                        return false;
+                    }
+                }
+            }
+        } catch (IOException ex) {
+            if (debug != null) {
+                debug.println("X509CertSelector.match: "
+                    + "IOException in certificate policy ID check");
+            }
+            return false;
+        }
+        return true;
+    }
+
+    /* match on pathToNames */
+    private boolean matchPathToNames(X509Certificate xcert) {
+        if (pathToGeneralNames == null) {
+            return true;
+        }
+        try {
+            NameConstraintsExtension ext = (NameConstraintsExtension)
+                getExtensionObject(xcert, NAME_CONSTRAINTS_ID);
+            if (ext == null) {
+                return true;
+            }
+            if ((debug != null) && Debug.isOn("certpath")) {
+                debug.println("X509CertSelector.match pathToNames:\n");
+                Iterator<GeneralNameInterface> i =
+                                        pathToGeneralNames.iterator();
+                while (i.hasNext()) {
+                    debug.println("    " + i.next() + "\n");
+                }
+            }
+
+            GeneralSubtrees permitted =
+                    ext.get(NameConstraintsExtension.PERMITTED_SUBTREES);
+            GeneralSubtrees excluded =
+                    ext.get(NameConstraintsExtension.EXCLUDED_SUBTREES);
+            if (excluded != null) {
+                if (matchExcluded(excluded) == false) {
+                    return false;
+                }
+            }
+            if (permitted != null) {
+                if (matchPermitted(permitted) == false) {
+                    return false;
+                }
+            }
+        } catch (IOException ex) {
+            if (debug != null) {
+                debug.println("X509CertSelector.match: "
+                    + "IOException in name constraints check");
+            }
+            return false;
+        }
+        return true;
+    }
+
+    private boolean matchExcluded(GeneralSubtrees excluded) {
+        /*
+         * Enumerate through excluded and compare each entry
+         * to all pathToNames. If any pathToName is within any of the
+         * subtrees listed in excluded, return false.
+         */
+        for (Iterator<GeneralSubtree> t = excluded.iterator(); t.hasNext(); ) {
+            GeneralSubtree tree = t.next();
+            GeneralNameInterface excludedName = tree.getName().getName();
+            Iterator<GeneralNameInterface> i = pathToGeneralNames.iterator();
+            while (i.hasNext()) {
+                GeneralNameInterface pathToName = i.next();
+                if (excludedName.getType() == pathToName.getType()) {
+                    switch (pathToName.constrains(excludedName)) {
+                    case GeneralNameInterface.NAME_WIDENS:
+                    case GeneralNameInterface.NAME_MATCH:
+                        if (debug != null) {
+                            debug.println("X509CertSelector.match: name constraints "
+                                + "inhibit path to specified name");
+                            debug.println("X509CertSelector.match: excluded name: " +
+                                pathToName);
+                        }
+                        return false;
+                    default:
+                    }
+                }
+            }
+        }
+        return true;
+    }
+
+    private boolean matchPermitted(GeneralSubtrees permitted) {
+        /*
+         * Enumerate through pathToNames, checking that each pathToName
+         * is in at least one of the subtrees listed in permitted.
+         * If not, return false. However, if no subtrees of a given type
+         * are listed, all names of that type are permitted.
+         */
+        Iterator<GeneralNameInterface> i = pathToGeneralNames.iterator();
+        while (i.hasNext()) {
+            GeneralNameInterface pathToName = i.next();
+            Iterator<GeneralSubtree> t = permitted.iterator();
+            boolean permittedNameFound = false;
+            boolean nameTypeFound = false;
+            String names = "";
+            while (t.hasNext() && !permittedNameFound) {
+                GeneralSubtree tree = t.next();
+                GeneralNameInterface permittedName = tree.getName().getName();
+                if (permittedName.getType() == pathToName.getType()) {
+                    nameTypeFound = true;
+                    names = names + "  " + permittedName;
+                    switch (pathToName.constrains(permittedName)) {
+                    case GeneralNameInterface.NAME_WIDENS:
+                    case GeneralNameInterface.NAME_MATCH:
+                        permittedNameFound = true;
+                        break;
+                    default:
+                    }
+                }
+            }
+            if (!permittedNameFound && nameTypeFound) {
+                if (debug != null)
+                  debug.println("X509CertSelector.match: " +
+                            "name constraints inhibit path to specified name; " +
+                            "permitted names of type " + pathToName.getType() +
+                            ": " + names);
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /* match on basic constraints */
+    private boolean matchBasicConstraints(X509Certificate xcert) {
+        if (basicConstraints == -1) {
+            return true;
+        }
+        int maxPathLen = xcert.getBasicConstraints();
+        if (basicConstraints == -2) {
+            if (maxPathLen != -1) {
+                if (debug != null) {
+                    debug.println("X509CertSelector.match: not an EE cert");
+                }
+                return false;
+            }
+        } else {
+            if (maxPathLen < basicConstraints) {
+                if (debug != null) {
+                    debug.println("X509CertSelector.match: cert's maxPathLen " +
+                            "is less than the min maxPathLen set by " +
+                            "basicConstraints. " +
+                            "(" + maxPathLen + " < " + basicConstraints + ")");
+                }
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @SuppressWarnings("unchecked") // Safe casts assuming clone() works correctly
+    private static <T> Set<T> cloneSet(Set<T> set) {
+        if (set instanceof HashSet) {
+            Object clone = ((HashSet<T>)set).clone();
+            return (Set<T>)clone;
+        } else {
+            return new HashSet<T>(set);
+        }
+    }
+
+    /**
+     * Returns a copy of this object.
+     *
+     * @return the copy
+     */
+    public Object clone() {
+        try {
+            X509CertSelector copy = (X509CertSelector)super.clone();
+            // Must clone these because addPathToName et al. modify them
+            if (subjectAlternativeNames != null) {
+                copy.subjectAlternativeNames =
+                        cloneSet(subjectAlternativeNames);
+                copy.subjectAlternativeGeneralNames =
+                        cloneSet(subjectAlternativeGeneralNames);
+            }
+            if (pathToGeneralNames != null) {
+                copy.pathToNames = cloneSet(pathToNames);
+                copy.pathToGeneralNames = cloneSet(pathToGeneralNames);
+            }
+            return copy;
+        } catch (CloneNotSupportedException e) {
+            /* Cannot happen */
+            throw new InternalError(e.toString(), e);
+        }
+    }
+}
diff --git a/java/security/cert/X509Certificate.java b/java/security/cert/X509Certificate.java
new file mode 100644
index 0000000..042eefd
--- /dev/null
+++ b/java/security/cert/X509Certificate.java
@@ -0,0 +1,685 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security.cert;
+
+import java.math.BigInteger;
+import java.security.*;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import javax.security.auth.x500.X500Principal;
+
+import sun.security.x509.X509CertImpl;
+
+/**
+ * <p>
+ * Abstract class for X.509 certificates. This provides a standard
+ * way to access all the attributes of an X.509 certificate.
+ * <p>
+ * In June of 1996, the basic X.509 v3 format was completed by
+ * ISO/IEC and ANSI X9, which is described below in ASN.1:
+ * <pre>
+ * Certificate  ::=  SEQUENCE  {
+ *     tbsCertificate       TBSCertificate,
+ *     signatureAlgorithm   AlgorithmIdentifier,
+ *     signature            BIT STRING  }
+ * </pre>
+ * <p>
+ * These certificates are widely used to support authentication and
+ * other functionality in Internet security systems. Common applications
+ * include Privacy Enhanced Mail (PEM), Transport Layer Security (SSL),
+ * code signing for trusted software distribution, and Secure Electronic
+ * Transactions (SET).
+ * <p>
+ * These certificates are managed and vouched for by <em>Certificate
+ * Authorities</em> (CAs). CAs are services which create certificates by
+ * placing data in the X.509 standard format and then digitally signing
+ * that data. CAs act as trusted third parties, making introductions
+ * between principals who have no direct knowledge of each other.
+ * CA certificates are either signed by themselves, or by some other
+ * CA such as a "root" CA.
+ * <p>
+ * More information can be found in
+ * <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280: Internet X.509
+ * Public Key Infrastructure Certificate and CRL Profile</a>.
+ * <p>
+ * The ASN.1 definition of {@code tbsCertificate} is:
+ * <pre>
+ * TBSCertificate  ::=  SEQUENCE  {
+ *     version         [0]  EXPLICIT Version DEFAULT v1,
+ *     serialNumber         CertificateSerialNumber,
+ *     signature            AlgorithmIdentifier,
+ *     issuer               Name,
+ *     validity             Validity,
+ *     subject              Name,
+ *     subjectPublicKeyInfo SubjectPublicKeyInfo,
+ *     issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
+ *                          -- If present, version must be v2 or v3
+ *     subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
+ *                          -- If present, version must be v2 or v3
+ *     extensions      [3]  EXPLICIT Extensions OPTIONAL
+ *                          -- If present, version must be v3
+ *     }
+ * </pre>
+ * <p>
+ * Certificates are instantiated using a certificate factory. The following is
+ * an example of how to instantiate an X.509 certificate:
+ * <pre>
+ * try (InputStream inStream = new FileInputStream("fileName-of-cert")) {
+ *     CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ *     X509Certificate cert = (X509Certificate)cf.generateCertificate(inStream);
+ * }
+ * </pre>
+ *
+ * @author Hemma Prafullchandra
+ *
+ *
+ * @see Certificate
+ * @see CertificateFactory
+ * @see X509Extension
+ */
+
+public abstract class X509Certificate extends Certificate
+implements X509Extension {
+
+    private static final long serialVersionUID = -2491127588187038216L;
+
+    private transient X500Principal subjectX500Principal, issuerX500Principal;
+
+    /**
+     * Constructor for X.509 certificates.
+     */
+    protected X509Certificate() {
+        super("X.509");
+    }
+
+    /**
+     * Checks that the certificate is currently valid. It is if
+     * the current date and time are within the validity period given in the
+     * certificate.
+     * <p>
+     * The validity period consists of two date/time values:
+     * the first and last dates (and times) on which the certificate
+     * is valid. It is defined in
+     * ASN.1 as:
+     * <pre>
+     * validity             Validity
+     *
+     * Validity ::= SEQUENCE {
+     *     notBefore      CertificateValidityDate,
+     *     notAfter       CertificateValidityDate }
+     *
+     * CertificateValidityDate ::= CHOICE {
+     *     utcTime        UTCTime,
+     *     generalTime    GeneralizedTime }
+     * </pre>
+     *
+     * @exception CertificateExpiredException if the certificate has expired.
+     * @exception CertificateNotYetValidException if the certificate is not
+     * yet valid.
+     */
+    public abstract void checkValidity()
+        throws CertificateExpiredException, CertificateNotYetValidException;
+
+    /**
+     * Checks that the given date is within the certificate's
+     * validity period. In other words, this determines whether the
+     * certificate would be valid at the given date/time.
+     *
+     * @param date the Date to check against to see if this certificate
+     *        is valid at that date/time.
+     *
+     * @exception CertificateExpiredException if the certificate has expired
+     * with respect to the {@code date} supplied.
+     * @exception CertificateNotYetValidException if the certificate is not
+     * yet valid with respect to the {@code date} supplied.
+     *
+     * @see #checkValidity()
+     */
+    public abstract void checkValidity(Date date)
+        throws CertificateExpiredException, CertificateNotYetValidException;
+
+    /**
+     * Gets the {@code version} (version number) value from the
+     * certificate.
+     * The ASN.1 definition for this is:
+     * <pre>
+     * version  [0] EXPLICIT Version DEFAULT v1
+     *
+     * Version ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
+     * </pre>
+     * @return the version number, i.e. 1, 2 or 3.
+     */
+    public abstract int getVersion();
+
+    /**
+     * Gets the {@code serialNumber} value from the certificate.
+     * The serial number is an integer assigned by the certification
+     * authority to each certificate. It must be unique for each
+     * certificate issued by a given CA (i.e., the issuer name and
+     * serial number identify a unique certificate).
+     * The ASN.1 definition for this is:
+     * <pre>
+     * serialNumber     CertificateSerialNumber
+     *
+     * CertificateSerialNumber  ::=  INTEGER
+     * </pre>
+     *
+     * @return the serial number.
+     */
+    public abstract BigInteger getSerialNumber();
+
+    /**
+     * <strong>Denigrated</strong>, replaced by {@linkplain
+     * #getIssuerX500Principal()}. This method returns the {@code issuer}
+     * as an implementation specific Principal object, which should not be
+     * relied upon by portable code.
+     *
+     * <p>
+     * Gets the {@code issuer} (issuer distinguished name) value from
+     * the certificate. The issuer name identifies the entity that signed (and
+     * issued) the certificate.
+     *
+     * <p>The issuer name field contains an
+     * X.500 distinguished name (DN).
+     * The ASN.1 definition for this is:
+     * <pre>
+     * issuer    Name
+     *
+     * Name ::= CHOICE { RDNSequence }
+     * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+     * RelativeDistinguishedName ::=
+     *     SET OF AttributeValueAssertion
+     *
+     * AttributeValueAssertion ::= SEQUENCE {
+     *                               AttributeType,
+     *                               AttributeValue }
+     * AttributeType ::= OBJECT IDENTIFIER
+     * AttributeValue ::= ANY
+     * </pre>
+     * The {@code Name} describes a hierarchical name composed of
+     * attributes,
+     * such as country name, and corresponding values, such as US.
+     * The type of the {@code AttributeValue} component is determined by
+     * the {@code AttributeType}; in general it will be a
+     * {@code directoryString}. A {@code directoryString} is usually
+     * one of {@code PrintableString},
+     * {@code TeletexString} or {@code UniversalString}.
+     *
+     * @return a Principal whose name is the issuer distinguished name.
+     */
+    public abstract Principal getIssuerDN();
+
+    /**
+     * Returns the issuer (issuer distinguished name) value from the
+     * certificate as an {@code X500Principal}.
+     * <p>
+     * It is recommended that subclasses override this method.
+     *
+     * @return an {@code X500Principal} representing the issuer
+     *          distinguished name
+     * @since 1.4
+     */
+    public X500Principal getIssuerX500Principal() {
+        if (issuerX500Principal == null) {
+            issuerX500Principal = X509CertImpl.getIssuerX500Principal(this);
+        }
+        return issuerX500Principal;
+    }
+
+    /**
+     * <strong>Denigrated</strong>, replaced by {@linkplain
+     * #getSubjectX500Principal()}. This method returns the {@code subject}
+     * as an implementation specific Principal object, which should not be
+     * relied upon by portable code.
+     *
+     * <p>
+     * Gets the {@code subject} (subject distinguished name) value
+     * from the certificate.  If the {@code subject} value is empty,
+     * then the {@code getName()} method of the returned
+     * {@code Principal} object returns an empty string ("").
+     *
+     * <p> The ASN.1 definition for this is:
+     * <pre>
+     * subject    Name
+     * </pre>
+     *
+     * <p>See {@link #getIssuerDN() getIssuerDN} for {@code Name}
+     * and other relevant definitions.
+     *
+     * @return a Principal whose name is the subject name.
+     */
+    public abstract Principal getSubjectDN();
+
+    /**
+     * Returns the subject (subject distinguished name) value from the
+     * certificate as an {@code X500Principal}.  If the subject value
+     * is empty, then the {@code getName()} method of the returned
+     * {@code X500Principal} object returns an empty string ("").
+     * <p>
+     * It is recommended that subclasses override this method.
+     *
+     * @return an {@code X500Principal} representing the subject
+     *          distinguished name
+     * @since 1.4
+     */
+    public X500Principal getSubjectX500Principal() {
+        if (subjectX500Principal == null) {
+            subjectX500Principal = X509CertImpl.getSubjectX500Principal(this);
+        }
+        return subjectX500Principal;
+    }
+
+    /**
+     * Gets the {@code notBefore} date from the validity period of
+     * the certificate.
+     * The relevant ASN.1 definitions are:
+     * <pre>
+     * validity             Validity
+     *
+     * Validity ::= SEQUENCE {
+     *     notBefore      CertificateValidityDate,
+     *     notAfter       CertificateValidityDate }
+     *
+     * CertificateValidityDate ::= CHOICE {
+     *     utcTime        UTCTime,
+     *     generalTime    GeneralizedTime }
+     * </pre>
+     *
+     * @return the start date of the validity period.
+     * @see #checkValidity
+     */
+    public abstract Date getNotBefore();
+
+    /**
+     * Gets the {@code notAfter} date from the validity period of
+     * the certificate. See {@link #getNotBefore() getNotBefore}
+     * for relevant ASN.1 definitions.
+     *
+     * @return the end date of the validity period.
+     * @see #checkValidity
+     */
+    public abstract Date getNotAfter();
+
+    /**
+     * Gets the DER-encoded certificate information, the
+     * {@code tbsCertificate} from this certificate.
+     * This can be used to verify the signature independently.
+     *
+     * @return the DER-encoded certificate information.
+     * @exception CertificateEncodingException if an encoding error occurs.
+     */
+    public abstract byte[] getTBSCertificate()
+        throws CertificateEncodingException;
+
+    /**
+     * Gets the {@code signature} value (the raw signature bits) from
+     * the certificate.
+     * The ASN.1 definition for this is:
+     * <pre>
+     * signature     BIT STRING
+     * </pre>
+     *
+     * @return the signature.
+     */
+    public abstract byte[] getSignature();
+
+    /**
+     * Gets the signature algorithm name for the certificate
+     * signature algorithm. An example is the string "SHA256withRSA".
+     * The ASN.1 definition for this is:
+     * <pre>
+     * signatureAlgorithm   AlgorithmIdentifier
+     *
+     * AlgorithmIdentifier  ::=  SEQUENCE  {
+     *     algorithm               OBJECT IDENTIFIER,
+     *     parameters              ANY DEFINED BY algorithm OPTIONAL  }
+     *                             -- contains a value of the type
+     *                             -- registered for use with the
+     *                             -- algorithm object identifier value
+     * </pre>
+     *
+     * <p>The algorithm name is determined from the {@code algorithm}
+     * OID string.
+     *
+     * @return the signature algorithm name.
+     */
+    public abstract String getSigAlgName();
+
+    /**
+     * Gets the signature algorithm OID string from the certificate.
+     * An OID is represented by a set of nonnegative whole numbers separated
+     * by periods.
+     * For example, the string "1.2.840.10040.4.3" identifies the SHA-1
+     * with DSA signature algorithm defined in
+     * <a href="http://www.ietf.org/rfc/rfc3279.txt">RFC 3279: Algorithms and
+     * Identifiers for the Internet X.509 Public Key Infrastructure Certificate
+     * and CRL Profile</a>.
+     *
+     * <p>See {@link #getSigAlgName() getSigAlgName} for
+     * relevant ASN.1 definitions.
+     *
+     * @return the signature algorithm OID string.
+     */
+    public abstract String getSigAlgOID();
+
+    /**
+     * Gets the DER-encoded signature algorithm parameters from this
+     * certificate's signature algorithm. In most cases, the signature
+     * algorithm parameters are null; the parameters are usually
+     * supplied with the certificate's public key.
+     * If access to individual parameter values is needed then use
+     * {@link java.security.AlgorithmParameters AlgorithmParameters}
+     * and instantiate with the name returned by
+     * {@link #getSigAlgName() getSigAlgName}.
+     *
+     * <p>See {@link #getSigAlgName() getSigAlgName} for
+     * relevant ASN.1 definitions.
+     *
+     * @return the DER-encoded signature algorithm parameters, or
+     *         null if no parameters are present.
+     */
+    public abstract byte[] getSigAlgParams();
+
+    /**
+     * Gets the {@code issuerUniqueID} value from the certificate.
+     * The issuer unique identifier is present in the certificate
+     * to handle the possibility of reuse of issuer names over time.
+     * RFC 3280 recommends that names not be reused and that
+     * conforming certificates not make use of unique identifiers.
+     * Applications conforming to that profile should be capable of
+     * parsing unique identifiers and making comparisons.
+     *
+     * <p>The ASN.1 definition for this is:
+     * <pre>
+     * issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL
+     *
+     * UniqueIdentifier  ::=  BIT STRING
+     * </pre>
+     *
+     * @return the issuer unique identifier or null if it is not
+     * present in the certificate.
+     */
+    public abstract boolean[] getIssuerUniqueID();
+
+    /**
+     * Gets the {@code subjectUniqueID} value from the certificate.
+     *
+     * <p>The ASN.1 definition for this is:
+     * <pre>
+     * subjectUniqueID  [2]  IMPLICIT UniqueIdentifier OPTIONAL
+     *
+     * UniqueIdentifier  ::=  BIT STRING
+     * </pre>
+     *
+     * @return the subject unique identifier or null if it is not
+     * present in the certificate.
+     */
+    public abstract boolean[] getSubjectUniqueID();
+
+    /**
+     * Gets a boolean array representing bits of
+     * the {@code KeyUsage} extension, (OID = 2.5.29.15).
+     * The key usage extension defines the purpose (e.g., encipherment,
+     * signature, certificate signing) of the key contained in the
+     * certificate.
+     * The ASN.1 definition for this is:
+     * <pre>
+     * KeyUsage ::= BIT STRING {
+     *     digitalSignature        (0),
+     *     nonRepudiation          (1),
+     *     keyEncipherment         (2),
+     *     dataEncipherment        (3),
+     *     keyAgreement            (4),
+     *     keyCertSign             (5),
+     *     cRLSign                 (6),
+     *     encipherOnly            (7),
+     *     decipherOnly            (8) }
+     * </pre>
+     * RFC 3280 recommends that when used, this be marked
+     * as a critical extension.
+     *
+     * @return the KeyUsage extension of this certificate, represented as
+     * an array of booleans. The order of KeyUsage values in the array is
+     * the same as in the above ASN.1 definition. The array will contain a
+     * value for each KeyUsage defined above. If the KeyUsage list encoded
+     * in the certificate is longer than the above list, it will not be
+     * truncated. Returns null if this certificate does not
+     * contain a KeyUsage extension.
+     */
+    public abstract boolean[] getKeyUsage();
+
+    /**
+     * Gets an unmodifiable list of Strings representing the OBJECT
+     * IDENTIFIERs of the {@code ExtKeyUsageSyntax} field of the
+     * extended key usage extension, (OID = 2.5.29.37).  It indicates
+     * one or more purposes for which the certified public key may be
+     * used, in addition to or in place of the basic purposes
+     * indicated in the key usage extension field.  The ASN.1
+     * definition for this is:
+     * <pre>
+     * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
+     *
+     * KeyPurposeId ::= OBJECT IDENTIFIER
+     * </pre>
+     *
+     * Key purposes may be defined by any organization with a
+     * need. Object identifiers used to identify key purposes shall be
+     * assigned in accordance with IANA or ITU-T Rec. X.660 |
+     * ISO/IEC/ITU 9834-1.
+     * <p>
+     * This method was added to version 1.4 of the Java 2 Platform Standard
+     * Edition. In order to maintain backwards compatibility with existing
+     * service providers, this method is not {@code abstract}
+     * and it provides a default implementation. Subclasses
+     * should override this method with a correct implementation.
+     *
+     * @return the ExtendedKeyUsage extension of this certificate,
+     *         as an unmodifiable list of object identifiers represented
+     *         as Strings. Returns null if this certificate does not
+     *         contain an ExtendedKeyUsage extension.
+     * @throws CertificateParsingException if the extension cannot be decoded
+     * @since 1.4
+     */
+    public List<String> getExtendedKeyUsage() throws CertificateParsingException {
+        return X509CertImpl.getExtendedKeyUsage(this);
+    }
+
+    /**
+     * Gets the certificate constraints path length from the
+     * critical {@code BasicConstraints} extension, (OID = 2.5.29.19).
+     * <p>
+     * The basic constraints extension identifies whether the subject
+     * of the certificate is a Certificate Authority (CA) and
+     * how deep a certification path may exist through that CA. The
+     * {@code pathLenConstraint} field (see below) is meaningful
+     * only if {@code cA} is set to TRUE. In this case, it gives the
+     * maximum number of CA certificates that may follow this certificate in a
+     * certification path. A value of zero indicates that only an end-entity
+     * certificate may follow in the path.
+     * <p>
+     * The ASN.1 definition for this is:
+     * <pre>
+     * BasicConstraints ::= SEQUENCE {
+     *     cA                  BOOLEAN DEFAULT FALSE,
+     *     pathLenConstraint   INTEGER (0..MAX) OPTIONAL }
+     * </pre>
+     *
+     * @return the value of {@code pathLenConstraint} if the
+     * BasicConstraints extension is present in the certificate and the
+     * subject of the certificate is a CA, otherwise -1.
+     * If the subject of the certificate is a CA and
+     * {@code pathLenConstraint} does not appear,
+     * {@code Integer.MAX_VALUE} is returned to indicate that there is no
+     * limit to the allowed length of the certification path.
+     */
+    public abstract int getBasicConstraints();
+
+    /**
+     * Gets an immutable collection of subject alternative names from the
+     * {@code SubjectAltName} extension, (OID = 2.5.29.17).
+     * <p>
+     * The ASN.1 definition of the {@code SubjectAltName} extension is:
+     * <pre>
+     * SubjectAltName ::= GeneralNames
+     *
+     * GeneralNames :: = SEQUENCE SIZE (1..MAX) OF GeneralName
+     *
+     * GeneralName ::= CHOICE {
+     *      otherName                       [0]     OtherName,
+     *      rfc822Name                      [1]     IA5String,
+     *      dNSName                         [2]     IA5String,
+     *      x400Address                     [3]     ORAddress,
+     *      directoryName                   [4]     Name,
+     *      ediPartyName                    [5]     EDIPartyName,
+     *      uniformResourceIdentifier       [6]     IA5String,
+     *      iPAddress                       [7]     OCTET STRING,
+     *      registeredID                    [8]     OBJECT IDENTIFIER}
+     * </pre>
+     * <p>
+     * If this certificate does not contain a {@code SubjectAltName}
+     * extension, {@code null} is returned. Otherwise, a
+     * {@code Collection} is returned with an entry representing each
+     * {@code GeneralName} included in the extension. Each entry is a
+     * {@code List} whose first entry is an {@code Integer}
+     * (the name type, 0-8) and whose second entry is a {@code String}
+     * or a byte array (the name, in string or ASN.1 DER encoded form,
+     * respectively).
+     * <p>
+     * <a href="http://www.ietf.org/rfc/rfc822.txt">RFC 822</a>, DNS, and URI
+     * names are returned as {@code String}s,
+     * using the well-established string formats for those types (subject to
+     * the restrictions included in RFC 3280). IPv4 address names are
+     * returned using dotted quad notation. IPv6 address names are returned
+     * in the form "a1:a2:...:a8", where a1-a8 are hexadecimal values
+     * representing the eight 16-bit pieces of the address. OID names are
+     * returned as {@code String}s represented as a series of nonnegative
+     * integers separated by periods. And directory names (distinguished names)
+     * are returned in <a href="http://www.ietf.org/rfc/rfc2253.txt">
+     * RFC 2253</a> string format. No standard string format is
+     * defined for otherNames, X.400 names, EDI party names, or any
+     * other type of names. They are returned as byte arrays
+     * containing the ASN.1 DER encoded form of the name.
+     * <p>
+     * Note that the {@code Collection} returned may contain more
+     * than one name of the same type. Also, note that the returned
+     * {@code Collection} is immutable and any entries containing byte
+     * arrays are cloned to protect against subsequent modifications.
+     * <p>
+     * This method was added to version 1.4 of the Java 2 Platform Standard
+     * Edition. In order to maintain backwards compatibility with existing
+     * service providers, this method is not {@code abstract}
+     * and it provides a default implementation. Subclasses
+     * should override this method with a correct implementation.
+     *
+     * @return an immutable {@code Collection} of subject alternative
+     * names (or {@code null})
+     * @throws CertificateParsingException if the extension cannot be decoded
+     * @since 1.4
+     */
+    public Collection<List<?>> getSubjectAlternativeNames()
+        throws CertificateParsingException {
+        return X509CertImpl.getSubjectAlternativeNames(this);
+    }
+
+    /**
+     * Gets an immutable collection of issuer alternative names from the
+     * {@code IssuerAltName} extension, (OID = 2.5.29.18).
+     * <p>
+     * The ASN.1 definition of the {@code IssuerAltName} extension is:
+     * <pre>
+     * IssuerAltName ::= GeneralNames
+     * </pre>
+     * The ASN.1 definition of {@code GeneralNames} is defined
+     * in {@link #getSubjectAlternativeNames getSubjectAlternativeNames}.
+     * <p>
+     * If this certificate does not contain an {@code IssuerAltName}
+     * extension, {@code null} is returned. Otherwise, a
+     * {@code Collection} is returned with an entry representing each
+     * {@code GeneralName} included in the extension. Each entry is a
+     * {@code List} whose first entry is an {@code Integer}
+     * (the name type, 0-8) and whose second entry is a {@code String}
+     * or a byte array (the name, in string or ASN.1 DER encoded form,
+     * respectively). For more details about the formats used for each
+     * name type, see the {@code getSubjectAlternativeNames} method.
+     * <p>
+     * Note that the {@code Collection} returned may contain more
+     * than one name of the same type. Also, note that the returned
+     * {@code Collection} is immutable and any entries containing byte
+     * arrays are cloned to protect against subsequent modifications.
+     * <p>
+     * This method was added to version 1.4 of the Java 2 Platform Standard
+     * Edition. In order to maintain backwards compatibility with existing
+     * service providers, this method is not {@code abstract}
+     * and it provides a default implementation. Subclasses
+     * should override this method with a correct implementation.
+     *
+     * @return an immutable {@code Collection} of issuer alternative
+     * names (or {@code null})
+     * @throws CertificateParsingException if the extension cannot be decoded
+     * @since 1.4
+     */
+    public Collection<List<?>> getIssuerAlternativeNames()
+        throws CertificateParsingException {
+        return X509CertImpl.getIssuerAlternativeNames(this);
+    }
+
+     /**
+     * Verifies that this certificate was signed using the
+     * private key that corresponds to the specified public key.
+     * This method uses the signature verification engine
+     * supplied by the specified provider. Note that the specified
+     * Provider object does not have to be registered in the provider list.
+     *
+     * This method was added to version 1.8 of the Java Platform Standard
+     * Edition. In order to maintain backwards compatibility with existing
+     * service providers, this method is not {@code abstract}
+     * and it provides a default implementation.
+     *
+     * @param key the PublicKey used to carry out the verification.
+     * @param sigProvider the signature provider.
+     *
+     * @exception NoSuchAlgorithmException on unsupported signature
+     * algorithms.
+     * @exception InvalidKeyException on incorrect key.
+     * @exception SignatureException on signature errors.
+     * @exception CertificateException on encoding errors.
+     * @exception UnsupportedOperationException if the method is not supported
+     * @since 1.8
+     */
+    public void verify(PublicKey key, Provider sigProvider)
+        throws CertificateException, NoSuchAlgorithmException,
+        InvalidKeyException, SignatureException {
+        // Android-changed: Use Certificate default implementation that
+        // throws UnsupportedOperationException.
+        // The method X509CertImpl calls this method, thus entering an
+        // infinite loop. This strange behaviour was checked to be not
+        // specific to libcore by running a test with vogar --mode=jvm
+        //
+        // X509CertImpl.verify(this, key, sigProvider);
+        super.verify(key, sigProvider);
+    }
+}
diff --git a/java/security/cert/X509Extension.java b/java/security/cert/X509Extension.java
new file mode 100644
index 0000000..0346960
--- /dev/null
+++ b/java/security/cert/X509Extension.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security.cert;
+
+import java.util.Set;
+
+/**
+ * Interface for an X.509 extension.
+ *
+ * <p>The extensions defined for X.509 v3
+ * {@link X509Certificate Certificates} and v2
+ * {@link X509CRL CRLs} (Certificate Revocation
+ * Lists) provide methods
+ * for associating additional attributes with users or public keys,
+ * for managing the certification hierarchy, and for managing CRL
+ * distribution. The X.509 extensions format also allows communities
+ * to define private extensions to carry information unique to those
+ * communities.
+ *
+ * <p>Each extension in a certificate/CRL may be designated as
+ * critical or non-critical.  A certificate/CRL-using system (an application
+ * validating a certificate/CRL) must reject the certificate/CRL if it
+ * encounters a critical extension it does not recognize.  A non-critical
+ * extension may be ignored if it is not recognized.
+ * <p>
+ * The ASN.1 definition for this is:
+ * <pre>
+ * Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
+ *
+ * Extension  ::=  SEQUENCE  {
+ *     extnId        OBJECT IDENTIFIER,
+ *     critical      BOOLEAN DEFAULT FALSE,
+ *     extnValue     OCTET STRING
+ *                   -- contains a DER encoding of a value
+ *                   -- of the type registered for use with
+ *                   -- the extnId object identifier value
+ * }
+ * </pre>
+ * Since not all extensions are known, the {@code getExtensionValue}
+ * method returns the DER-encoded OCTET STRING of the
+ * extension value (i.e., the {@code extnValue}). This can then
+ * be handled by a <em>Class</em> that understands the extension.
+ *
+ * @author Hemma Prafullchandra
+ */
+
+public interface X509Extension {
+
+    /**
+     * Check if there is a critical extension that is not supported.
+     *
+     * @return {@code true} if a critical extension is found that is
+     * not supported, otherwise {@code false}.
+     */
+    public boolean hasUnsupportedCriticalExtension();
+
+    /**
+     * Gets a Set of the OID strings for the extension(s) marked
+     * CRITICAL in the certificate/CRL managed by the object
+     * implementing this interface.
+     *
+     * Here is sample code to get a Set of critical extensions from an
+     * X509Certificate and print the OIDs:
+     * <pre>{@code
+     * X509Certificate cert = null;
+     * try (InputStream inStrm = new FileInputStream("DER-encoded-Cert")) {
+     *     CertificateFactory cf = CertificateFactory.getInstance("X.509");
+     *     cert = (X509Certificate)cf.generateCertificate(inStrm);
+     * }
+     *
+     * Set<String> critSet = cert.getCriticalExtensionOIDs();
+     * if (critSet != null && !critSet.isEmpty()) {
+     *     System.out.println("Set of critical extensions:");
+     *     for (String oid : critSet) {
+     *         System.out.println(oid);
+     *     }
+     * }
+     * }</pre>
+     * @return a Set (or an empty Set if none are marked critical) of
+     * the extension OID strings for extensions that are marked critical.
+     * If there are no extensions present at all, then this method returns
+     * null.
+     */
+    public Set<String> getCriticalExtensionOIDs();
+
+    /**
+     * Gets a Set of the OID strings for the extension(s) marked
+     * NON-CRITICAL in the certificate/CRL managed by the object
+     * implementing this interface.
+     *
+     * Here is sample code to get a Set of non-critical extensions from an
+     * X509CRL revoked certificate entry and print the OIDs:
+     * <pre>{@code
+     * CertificateFactory cf = null;
+     * X509CRL crl = null;
+     * try (InputStream inStrm = new FileInputStream("DER-encoded-CRL")) {
+     *     cf = CertificateFactory.getInstance("X.509");
+     *     crl = (X509CRL)cf.generateCRL(inStrm);
+     * }
+     *
+     * byte[] certData = <DER-encoded certificate data>
+     * ByteArrayInputStream bais = new ByteArrayInputStream(certData);
+     * X509Certificate cert = (X509Certificate)cf.generateCertificate(bais);
+     * X509CRLEntry badCert =
+     *              crl.getRevokedCertificate(cert.getSerialNumber());
+     *
+     * if (badCert != null) {
+     *     Set<String> nonCritSet = badCert.getNonCriticalExtensionOIDs();
+     *     if (nonCritSet != null)
+     *         for (String oid : nonCritSet) {
+     *             System.out.println(oid);
+     *         }
+     * }
+     * }</pre>
+     *
+     * @return a Set (or an empty Set if none are marked non-critical) of
+     * the extension OID strings for extensions that are marked non-critical.
+     * If there are no extensions present at all, then this method returns
+     * null.
+     */
+    public Set<String> getNonCriticalExtensionOIDs();
+
+    /**
+     * Gets the DER-encoded OCTET string for the extension value
+     * (<em>extnValue</em>) identified by the passed-in {@code oid}
+     * String.
+     * The {@code oid} string is
+     * represented by a set of nonnegative whole numbers separated
+     * by periods.
+     *
+     * <p>For example:<br>
+     * <table border=groove summary="Examples of OIDs and extension names">
+     * <tr>
+     * <th>OID <em>(Object Identifier)</em></th>
+     * <th>Extension Name</th></tr>
+     * <tr><td>2.5.29.14</td>
+     * <td>SubjectKeyIdentifier</td></tr>
+     * <tr><td>2.5.29.15</td>
+     * <td>KeyUsage</td></tr>
+     * <tr><td>2.5.29.16</td>
+     * <td>PrivateKeyUsage</td></tr>
+     * <tr><td>2.5.29.17</td>
+     * <td>SubjectAlternativeName</td></tr>
+     * <tr><td>2.5.29.18</td>
+     * <td>IssuerAlternativeName</td></tr>
+     * <tr><td>2.5.29.19</td>
+     * <td>BasicConstraints</td></tr>
+     * <tr><td>2.5.29.30</td>
+     * <td>NameConstraints</td></tr>
+     * <tr><td>2.5.29.33</td>
+     * <td>PolicyMappings</td></tr>
+     * <tr><td>2.5.29.35</td>
+     * <td>AuthorityKeyIdentifier</td></tr>
+     * <tr><td>2.5.29.36</td>
+     * <td>PolicyConstraints</td></tr>
+     * </table>
+     *
+     * @param oid the Object Identifier value for the extension.
+     * @return the DER-encoded octet string of the extension value or
+     * null if it is not present.
+     */
+    public byte[] getExtensionValue(String oid);
+}
diff --git a/java/security/cert/package-info.java b/java/security/cert/package-info.java
new file mode 100644
index 0000000..0ef896b
--- /dev/null
+++ b/java/security/cert/package-info.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 1998, 2013, 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.
+ */
+
+/**
+ * Provides classes and interfaces for parsing and managing
+ * certificates, certificate revocation lists (CRLs), and
+ * certification paths. It contains support for X.509 v3
+ * certificates and X.509 v2 CRLs.
+ *
+ * <h2>Package Specification</h2>
+ *
+ * <ul>
+ *   <li><a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/CryptoSpec.html">
+ *     <b>Java&trade;
+ *     Cryptography Architecture (JCA) Reference Guide</b></a>
+ *   <li>RFC 5280: Internet X.509 Public Key Infrastructure Certificate and
+ *     Certificate Revocation List (CRL) Profile
+ *   <li>RFC 2560: X.509 Internet Public Key Infrastructure Online Certificate
+ *     Status Protocol - OCSP
+ *   <li><a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html">
+ *     <b>Java&trade;
+ *     Cryptography Architecture Standard Algorithm Name
+ *     Documentation</b></a></li>
+ * </ul>
+ *
+ * <h2>Related Documentation</h2>
+ *
+ * For information about X.509 certificates and CRLs, please see:
+ * <ul>
+ *   <li><a href="http://www.ietf.org/rfc/rfc5280.txt">
+ *     http://www.ietf.org/rfc/rfc5280.txt</a>
+ *   <li><a href=
+ *     "{@docRoot}/../technotes/guides/security/certpath/CertPathProgGuide.html">
+ *     <b>Java&trade;
+ *     PKI Programmer's Guide</b></a>
+ *   <li><a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/cert3.html">
+ *     <b>X.509 Certificates and Certificate Revocation Lists (CRLs)</b></a>
+ * </ul>
+ *
+ * @since 1.2
+ */
+package java.security.cert;
diff --git a/java/security/interfaces/DSAKey.java b/java/security/interfaces/DSAKey.java
new file mode 100644
index 0000000..d78b3e1
--- /dev/null
+++ b/java/security/interfaces/DSAKey.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1996, 1998, 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 java.security.interfaces;
+
+/**
+ * The interface to a DSA public or private key. DSA (Digital Signature
+ * Algorithm) is defined in NIST's FIPS-186.
+ *
+ * @see DSAParams
+ * @see java.security.Key
+ * @see java.security.Signature
+ *
+ * @author Benjamin Renaud
+ * @author Josh Bloch
+ */
+public interface DSAKey {
+
+    /**
+     * Returns the DSA-specific key parameters. These parameters are
+     * never secret.
+     *
+     * @return the DSA-specific key parameters.
+     *
+     * @see DSAParams
+     */
+    public DSAParams getParams();
+}
diff --git a/java/security/interfaces/DSAKeyPairGenerator.java b/java/security/interfaces/DSAKeyPairGenerator.java
new file mode 100644
index 0000000..e50cfd2
--- /dev/null
+++ b/java/security/interfaces/DSAKeyPairGenerator.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security.interfaces;
+
+import java.security.*;
+
+/**
+ * An interface to an object capable of generating DSA key pairs.
+ *
+ * <p>The {@code initialize} methods may each be called any number
+ * of times. If no {@code initialize} method is called on a
+ * DSAKeyPairGenerator, the default is to generate 1024-bit keys, using
+ * precomputed p, q and g parameters and an instance of SecureRandom as
+ * the random bit source.
+ *
+ * <p>Users wishing to indicate DSA-specific parameters, and to generate a key
+ * pair suitable for use with the DSA algorithm typically
+ *
+ * <ol>
+ *
+ * <li>Get a key pair generator for the DSA algorithm by calling the
+ * KeyPairGenerator {@code getInstance} method with "DSA"
+ * as its argument.
+ *
+ * <li>Initialize the generator by casting the result to a DSAKeyPairGenerator
+ * and calling one of the
+ * {@code initialize} methods from this DSAKeyPairGenerator interface.
+ *
+ * <li>Generate a key pair by calling the {@code generateKeyPair}
+ * method from the KeyPairGenerator class.
+ *
+ * </ol>
+ *
+ * <p>Note: it is not always necessary to do do algorithm-specific
+ * initialization for a DSA key pair generator. That is, it is not always
+ * necessary to call an {@code initialize} method in this interface.
+ * Algorithm-independent initialization using the {@code initialize} method
+ * in the KeyPairGenerator
+ * interface is all that is needed when you accept defaults for algorithm-specific
+ * parameters.
+ *
+ * <p>Note: Some earlier implementations of this interface may not support
+ * larger sizes of DSA parameters such as 2048 and 3072-bit.
+ *
+ * @see java.security.KeyPairGenerator
+ */
+public interface DSAKeyPairGenerator {
+
+    /**
+     * Initializes the key pair generator using the DSA family parameters
+     * (p,q and g) and an optional SecureRandom bit source. If a
+     * SecureRandom bit source is needed but not supplied, i.e. null, a
+     * default SecureRandom instance will be used.
+     *
+     * @param params the parameters to use to generate the keys.
+     *
+     * @param random the random bit source to use to generate key bits;
+     * can be null.
+     *
+     * @exception InvalidParameterException if the {@code params}
+     * value is invalid, null, or unsupported.
+     */
+   public void initialize(DSAParams params, SecureRandom random)
+   throws InvalidParameterException;
+
+    /**
+     * Initializes the key pair generator for a given modulus length
+     * (instead of parameters), and an optional SecureRandom bit source.
+     * If a SecureRandom bit source is needed but not supplied, i.e.
+     * null, a default SecureRandom instance will be used.
+     *
+     * <p>If {@code genParams} is true, this method generates new
+     * p, q and g parameters. If it is false, the method uses precomputed
+     * parameters for the modulus length requested. If there are no
+     * precomputed parameters for that modulus length, an exception will be
+     * thrown. It is guaranteed that there will always be
+     * default parameters for modulus lengths of 512 and 1024 bits.
+     *
+     * @param modlen the modulus length in bits. Valid values are any
+     * multiple of 64 between 512 and 1024, inclusive, 2048, and 3072.
+     *
+     * @param random the random bit source to use to generate key bits;
+     * can be null.
+     *
+     * @param genParams whether or not to generate new parameters for
+     * the modulus length requested.
+     *
+     * @exception InvalidParameterException if {@code modlen} is
+     * invalid, or unsupported, or if {@code genParams} is false and there
+     * are no precomputed parameters for the requested modulus length.
+     */
+    public void initialize(int modlen, boolean genParams, SecureRandom random)
+    throws InvalidParameterException;
+}
diff --git a/java/security/interfaces/DSAParams.java b/java/security/interfaces/DSAParams.java
new file mode 100644
index 0000000..8c46ed5
--- /dev/null
+++ b/java/security/interfaces/DSAParams.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 1996, 2013, 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 java.security.interfaces;
+
+import java.math.BigInteger;
+
+/**
+ * Interface to a DSA-specific set of key parameters, which defines a
+ * DSA <em>key family</em>. DSA (Digital Signature Algorithm) is defined
+ * in NIST's FIPS-186.
+ *
+ * @see DSAKey
+ * @see java.security.Key
+ * @see java.security.Signature
+ *
+ * @author Benjamin Renaud
+ * @author Josh Bloch
+ */
+public interface DSAParams {
+
+    /**
+     * Returns the prime, {@code p}.
+     *
+     * @return the prime, {@code p}.
+     */
+    public BigInteger getP();
+
+    /**
+     * Returns the subprime, {@code q}.
+     *
+     * @return the subprime, {@code q}.
+     */
+    public BigInteger getQ();
+
+    /**
+     * Returns the base, {@code g}.
+     *
+     * @return the base, {@code g}.
+     */
+    public BigInteger getG();
+}
diff --git a/java/security/interfaces/DSAPrivateKey.java b/java/security/interfaces/DSAPrivateKey.java
new file mode 100644
index 0000000..81ab358
--- /dev/null
+++ b/java/security/interfaces/DSAPrivateKey.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security.interfaces;
+
+import java.math.BigInteger;
+
+/**
+ * The standard interface to a DSA private key. DSA (Digital Signature
+ * Algorithm) is defined in NIST's FIPS-186.
+ *
+ * @see java.security.Key
+ * @see java.security.Signature
+ * @see DSAKey
+ * @see DSAPublicKey
+ *
+ * @author Benjamin Renaud
+ */
+public interface DSAPrivateKey extends DSAKey, java.security.PrivateKey {
+
+    // Declare serialVersionUID to be compatible with JDK1.1
+
+   /**
+    * The class fingerprint that is set to indicate
+    * serialization compatibility with a previous
+    * version of the class.
+    */
+    static final long serialVersionUID = 7776497482533790279L;
+
+    /**
+     * Returns the value of the private key, {@code x}.
+     *
+     * @return the value of the private key, {@code x}.
+     */
+    public BigInteger getX();
+}
diff --git a/java/security/interfaces/DSAPublicKey.java b/java/security/interfaces/DSAPublicKey.java
new file mode 100644
index 0000000..e56b795
--- /dev/null
+++ b/java/security/interfaces/DSAPublicKey.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1996, 2013, 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 java.security.interfaces;
+
+import java.math.BigInteger;
+
+/**
+ * The interface to a DSA public key. DSA (Digital Signature Algorithm)
+ * is defined in NIST's FIPS-186.
+ *
+ * @see java.security.Key
+ * @see java.security.Signature
+ * @see DSAKey
+ * @see DSAPrivateKey
+ *
+ * @author Benjamin Renaud
+ */
+public interface DSAPublicKey extends DSAKey, java.security.PublicKey {
+
+    // Declare serialVersionUID to be compatible with JDK1.1
+
+   /**
+    * The class fingerprint that is set to indicate
+    * serialization compatibility with a previous
+    * version of the class.
+    */
+    static final long serialVersionUID = 1234526332779022332L;
+
+    /**
+     * Returns the value of the public key, {@code y}.
+     *
+     * @return the value of the public key, {@code y}.
+     */
+    public BigInteger getY();
+}
diff --git a/java/security/interfaces/ECKey.java b/java/security/interfaces/ECKey.java
new file mode 100644
index 0000000..dd4b9d1
--- /dev/null
+++ b/java/security/interfaces/ECKey.java
@@ -0,0 +1,45 @@
+/*
+ * 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.  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 java.security.interfaces;
+
+import java.security.spec.ECParameterSpec;
+
+/**
+ * The interface to an elliptic curve (EC) key.
+ *
+ * @author Valerie Peng
+ *
+ * @since 1.5
+ */
+public interface ECKey {
+    /**
+     * Returns the domain parameters associated
+     * with this key. The domain parameters are
+     * either explicitly specified or implicitly
+     * created during key generation.
+     * @return the associated domain parameters.
+     */
+    ECParameterSpec getParams();
+}
diff --git a/java/security/interfaces/ECPrivateKey.java b/java/security/interfaces/ECPrivateKey.java
new file mode 100644
index 0000000..0ccdc2d
--- /dev/null
+++ b/java/security/interfaces/ECPrivateKey.java
@@ -0,0 +1,53 @@
+/*
+ * 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.  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 java.security.interfaces;
+
+import java.math.BigInteger;
+import java.security.PrivateKey;
+
+/**
+ * The interface to an elliptic curve (EC) private key.
+ *
+ * @author Valerie Peng
+ *
+ *
+ * @see PrivateKey
+ * @see ECKey
+ *
+ * @since 1.5
+ */
+public interface ECPrivateKey extends PrivateKey, ECKey {
+   /**
+    * The class fingerprint that is set to indicate
+    * serialization compatibility.
+    */
+    static final long serialVersionUID = -7896394956925609184L;
+
+    /**
+     * Returns the private value S.
+     * @return the private value S.
+     */
+    BigInteger getS();
+}
diff --git a/java/security/interfaces/ECPublicKey.java b/java/security/interfaces/ECPublicKey.java
new file mode 100644
index 0000000..6d16157
--- /dev/null
+++ b/java/security/interfaces/ECPublicKey.java
@@ -0,0 +1,55 @@
+/*
+ * 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.  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 java.security.interfaces;
+
+import java.security.PublicKey;
+import java.security.spec.ECPoint;
+
+/**
+ * The interface to an elliptic curve (EC) public key.
+ *
+ * @author Valerie Peng
+ *
+ *
+ * @see PublicKey
+ * @see ECKey
+ * @see java.security.spec.ECPoint
+ *
+ * @since 1.5
+ */
+public interface ECPublicKey extends PublicKey, ECKey {
+
+   /**
+    * The class fingerprint that is set to indicate
+    * serialization compatibility.
+    */
+    static final long serialVersionUID = -3314988629879632826L;
+
+    /**
+     * Returns the public point W.
+     * @return the public point W.
+     */
+    ECPoint getW();
+}
diff --git a/java/security/interfaces/RSAKey.java b/java/security/interfaces/RSAKey.java
new file mode 100644
index 0000000..67fbe2b
--- /dev/null
+++ b/java/security/interfaces/RSAKey.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 1999, 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 java.security.interfaces;
+
+import java.math.BigInteger;
+
+/**
+ * The interface to an RSA public or private key.
+ *
+ * @author Jan Luehe
+ *
+ * @see RSAPublicKey
+ * @see RSAPrivateKey
+ *
+ * @since 1.3
+ */
+
+public interface RSAKey {
+
+    /**
+     * Returns the modulus.
+     *
+     * @return the modulus
+     */
+    public BigInteger getModulus();
+}
diff --git a/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java b/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java
new file mode 100644
index 0000000..f85d96a
--- /dev/null
+++ b/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2001, 2013, 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 java.security.interfaces;
+
+import java.math.BigInteger;
+import java.security.spec.RSAOtherPrimeInfo;
+
+/**
+ * The interface to an RSA multi-prime private key, as defined in the
+ * PKCS#1 v2.1, using the <i>Chinese Remainder Theorem</i>
+ * (CRT) information values.
+ *
+ * @author Valerie Peng
+ *
+ *
+ * @see java.security.spec.RSAPrivateKeySpec
+ * @see java.security.spec.RSAMultiPrimePrivateCrtKeySpec
+ * @see RSAPrivateKey
+ * @see RSAPrivateCrtKey
+ *
+ * @since 1.4
+ */
+
+public interface RSAMultiPrimePrivateCrtKey extends RSAPrivateKey {
+
+    /**
+     * The type fingerprint that is set to indicate
+     * serialization compatibility with a previous
+     * version of the type.
+     */
+    static final long serialVersionUID = 618058533534628008L;
+
+    /**
+     * Returns the public exponent.
+     *
+     * @return the public exponent.
+     */
+    public BigInteger getPublicExponent();
+
+    /**
+     * Returns the primeP.
+     *
+     * @return the primeP.
+     */
+    public BigInteger getPrimeP();
+
+    /**
+     * Returns the primeQ.
+     *
+     * @return the primeQ.
+     */
+    public BigInteger getPrimeQ();
+
+    /**
+     * Returns the primeExponentP.
+     *
+     * @return the primeExponentP.
+     */
+    public BigInteger getPrimeExponentP();
+
+    /**
+     * Returns the primeExponentQ.
+     *
+     * @return the primeExponentQ.
+     */
+    public BigInteger getPrimeExponentQ();
+
+    /**
+     * Returns the crtCoefficient.
+     *
+     * @return the crtCoefficient.
+     */
+    public BigInteger getCrtCoefficient();
+
+    /**
+     * Returns the otherPrimeInfo or null if there are only
+     * two prime factors (p and q).
+     *
+     * @return the otherPrimeInfo.
+     */
+    public RSAOtherPrimeInfo[] getOtherPrimeInfo();
+}
diff --git a/java/security/interfaces/RSAPrivateCrtKey.java b/java/security/interfaces/RSAPrivateCrtKey.java
new file mode 100644
index 0000000..0408fea
--- /dev/null
+++ b/java/security/interfaces/RSAPrivateCrtKey.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 1998, 2013, 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 java.security.interfaces;
+
+import java.math.BigInteger;
+
+/**
+ * The interface to an RSA private key, as defined in the PKCS#1 standard,
+ * using the <i>Chinese Remainder Theorem</i> (CRT) information values.
+ *
+ * @author Jan Luehe
+ *
+ *
+ * @see RSAPrivateKey
+ */
+
+public interface RSAPrivateCrtKey extends RSAPrivateKey {
+
+    /**
+     * The type fingerprint that is set to indicate
+     * serialization compatibility with a previous
+     * version of the type.
+     */
+    static final long serialVersionUID = -5682214253527700368L;
+
+    /**
+     * Returns the public exponent.
+     *
+     * @return the public exponent
+     */
+    public BigInteger getPublicExponent();
+
+    /**
+     * Returns the primeP.
+
+     * @return the primeP
+     */
+    public BigInteger getPrimeP();
+
+    /**
+     * Returns the primeQ.
+     *
+     * @return the primeQ
+     */
+    public BigInteger getPrimeQ();
+
+    /**
+     * Returns the primeExponentP.
+     *
+     * @return the primeExponentP
+     */
+    public BigInteger getPrimeExponentP();
+
+    /**
+     * Returns the primeExponentQ.
+     *
+     * @return the primeExponentQ
+     */
+    public BigInteger getPrimeExponentQ();
+
+    /**
+     * Returns the crtCoefficient.
+     *
+     * @return the crtCoefficient
+     */
+    public BigInteger getCrtCoefficient();
+}
diff --git a/java/security/interfaces/RSAPrivateKey.java b/java/security/interfaces/RSAPrivateKey.java
new file mode 100644
index 0000000..5d69ad6
--- /dev/null
+++ b/java/security/interfaces/RSAPrivateKey.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1998, 2013, 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 java.security.interfaces;
+
+import java.math.BigInteger;
+
+/**
+ * The interface to an RSA private key.
+ *
+ * @author Jan Luehe
+ *
+ *
+ * @see RSAPrivateCrtKey
+ */
+
+public interface RSAPrivateKey extends java.security.PrivateKey, RSAKey
+{
+
+    /**
+     * The type fingerprint that is set to indicate
+     * serialization compatibility with a previous
+     * version of the type.
+     */
+    static final long serialVersionUID = 5187144804936595022L;
+
+    /**
+     * Returns the private exponent.
+     *
+     * @return the private exponent
+     */
+    public BigInteger getPrivateExponent();
+}
diff --git a/java/security/interfaces/RSAPublicKey.java b/java/security/interfaces/RSAPublicKey.java
new file mode 100644
index 0000000..a698c05
--- /dev/null
+++ b/java/security/interfaces/RSAPublicKey.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1998, 2013, 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 java.security.interfaces;
+
+import java.math.BigInteger;
+
+/**
+ * The interface to an RSA public key.
+ *
+ * @author Jan Luehe
+ *
+ */
+
+public interface RSAPublicKey extends java.security.PublicKey, RSAKey
+{
+    /**
+     * The type fingerprint that is set to indicate
+     * serialization compatibility with a previous
+     * version of the type.
+     */
+    static final long serialVersionUID = -8727434096241101194L;
+
+    /**
+     * Returns the public exponent.
+     *
+     * @return the public exponent
+     */
+    public BigInteger getPublicExponent();
+}
diff --git a/java/security/interfaces/package-info.java b/java/security/interfaces/package-info.java
new file mode 100644
index 0000000..a2d77da
--- /dev/null
+++ b/java/security/interfaces/package-info.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1998, 2013, 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.
+ */
+
+/**
+ * Provides interfaces for generating RSA (Rivest, Shamir and
+ * Adleman AsymmetricCipher algorithm)
+ * keys as defined in the RSA Laboratory Technical Note
+ * PKCS#1, and DSA (Digital Signature
+ * Algorithm) keys as defined in NIST's FIPS-186.
+ * <P>
+ * Note that these interfaces are intended only for key
+ * implementations whose key material is accessible and
+ * available. These interfaces are not intended for key
+ * implementations whose key material resides in
+ * inaccessible, protected storage (such as in a
+ * hardware device).
+ * <P>
+ * For more developer information on how to use these
+ * interfaces, including information on how to design
+ * {@code Key} classes for hardware devices, please refer
+ * to these cryptographic provider developer guides:
+ * <ul>
+ *   <li><a href=
+ *     "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/HowToImplAProvider.html">
+ *     <b>How to Implement a Provider for the
+ *     Java&trade; Cryptography Architecture
+ *     </b></a></li>
+ * </ul>
+ *
+ * <h2>Package Specification</h2>
+ *
+ * <ul>
+ *   <li>PKCS #1: RSA Encryption Standard, Version 1.5, November 1993 </li>
+ *   <li>Federal Information Processing Standards Publication (FIPS PUB) 186:
+ *     Digital Signature Standard (DSS) </li>
+ * </ul>
+ *
+ * <h2>Related Documentation</h2>
+ *
+ * For further documentation, please see:
+ * <ul>
+ *   <li>
+ *     <a href=
+ *       "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/CryptoSpec.html">
+ *       <b>Java&trade;
+ *       Cryptography Architecture API Specification and Reference
+ *       </b></a></li>
+ * </ul>
+ *
+ * @since JDK1.1
+ */
+package java.security.interfaces;
diff --git a/java/security/package-info.java b/java/security/package-info.java
new file mode 100644
index 0000000..376aa9d
--- /dev/null
+++ b/java/security/package-info.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 1998, 2013, 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.
+ */
+
+/**
+ * Provides the classes and interfaces for the security framework.
+ * This includes classes that implement an easily configurable,
+ * fine-grained access control security architecture.
+ * This package also supports
+ * the generation and storage of cryptographic public key pairs,
+ * as well as a number of exportable cryptographic operations
+ * including those for message digest and signature generation.  Finally,
+ * this package provides classes that support signed/guarded objects
+ * and secure random number generation.
+ *
+ * Many of the classes provided in this package (the cryptographic
+ * and secure random number generator classes in particular) are
+ * provider-based.  The class itself defines a programming interface
+ * to which applications may write.  The implementations themselves may
+ * then be written by independent third-party vendors and plugged
+ * in seamlessly as needed.  Therefore application developers may
+ * take advantage of any number of provider-based implementations
+ * without having to add or rewrite code.
+ *
+ * <h2>Package Specification</h2>
+ *
+ * <ul>
+ *   <li><a href="{@docRoot}openjdk-redirect.html?v=8&path=/../technotes/guides/security/crypto/CryptoSpec.html">
+ *     <b>Java&trade;
+ *     Cryptography Architecture (JCA) Reference Guide</b></a></li>
+ *
+ *   <li>PKCS #8: Private-Key Information Syntax Standard, Version 1.2,
+ *     November 1993</li>
+ *
+ *   <li><a href="{@docRoot}openjdk-redirect.html?v=8&path=/../technotes/guides/security/StandardNames.html">
+ *     <b>Java&trade;
+ *     Cryptography Architecture Standard Algorithm Name
+ *     Documentation</b></a></li>
+ * </ul>
+ *
+ * <h2>Related Documentation</h2>
+ *
+ * For further documentation, please see:
+ * <ul>
+ *   <li><a href=
+ *     "{@docRoot}openjdk-redirect.html?v=8&path=/../technotes/guides/security/spec/security-spec.doc.html">
+ *     <b>Java&trade;
+ *     SE Platform Security Architecture</b></a></li>
+ *
+ *   <li><a href=
+ *     "{@docRoot}openjdk-redirect.html?v=8&path=/../technotes/guides/security/crypto/HowToImplAProvider.html">
+ *     <b>How to Implement a Provider in the
+ *     Java&trade; Cryptography Architecture
+ *     </b></a></li>
+ *
+ *   <li><a href=
+ *     "{@docRoot}openjdk-redirect.html?v=8&path=/../technotes/guides/security/PolicyFiles.html"><b>
+ *     Default Policy Implementation and Policy File Syntax
+ *     </b></a></li>
+ *
+ *   <li><a href=
+ *     "{@docRoot}openjdk-redirect.html?v=8&path=/../technotes/guides/security/permissions.html"><b>
+ *     Permissions in the
+ *     Java&trade; SE Development Kit (JDK)
+ *     </b></a></li>
+ *
+ *   <li><a href=
+ *     "{@docRoot}openjdk-redirect.html?v=8&path=/../technotes/guides/security/SecurityToolsSummary.html"><b>
+ *     Summary of Tools for
+ *     Java&trade; Platform Security
+ *     </b></a></li>
+ *
+ *   <li><b>keytool</b>
+ *     (<a href="{@docRoot}openjdk-redirect.html?v=8&path=/../technotes/tools/unix/keytool.html">
+ *       for Solaris/Linux</a>)
+ *     (<a href="{@docRoot}openjdk-redirect.html?v=8&path=/../technotes/tools/windows/keytool.html">
+ *       for Windows</a>)
+ *     </li>
+ *
+ *   <li><b>jarsigner</b>
+ *     (<a href="{@docRoot}openjdk-redirect.html?v=8&path=/../technotes/tools/unix/jarsigner.html">
+ *       for Solaris/Linux</a>)
+ *     (<a href="{@docRoot}openjdk-redirect.html?v=8&path=/../technotes/tools/windows/jarsigner.html">
+ *       for Windows</a>)
+ *     </li>
+ *
+ * </ul>
+ *
+ * @since 1.1
+ */
+package java.security;
diff --git a/java/security/spec/AlgorithmParameterSpec.java b/java/security/spec/AlgorithmParameterSpec.java
new file mode 100644
index 0000000..7714c30
--- /dev/null
+++ b/java/security/spec/AlgorithmParameterSpec.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 1997, 1999, 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 java.security.spec;
+
+/**
+ * A (transparent) specification of cryptographic parameters.
+ *
+ * <P> This interface contains no methods or constants. Its only purpose
+ * is to group (and provide type safety for) all parameter specifications.
+ * All parameter specifications must implement this interface.
+ *
+ * @author Jan Luehe
+ *
+ *
+ * @see java.security.AlgorithmParameters
+ * @see DSAParameterSpec
+ *
+ * @since 1.2
+ */
+
+public interface AlgorithmParameterSpec { }
diff --git a/java/security/spec/DSAParameterSpec.java b/java/security/spec/DSAParameterSpec.java
new file mode 100644
index 0000000..eed6bdc
--- /dev/null
+++ b/java/security/spec/DSAParameterSpec.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security.spec;
+
+import java.math.BigInteger;
+
+/**
+ * This class specifies the set of parameters used with the DSA algorithm.
+ *
+ * @author Jan Luehe
+ *
+ *
+ * @see AlgorithmParameterSpec
+ *
+ * @since 1.2
+ */
+
+public class DSAParameterSpec implements AlgorithmParameterSpec,
+java.security.interfaces.DSAParams {
+
+    BigInteger p;
+    BigInteger q;
+    BigInteger g;
+
+    /**
+     * Creates a new DSAParameterSpec with the specified parameter values.
+     *
+     * @param p the prime.
+     *
+     * @param q the sub-prime.
+     *
+     * @param g the base.
+     */
+    public DSAParameterSpec(BigInteger p, BigInteger q, BigInteger g) {
+        this.p = p;
+        this.q = q;
+        this.g = g;
+    }
+
+    /**
+     * Returns the prime {@code p}.
+     *
+     * @return the prime {@code p}.
+     */
+    public BigInteger getP() {
+        return this.p;
+    }
+
+    /**
+     * Returns the sub-prime {@code q}.
+     *
+     * @return the sub-prime {@code q}.
+     */
+    public BigInteger getQ() {
+        return this.q;
+    }
+
+    /**
+     * Returns the base {@code g}.
+     *
+     * @return the base {@code g}.
+     */
+    public BigInteger getG() {
+        return this.g;
+    }
+}
diff --git a/java/security/spec/DSAPrivateKeySpec.java b/java/security/spec/DSAPrivateKeySpec.java
new file mode 100644
index 0000000..a004de7
--- /dev/null
+++ b/java/security/spec/DSAPrivateKeySpec.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security.spec;
+
+import java.math.BigInteger;
+
+/**
+ * This class specifies a DSA private key with its associated parameters.
+ *
+ * @author Jan Luehe
+ *
+ *
+ * @see java.security.Key
+ * @see java.security.KeyFactory
+ * @see KeySpec
+ * @see DSAPublicKeySpec
+ * @see PKCS8EncodedKeySpec
+ *
+ * @since 1.2
+ */
+
+public class DSAPrivateKeySpec implements KeySpec {
+
+    private BigInteger x;
+    private BigInteger p;
+    private BigInteger q;
+    private BigInteger g;
+
+    /**
+     * Creates a new DSAPrivateKeySpec with the specified parameter values.
+     *
+     * @param x the private key.
+     *
+     * @param p the prime.
+     *
+     * @param q the sub-prime.
+     *
+     * @param g the base.
+     */
+    public DSAPrivateKeySpec(BigInteger x, BigInteger p, BigInteger q,
+                             BigInteger g) {
+        this.x = x;
+        this.p = p;
+        this.q = q;
+        this.g = g;
+    }
+
+    /**
+     * Returns the private key {@code x}.
+     *
+     * @return the private key {@code x}.
+     */
+    public BigInteger getX() {
+        return this.x;
+    }
+
+    /**
+     * Returns the prime {@code p}.
+     *
+     * @return the prime {@code p}.
+     */
+    public BigInteger getP() {
+        return this.p;
+    }
+
+    /**
+     * Returns the sub-prime {@code q}.
+     *
+     * @return the sub-prime {@code q}.
+     */
+    public BigInteger getQ() {
+        return this.q;
+    }
+
+    /**
+     * Returns the base {@code g}.
+     *
+     * @return the base {@code g}.
+     */
+    public BigInteger getG() {
+        return this.g;
+    }
+}
diff --git a/java/security/spec/DSAPublicKeySpec.java b/java/security/spec/DSAPublicKeySpec.java
new file mode 100644
index 0000000..a56e6f9
--- /dev/null
+++ b/java/security/spec/DSAPublicKeySpec.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security.spec;
+
+import java.math.BigInteger;
+
+/**
+ * This class specifies a DSA public key with its associated parameters.
+ *
+ * @author Jan Luehe
+ *
+ *
+ * @see java.security.Key
+ * @see java.security.KeyFactory
+ * @see KeySpec
+ * @see DSAPrivateKeySpec
+ * @see X509EncodedKeySpec
+ *
+ * @since 1.2
+ */
+
+public class DSAPublicKeySpec implements KeySpec {
+
+    private BigInteger y;
+    private BigInteger p;
+    private BigInteger q;
+    private BigInteger g;
+
+    /**
+     * Creates a new DSAPublicKeySpec with the specified parameter values.
+     *
+     * @param y the public key.
+     *
+     * @param p the prime.
+     *
+     * @param q the sub-prime.
+     *
+     * @param g the base.
+     */
+    public DSAPublicKeySpec(BigInteger y, BigInteger p, BigInteger q,
+                            BigInteger g) {
+        this.y = y;
+        this.p = p;
+        this.q = q;
+        this.g = g;
+    }
+
+    /**
+     * Returns the public key {@code y}.
+     *
+     * @return the public key {@code y}.
+     */
+    public BigInteger getY() {
+        return this.y;
+    }
+
+    /**
+     * Returns the prime {@code p}.
+     *
+     * @return the prime {@code p}.
+     */
+    public BigInteger getP() {
+        return this.p;
+    }
+
+    /**
+     * Returns the sub-prime {@code q}.
+     *
+     * @return the sub-prime {@code q}.
+     */
+    public BigInteger getQ() {
+        return this.q;
+    }
+
+    /**
+     * Returns the base {@code g}.
+     *
+     * @return the base {@code g}.
+     */
+    public BigInteger getG() {
+        return this.g;
+    }
+}
diff --git a/java/security/spec/ECField.java b/java/security/spec/ECField.java
new file mode 100644
index 0000000..6a42521
--- /dev/null
+++ b/java/security/spec/ECField.java
@@ -0,0 +1,49 @@
+/*
+ * 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.  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 java.security.spec;
+
+import java.math.BigInteger;
+import java.util.Arrays;
+
+/**
+ * This interface represents an elliptic curve (EC) finite field.
+ * All specialized EC fields must implements this interface.
+ *
+ * @see ECFieldFp
+ * @see ECFieldF2m
+ *
+ * @author Valerie Peng
+ *
+ * @since 1.5
+ */
+public interface ECField {
+    /**
+     * Returns the field size in bits. Note: For prime finite
+     * field ECFieldFp, size of prime p in bits is returned.
+     * For characteristic 2 finite field ECFieldF2m, m is returned.
+     * @return the field size in bits.
+     */
+    int getFieldSize();
+}
diff --git a/java/security/spec/ECFieldF2m.java b/java/security/spec/ECFieldF2m.java
new file mode 100644
index 0000000..4076fa6
--- /dev/null
+++ b/java/security/spec/ECFieldF2m.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2003, 2013, 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 java.security.spec;
+
+import java.math.BigInteger;
+import java.util.Arrays;
+
+/**
+ * This immutable class defines an elliptic curve (EC)
+ * characteristic 2 finite field.
+ *
+ * @see ECField
+ *
+ * @author Valerie Peng
+ *
+ * @since 1.5
+ */
+public class ECFieldF2m implements ECField {
+
+    private int m;
+    private int[] ks;
+    private BigInteger rp;
+
+    /**
+     * Creates an elliptic curve characteristic 2 finite
+     * field which has 2^{@code m} elements with normal basis.
+     * @param m with 2^{@code m} being the number of elements.
+     * @exception IllegalArgumentException if {@code m}
+     * is not positive.
+     */
+    public ECFieldF2m(int m) {
+        if (m <= 0) {
+            throw new IllegalArgumentException("m is not positive");
+        }
+        this.m = m;
+        this.ks = null;
+        this.rp = null;
+    }
+
+    /**
+     * Creates an elliptic curve characteristic 2 finite
+     * field which has 2^{@code m} elements with
+     * polynomial basis.
+     * The reduction polynomial for this field is based
+     * on {@code rp} whose i-th bit corresponds to
+     * the i-th coefficient of the reduction polynomial.<p>
+     * Note: A valid reduction polynomial is either a
+     * trinomial (X^{@code m} + X^{@code k} + 1
+     * with {@code m} &gt; {@code k} &gt;= 1) or a
+     * pentanomial (X^{@code m} + X^{@code k3}
+     * + X^{@code k2} + X^{@code k1} + 1 with
+     * {@code m} &gt; {@code k3} &gt; {@code k2}
+     * &gt; {@code k1} &gt;= 1).
+     * @param m with 2^{@code m} being the number of elements.
+     * @param rp the BigInteger whose i-th bit corresponds to
+     * the i-th coefficient of the reduction polynomial.
+     * @exception NullPointerException if {@code rp} is null.
+     * @exception IllegalArgumentException if {@code m}
+     * is not positive, or {@code rp} does not represent
+     * a valid reduction polynomial.
+     */
+    public ECFieldF2m(int m, BigInteger rp) {
+        // check m and rp
+        this.m = m;
+        this.rp = rp;
+        if (m <= 0) {
+            throw new IllegalArgumentException("m is not positive");
+        }
+        int bitCount = this.rp.bitCount();
+        if (!this.rp.testBit(0) || !this.rp.testBit(m) ||
+            ((bitCount != 3) && (bitCount != 5))) {
+            throw new IllegalArgumentException
+                ("rp does not represent a valid reduction polynomial");
+        }
+        // convert rp into ks
+        BigInteger temp = this.rp.clearBit(0).clearBit(m);
+        this.ks = new int[bitCount-2];
+        for (int i = this.ks.length-1; i >= 0; i--) {
+            int index = temp.getLowestSetBit();
+            this.ks[i] = index;
+            temp = temp.clearBit(index);
+        }
+    }
+
+    /**
+     * Creates an elliptic curve characteristic 2 finite
+     * field which has 2^{@code m} elements with
+     * polynomial basis. The reduction polynomial for this
+     * field is based on {@code ks} whose content
+     * contains the order of the middle term(s) of the
+     * reduction polynomial.
+     * Note: A valid reduction polynomial is either a
+     * trinomial (X^{@code m} + X^{@code k} + 1
+     * with {@code m} &gt; {@code k} &gt;= 1) or a
+     * pentanomial (X^{@code m} + X^{@code k3}
+     * + X^{@code k2} + X^{@code k1} + 1 with
+     * {@code m} &gt; {@code k3} &gt; {@code k2}
+     * &gt; {@code k1} &gt;= 1), so {@code ks} should
+     * have length 1 or 3.
+     * @param m with 2^{@code m} being the number of elements.
+     * @param ks the order of the middle term(s) of the
+     * reduction polynomial. Contents of this array are copied
+     * to protect against subsequent modification.
+     * @exception NullPointerException if {@code ks} is null.
+     * @exception IllegalArgumentException if{@code m}
+     * is not positive, or the length of {@code ks}
+     * is neither 1 nor 3, or values in {@code ks}
+     * are not between {@code m}-1 and 1 (inclusive)
+     * and in descending order.
+     */
+    public ECFieldF2m(int m, int[] ks) {
+        // check m and ks
+        this.m = m;
+        this.ks = ks.clone();
+        if (m <= 0) {
+            throw new IllegalArgumentException("m is not positive");
+        }
+        if ((this.ks.length != 1) && (this.ks.length != 3)) {
+            throw new IllegalArgumentException
+                ("length of ks is neither 1 nor 3");
+        }
+        for (int i = 0; i < this.ks.length; i++) {
+            if ((this.ks[i] < 1) || (this.ks[i] > m-1)) {
+                throw new IllegalArgumentException
+                    ("ks["+ i + "] is out of range");
+            }
+            if ((i != 0) && (this.ks[i] >= this.ks[i-1])) {
+                throw new IllegalArgumentException
+                    ("values in ks are not in descending order");
+            }
+        }
+        // convert ks into rp
+        this.rp = BigInteger.ONE;
+        this.rp = rp.setBit(m);
+        for (int j = 0; j < this.ks.length; j++) {
+            rp = rp.setBit(this.ks[j]);
+        }
+    }
+
+    /**
+     * Returns the field size in bits which is {@code m}
+     * for this characteristic 2 finite field.
+     * @return the field size in bits.
+     */
+    public int getFieldSize() {
+        return m;
+    }
+
+    /**
+     * Returns the value {@code m} of this characteristic
+     * 2 finite field.
+     * @return {@code m} with 2^{@code m} being the
+     * number of elements.
+     */
+    public int getM() {
+        return m;
+    }
+
+    /**
+     * Returns a BigInteger whose i-th bit corresponds to the
+     * i-th coefficient of the reduction polynomial for polynomial
+     * basis or null for normal basis.
+     * @return a BigInteger whose i-th bit corresponds to the
+     * i-th coefficient of the reduction polynomial for polynomial
+     * basis or null for normal basis.
+     */
+    public BigInteger getReductionPolynomial() {
+        return rp;
+    }
+
+    /**
+     * Returns an integer array which contains the order of the
+     * middle term(s) of the reduction polynomial for polynomial
+     * basis or null for normal basis.
+     * @return an integer array which contains the order of the
+     * middle term(s) of the reduction polynomial for polynomial
+     * basis or null for normal basis. A new array is returned
+     * each time this method is called.
+     */
+    public int[] getMidTermsOfReductionPolynomial() {
+        if (ks == null) {
+            return null;
+        } else {
+            return ks.clone();
+        }
+    }
+
+    /**
+     * Compares this finite field for equality with the
+     * specified object.
+     * @param obj the object to be compared.
+     * @return true if {@code obj} is an instance
+     * of ECFieldF2m and both {@code m} and the reduction
+     * polynomial match, false otherwise.
+     */
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+        if (obj instanceof ECFieldF2m) {
+            // no need to compare rp here since ks and rp
+            // should be equivalent
+            return ((m == ((ECFieldF2m)obj).m) &&
+                    (Arrays.equals(ks, ((ECFieldF2m) obj).ks)));
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash code value for this characteristic 2
+     * finite field.
+     * @return a hash code value.
+     */
+    public int hashCode() {
+        int value = m << 5;
+        value += (rp==null? 0:rp.hashCode());
+        // no need to involve ks here since ks and rp
+        // should be equivalent.
+        return value;
+    }
+}
diff --git a/java/security/spec/ECFieldFp.java b/java/security/spec/ECFieldFp.java
new file mode 100644
index 0000000..c578962
--- /dev/null
+++ b/java/security/spec/ECFieldFp.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2003, 2013, 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 java.security.spec;
+
+import java.math.BigInteger;
+import java.util.Arrays;
+
+/**
+ * This immutable class defines an elliptic curve (EC) prime
+ * finite field.
+ *
+ * @see ECField
+ *
+ * @author Valerie Peng
+ *
+ * @since 1.5
+ */
+public class ECFieldFp implements ECField {
+
+    private BigInteger p;
+
+    /**
+     * Creates an elliptic curve prime finite field
+     * with the specified prime {@code p}.
+     * @param p the prime.
+     * @exception NullPointerException if {@code p} is null.
+     * @exception IllegalArgumentException if {@code p}
+     * is not positive.
+     */
+    public ECFieldFp(BigInteger p) {
+        if (p.signum() != 1) {
+            throw new IllegalArgumentException("p is not positive");
+        }
+        this.p = p;
+    }
+
+    /**
+     * Returns the field size in bits which is size of prime p
+     * for this prime finite field.
+     * @return the field size in bits.
+     */
+    public int getFieldSize() {
+        return p.bitLength();
+    };
+
+    /**
+     * Returns the prime {@code p} of this prime finite field.
+     * @return the prime.
+     */
+    public BigInteger getP() {
+        return p;
+    }
+
+    /**
+     * Compares this prime finite field for equality with the
+     * specified object.
+     * @param obj the object to be compared.
+     * @return true if {@code obj} is an instance
+     * of ECFieldFp and the prime value match, false otherwise.
+     */
+    public boolean equals(Object obj) {
+        if (this == obj)  return true;
+        if (obj instanceof ECFieldFp) {
+            return (p.equals(((ECFieldFp)obj).p));
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash code value for this prime finite field.
+     * @return a hash code value.
+     */
+    public int hashCode() {
+        return p.hashCode();
+    }
+}
diff --git a/java/security/spec/ECGenParameterSpec.java b/java/security/spec/ECGenParameterSpec.java
new file mode 100644
index 0000000..4f3f63b
--- /dev/null
+++ b/java/security/spec/ECGenParameterSpec.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2003, 2013, 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 java.security.spec;
+
+/**
+ * This immutable class specifies the set of parameters used for
+ * generating elliptic curve (EC) domain parameters.
+ *
+ * @see AlgorithmParameterSpec
+ *
+ * @author Valerie Peng
+ *
+ * @since 1.5
+ */
+public class ECGenParameterSpec implements AlgorithmParameterSpec {
+
+    private String name;
+
+    /**
+     * Creates a parameter specification for EC parameter
+     * generation using a standard (or predefined) name
+     * {@code stdName} in order to generate the corresponding
+     * (precomputed) elliptic curve domain parameters. For the
+     * list of supported names, please consult the documentation
+     * of provider whose implementation will be used.
+     * @param stdName the standard name of the to-be-generated EC
+     * domain parameters.
+     * @exception NullPointerException if {@code stdName}
+     * is null.
+     */
+    public ECGenParameterSpec(String stdName) {
+        if (stdName == null) {
+            throw new NullPointerException("stdName is null");
+        }
+        this.name = stdName;
+    }
+
+    /**
+     * Returns the standard or predefined name of the
+     * to-be-generated EC domain parameters.
+     * @return the standard or predefined name.
+     */
+    public String getName() {
+        return name;
+    }
+}
diff --git a/java/security/spec/ECParameterSpec.java b/java/security/spec/ECParameterSpec.java
new file mode 100644
index 0000000..65bd027
--- /dev/null
+++ b/java/security/spec/ECParameterSpec.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2003, 2013, 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 java.security.spec;
+
+import java.math.BigInteger;
+
+/**
+ * This immutable class specifies the set of domain parameters
+ * used with elliptic curve cryptography (ECC).
+ *
+ * @see AlgorithmParameterSpec
+ *
+ * @author Valerie Peng
+ *
+ * @since 1.5
+ */
+public class ECParameterSpec implements AlgorithmParameterSpec {
+
+    private final EllipticCurve curve;
+    private final ECPoint g;
+    private final BigInteger n;
+    private final int h;
+
+    /**
+     * Creates elliptic curve domain parameters based on the
+     * specified values.
+     * @param curve the elliptic curve which this parameter
+     * defines.
+     * @param g the generator which is also known as the base point.
+     * @param n the order of the generator {@code g}.
+     * @param h the cofactor.
+     * @exception NullPointerException if {@code curve},
+     * {@code g}, or {@code n} is null.
+     * @exception IllegalArgumentException if {@code n}
+     * or {@code h} is not positive.
+     */
+    public ECParameterSpec(EllipticCurve curve, ECPoint g,
+                           BigInteger n, int h) {
+        if (curve == null) {
+            throw new NullPointerException("curve is null");
+        }
+        if (g == null) {
+            throw new NullPointerException("g is null");
+        }
+        if (n == null) {
+            throw new NullPointerException("n is null");
+        }
+        if (n.signum() != 1) {
+            throw new IllegalArgumentException("n is not positive");
+        }
+        if (h <= 0) {
+            throw new IllegalArgumentException("h is not positive");
+        }
+        this.curve = curve;
+        this.g = g;
+        this.n = n;
+        this.h = h;
+    }
+
+    /**
+     * Returns the elliptic curve that this parameter defines.
+     * @return the elliptic curve that this parameter defines.
+     */
+    public EllipticCurve getCurve() {
+        return curve;
+    }
+
+    /**
+     * Returns the generator which is also known as the base point.
+     * @return the generator which is also known as the base point.
+     */
+    public ECPoint getGenerator() {
+        return g;
+    }
+
+    /**
+     * Returns the order of the generator.
+     * @return the order of the generator.
+     */
+    public BigInteger getOrder() {
+        return n;
+    }
+
+    /**
+     * Returns the cofactor.
+     * @return the cofactor.
+     */
+    public int getCofactor() {
+        return h;
+    }
+    // BEGIN Android-added: Store the curve name as part of the parameters
+    // Knowing the name of the curve sometimes allows implementations to operate
+    // more efficiently.
+    private String curveName;
+
+    /**
+     * Used to set the curve name if available.
+     *
+     * @hide
+     */
+    public void setCurveName(String curveName) {
+        this.curveName = curveName;
+    }
+
+    /**
+     * Returns the name of the curve if this is a named curve. Returns
+     * {@code null} if this is not known to be a named curve.
+     *
+     * @hide
+     */
+    public String getCurveName() {
+        return curveName;
+    }
+    // END Android-added: Store the curve name as part of the parameters
+}
diff --git a/java/security/spec/ECPoint.java b/java/security/spec/ECPoint.java
new file mode 100644
index 0000000..1b051c7
--- /dev/null
+++ b/java/security/spec/ECPoint.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2003, 2013, 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 java.security.spec;
+
+import java.math.BigInteger;
+
+/**
+ * This immutable class represents a point on an elliptic curve (EC)
+ * in affine coordinates. Other coordinate systems can
+ * extend this class to represent this point in other
+ * coordinates.
+ *
+ * @author Valerie Peng
+ *
+ * @since 1.5
+ */
+public class ECPoint {
+
+    private final BigInteger x;
+    private final BigInteger y;
+
+    /**
+     * This defines the point at infinity.
+     */
+    public static final ECPoint POINT_INFINITY = new ECPoint();
+
+    // private constructor for constructing point at infinity
+    private ECPoint() {
+        this.x = null;
+        this.y = null;
+    }
+
+    /**
+     * Creates an ECPoint from the specified affine x-coordinate
+     * {@code x} and affine y-coordinate {@code y}.
+     * @param x the affine x-coordinate.
+     * @param y the affine y-coordinate.
+     * @exception NullPointerException if {@code x} or
+     * {@code y} is null.
+     */
+    public ECPoint(BigInteger x, BigInteger y) {
+        if ((x==null) || (y==null)) {
+            throw new NullPointerException("affine coordinate x or y is null");
+        }
+        this.x = x;
+        this.y = y;
+    }
+
+    /**
+     * Returns the affine x-coordinate {@code x}.
+     * Note: POINT_INFINITY has a null affine x-coordinate.
+     * @return the affine x-coordinate.
+     */
+    public BigInteger getAffineX() {
+        return x;
+    }
+
+    /**
+     * Returns the affine y-coordinate {@code y}.
+     * Note: POINT_INFINITY has a null affine y-coordinate.
+     * @return the affine y-coordinate.
+     */
+    public BigInteger getAffineY() {
+        return y;
+    }
+
+    /**
+     * Compares this elliptic curve point for equality with
+     * the specified object.
+     * @param obj the object to be compared.
+     * @return true if {@code obj} is an instance of
+     * ECPoint and the affine coordinates match, false otherwise.
+     */
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+        if (this == POINT_INFINITY) return false;
+        if (obj instanceof ECPoint) {
+            return ((x.equals(((ECPoint)obj).x)) &&
+                    (y.equals(((ECPoint)obj).y)));
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash code value for this elliptic curve point.
+     * @return a hash code value.
+     */
+    public int hashCode() {
+        if (this == POINT_INFINITY) return 0;
+        return x.hashCode() << 5 + y.hashCode();
+    }
+}
diff --git a/java/security/spec/ECPrivateKeySpec.java b/java/security/spec/ECPrivateKeySpec.java
new file mode 100644
index 0000000..7f03cfd
--- /dev/null
+++ b/java/security/spec/ECPrivateKeySpec.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2003, 2013, 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 java.security.spec;
+
+import java.math.BigInteger;
+
+/**
+ * This immutable class specifies an elliptic curve private key with
+ * its associated parameters.
+ *
+ * @see KeySpec
+ * @see ECParameterSpec
+ *
+ * @author Valerie Peng
+ *
+ * @since 1.5
+ */
+public class ECPrivateKeySpec implements KeySpec {
+
+    private BigInteger s;
+    private ECParameterSpec params;
+
+    /**
+     * Creates a new ECPrivateKeySpec with the specified
+     * parameter values.
+     * @param s the private value.
+     * @param params the associated elliptic curve domain
+     * parameters.
+     * @exception NullPointerException if {@code s}
+     * or {@code params} is null.
+     */
+    public ECPrivateKeySpec(BigInteger s, ECParameterSpec params) {
+        if (s == null) {
+            throw new NullPointerException("s is null");
+        }
+        if (params == null) {
+            throw new NullPointerException("params is null");
+        }
+        this.s = s;
+        this.params = params;
+    }
+
+    /**
+     * Returns the private value S.
+     * @return the private value S.
+     */
+    public BigInteger getS() {
+        return s;
+    }
+
+    /**
+     * Returns the associated elliptic curve domain
+     * parameters.
+     * @return the EC domain parameters.
+     */
+    public ECParameterSpec getParams() {
+        return params;
+    }
+}
diff --git a/java/security/spec/ECPublicKeySpec.java b/java/security/spec/ECPublicKeySpec.java
new file mode 100644
index 0000000..e0cfb77
--- /dev/null
+++ b/java/security/spec/ECPublicKeySpec.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2003, 2013, 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 java.security.spec;
+
+/**
+ * This immutable class specifies an elliptic curve public key with
+ * its associated parameters.
+ *
+ * @see KeySpec
+ * @see ECPoint
+ * @see ECParameterSpec
+ *
+ * @author Valerie Peng
+ *
+ * @since 1.5
+ */
+public class ECPublicKeySpec implements KeySpec {
+
+    private ECPoint w;
+    private ECParameterSpec params;
+
+    /**
+     * Creates a new ECPublicKeySpec with the specified
+     * parameter values.
+     * @param w the public point.
+     * @param params the associated elliptic curve domain
+     * parameters.
+     * @exception NullPointerException if {@code w}
+     * or {@code params} is null.
+     * @exception IllegalArgumentException if {@code w}
+     * is point at infinity, i.e. ECPoint.POINT_INFINITY
+     */
+    public ECPublicKeySpec(ECPoint w, ECParameterSpec params) {
+        if (w == null) {
+            throw new NullPointerException("w is null");
+        }
+        if (params == null) {
+            throw new NullPointerException("params is null");
+        }
+        if (w == ECPoint.POINT_INFINITY) {
+            throw new IllegalArgumentException("w is ECPoint.POINT_INFINITY");
+        }
+        this.w = w;
+        this.params = params;
+    }
+
+    /**
+     * Returns the public point W.
+     * @return the public point W.
+     */
+    public ECPoint getW() {
+        return w;
+    }
+
+    /**
+     * Returns the associated elliptic curve domain
+     * parameters.
+     * @return the EC domain parameters.
+     */
+    public ECParameterSpec getParams() {
+        return params;
+    }
+}
diff --git a/java/security/spec/EllipticCurve.java b/java/security/spec/EllipticCurve.java
new file mode 100644
index 0000000..8ec97b0
--- /dev/null
+++ b/java/security/spec/EllipticCurve.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2003, 2013, 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 java.security.spec;
+
+import java.math.BigInteger;
+import java.util.Arrays;
+
+/**
+ * This immutable class holds the necessary values needed to represent
+ * an elliptic curve.
+ *
+ * @see ECField
+ * @see ECFieldFp
+ * @see ECFieldF2m
+ *
+ * @author Valerie Peng
+ *
+ * @since 1.5
+ */
+public class EllipticCurve {
+
+    private final ECField field;
+    private final BigInteger a;
+    private final BigInteger b;
+    private final byte[] seed;
+
+    // Check coefficient c is a valid element in ECField field.
+    private static void checkValidity(ECField field, BigInteger c,
+        String cName) {
+        // can only perform check if field is ECFieldFp or ECFieldF2m.
+        if (field instanceof ECFieldFp) {
+            BigInteger p = ((ECFieldFp)field).getP();
+            if (p.compareTo(c) != 1) {
+                throw new IllegalArgumentException(cName + " is too large");
+            } else if (c.signum() < 0) {
+                throw new IllegalArgumentException(cName + " is negative");
+            }
+        } else if (field instanceof ECFieldF2m) {
+            int m = ((ECFieldF2m)field).getM();
+            if (c.bitLength() > m) {
+                throw new IllegalArgumentException(cName + " is too large");
+            }
+        }
+    }
+
+    /**
+     * Creates an elliptic curve with the specified elliptic field
+     * {@code field} and the coefficients {@code a} and
+     * {@code b}.
+     * @param field the finite field that this elliptic curve is over.
+     * @param a the first coefficient of this elliptic curve.
+     * @param b the second coefficient of this elliptic curve.
+     * @exception NullPointerException if {@code field},
+     * {@code a}, or {@code b} is null.
+     * @exception IllegalArgumentException if {@code a}
+     * or {@code b} is not null and not in {@code field}.
+     */
+    public EllipticCurve(ECField field, BigInteger a,
+                         BigInteger b) {
+        this(field, a, b, null);
+    }
+
+    /**
+     * Creates an elliptic curve with the specified elliptic field
+     * {@code field}, the coefficients {@code a} and
+     * {@code b}, and the {@code seed} used for curve generation.
+     * @param field the finite field that this elliptic curve is over.
+     * @param a the first coefficient of this elliptic curve.
+     * @param b the second coefficient of this elliptic curve.
+     * @param seed the bytes used during curve generation for later
+     * validation. Contents of this array are copied to protect against
+     * subsequent modification.
+     * @exception NullPointerException if {@code field},
+     * {@code a}, or {@code b} is null.
+     * @exception IllegalArgumentException if {@code a}
+     * or {@code b} is not null and not in {@code field}.
+     */
+    public EllipticCurve(ECField field, BigInteger a,
+                         BigInteger b, byte[] seed) {
+        if (field == null) {
+            throw new NullPointerException("field is null");
+        }
+        if (a == null) {
+            throw new NullPointerException("first coefficient is null");
+        }
+        if (b == null) {
+            throw new NullPointerException("second coefficient is null");
+        }
+        checkValidity(field, a, "first coefficient");
+        checkValidity(field, b, "second coefficient");
+        this.field = field;
+        this.a = a;
+        this.b = b;
+        if (seed != null) {
+            this.seed = seed.clone();
+        } else {
+            this.seed = null;
+        }
+    }
+
+    /**
+     * Returns the finite field {@code field} that this
+     * elliptic curve is over.
+     * @return the field {@code field} that this curve
+     * is over.
+     */
+    public ECField getField() {
+        return field;
+    }
+
+    /**
+     * Returns the first coefficient {@code a} of the
+     * elliptic curve.
+     * @return the first coefficient {@code a}.
+     */
+    public BigInteger getA() {
+        return a;
+    }
+
+    /**
+     * Returns the second coefficient {@code b} of the
+     * elliptic curve.
+     * @return the second coefficient {@code b}.
+     */
+    public BigInteger getB() {
+        return b;
+    }
+
+    /**
+     * Returns the seeding bytes {@code seed} used
+     * during curve generation. May be null if not specified.
+     * @return the seeding bytes {@code seed}. A new
+     * array is returned each time this method is called.
+     */
+    public byte[] getSeed() {
+        if (seed == null) return null;
+        else return seed.clone();
+    }
+
+    /**
+     * Compares this elliptic curve for equality with the
+     * specified object.
+     * @param obj the object to be compared.
+     * @return true if {@code obj} is an instance of
+     * EllipticCurve and the field, A, and B match, false otherwise.
+     */
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+        if (obj instanceof EllipticCurve) {
+            EllipticCurve curve = (EllipticCurve) obj;
+            if ((field.equals(curve.field)) &&
+                (a.equals(curve.a)) &&
+                (b.equals(curve.b))) {
+                    return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash code value for this elliptic curve.
+     * @return a hash code value computed from the hash codes of the field, A,
+     * and B, as follows:
+     * <pre>{@code
+     *     (field.hashCode() << 6) + (a.hashCode() << 4) + (b.hashCode() << 2)
+     * }</pre>
+     */
+    public int hashCode() {
+        return (field.hashCode() << 6 +
+            (a.hashCode() << 4) +
+            (b.hashCode() << 2));
+    }
+}
diff --git a/java/security/spec/EncodedKeySpec.java b/java/security/spec/EncodedKeySpec.java
new file mode 100644
index 0000000..cc3b81e
--- /dev/null
+++ b/java/security/spec/EncodedKeySpec.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security.spec;
+
+/**
+ * This class represents a public or private key in encoded format.
+ *
+ * @author Jan Luehe
+ *
+ *
+ * @see java.security.Key
+ * @see java.security.KeyFactory
+ * @see KeySpec
+ * @see X509EncodedKeySpec
+ * @see PKCS8EncodedKeySpec
+ *
+ * @since 1.2
+ */
+
+public abstract class EncodedKeySpec implements KeySpec {
+
+    private byte[] encodedKey;
+
+    /**
+     * Creates a new EncodedKeySpec with the given encoded key.
+     *
+     * @param encodedKey the encoded key. The contents of the
+     * array are copied to protect against subsequent modification.
+     * @exception NullPointerException if {@code encodedKey}
+     * is null.
+     */
+    public EncodedKeySpec(byte[] encodedKey) {
+        this.encodedKey = encodedKey.clone();
+    }
+
+    /**
+     * Returns the encoded key.
+     *
+     * @return the encoded key. Returns a new array each time
+     * this method is called.
+     */
+    public byte[] getEncoded() {
+        return this.encodedKey.clone();
+    }
+
+    /**
+     * Returns the name of the encoding format associated with this
+     * key specification.
+     *
+     * <p>If the opaque representation of a key
+     * (see {@link java.security.Key Key}) can be transformed
+     * (see {@link java.security.KeyFactory KeyFactory})
+     * into this key specification (or a subclass of it),
+     * {@code getFormat} called
+     * on the opaque key returns the same value as the
+     * {@code getFormat} method
+     * of this key specification.
+     *
+     * @return a string representation of the encoding format.
+     */
+    public abstract String getFormat();
+}
diff --git a/java/security/spec/InvalidKeySpecException.java b/java/security/spec/InvalidKeySpecException.java
new file mode 100644
index 0000000..4655c4a
--- /dev/null
+++ b/java/security/spec/InvalidKeySpecException.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security.spec;
+
+import java.security.GeneralSecurityException;
+
+/**
+ * This is the exception for invalid key specifications.
+ *
+ * @author Jan Luehe
+ *
+ *
+ * @see KeySpec
+ *
+ * @since 1.2
+ */
+
+public class InvalidKeySpecException extends GeneralSecurityException {
+
+    private static final long serialVersionUID = 3546139293998810778L;
+
+    /**
+     * Constructs an InvalidKeySpecException with no detail message. A
+     * detail message is a String that describes this particular
+     * exception.
+     */
+    public InvalidKeySpecException() {
+        super();
+    }
+
+    /**
+     * Constructs an InvalidKeySpecException with the specified detail
+     * message. A detail message is a String that describes this
+     * particular exception.
+     *
+     * @param msg the detail message.
+     */
+    public InvalidKeySpecException(String msg) {
+        super(msg);
+    }
+
+    /**
+     * Creates a {@code InvalidKeySpecException} with the specified
+     * detail message and cause.
+     *
+     * @param message the detail message (which is saved for later retrieval
+     *        by the {@link #getMessage()} method).
+     * @param cause the cause (which is saved for later retrieval by the
+     *        {@link #getCause()} method).  (A {@code null} value is permitted,
+     *        and indicates that the cause is nonexistent or unknown.)
+     * @since 1.5
+     */
+    public InvalidKeySpecException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Creates a {@code InvalidKeySpecException} with the specified cause
+     * and a detail message of {@code (cause==null ? null : cause.toString())}
+     * (which typically contains the class and detail message of
+     * {@code cause}).
+     *
+     * @param cause the cause (which is saved for later retrieval by the
+     *        {@link #getCause()} method).  (A {@code null} value is permitted,
+     *        and indicates that the cause is nonexistent or unknown.)
+     * @since 1.5
+     */
+    public InvalidKeySpecException(Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/java/security/spec/InvalidParameterSpecException.java b/java/security/spec/InvalidParameterSpecException.java
new file mode 100644
index 0000000..3059c77
--- /dev/null
+++ b/java/security/spec/InvalidParameterSpecException.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 1997, 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.  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 java.security.spec;
+
+import java.security.GeneralSecurityException;
+
+/**
+ * This is the exception for invalid parameter specifications.
+ *
+ * @author Jan Luehe
+ *
+ *
+ * @see java.security.AlgorithmParameters
+ * @see AlgorithmParameterSpec
+ * @see DSAParameterSpec
+ *
+ * @since 1.2
+ */
+
+public class InvalidParameterSpecException extends GeneralSecurityException {
+
+    private static final long serialVersionUID = -970468769593399342L;
+
+    /**
+     * Constructs an InvalidParameterSpecException with no detail message. A
+     * detail message is a String that describes this particular
+     * exception.
+     */
+    public InvalidParameterSpecException() {
+        super();
+    }
+
+    /**
+     * Constructs an InvalidParameterSpecException with the specified detail
+     * message. A detail message is a String that describes this
+     * particular exception.
+     *
+     * @param msg the detail message.
+     */
+    public InvalidParameterSpecException(String msg) {
+        super(msg);
+    }
+}
diff --git a/java/security/spec/KeySpec.java b/java/security/spec/KeySpec.java
new file mode 100644
index 0000000..34fec5d
--- /dev/null
+++ b/java/security/spec/KeySpec.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security.spec;
+
+/**
+ * A (transparent) specification of the key material
+ * that constitutes a cryptographic key.
+ *
+ * <p>If the key is stored on a hardware device, its
+ * specification may contain information that helps identify the key on the
+ * device.
+ *
+ * <P> A key may be specified in an algorithm-specific way, or in an
+ * algorithm-independent encoding format (such as ASN.1).
+ * For example, a DSA private key may be specified by its components
+ * {@code x}, {@code p}, {@code q}, and {@code g}
+ * (see {@link DSAPrivateKeySpec}), or it may be
+ * specified using its DER encoding
+ * (see {@link PKCS8EncodedKeySpec}).
+ *
+ * <P> This interface contains no methods or constants. Its only purpose
+ * is to group (and provide type safety for) all key specifications.
+ * All key specifications must implement this interface.
+ *
+ * @author Jan Luehe
+ *
+ *
+ * @see java.security.Key
+ * @see java.security.KeyFactory
+ * @see EncodedKeySpec
+ * @see X509EncodedKeySpec
+ * @see PKCS8EncodedKeySpec
+ * @see DSAPrivateKeySpec
+ * @see DSAPublicKeySpec
+ *
+ * @since 1.2
+ */
+
+public interface KeySpec { }
diff --git a/java/security/spec/MGF1ParameterSpec.java b/java/security/spec/MGF1ParameterSpec.java
new file mode 100644
index 0000000..1be267f
--- /dev/null
+++ b/java/security/spec/MGF1ParameterSpec.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2003, 2013, 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 java.security.spec;
+
+import java.security.spec.AlgorithmParameterSpec;
+
+/**
+ * This class specifies the set of parameters used with mask generation
+ * function MGF1 in OAEP Padding and RSA-PSS signature scheme, as
+ * defined in the
+ * <a href="http://www.ietf.org/rfc/rfc3447.txt">PKCS #1 v2.1</a>
+ * standard.
+ *
+ * <p>Its ASN.1 definition in PKCS#1 standard is described below:
+ * <pre>
+ * MGF1Parameters ::= OAEP-PSSDigestAlgorthms
+ * </pre>
+ * where
+ * <pre>
+ * OAEP-PSSDigestAlgorithms    ALGORITHM-IDENTIFIER ::= {
+ *   { OID id-sha1 PARAMETERS NULL   }|
+ *   { OID id-sha224 PARAMETERS NULL   }|
+ *   { OID id-sha256 PARAMETERS NULL }|
+ *   { OID id-sha384 PARAMETERS NULL }|
+ *   { OID id-sha512 PARAMETERS NULL },
+ *   ...  -- Allows for future expansion --
+ * }
+ * </pre>
+ * @see PSSParameterSpec
+ * @see javax.crypto.spec.OAEPParameterSpec
+ *
+ * @author Valerie Peng
+ *
+ * @since 1.5
+ */
+public class MGF1ParameterSpec implements AlgorithmParameterSpec {
+
+    /**
+     * The MGF1ParameterSpec which uses "SHA-1" message digest.
+     */
+    public static final MGF1ParameterSpec SHA1 =
+        new MGF1ParameterSpec("SHA-1");
+    /**
+     * The MGF1ParameterSpec which uses "SHA-224" message digest.
+     */
+    public static final MGF1ParameterSpec SHA224 =
+        new MGF1ParameterSpec("SHA-224");
+    /**
+     * The MGF1ParameterSpec which uses "SHA-256" message digest.
+     */
+    public static final MGF1ParameterSpec SHA256 =
+        new MGF1ParameterSpec("SHA-256");
+    /**
+     * The MGF1ParameterSpec which uses "SHA-384" message digest.
+     */
+    public static final MGF1ParameterSpec SHA384 =
+        new MGF1ParameterSpec("SHA-384");
+    /**
+     * The MGF1ParameterSpec which uses SHA-512 message digest.
+     */
+    public static final MGF1ParameterSpec SHA512 =
+        new MGF1ParameterSpec("SHA-512");
+
+    private String mdName;
+
+    /**
+     * Constructs a parameter set for mask generation function MGF1
+     * as defined in the PKCS #1 standard.
+     *
+     * @param mdName the algorithm name for the message digest
+     * used in this mask generation function MGF1.
+     * @exception NullPointerException if {@code mdName} is null.
+     */
+    public MGF1ParameterSpec(String mdName) {
+        if (mdName == null) {
+            throw new NullPointerException("digest algorithm is null");
+        }
+        this.mdName = mdName;
+    }
+
+    /**
+     * Returns the algorithm name of the message digest used by the mask
+     * generation function.
+     *
+     * @return the algorithm name of the message digest.
+     */
+    public String getDigestAlgorithm() {
+        return mdName;
+    }
+}
diff --git a/java/security/spec/PKCS8EncodedKeySpec.java b/java/security/spec/PKCS8EncodedKeySpec.java
new file mode 100644
index 0000000..060f266
--- /dev/null
+++ b/java/security/spec/PKCS8EncodedKeySpec.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security.spec;
+
+/**
+ * This class represents the ASN.1 encoding of a private key,
+ * encoded according to the ASN.1 type {@code PrivateKeyInfo}.
+ * The {@code PrivateKeyInfo} syntax is defined in the PKCS#8 standard
+ * as follows:
+ *
+ * <pre>
+ * PrivateKeyInfo ::= SEQUENCE {
+ *   version Version,
+ *   privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
+ *   privateKey PrivateKey,
+ *   attributes [0] IMPLICIT Attributes OPTIONAL }
+ *
+ * Version ::= INTEGER
+ *
+ * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
+ *
+ * PrivateKey ::= OCTET STRING
+ *
+ * Attributes ::= SET OF Attribute
+ * </pre>
+ *
+ * @author Jan Luehe
+ *
+ *
+ * @see java.security.Key
+ * @see java.security.KeyFactory
+ * @see KeySpec
+ * @see EncodedKeySpec
+ * @see X509EncodedKeySpec
+ *
+ * @since 1.2
+ */
+
+public class PKCS8EncodedKeySpec extends EncodedKeySpec {
+
+    /**
+     * Creates a new PKCS8EncodedKeySpec with the given encoded key.
+     *
+     * @param encodedKey the key, which is assumed to be
+     * encoded according to the PKCS #8 standard. The contents of
+     * the array are copied to protect against subsequent modification.
+     * @exception NullPointerException if {@code encodedKey}
+     * is null.
+     */
+    public PKCS8EncodedKeySpec(byte[] encodedKey) {
+        super(encodedKey);
+    }
+
+    /**
+     * Returns the key bytes, encoded according to the PKCS #8 standard.
+     *
+     * @return the PKCS #8 encoding of the key. Returns a new array
+     * each time this method is called.
+     */
+    public byte[] getEncoded() {
+        return super.getEncoded();
+    }
+
+    /**
+     * Returns the name of the encoding format associated with this
+     * key specification.
+     *
+     * @return the string {@code "PKCS#8"}.
+     */
+    public final String getFormat() {
+        return "PKCS#8";
+    }
+}
diff --git a/java/security/spec/PSSParameterSpec.java b/java/security/spec/PSSParameterSpec.java
new file mode 100644
index 0000000..a9b82d8
--- /dev/null
+++ b/java/security/spec/PSSParameterSpec.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2001, 2013, 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 java.security.spec;
+
+import java.math.BigInteger;
+import java.security.spec.MGF1ParameterSpec;
+
+/**
+ * This class specifies a parameter spec for RSA-PSS signature scheme,
+ * as defined in the
+ * <a href="http://www.ietf.org/rfc/rfc3447.txt">PKCS#1 v2.1</a>
+ * standard.
+ *
+ * <p>Its ASN.1 definition in PKCS#1 standard is described below:
+ * <pre>
+ * RSASSA-PSS-params ::= SEQUENCE {
+ *   hashAlgorithm      [0] OAEP-PSSDigestAlgorithms  DEFAULT sha1,
+ *   maskGenAlgorithm   [1] PKCS1MGFAlgorithms  DEFAULT mgf1SHA1,
+ *   saltLength         [2] INTEGER  DEFAULT 20,
+ *   trailerField       [3] INTEGER  DEFAULT 1
+ * }
+ * </pre>
+ * where
+ * <pre>
+ * OAEP-PSSDigestAlgorithms    ALGORITHM-IDENTIFIER ::= {
+ *   { OID id-sha1 PARAMETERS NULL   }|
+ *   { OID id-sha224 PARAMETERS NULL   }|
+ *   { OID id-sha256 PARAMETERS NULL }|
+ *   { OID id-sha384 PARAMETERS NULL }|
+ *   { OID id-sha512 PARAMETERS NULL },
+ *   ...  -- Allows for future expansion --
+ * }
+ *
+ * PKCS1MGFAlgorithms    ALGORITHM-IDENTIFIER ::= {
+ *   { OID id-mgf1 PARAMETERS OAEP-PSSDigestAlgorithms },
+ *   ...  -- Allows for future expansion --
+ * }
+ * </pre>
+ * <p>Note: the PSSParameterSpec.DEFAULT uses the following:
+ *     message digest  -- "SHA-1"
+ *     mask generation function (mgf) -- "MGF1"
+ *     parameters for mgf -- MGF1ParameterSpec.SHA1
+ *     SaltLength   -- 20
+ *     TrailerField -- 1
+ *
+ * @see MGF1ParameterSpec
+ * @see AlgorithmParameterSpec
+ * @see java.security.Signature
+ *
+ * @author Valerie Peng
+ *
+ *
+ * @since 1.4
+ */
+
+public class PSSParameterSpec implements AlgorithmParameterSpec {
+
+    private String mdName = "SHA-1";
+    private String mgfName = "MGF1";
+    private AlgorithmParameterSpec mgfSpec = MGF1ParameterSpec.SHA1;
+    private int saltLen = 20;
+    private int trailerField = 1;
+
+    /**
+     * The PSS parameter set with all default values.
+     * @since 1.5
+     */
+    public static final PSSParameterSpec DEFAULT = new PSSParameterSpec();
+
+    /**
+     * Constructs a new {@code PSSParameterSpec} as defined in
+     * the PKCS #1 standard using the default values.
+     */
+    private PSSParameterSpec() {
+    }
+
+    /**
+     * Creates a new {@code PSSParameterSpec} as defined in
+     * the PKCS #1 standard using the specified message digest,
+     * mask generation function, parameters for mask generation
+     * function, salt length, and trailer field values.
+     *
+     * @param mdName the algorithm name of the hash function.
+     * @param mgfName the algorithm name of the mask generation
+     * function.
+     * @param mgfSpec the parameters for the mask generation
+     * function. If null is specified, null will be returned by
+     * getMGFParameters().
+     * @param saltLen the length of salt.
+     * @param trailerField the value of the trailer field.
+     * @exception NullPointerException if {@code mdName},
+     * or {@code mgfName} is null.
+     * @exception IllegalArgumentException if {@code saltLen}
+     * or {@code trailerField} is less than 0.
+     * @since 1.5
+     */
+    public PSSParameterSpec(String mdName, String mgfName,
+                            AlgorithmParameterSpec mgfSpec,
+                            int saltLen, int trailerField) {
+        if (mdName == null) {
+            throw new NullPointerException("digest algorithm is null");
+        }
+        if (mgfName == null) {
+            throw new NullPointerException("mask generation function " +
+                                           "algorithm is null");
+        }
+        if (saltLen < 0) {
+            throw new IllegalArgumentException("negative saltLen value: " +
+                                               saltLen);
+        }
+        if (trailerField < 0) {
+            throw new IllegalArgumentException("negative trailerField: " +
+                                               trailerField);
+        }
+        this.mdName = mdName;
+        this.mgfName = mgfName;
+        this.mgfSpec = mgfSpec;
+        this.saltLen = saltLen;
+        this.trailerField = trailerField;
+    }
+
+    /**
+     * Creates a new {@code PSSParameterSpec}
+     * using the specified salt length and other default values as
+     * defined in PKCS#1.
+     *
+     * @param saltLen the length of salt in bits to be used in PKCS#1
+     * PSS encoding.
+     * @exception IllegalArgumentException if {@code saltLen} is
+     * less than 0.
+     */
+    public PSSParameterSpec(int saltLen) {
+        if (saltLen < 0) {
+            throw new IllegalArgumentException("negative saltLen value: " +
+                                               saltLen);
+        }
+        this.saltLen = saltLen;
+    }
+
+    /**
+     * Returns the message digest algorithm name.
+     *
+     * @return the message digest algorithm name.
+     * @since 1.5
+     */
+    public String getDigestAlgorithm() {
+        return mdName;
+    }
+
+    /**
+     * Returns the mask generation function algorithm name.
+     *
+     * @return the mask generation function algorithm name.
+     *
+     * @since 1.5
+     */
+    public String getMGFAlgorithm() {
+        return mgfName;
+    }
+
+    /**
+     * Returns the parameters for the mask generation function.
+     *
+     * @return the parameters for the mask generation function.
+     * @since 1.5
+     */
+    public AlgorithmParameterSpec getMGFParameters() {
+        return mgfSpec;
+    }
+
+    /**
+     * Returns the salt length in bits.
+     *
+     * @return the salt length.
+     */
+    public int getSaltLength() {
+        return saltLen;
+    }
+
+    /**
+     * Returns the value for the trailer field, i.e. bc in PKCS#1 v2.1.
+     *
+     * @return the value for the trailer field, i.e. bc in PKCS#1 v2.1.
+     * @since 1.5
+     */
+    public int getTrailerField() {
+        return trailerField;
+    }
+}
diff --git a/java/security/spec/RSAKeyGenParameterSpec.java b/java/security/spec/RSAKeyGenParameterSpec.java
new file mode 100644
index 0000000..a73c6cd
--- /dev/null
+++ b/java/security/spec/RSAKeyGenParameterSpec.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 1999, 2013, 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 java.security.spec;
+
+import java.math.BigInteger;
+import java.security.spec.AlgorithmParameterSpec;
+
+/**
+ * This class specifies the set of parameters used to generate an RSA
+ * key pair.
+ *
+ * @author Jan Luehe
+ *
+ * @see java.security.KeyPairGenerator#initialize(java.security.spec.AlgorithmParameterSpec)
+ *
+ * @since 1.3
+ */
+
+public class RSAKeyGenParameterSpec implements AlgorithmParameterSpec {
+
+    private int keysize;
+    private BigInteger publicExponent;
+
+    /**
+     * The public-exponent value F0 = 3.
+     */
+    public static final BigInteger F0 = BigInteger.valueOf(3);
+
+    /**
+     * The public exponent-value F4 = 65537.
+     */
+    public static final BigInteger F4 = BigInteger.valueOf(65537);
+
+    /**
+     * Constructs a new {@code RSAParameterSpec} object from the
+     * given keysize and public-exponent value.
+     *
+     * @param keysize the modulus size (specified in number of bits)
+     * @param publicExponent the public exponent
+     */
+    public RSAKeyGenParameterSpec(int keysize, BigInteger publicExponent) {
+        this.keysize = keysize;
+        this.publicExponent = publicExponent;
+    }
+
+    /**
+     * Returns the keysize.
+     *
+     * @return the keysize.
+     */
+    public int getKeysize() {
+        return keysize;
+    }
+
+    /**
+     * Returns the public-exponent value.
+     *
+     * @return the public-exponent value.
+     */
+    public BigInteger getPublicExponent() {
+        return publicExponent;
+    }
+}
diff --git a/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java b/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java
new file mode 100644
index 0000000..a198e43
--- /dev/null
+++ b/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2001, 2013, 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 java.security.spec;
+
+import java.math.BigInteger;
+
+/**
+ * This class specifies an RSA multi-prime private key, as defined in the
+ * PKCS#1 v2.1, using the Chinese Remainder Theorem (CRT) information
+ * values for efficiency.
+ *
+ * @author Valerie Peng
+ *
+ *
+ * @see java.security.Key
+ * @see java.security.KeyFactory
+ * @see KeySpec
+ * @see PKCS8EncodedKeySpec
+ * @see RSAPrivateKeySpec
+ * @see RSAPublicKeySpec
+ * @see RSAOtherPrimeInfo
+ *
+ * @since 1.4
+ */
+
+public class RSAMultiPrimePrivateCrtKeySpec extends RSAPrivateKeySpec {
+
+    private final BigInteger publicExponent;
+    private final BigInteger primeP;
+    private final BigInteger primeQ;
+    private final BigInteger primeExponentP;
+    private final BigInteger primeExponentQ;
+    private final BigInteger crtCoefficient;
+    private final RSAOtherPrimeInfo otherPrimeInfo[];
+
+   /**
+    * Creates a new {@code RSAMultiPrimePrivateCrtKeySpec}
+    * given the modulus, publicExponent, privateExponent,
+    * primeP, primeQ, primeExponentP, primeExponentQ,
+    * crtCoefficient, and otherPrimeInfo as defined in PKCS#1 v2.1.
+    *
+    * <p>Note that the contents of {@code otherPrimeInfo}
+    * are copied to protect against subsequent modification when
+    * constructing this object.
+    *
+    * @param modulus the modulus n.
+    * @param publicExponent the public exponent e.
+    * @param privateExponent the private exponent d.
+    * @param primeP the prime factor p of n.
+    * @param primeQ the prime factor q of n.
+    * @param primeExponentP this is d mod (p-1).
+    * @param primeExponentQ this is d mod (q-1).
+    * @param crtCoefficient the Chinese Remainder Theorem
+    * coefficient q-1 mod p.
+    * @param otherPrimeInfo triplets of the rest of primes, null can be
+    * specified if there are only two prime factors (p and q).
+    * @exception NullPointerException if any of the parameters, i.e.
+    * {@code modulus},
+    * {@code publicExponent}, {@code privateExponent},
+    * {@code primeP}, {@code primeQ},
+    * {@code primeExponentP}, {@code primeExponentQ},
+    * {@code crtCoefficient}, is null.
+    * @exception IllegalArgumentException if an empty, i.e. 0-length,
+    * {@code otherPrimeInfo} is specified.
+    */
+    public RSAMultiPrimePrivateCrtKeySpec(BigInteger modulus,
+                                BigInteger publicExponent,
+                                BigInteger privateExponent,
+                                BigInteger primeP,
+                                BigInteger primeQ,
+                                BigInteger primeExponentP,
+                                BigInteger primeExponentQ,
+                                BigInteger crtCoefficient,
+                                RSAOtherPrimeInfo[] otherPrimeInfo) {
+        super(modulus, privateExponent);
+        if (modulus == null) {
+            throw new NullPointerException("the modulus parameter must be " +
+                                            "non-null");
+        }
+        if (publicExponent == null) {
+            throw new NullPointerException("the publicExponent parameter " +
+                                            "must be non-null");
+        }
+        if (privateExponent == null) {
+            throw new NullPointerException("the privateExponent parameter " +
+                                            "must be non-null");
+        }
+        if (primeP == null) {
+            throw new NullPointerException("the primeP parameter " +
+                                            "must be non-null");
+        }
+        if (primeQ == null) {
+            throw new NullPointerException("the primeQ parameter " +
+                                            "must be non-null");
+        }
+        if (primeExponentP == null) {
+            throw new NullPointerException("the primeExponentP parameter " +
+                                            "must be non-null");
+        }
+        if (primeExponentQ == null) {
+            throw new NullPointerException("the primeExponentQ parameter " +
+                                            "must be non-null");
+        }
+        if (crtCoefficient == null) {
+            throw new NullPointerException("the crtCoefficient parameter " +
+                                            "must be non-null");
+        }
+        this.publicExponent = publicExponent;
+        this.primeP = primeP;
+        this.primeQ = primeQ;
+        this.primeExponentP = primeExponentP;
+        this.primeExponentQ = primeExponentQ;
+        this.crtCoefficient = crtCoefficient;
+        if (otherPrimeInfo == null)  {
+            this.otherPrimeInfo = null;
+        } else if (otherPrimeInfo.length == 0) {
+            throw new IllegalArgumentException("the otherPrimeInfo " +
+                                                "parameter must not be empty");
+        } else {
+            this.otherPrimeInfo = otherPrimeInfo.clone();
+        }
+    }
+
+    /**
+     * Returns the public exponent.
+     *
+     * @return the public exponent.
+     */
+    public BigInteger getPublicExponent() {
+        return this.publicExponent;
+    }
+
+    /**
+     * Returns the primeP.
+     *
+     * @return the primeP.
+     */
+    public BigInteger getPrimeP() {
+        return this.primeP;
+    }
+
+    /**
+     * Returns the primeQ.
+     *
+     * @return the primeQ.
+     */
+    public BigInteger getPrimeQ() {
+        return this.primeQ;
+    }
+
+    /**
+     * Returns the primeExponentP.
+     *
+     * @return the primeExponentP.
+     */
+    public BigInteger getPrimeExponentP() {
+        return this.primeExponentP;
+    }
+
+    /**
+     * Returns the primeExponentQ.
+     *
+     * @return the primeExponentQ.
+     */
+    public BigInteger getPrimeExponentQ() {
+        return this.primeExponentQ;
+    }
+
+    /**
+     * Returns the crtCoefficient.
+     *
+     * @return the crtCoefficient.
+     */
+    public BigInteger getCrtCoefficient() {
+        return this.crtCoefficient;
+    }
+
+    /**
+     * Returns a copy of the otherPrimeInfo or null if there are
+     * only two prime factors (p and q).
+     *
+     * @return the otherPrimeInfo. Returns a new array each
+     * time this method is called.
+     */
+    public RSAOtherPrimeInfo[] getOtherPrimeInfo() {
+        if (otherPrimeInfo == null) return null;
+        return otherPrimeInfo.clone();
+    }
+}
diff --git a/java/security/spec/RSAOtherPrimeInfo.java b/java/security/spec/RSAOtherPrimeInfo.java
new file mode 100644
index 0000000..10d8471
--- /dev/null
+++ b/java/security/spec/RSAOtherPrimeInfo.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2001, 2013, 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 java.security.spec;
+
+import java.math.BigInteger;
+
+/**
+ * This class represents the triplet (prime, exponent, and coefficient)
+ * inside RSA's OtherPrimeInfo structure, as defined in the PKCS#1 v2.1.
+ * The ASN.1 syntax of RSA's OtherPrimeInfo is as follows:
+ *
+ * <pre>
+ * OtherPrimeInfo ::= SEQUENCE {
+ *   prime INTEGER,
+ *   exponent INTEGER,
+ *   coefficient INTEGER
+ *   }
+ *
+ * </pre>
+ *
+ * @author Valerie Peng
+ *
+ *
+ * @see RSAPrivateCrtKeySpec
+ * @see java.security.interfaces.RSAMultiPrimePrivateCrtKey
+ *
+ * @since 1.4
+ */
+
+public class RSAOtherPrimeInfo {
+
+    private BigInteger prime;
+    private BigInteger primeExponent;
+    private BigInteger crtCoefficient;
+
+
+   /**
+    * Creates a new {@code RSAOtherPrimeInfo}
+    * given the prime, primeExponent, and
+    * crtCoefficient as defined in PKCS#1.
+    *
+    * @param prime the prime factor of n.
+    * @param primeExponent the exponent.
+    * @param crtCoefficient the Chinese Remainder Theorem
+    * coefficient.
+    * @exception NullPointerException if any of the parameters, i.e.
+    * {@code prime}, {@code primeExponent},
+    * {@code crtCoefficient}, is null.
+    *
+    */
+    public RSAOtherPrimeInfo(BigInteger prime,
+                          BigInteger primeExponent,
+                          BigInteger crtCoefficient) {
+        if (prime == null) {
+            throw new NullPointerException("the prime parameter must be " +
+                                            "non-null");
+        }
+        if (primeExponent == null) {
+            throw new NullPointerException("the primeExponent parameter " +
+                                            "must be non-null");
+        }
+        if (crtCoefficient == null) {
+            throw new NullPointerException("the crtCoefficient parameter " +
+                                            "must be non-null");
+        }
+        this.prime = prime;
+        this.primeExponent = primeExponent;
+        this.crtCoefficient = crtCoefficient;
+    }
+
+    /**
+     * Returns the prime.
+     *
+     * @return the prime.
+     */
+    public final BigInteger getPrime() {
+        return this.prime;
+    }
+
+    /**
+     * Returns the prime's exponent.
+     *
+     * @return the primeExponent.
+     */
+    public final BigInteger getExponent() {
+        return this.primeExponent;
+    }
+
+    /**
+     * Returns the prime's crtCoefficient.
+     *
+     * @return the crtCoefficient.
+     */
+    public final BigInteger getCrtCoefficient() {
+        return this.crtCoefficient;
+    }
+}
diff --git a/java/security/spec/RSAPrivateCrtKeySpec.java b/java/security/spec/RSAPrivateCrtKeySpec.java
new file mode 100644
index 0000000..d0ba70b
--- /dev/null
+++ b/java/security/spec/RSAPrivateCrtKeySpec.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 1998, 2013, 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 java.security.spec;
+
+import java.math.BigInteger;
+
+/**
+ * This class specifies an RSA private key, as defined in the PKCS#1
+ * standard, using the Chinese Remainder Theorem (CRT) information values for
+ * efficiency.
+ *
+ * @author Jan Luehe
+ *
+ *
+ * @see java.security.Key
+ * @see java.security.KeyFactory
+ * @see KeySpec
+ * @see PKCS8EncodedKeySpec
+ * @see RSAPrivateKeySpec
+ * @see RSAPublicKeySpec
+ */
+
+public class RSAPrivateCrtKeySpec extends RSAPrivateKeySpec {
+
+    private final BigInteger publicExponent;
+    private final BigInteger primeP;
+    private final BigInteger primeQ;
+    private final BigInteger primeExponentP;
+    private final BigInteger primeExponentQ;
+    private final BigInteger crtCoefficient;
+
+
+
+   /**
+    * Creates a new {@code RSAPrivateCrtKeySpec}
+    * given the modulus, publicExponent, privateExponent,
+    * primeP, primeQ, primeExponentP, primeExponentQ, and
+    * crtCoefficient as defined in PKCS#1.
+    *
+    * @param modulus the modulus n
+    * @param publicExponent the public exponent e
+    * @param privateExponent the private exponent d
+    * @param primeP the prime factor p of n
+    * @param primeQ the prime factor q of n
+    * @param primeExponentP this is d mod (p-1)
+    * @param primeExponentQ this is d mod (q-1)
+    * @param crtCoefficient the Chinese Remainder Theorem
+    * coefficient q-1 mod p
+    */
+    public RSAPrivateCrtKeySpec(BigInteger modulus,
+                                BigInteger publicExponent,
+                                BigInteger privateExponent,
+                                BigInteger primeP,
+                                BigInteger primeQ,
+                                BigInteger primeExponentP,
+                                BigInteger primeExponentQ,
+                                BigInteger crtCoefficient) {
+        super(modulus, privateExponent);
+        this.publicExponent = publicExponent;
+        this.primeP = primeP;
+        this.primeQ = primeQ;
+        this.primeExponentP = primeExponentP;
+        this.primeExponentQ = primeExponentQ;
+        this.crtCoefficient = crtCoefficient;
+    }
+
+    /**
+     * Returns the public exponent.
+     *
+     * @return the public exponent
+     */
+    public BigInteger getPublicExponent() {
+        return this.publicExponent;
+    }
+
+    /**
+     * Returns the primeP.
+
+     * @return the primeP
+     */
+    public BigInteger getPrimeP() {
+        return this.primeP;
+    }
+
+    /**
+     * Returns the primeQ.
+     *
+     * @return the primeQ
+     */
+    public BigInteger getPrimeQ() {
+        return this.primeQ;
+    }
+
+    /**
+     * Returns the primeExponentP.
+     *
+     * @return the primeExponentP
+     */
+    public BigInteger getPrimeExponentP() {
+        return this.primeExponentP;
+    }
+
+    /**
+     * Returns the primeExponentQ.
+     *
+     * @return the primeExponentQ
+     */
+    public BigInteger getPrimeExponentQ() {
+        return this.primeExponentQ;
+    }
+
+    /**
+     * Returns the crtCoefficient.
+     *
+     * @return the crtCoefficient
+     */
+    public BigInteger getCrtCoefficient() {
+        return this.crtCoefficient;
+    }
+}
diff --git a/java/security/spec/RSAPrivateKeySpec.java b/java/security/spec/RSAPrivateKeySpec.java
new file mode 100644
index 0000000..e749146
--- /dev/null
+++ b/java/security/spec/RSAPrivateKeySpec.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 1998, 2001, 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 java.security.spec;
+
+import java.math.BigInteger;
+
+/**
+ * This class specifies an RSA private key.
+ *
+ * @author Jan Luehe
+ *
+ *
+ * @see java.security.Key
+ * @see java.security.KeyFactory
+ * @see KeySpec
+ * @see PKCS8EncodedKeySpec
+ * @see RSAPublicKeySpec
+ * @see RSAPrivateCrtKeySpec
+ */
+
+public class RSAPrivateKeySpec implements KeySpec {
+
+    private BigInteger modulus;
+    private BigInteger privateExponent;
+
+    /**
+     * Creates a new RSAPrivateKeySpec.
+     *
+     * @param modulus the modulus
+     * @param privateExponent the private exponent
+     */
+    public RSAPrivateKeySpec(BigInteger modulus, BigInteger privateExponent) {
+        this.modulus = modulus;
+        this.privateExponent = privateExponent;
+    }
+
+    /**
+     * Returns the modulus.
+     *
+     * @return the modulus
+     */
+    public BigInteger getModulus() {
+        return this.modulus;
+    }
+
+    /**
+     * Returns the private exponent.
+     *
+     * @return the private exponent
+     */
+    public BigInteger getPrivateExponent() {
+        return this.privateExponent;
+    }
+}
diff --git a/java/security/spec/RSAPublicKeySpec.java b/java/security/spec/RSAPublicKeySpec.java
new file mode 100644
index 0000000..9a944f9
--- /dev/null
+++ b/java/security/spec/RSAPublicKeySpec.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 1998, 2001, 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 java.security.spec;
+
+import java.math.BigInteger;
+
+/**
+ * This class specifies an RSA public key.
+ *
+ * @author Jan Luehe
+ *
+ *
+ * @see java.security.Key
+ * @see java.security.KeyFactory
+ * @see KeySpec
+ * @see X509EncodedKeySpec
+ * @see RSAPrivateKeySpec
+ * @see RSAPrivateCrtKeySpec
+ */
+
+public class RSAPublicKeySpec implements KeySpec {
+
+    private BigInteger modulus;
+    private BigInteger publicExponent;
+
+    /**
+     * Creates a new RSAPublicKeySpec.
+     *
+     * @param modulus the modulus
+     * @param publicExponent the public exponent
+     */
+    public RSAPublicKeySpec(BigInteger modulus, BigInteger publicExponent) {
+        this.modulus = modulus;
+        this.publicExponent = publicExponent;
+    }
+
+    /**
+     * Returns the modulus.
+     *
+     * @return the modulus
+     */
+    public BigInteger getModulus() {
+        return this.modulus;
+    }
+
+    /**
+     * Returns the public exponent.
+     *
+     * @return the public exponent
+     */
+    public BigInteger getPublicExponent() {
+        return this.publicExponent;
+    }
+}
diff --git a/java/security/spec/X509EncodedKeySpec.java b/java/security/spec/X509EncodedKeySpec.java
new file mode 100644
index 0000000..b9984de
--- /dev/null
+++ b/java/security/spec/X509EncodedKeySpec.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 1997, 2013, 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 java.security.spec;
+
+/**
+ * This class represents the ASN.1 encoding of a public key,
+ * encoded according to the ASN.1 type {@code SubjectPublicKeyInfo}.
+ * The {@code SubjectPublicKeyInfo} syntax is defined in the X.509
+ * standard as follows:
+ *
+ * <pre>
+ * SubjectPublicKeyInfo ::= SEQUENCE {
+ *   algorithm AlgorithmIdentifier,
+ *   subjectPublicKey BIT STRING }
+ * </pre>
+ *
+ * @author Jan Luehe
+ *
+ *
+ * @see java.security.Key
+ * @see java.security.KeyFactory
+ * @see KeySpec
+ * @see EncodedKeySpec
+ * @see PKCS8EncodedKeySpec
+ *
+ * @since 1.2
+ */
+
+public class X509EncodedKeySpec extends EncodedKeySpec {
+
+    /**
+     * Creates a new X509EncodedKeySpec with the given encoded key.
+     *
+     * @param encodedKey the key, which is assumed to be
+     * encoded according to the X.509 standard. The contents of the
+     * array are copied to protect against subsequent modification.
+     * @exception NullPointerException if {@code encodedKey}
+     * is null.
+     */
+    public X509EncodedKeySpec(byte[] encodedKey) {
+        super(encodedKey);
+    }
+
+    /**
+     * Returns the key bytes, encoded according to the X.509 standard.
+     *
+     * @return the X.509 encoding of the key. Returns a new array
+     * each time this method is called.
+     */
+    public byte[] getEncoded() {
+        return super.getEncoded();
+    }
+
+    /**
+     * Returns the name of the encoding format associated with this
+     * key specification.
+     *
+     * @return the string {@code "X.509"}.
+     */
+    public final String getFormat() {
+        return "X.509";
+    }
+}
diff --git a/java/security/spec/package-info.java b/java/security/spec/package-info.java
new file mode 100644
index 0000000..92f30be
--- /dev/null
+++ b/java/security/spec/package-info.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 1998, 2013, 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.
+ */
+
+/**
+ * Provides classes and interfaces for key specifications and algorithm
+ * parameter specifications.
+ *
+ * <p>A key specification is a transparent representation of the key material
+ * that constitutes a key. A key may be specified in an algorithm-specific
+ * way, or in an algorithm-independent encoding format (such as ASN.1).
+ * This package contains key specifications for DSA public and private keys,
+ * RSA public and private keys, PKCS #8 private keys in DER-encoded format,
+ * and X.509 public and private keys in DER-encoded format.
+ *
+ * <p>An algorithm parameter specification is a transparent representation
+ * of the sets of parameters used with an algorithm. This package contains
+ * an algorithm parameter specification for parameters used with the
+ * DSA algorithm.
+ *
+ * <h2>Package Specification</h2>
+ *
+ * <ul>
+ *   <li>PKCS #1: RSA Encryption Standard, Version 1.5, November 1993</li>
+ *   <li>PKCS #8: Private-Key Information Syntax Standard,
+ *     Version 1.2, November 1993</li>
+ *   <li>Federal Information Processing Standards Publication (FIPS PUB) 186:
+ *     Digital Signature Standard (DSS)</li>
+ * </ul>
+ *
+ * <h2>Related Documentation</h2>
+ *
+ * For documentation that includes information about algorithm parameter
+ * and key specifications, please see:
+ * <ul>
+ *   <li>
+ *     <a href=
+ *       "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/CryptoSpec.html">
+ *       <b>Java&trade;
+ *       Cryptography Architecture API Specification and Reference
+ *       </b></a></li>
+ *   <li>
+ *     <a href=
+ *       "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/HowToImplAProvider.html">
+ *       <b>How to Implement a Provider for the
+ *       Java&trade; Cryptography Architecture
+ *       </b></a></li>
+ * </ul>
+ *
+ * @since 1.2
+ */
+package java.security.spec;
