/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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.
*/
/**
* JCE has two pairs of jurisdiction policy files: one represents U.S. export
* laws, and the other represents the local laws of the country where the
* JCE will be used.
*
* The jurisdiction policy file has the same syntax as JDK policy files except
* that JCE has new permission classes called javax.crypto.CryptoPermission
* and javax.crypto.CryptoAllPermission.
*
* The format of a permission entry in the jurisdiction policy file is:
*
* permission <crypto permission class name>[, <algorithm name>
* [[, <exemption mechanism name>][, <maxKeySize>
* [, <AlgrithomParameterSpec class name>, <parameters
* for constructing an AlgrithomParameterSpec object>]]]];
*
* @author Sharon Liu
*
* @see java.security.Permissions
* @see java.security.spec.AlgrithomParameterSpec
* @see javax.crypto.CryptoPermission
* @see javax.crypto.CryptoAllPermission
* @see javax.crypto.CryptoPermissions
* @since 1.4
*/
final class CryptoPolicyParser {
// Convenience variables for parsing
private int lookahead;
/**
* Creates a CryptoPolicyParser object.
*/
grantEntries = new Vector();
}
/**
* Reads a policy configuration 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.
*/
throws ParsingException, IOException
{
if (!(policy instanceof BufferedReader)) {
}
/*
* 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.resetSyntax();
st.lowerCaseMode(false);
st.slashSlashComments(true);
st.slashStarComments(true);
st.parseNumbers();
/*
* The crypto jurisdiction policy must be consistent. The
* following hashtable is used for checking consistency.
*/
/*
* The main parsing loop. The loop is executed once for each entry
* in the policy 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 grantEntries.
*/
if (peek("grant")) {
} else {
"statement");
}
match(";");
}
}
/**
* parse a Grant entry
*/
throws ParsingException, IOException
{
GrantEntry e = new GrantEntry();
match("grant");
match("{");
while(!peek("}")) {
if (peek("Permission")) {
match(";");
} else {
throw new
}
}
match("}");
return e;
}
/**
* parse a CryptoPermission entry
*/
throws ParsingException, IOException
{
CryptoPermissionEntry e = new CryptoPermissionEntry();
match("Permission");
// Done with the CryptoAllPermission entry.
return e;
}
// Should see the algorithm name.
if (peek("\"")) {
// Algorithm name - always convert to upper case after parsing.
} else {
// The algorithm name can be a wildcard.
if (peek("*")) {
match("*");
} else {
"Missing the algorithm name");
}
}
peekAndMatch(",");
// May see the exemption mechanism name.
if (peek("\"")) {
// Exemption mechanism name - convert to upper case too.
}
peekAndMatch(",");
// Check whether this entry is consistent with other permission entries
// that have been read.
}
// Should see the maxKeySize if not at the end of this entry yet.
if (peek("number")) {
e.maxKeySize = match();
} else {
if (peek("*")) {
match("*");
} else {
if (!peek(";")) {
"Missing the maximum " +
"allowable key size");
} else {
// At the end of this permission entry
}
}
}
peekAndMatch(",");
// May see an AlgorithmParameterSpec class name.
if (peek("\"")) {
// AlgorithmParameterSpec class name.
while (peek(",")) {
match(",");
if (peek("number")) {
} else {
if (peek("*")) {
match("*");
} else {
"Expecting an integer");
}
}
}
e.checkParam = true;
}
return e;
}
throws ParsingException
{
try {
paramClasses[i] = int.class;
}
} catch (Exception e) {
throw new ParsingException("Cannot call the constructor of " +
type + e);
}
return ret;
}
throws ParsingException, IOException
{
return true;
}
return false;
}
boolean found = false;
switch (lookahead) {
case StreamTokenizer.TT_WORD:
found = true;
break;
case StreamTokenizer.TT_NUMBER:
found = true;
}
break;
case ',':
found = true;
break;
case '{':
found = true;
break;
case '}':
found = true;
break;
case '"':
found = true;
break;
case '*':
found = true;
break;
case ';':
found = true;
break;
default:
break;
}
return found;
}
/**
* Excepts to match a non-negative number.
*/
private int match()
throws ParsingException, IOException
{
int value = -1;
switch (lookahead) {
case StreamTokenizer.TT_NUMBER:
if (value < 0) {
}
break;
default:
break;
}
if (value <= 0) {
sValue);
}
return value;
}
throws ParsingException, IOException
{
switch (lookahead) {
case StreamTokenizer.TT_NUMBER:
case StreamTokenizer.TT_EOF:
case StreamTokenizer.TT_WORD:
}
}
else
break;
case '"':
}
else
break;
case ',':
else
break;
case '{':
else
break;
case '}':
else
break;
case ';':
else
break;
case '*':
else
break;
default:
}
return value;
}
while (grantEnum.hasMoreElements()) {
while (permEnum.hasMoreElements()) {
"javax.crypto.CryptoAllPermission")) {
} else {
if (pe.checkParam) {
} else {
}
}
}
}
return ret;
}
if (processedPermissions == null) {
processedPermissions = new Hashtable();
return true;
}
return false;
}
return false;
}
} else {
}
return true;
}
/**
* Each grant entry in the policy configuration file is represented by a
* GrantEntry object. <p>
*
* <p>
* For example, the entry
* <pre>
* grant {
* permission javax.crypto.CryptoPermission "DES", 56;
* };
*
* </pre>
* is represented internally
* <pre>
*
* pe = new CryptoPermissionEntry("javax.crypto.CryptoPermission",
* "DES", 56);
*
* ge = new GrantEntry();
*
* ge.add(pe);
*
* </pre>
*
* @see java.security.Permission
* @see javax.crypto.CryptoPermission
* @see javax.crypto.CryptoPermissions
*/
private static class GrantEntry {
GrantEntry() {
permissionEntries = new Vector();
}
{
}
{
}
{
}
/**
* Enumerate all the permission entries in this GrantEntry.
*/
return permissionEntries.elements();
}
}
/**
* Each crypto permission entry in the policy configuration file is
* represented by a CryptoPermissionEntry object. <p>
*
* <p>
* For example, the entry
* <pre>
* permission javax.crypto.CryptoPermission "DES", 56;
* </pre>
* is represented internally
* <pre>
*
* pe = new CryptoPermissionEntry("javax.crypto.cryptoPermission",
* "DES", 56);
* </pre>
*
* @see java.security.Permissions
* @see javax.crypto.CryptoPermission
* @see javax.crypto.CryptoAllPermission
*/
private static class CryptoPermissionEntry {
int maxKeySize;
boolean checkParam;
// Set default values.
maxKeySize = 0;
checkParam = false;
algParamSpec = null;
}
/**
* Calculates a hash code value for the object. Objects
* which are equal will also have the same hashcode.
*/
public int hashCode() {
if (exemptionMechanism != null) {
}
retval ^= maxKeySize;
if (algParamSpec != null) {
}
return retval;
}
if (obj == this)
return true;
if (!(obj instanceof CryptoPermissionEntry))
return false;
if (this.cryptoPermission == null) {
} else {
if (!this.cryptoPermission.equals(
return false;
}
} else {
return false;
}
if (this.algParamSpec == null) {
} else {
return false;
}
// everything matched -- the 2 objects are equal
return true;
}
}
/**
* Constructs a ParsingException with the specified
* detail message.
* @param msg the detail message.
*/
super(msg);
}
}
}
}
}