changeset 7915:f120e2c4b4b1

8016850: JCK javax.security.auth.Policy tests fail when run in Profiles mode Summary: Move default javax.security.auth.Policy implementation to compact1 profile Reviewed-by: vinnie
author mullan
date Mon, 19 Aug 2013 17:17:17 -0400
parents 2fd841fccb2e
children 096e7c665857
files src/share/classes/com/sun/security/auth/PolicyFile.java src/share/classes/com/sun/security/auth/PolicyParser.java src/share/classes/com/sun/security/auth/SubjectCodeSource.java src/share/classes/javax/security/auth/Policy.java src/share/classes/sun/security/provider/AuthPolicyFile.java src/share/classes/sun/security/provider/SubjectCodeSource.java
diffstat 6 files changed, 1615 insertions(+), 2539 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/security/auth/PolicyFile.java	Mon Aug 19 12:38:56 2013 -0700
+++ b/src/share/classes/com/sun/security/auth/PolicyFile.java	Mon Aug 19 17:17:17 2013 -0400
@@ -25,31 +25,9 @@
 
 package com.sun.security.auth;
 
-import java.io.*;
-import java.lang.reflect.*;
-import java.net.URL;
-import java.util.*;
-
 import java.security.CodeSource;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.Permission;
-import java.security.Permissions;
 import java.security.PermissionCollection;
-import java.security.Principal;
-import java.security.UnresolvedPermission;
-import java.security.Security;
-import java.security.cert.Certificate;
-import java.security.cert.X509Certificate;
-
 import javax.security.auth.Subject;
-import javax.security.auth.PrivateCredentialPermission;
-
-import sun.security.util.PropertyExpander;
-
-import sun.security.provider.PolicyParser.PrincipalEntry;
-import sun.security.provider.PolicyParser.GrantEntry;
-import sun.security.provider.PolicyParser.PermissionEntry;
 
 /**
  * This class represents a default implementation for
@@ -240,61 +218,14 @@
 @Deprecated
 public class PolicyFile extends javax.security.auth.Policy {
 
-    static final java.util.ResourceBundle rb =
-        java.security.AccessController.doPrivileged
-        (new java.security.PrivilegedAction<java.util.ResourceBundle>() {
-            public java.util.ResourceBundle run() {
-                return (java.util.ResourceBundle.getBundle
-                        ("sun.security.util.AuthResources"));
-            }
-        });
-    // needs to be package private
-
-    private static final sun.security.util.Debug debug =
-        sun.security.util.Debug.getInstance("policy", "\t[Auth Policy]");
-
-    private static final String AUTH_POLICY = "java.security.auth.policy";
-    private static final String SECURITY_MANAGER = "java.security.manager";
-    private static final String AUTH_POLICY_URL = "auth.policy.url.";
-
-    private Vector<PolicyEntry> policyEntries;
-    private Hashtable<Object, Object> aliasMapping;
-
-    private boolean initialized = false;
-
-    private boolean expandProperties = true;
-    private boolean ignoreIdentityScope = true;
-
-    // for use with the reflection API
-
-    private static final Class[] PARAMS = { String.class, String.class};
+    private final sun.security.provider.AuthPolicyFile apf;
 
     /**
      * Initializes the Policy object and reads the default policy
      * configuration file(s) into the Policy object.
      */
     public PolicyFile() {
-        // initialize Policy if either the AUTH_POLICY or
-        // SECURITY_MANAGER properties are set
-        String prop = System.getProperty(AUTH_POLICY);
-
-        if (prop == null) {
-            prop = System.getProperty(SECURITY_MANAGER);
-        }
-        if (prop != null)
-            init();
-    }
-
-    private synchronized void init() {
-
-        if (initialized)
-            return;
-
-        policyEntries = new Vector<PolicyEntry>();
-        aliasMapping = new Hashtable<Object, Object>(11);
-
-        initPolicyFile();
-        initialized = true;
+        apf = new sun.security.provider.AuthPolicyFile();
     }
 
     /**
@@ -305,460 +236,9 @@
      * @exception SecurityException if the caller doesn't have permission
      *          to refresh the <code>Policy</code>.
      */
-    public synchronized void refresh()
-    {
-
-        java.lang.SecurityManager sm = System.getSecurityManager();
-        if (sm != null) {
-            sm.checkPermission(new javax.security.auth.AuthPermission
-                                ("refreshPolicy"));
-        }
-
-        // XXX
-        //
-        // 1)   if code instantiates PolicyFile directly, then it will need
-        //      all the permissions required for the PolicyFile initialization
-        // 2)   if code calls Policy.getPolicy, then it simply needs
-        //      AuthPermission(getPolicy), and the javax.security.auth.Policy
-        //      implementation instantiates PolicyFile in a doPrivileged block
-        // 3)   if after instantiating a Policy (either via #1 or #2),
-        //      code calls refresh, it simply needs
-        //      AuthPermission(refreshPolicy).  then PolicyFile wraps
-        //      the refresh in a doPrivileged block.
-        initialized = false;
-        java.security.AccessController.doPrivileged
-            (new java.security.PrivilegedAction<Void>() {
-            public Void run() {
-                init();
-                return null;
-            }
-        });
-    }
-
-    private KeyStore initKeyStore(URL policyUrl, String keyStoreName,
-                                  String keyStoreType) {
-        if (keyStoreName != null) {
-            try {
-                /*
-                 * location of keystore is specified as absolute URL in policy
-                 * file, or is relative to URL of policy file
-                 */
-                URL keyStoreUrl = null;
-                try {
-                    keyStoreUrl = new URL(keyStoreName);
-                    // absolute URL
-                } catch (java.net.MalformedURLException e) {
-                    // relative URL
-                    keyStoreUrl = new URL(policyUrl, keyStoreName);
-                }
-
-                if (debug != null) {
-                    debug.println("reading keystore"+keyStoreUrl);
-                }
-
-                InputStream inStream =
-                    new BufferedInputStream(getInputStream(keyStoreUrl));
-
-                KeyStore ks;
-                if (keyStoreType != null)
-                    ks = KeyStore.getInstance(keyStoreType);
-                else
-                    ks = KeyStore.getInstance(KeyStore.getDefaultType());
-                ks.load(inStream, null);
-                inStream.close();
-                return ks;
-            } catch (Exception e) {
-                // ignore, treat it like we have no keystore
-                if (debug != null) {
-                    e.printStackTrace();
-                }
-                return null;
-            }
-        }
-        return null;
-    }
-
-    private void initPolicyFile() {
-
-        String prop = Security.getProperty("policy.expandProperties");
-
-        if (prop != null) expandProperties = prop.equalsIgnoreCase("true");
-
-        String iscp = Security.getProperty("policy.ignoreIdentityScope");
-
-        if (iscp != null) ignoreIdentityScope = iscp.equalsIgnoreCase("true");
-
-        String allowSys  = Security.getProperty("policy.allowSystemProperty");
-
-        if ((allowSys!=null) && allowSys.equalsIgnoreCase("true")) {
-
-            String extra_policy = System.getProperty(AUTH_POLICY);
-            if (extra_policy != null) {
-                boolean overrideAll = false;
-                if (extra_policy.startsWith("=")) {
-                    overrideAll = true;
-                    extra_policy = extra_policy.substring(1);
-                }
-                try {
-                    extra_policy = PropertyExpander.expand(extra_policy);
-                    URL policyURL;
-                    File policyFile = new File(extra_policy);
-                    if (policyFile.exists()) {
-                        policyURL =
-                            new URL("file:" + policyFile.getCanonicalPath());
-                    } else {
-                        policyURL = new URL(extra_policy);
-                    }
-                    if (debug != null)
-                        debug.println("reading "+policyURL);
-                    init(policyURL);
-                } catch (Exception e) {
-                    // ignore.
-                    if (debug != null) {
-                        debug.println("caught exception: "+e);
-                    }
-
-                }
-                if (overrideAll) {
-                    if (debug != null) {
-                        debug.println("overriding other policies!");
-                    }
-                    return;
-                }
-            }
-        }
-
-        int n = 1;
-        boolean loaded_one = false;
-        String policy_url;
-
-        while ((policy_url = Security.getProperty(AUTH_POLICY_URL+n)) != null) {
-            try {
-                policy_url = PropertyExpander.expand(policy_url).replace
-                                                (File.separatorChar, '/');
-                if (debug != null)
-                    debug.println("reading "+policy_url);
-                init(new URL(policy_url));
-                loaded_one = true;
-            } catch (Exception e) {
-                if (debug != null) {
-                    debug.println("error reading policy "+e);
-                    e.printStackTrace();
-                }
-                // ignore that policy
-            }
-            n++;
-        }
-
-        if (loaded_one == false) {
-            // do not load a static policy
-        }
-    }
-
-    /**
-     * Checks public key. If it is marked as trusted in
-     * the identity database, add it to the policy
-     * with the AllPermission.
-     */
-    private boolean checkForTrustedIdentity(final Certificate cert) {
-        // XXX  JAAS has no way to access the SUN package.
-        //      we'll add this back in when JAAS goes into core.
-        return false;
-    }
-
-    /**
-     * Reads a policy configuration into the Policy object using a
-     * Reader object.
-     *
-     * @param policyFile the policy Reader object.
-     */
-    private void init(URL policy) {
-        sun.security.provider.PolicyParser pp =
-                new sun.security.provider.PolicyParser(expandProperties);
-        try {
-            InputStreamReader isr
-                = new InputStreamReader(getInputStream(policy));
-            pp.read(isr);
-            isr.close();
-            KeyStore keyStore = initKeyStore(policy, pp.getKeyStoreUrl(),
-                                             pp.getKeyStoreType());
-            Enumeration<GrantEntry> enum_ = pp.grantElements();
-            while (enum_.hasMoreElements()) {
-                GrantEntry ge = enum_.nextElement();
-                addGrantEntry(ge, keyStore);
-            }
-        } catch (sun.security.provider.PolicyParser.ParsingException pe) {
-            System.err.println(AUTH_POLICY +
-                                rb.getString(".error.parsing.") + policy);
-            System.err.println(AUTH_POLICY +
-                                rb.getString("COLON") +
-                                pe.getMessage());
-            if (debug != null)
-                pe.printStackTrace();
-
-        } catch (Exception e) {
-            if (debug != null) {
-                debug.println("error parsing "+policy);
-                debug.println(e.toString());
-                e.printStackTrace();
-            }
-        }
-    }
-
-    /*
-     * Fast path reading from file urls in order to avoid calling
-     * FileURLConnection.connect() which can be quite slow the first time
-     * it is called. We really should clean up FileURLConnection so that
-     * this is not a problem but in the meantime this fix helps reduce
-     * start up time noticeably for the new launcher. -- DAC
-     */
-    private InputStream getInputStream(URL url) throws IOException {
-        if ("file".equals(url.getProtocol())) {
-            String path = url.getFile().replace('/', File.separatorChar);
-            return new FileInputStream(path);
-        } else {
-            return url.openStream();
-        }
-    }
-
-    /**
-     * Given a PermissionEntry, create a codeSource.
-     *
-     * @return null if signedBy alias is not recognized
-     */
-    CodeSource getCodeSource(GrantEntry ge, KeyStore keyStore)
-            throws java.net.MalformedURLException
-    {
-        Certificate[] certs = null;
-        if (ge.signedBy != null) {
-            certs = getCertificates(keyStore, ge.signedBy);
-            if (certs == null) {
-                // we don't have a key for this alias,
-                // just return
-                if (debug != null) {
-                    debug.println(" no certs for alias " +
-                                       ge.signedBy + ", ignoring.");
-                }
-                return null;
-            }
-        }
-
-        URL location;
-
-        if (ge.codeBase != null)
-            location = new URL(ge.codeBase);
-        else
-            location = null;
-
-        if (ge.principals == null || ge.principals.size() == 0) {
-            return (canonicalizeCodebase
-                        (new CodeSource(location, certs),
-                        false));
-        } else {
-            return (canonicalizeCodebase
-                (new SubjectCodeSource(null, ge.principals, location, certs),
-                false));
-        }
-    }
-
-    /**
-     * Add one policy entry to the vector.
-     */
-    private void addGrantEntry(GrantEntry ge, KeyStore keyStore) {
-
-        if (debug != null) {
-            debug.println("Adding policy entry: ");
-            debug.println("  signedBy " + ge.signedBy);
-            debug.println("  codeBase " + ge.codeBase);
-            if (ge.principals != null && ge.principals.size() > 0) {
-                ListIterator<PrincipalEntry> li = ge.principals.listIterator();
-                while (li.hasNext()) {
-                    PrincipalEntry pppe = li.next();
-                    debug.println("  " + pppe.getPrincipalClass() +
-                                        " " + pppe.getPrincipalName());
-                }
-            }
-            debug.println();
-        }
-
-        try {
-            CodeSource codesource = getCodeSource(ge, keyStore);
-            // skip if signedBy alias was unknown...
-            if (codesource == null) return;
-
-            PolicyEntry entry = new PolicyEntry(codesource);
-            Enumeration<PermissionEntry> enum_ = ge.permissionElements();
-            while (enum_.hasMoreElements()) {
-                PermissionEntry pe = enum_.nextElement();
-                try {
-                    // XXX special case PrivateCredentialPermission-SELF
-                    Permission perm;
-                    if (pe.permission.equals
-                        ("javax.security.auth.PrivateCredentialPermission") &&
-                        pe.name.endsWith(" self")) {
-                        perm = getInstance(pe.permission,
-                                         pe.name + " \"self\"",
-                                         pe.action);
-                    } else {
-                        perm = getInstance(pe.permission,
-                                         pe.name,
-                                         pe.action);
-                    }
-                    entry.add(perm);
-                    if (debug != null) {
-                        debug.println("  "+perm);
-                    }
-                } catch (ClassNotFoundException cnfe) {
-                    Certificate certs[];
-                    if (pe.signedBy != null)
-                        certs = getCertificates(keyStore, pe.signedBy);
-                    else
-                        certs = null;
-
-                    // only add if we had no signer or we had a
-                    // a signer and found the keys for it.
-                    if (certs != null || pe.signedBy == null) {
-                            Permission perm = new UnresolvedPermission(
-                                             pe.permission,
-                                             pe.name,
-                                             pe.action,
-                                             certs);
-                            entry.add(perm);
-                            if (debug != null) {
-                                debug.println("  "+perm);
-                            }
-                    }
-                } catch (java.lang.reflect.InvocationTargetException ite) {
-                    System.err.println
-                        (AUTH_POLICY +
-                        rb.getString(".error.adding.Permission.") +
-                        pe.permission +
-                        rb.getString("SPACE") +
-                        ite.getTargetException());
-                } catch (Exception e) {
-                    System.err.println
-                        (AUTH_POLICY +
-                        rb.getString(".error.adding.Permission.") +
-                        pe.permission +
-                        rb.getString("SPACE") +
-                        e);
-                }
-            }
-            policyEntries.addElement(entry);
-        } catch (Exception e) {
-            System.err.println
-                (AUTH_POLICY +
-                rb.getString(".error.adding.Entry.") +
-                ge +
-                rb.getString("SPACE") +
-                e);
-        }
-
-        if (debug != null)
-            debug.println();
-    }
-
-    /**
-     * Returns a new Permission object of the given Type. The Permission is
-     * created by getting the
-     * Class object using the <code>Class.forName</code> method, and using
-     * the reflection API to invoke the (String name, String actions)
-     * constructor on the
-     * object.
-     *
-     * @param type the type of Permission being created.
-     * @param name the name of the Permission being created.
-     * @param actions the actions of the Permission being created.
-     *
-     * @exception  ClassNotFoundException  if the particular Permission
-     *             class could not be found.
-     *
-     * @exception  IllegalAccessException  if the class or initializer is
-     *               not accessible.
-     *
-     * @exception  InstantiationException  if getInstance tries to
-     *               instantiate an abstract class or an interface, or if the
-     *               instantiation fails for some other reason.
-     *
-     * @exception  NoSuchMethodException if the (String, String) constructor
-     *               is not found.
-     *
-     * @exception  InvocationTargetException if the underlying Permission
-     *               constructor throws an exception.
-     *
-     */
-
-    private static final Permission getInstance(String type,
-                                    String name,
-                                    String actions)
-        throws ClassNotFoundException,
-               InstantiationException,
-               IllegalAccessException,
-               NoSuchMethodException,
-               InvocationTargetException
-    {
-        //XXX we might want to keep a hash of created factories...
-        Class<?> pc = Class.forName(type);
-        Constructor<?> c = pc.getConstructor(PARAMS);
-        return (Permission) c.newInstance(new Object[] { name, actions });
-    }
-
-    /**
-     * Fetch all certs associated with this alias.
-     */
-    Certificate[] getCertificates(
-                                    KeyStore keyStore, String aliases) {
-
-        Vector<Certificate> vcerts = null;
-
-        StringTokenizer st = new StringTokenizer(aliases, ",");
-        int n = 0;
-
-        while (st.hasMoreTokens()) {
-            String alias = st.nextToken().trim();
-            n++;
-            Certificate cert = null;
-            //See if this alias's cert has already been cached
-            cert = (Certificate) aliasMapping.get(alias);
-            if (cert == null && keyStore != null) {
-
-                try {
-                    cert = keyStore.getCertificate(alias);
-                } catch (KeyStoreException kse) {
-                    // never happens, because keystore has already been loaded
-                    // when we call this
-                }
-                if (cert != null) {
-                    aliasMapping.put(alias, cert);
-                    aliasMapping.put(cert, alias);
-                }
-            }
-
-            if (cert != null) {
-                if (vcerts == null)
-                    vcerts = new Vector<Certificate>();
-                vcerts.addElement(cert);
-            }
-        }
-
-        // make sure n == vcerts.size, since we are doing a logical *and*
-        if (vcerts != null && n == vcerts.size()) {
-            Certificate[] certs = new Certificate[vcerts.size()];
-            vcerts.copyInto(certs);
-            return certs;
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Enumerate all the entries in the global policy object.
-     * This method is used by policy admin tools.   The tools
-     * should use the Enumeration methods on the returned object
-     * to fetch the elements sequentially.
-     */
-    private final synchronized Enumeration<PolicyEntry> elements(){
-        return policyEntries.elements();
+    @Override
+    public void refresh() {
+        apf.refresh();
     }
 
     /**
@@ -816,646 +296,9 @@
      * @return the Permissions granted to the provided <code>Subject</code>
      *          <code>CodeSource</code>.
      */
+    @Override
     public PermissionCollection getPermissions(final Subject subject,
-                                        final CodeSource codesource) {
-
-        // XXX  when JAAS goes into the JDK core,
-        //      we can remove this method and simply
-        //      rely on the getPermissions variant that takes a codesource,
-        //      which no one can use at this point in time.
-        //      at that time, we can also make SubjectCodeSource a public
-        //      class.
-
-        // XXX
-        //
-        // 1)   if code instantiates PolicyFile directly, then it will need
-        //      all the permissions required for the PolicyFile initialization
-        // 2)   if code calls Policy.getPolicy, then it simply needs
-        //      AuthPermission(getPolicy), and the javax.security.auth.Policy
-        //      implementation instantiates PolicyFile in a doPrivileged block
-        // 3)   if after instantiating a Policy (either via #1 or #2),
-        //      code calls getPermissions, PolicyFile wraps the call
-        //      in a doPrivileged block.
-        return java.security.AccessController.doPrivileged
-            (new java.security.PrivilegedAction<PermissionCollection>() {
-            public PermissionCollection run() {
-                SubjectCodeSource scs = new SubjectCodeSource
-                    (subject,
-                    null,
-                    codesource == null ? null : codesource.getLocation(),
-                    codesource == null ? null : codesource.getCertificates());
-                if (initialized)
-                    return getPermissions(new Permissions(), scs);
-                else
-                    return new PolicyPermissions(PolicyFile.this, scs);
-            }
-        });
-    }
-
-    /**
-     * Examines the global policy for the specified CodeSource, and
-     * creates a PermissionCollection object with
-     * the set of permissions for that principal's protection domain.
-     *
-     * @param CodeSource the codesource associated with the caller.
-     * This encapsulates the original location of the code (where the code
-     * came from) and the public key(s) of its signer.
-     *
-     * @return the set of permissions according to the policy.
-     */
-    PermissionCollection getPermissions(CodeSource codesource) {
-
-        if (initialized)
-            return getPermissions(new Permissions(), codesource);
-        else
-            return new PolicyPermissions(this, codesource);
-    }
-
-    /**
-     * Examines the global policy for the specified CodeSource, and
-     * creates a PermissionCollection object with
-     * the set of permissions for that principal's protection domain.
-     *
-     * @param permissions the permissions to populate
-     * @param codesource the codesource associated with the caller.
-     * This encapsulates the original location of the code (where the code
-     * came from) and the public key(s) of its signer.
-     *
-     * @return the set of permissions according to the policy.
-     */
-    Permissions getPermissions(final Permissions perms,
-                               final CodeSource cs)
-    {
-        if (!initialized) {
-            init();
-        }
-
-        final CodeSource codesource[] = {null};
-
-        codesource[0] = canonicalizeCodebase(cs, true);
-
-        if (debug != null) {
-            debug.println("evaluate("+codesource[0]+")\n");
-        }
-
-        // needs to be in a begin/endPrivileged block because
-        // codesource.implies calls URL.equals which does an
-        // InetAddress lookup
-
-        for (int i = 0; i < policyEntries.size(); i++) {
-
-           PolicyEntry entry = policyEntries.elementAt(i);
-
-           if (debug != null) {
-                debug.println("PolicyFile CodeSource implies: " +
-                        entry.codesource.toString() + "\n\n" +
-                        "\t" + codesource[0].toString() + "\n\n");
-           }
-
-           if (entry.codesource.implies(codesource[0])) {
-               for (int j = 0; j < entry.permissions.size(); j++) {
-                    Permission p = entry.permissions.elementAt(j);
-                    if (debug != null) {
-                       debug.println("  granting " + p);
-                    }
-                    if (!addSelfPermissions(p, entry.codesource,
-                                        codesource[0], perms)) {
-                        // we could check for duplicates
-                        // before adding new permissions,
-                        // but the SubjectDomainCombiner
-                        // already checks for duplicates later
-                        perms.add(p);
-                    }
-                }
-            }
-        }
-
-        // now see if any of the keys are trusted ids.
-
-        if (!ignoreIdentityScope) {
-            Certificate certs[] = codesource[0].getCertificates();
-            if (certs != null) {
-                for (int k=0; k < certs.length; k++) {
-                    if ((aliasMapping.get(certs[k]) == null) &&
-                        checkForTrustedIdentity(certs[k])) {
-                        // checkForTrustedIdentity added it
-                        // to the policy for us. next time
-                        // around we'll find it. This time
-                        // around we need to add it.
-                        perms.add(new java.security.AllPermission());
-                    }
-                }
-            }
-        }
-        return perms;
-    }
-
-    /**
-     * Returns true if 'Self' permissions were added to the provided
-     * 'perms', and false otherwise.
-     *
-     * <p>
-     *
-     * @param p check to see if this Permission is a "SELF"
-     *                  PrivateCredentialPermission. <p>
-     *
-     * @param entryCs the codesource for the Policy entry.
-     *
-     * @param accCs the codesource for from the current AccessControlContext.
-     *
-     * @param perms the PermissionCollection where the individual
-     *                  PrivateCredentialPermissions will be added.
-     */
-    private boolean addSelfPermissions(final Permission p,
-                                CodeSource entryCs,
-                                CodeSource accCs,
-                                Permissions perms) {
-
-        if (!(p instanceof PrivateCredentialPermission))
-            return false;
-
-        if (!(entryCs instanceof SubjectCodeSource))
-            return false;
-
-
-        PrivateCredentialPermission pcp = (PrivateCredentialPermission)p;
-        SubjectCodeSource scs = (SubjectCodeSource)entryCs;
-
-        // see if it is a SELF permission
-        String[][] pPrincipals = pcp.getPrincipals();
-        if (pPrincipals.length <= 0 ||
-            !pPrincipals[0][0].equalsIgnoreCase("self") ||
-            !pPrincipals[0][1].equalsIgnoreCase("self")) {
-
-            // regular PrivateCredentialPermission
-            return false;
-        } else {
-
-            // granted a SELF permission - create a
-            // PrivateCredentialPermission for each
-            // of the Policy entry's CodeSource Principals
-
-            if (scs.getPrincipals() == null) {
-                // XXX SubjectCodeSource has no Subject???
-                return true;
-            }
-
-            ListIterator<PrincipalEntry> pli =
-                    scs.getPrincipals().listIterator();
-            while (pli.hasNext()) {
-
-                PrincipalEntry principal = pli.next();
-
-                // XXX
-                //      if the Policy entry's Principal does not contain a
-                //              WILDCARD for the Principal name, then a
-                //              new PrivateCredentialPermission is created
-                //              for the Principal listed in the Policy entry.
-                //      if the Policy entry's Principal contains a WILDCARD
-                //              for the Principal name, then a new
-                //              PrivateCredentialPermission is created
-                //              for each Principal associated with the Subject
-                //              in the current ACC.
-
-                String[][] principalInfo = getPrincipalInfo
-                                                (principal, accCs);
-
-                for (int i = 0; i < principalInfo.length; i++) {
-
-                    // here's the new PrivateCredentialPermission
-
-                    PrivateCredentialPermission newPcp =
-                        new PrivateCredentialPermission
-                                (pcp.getCredentialClass() +
-                                        " " +
-                                        principalInfo[i][0] +
-                                        " " +
-                                        "\"" + principalInfo[i][1] + "\"",
-                                "read");
-
-                    if (debug != null) {
-                        debug.println("adding SELF permission: " +
-                                        newPcp.toString());
-                    }
-
-                    perms.add(newPcp);
-                }
-            }
-        }
-        return true;
-    }
-
-    /**
-     * return the principal class/name pair in the 2D array.
-     * array[x][y]:     x corresponds to the array length.
-     *                  if (y == 0), it's the principal class.
-     *                  if (y == 1), it's the principal name.
-     */
-    private String[][] getPrincipalInfo
-                (PrincipalEntry principal, final CodeSource accCs) {
-
-        // there are 3 possibilities:
-        // 1) the entry's Principal class and name are not wildcarded
-        // 2) the entry's Principal name is wildcarded only
-        // 3) the entry's Principal class and name are wildcarded
-
-        if (!principal.getPrincipalClass().equals
-                (PrincipalEntry.WILDCARD_CLASS) &&
-            !principal.getPrincipalName().equals
-                (PrincipalEntry.WILDCARD_NAME)) {
-
-            // build a PrivateCredentialPermission for the principal
-            // from the Policy entry
-            String[][] info = new String[1][2];
-            info[0][0] = principal.getPrincipalClass();
-            info[0][1] = principal.getPrincipalName();
-            return info;
-
-        } else if (!principal.getPrincipalClass().equals
-                (PrincipalEntry.WILDCARD_CLASS) &&
-            principal.getPrincipalName().equals
-                (PrincipalEntry.WILDCARD_NAME)) {
-
-            // build a PrivateCredentialPermission for all
-            // the Subject's principals that are instances of principalClass
-
-            // the accCs is guaranteed to be a SubjectCodeSource
-            // because the earlier CodeSource.implies succeeded
-            SubjectCodeSource scs = (SubjectCodeSource)accCs;
-
-            Set<? extends Principal> principalSet = null;
-            try {
-                // principal.principalClass should extend Principal
-                // If it doesn't, we should stop here with a ClassCastException.
-                @SuppressWarnings("unchecked")
-                Class<? extends Principal> pClass = (Class<? extends Principal>)
-                        Class.forName(principal.getPrincipalClass(), false,
-                                      ClassLoader.getSystemClassLoader());
-                principalSet = scs.getSubject().getPrincipals(pClass);
-            } catch (Exception e) {
-                if (debug != null) {
-                    debug.println("problem finding Principal Class " +
-                                  "when expanding SELF permission: " +
-                                  e.toString());
-                }
-            }
-
-            if (principalSet == null) {
-                // error
-                return new String[0][0];
-            }
-
-            String[][] info = new String[principalSet.size()][2];
-
-            int i = 0;
-            for (Principal p : principalSet) {
-                info[i][0] = p.getClass().getName();
-                info[i][1] = p.getName();
-                i++;
-            }
-            return info;
-
-        } else {
-
-            // build a PrivateCredentialPermission for every
-            // one of the current Subject's principals
-
-            // the accCs is guaranteed to be a SubjectCodeSource
-            // because the earlier CodeSource.implies succeeded
-            SubjectCodeSource scs = (SubjectCodeSource)accCs;
-            Set<Principal> principalSet = scs.getSubject().getPrincipals();
-
-            String[][] info = new String[principalSet.size()][2];
-            java.util.Iterator<Principal> pIterator = principalSet.iterator();
-
-            int i = 0;
-            while (pIterator.hasNext()) {
-                Principal p = pIterator.next();
-                info[i][0] = p.getClass().getName();
-                info[i][1] = p.getName();
-                i++;
-            }
-            return info;
-        }
-    }
-
-    /*
-     * Returns the signer certificates from the list of certificates associated
-     * with the given code source.
-     *
-     * The signer certificates are those certificates that were used to verify
-     * signed code originating from the codesource location.
-     *
-     * This method assumes that in the given code source, each signer
-     * certificate is followed by its supporting certificate chain
-     * (which may be empty), and that the signer certificate and its
-     * supporting certificate chain are ordered bottom-to-top (i.e., with the
-     * signer certificate first and the (root) certificate authority last).
-     */
-    Certificate[] getSignerCertificates(CodeSource cs) {
-        Certificate[] certs = null;
-        if ((certs = cs.getCertificates()) == null)
-            return null;
-        for (int i=0; i<certs.length; i++) {
-            if (!(certs[i] instanceof X509Certificate))
-                return cs.getCertificates();
-        }
-
-        // Do we have to do anything?
-        int i = 0;
-        int count = 0;
-        while (i < certs.length) {
-            count++;
-            while (((i+1) < certs.length)
-                   && ((X509Certificate)certs[i]).getIssuerDN().equals(
-                           ((X509Certificate)certs[i+1]).getSubjectDN())) {
-                i++;
-            }
-            i++;
-        }
-        if (count == certs.length)
-            // Done
-            return certs;
-
-        ArrayList<Certificate> userCertList = new ArrayList<>();
-        i = 0;
-        while (i < certs.length) {
-            userCertList.add(certs[i]);
-            while (((i+1) < certs.length)
-                   && ((X509Certificate)certs[i]).getIssuerDN().equals(
-                           ((X509Certificate)certs[i+1]).getSubjectDN())) {
-                i++;
-            }
-            i++;
-        }
-        Certificate[] userCerts = new Certificate[userCertList.size()];
-        userCertList.toArray(userCerts);
-        return userCerts;
-    }
-
-    private CodeSource canonicalizeCodebase(CodeSource cs,
-                                            boolean extractSignerCerts) {
-        CodeSource canonCs = cs;
-        if (cs.getLocation() != null &&
-            cs.getLocation().getProtocol().equalsIgnoreCase("file")) {
-            try {
-                String path = cs.getLocation().getFile().replace
-                                                        ('/',
-                                                        File.separatorChar);
-                URL csUrl = null;
-                if (path.endsWith("*")) {
-                    // remove trailing '*' because it causes canonicalization
-                    // to fail on win32
-                    path = path.substring(0, path.length()-1);
-                    boolean appendFileSep = false;
-                    if (path.endsWith(File.separator))
-                        appendFileSep = true;
-                    if (path.equals("")) {
-                        path = System.getProperty("user.dir");
-                    }
-                    File f = new File(path);
-                    path = f.getCanonicalPath();
-                    StringBuffer sb = new StringBuffer(path);
-                    // reappend '*' to canonicalized filename (note that
-                    // canonicalization may have removed trailing file
-                    // separator, so we have to check for that, too)
-                    if (!path.endsWith(File.separator) &&
-                        (appendFileSep || f.isDirectory()))
-                        sb.append(File.separatorChar);
-                    sb.append('*');
-                    path = sb.toString();
-                } else {
-                    path = new File(path).getCanonicalPath();
-                }
-                csUrl = new File(path).toURL();
-
-                if (cs instanceof SubjectCodeSource) {
-                    SubjectCodeSource scs = (SubjectCodeSource)cs;
-                    if (extractSignerCerts) {
-                        canonCs = new SubjectCodeSource
-                                                (scs.getSubject(),
-                                                scs.getPrincipals(),
-                                                csUrl,
-                                                getSignerCertificates(scs));
-                    } else {
-                        canonCs = new SubjectCodeSource
-                                                (scs.getSubject(),
-                                                scs.getPrincipals(),
-                                                csUrl,
-                                                scs.getCertificates());
-                    }
-                } else {
-                    if (extractSignerCerts) {
-                        canonCs = new CodeSource(csUrl,
-                                                getSignerCertificates(cs));
-                    } else {
-                        canonCs = new CodeSource(csUrl,
-                                                cs.getCertificates());
-                    }
-                }
-            } catch (IOException ioe) {
-                // leave codesource as it is, unless we have to extract its
-                // signer certificates
-                if (extractSignerCerts) {
-                    if (!(cs instanceof SubjectCodeSource)) {
-                        canonCs = new CodeSource(cs.getLocation(),
-                                                getSignerCertificates(cs));
-                    } else {
-                        SubjectCodeSource scs = (SubjectCodeSource)cs;
-                        canonCs = new SubjectCodeSource(scs.getSubject(),
-                                                scs.getPrincipals(),
-                                                scs.getLocation(),
-                                                getSignerCertificates(scs));
-                    }
-                }
-            }
-        } else {
-            if (extractSignerCerts) {
-                if (!(cs instanceof SubjectCodeSource)) {
-                    canonCs = new CodeSource(cs.getLocation(),
-                                        getSignerCertificates(cs));
-                } else {
-                    SubjectCodeSource scs = (SubjectCodeSource)cs;
-                    canonCs = new SubjectCodeSource(scs.getSubject(),
-                                        scs.getPrincipals(),
-                                        scs.getLocation(),
-                                        getSignerCertificates(scs));
-                }
-            }
-        }
-        return canonCs;
-    }
-
-    /**
-     * Each entry in the policy configuration file is represented by a
-     * PolicyEntry object.  <p>
-     *
-     * A PolicyEntry is a (CodeSource,Permission) pair.  The
-     * CodeSource contains the (URL, PublicKey) that together identify
-     * where the Java bytecodes come from and who (if anyone) signed
-     * them.  The URL could refer to localhost.  The URL could also be
-     * null, meaning that this policy entry is given to all comers, as
-     * long as they match the signer field.  The signer could be null,
-     * meaning the code is not signed. <p>
-     *
-     * The Permission contains the (Type, Name, Action) triplet. <p>
-     *
-     * For now, the Policy object retrieves the public key from the
-     * X.509 certificate on disk that corresponds to the signedBy
-     * alias specified in the Policy config file.  For reasons of
-     * efficiency, the Policy object keeps a hashtable of certs already
-     * read in.  This could be replaced by a secure internal key
-     * store.
-     *
-     * <p>
-     * For example, the entry
-     * <pre>
-     *          permission java.io.File "/tmp", "read,write",
-     *          signedBy "Duke";
-     * </pre>
-     * is represented internally
-     * <pre>
-     *
-     * FilePermission f = new FilePermission("/tmp", "read,write");
-     * PublicKey p = publickeys.get("Duke");
-     * URL u = InetAddress.getLocalHost();
-     * CodeBase c = new CodeBase( p, u );
-     * pe = new PolicyEntry(f, c);
-     * </pre>
-     *
-     * @author Marianne Mueller
-     * @author Roland Schemers
-     * @see java.security.CodeSource
-     * @see java.security.Policy
-     * @see java.security.Permissions
-     * @see java.security.ProtectionDomain
-     */
-
-    private static class PolicyEntry {
-
-        CodeSource codesource;
-        Vector<Permission> permissions;
-
-        /**
-         * Given a Permission and a CodeSource, create a policy entry.
-         *
-         * XXX Decide if/how to add validity fields and "purpose" fields to
-         * XXX policy entries
-         *
-         * @param cs the CodeSource, which encapsulates the URL and the public
-         *        key
-         *        attributes from the policy config file.   Validity checks are
-         *        performed on the public key before PolicyEntry is called.
-         *
-         */
-        PolicyEntry(CodeSource cs)
-        {
-            this.codesource = cs;
-            this.permissions = new Vector<Permission>();
-        }
-
-        /**
-         * add a Permission object to this entry.
-         */
-        void add(Permission p) {
-            permissions.addElement(p);
-        }
-
-        /**
-         * Return the CodeSource for this policy entry
-         */
-        CodeSource getCodeSource() {
-            return this.codesource;
-        }
-
-        public String toString(){
-            StringBuffer sb = new StringBuffer();
-            sb.append(rb.getString("LPARAM"));
-            sb.append(getCodeSource());
-            sb.append("\n");
-            for (int j = 0; j < permissions.size(); j++) {
-                Permission p = permissions.elementAt(j);
-                sb.append(rb.getString("SPACE"));
-                sb.append(rb.getString("SPACE"));
-                sb.append(p);
-                sb.append(rb.getString("NEWLINE"));
-            }
-            sb.append(rb.getString("RPARAM"));
-            sb.append(rb.getString("NEWLINE"));
-            return sb.toString();
-        }
-
+                                               final CodeSource codesource) {
+        return apf.getPermissions(subject, codesource);
     }
 }
-
-@SuppressWarnings("deprecation")
-class PolicyPermissions extends PermissionCollection {
-
-    private static final long serialVersionUID = -1954188373270545523L;
-
-    private CodeSource codesource;
-    private Permissions perms;
-    private PolicyFile policy;
-    private boolean notInit; // have we pulled in the policy permissions yet?
-    private Vector<Permission> additionalPerms;
-
-    PolicyPermissions(PolicyFile policy,
-                      CodeSource codesource)
-    {
-        this.codesource = codesource;
-        this.policy = policy;
-        this.perms = null;
-        this.notInit = true;
-        this.additionalPerms = null;
-    }
-
-    public void add(Permission permission) {
-        if (isReadOnly())
-            throw new SecurityException
-            (PolicyFile.rb.getString
-            ("attempt.to.add.a.Permission.to.a.readonly.PermissionCollection"));
-
-        if (perms == null) {
-            if (additionalPerms == null)
-                additionalPerms = new Vector<Permission>();
-            additionalPerms.add(permission);
-        } else {
-            perms.add(permission);
-        }
-    }
-
-    private synchronized void init() {
-        if (notInit) {
-            if (perms == null)
-                perms = new Permissions();
-
-            if (additionalPerms != null) {
-                Enumeration<Permission> e = additionalPerms.elements();
-                while (e.hasMoreElements()) {
-                    perms.add(e.nextElement());
-                }
-                additionalPerms = null;
-            }
-            policy.getPermissions(perms,codesource);
-            notInit=false;
-        }
-    }
-
-    public boolean implies(Permission permission) {
-        if (notInit)
-            init();
-        return perms.implies(permission);
-    }
-
-    public Enumeration<Permission> elements() {
-        if (notInit)
-            init();
-        return perms.elements();
-    }
-
-    public String toString() {
-        if (notInit)
-            init();
-        return perms.toString();
-    }
-}
--- a/src/share/classes/com/sun/security/auth/PolicyParser.java	Mon Aug 19 12:38:56 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,964 +0,0 @@
-/*
- * Copyright (c) 1998, 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 com.sun.security.auth;
-
-import java.io.*;
-import java.lang.RuntimePermission;
-import java.net.MalformedURLException;
-import java.net.SocketPermission;
-import java.net.URL;
-import java.security.GeneralSecurityException;
-import java.text.MessageFormat;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.LinkedList;
-import java.util.ListIterator;
-import java.util.Vector;
-import java.util.StringTokenizer;
-import sun.security.util.PropertyExpander;
-
-/**
- * The policy for a Java runtime (specifying
- * which permissions are available for code from various principals)
- * is represented as a separate
- * persistent configuration.  The configuration may be stored as a
- * flat ASCII file, as a serialized binary file of
- * the Policy class, or as a database. <p>
- *
- * <p>The Java runtime creates one global Policy object, which is used to
- * represent the static policy configuration file.  It is consulted by
- * a ProtectionDomain when the protection domain initializes its set of
- * permissions. <p>
- *
- * <p>The Policy <code>init</code> method parses the policy
- * configuration file, and then
- * populates the Policy object.  The Policy object is agnostic in that
- * it is not involved in making policy decisions.  It is merely the
- * Java runtime representation of the persistent policy configuration
- * file. <p>
- *
- * <p>When a protection domain needs to initialize its set of
- * permissions, it executes code such as the following
- * to ask the global Policy object to populate a
- * Permissions object with the appropriate permissions:
- * <pre>
- *  policy = Policy.getPolicy();
- *  Permissions perms = policy.getPermissions(MyCodeSource)
- * </pre>
- *
- * <p>The protection domain passes in a CodeSource
- * object, which encapsulates its codebase (URL) and public key attributes.
- * The Policy object evaluates the global policy in light of who the
- * principal is and returns an appropriate Permissions object.
- *
- * @deprecated As of JDK&nbsp;1.4, replaced by
- *             {@link sun.security.provider.PolicyParser}.
- *             This class is entirely deprecated.
- *
- * @author Roland Schemers
- *
- * @since 1.2
- */
-@Deprecated
-class PolicyParser {
-
-    private static final java.util.ResourceBundle rb =
-        java.security.AccessController.doPrivileged
-        (new java.security.PrivilegedAction<java.util.ResourceBundle>() {
-            public java.util.ResourceBundle run() {
-                    return (java.util.ResourceBundle.getBundle
-                                ("sun.security.util.AuthResources"));
-           }
-        });
-
-    private Vector<GrantEntry> grantEntries;
-
-    // Convenience variables for parsing
-    private static final sun.security.util.Debug debug =
-        sun.security.util.Debug.getInstance("parser", "\t[Auth Policy Parser]");
-    private StreamTokenizer st;
-    private int lookahead;
-    private int linenum;
-    private boolean expandProp = false;
-    private String keyStoreUrlString = null; // unexpanded
-    private String keyStoreType = null;
-
-    private String expand(String value)
-        throws PropertyExpander.ExpandException
-    {
-        if (expandProp)
-            return PropertyExpander.expand(value);
-        else
-            return value;
-    }
-    /**
-     * Creates a PolicyParser object.
-     */
-
-    public PolicyParser() {
-        grantEntries = new Vector<GrantEntry>();
-    }
-
-
-    public PolicyParser(boolean expandProp) {
-        this();
-        this.expandProp = expandProp;
-    }
-
-    /**
-     * Reads a policy configuration into the Policy object using a
-     * Reader object. <p>
-     *
-     * @param policy the policy Reader object.
-     *
-     * @exception ParsingException if the policy configuration contains
-     *          a syntax error.
-     *
-     * @exception IOException if an error occurs while reading the policy
-     *          configuration.
-     */
-
-    public void read(Reader policy)
-        throws ParsingException, IOException
-    {
-        if (!(policy instanceof BufferedReader)) {
-            policy = new BufferedReader(policy);
-        }
-
-        /**
-         * Configure the stream tokenizer:
-         *      Recognize strings between "..."
-         *      Don't convert words to lowercase
-         *      Recognize both C-style and C++-style comments
-         *      Treat end-of-line as white space, not as a token
-         */
-        st   = new StreamTokenizer(policy);
-
-        st.resetSyntax();
-        st.wordChars('a', 'z');
-        st.wordChars('A', 'Z');
-        st.wordChars('.', '.');
-        st.wordChars('0', '9');
-        st.wordChars('_', '_');
-        st.wordChars('$', '$');
-        st.wordChars(128 + 32, 255);
-        st.whitespaceChars(0, ' ');
-        st.commentChar('/');
-        st.quoteChar('\'');
-        st.quoteChar('"');
-        st.lowerCaseMode(false);
-        st.ordinaryChar('/');
-        st.slashSlashComments(true);
-        st.slashStarComments(true);
-
-        /**
-         * The main parsing loop.  The loop is executed once
-         * for each entry in the config file.      The entries
-         * are delimited by semicolons.   Once we've read in
-         * the information for an entry, go ahead and try to
-         * add it to the policy vector.
-         *
-         */
-
-        lookahead = st.nextToken();
-        while (lookahead != StreamTokenizer.TT_EOF) {
-            if (peek("grant")) {
-                GrantEntry ge = parseGrantEntry();
-                // could be null if we couldn't expand a property
-                if (ge != null)
-                    add(ge);
-            } else if (peek("keystore") && keyStoreUrlString==null) {
-                // only one keystore entry per policy file, others will be
-                // ignored
-                parseKeyStoreEntry();
-            } else {
-                // error?
-            }
-            match(";");
-        }
-    }
-
-    public void add(GrantEntry ge)
-    {
-        grantEntries.addElement(ge);
-    }
-
-    public void replace(GrantEntry origGe, GrantEntry newGe)
-    {
-        grantEntries.setElementAt(newGe, grantEntries.indexOf(origGe));
-    }
-
-    public boolean remove(GrantEntry ge)
-    {
-        return grantEntries.removeElement(ge);
-    }
-
-    /**
-     * Returns the (possibly expanded) keystore location, or null if the
-     * expansion fails.
-     */
-    public String getKeyStoreUrl() {
-        try {
-            if (keyStoreUrlString!=null && keyStoreUrlString.length()!=0) {
-                return expand(keyStoreUrlString).replace(File.separatorChar,
-                                                         '/');
-            }
-        } catch (PropertyExpander.ExpandException peee) {
-            return null;
-        }
-        return null;
-    }
-
-    public void setKeyStoreUrl(String url) {
-        keyStoreUrlString = url;
-    }
-
-    public String getKeyStoreType() {
-        return keyStoreType;
-    }
-
-    public void setKeyStoreType(String type) {
-        keyStoreType = type;
-    }
-
-    /**
-     * Enumerate all the entries in the global policy object.
-     * This method is used by policy admin tools.   The tools
-     * should use the Enumeration methods on the returned object
-     * to fetch the elements sequentially.
-     */
-    public Enumeration<GrantEntry> grantElements(){
-        return grantEntries.elements();
-    }
-
-    /**
-     * write out the policy
-     */
-
-    public void write(Writer policy)
-    {
-        PrintWriter out = new PrintWriter(new BufferedWriter(policy));
-
-        Enumeration<GrantEntry> enum_ = grantElements();
-
-        out.println("/* AUTOMATICALLY GENERATED ON "+
-                    (new java.util.Date()) + "*/");
-        out.println("/* DO NOT EDIT */");
-        out.println();
-
-        // write the (unexpanded) keystore entry as the first entry of the
-        // policy file
-        if (keyStoreUrlString != null) {
-            writeKeyStoreEntry(out);
-        }
-
-        // write "grant" entries
-        while (enum_.hasMoreElements()) {
-            GrantEntry ge = enum_.nextElement();
-            ge.write(out);
-            out.println();
-        }
-        out.flush();
-    }
-
-    /**
-     * parses a keystore entry
-     */
-    private void parseKeyStoreEntry() throws ParsingException, IOException {
-        match("keystore");
-        keyStoreUrlString = match("quoted string");
-
-        // parse keystore type
-        if (!peek(",")) {
-            return; // default type
-        }
-        match(",");
-
-        if (peek("\"")) {
-            keyStoreType = match("quoted string");
-        } else {
-            throw new ParsingException(st.lineno(),
-                        rb.getString("expected.keystore.type"));
-        }
-    }
-
-    /**
-     * writes the (unexpanded) keystore entry
-     */
-    private void writeKeyStoreEntry(PrintWriter out) {
-        out.print("keystore \"");
-        out.print(keyStoreUrlString);
-        out.print('"');
-        if (keyStoreType != null && keyStoreType.length() > 0)
-            out.print(", \"" + keyStoreType + "\"");
-        out.println(";");
-        out.println();
-    }
-
-    /**
-     * parse a Grant entry
-     */
-    private GrantEntry parseGrantEntry()
-        throws ParsingException, IOException
-    {
-        GrantEntry e = new GrantEntry();
-        LinkedList<PrincipalEntry> principals = null;
-        boolean ignoreEntry = false;
-
-        match("grant");
-
-        while(!peek("{")) {
-
-            if (peekAndMatch("Codebase")) {
-                e.codeBase = match("quoted string");
-                peekAndMatch(",");
-            } else if (peekAndMatch("SignedBy")) {
-                e.signedBy = match("quoted string");
-                peekAndMatch(",");
-            } else if (peekAndMatch("Principal")) {
-                if (principals == null) {
-                    principals = new LinkedList<PrincipalEntry>();
-                }
-
-                // check for principalClass wildcard
-                String principalClass;
-                if (peek("*")) {
-                    match("*");
-                    principalClass = PrincipalEntry.WILDCARD_CLASS;
-                } else {
-                    principalClass = match("principal type");
-                }
-
-                // check for principalName wildcard
-                String principalName;
-                if (peek("*")) {
-                    match("*");
-                    principalName = PrincipalEntry.WILDCARD_NAME;
-                } else {
-                    principalName = match("quoted string");
-                }
-
-                // disallow WILDCARD_CLASS && actual name
-                if (principalClass.equals(PrincipalEntry.WILDCARD_CLASS) &&
-                    !principalName.equals(PrincipalEntry.WILDCARD_NAME)) {
-                    if (debug != null)
-                        debug.println("disallowing principal that has " +
-                                "WILDCARD class but no WILDCARD name");
-                    throw new ParsingException
-                        (st.lineno(),
-                        rb.getString("can.not.specify.Principal.with.a." +
-                                     "wildcard.class.without.a.wildcard.name"));
-                }
-
-                try {
-                    principalName = expand(principalName);
-                    principals.add
-                        (new PrincipalEntry(principalClass, principalName));
-                } catch (PropertyExpander.ExpandException peee) {
-                    // ignore the entire policy entry
-                    // but continue parsing all the info
-                    // so we can get to the next entry
-                    if (debug != null)
-                        debug.println("principal name expansion failed: " +
-                                        principalName);
-                    ignoreEntry = true;
-                }
-                peekAndMatch(",");
-            } else {
-                throw new
-                 ParsingException(st.lineno(),
-                        rb.getString("expected.codeBase.or.SignedBy"));
-            }
-        }
-
-        // disallow non principal-based grant entries
-        if (principals == null) {
-            throw new ParsingException
-                (st.lineno(),
-                rb.getString("only.Principal.based.grant.entries.permitted"));
-        }
-
-        e.principals = principals;
-        match("{");
-
-        while(!peek("}")) {
-            if (peek("Permission")) {
-                try {
-                    PermissionEntry pe = parsePermissionEntry();
-                    e.add(pe);
-                } catch (PropertyExpander.ExpandException peee) {
-                    // ignore. The add never happened
-                    skipEntry();  // BugId 4219343
-                }
-                match(";");
-            } else {
-                throw new
-                    ParsingException(st.lineno(),
-                    rb.getString("expected.permission.entry"));
-            }
-        }
-        match("}");
-
-        try {
-            if (e.codeBase != null)
-              e.codeBase = expand(e.codeBase).replace(File.separatorChar, '/');
-            e.signedBy = expand(e.signedBy);
-        } catch (PropertyExpander.ExpandException peee) {
-            return null;
-        }
-
-        return (ignoreEntry == true) ? null : e;
-    }
-
-    /**
-     * parse a Permission entry
-     */
-    private PermissionEntry parsePermissionEntry()
-        throws ParsingException, IOException, PropertyExpander.ExpandException
-    {
-        PermissionEntry e = new PermissionEntry();
-
-        // Permission
-        match("Permission");
-        e.permission = match("permission type");
-
-        if (peek("\"")) {
-            // Permission name
-            e.name = expand(match("quoted string"));
-        }
-
-        if (!peek(",")) {
-            return e;
-        }
-        match(",");
-
-        if (peek("\"")) {
-                e.action = expand(match("quoted string"));
-                if (!peek(",")) {
-                    return e;
-                }
-                match(",");
-        }
-
-        if (peekAndMatch("SignedBy")) {
-            e.signedBy = expand(match("quoted string"));
-        }
-        return e;
-    }
-
-    private boolean peekAndMatch(String expect)
-        throws ParsingException, IOException
-    {
-        if (peek(expect)) {
-            match(expect);
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    private boolean peek(String expect) {
-        boolean found = false;
-
-        switch (lookahead) {
-
-        case StreamTokenizer.TT_WORD:
-            if (expect.equalsIgnoreCase(st.sval))
-                found = true;
-            break;
-        case ',':
-            if (expect.equalsIgnoreCase(","))
-                found = true;
-            break;
-        case '{':
-            if (expect.equalsIgnoreCase("{"))
-                found = true;
-            break;
-        case '}':
-            if (expect.equalsIgnoreCase("}"))
-                found = true;
-            break;
-        case '"':
-            if (expect.equalsIgnoreCase("\""))
-                found = true;
-            break;
-        case '*':
-            if (expect.equalsIgnoreCase("*"))
-                found = true;
-            break;
-        default:
-
-        }
-        return found;
-    }
-
-    private String match(String expect)
-        throws ParsingException, IOException
-    {
-        String value = null;
-
-        switch (lookahead) {
-        case StreamTokenizer.TT_NUMBER:
-            throw new ParsingException(st.lineno(), expect,
-                                        rb.getString("number.") +
-                                        String.valueOf(st.nval));
-        case StreamTokenizer.TT_EOF:
-            MessageFormat form = new MessageFormat(
-                    rb.getString("expected.expect.read.end.of.file."));
-            Object[] source = {expect};
-            throw new ParsingException(form.format(source));
-        case StreamTokenizer.TT_WORD:
-            if (expect.equalsIgnoreCase(st.sval)) {
-                lookahead = st.nextToken();
-            } else if (expect.equalsIgnoreCase("permission type")) {
-                value = st.sval;
-                lookahead = st.nextToken();
-            } else if (expect.equalsIgnoreCase("principal type")) {
-                value = st.sval;
-                lookahead = st.nextToken();
-            } else {
-                throw new ParsingException(st.lineno(), expect, st.sval);
-            }
-            break;
-        case '"':
-            if (expect.equalsIgnoreCase("quoted string")) {
-                value = st.sval;
-                lookahead = st.nextToken();
-            } else if (expect.equalsIgnoreCase("permission type")) {
-                value = st.sval;
-                lookahead = st.nextToken();
-            } else if (expect.equalsIgnoreCase("principal type")) {
-                value = st.sval;
-                lookahead = st.nextToken();
-            } else {
-                throw new ParsingException(st.lineno(), expect, st.sval);
-            }
-            break;
-        case ',':
-            if (expect.equalsIgnoreCase(","))
-                lookahead = st.nextToken();
-            else
-                throw new ParsingException(st.lineno(), expect, ",");
-            break;
-        case '{':
-            if (expect.equalsIgnoreCase("{"))
-                lookahead = st.nextToken();
-            else
-                throw new ParsingException(st.lineno(), expect, "{");
-            break;
-        case '}':
-            if (expect.equalsIgnoreCase("}"))
-                lookahead = st.nextToken();
-            else
-                throw new ParsingException(st.lineno(), expect, "}");
-            break;
-        case ';':
-            if (expect.equalsIgnoreCase(";"))
-                lookahead = st.nextToken();
-            else
-                throw new ParsingException(st.lineno(), expect, ";");
-            break;
-        case '*':
-            if (expect.equalsIgnoreCase("*"))
-                lookahead = st.nextToken();
-            else
-                throw new ParsingException(st.lineno(), expect, "*");
-            break;
-        default:
-            throw new ParsingException(st.lineno(), expect,
-                               new String(new char[] {(char)lookahead}));
-        }
-        return value;
-    }
-
-    /**
-     * skip all tokens for this entry leaving the delimiter ";"
-     * in the stream.
-     */
-    private void skipEntry()
-        throws ParsingException, IOException
-    {
-      while(lookahead != ';') {
-        switch (lookahead) {
-        case StreamTokenizer.TT_NUMBER:
-            throw new ParsingException(st.lineno(), ";",
-                                       rb.getString("number.") +
-                                        String.valueOf(st.nval));
-        case StreamTokenizer.TT_EOF:
-          throw new ParsingException
-                (rb.getString("expected.read.end.of.file"));
-        default:
-          lookahead = st.nextToken();
-        }
-      }
-    }
-
-    /**
-     * Each grant entry in the policy configuration file is
-     * represented by a
-     * GrantEntry object.  <p>
-     *
-     * <p>
-     * For example, the entry
-     * <pre>
-     *      grant signedBy "Duke" {
-     *          permission java.io.FilePermission "/tmp", "read,write";
-     *      };
-     *
-     * </pre>
-     * is represented internally
-     * <pre>
-     *
-     * pe = new PermissionEntry("java.io.FilePermission",
-     *                           "/tmp", "read,write");
-     *
-     * ge = new GrantEntry("Duke", null);
-     *
-     * ge.add(pe);
-     *
-     * </pre>
-     *
-     * @author Roland Schemers
-     *
-     * version 1.19, 05/21/98
-     */
-
-    static class GrantEntry {
-
-        public String signedBy;
-        public String codeBase;
-        public LinkedList<PrincipalEntry> principals;
-        public Vector<PermissionEntry> permissionEntries;
-
-        public GrantEntry() {
-            permissionEntries = new Vector<PermissionEntry>();
-        }
-
-        public GrantEntry(String signedBy, String codeBase) {
-            this.codeBase = codeBase;
-            this.signedBy = signedBy;
-            permissionEntries = new Vector<PermissionEntry>();
-        }
-
-        public void add(PermissionEntry pe)
-        {
-            permissionEntries.addElement(pe);
-        }
-
-        public boolean remove(PermissionEntry pe)
-        {
-            return permissionEntries.removeElement(pe);
-        }
-
-        public boolean contains(PermissionEntry pe)
-        {
-            return permissionEntries.contains(pe);
-        }
-
-        /**
-         * Enumerate all the permission entries in this GrantEntry.
-         */
-        public Enumeration<PermissionEntry> permissionElements(){
-            return permissionEntries.elements();
-        }
-
-
-        public void write(PrintWriter out) {
-            out.print("grant");
-            if (signedBy != null) {
-                out.print(" signedBy \"");
-                out.print(signedBy);
-                out.print('"');
-                if (codeBase != null)
-                    out.print(", ");
-            }
-            if (codeBase != null) {
-                out.print(" codeBase \"");
-                out.print(codeBase);
-                out.print('"');
-                if (principals != null && principals.size() > 0)
-                    out.print(",\n");
-            }
-            if (principals != null && principals.size() > 0) {
-                ListIterator<PrincipalEntry> pli = principals.listIterator();
-                while (pli.hasNext()) {
-                    out.print("\tPrincipal ");
-                    PrincipalEntry pe = pli.next();
-                    out.print(pe.principalClass +
-                                " \"" + pe.principalName + "\"");
-                    if (pli.hasNext())
-                        out.print(",\n");
-                }
-            }
-            out.println(" {");
-            Enumeration<PermissionEntry> enum_ = permissionEntries.elements();
-            while (enum_.hasMoreElements()) {
-                PermissionEntry pe = enum_.nextElement();
-                out.write("  ");
-                pe.write(out);
-            }
-            out.println("};");
-        }
-
-    }
-
-    /**
-     * Principal info (class and name) in a grant entry
-     */
-    static class PrincipalEntry {
-
-        static final String WILDCARD_CLASS = "WILDCARD_PRINCIPAL_CLASS";
-        static final String WILDCARD_NAME = "WILDCARD_PRINCIPAL_NAME";
-
-        String principalClass;
-        String principalName;
-
-        /**
-         * A PrincipalEntry consists of the <code>Principal</code>
-         * class and <code>Principal</code> name.
-         *
-         * <p>
-         *
-         * @param principalClass the <code>Principal</code> class. <p>
-         *
-         * @param principalName the <code>Principal</code> name. <p>
-         */
-        public PrincipalEntry(String principalClass, String principalName) {
-            if (principalClass == null || principalName == null)
-                throw new NullPointerException
-                        ("null principalClass or principalName");
-            this.principalClass = principalClass;
-            this.principalName = principalName;
-        }
-
-        /**
-         * Test for equality between the specified object and this object.
-         * Two PrincipalEntries are equal if their PrincipalClass and
-         * PrincipalName values are equal.
-         *
-         * <p>
-         *
-         * @param obj the object to test for equality with this object.
-         *
-         * @return true if the objects are equal, false otherwise.
-         */
-        public boolean equals(Object obj) {
-            if (this == obj)
-                return true;
-
-            if (!(obj instanceof PrincipalEntry))
-                return false;
-
-            PrincipalEntry that = (PrincipalEntry)obj;
-            if (this.principalClass.equals(that.principalClass) &&
-                this.principalName.equals(that.principalName)) {
-                return true;
-            }
-
-            return false;
-        }
-
-        /**
-         * Return a hashcode for this <code>PrincipalEntry</code>.
-         *
-         * <p>
-         *
-         * @return a hashcode for this <code>PrincipalEntry</code>.
-         */
-        public int hashCode() {
-            return principalClass.hashCode();
-        }
-    }
-
-    /**
-     * Each permission entry in the policy configuration file is
-     * represented by a
-     * PermissionEntry object.  <p>
-     *
-     * <p>
-     * For example, the entry
-     * <pre>
-     *          permission java.io.FilePermission "/tmp", "read,write";
-     * </pre>
-     * is represented internally
-     * <pre>
-     *
-     * pe = new PermissionEntry("java.io.FilePermission",
-     *                           "/tmp", "read,write");
-     * </pre>
-     *
-     * @author Roland Schemers
-     *
-     * version 1.19, 05/21/98
-     */
-
-    static class PermissionEntry {
-
-        public String permission;
-        public String name;
-        public String action;
-        public String signedBy;
-
-        public PermissionEntry() {
-        }
-
-        public PermissionEntry(String permission,
-                        String name,
-                        String action) {
-            this.permission = permission;
-            this.name = name;
-            this.action = action;
-        }
-
-        /**
-         * Calculates a hash code value for the object.  Objects
-         * which are equal will also have the same hashcode.
-         */
-        public int hashCode() {
-            int retval = permission.hashCode();
-            if (name != null) retval ^= name.hashCode();
-            if (action != null) retval ^= action.hashCode();
-            return retval;
-        }
-
-        public boolean equals(Object obj) {
-            if (obj == this)
-                return true;
-
-            if (! (obj instanceof PermissionEntry))
-                return false;
-
-            PermissionEntry that = (PermissionEntry) obj;
-
-            if (this.permission == null) {
-                if (that.permission != null) return false;
-            } else {
-                if (!this.permission.equals(that.permission)) return false;
-            }
-
-            if (this.name == null) {
-                if (that.name != null) return false;
-            } else {
-                if (!this.name.equals(that.name)) return false;
-            }
-
-            if (this.action == null) {
-                if (that.action != null) return false;
-            } else {
-                if (!this.action.equals(that.action)) return false;
-            }
-
-            if (this.signedBy == null) {
-                if (that.signedBy != null) return false;
-            } else {
-                if (!this.signedBy.equals(that.signedBy)) return false;
-            }
-
-            // everything matched -- the 2 objects are equal
-            return true;
-        }
-
-        public void write(PrintWriter out) {
-            out.print("permission ");
-            out.print(permission);
-            if (name != null) {
-                out.print(" \"");
-
-                // have to add escape chars for quotes
-                if (name.indexOf("\"") != -1) {
-                    int numQuotes = 0;
-                    char[] chars = name.toCharArray();
-
-                    // count the number of quote chars
-                    for (int i = 0; i < chars.length; i++) {
-                        if (chars[i] == '"')
-                            numQuotes++;
-                    }
-
-                    // now, add an escape char before each quote
-                    char[] newChars = new char[chars.length + numQuotes];
-                    for (int i = 0, j = 0; i < chars.length; i++) {
-                        if (chars[i] != '"') {
-                            newChars[j++] = chars[i];
-                        } else {
-                            newChars[j++] = '\\';
-                            newChars[j++] = chars[i];
-                        }
-                    }
-                    name = new String(newChars);
-                }
-                out.print(name);
-                out.print('"');
-            }
-            if (action != null) {
-                out.print(", \"");
-                out.print(action);
-                out.print('"');
-            }
-            if (signedBy != null) {
-                out.print(", signedBy \"");
-                out.print(signedBy);
-                out.print('"');
-            }
-            out.println(";");
-        }
-    }
-
-    static class ParsingException extends GeneralSecurityException {
-
-        private static final long serialVersionUID = 8240970523155877400L;
-
-        /**
-         * Constructs a ParsingException 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 ParsingException(String msg) {
-            super(msg);
-        }
-
-        public ParsingException(int line, String msg) {
-            super(rb.getString("line.") + line + rb.getString("COLON") + msg);
-        }
-
-        public ParsingException(int line, String expect, String actual) {
-            super(rb.getString("line.") + line + rb.getString(".expected.") +
-                expect + rb.getString(".found.") + actual +
-                rb.getString("QUOTE"));
-        }
-    }
-
-    public static void main(String arg[]) throws Exception {
-        PolicyParser pp = new PolicyParser(true);
-        pp.read(new FileReader(arg[0]));
-        FileWriter fr = new FileWriter(arg[1]);
-        pp.write(fr);
-        fr.close();
-    }
-}
--- a/src/share/classes/com/sun/security/auth/SubjectCodeSource.java	Mon Aug 19 12:38:56 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,398 +0,0 @@
-/*
- * 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 com.sun.security.auth;
-
-import java.net.URL;
-import java.util.*;
-import java.security.CodeSource;
-import java.security.Principal;
-import java.security.cert.Certificate;
-import java.lang.reflect.Constructor;
-
-import javax.security.auth.Subject;
-import sun.security.provider.PolicyParser.PrincipalEntry;
-
-/**
- * <p> This <code>SubjectCodeSource</code> class contains
- * a <code>URL</code>, signer certificates, and either a <code>Subject</code>
- * (that represents the <code>Subject</code> in the current
- * <code>AccessControlContext</code>),
- * or a linked list of Principals/PrincipalComparators
- * (that represent a "subject" in a <code>Policy</code>).
- *
- */
-class SubjectCodeSource extends CodeSource implements java.io.Serializable {
-
-    private static final long serialVersionUID = 6039418085604715275L;
-
-    private static final java.util.ResourceBundle rb =
-        java.security.AccessController.doPrivileged
-        (new java.security.PrivilegedAction<java.util.ResourceBundle>() {
-            public java.util.ResourceBundle run() {
-                return (java.util.ResourceBundle.getBundle
-                        ("sun.security.util.AuthResources"));
-            }
-        });
-
-    private Subject subject;
-    private LinkedList<PrincipalEntry> principals;
-    private static final Class[] PARAMS = { String.class };
-    private static final sun.security.util.Debug debug =
-        sun.security.util.Debug.getInstance("auth", "\t[Auth Access]");
-    private ClassLoader sysClassLoader;
-
-    /**
-     * Creates a new <code>SubjectCodeSource</code>
-     * with the given <code>Subject</code>, principals, <code>URL</code>,
-     * and signers (Certificates).  The <code>Subject</code>
-     * represents the <code>Subject</code> associated with the current
-     * <code>AccessControlContext</code>.
-     * The Principals are given as a <code>LinkedList</code>
-     * of <code>PolicyParser.PrincipalEntry</code> objects.
-     * Typically either a <code>Subject</code> will be provided,
-     * or a list of <code>principals</code> will be provided
-     * (not both).
-     *
-     * <p>
-     *
-     * @param subject the <code>Subject</code> associated with this
-     *                  <code>SubjectCodeSource</code> <p>
-     *
-     * @param url the <code>URL</code> associated with this
-     *                  <code>SubjectCodeSource</code> <p>
-     *
-     * @param certs the signers associated with this
-     *                  <code>SubjectCodeSource</code> <p>
-     */
-    SubjectCodeSource(Subject subject,
-        LinkedList<PrincipalEntry> principals,
-        URL url, Certificate[] certs) {
-
-        super(url, certs);
-        this.subject = subject;
-        this.principals = (principals == null ?
-                new LinkedList<PrincipalEntry>() :
-                new LinkedList<PrincipalEntry>(principals));
-        sysClassLoader = java.security.AccessController.doPrivileged
-        (new java.security.PrivilegedAction<ClassLoader>() {
-            public ClassLoader run() {
-                    return ClassLoader.getSystemClassLoader();
-            }
-        });
-    }
-
-    /**
-     * Get the Principals associated with this <code>SubjectCodeSource</code>.
-     * The Principals are retrieved as a <code>LinkedList</code>
-     * of <code>PolicyParser.PrincipalEntry</code> objects.
-     *
-     * <p>
-     *
-     * @return the Principals associated with this
-     *          <code>SubjectCodeSource</code> as a <code>LinkedList</code>
-     *          of <code>PolicyParser.PrincipalEntry</code> objects.
-     */
-    LinkedList<PrincipalEntry> getPrincipals() {
-        return principals;
-    }
-
-    /**
-     * Get the <code>Subject</code> associated with this
-     * <code>SubjectCodeSource</code>.  The <code>Subject</code>
-     * represents the <code>Subject</code> associated with the
-     * current <code>AccessControlContext</code>.
-     *
-     * <p>
-     *
-     * @return the <code>Subject</code> associated with this
-     *          <code>SubjectCodeSource</code>.
-     */
-    Subject getSubject() {
-        return subject;
-    }
-
-    /**
-     * Returns true if this <code>SubjectCodeSource</code> object "implies"
-     * the specified <code>CodeSource</code>.
-     * More specifically, this method makes the following checks.
-     * If any fail, it returns false.  If they all succeed, it returns true.
-     *
-     * <p>
-     * <ol>
-     * <li> The provided codesource must not be <code>null</code>.
-     * <li> codesource must be an instance of <code>SubjectCodeSource</code>.
-     * <li> super.implies(codesource) must return true.
-     * <li> for each principal in this codesource's principal list:
-     * <ol>
-     * <li>     if the principal is an instanceof
-     *          <code>PrincipalComparator</code>, then the principal must
-     *          imply the provided codesource's <code>Subject</code>.
-     * <li>     if the principal is not an instanceof
-     *          <code>PrincipalComparator</code>, then the provided
-     *          codesource's <code>Subject</code> must have an
-     *          associated <code>Principal</code>, <i>P</i>, where
-     *          P.getClass().getName equals principal.principalClass,
-     *          and P.getName() equals principal.principalName.
-     * </ol>
-     * </ol>
-     *
-     * <p>
-     *
-     * @param codesource the <code>CodeSource</code> to compare against.
-     *
-     * @return true if this <code>SubjectCodeSource</code> implies the
-     *          the specified <code>CodeSource</code>.
-     */
-    public boolean implies(CodeSource codesource) {
-
-        LinkedList<PrincipalEntry> subjectList = null;
-
-        if (codesource == null ||
-            !(codesource instanceof SubjectCodeSource) ||
-            !(super.implies(codesource))) {
-
-            if (debug != null)
-                debug.println("\tSubjectCodeSource.implies: FAILURE 1");
-            return false;
-        }
-
-        SubjectCodeSource that = (SubjectCodeSource)codesource;
-
-        // if the principal list in the policy "implies"
-        // the Subject associated with the current AccessControlContext,
-        // then return true
-
-        if (this.principals == null) {
-            if (debug != null)
-                debug.println("\tSubjectCodeSource.implies: PASS 1");
-            return true;
-        }
-
-        if (that.getSubject() == null ||
-            that.getSubject().getPrincipals().size() == 0) {
-            if (debug != null)
-                debug.println("\tSubjectCodeSource.implies: FAILURE 2");
-            return false;
-        }
-
-        ListIterator<PrincipalEntry> li = this.principals.listIterator(0);
-        while (li.hasNext()) {
-            PrincipalEntry pppe = li.next();
-            try {
-
-                // handle PrincipalComparators
-
-                Class<?> principalComparator = Class.forName(
-                        pppe.getPrincipalClass(), true, sysClassLoader);
-                Constructor<?> c = principalComparator.getConstructor(PARAMS);
-                PrincipalComparator pc =
-                        (PrincipalComparator)c.newInstance
-                        (new Object[] { pppe.getPrincipalName() });
-
-                if (!pc.implies(that.getSubject())) {
-                    if (debug != null)
-                        debug.println("\tSubjectCodeSource.implies: FAILURE 3");
-                    return false;
-                } else {
-                    if (debug != null)
-                        debug.println("\tSubjectCodeSource.implies: PASS 2");
-                    return true;
-                }
-            } catch (Exception e) {
-
-                // no PrincipalComparator, simply compare Principals
-
-                if (subjectList == null) {
-
-                    if (that.getSubject() == null) {
-                        if (debug != null)
-                            debug.println("\tSubjectCodeSource.implies: " +
-                                        "FAILURE 4");
-                        return false;
-                    }
-                    Iterator<Principal> i =
-                                that.getSubject().getPrincipals().iterator();
-
-                    subjectList = new LinkedList<PrincipalEntry>();
-                    while (i.hasNext()) {
-                        Principal p = i.next();
-                        PrincipalEntry spppe = new PrincipalEntry
-                                (p.getClass().getName(), p.getName());
-                        subjectList.add(spppe);
-                    }
-                }
-
-                if (!subjectListImpliesPrincipalEntry(subjectList, pppe)) {
-                    if (debug != null)
-                        debug.println("\tSubjectCodeSource.implies: FAILURE 5");
-                    return false;
-                }
-            }
-        }
-
-        if (debug != null)
-            debug.println("\tSubjectCodeSource.implies: PASS 3");
-        return true;
-    }
-
-    /**
-     * This method returns, true, if the provided <i>subjectList</i>
-     * "contains" the <code>Principal</code> specified
-     * in the provided <i>pppe</i> argument.
-     *
-     * Note that the provided <i>pppe</i> argument may have
-     * wildcards (*) for the <code>Principal</code> class and name,
-     * which need to be considered.
-     *
-     * <p>
-     *
-     * @param subjectList a list of PolicyParser.PrincipalEntry objects
-     *          that correspond to all the Principals in the Subject currently
-     *          on this thread's AccessControlContext. <p>
-     *
-     * @param pppe the Principals specified in a grant entry.
-     *
-     * @return true if the provided <i>subjectList</i> "contains"
-     *          the <code>Principal</code> specified in the provided
-     *          <i>pppe</i> argument.
-     */
-    private boolean subjectListImpliesPrincipalEntry(
-                LinkedList<PrincipalEntry> subjectList, PrincipalEntry pppe) {
-
-        ListIterator<PrincipalEntry> li = subjectList.listIterator(0);
-        while (li.hasNext()) {
-            PrincipalEntry listPppe = li.next();
-
-            if (pppe.getPrincipalClass().equals
-                        (PrincipalEntry.WILDCARD_CLASS) ||
-                pppe.getPrincipalClass().equals(listPppe.getPrincipalClass()))
-            {
-                if (pppe.getPrincipalName().equals
-                        (PrincipalEntry.WILDCARD_NAME) ||
-                    pppe.getPrincipalName().equals(listPppe.getPrincipalName()))
-                    return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Tests for equality between the specified object and this
-     * object. Two <code>SubjectCodeSource</code> objects are considered equal
-     * if their locations are of identical value, if the two sets of
-     * Certificates are of identical values, and if the
-     * Subjects are equal, and if the PolicyParser.PrincipalEntry values
-     * are of identical values.  It is not required that
-     * the Certificates or PolicyParser.PrincipalEntry values
-     * be in the same order.
-     *
-     * <p>
-     *
-     * @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 == this)
-            return true;
-
-        if (super.equals(obj) == false)
-            return false;
-
-        if (!(obj instanceof SubjectCodeSource))
-            return false;
-
-        SubjectCodeSource that = (SubjectCodeSource)obj;
-
-        // the principal lists must match
-        try {
-            if (this.getSubject() != that.getSubject())
-                return false;
-        } catch (SecurityException se) {
-            return false;
-        }
-
-        if ((this.principals == null && that.principals != null) ||
-            (this.principals != null && that.principals == null))
-            return false;
-
-        if (this.principals != null && that.principals != null) {
-            if (!this.principals.containsAll(that.principals) ||
-                !that.principals.containsAll(this.principals))
-
-                return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Return a hashcode for this <code>SubjectCodeSource</code>.
-     *
-     * <p>
-     *
-     * @return a hashcode for this <code>SubjectCodeSource</code>.
-     */
-    public int hashCode() {
-        return super.hashCode();
-    }
-
-    /**
-     * Return a String representation of this <code>SubjectCodeSource</code>.
-     *
-     * <p>
-     *
-     * @return a String representation of this <code>SubjectCodeSource</code>.
-     */
-    public String toString() {
-        String returnMe = super.toString();
-        if (getSubject() != null) {
-            if (debug != null) {
-                final Subject finalSubject = getSubject();
-                returnMe = returnMe + "\n" +
-                        java.security.AccessController.doPrivileged
-                                (new java.security.PrivilegedAction<String>() {
-                                public String run() {
-                                    return finalSubject.toString();
-                                }
-                        });
-            } else {
-                returnMe = returnMe + "\n" + getSubject().toString();
-            }
-        }
-        if (principals != null) {
-            ListIterator<PrincipalEntry> li = principals.listIterator();
-            while (li.hasNext()) {
-                PrincipalEntry pppe = li.next();
-                returnMe = returnMe + rb.getString("NEWLINE") +
-                        pppe.getPrincipalClass() + " " +
-                        pppe.getPrincipalName();
-            }
-        }
-        return returnMe;
-    }
-}
--- a/src/share/classes/javax/security/auth/Policy.java	Mon Aug 19 12:38:56 2013 -0700
+++ b/src/share/classes/javax/security/auth/Policy.java	Mon Aug 19 17:17:17 2013 -0400
@@ -156,9 +156,10 @@
 
     private static Policy policy;
     private static ClassLoader contextClassLoader;
+    private final static String AUTH_POLICY =
+        "sun.security.provider.AuthPolicyFile";
 
-    // true if a custom (not com.sun.security.auth.PolicyFile) system-wide
-    // policy object is set
+    // true if a custom (not AUTH_POLICY) system-wide policy object is set
     private static boolean isCustomPolicy;
 
     static {
@@ -220,7 +221,7 @@
                         }
                     });
                     if (policy_class == null) {
-                        policy_class = "com.sun.security.auth.PolicyFile";
+                        policy_class = AUTH_POLICY;
                     }
 
                     try {
@@ -236,8 +237,7 @@
                                         contextClassLoader).newInstance();
                             }
                         });
-                        isCustomPolicy =
-                            !finalClass.equals("com.sun.security.auth.PolicyFile");
+                        isCustomPolicy = !finalClass.equals(AUTH_POLICY);
                     } catch (Exception e) {
                         throw new SecurityException
                                 (sun.security.util.ResourcesMgr.getString
@@ -274,14 +274,14 @@
     }
 
     /**
-     * Returns true if a custom (not com.sun.security.auth.PolicyFile)
-     * system-wide policy object has been set or installed. This method is
-     * called by SubjectDomainCombiner to provide backwards compatibility for
+     * Returns true if a custom (not AUTH_POLICY) system-wide policy object
+     * has been set or installed. This method is called by
+     * SubjectDomainCombiner to provide backwards compatibility for
      * developers that provide their own javax.security.auth.Policy
      * implementations.
      *
-     * @return true if a custom (not com.sun.security.auth.PolicyFile)
-     * system-wide policy object has been set; false otherwise
+     * @return true if a custom (not AUTH_POLICY) system-wide policy object
+     * has been set; false otherwise
      */
     static boolean isCustomPolicySet(Debug debug) {
         if (policy != null) {
@@ -299,8 +299,7 @@
                     return Security.getProperty("auth.policy.provider");
                 }
         });
-        if (policyClass != null
-            && !policyClass.equals("com.sun.security.auth.PolicyFile")) {
+        if (policyClass != null && !policyClass.equals(AUTH_POLICY)) {
             if (debug != null) {
                 debug.println("Providing backwards compatibility for " +
                               "javax.security.auth.policy implementation: " +
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/security/provider/AuthPolicyFile.java	Mon Aug 19 17:17:17 2013 -0400
@@ -0,0 +1,1195 @@
+/*
+ * 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 sun.security.provider;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.net.URL;
+import java.util.*;
+
+import java.security.AccessController;
+import java.security.CodeSource;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.Permission;
+import java.security.Permissions;
+import java.security.PermissionCollection;
+import java.security.Principal;
+import java.security.PrivilegedAction;
+import java.security.UnresolvedPermission;
+import java.security.Security;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+
+import javax.security.auth.Subject;
+import javax.security.auth.PrivateCredentialPermission;
+
+import sun.security.provider.PolicyParser.GrantEntry;
+import sun.security.provider.PolicyParser.PermissionEntry;
+import sun.security.provider.PolicyParser.PrincipalEntry;
+import sun.security.util.Debug;
+import sun.security.util.PolicyUtil;
+import sun.security.util.PropertyExpander;
+
+/**
+ * See {@code com.sun.security.auth.PolicyFile} for the class description.
+ * This class is necessary in order to support a default
+ * {@code javax.security.auth.Policy} implementation on the compact1 and
+ * compact2 profiles.
+ *
+ * @deprecated As of JDK&nbsp;1.4, replaced by
+ *             {@code sun.security.provider.PolicyFile}.
+ *             This class is entirely deprecated.
+ */
+@Deprecated
+public class AuthPolicyFile extends javax.security.auth.Policy {
+
+    static final ResourceBundle rb =
+        AccessController.doPrivileged(new PrivilegedAction<ResourceBundle>() {
+            @Override public ResourceBundle run() {
+                return (ResourceBundle.getBundle
+                        ("sun.security.util.AuthResources"));
+            }
+        });
+
+    private static final Debug debug = Debug.getInstance("policy",
+                                                         "\t[Auth Policy]");
+
+    private static final String AUTH_POLICY = "java.security.auth.policy";
+    private static final String SECURITY_MANAGER = "java.security.manager";
+    private static final String AUTH_POLICY_URL = "auth.policy.url.";
+
+    private Vector<PolicyEntry> policyEntries;
+    private Hashtable<Object, Object> aliasMapping;
+
+    private boolean initialized = false;
+
+    private boolean expandProperties = true;
+    private boolean ignoreIdentityScope = true;
+
+    // for use with the reflection API
+    private static final Class[] PARAMS = { String.class, String.class};
+
+    /**
+     * Initializes the Policy object and reads the default policy
+     * configuration file(s) into the Policy object.
+     */
+    public AuthPolicyFile() {
+        // initialize Policy if either the AUTH_POLICY or
+        // SECURITY_MANAGER properties are set
+        String prop = System.getProperty(AUTH_POLICY);
+
+        if (prop == null) {
+            prop = System.getProperty(SECURITY_MANAGER);
+        }
+        if (prop != null) {
+            init();
+        }
+    }
+
+    private synchronized void init() {
+        if (initialized) {
+            return;
+        }
+
+        policyEntries = new Vector<PolicyEntry>();
+        aliasMapping = new Hashtable<Object, Object>(11);
+
+        initPolicyFile();
+        initialized = true;
+    }
+
+    @Override
+    public synchronized void refresh() {
+
+        java.lang.SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new javax.security.auth.AuthPermission
+                                ("refreshPolicy"));
+        }
+
+        // XXX
+        //
+        // 1)   if code instantiates PolicyFile directly, then it will need
+        //      all the permissions required for the PolicyFile initialization
+        // 2)   if code calls Policy.getPolicy, then it simply needs
+        //      AuthPermission(getPolicy), and the javax.security.auth.Policy
+        //      implementation instantiates PolicyFile in a doPrivileged block
+        // 3)   if after instantiating a Policy (either via #1 or #2),
+        //      code calls refresh, it simply needs
+        //      AuthPermission(refreshPolicy).  then PolicyFile wraps
+        //      the refresh in a doPrivileged block.
+        initialized = false;
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            @Override public Void run() {
+                init();
+                return null;
+            }
+        });
+    }
+
+    private KeyStore initKeyStore(URL policyUrl, String keyStoreName,
+                                  String keyStoreType) {
+        if (keyStoreName != null) {
+            try {
+                /*
+                 * location of keystore is specified as absolute URL in policy
+                 * file, or is relative to URL of policy file
+                 */
+                URL keyStoreUrl = null;
+                try {
+                    keyStoreUrl = new URL(keyStoreName);
+                    // absolute URL
+                } catch (java.net.MalformedURLException e) {
+                    // relative URL
+                    keyStoreUrl = new URL(policyUrl, keyStoreName);
+                }
+
+                if (debug != null) {
+                    debug.println("reading keystore"+keyStoreUrl);
+                }
+
+                InputStream inStream = new BufferedInputStream(
+                    PolicyUtil.getInputStream(keyStoreUrl));
+
+                KeyStore ks;
+                if (keyStoreType != null)
+                    ks = KeyStore.getInstance(keyStoreType);
+                else
+                    ks = KeyStore.getInstance(KeyStore.getDefaultType());
+                ks.load(inStream, null);
+                inStream.close();
+                return ks;
+            } catch (Exception e) {
+                // ignore, treat it like we have no keystore
+                if (debug != null) {
+                    e.printStackTrace();
+                }
+                return null;
+            }
+        }
+        return null;
+    }
+
+    private void initPolicyFile() {
+
+        String prop = Security.getProperty("policy.expandProperties");
+        if (prop != null) {
+            expandProperties = prop.equalsIgnoreCase("true");
+        }
+
+        String iscp = Security.getProperty("policy.ignoreIdentityScope");
+        if (iscp != null) {
+            ignoreIdentityScope = iscp.equalsIgnoreCase("true");
+        }
+
+        String allowSys = Security.getProperty("policy.allowSystemProperty");
+        if (allowSys != null && allowSys.equalsIgnoreCase("true")) {
+            String extra_policy = System.getProperty(AUTH_POLICY);
+            if (extra_policy != null) {
+                boolean overrideAll = false;
+                if (extra_policy.startsWith("=")) {
+                    overrideAll = true;
+                    extra_policy = extra_policy.substring(1);
+                }
+                try {
+                    extra_policy = PropertyExpander.expand(extra_policy);
+                    URL policyURL;
+                    File policyFile = new File(extra_policy);
+                    if (policyFile.exists()) {
+                        policyURL =
+                            new URL("file:" + policyFile.getCanonicalPath());
+                    } else {
+                        policyURL = new URL(extra_policy);
+                    }
+                    if (debug != null) {
+                        debug.println("reading " + policyURL);
+                    }
+                    init(policyURL);
+                } catch (Exception e) {
+                    // ignore.
+                    if (debug != null) {
+                        debug.println("caught exception: " + e);
+                    }
+
+                }
+                if (overrideAll) {
+                    if (debug != null) {
+                        debug.println("overriding other policies!");
+                    }
+                    return;
+                }
+            }
+        }
+
+        int n = 1;
+        boolean loaded_one = false;
+        String policy_url;
+
+        while ((policy_url = Security.getProperty(AUTH_POLICY_URL+n)) != null) {
+            try {
+                policy_url = PropertyExpander.expand(policy_url).replace
+                                                (File.separatorChar, '/');
+                if (debug != null) {
+                    debug.println("reading " + policy_url);
+                }
+                init(new URL(policy_url));
+                loaded_one = true;
+            } catch (Exception e) {
+                if (debug != null) {
+                    debug.println("error reading policy " + e);
+                    e.printStackTrace();
+                }
+                // ignore that policy
+            }
+            n++;
+        }
+
+        if (loaded_one == false) {
+            // do not load a static policy
+        }
+    }
+
+    /**
+     * Checks public key. If it is marked as trusted in
+     * the identity database, add it to the policy
+     * with the AllPermission.
+     */
+    private boolean checkForTrustedIdentity(final Certificate cert) {
+        return false;
+    }
+
+    /**
+     * Reads a policy configuration into the Policy object using a
+     * Reader object.
+     *
+     * @param policyFile the policy Reader object.
+     */
+    private void init(URL policy) {
+        PolicyParser pp = new PolicyParser(expandProperties);
+        try (InputStreamReader isr
+                = new InputStreamReader(PolicyUtil.getInputStream(policy))) {
+            pp.read(isr);
+            KeyStore keyStore = initKeyStore(policy, pp.getKeyStoreUrl(),
+                                             pp.getKeyStoreType());
+            Enumeration<GrantEntry> enum_ = pp.grantElements();
+            while (enum_.hasMoreElements()) {
+                GrantEntry ge = enum_.nextElement();
+                addGrantEntry(ge, keyStore);
+            }
+        } catch (PolicyParser.ParsingException pe) {
+            System.err.println(AUTH_POLICY +
+                               rb.getString(".error.parsing.") + policy);
+            System.err.println(AUTH_POLICY + rb.getString("COLON") +
+                               pe.getMessage());
+            if (debug != null) {
+                pe.printStackTrace();
+            }
+        } catch (Exception e) {
+            if (debug != null) {
+                debug.println("error parsing " + policy);
+                debug.println(e.toString());
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * Given a PermissionEntry, create a codeSource.
+     *
+     * @return null if signedBy alias is not recognized
+     */
+    CodeSource getCodeSource(GrantEntry ge, KeyStore keyStore)
+            throws java.net.MalformedURLException
+    {
+        Certificate[] certs = null;
+        if (ge.signedBy != null) {
+            certs = getCertificates(keyStore, ge.signedBy);
+            if (certs == null) {
+                // we don't have a key for this alias,
+                // just return
+                if (debug != null) {
+                    debug.println(" no certs for alias " +
+                                       ge.signedBy + ", ignoring.");
+                }
+                return null;
+            }
+        }
+
+        URL location;
+        if (ge.codeBase != null) {
+            location = new URL(ge.codeBase);
+        } else {
+            location = null;
+        }
+
+        if (ge.principals == null || ge.principals.size() == 0) {
+            return (canonicalizeCodebase
+                        (new CodeSource(location, certs),
+                        false));
+        } else {
+            return (canonicalizeCodebase
+                (new SubjectCodeSource(null, ge.principals, location, certs),
+                false));
+        }
+    }
+
+    /**
+     * Add one policy entry to the vector.
+     */
+    private void addGrantEntry(GrantEntry ge, KeyStore keyStore) {
+
+        if (debug != null) {
+            debug.println("Adding policy entry: ");
+            debug.println("  signedBy " + ge.signedBy);
+            debug.println("  codeBase " + ge.codeBase);
+            if (ge.principals != null) {
+                for (PrincipalEntry pppe : ge.principals) {
+                    debug.println("  " + pppe.getPrincipalClass() +
+                                        " " + pppe.getPrincipalName());
+                }
+            }
+            debug.println();
+        }
+
+        try {
+            CodeSource codesource = getCodeSource(ge, keyStore);
+            // skip if signedBy alias was unknown...
+            if (codesource == null) return;
+
+            PolicyEntry entry = new PolicyEntry(codesource);
+            Enumeration<PermissionEntry> enum_ = ge.permissionElements();
+            while (enum_.hasMoreElements()) {
+                PermissionEntry pe = enum_.nextElement();
+                try {
+                    // XXX special case PrivateCredentialPermission-SELF
+                    Permission perm;
+                    if (pe.permission.equals
+                        ("javax.security.auth.PrivateCredentialPermission") &&
+                        pe.name.endsWith(" self")) {
+                        perm = getInstance(pe.permission,
+                                         pe.name + " \"self\"",
+                                         pe.action);
+                    } else {
+                        perm = getInstance(pe.permission,
+                                         pe.name,
+                                         pe.action);
+                    }
+                    entry.add(perm);
+                    if (debug != null) {
+                        debug.println("  "+perm);
+                    }
+                } catch (ClassNotFoundException cnfe) {
+                    Certificate certs[];
+                    if (pe.signedBy != null) {
+                        certs = getCertificates(keyStore, pe.signedBy);
+                    } else {
+                        certs = null;
+                    }
+
+                    // only add if we had no signer or we had a
+                    // a signer and found the keys for it.
+                    if (certs != null || pe.signedBy == null) {
+                            Permission perm = new UnresolvedPermission(
+                                             pe.permission,
+                                             pe.name,
+                                             pe.action,
+                                             certs);
+                            entry.add(perm);
+                            if (debug != null) {
+                                debug.println("  "+perm);
+                            }
+                    }
+                } catch (java.lang.reflect.InvocationTargetException ite) {
+                    System.err.println
+                        (AUTH_POLICY +
+                        rb.getString(".error.adding.Permission.") +
+                        pe.permission +
+                        rb.getString("SPACE") +
+                        ite.getTargetException());
+                } catch (Exception e) {
+                    System.err.println
+                        (AUTH_POLICY +
+                        rb.getString(".error.adding.Permission.") +
+                        pe.permission +
+                        rb.getString("SPACE") +
+                        e);
+                }
+            }
+            policyEntries.addElement(entry);
+        } catch (Exception e) {
+            System.err.println
+                (AUTH_POLICY +
+                rb.getString(".error.adding.Entry.") +
+                ge +
+                rb.getString("SPACE") +
+                e);
+        }
+
+        if (debug != null) {
+            debug.println();
+        }
+    }
+
+    /**
+     * Returns a new Permission object of the given Type. The Permission is
+     * created by getting the
+     * Class object using the <code>Class.forName</code> method, and using
+     * the reflection API to invoke the (String name, String actions)
+     * constructor on the
+     * object.
+     *
+     * @param type the type of Permission being created.
+     * @param name the name of the Permission being created.
+     * @param actions the actions of the Permission being created.
+     *
+     * @exception  ClassNotFoundException  if the particular Permission
+     *             class could not be found.
+     *
+     * @exception  IllegalAccessException  if the class or initializer is
+     *               not accessible.
+     *
+     * @exception  InstantiationException  if getInstance tries to
+     *               instantiate an abstract class or an interface, or if the
+     *               instantiation fails for some other reason.
+     *
+     * @exception  NoSuchMethodException if the (String, String) constructor
+     *               is not found.
+     *
+     * @exception  InvocationTargetException if the underlying Permission
+     *               constructor throws an exception.
+     *
+     */
+    private static final Permission getInstance(String type,
+                                    String name,
+                                    String actions)
+        throws ClassNotFoundException,
+               InstantiationException,
+               IllegalAccessException,
+               NoSuchMethodException,
+               InvocationTargetException
+    {
+        //XXX we might want to keep a hash of created factories...
+        Class<?> pc = Class.forName(type);
+        Constructor<?> c = pc.getConstructor(PARAMS);
+        return (Permission) c.newInstance(new Object[] { name, actions });
+    }
+
+    /**
+     * Fetch all certs associated with this alias.
+     */
+    Certificate[] getCertificates(KeyStore keyStore, String aliases) {
+
+        Vector<Certificate> vcerts = null;
+
+        StringTokenizer st = new StringTokenizer(aliases, ",");
+        int n = 0;
+
+        while (st.hasMoreTokens()) {
+            String alias = st.nextToken().trim();
+            n++;
+            Certificate cert = null;
+            // See if this alias's cert has already been cached
+            cert = (Certificate) aliasMapping.get(alias);
+            if (cert == null && keyStore != null) {
+
+                try {
+                    cert = keyStore.getCertificate(alias);
+                } catch (KeyStoreException kse) {
+                    // never happens, because keystore has already been loaded
+                    // when we call this
+                }
+                if (cert != null) {
+                    aliasMapping.put(alias, cert);
+                    aliasMapping.put(cert, alias);
+                }
+            }
+
+            if (cert != null) {
+                if (vcerts == null) {
+                    vcerts = new Vector<Certificate>();
+                }
+                vcerts.addElement(cert);
+            }
+        }
+
+        // make sure n == vcerts.size, since we are doing a logical *and*
+        if (vcerts != null && n == vcerts.size()) {
+            Certificate[] certs = new Certificate[vcerts.size()];
+            vcerts.copyInto(certs);
+            return certs;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Enumerate all the entries in the global policy object.
+     * This method is used by policy admin tools.   The tools
+     * should use the Enumeration methods on the returned object
+     * to fetch the elements sequentially.
+     */
+    private final synchronized Enumeration<PolicyEntry> elements() {
+        return policyEntries.elements();
+    }
+
+    @Override
+    public PermissionCollection getPermissions(final Subject subject,
+                                               final CodeSource codesource) {
+
+        // 1)   if code instantiates PolicyFile directly, then it will need
+        //      all the permissions required for the PolicyFile initialization
+        // 2)   if code calls Policy.getPolicy, then it simply needs
+        //      AuthPermission(getPolicy), and the javax.security.auth.Policy
+        //      implementation instantiates PolicyFile in a doPrivileged block
+        // 3)   if after instantiating a Policy (either via #1 or #2),
+        //      code calls getPermissions, PolicyFile wraps the call
+        //      in a doPrivileged block.
+        return AccessController.doPrivileged
+            (new PrivilegedAction<PermissionCollection>() {
+            @Override public PermissionCollection run() {
+                SubjectCodeSource scs = new SubjectCodeSource(
+                    subject, null,
+                    codesource == null ? null : codesource.getLocation(),
+                    codesource == null ? null : codesource.getCertificates());
+                if (initialized) {
+                    return getPermissions(new Permissions(), scs);
+                } else {
+                    return new PolicyPermissions(AuthPolicyFile.this, scs);
+                }
+            }
+        });
+    }
+
+    /**
+     * Examines the global policy for the specified CodeSource, and
+     * creates a PermissionCollection object with
+     * the set of permissions for that principal's protection domain.
+     *
+     * @param CodeSource the codesource associated with the caller.
+     * This encapsulates the original location of the code (where the code
+     * came from) and the public key(s) of its signer.
+     *
+     * @return the set of permissions according to the policy.
+     */
+    PermissionCollection getPermissions(CodeSource codesource) {
+
+        if (initialized) {
+            return getPermissions(new Permissions(), codesource);
+        } else {
+            return new PolicyPermissions(this, codesource);
+        }
+    }
+
+    /**
+     * Examines the global policy for the specified CodeSource, and
+     * creates a PermissionCollection object with
+     * the set of permissions for that principal's protection domain.
+     *
+     * @param permissions the permissions to populate
+     * @param codesource the codesource associated with the caller.
+     * This encapsulates the original location of the code (where the code
+     * came from) and the public key(s) of its signer.
+     *
+     * @return the set of permissions according to the policy.
+     */
+    Permissions getPermissions(final Permissions perms,
+                               final CodeSource cs)
+    {
+        if (!initialized) {
+            init();
+        }
+
+        final CodeSource codesource[] = {null};
+
+        codesource[0] = canonicalizeCodebase(cs, true);
+
+        if (debug != null) {
+            debug.println("evaluate(" + codesource[0] + ")\n");
+        }
+
+        // needs to be in a begin/endPrivileged block because
+        // codesource.implies calls URL.equals which does an
+        // InetAddress lookup
+
+        for (int i = 0; i < policyEntries.size(); i++) {
+
+           PolicyEntry entry = policyEntries.elementAt(i);
+
+           if (debug != null) {
+                debug.println("PolicyFile CodeSource implies: " +
+                              entry.codesource.toString() + "\n\n" +
+                              "\t" + codesource[0].toString() + "\n\n");
+           }
+
+           if (entry.codesource.implies(codesource[0])) {
+               for (int j = 0; j < entry.permissions.size(); j++) {
+                    Permission p = entry.permissions.elementAt(j);
+                    if (debug != null) {
+                        debug.println("  granting " + p);
+                    }
+                    if (!addSelfPermissions(p, entry.codesource,
+                                            codesource[0], perms)) {
+                        // we could check for duplicates
+                        // before adding new permissions,
+                        // but the SubjectDomainCombiner
+                        // already checks for duplicates later
+                        perms.add(p);
+                    }
+                }
+            }
+        }
+
+        // now see if any of the keys are trusted ids.
+
+        if (!ignoreIdentityScope) {
+            Certificate certs[] = codesource[0].getCertificates();
+            if (certs != null) {
+                for (int k=0; k < certs.length; k++) {
+                    if (aliasMapping.get(certs[k]) == null &&
+                        checkForTrustedIdentity(certs[k])) {
+                        // checkForTrustedIdentity added it
+                        // to the policy for us. next time
+                        // around we'll find it. This time
+                        // around we need to add it.
+                        perms.add(new java.security.AllPermission());
+                    }
+                }
+            }
+        }
+        return perms;
+    }
+
+    /**
+     * Returns true if 'Self' permissions were added to the provided
+     * 'perms', and false otherwise.
+     *
+     * <p>
+     *
+     * @param p check to see if this Permission is a "SELF"
+     *                  PrivateCredentialPermission. <p>
+     *
+     * @param entryCs the codesource for the Policy entry.
+     *
+     * @param accCs the codesource for from the current AccessControlContext.
+     *
+     * @param perms the PermissionCollection where the individual
+     *                  PrivateCredentialPermissions will be added.
+     */
+    private boolean addSelfPermissions(final Permission p,
+                                       CodeSource entryCs,
+                                       CodeSource accCs,
+                                       Permissions perms) {
+
+        if (!(p instanceof PrivateCredentialPermission)) {
+            return false;
+        }
+
+        if (!(entryCs instanceof SubjectCodeSource)) {
+            return false;
+        }
+
+        PrivateCredentialPermission pcp = (PrivateCredentialPermission)p;
+        SubjectCodeSource scs = (SubjectCodeSource)entryCs;
+
+        // see if it is a SELF permission
+        String[][] pPrincipals = pcp.getPrincipals();
+        if (pPrincipals.length <= 0 ||
+            !pPrincipals[0][0].equalsIgnoreCase("self") ||
+            !pPrincipals[0][1].equalsIgnoreCase("self")) {
+
+            // regular PrivateCredentialPermission
+            return false;
+        } else {
+
+            // granted a SELF permission - create a
+            // PrivateCredentialPermission for each
+            // of the Policy entry's CodeSource Principals
+
+            if (scs.getPrincipals() == null) {
+                // XXX SubjectCodeSource has no Subject???
+                return true;
+            }
+
+            for (PrincipalEntry principal : scs.getPrincipals()) {
+
+                //      if the Policy entry's Principal does not contain a
+                //              WILDCARD for the Principal name, then a
+                //              new PrivateCredentialPermission is created
+                //              for the Principal listed in the Policy entry.
+                //      if the Policy entry's Principal contains a WILDCARD
+                //              for the Principal name, then a new
+                //              PrivateCredentialPermission is created
+                //              for each Principal associated with the Subject
+                //              in the current ACC.
+
+                String[][] principalInfo = getPrincipalInfo(principal, accCs);
+
+                for (int i = 0; i < principalInfo.length; i++) {
+
+                    // here's the new PrivateCredentialPermission
+
+                    PrivateCredentialPermission newPcp =
+                        new PrivateCredentialPermission
+                                (pcp.getCredentialClass() +
+                                        " " +
+                                        principalInfo[i][0] +
+                                        " " +
+                                        "\"" + principalInfo[i][1] + "\"",
+                                "read");
+
+                    if (debug != null) {
+                        debug.println("adding SELF permission: " +
+                                        newPcp.toString());
+                    }
+
+                    perms.add(newPcp);
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * return the principal class/name pair in the 2D array.
+     * array[x][y]:     x corresponds to the array length.
+     *                  if (y == 0), it's the principal class.
+     *                  if (y == 1), it's the principal name.
+     */
+    private String[][] getPrincipalInfo(PrincipalEntry principal,
+                                        final CodeSource accCs) {
+
+        // there are 3 possibilities:
+        // 1) the entry's Principal class and name are not wildcarded
+        // 2) the entry's Principal name is wildcarded only
+        // 3) the entry's Principal class and name are wildcarded
+
+        if (!principal.getPrincipalClass().equals
+                (PrincipalEntry.WILDCARD_CLASS) &&
+            !principal.getPrincipalName().equals
+                (PrincipalEntry.WILDCARD_NAME)) {
+
+            // build a PrivateCredentialPermission for the principal
+            // from the Policy entry
+            String[][] info = new String[1][2];
+            info[0][0] = principal.getPrincipalClass();
+            info[0][1] = principal.getPrincipalName();
+            return info;
+
+        } else if (!principal.getPrincipalClass().equals
+                (PrincipalEntry.WILDCARD_CLASS) &&
+            principal.getPrincipalName().equals
+                (PrincipalEntry.WILDCARD_NAME)) {
+
+            // build a PrivateCredentialPermission for all
+            // the Subject's principals that are instances of principalClass
+
+            // the accCs is guaranteed to be a SubjectCodeSource
+            // because the earlier CodeSource.implies succeeded
+            SubjectCodeSource scs = (SubjectCodeSource)accCs;
+
+            Set<? extends Principal> principalSet = null;
+            try {
+                // principal.principalClass should extend Principal
+                // If it doesn't, we should stop here with a ClassCastException.
+                @SuppressWarnings("unchecked")
+                Class<? extends Principal> pClass = (Class<? extends Principal>)
+                        Class.forName(principal.getPrincipalClass(), false,
+                                      ClassLoader.getSystemClassLoader());
+                principalSet = scs.getSubject().getPrincipals(pClass);
+            } catch (Exception e) {
+                if (debug != null) {
+                    debug.println("problem finding Principal Class " +
+                                  "when expanding SELF permission: " +
+                                  e.toString());
+                }
+            }
+
+            if (principalSet == null) {
+                // error
+                return new String[0][0];
+            }
+
+            String[][] info = new String[principalSet.size()][2];
+
+            int i = 0;
+            for (Principal p : principalSet) {
+                info[i][0] = p.getClass().getName();
+                info[i][1] = p.getName();
+                i++;
+            }
+            return info;
+
+        } else {
+
+            // build a PrivateCredentialPermission for every
+            // one of the current Subject's principals
+
+            // the accCs is guaranteed to be a SubjectCodeSource
+            // because the earlier CodeSource.implies succeeded
+            SubjectCodeSource scs = (SubjectCodeSource)accCs;
+            Set<Principal> principalSet = scs.getSubject().getPrincipals();
+
+            String[][] info = new String[principalSet.size()][2];
+
+            int i = 0;
+            for (Principal p : principalSet) {
+                info[i][0] = p.getClass().getName();
+                info[i][1] = p.getName();
+                i++;
+            }
+            return info;
+        }
+    }
+
+    /*
+     * Returns the signer certificates from the list of certificates associated
+     * with the given code source.
+     *
+     * The signer certificates are those certificates that were used to verify
+     * signed code originating from the codesource location.
+     *
+     * This method assumes that in the given code source, each signer
+     * certificate is followed by its supporting certificate chain
+     * (which may be empty), and that the signer certificate and its
+     * supporting certificate chain are ordered bottom-to-top (i.e., with the
+     * signer certificate first and the (root) certificate authority last).
+     */
+    Certificate[] getSignerCertificates(CodeSource cs) {
+        Certificate[] certs = null;
+        if ((certs = cs.getCertificates()) == null) {
+            return null;
+        }
+        for (int i = 0; i < certs.length; i++) {
+            if (!(certs[i] instanceof X509Certificate))
+                return cs.getCertificates();
+        }
+
+        // Do we have to do anything?
+        int i = 0;
+        int count = 0;
+        while (i < certs.length) {
+            count++;
+            while (((i+1) < certs.length)
+                   && ((X509Certificate)certs[i]).getIssuerDN().equals(
+                           ((X509Certificate)certs[i+1]).getSubjectDN())) {
+                i++;
+            }
+            i++;
+        }
+        if (count == certs.length) {
+            // Done
+            return certs;
+        }
+
+        ArrayList<Certificate> userCertList = new ArrayList<>();
+        i = 0;
+        while (i < certs.length) {
+            userCertList.add(certs[i]);
+            while (((i+1) < certs.length)
+                   && ((X509Certificate)certs[i]).getIssuerDN().equals(
+                           ((X509Certificate)certs[i+1]).getSubjectDN())) {
+                i++;
+            }
+            i++;
+        }
+        Certificate[] userCerts = new Certificate[userCertList.size()];
+        userCertList.toArray(userCerts);
+        return userCerts;
+    }
+
+    private CodeSource canonicalizeCodebase(CodeSource cs,
+                                            boolean extractSignerCerts) {
+        CodeSource canonCs = cs;
+        if (cs.getLocation() != null &&
+            cs.getLocation().getProtocol().equalsIgnoreCase("file")) {
+            try {
+                String path = cs.getLocation().getFile().replace
+                                                        ('/',
+                                                        File.separatorChar);
+                URL csUrl = null;
+                if (path.endsWith("*")) {
+                    // remove trailing '*' because it causes canonicalization
+                    // to fail on win32
+                    path = path.substring(0, path.length()-1);
+                    boolean appendFileSep = false;
+                    if (path.endsWith(File.separator)) {
+                        appendFileSep = true;
+                    }
+                    if (path.equals("")) {
+                        path = System.getProperty("user.dir");
+                    }
+                    File f = new File(path);
+                    path = f.getCanonicalPath();
+                    StringBuffer sb = new StringBuffer(path);
+                    // reappend '*' to canonicalized filename (note that
+                    // canonicalization may have removed trailing file
+                    // separator, so we have to check for that, too)
+                    if (!path.endsWith(File.separator) &&
+                        (appendFileSep || f.isDirectory())) {
+                        sb.append(File.separatorChar);
+                    }
+                    sb.append('*');
+                    path = sb.toString();
+                } else {
+                    path = new File(path).getCanonicalPath();
+                }
+                csUrl = new File(path).toURL();
+
+                if (cs instanceof SubjectCodeSource) {
+                    SubjectCodeSource scs = (SubjectCodeSource)cs;
+                    if (extractSignerCerts) {
+                        canonCs = new SubjectCodeSource(scs.getSubject(),
+                                                        scs.getPrincipals(),
+                                                        csUrl,
+                                                        getSignerCertificates(scs));
+                    } else {
+                        canonCs = new SubjectCodeSource(scs.getSubject(),
+                                                        scs.getPrincipals(),
+                                                        csUrl,
+                                                        scs.getCertificates());
+                    }
+                } else {
+                    if (extractSignerCerts) {
+                        canonCs = new CodeSource(csUrl,
+                                                 getSignerCertificates(cs));
+                    } else {
+                        canonCs = new CodeSource(csUrl,
+                                                 cs.getCertificates());
+                    }
+                }
+            } catch (IOException ioe) {
+                // leave codesource as it is, unless we have to extract its
+                // signer certificates
+                if (extractSignerCerts) {
+                    if (!(cs instanceof SubjectCodeSource)) {
+                        canonCs = new CodeSource(cs.getLocation(),
+                                                getSignerCertificates(cs));
+                    } else {
+                        SubjectCodeSource scs = (SubjectCodeSource)cs;
+                        canonCs = new SubjectCodeSource(scs.getSubject(),
+                                                scs.getPrincipals(),
+                                                scs.getLocation(),
+                                                getSignerCertificates(scs));
+                    }
+                }
+            }
+        } else {
+            if (extractSignerCerts) {
+                if (!(cs instanceof SubjectCodeSource)) {
+                    canonCs = new CodeSource(cs.getLocation(),
+                                        getSignerCertificates(cs));
+                } else {
+                    SubjectCodeSource scs = (SubjectCodeSource)cs;
+                    canonCs = new SubjectCodeSource(scs.getSubject(),
+                                        scs.getPrincipals(),
+                                        scs.getLocation(),
+                                        getSignerCertificates(scs));
+                }
+            }
+        }
+        return canonCs;
+    }
+
+    /**
+     * Each entry in the policy configuration file is represented by a
+     * PolicyEntry object.  <p>
+     *
+     * A PolicyEntry is a (CodeSource,Permission) pair.  The
+     * CodeSource contains the (URL, PublicKey) that together identify
+     * where the Java bytecodes come from and who (if anyone) signed
+     * them.  The URL could refer to localhost.  The URL could also be
+     * null, meaning that this policy entry is given to all comers, as
+     * long as they match the signer field.  The signer could be null,
+     * meaning the code is not signed. <p>
+     *
+     * The Permission contains the (Type, Name, Action) triplet. <p>
+     *
+     * For now, the Policy object retrieves the public key from the
+     * X.509 certificate on disk that corresponds to the signedBy
+     * alias specified in the Policy config file.  For reasons of
+     * efficiency, the Policy object keeps a hashtable of certs already
+     * read in.  This could be replaced by a secure internal key
+     * store.
+     *
+     * <p>
+     * For example, the entry
+     * <pre>
+     *          permission java.io.File "/tmp", "read,write",
+     *          signedBy "Duke";
+     * </pre>
+     * is represented internally
+     * <pre>
+     *
+     * FilePermission f = new FilePermission("/tmp", "read,write");
+     * PublicKey p = publickeys.get("Duke");
+     * URL u = InetAddress.getLocalHost();
+     * CodeBase c = new CodeBase( p, u );
+     * pe = new PolicyEntry(f, c);
+     * </pre>
+     *
+     * @author Marianne Mueller
+     * @author Roland Schemers
+     * @see java.security.CodeSource
+     * @see java.security.Policy
+     * @see java.security.Permissions
+     * @see java.security.ProtectionDomain
+     */
+    private static class PolicyEntry {
+
+        CodeSource codesource;
+        Vector<Permission> permissions;
+
+        /**
+         * Given a Permission and a CodeSource, create a policy entry.
+         *
+         * XXX Decide if/how to add validity fields and "purpose" fields to
+         * XXX policy entries
+         *
+         * @param cs the CodeSource, which encapsulates the URL and the public
+         *        key attributes from the policy config file. Validity checks
+         *        are performed on the public key before PolicyEntry is called.
+         *
+         */
+        PolicyEntry(CodeSource cs) {
+            this.codesource = cs;
+            this.permissions = new Vector<Permission>();
+        }
+
+        /**
+         * add a Permission object to this entry.
+         */
+        void add(Permission p) {
+            permissions.addElement(p);
+        }
+
+        /**
+         * Return the CodeSource for this policy entry
+         */
+        CodeSource getCodeSource() {
+            return this.codesource;
+        }
+
+        @Override
+        public String toString(){
+            StringBuffer sb = new StringBuffer();
+            sb.append(rb.getString("LPARAM"));
+            sb.append(getCodeSource());
+            sb.append("\n");
+            for (int j = 0; j < permissions.size(); j++) {
+                Permission p = permissions.elementAt(j);
+                sb.append(rb.getString("SPACE"));
+                sb.append(rb.getString("SPACE"));
+                sb.append(p);
+                sb.append(rb.getString("NEWLINE"));
+            }
+            sb.append(rb.getString("RPARAM"));
+            sb.append(rb.getString("NEWLINE"));
+            return sb.toString();
+        }
+
+    }
+}
+
+@SuppressWarnings("deprecation")
+class PolicyPermissions extends PermissionCollection {
+
+    private static final long serialVersionUID = -1954188373270545523L;
+
+    private CodeSource codesource;
+    private Permissions perms;
+    private AuthPolicyFile policy;
+    private boolean notInit; // have we pulled in the policy permissions yet?
+    private Vector<Permission> additionalPerms;
+
+    PolicyPermissions(AuthPolicyFile policy,
+                      CodeSource codesource)
+    {
+        this.codesource = codesource;
+        this.policy = policy;
+        this.perms = null;
+        this.notInit = true;
+        this.additionalPerms = null;
+    }
+
+    @Override
+    public void add(Permission permission) {
+        if (isReadOnly())
+            throw new SecurityException
+            (AuthPolicyFile.rb.getString
+            ("attempt.to.add.a.Permission.to.a.readonly.PermissionCollection"));
+
+        if (perms == null) {
+            if (additionalPerms == null) {
+                additionalPerms = new Vector<Permission>();
+            }
+            additionalPerms.add(permission);
+        } else {
+            perms.add(permission);
+        }
+    }
+
+    private synchronized void init() {
+        if (notInit) {
+            if (perms == null) {
+                perms = new Permissions();
+            }
+            if (additionalPerms != null) {
+                Enumeration<Permission> e = additionalPerms.elements();
+                while (e.hasMoreElements()) {
+                    perms.add(e.nextElement());
+                }
+                additionalPerms = null;
+            }
+            policy.getPermissions(perms, codesource);
+            notInit = false;
+        }
+    }
+
+    @Override
+    public boolean implies(Permission permission) {
+        if (notInit) {
+            init();
+        }
+        return perms.implies(permission);
+    }
+
+    @Override
+    public Enumeration<Permission> elements() {
+        if (notInit) {
+            init();
+        }
+        return perms.elements();
+    }
+
+    @Override
+    public String toString() {
+        if (notInit) {
+            init();
+        }
+        return perms.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/security/provider/SubjectCodeSource.java	Mon Aug 19 17:17:17 2013 -0400
@@ -0,0 +1,401 @@
+/*
+ * 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 sun.security.provider;
+
+import java.net.URL;
+import java.util.*;
+import java.security.CodeSource;
+import java.security.Principal;
+import java.security.cert.Certificate;
+import java.lang.reflect.Constructor;
+
+import javax.security.auth.Subject;
+import sun.security.provider.PolicyParser.PrincipalEntry;
+
+/**
+ * <p> This <code>SubjectCodeSource</code> class contains
+ * a <code>URL</code>, signer certificates, and either a <code>Subject</code>
+ * (that represents the <code>Subject</code> in the current
+ * <code>AccessControlContext</code>), or a linked list of Principals
+ * (that represent a "subject" in a <code>Policy</code>).
+ *
+ */
+class SubjectCodeSource extends CodeSource implements java.io.Serializable {
+
+    private static final long serialVersionUID = 6039418085604715275L;
+
+    private static final java.util.ResourceBundle rb =
+        java.security.AccessController.doPrivileged
+        (new java.security.PrivilegedAction<java.util.ResourceBundle>() {
+            public java.util.ResourceBundle run() {
+                return (java.util.ResourceBundle.getBundle
+                        ("sun.security.util.AuthResources"));
+            }
+        });
+
+    private Subject subject;
+    private LinkedList<PrincipalEntry> principals;
+    private static final Class[] PARAMS = { String.class };
+    private static final sun.security.util.Debug debug =
+        sun.security.util.Debug.getInstance("auth", "\t[Auth Access]");
+    private ClassLoader sysClassLoader;
+
+    /**
+     * Creates a new <code>SubjectCodeSource</code>
+     * with the given <code>Subject</code>, principals, <code>URL</code>,
+     * and signers (Certificates).  The <code>Subject</code>
+     * represents the <code>Subject</code> associated with the current
+     * <code>AccessControlContext</code>.
+     * The Principals are given as a <code>LinkedList</code>
+     * of <code>PolicyParser.PrincipalEntry</code> objects.
+     * Typically either a <code>Subject</code> will be provided,
+     * or a list of <code>principals</code> will be provided
+     * (not both).
+     *
+     * <p>
+     *
+     * @param subject the <code>Subject</code> associated with this
+     *                  <code>SubjectCodeSource</code> <p>
+     *
+     * @param url the <code>URL</code> associated with this
+     *                  <code>SubjectCodeSource</code> <p>
+     *
+     * @param certs the signers associated with this
+     *                  <code>SubjectCodeSource</code> <p>
+     */
+    SubjectCodeSource(Subject subject,
+        LinkedList<PrincipalEntry> principals,
+        URL url, Certificate[] certs) {
+
+        super(url, certs);
+        this.subject = subject;
+        this.principals = (principals == null ?
+                new LinkedList<PrincipalEntry>() :
+                new LinkedList<PrincipalEntry>(principals));
+        sysClassLoader = java.security.AccessController.doPrivileged
+        (new java.security.PrivilegedAction<ClassLoader>() {
+            public ClassLoader run() {
+                    return ClassLoader.getSystemClassLoader();
+            }
+        });
+    }
+
+    /**
+     * Get the Principals associated with this <code>SubjectCodeSource</code>.
+     * The Principals are retrieved as a <code>LinkedList</code>
+     * of <code>PolicyParser.PrincipalEntry</code> objects.
+     *
+     * <p>
+     *
+     * @return the Principals associated with this
+     *          <code>SubjectCodeSource</code> as a <code>LinkedList</code>
+     *          of <code>PolicyParser.PrincipalEntry</code> objects.
+     */
+    LinkedList<PrincipalEntry> getPrincipals() {
+        return principals;
+    }
+
+    /**
+     * Get the <code>Subject</code> associated with this
+     * <code>SubjectCodeSource</code>.  The <code>Subject</code>
+     * represents the <code>Subject</code> associated with the
+     * current <code>AccessControlContext</code>.
+     *
+     * <p>
+     *
+     * @return the <code>Subject</code> associated with this
+     *          <code>SubjectCodeSource</code>.
+     */
+    Subject getSubject() {
+        return subject;
+    }
+
+    /**
+     * Returns true if this <code>SubjectCodeSource</code> object "implies"
+     * the specified <code>CodeSource</code>.
+     * More specifically, this method makes the following checks.
+     * If any fail, it returns false.  If they all succeed, it returns true.
+     *
+     * <p>
+     * <ol>
+     * <li> The provided codesource must not be <code>null</code>.
+     * <li> codesource must be an instance of <code>SubjectCodeSource</code>.
+     * <li> super.implies(codesource) must return true.
+     * <li> for each principal in this codesource's principal list:
+     * <ol>
+     * <li>     if the principal is an instanceof
+     *          <code>Principal</code>, then the principal must
+     *          imply the provided codesource's <code>Subject</code>.
+     * <li>     if the principal is not an instanceof
+     *          <code>Principal</code>, then the provided
+     *          codesource's <code>Subject</code> must have an
+     *          associated <code>Principal</code>, <i>P</i>, where
+     *          P.getClass().getName equals principal.principalClass,
+     *          and P.getName() equals principal.principalName.
+     * </ol>
+     * </ol>
+     *
+     * <p>
+     *
+     * @param codesource the <code>CodeSource</code> to compare against.
+     *
+     * @return true if this <code>SubjectCodeSource</code> implies the
+     *          the specified <code>CodeSource</code>.
+     */
+    public boolean implies(CodeSource codesource) {
+
+        LinkedList<PrincipalEntry> subjectList = null;
+
+        if (codesource == null ||
+            !(codesource instanceof SubjectCodeSource) ||
+            !(super.implies(codesource))) {
+
+            if (debug != null)
+                debug.println("\tSubjectCodeSource.implies: FAILURE 1");
+            return false;
+        }
+
+        SubjectCodeSource that = (SubjectCodeSource)codesource;
+
+        // if the principal list in the policy "implies"
+        // the Subject associated with the current AccessControlContext,
+        // then return true
+
+        if (this.principals == null) {
+            if (debug != null)
+                debug.println("\tSubjectCodeSource.implies: PASS 1");
+            return true;
+        }
+
+        if (that.getSubject() == null ||
+            that.getSubject().getPrincipals().size() == 0) {
+            if (debug != null)
+                debug.println("\tSubjectCodeSource.implies: FAILURE 2");
+            return false;
+        }
+
+        ListIterator<PrincipalEntry> li = this.principals.listIterator(0);
+        while (li.hasNext()) {
+            PrincipalEntry pppe = li.next();
+            try {
+
+                // use new Principal.implies method
+
+                Class<?> pClass = Class.forName(pppe.principalClass,
+                                                true, sysClassLoader);
+                if (!Principal.class.isAssignableFrom(pClass)) {
+                    // not the right subtype
+                    throw new ClassCastException(pppe.principalClass +
+                                                 " is not a Principal");
+                }
+                Constructor<?> c = pClass.getConstructor(PARAMS);
+                Principal p = (Principal)c.newInstance(new Object[] {
+                                                       pppe.principalName });
+
+                if (!p.implies(that.getSubject())) {
+                    if (debug != null)
+                        debug.println("\tSubjectCodeSource.implies: FAILURE 3");
+                    return false;
+                } else {
+                    if (debug != null)
+                        debug.println("\tSubjectCodeSource.implies: PASS 2");
+                    return true;
+                }
+            } catch (Exception e) {
+
+                // simply compare Principals
+
+                if (subjectList == null) {
+
+                    if (that.getSubject() == null) {
+                        if (debug != null)
+                            debug.println("\tSubjectCodeSource.implies: " +
+                                        "FAILURE 4");
+                        return false;
+                    }
+                    Iterator<Principal> i =
+                                that.getSubject().getPrincipals().iterator();
+
+                    subjectList = new LinkedList<PrincipalEntry>();
+                    while (i.hasNext()) {
+                        Principal p = i.next();
+                        PrincipalEntry spppe = new PrincipalEntry
+                                (p.getClass().getName(), p.getName());
+                        subjectList.add(spppe);
+                    }
+                }
+
+                if (!subjectListImpliesPrincipalEntry(subjectList, pppe)) {
+                    if (debug != null)
+                        debug.println("\tSubjectCodeSource.implies: FAILURE 5");
+                    return false;
+                }
+            }
+        }
+
+        if (debug != null)
+            debug.println("\tSubjectCodeSource.implies: PASS 3");
+        return true;
+    }
+
+    /**
+     * This method returns, true, if the provided <i>subjectList</i>
+     * "contains" the <code>Principal</code> specified
+     * in the provided <i>pppe</i> argument.
+     *
+     * Note that the provided <i>pppe</i> argument may have
+     * wildcards (*) for the <code>Principal</code> class and name,
+     * which need to be considered.
+     *
+     * <p>
+     *
+     * @param subjectList a list of PolicyParser.PrincipalEntry objects
+     *          that correspond to all the Principals in the Subject currently
+     *          on this thread's AccessControlContext. <p>
+     *
+     * @param pppe the Principals specified in a grant entry.
+     *
+     * @return true if the provided <i>subjectList</i> "contains"
+     *          the <code>Principal</code> specified in the provided
+     *          <i>pppe</i> argument.
+     */
+    private boolean subjectListImpliesPrincipalEntry(
+                LinkedList<PrincipalEntry> subjectList, PrincipalEntry pppe) {
+
+        ListIterator<PrincipalEntry> li = subjectList.listIterator(0);
+        while (li.hasNext()) {
+            PrincipalEntry listPppe = li.next();
+
+            if (pppe.getPrincipalClass().equals
+                        (PrincipalEntry.WILDCARD_CLASS) ||
+                pppe.getPrincipalClass().equals(listPppe.getPrincipalClass()))
+            {
+                if (pppe.getPrincipalName().equals
+                        (PrincipalEntry.WILDCARD_NAME) ||
+                    pppe.getPrincipalName().equals(listPppe.getPrincipalName()))
+                    return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Tests for equality between the specified object and this
+     * object. Two <code>SubjectCodeSource</code> objects are considered equal
+     * if their locations are of identical value, if the two sets of
+     * Certificates are of identical values, and if the
+     * Subjects are equal, and if the PolicyParser.PrincipalEntry values
+     * are of identical values.  It is not required that
+     * the Certificates or PolicyParser.PrincipalEntry values
+     * be in the same order.
+     *
+     * <p>
+     *
+     * @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 == this)
+            return true;
+
+        if (super.equals(obj) == false)
+            return false;
+
+        if (!(obj instanceof SubjectCodeSource))
+            return false;
+
+        SubjectCodeSource that = (SubjectCodeSource)obj;
+
+        // the principal lists must match
+        try {
+            if (this.getSubject() != that.getSubject())
+                return false;
+        } catch (SecurityException se) {
+            return false;
+        }
+
+        if ((this.principals == null && that.principals != null) ||
+            (this.principals != null && that.principals == null))
+            return false;
+
+        if (this.principals != null && that.principals != null) {
+            if (!this.principals.containsAll(that.principals) ||
+                !that.principals.containsAll(this.principals))
+
+                return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Return a hashcode for this <code>SubjectCodeSource</code>.
+     *
+     * <p>
+     *
+     * @return a hashcode for this <code>SubjectCodeSource</code>.
+     */
+    public int hashCode() {
+        return super.hashCode();
+    }
+
+    /**
+     * Return a String representation of this <code>SubjectCodeSource</code>.
+     *
+     * <p>
+     *
+     * @return a String representation of this <code>SubjectCodeSource</code>.
+     */
+    public String toString() {
+        String returnMe = super.toString();
+        if (getSubject() != null) {
+            if (debug != null) {
+                final Subject finalSubject = getSubject();
+                returnMe = returnMe + "\n" +
+                        java.security.AccessController.doPrivileged
+                                (new java.security.PrivilegedAction<String>() {
+                                public String run() {
+                                    return finalSubject.toString();
+                                }
+                        });
+            } else {
+                returnMe = returnMe + "\n" + getSubject().toString();
+            }
+        }
+        if (principals != null) {
+            ListIterator<PrincipalEntry> li = principals.listIterator();
+            while (li.hasNext()) {
+                PrincipalEntry pppe = li.next();
+                returnMe = returnMe + rb.getString("NEWLINE") +
+                        pppe.getPrincipalClass() + " " +
+                        pppe.getPrincipalName();
+            }
+        }
+        return returnMe;
+    }
+}