Certificate cert = null; try { cert = keystore.getCertificate(alias); } catch (Exception e) { if (debug != null) { debug.println(" Error retrieving certificate for '" + alias + "': " + e.toString()); } return null; } if (cert == null || !(cert instanceof X509Certificate)) { if (debug != null) { debug.println(" -- No certificate for '" + alias + "' - ignoring entry"); } return null; } else { X509Certificate x509Cert = (X509Certificate)cert; // 4702543: X500 names with an EmailAddress // were encoded incorrectly. create new // X500Principal name with correct encoding X500Principal p = new X500Principal (x509Cert.getSubjectX500Principal().toString()); return p.getName(); } } /** * 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, PolicyInfo myInfo) { return false; } /** * 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 { private final CodeSource codesource; final List<Permission> permissions; private final List<PolicyParser.PrincipalEntry> principals; /** * 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, List<PolicyParser.PrincipalEntry> principals) { this.codesource = cs; this.permissions = new ArrayList<Permission>(); this.principals = principals; // can be null } PolicyEntry(CodeSource cs) { this(cs, null); } List<PolicyParser.PrincipalEntry> getPrincipals() { return principals; // can be null } /** * add a Permission object to this entry. * No need to sync add op because perms are added to entry only * while entry is being initialized */ void add(Permission p) { permissions.add(p); } /** * Return the CodeSource for this policy entry */ CodeSource getCodeSource() { return codesource; } @Override public String toString(){ StringBuilder sb = new StringBuilder(); sb.append(ResourcesMgr.getString("LPARAM")); sb.append(getCodeSource()); sb.append("\n"); for (int j = 0; j < permissions.size(); j++) { Permission p = permissions.get(j); sb.append(ResourcesMgr.getString("SPACE")); sb.append(ResourcesMgr.getString("SPACE")); sb.append(p); sb.append(ResourcesMgr.getString("NEWLINE")); } sb.append(ResourcesMgr.getString("RPARAM")); sb.append(ResourcesMgr.getString("NEWLINE")); return sb.toString(); } } private static class SelfPermission extends Permission { private static final long serialVersionUID = -8315562579967246806L; /** * The class name of the Permission class that will be * created when this self permission is expanded . * * @serial */ private String type; /** * The permission name. * * @serial */ private String name; /** * The actions of the permission. * * @serial */ private String actions; /** * The certs of the permission. * * @serial */ private Certificate certs[]; /** * Creates a new SelfPermission containing the permission * information needed later to expand the self * @param type the class name of the Permission class that will be * created when this permission is expanded and if necessary resolved. * @param name the name of the permission. * @param actions the actions of the permission. * @param certs the certificates the permission's class was signed with. * This is a list of certificate chains, where each chain is composed of * a signer certificate and optionally its supporting certificate chain. * Each chain is ordered bottom-to-top (i.e., with the signer * certificate first and the (root) certificate authority last). */ public SelfPermission(String type, String name, String actions, Certificate certs[]) { super(type); if (type == null) { throw new NullPointerException (ResourcesMgr.getString("type.can.t.be.null")); } this.type = type; this.name = name; this.actions = actions; if (certs != null) { // Extract the signer certs from the list of certificates. for (int i=0; i<certs.length; i++) { if (!(certs[i] instanceof X509Certificate)) { // there is no concept of signer certs, so we store the // entire cert array this.certs = certs.clone(); break; } } if (this.certs == null) { // Go through the list of certs and see if all the certs are // signer certs. 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) { // All the certs are signer certs, so we store the // entire array this.certs = certs.clone(); } if (this.certs == null) { // extract the signer certs ArrayList<Certificate> signerCerts = new ArrayList<>(); i = 0; while (i < certs.length) { signerCerts.add(certs[i]); while (((i+1) < certs.length) && ((X509Certificate)certs[i]).getIssuerDN().equals( ((X509Certificate)certs[i+1]).getSubjectDN())) { i++; } i++; } this.certs = new Certificate[signerCerts.size()]; signerCerts.toArray(this.certs); } } } } /** * This method always returns false for SelfPermission permissions. * That is, an SelfPermission never considered to * imply another permission. * * @param p the permission to check against. * * @return false. */ @Override public boolean implies(Permission p) { return false; } /** * Checks two SelfPermission objects for equality. * * Checks that <i>obj</i> is an SelfPermission, and has * the same type (class) name, permission name, actions, and * certificates as this object. * * @param obj the object we are testing for equality with this object. * * @return true if obj is an SelfPermission, and has the same * type (class) name, permission name, actions, and * certificates as this object. */ @Override public boolean equals(Object obj) { if (obj == this) return true; if (! (obj instanceof SelfPermission)) return false; SelfPermission that = (SelfPermission) obj; if (!(this.type.equals(that.type) && this.name.equals(that.name) && this.actions.equals(that.actions))) return false; if (this.certs.length != that.certs.length) return false; int i,j; boolean match; for (i = 0; i < this.certs.length; i++) { match = false; for (j = 0; j < that.certs.length; j++) { if (this.certs[i].equals(that.certs[j])) { match = true; break; } } if (!match) return false; } for (i = 0; i < that.certs.length; i++) { match = false; for (j = 0; j < this.certs.length; j++) { if (that.certs[i].equals(this.certs[j])) { match = true; break; } } if (!match) return false; } return true; } /** * Returns the hash code value for this object. * * @return a hash code value for this object. */ @Override public int hashCode() { int hash = type.hashCode(); if (name != null) hash ^= name.hashCode(); if (actions != null) hash ^= actions.hashCode(); return hash; } /** * Returns the canonical string representation of the actions, * which currently is the empty string "", since there are no actions * for an SelfPermission. That is, the actions for the * permission that will be created when this SelfPermission * is resolved may be non-null, but an SelfPermission * itself is never considered to have any actions. * * @return the empty string "". */ @Override public String getActions() { return ""; } public String getSelfType() { return type; } public String getSelfName() { return name; } public String getSelfActions() { return actions; } public Certificate[] getCerts() { return certs; } /** * Returns a string describing this SelfPermission. The convention * is to specify the class name, the permission name, and the actions, * in the following format: '(unresolved "ClassName" "name" "actions")'. * * @return information about this SelfPermission. */ @Override public String toString() { return "(SelfPermission " + type + " " + name + " " + actions + ")"; } } /** * holds policy information that we need to synch on */ private static class PolicyInfo { private static final boolean verbose = false; // Stores grant entries in the policy final List<PolicyEntry> policyEntries; // Stores grant entries gotten from identity database // Use separate lists to avoid sync on policyEntries final List<PolicyEntry> identityPolicyEntries; // Maps aliases to certs final Map aliasMapping; // Maps ProtectionDomain to PermissionCollection private final ProtectionDomainCache[] pdMapping; private java.util.Random random; PolicyInfo(int numCaches) { policyEntries = new ArrayList<PolicyEntry>(); identityPolicyEntries = Collections.synchronizedList(new ArrayList<PolicyEntry>(2)); aliasMapping = Collections.synchronizedMap(new HashMap(11)); pdMapping = new ProtectionDomainCache[numCaches]; JavaSecurityProtectionDomainAccess jspda = SharedSecrets.getJavaSecurityProtectionDomainAccess(); for (int i = 0; i < numCaches; i++) { pdMapping[i] = jspda.getProtectionDomainCache(); } if (numCaches > 1) { random = new java.util.Random(); } } ProtectionDomainCache getPdMapping() { if (pdMapping.length == 1) { return pdMapping[0]; } else { int i = java.lang.Math.abs(random.nextInt() % pdMapping.length); return pdMapping[i]; } } }}Lines 2001–2437 of 2437. Previous lines
Certificate cert = null; try { cert = keystore.getCertificate(alias); } catch (Exception e) { if (debug != null) { debug.println(" Error retrieving certificate for '" + alias + "': " + e.toString()); } return null; } if (cert == null || !(cert instanceof X509Certificate)) { if (debug != null) { debug.println(" -- No certificate for '" + alias + "' - ignoring entry"); } return null; } else { X509Certificate x509Cert = (X509Certificate)cert; // 4702543: X500 names with an EmailAddress // were encoded incorrectly. create new // X500Principal name with correct encoding X500Principal p = new X500Principal (x509Cert.getSubjectX500Principal().toString()); return p.getName(); } } /** * 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, PolicyInfo myInfo) { return false; } /** * 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 { private final CodeSource codesource; final List<Permission> permissions; private final List<PolicyParser.PrincipalEntry> principals; /** * 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, List<PolicyParser.PrincipalEntry> principals) { this.codesource = cs; this.permissions = new ArrayList<Permission>(); this.principals = principals; // can be null } PolicyEntry(CodeSource cs) { this(cs, null); } List<PolicyParser.PrincipalEntry> getPrincipals() { return principals; // can be null } /** * add a Permission object to this entry. * No need to sync add op because perms are added to entry only * while entry is being initialized */ void add(Permission p) { permissions.add(p); } /** * Return the CodeSource for this policy entry */ CodeSource getCodeSource() { return codesource; } @Override public String toString(){ StringBuilder sb = new StringBuilder(); sb.append(ResourcesMgr.getString("LPARAM")); sb.append(getCodeSource()); sb.append("\n"); for (int j = 0; j < permissions.size(); j++) { Permission p = permissions.get(j); sb.append(ResourcesMgr.getString("SPACE")); sb.append(ResourcesMgr.getString("SPACE")); sb.append(p); sb.append(ResourcesMgr.getString("NEWLINE")); } sb.append(ResourcesMgr.getString("RPARAM")); sb.append(ResourcesMgr.getString("NEWLINE")); return sb.toString(); } } private static class SelfPermission extends Permission { private static final long serialVersionUID = -8315562579967246806L; /** * The class name of the Permission class that will be * created when this self permission is expanded . * * @serial */ private String type; /** * The permission name. * * @serial */ private String name; /** * The actions of the permission. * * @serial */ private String actions; /** * The certs of the permission. * * @serial */ private Certificate certs[]; /** * Creates a new SelfPermission containing the permission * information needed later to expand the self * @param type the class name of the Permission class that will be * created when this permission is expanded and if necessary resolved. * @param name the name of the permission. * @param actions the actions of the permission. * @param certs the certificates the permission's class was signed with. * This is a list of certificate chains, where each chain is composed of * a signer certificate and optionally its supporting certificate chain. * Each chain is ordered bottom-to-top (i.e., with the signer * certificate first and the (root) certificate authority last). */ public SelfPermission(String type, String name, String actions, Certificate certs[]) { super(type); if (type == null) { throw new NullPointerException (ResourcesMgr.getString("type.can.t.be.null")); } this.type = type; this.name = name; this.actions = actions; if (certs != null) { // Extract the signer certs from the list of certificates. for (int i=0; i<certs.length; i++) { if (!(certs[i] instanceof X509Certificate)) { // there is no concept of signer certs, so we store the // entire cert array this.certs = certs.clone(); break; } } if (this.certs == null) { // Go through the list of certs and see if all the certs are // signer certs. 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) { // All the certs are signer certs, so we store the // entire array this.certs = certs.clone(); } if (this.certs == null) { // extract the signer certs ArrayList<Certificate> signerCerts = new ArrayList<>(); i = 0; while (i < certs.length) { signerCerts.add(certs[i]); while (((i+1) < certs.length) && ((X509Certificate)certs[i]).getIssuerDN().equals( ((X509Certificate)certs[i+1]).getSubjectDN())) { i++; } i++; } this.certs = new Certificate[signerCerts.size()]; signerCerts.toArray(this.certs); } } } } /** * This method always returns false for SelfPermission permissions. * That is, an SelfPermission never considered to * imply another permission. * * @param p the permission to check against. * * @return false. */ @Override public boolean implies(Permission p) { return false; } /** * Checks two SelfPermission objects for equality. * * Checks that <i>obj</i> is an SelfPermission, and has * the same type (class) name, permission name, actions, and * certificates as this object. * * @param obj the object we are testing for equality with this object. * * @return true if obj is an SelfPermission, and has the same * type (class) name, permission name, actions, and * certificates as this object. */ @Override public boolean equals(Object obj) { if (obj == this) return true; if (! (obj instanceof SelfPermission)) return false; SelfPermission that = (SelfPermission) obj; if (!(this.type.equals(that.type) && this.name.equals(that.name) && this.actions.equals(that.actions))) return false; if (this.certs.length != that.certs.length) return false; int i,j; boolean match; for (i = 0; i < this.certs.length; i++) { match = false; for (j = 0; j < that.certs.length; j++) { if (this.certs[i].equals(that.certs[j])) { match = true; break; } } if (!match) return false; } for (i = 0; i < that.certs.length; i++) { match = false; for (j = 0; j < this.certs.length; j++) { if (that.certs[i].equals(this.certs[j])) { match = true; break; } } if (!match) return false; } return true; } /** * Returns the hash code value for this object. * * @return a hash code value for this object. */ @Override public int hashCode() { int hash = type.hashCode(); if (name != null) hash ^= name.hashCode(); if (actions != null) hash ^= actions.hashCode(); return hash; } /** * Returns the canonical string representation of the actions, * which currently is the empty string "", since there are no actions * for an SelfPermission. That is, the actions for the * permission that will be created when this SelfPermission * is resolved may be non-null, but an SelfPermission * itself is never considered to have any actions. * * @return the empty string "". */ @Override public String getActions() { return ""; } public String getSelfType() { return type; } public String getSelfName() { return name; } public String getSelfActions() { return actions; } public Certificate[] getCerts() { return certs; } /** * Returns a string describing this SelfPermission. The convention * is to specify the class name, the permission name, and the actions, * in the following format: '(unresolved "ClassName" "name" "actions")'. * * @return information about this SelfPermission. */ @Override public String toString() { return "(SelfPermission " + type + " " + name + " " + actions + ")"; } } /** * holds policy information that we need to synch on */ private static class PolicyInfo { private static final boolean verbose = false; // Stores grant entries in the policy final List<PolicyEntry> policyEntries; // Stores grant entries gotten from identity database // Use separate lists to avoid sync on policyEntries final List<PolicyEntry> identityPolicyEntries; // Maps aliases to certs final Map aliasMapping; // Maps ProtectionDomain to PermissionCollection private final ProtectionDomainCache[] pdMapping; private java.util.Random random; PolicyInfo(int numCaches) { policyEntries = new ArrayList<PolicyEntry>(); identityPolicyEntries = Collections.synchronizedList(new ArrayList<PolicyEntry>(2)); aliasMapping = Collections.synchronizedMap(new HashMap(11)); pdMapping = new ProtectionDomainCache[numCaches]; JavaSecurityProtectionDomainAccess jspda = SharedSecrets.getJavaSecurityProtectionDomainAccess(); for (int i = 0; i < numCaches; i++) { pdMapping[i] = jspda.getProtectionDomainCache(); } if (numCaches > 1) { random = new java.util.Random(); } } ProtectionDomainCache getPdMapping() { if (pdMapping.length == 1) { return pdMapping[0]; } else { int i = java.lang.Math.abs(random.nextInt() % pdMapping.length); return pdMapping[i]; } } } }