/* * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */package javax.crypto;import java.security.*;import java.util.Enumeration;import java.util.Hashtable;import java.util.Vector;import java.util.NoSuchElementException;import java.io.Serializable;import java.io.InputStream;import java.io.InputStreamReader;import java.io.BufferedReader;import java.io.IOException;/** * This class contains CryptoPermission objects, organized into * PermissionCollections according to algorithm names. * * <p>When the <code>add</code> method is called to add a * CryptoPermission, the CryptoPermission is stored in the * appropriate PermissionCollection. If no such * collection exists yet, the algorithm name associated with * the CryptoPermission object is * determined and the <code>newPermissionCollection</code> method * is called on the CryptoPermission or CryptoAllPermission class to * create the PermissionCollection and add it to the Permissions object. * * @see javax.crypto.CryptoPermission * @see java.security.PermissionCollection * @see java.security.Permissions * * @author Sharon Liu * @since 1.4 */final class CryptoPermissions extends PermissionCollectionimplements Serializable { private static final long serialVersionUID = 4946547168093391015L; // This class is similar to java.security.Permissions private Hashtable perms; /** * Creates a new CryptoPermissions object containing * no CryptoPermissionCollections. */ CryptoPermissions() { perms = new Hashtable(7); } /** * Populates the crypto policy from the specified * InputStream into this CryptoPermissions object. * * @param in the InputStream to load from. * * @exception SecurityException if cannot load * successfully. */ void load(InputStream in) throws IOException, CryptoPolicyParser.ParsingException { CryptoPolicyParser parser = new CryptoPolicyParser(); parser.read(new BufferedReader(new InputStreamReader(in, "UTF-8"))); CryptoPermission[] parsingResult = parser.getPermissions(); for (int i = 0; i < parsingResult.length; i++) { this.add(parsingResult[i]); } } /** * Returns true if this CryptoPermissions object doesn't * contain any CryptoPermission objects; otherwise, returns * false. */ boolean isEmpty() { return perms.isEmpty(); } /** * Adds a permission object to the PermissionCollection for the * algorithm returned by * <code>(CryptoPermission)permission.getAlgorithm()</code>. * * This method creates * a new PermissionCollection object (and adds the permission to it) * if an appropriate collection does not yet exist. <p> * * @param permission the Permission object to add. * * @exception SecurityException if this CryptoPermissions object is * marked as readonly. * * @see isReadOnly */ public void add(Permission permission) { if (isReadOnly()) throw new SecurityException("Attempt to add a Permission " + "to a readonly CryptoPermissions " + "object"); if (!(permission instanceof CryptoPermission)) return; CryptoPermission cryptoPerm = (CryptoPermission)permission; PermissionCollection pc = getPermissionCollection(cryptoPerm); pc.add(cryptoPerm); String alg = cryptoPerm.getAlgorithm(); if (!perms.containsKey(alg)) { perms.put(alg, pc); } } /** * Checks if this object's PermissionCollection for permissons * of the specified permission's algorithm implies the specified * permission. Returns true if the checking succeeded. * * @param permission the Permission object to check. * * @return true if "permission" is implied by the permissions * in the PermissionCollection it belongs to, false if not. * */ public boolean implies(Permission permission) { if (!(permission instanceof CryptoPermission)) { return false; } CryptoPermission cryptoPerm = (CryptoPermission)permission; PermissionCollection pc = getPermissionCollection(cryptoPerm.getAlgorithm()); return pc.implies(cryptoPerm); } /** * Returns an enumeration of all the Permission objects in all the * PermissionCollections in this CryptoPermissions object. * * @return an enumeration of all the Permissions. */ public Enumeration elements() { // go through each Permissions in the hash table // and call their elements() function. return new PermissionsEnumerator(perms.elements()); } /** * Returns a CryptoPermissions object which * represents the minimum of the specified * CryptoPermissions object and this * CryptoPermissions object. * * @param other the CryptoPermission * object to compare with this object. */ CryptoPermissions getMinimum(CryptoPermissions other) { if (other == null) { return null; } if (this.perms.containsKey(CryptoAllPermission.ALG_NAME)) { return other; } if (other.perms.containsKey(CryptoAllPermission.ALG_NAME)) { return this; } CryptoPermissions ret = new CryptoPermissions(); PermissionCollection thatWildcard = (PermissionCollection)other.perms.get( CryptoPermission.ALG_NAME_WILDCARD); int maxKeySize = 0; if (thatWildcard != null) { maxKeySize = ((CryptoPermission) thatWildcard.elements().nextElement()).getMaxKeySize(); } // For each algorithm in this CryptoPermissions, // find out if there is anything we should add into // ret. Enumeration thisKeys = this.perms.keys(); while (thisKeys.hasMoreElements()) { String alg = (String)thisKeys.nextElement(); PermissionCollection thisPc = (PermissionCollection)this.perms.get(alg); PermissionCollection thatPc = (PermissionCollection)other.perms.get(alg); CryptoPermission[] partialResult; if (thatPc == null) { if (thatWildcard == null) { // The other CryptoPermissions // doesn't allow this given // algorithm at all. Just skip this // algorithm. continue; } partialResult = getMinimum(maxKeySize, thisPc); } else { partialResult = getMinimum(thisPc, thatPc); } for (int i = 0; i < partialResult.length; i++) { ret.add(partialResult[i]); } } PermissionCollection thisWildcard = (PermissionCollection)this.perms.get( CryptoPermission.ALG_NAME_WILDCARD); // If this CryptoPermissions doesn't // have a wildcard, we are done. if (thisWildcard == null) { return ret; } // Deal with the algorithms only appear // in the other CryptoPermissions. maxKeySize = ((CryptoPermission) thisWildcard.elements().nextElement()).getMaxKeySize(); Enumeration thatKeys = other.perms.keys(); while (thatKeys.hasMoreElements()) { String alg = (String)thatKeys.nextElement(); if (this.perms.containsKey(alg)) { continue; } PermissionCollection thatPc = (PermissionCollection)other.perms.get(alg); CryptoPermission[] partialResult; partialResult = getMinimum(maxKeySize, thatPc); for (int i = 0; i < partialResult.length; i++) { ret.add(partialResult[i]); } } return ret; } /** * Get the minimum of the two given PermissionCollection * <code>thisPc</code> and <code>thatPc</code>. * * @param thisPc the first given PermissionColloection * object. * * @param thatPc the second given PermissionCollection * object. */ private CryptoPermission[] getMinimum(PermissionCollection thisPc, PermissionCollection thatPc) { Vector permVector = new Vector(2); Enumeration thisPcPermissions = thisPc.elements(); // For each CryptoPermission in // thisPc object, do the following: // 1) if this CryptoPermission is implied // by thatPc, this CryptoPermission // should be returned, and we can // move on to check the next // CryptoPermission in thisPc. // 2) otherwise, we should return // all CryptoPermissions in thatPc // which // are implied by this CryptoPermission. // Then we can move on to the // next CryptoPermission in thisPc. while (thisPcPermissions.hasMoreElements()) { CryptoPermission thisCp = (CryptoPermission)thisPcPermissions.nextElement(); Enumeration thatPcPermissions = thatPc.elements(); while (thatPcPermissions.hasMoreElements()) { CryptoPermission thatCp = (CryptoPermission)thatPcPermissions.nextElement(); if (thatCp.implies(thisCp)) { permVector.addElement(thisCp); break; } if (thisCp.implies(thatCp)) { permVector.addElement(thatCp); } } } CryptoPermission[] ret = new CryptoPermission[permVector.size()]; permVector.copyInto(ret); return ret; } /** * Returns all the CryptoPermission objects in the given * PermissionCollection object * whose maximum keysize no greater than <code>maxKeySize</code>. * For all CryptoPermission objects with a maximum keysize greater * than <code>maxKeySize</code>, this method constructs a * corresponding CryptoPermission object whose maximum keysize is * set to <code>maxKeySize</code>, and includes that in the result. * * @param maxKeySize the given maximum key size. * * @param pc the given PermissionCollection object. */ private CryptoPermission[] getMinimum(int maxKeySize, PermissionCollection pc) { Vector permVector = new Vector(1); Enumeration enum_ = pc.elements(); while (enum_.hasMoreElements()) { CryptoPermission cp = (CryptoPermission)enum_.nextElement(); if (cp.getMaxKeySize() <= maxKeySize) { permVector.addElement(cp); } else { if (cp.getCheckParam()) { permVector.addElement( new CryptoPermission(cp.getAlgorithm(), maxKeySize, cp.getAlgorithmParameterSpec(), cp.getExemptionMechanism())); } else { permVector.addElement( new CryptoPermission(cp.getAlgorithm(), maxKeySize, cp.getExemptionMechanism())); } } } CryptoPermission[] ret = new CryptoPermission[permVector.size()]; permVector.copyInto(ret); return ret; } /** * Returns the PermissionCollection for the * specified algorithm. Returns null if there * isn't such a PermissionCollection. * * @param alg the algorithm name. */ PermissionCollection getPermissionCollection(String alg) { // If this CryptoPermissions includes CryptoAllPermission, // we should return CryptoAllPermission. if (perms.containsKey(CryptoAllPermission.ALG_NAME)) { return (PermissionCollection)(perms.get(CryptoAllPermission.ALG_NAME)); } PermissionCollection pc = (PermissionCollection)perms.get(alg); // If there isn't a PermissionCollection for // the given algorithm,we should return the // PermissionCollection for the wildcard // if there is one. if (pc == null) { pc = (PermissionCollection)perms.get( CryptoPermission.ALG_NAME_WILDCARD); } return pc; } /** * Returns the PermissionCollection for the algorithm * associated with the specified CryptoPermission * object. Creates such a PermissionCollection * if such a PermissionCollection does not * exist yet. * * @param cryptoPerm the CryptoPermission object. */ private PermissionCollection getPermissionCollection( CryptoPermission cryptoPerm) { String alg = cryptoPerm.getAlgorithm(); PermissionCollection pc = (PermissionCollection)perms.get(alg); if (pc == null) { pc = cryptoPerm.newPermissionCollection(); } return pc; }}final class PermissionsEnumerator implements Enumeration { // all the perms private Enumeration perms; // the current set private Enumeration permset; PermissionsEnumerator(Enumeration e) { perms = e; permset = getNextEnumWithMore(); } public synchronized boolean hasMoreElements() { // if we enter with permissionimpl null, we know // there are no more left. if (permset == null) return false; // try to see if there are any left in the current one if (permset.hasMoreElements()) return true; // get the next one that has something in it... permset = getNextEnumWithMore(); // if it is null, we are done! return (permset != null); } public synchronized Object nextElement() { // hasMoreElements will update permset to the next permset // with something in it... if (hasMoreElements()) { return permset.nextElement(); } else { throw new NoSuchElementException("PermissionsEnumerator"); } } private Enumeration getNextEnumWithMore() { while (perms.hasMoreElements()) { PermissionCollection pc = (PermissionCollection) perms.nextElement(); Enumeration next = pc.elements(); if (next.hasMoreElements()) return next; } return null; }}
/*
* Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.crypto;
import java.security.*;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import java.util.NoSuchElementException;
import java.io.Serializable;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;
/**
* This class contains CryptoPermission objects, organized into
* PermissionCollections according to algorithm names.
*
* <p>When the <code>add</code> method is called to add a
* CryptoPermission, the CryptoPermission is stored in the
* appropriate PermissionCollection. If no such
* collection exists yet, the algorithm name associated with
* the CryptoPermission object is
* determined and the <code>newPermissionCollection</code> method
* is called on the CryptoPermission or CryptoAllPermission class to
* create the PermissionCollection and add it to the Permissions object.
*
* @see javax.crypto.CryptoPermission
* @see java.security.PermissionCollection
* @see java.security.Permissions
*
* @author Sharon Liu
* @since 1.4
*/
final class CryptoPermissions extends PermissionCollection
implements Serializable {
private static final long serialVersionUID = 4946547168093391015L;
// This class is similar to java.security.Permissions
private Hashtable perms;
/**
* Creates a new CryptoPermissions object containing
* no CryptoPermissionCollections.
*/
CryptoPermissions() {
perms = new Hashtable(7);
}
/**
* Populates the crypto policy from the specified
* InputStream into this CryptoPermissions object.
*
* @param in the InputStream to load from.
*
* @exception SecurityException if cannot load
* successfully.
*/
void load(InputStream in)
throws IOException, CryptoPolicyParser.ParsingException {
CryptoPolicyParser parser = new CryptoPolicyParser();
parser.read(new BufferedReader(new InputStreamReader(in, "UTF-8")));
CryptoPermission[] parsingResult = parser.getPermissions();
for (int i = 0; i < parsingResult.length; i++) {
this.add(parsingResult[i]);
}
}
/**
* Returns true if this CryptoPermissions object doesn't
* contain any CryptoPermission objects; otherwise, returns
* false.
*/
boolean isEmpty() {
return perms.isEmpty();
}
/**
* Adds a permission object to the PermissionCollection for the
* algorithm returned by
* <code>(CryptoPermission)permission.getAlgorithm()</code>.
*
* This method creates
* a new PermissionCollection object (and adds the permission to it)
* if an appropriate collection does not yet exist. <p>
*
* @param permission the Permission object to add.
*
* @exception SecurityException if this CryptoPermissions object is
* marked as readonly.
*
* @see isReadOnly
*/
public void add(Permission permission) {
if (isReadOnly())
throw new SecurityException("Attempt to add a Permission " +
"to a readonly CryptoPermissions " +
"object");
if (!(permission instanceof CryptoPermission))
return;
CryptoPermission cryptoPerm = (CryptoPermission)permission;
PermissionCollection pc =
getPermissionCollection(cryptoPerm);
pc.add(cryptoPerm);
String alg = cryptoPerm.getAlgorithm();
if (!perms.containsKey(alg)) {
perms.put(alg, pc);
}
}
/**
* Checks if this object's PermissionCollection for permissons
* of the specified permission's algorithm implies the specified
* permission. Returns true if the checking succeeded.
*
* @param permission the Permission object to check.
*
* @return true if "permission" is implied by the permissions
* in the PermissionCollection it belongs to, false if not.
*
*/
public boolean implies(Permission permission) {
if (!(permission instanceof CryptoPermission)) {
return false;
}
CryptoPermission cryptoPerm = (CryptoPermission)permission;
PermissionCollection pc =
getPermissionCollection(cryptoPerm.getAlgorithm());
return pc.implies(cryptoPerm);
}
/**
* Returns an enumeration of all the Permission objects in all the
* PermissionCollections in this CryptoPermissions object.
*
* @return an enumeration of all the Permissions.
*/
public Enumeration elements() {
// go through each Permissions in the hash table
// and call their elements() function.
return new PermissionsEnumerator(perms.elements());
}
/**
* Returns a CryptoPermissions object which
* represents the minimum of the specified
* CryptoPermissions object and this
* CryptoPermissions object.
*
* @param other the CryptoPermission
* object to compare with this object.
*/
CryptoPermissions getMinimum(CryptoPermissions other) {
if (other == null) {
return null;
}
if (this.perms.containsKey(CryptoAllPermission.ALG_NAME)) {
return other;
}
if (other.perms.containsKey(CryptoAllPermission.ALG_NAME)) {
return this;
}
CryptoPermissions ret = new CryptoPermissions();
PermissionCollection thatWildcard =
(PermissionCollection)other.perms.get(
CryptoPermission.ALG_NAME_WILDCARD);
int maxKeySize = 0;
if (thatWildcard != null) {
maxKeySize = ((CryptoPermission)
thatWildcard.elements().nextElement()).getMaxKeySize();
}
// For each algorithm in this CryptoPermissions,
// find out if there is anything we should add into
// ret.
Enumeration thisKeys = this.perms.keys();
while (thisKeys.hasMoreElements()) {
String alg = (String)thisKeys.nextElement();
PermissionCollection thisPc =
(PermissionCollection)this.perms.get(alg);
PermissionCollection thatPc =
(PermissionCollection)other.perms.get(alg);
CryptoPermission[] partialResult;
if (thatPc == null) {
if (thatWildcard == null) {
// The other CryptoPermissions
// doesn't allow this given
// algorithm at all. Just skip this
// algorithm.
continue;
}
partialResult = getMinimum(maxKeySize, thisPc);
} else {
partialResult = getMinimum(thisPc, thatPc);
}
for (int i = 0; i < partialResult.length; i++) {
ret.add(partialResult[i]);
}
}
PermissionCollection thisWildcard =
(PermissionCollection)this.perms.get(
CryptoPermission.ALG_NAME_WILDCARD);
// If this CryptoPermissions doesn't
// have a wildcard, we are done.
if (thisWildcard == null) {
return ret;
}
// Deal with the algorithms only appear
// in the other CryptoPermissions.
maxKeySize =
((CryptoPermission)
thisWildcard.elements().nextElement()).getMaxKeySize();
Enumeration thatKeys = other.perms.keys();
while (thatKeys.hasMoreElements()) {
String alg = (String)thatKeys.nextElement();
if (this.perms.containsKey(alg)) {
continue;
}
PermissionCollection thatPc =
(PermissionCollection)other.perms.get(alg);
CryptoPermission[] partialResult;
partialResult = getMinimum(maxKeySize, thatPc);
for (int i = 0; i < partialResult.length; i++) {
ret.add(partialResult[i]);
}
}
return ret;
}
/**
* Get the minimum of the two given PermissionCollection
* <code>thisPc</code> and <code>thatPc</code>.
*
* @param thisPc the first given PermissionColloection
* object.
*
* @param thatPc the second given PermissionCollection
* object.
*/
private CryptoPermission[] getMinimum(PermissionCollection thisPc,
PermissionCollection thatPc) {
Vector permVector = new Vector(2);
Enumeration thisPcPermissions = thisPc.elements();
// For each CryptoPermission in
// thisPc object, do the following:
// 1) if this CryptoPermission is implied
// by thatPc, this CryptoPermission
// should be returned, and we can
// move on to check the next
// CryptoPermission in thisPc.
// 2) otherwise, we should return
// all CryptoPermissions in thatPc
// which
// are implied by this CryptoPermission.
// Then we can move on to the
// next CryptoPermission in thisPc.
while (thisPcPermissions.hasMoreElements()) {
CryptoPermission thisCp =
(CryptoPermission)thisPcPermissions.nextElement();
Enumeration thatPcPermissions = thatPc.elements();
while (thatPcPermissions.hasMoreElements()) {
CryptoPermission thatCp =
(CryptoPermission)thatPcPermissions.nextElement();
if (thatCp.implies(thisCp)) {
permVector.addElement(thisCp);
break;
}
if (thisCp.implies(thatCp)) {
permVector.addElement(thatCp);
}
}
}
CryptoPermission[] ret = new CryptoPermission[permVector.size()];
permVector.copyInto(ret);
return ret;
}
/**
* Returns all the CryptoPermission objects in the given
* PermissionCollection object
* whose maximum keysize no greater than <code>maxKeySize</code>.
* For all CryptoPermission objects with a maximum keysize greater
* than <code>maxKeySize</code>, this method constructs a
* corresponding CryptoPermission object whose maximum keysize is
* set to <code>maxKeySize</code>, and includes that in the result.
*
* @param maxKeySize the given maximum key size.
*
* @param pc the given PermissionCollection object.
*/
private CryptoPermission[] getMinimum(int maxKeySize,
PermissionCollection pc) {
Vector permVector = new Vector(1);
Enumeration enum_ = pc.elements();
while (enum_.hasMoreElements()) {
CryptoPermission cp =
(CryptoPermission)enum_.nextElement();
if (cp.getMaxKeySize() <= maxKeySize) {
permVector.addElement(cp);
} else {
if (cp.getCheckParam()) {
permVector.addElement(
new CryptoPermission(cp.getAlgorithm(),
maxKeySize,
cp.getAlgorithmParameterSpec(),
cp.getExemptionMechanism()));
} else {
permVector.addElement(
new CryptoPermission(cp.getAlgorithm(),
maxKeySize,
cp.getExemptionMechanism()));
}
}
}
CryptoPermission[] ret = new CryptoPermission[permVector.size()];
permVector.copyInto(ret);
return ret;
}
/**
* Returns the PermissionCollection for the
* specified algorithm. Returns null if there
* isn't such a PermissionCollection.
*
* @param alg the algorithm name.
*/
PermissionCollection getPermissionCollection(String alg) {
// If this CryptoPermissions includes CryptoAllPermission,
// we should return CryptoAllPermission.
if (perms.containsKey(CryptoAllPermission.ALG_NAME)) {
return
(PermissionCollection)(perms.get(CryptoAllPermission.ALG_NAME));
}
PermissionCollection pc = (PermissionCollection)perms.get(alg);
// If there isn't a PermissionCollection for
// the given algorithm,we should return the
// PermissionCollection for the wildcard
// if there is one.
if (pc == null) {
pc = (PermissionCollection)perms.get(
CryptoPermission.ALG_NAME_WILDCARD);
}
return pc;
}
/**
* Returns the PermissionCollection for the algorithm
* associated with the specified CryptoPermission
* object. Creates such a PermissionCollection
* if such a PermissionCollection does not
* exist yet.
*
* @param cryptoPerm the CryptoPermission object.
*/
private PermissionCollection getPermissionCollection(
CryptoPermission cryptoPerm) {
String alg = cryptoPerm.getAlgorithm();
PermissionCollection pc = (PermissionCollection)perms.get(alg);
if (pc == null) {
pc = cryptoPerm.newPermissionCollection();
}
return pc;
}
}
final class PermissionsEnumerator implements Enumeration {
// all the perms
private Enumeration perms;
// the current set
private Enumeration permset;
PermissionsEnumerator(Enumeration e) {
perms = e;
permset = getNextEnumWithMore();
}
public synchronized boolean hasMoreElements() {
// if we enter with permissionimpl null, we know
// there are no more left.
if (permset == null)
return false;
// try to see if there are any left in the current one
if (permset.hasMoreElements())
return true;
// get the next one that has something in it...
permset = getNextEnumWithMore();
// if it is null, we are done!
return (permset != null);
}
public synchronized Object nextElement() {
// hasMoreElements will update permset to the next permset
// with something in it...
if (hasMoreElements()) {
return permset.nextElement();
} else {
throw new NoSuchElementException("PermissionsEnumerator");
}
}
private Enumeration getNextEnumWithMore() {
while (perms.hasMoreElements()) {
PermissionCollection pc =
(PermissionCollection) perms.nextElement();
Enumeration next = pc.elements();
if (next.hasMoreElements())
return next;
}
return null;
}
}