This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
Patch: FYI: java.security update
- From: Tom Tromey <tromey at redhat dot com>
- To: GCC libjava patches <java-patches at gcc dot gnu dot org>
- Date: 19 Apr 2003 14:44:13 -0600
- Subject: Patch: FYI: java.security update
- Reply-to: tromey at redhat dot com
I'm checking this in on the trunk.
This updates java.security with code from Classpath.
Tom
Index: libjava/ChangeLog
from Tom Tromey <tromey at redhat dot com>
* Makefile.in: Rebuilt.
* Makefile.am (ordinary_java_source_files): Added new files.
* java/security/AlgorithmParameterGenerator.java,
java/security/AlgorithmParameters.java, java/security/Engine.java,
java/security/Identity.java, java/security/IdentityScope.java,
java/security/KeyFactory.java,
java/security/KeyPairGenerator.java, java/security/KeyStore.java,
java/security/MessageDigest.java, java/security/Policy.java,
java/security/ProtectionDomain.java,
java/security/SecureRandom.java, java/security/Security.java,
java/security/Signature.java, java/security/SignatureSpi.java,
java/security/SignedObject.java, java/security/Signer.java,
java/security/interfaces/RSAMultiPrimePrivateCrtKey.java,
java/security/spec/PSSParameterSpec.java,
java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java,
java/security/spec/RSAOtherPrimeInfo.java: New versions from
Classpath.
Index: libjava/Makefile.am
===================================================================
RCS file: /cvs/gcc/gcc/libjava/Makefile.am,v
retrieving revision 1.290
diff -u -r1.290 Makefile.am
--- libjava/Makefile.am 29 Mar 2003 21:23:25 -0000 1.290
+++ libjava/Makefile.am 19 Apr 2003 20:19:35 -0000
@@ -2294,6 +2294,7 @@
java/security/DigestInputStream.java \
java/security/DomainCombiner.java \
java/security/DummyMessageDigest.java \
+java/security/Engine.java \
java/security/GeneralSecurityException.java \
java/security/Guard.java \
java/security/GuardedObject.java \
@@ -2374,6 +2375,7 @@
java/security/interfaces/DSAPrivateKey.java \
java/security/interfaces/DSAPublicKey.java \
java/security/interfaces/RSAKey.java \
+java/security/interfaces/RSAMultiPrimePrivateCrtKey.java \
java/security/interfaces/RSAPrivateCrtKey.java \
java/security/interfaces/RSAPrivateKey.java \
java/security/interfaces/RSAPublicKey.java \
@@ -2386,7 +2388,10 @@
java/security/spec/InvalidParameterSpecException.java \
java/security/spec/KeySpec.java \
java/security/spec/PKCS8EncodedKeySpec.java \
+java/security/spec/PSSParameterSpec.java \
java/security/spec/RSAKeyGenParameterSpec.java \
+java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java\
+java/security/spec/RSAOtherPrimeInfo.java \
java/security/spec/RSAPrivateCrtKeySpec.java \
java/security/spec/RSAPrivateKeySpec.java \
java/security/spec/RSAPublicKeySpec.java \
Index: libjava/java/security/AlgorithmParameterGenerator.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/security/AlgorithmParameterGenerator.java,v
retrieving revision 1.2
diff -u -r1.2 AlgorithmParameterGenerator.java
--- libjava/java/security/AlgorithmParameterGenerator.java 22 Jan 2002 22:40:30 -0000 1.2
+++ libjava/java/security/AlgorithmParameterGenerator.java 19 Apr 2003 20:19:46 -0000
@@ -1,5 +1,5 @@
/* AlgorithmParameterGenerator.java --- Algorithm Parameter Generator
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -36,29 +36,64 @@
exception statement from your version. */
package java.security;
+
import java.security.spec.AlgorithmParameterSpec;
/**
- AlgorithmParameterGenerator is used to generate
- algorithm parameters for specified algorithms.
- This class is used to generate the algorithm parameters
- for a specific algorithm.
-
- @since JDK 1.2
- @author Mark Benvenuto
+ * <p>The <code>AlgorithmParameterGenerator</code> class is used to generate a
+ * set of parameters to be used with a certain algorithm. Parameter generators
+ * are constructed using the <code>getInstance()</code> factory methods (static
+ * methods that return instances of a given class).</p>
+ *
+ * <p>The object that will generate the parameters can be initialized in two
+ * different ways: in an algorithm-independent manner, or in an
+ * algorithm-specific manner:</p>
+ *
+ * <ul>
+ * <li>The algorithm-independent approach uses the fact that all parameter
+ * generators share the concept of a <i>"size"</i> and a <i>source of
+ * randomness</i>. The measure of <i>size</i> is universally shared by all
+ * algorithm parameters, though it is interpreted differently for different
+ * algorithms. For example, in the case of parameters for the <i>DSA</i>
+ * algorithm, <i>"size"</i> corresponds to the size of the prime modulus (in
+ * bits). When using this approach, algorithm-specific parameter generation
+ * values - if any - default to some standard values, unless they can be
+ * derived from the specified size.</li>
+ * <li>The other approach initializes a parameter generator object using
+ * algorithm-specific semantics, which are represented by a set of
+ * algorithm-specific parameter generation values. To generate Diffie-Hellman
+ * system parameters, for example, the parameter generation values usually
+ * consist of the size of the prime modulus and the size of the random
+ * exponent, both specified in number of bits.</li>
+ * <ul>
+ *
+ * <p>In case the client does not explicitly initialize the
+ * <code>AlgorithmParameterGenerator</code> (via a call to an <code>init()</code>
+ * method), each provider must supply (and document) a default initialization.
+ * For example, the <b>GNU</b> provider uses a default modulus prime size of
+ * <code>1024</code> bits for the generation of <i>DSA</i> parameters.
+ *
+ * @author Mark Benvenuto
+ * @since 1.2
+ * @see AlgorithmParameters
+ * @see AlgorithmParameterSpec
*/
public class AlgorithmParameterGenerator
{
+ /** Service name for algorithm parameter generators. */
+ private static final String ALGORITHM_PARAMETER_GENERATOR =
+ "AlgorithmParameterGenerator";
+
private AlgorithmParameterGeneratorSpi paramGenSpi;
private Provider provider;
private String algorithm;
/**
- Creates an instance of AlgorithmParameters
-
- @param paramSpi A parameters engine to use
- @param provider A provider to use
- @param algorithm The algorithm
+ * Creates an <code>AlgorithmParameterGenerator</code> object.
+ *
+ * @param paramGenSpi the delegate.
+ * @param provider the provider.
+ * @param algorithm the algorithm.
*/
protected AlgorithmParameterGenerator(AlgorithmParameterGeneratorSpi
paramGenSpi, Provider provider,
@@ -70,97 +105,113 @@
}
/**
- Returns the name of the algorithm used
-
- @return A string with the name of the algorithm
+ * Returns the standard name of the algorithm this parameter generator is
+ * associated with.
+ *
+ * @return the string name of the algorithm.
*/
public final String getAlgorithm()
{
return algorithm;
}
- /**
- Gets an instance of the AlgorithmParameterGenerator class
- which generates algorithm parameters for the specified algorithm.
- If the algorithm is not found then, it throws NoSuchAlgorithmException.
-
- @param algorithm the name of algorithm to choose
- @return a AlgorithmParameterGenerator repesenting the desired algorithm
-
- @throws NoSuchAlgorithmException if the algorithm is not implemented by providers
+ /**
+ * Generates an <code>AlgorithmParameterGenerator</code> object that
+ * implements the specified digest algorithm. If the default provider package
+ * provides an implementation of the requested digest algorithm, an instance
+ * of <code>AlgorithmParameterGenerator</code> containing that implementation
+ * is returned. If the algorithm is not available in the default package,
+ * other packages are searched.
+ *
+ * @param algorithm the string name of the algorithm this parameter generator
+ * is associated with.
+ * @return the new <code>AlgorithmParameterGenerator</code> object.
+ * @throws NoSuchAlgorithmException if the algorithm is not available in the
+ * environment.
*/
public static AlgorithmParameterGenerator getInstance(String algorithm)
throws NoSuchAlgorithmException
{
Provider[] p = Security.getProviders();
-
for (int i = 0; i < p.length; i++)
- {
- String classname =
- p[i].getProperty("AlgorithmParameterGenerator." + algorithm);
- if (classname != null)
- return getInstance(classname, algorithm, p[i]);
- }
+ try
+ {
+ return getInstance(algorithm, p[i]);
+ }
+ catch (NoSuchAlgorithmException ignored) {}
throw new NoSuchAlgorithmException(algorithm);
}
- /**
- Gets an instance of the AlgorithmParameterGenerator class
- which generates algorithm parameters for the specified algorithm.
- If the algorithm is not found then, it throws NoSuchAlgorithmException.
-
- @param algorithm the name of algorithm to choose
- @param provider the name of the provider to find the algorithm in
- @return a AlgorithmParameterGenerator repesenting the desired algorithm
-
- @throws NoSuchAlgorithmException if the algorithm is not implemented by the provider
- @throws NoSuchProviderException if the provider is not found
+ /**
+ * Generates an <code>AlgorithmParameterGenerator</code> object for the
+ * requested algorithm, as supplied from the specified provider, if such a
+ * parameter generator is available from the provider.
+ *
+ * @param algorithm the string name of the algorithm.
+ * @param provider the string name of the provider.
+ * @return the new <code>AlgorithmParameterGenerator</code> object.
+ * @throws NoSuchAlgorithmException if the <code>algorithm</code> is not
+ * available from the <code>provider</code>.
+ * @throws NoSuchProviderException if the <code>provider</code> is not
+ * available in the environment.
+ * @throws IllegalArgumentException if the <code>provider</code> name is
+ * <code>null</code> or empty.
+ * @see Provider
*/
public static AlgorithmParameterGenerator getInstance(String algorithm,
String provider)
throws NoSuchAlgorithmException, NoSuchProviderException
{
+ if (provider == null || provider.length() == 0)
+ throw new IllegalArgumentException("Illegal provider");
+
Provider p = Security.getProvider(provider);
if (p == null)
throw new NoSuchProviderException();
- return getInstance(p.
- getProperty("AlgorithmParameterGenerator." +
- algorithm), algorithm, p);
+ return getInstance(algorithm, p);
}
- private static AlgorithmParameterGenerator getInstance(String classname,
- String algorithm,
- Provider provider)
+ /**
+ * Generates an AlgorithmParameterGenerator object for the requested
+ * algorithm, as supplied from the specified provider, if such a parameter
+ * generator is available from the provider. Note: the <code>provider</code>
+ * doesn't have to be registered.
+ *
+ * @param algorithm the string name of the algorithm.
+ * @param provider the provider.
+ * @return the new AlgorithmParameterGenerator object.
+ * @throws NoSuchAlgorithmException if the algorithm is not available from
+ * the provider.
+ * @throws IllegalArgumentException if the provider is null.
+ * @since 1.4
+ * @see Provider
+ */
+ public static AlgorithmParameterGenerator getInstance(String algorithm,
+ Provider provider)
throws NoSuchAlgorithmException
{
+ if (provider == null)
+ throw new IllegalArgumentException("Illegal provider");
try
{
- return new
- AlgorithmParameterGenerator((AlgorithmParameterGeneratorSpi) Class.
- forName(classname).newInstance(),
- provider, algorithm);
- }
- catch (ClassNotFoundException cnfe)
- {
- throw new NoSuchAlgorithmException("Class not found");
- }
- catch (InstantiationException ie)
- {
- throw new NoSuchAlgorithmException("Class instantiation failed");
- }
- catch (IllegalAccessException iae)
+ return new AlgorithmParameterGenerator(
+ (AlgorithmParameterGeneratorSpi) Engine.getInstance(
+ ALGORITHM_PARAMETER_GENERATOR, algorithm, provider),
+ provider, algorithm);
+ }
+ catch (ClassCastException cce)
{
- throw new NoSuchAlgorithmException("Illegal Access");
+ throw new NoSuchAlgorithmException(algorithm);
}
}
/**
- Gets the provider that the class is from.
-
- @return the provider of this class
+ * Returns the provider of this algorithm parameter generator object.
+ *
+ * @return the provider of this algorithm parameter generator object.
*/
public final Provider getProvider()
{
@@ -168,11 +219,13 @@
}
/**
- Initializes the Algorithm Parameter Generator with the specified
- size. (Since no source of randomness is supplied, a default
- one is supplied).
-
- @param size size (in bits) to use
+ * Initializes this parameter generator for a certain <i>size</i>. To create
+ * the parameters, the { at link SecureRandom} implementation of the
+ * highest-priority installed provider is used as the source of randomness.
+ * (If none of the installed providers supply an implementation of
+ * { at link SecureRandom}, a system-provided source of randomness is used.)
+ *
+ * @param size the size (number of bits).
*/
public final void init(int size)
{
@@ -180,11 +233,11 @@
}
/**
- Initializes the Algorithm Parameter Generator with the specified
- size and source of randomness.
-
- @param size size (in bits) to use
- @param random source of randomness to use
+ * Initializes this parameter generator for a certain size and source of
+ * randomness.
+ *
+ * @param size the size (number of bits).
+ * @param random the source of randomness.
*/
public final void init(int size, SecureRandom random)
{
@@ -192,36 +245,45 @@
}
/**
- Initializes the Algorithm Parameter Generator with the specified
- AlgorithmParameterSpec. (Since no source of randomness is supplied,
- a default one is supplied).
-
- @param genParamSpec the AlgorithmParameterSpec class to use
+ * Initializes this parameter generator with a set of algorithm-specific
+ * parameter generation values. To generate the parameters, the { at link
+ * SecureRandom} implementation of the highest-priority installed provider is
+ * used as the source of randomness. (If none of the installed providers
+ * supply an implementation of { at link SecureRandom}, a system-provided source
+ * of randomness is used.)
+ *
+ * @param genParamSpec the set of algorithm-specific parameter generation
+ * values.
+ * @throws InvalidAlgorithmParameterException if the given parameter
+ * generation values are inappropriate for this parameter generator.
*/
- public final void init(AlgorithmParameterSpec genParamSpec) throws
- InvalidAlgorithmParameterException
+ public final void init(AlgorithmParameterSpec genParamSpec)
+ throws InvalidAlgorithmParameterException
{
init(genParamSpec, new SecureRandom());
}
/**
- Initializes the Algorithm Parameter Generator with the specified
- AlgorithmParameterSpec and source of randomness.
-
- @param genParamSpec the AlgorithmParameterSpec class to use
- @param random source of randomness to use
+ * Initializes this parameter generator with a set of algorithm-specific
+ * parameter generation values.
+ *
+ * @param genParamSpec the set of algorithm-specific parameter generation
+ * values.
+ * @param random the source of randomness.
+ * @throws InvalidAlgorithmParameterException if the given parameter
+ * generation values are inappropriate for this parameter generator.
*/
public final void init(AlgorithmParameterSpec genParamSpec,
- SecureRandom random) throws
- InvalidAlgorithmParameterException
+ SecureRandom random)
+ throws InvalidAlgorithmParameterException
{
paramGenSpi.engineInit(genParamSpec, random);
}
/**
- Generate a new set of AlgorithmParameters.
-
- @returns a new set of algorithm parameters
+ * Generates the parameters.
+ *
+ * @return the new { at link AlgorithmParameters} object.
*/
public final AlgorithmParameters generateParameters()
{
Index: libjava/java/security/AlgorithmParameters.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/security/AlgorithmParameters.java,v
retrieving revision 1.2
diff -u -r1.2 AlgorithmParameters.java
--- libjava/java/security/AlgorithmParameters.java 22 Jan 2002 22:40:30 -0000 1.2
+++ libjava/java/security/AlgorithmParameters.java 19 Apr 2003 20:19:46 -0000
@@ -1,5 +1,5 @@
/* AlgorithmParameters.java --- Algorithm Parameters Implementation Class
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -35,35 +35,68 @@
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
-
package java.security;
+
import java.security.spec.InvalidParameterSpecException;
import java.security.spec.AlgorithmParameterSpec;
import java.io.IOException;
/**
- AlgorithmParameters is the Algorithm Parameters class which
- provides an interface through which to modify parameters for
- classes. This class is used to manage the algorithm parameters.
-
- @since JDK 1.2
- @author Mark Benvenuto
+ * <p>This class is used as an opaque representation of cryptographic
+ * parameters.</p>
+ *
+ * <p>An <code>AlgorithmParameters</code> object for managing the parameters
+ * for a particular algorithm can be obtained by calling one of the
+ * <code>getInstance()</code> factory methods (static methods that return
+ * instances of a given class).</p>
+ *
+ * <p>There are two ways to request such an implementation: by specifying
+ * either just an algorithm name, or both an algorithm name and a package
+ * provider.</p>
+ *
+ * <ul>
+ * <li>If just an algorithm name is specified, the system will determine if
+ * there is an AlgorithmParameters implementation for the algorithm requested
+ * available in the environment, and if there is more than one, if there is
+ * a preferred one.</li>
+ * <li>If both an algorithm name and a package provider are specified, the
+ * system will determine if there is an implementation in the package
+ * requested, and throw an exception if there is not.</li>
+ * </ul>
+ *
+ * <p>Once an <code>AlgorithmParameters</code> object is returned, it must be
+ * initialized via a call to <code>init()</code>, using an appropriate
+ * parameter specification or parameter encoding.</p>
+ *
+ * <p>A transparent parameter specification is obtained from an
+ * <ocde>AlgorithmParameters</code> object via a call to
+ * <code>getParameterSpec()</code>, and a byte encoding of the parameters is
+ * obtained via a call to <code>getEncoded()</code>.</p>
+ *
+ * @author Mark Benvenuto
+ * @since 1.2
+ * @see AlgorithmParameterSpec
+ * @see java.security.spec.DSAParameterSpec
+ * @see KeyPairGenerator
*/
public class AlgorithmParameters
{
+ /** Service name for algorithm parameters. */
+ private static final String ALGORITHM_PARAMETERS = "AlgorithmParameters";
+
private AlgorithmParametersSpi paramSpi;
private Provider provider;
private String algorithm;
/**
- Creates an instance of AlgorithmParameters
-
- @param paramSpi A parameters engine to use
- @param provider A provider to use
- @param algorithm The algorithm
+ * Creates an <code>AlgorithmParameters</code> object.
+ *
+ * @param paramSpi the delegate.
+ * @param provider the provider.
+ * @param algorithm the algorithm.
*/
protected AlgorithmParameters(AlgorithmParametersSpi paramSpi,
- Provider provider, String algorithm)
+ Provider provider, String algorithm)
{
this.paramSpi = paramSpi;
this.provider = provider;
@@ -71,103 +104,116 @@
}
/**
- Returns the name of the algorithm used
-
- @return A string with the name of the algorithm
+ * Returns the name of the algorithm associated with this parameter object.
+ *
+ * @return the algorithm name.
*/
public final String getAlgorithm()
{
return algorithm;
}
- /**
- Gets an instance of the AlgorithmParameters class representing
- the specified algorithm parameters. If the algorithm is not
- found then, it throws NoSuchAlgorithmException.
-
- The returned AlgorithmParameters must still be intialized with
- init().
-
- @param algorithm the name of algorithm to choose
- @return a AlgorithmParameters repesenting the desired algorithm
-
- @throws NoSuchAlgorithmException if the algorithm is not implemented by providers
+ /**
+ * <p>Generates a parameter object for the specified algorithm.</p>
+ *
+ * <p>If the default provider package provides an implementation of the
+ * requested algorithm, an instance of <code>AlgorithmParameters</code>
+ * containing that implementation is returned. If the algorithm is not
+ * available in the default package, other packages are searched.</p>
+ *
+ * <p>The returned parameter object must be initialized via a call to
+ * <code>init()</code>, using an appropriate parameter specification or
+ * parameter encoding.</p>
+ *
+ * @param algorithm the name of the algorithm requested.
+ * @return the new parameter object.
+ * @throws NoSuchAlgorithmException if the algorithm is not available in the
+ * environment.
*/
- public static AlgorithmParameters getInstance(String algorithm) throws
- NoSuchAlgorithmException
+ public static AlgorithmParameters getInstance(String algorithm)
+ throws NoSuchAlgorithmException
{
Provider[] p = Security.getProviders();
-
for (int i = 0; i < p.length; i++)
- {
- String classname =
- p[i].getProperty("AlgorithmParameters." + algorithm);
- if (classname != null)
- return getInstance(classname, algorithm, p[i]);
- }
+ try
+ {
+ return getInstance(algorithm, p[i]);
+ }
+ catch (NoSuchAlgorithmException ignored) {}
throw new NoSuchAlgorithmException(algorithm);
}
- /**
- Gets an instance of the AlgorithmParameters class representing
- the specified algorithm parameters from the specified provider.
- If the algorithm is not found then, it throws
- NoSuchAlgorithmException. If the provider is not found, then
- it throws NoSuchProviderException.
-
- The returned AlgorithmParameters must still be intialized with
- init().
-
- @param algorithm the name of algorithm to choose
- @param provider the name of the provider to find the algorithm in
- @return a AlgorithmParameters repesenting the desired algorithm
-
- @throws NoSuchAlgorithmException if the algorithm is not implemented by the provider
- @throws NoSuchProviderException if the provider is not found
- */
- public static AlgorithmParameters getInstance(String algorithm,
- String provider) throws
- NoSuchAlgorithmException, NoSuchProviderException
- {
+ /**
+ * <p>Generates a parameter object for the specified algorithm, as supplied
+ * by the specified provider, if such an algorithm is available from the
+ * provider.</p>
+ *
+ * <p>The returned parameter object must be initialized via a call to
+ * <code>init()</code>, using an appropriate parameter specification or
+ * parameter encoding.</p>
+ *
+ * @param algorithm the name of the algorithm requested.
+ * @param provider the name of the provider.
+ * @return the new parameter object.
+ * @throws NoSuchAlgorithmException if the algorithm is not available in the
+ * package supplied by the requested provider.
+ * @throws NoSuchProviderException if the provider is not available in the
+ * environment.
+ * @throws IllegalArgumentException if the provider name is null or empty.
+ * @see Provider
+ */
+ public static AlgorithmParameters getInstance(String algorithm, String provider)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ if (provider == null || provider.length() == 0)
+ throw new IllegalArgumentException("Illegal provider");
+
Provider p = Security.getProvider(provider);
if (p == null)
throw new NoSuchProviderException();
- return getInstance(p.getProperty("AlgorithmParameters." + algorithm),
- algorithm, p);
+ return getInstance(algorithm, p);
}
- private static AlgorithmParameters getInstance(String classname,
- String algorithm,
- Provider provider)
+ /**
+ * Generates an <code>AlgorithmParameterGenerator</code> object for the
+ * requested algorithm, as supplied from the specified provider, if such a
+ * parameter generator is available from the provider. Note: the
+ * <code>provider</code> doesn't have to be registered.
+ *
+ * @param algorithm the string name of the algorithm.
+ * @param provider the provider.
+ * @return the new <code>AlgorithmParameterGenerator</code> object.
+ * @throws NoSuchAlgorithmException if the <code>algorithm</code> is not
+ * available from the <code>provider</code>.
+ * @throws IllegalArgumentException if the <code>provider</code> is
+ * <code>null</code>.
+ * @since 1.4
+ */
+ public static AlgorithmParameters getInstance(String algorithm,
+ Provider provider)
throws NoSuchAlgorithmException
{
+ if (provider == null)
+ throw new IllegalArgumentException("Illegal provider");
try
{
- return new AlgorithmParameters((AlgorithmParametersSpi) Class.
- forName(classname).newInstance(),
- provider, algorithm);
- }
- catch (ClassNotFoundException cnfe)
- {
- throw new NoSuchAlgorithmException("Class not found");
- }
- catch (InstantiationException ie)
- {
- throw new NoSuchAlgorithmException("Class instantiation failed");
+ return new AlgorithmParameters((AlgorithmParametersSpi)
+ Engine.getInstance(ALGORITHM_PARAMETERS, algorithm, provider),
+ provider, algorithm);
}
- catch (IllegalAccessException iae)
+ catch (ClassCastException cce)
{
- throw new NoSuchAlgorithmException("Illegal Access");
+ throw new NoSuchAlgorithmException(algorithm);
}
}
/**
- Gets the provider that the class is from.
-
- @return the provider of this class
+ * Returns the provider of this parameter object.
+ *
+ * @return the provider of this parameter object.
*/
public final Provider getProvider()
{
@@ -175,29 +221,28 @@
}
/**
- Initializes the engine with the specified
- AlgorithmParameterSpec class.
-
- @param paramSpec A AlgorithmParameterSpec to initialize with
-
- @throws InvalidParameterSpecException For an inapporiate ParameterSpec class
+ * Initializes this parameter object using the parameters specified in
+ * <code>paramSpec</code>.
+ *
+ * @param paramSpec the parameter specification.
+ * @throws InvalidParameterSpecException if the given parameter specification
+ * is inappropriate for the initialization of this parameter object, or if
+ * this parameter object has already been initialized.
*/
- public final void init(AlgorithmParameterSpec paramSpec) throws
- InvalidParameterSpecException
+ public final void init(AlgorithmParameterSpec paramSpec)
+ throws InvalidParameterSpecException
{
paramSpi.engineInit(paramSpec);
}
/**
- Initializes the engine with the specified
- parameters stored in the byte array and decodes them
- according to the ASN.1 specification. If the ASN.1
- specification exists then it succeeds or else it throws
- IOException.
-
- @param params Parameters to initialize with
-
- @throws IOException Decoding Error
+ * Imports the specified parameters and decodes them according to the primary
+ * decoding format for parameters. The primary decoding format for parameters
+ * is ASN.1, if an ASN.1 specification for this type of parameters exists.
+ *
+ * @param params the encoded parameters.
+ * @throws IOException on decoding errors, or if this parameter object has
+ * already been initialized.
*/
public final void init(byte[]params) throws IOException
{
@@ -205,17 +250,15 @@
}
/**
- Initializes the engine with the specified
- parameters stored in the byte array and decodes them
- according to the specified decoding specification.
- If format is null, then it is decoded using the ASN.1
- specification if it exists or else it throws
- IOException.
-
- @param params Parameters to initialize with
- @param format Name of decoding format to use
-
- @throws IOException Decoding Error
+ * Imports the parameters from params and decodes them according to the
+ * specified decoding scheme. If <code>format</code> is <code>null</code>,
+ * the primary decoding format for parameters is used. The primary decoding
+ * format is ASN.1, if an ASN.1 specification for these parameters exists.
+ *
+ * @param params the encoded parameters.
+ * @param format the name of the decoding scheme.
+ * @throws IOException on decoding errors, or if this parameter object has
+ * already been initialized.
*/
public final void init(byte[]params, String format) throws IOException
{
@@ -223,28 +266,34 @@
}
/**
- Returns a specification of this AlgorithmParameters object.
- paramSpec identifies the class to return the AlgortihmParameters
- in.
-
- @param paramSpec Class to return AlgorithmParameters in
-
- @return the parameter specification
-
- @throws InvalidParameterSpecException if the paramSpec is an invalid parameter class
+ * Returns a (transparent) specification of this parameter object.
+ * <code>paramSpec</code> identifies the specification class in which the
+ * parameters should be returned. It could, for example, be
+ * <code>DSAParameterSpec.class</code>, to indicate that the parameters should
+ * be returned in an instance of the { at link java.security.spec.DSAParameterSpec}
+ * class.
+ *
+ * @param paramSpec the specification class in which the parameters should be
+ * returned.
+ * @return the parameter specification.
+ * @throws InvalidParameterSpecException if the requested parameter
+ * specification is inappropriate for this parameter object, or if this
+ * parameter object has not been initialized.
*/
- public final AlgorithmParameterSpec getParameterSpec(Class paramSpec) throws
- InvalidParameterSpecException
+ public final AlgorithmParameterSpec getParameterSpec(Class paramSpec)
+ throws InvalidParameterSpecException
{
return paramSpi.engineGetParameterSpec(paramSpec);
}
/**
- Returns the parameters in the default encoding format.
- The primary encoding format is ASN.1 format if it exists
- for the specified type.
-
- @return byte array representing the parameters
+ * Returns the parameters in their primary encoding format. The primary
+ * encoding format for parameters is ASN.1, if an ASN.1 specification for
+ * this type of parameters exists.
+ *
+ * @return the parameters encoded using their primary encoding format.
+ * @throws IOException on encoding errors, or if this parameter object has not
+ * been initialized.
*/
public final byte[] getEncoded() throws IOException
{
@@ -252,12 +301,15 @@
}
/**
- Returns the parameters in the specified encoding format.
- If <code>format</code> is <code>null</code> then the
- primary encoding format is used, the ASN.1 format,
- if it exists for the specified type.
-
- @return byte array representing the parameters
+ * Returns the parameters encoded in the specified scheme. If format is
+ * <code>null</code>, the primary encoding format for parameters is used. The
+ * primary encoding format is ASN.1, if an ASN.1 specification for these
+ * parameters exists.
+ *
+ * @param format the name of the encoding format.
+ * @return the parameters encoded using the specified encoding scheme.
+ * @throws IOException on encoding errors, or if this parameter object has
+ * not been initialized.
*/
public final byte[] getEncoded(String format) throws IOException
{
@@ -265,9 +317,10 @@
}
/**
- Returns a string representation of the encoding format
-
- @return a string containing the string representation
+ * Returns a formatted string describing the parameters.
+ *
+ * @return a formatted string describing the parameters, or <code>null</code>
+ * if this parameter object has not been initialized.
*/
public final String toString()
{
Index: libjava/java/security/Engine.java
===================================================================
RCS file: libjava/java/security/Engine.java
diff -N libjava/java/security/Engine.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ libjava/java/security/Engine.java 19 Apr 2003 20:19:46 -0000
@@ -0,0 +1,152 @@
+/* Engine -- generic getInstance method.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.security;
+
+/**
+ * Generic implementation of the getInstance methods in the various
+ * engine classes in java.security.
+ * <p>
+ * These classes ({ at link java.security.Signature} for example) can be
+ * thought of as the "chrome, upholstery, and steering wheel", and the SPI
+ * (service provider interface, e.g. { at link java.security.SignatureSpi})
+ * classes can be thought of as the "engine" -- providing the actual
+ * functionality of whatever cryptographic algorithm the instance
+ * represents.
+ *
+ * @see Provider
+ * @author Casey Marshall
+ */
+final class Engine
+{
+
+ // Constants.
+ // ------------------------------------------------------------------------
+
+ /** Prefix for aliases. */
+ private static final String ALG_ALIAS = "Alg.Alias.";
+
+ /** Maximum number of aliases to try. */
+ private static final int MAX_ALIASES = 5;
+
+ // Constructor.
+ // ------------------------------------------------------------------------
+
+ /** This class cannot be instantiated. */
+ private Engine() { }
+
+ // Class method.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Get the implementation for <i>algorithm</i> for service
+ * <i>service</i> from <i>provider</i>. The service is e.g.
+ * "Signature", and the algorithm "DSA".
+ *
+ * @param service The service name.
+ * @param algorithm The name of the algorithm to get.
+ * @param provider The provider to get the implementation from.
+ * @return The engine class for the specified algorithm; the object
+ * returned is typically a subclass of the SPI class for that
+ * service, but callers should check that this is so.
+ * @throws NoSuchAlgorithmException If the implementation cannot be
+ * found or cannot be instantiated.
+ * @throws IllegalArgumentException If any of the three arguments are null.
+ */
+ static Object
+ getInstance(String service, String algorithm, Provider provider)
+ throws NoSuchAlgorithmException
+ {
+ if (service == null || algorithm == null || provider == null)
+ throw new IllegalArgumentException();
+
+ // If there is no property "service.algorithm"
+ if (provider.getProperty(service + "." + algorithm) == null)
+ {
+ // Iterate through aliases, until we find the class name or resolve
+ // too many aliases.
+ String alias = null;
+ int count = 0;
+ while ((alias = provider.getProperty(
+ ALG_ALIAS + service + "." + algorithm)) != null)
+ {
+ if (algorithm.equals(alias)) // Refers to itself!
+ break;
+ algorithm = alias;
+ if (count++ > MAX_ALIASES)
+ throw new NoSuchAlgorithmException("too many aliases");
+ }
+ if (provider.getProperty(service + "." + algorithm) == null)
+ throw new NoSuchAlgorithmException(algorithm);
+ }
+
+ // Find and instantiate the implementation.
+ Class clazz = null;
+ ClassLoader loader = provider.getClass().getClassLoader();
+ String error = algorithm;
+ try
+ {
+ if (loader != null)
+ clazz = loader.loadClass(provider.getProperty(service+"."+algorithm));
+ else
+ clazz = Class.forName(provider.getProperty(service+"."+algorithm));
+ return clazz.newInstance();
+ }
+ catch (ClassNotFoundException cnfe)
+ {
+ error = "class not found: " + algorithm;
+ }
+ catch (IllegalAccessException iae)
+ {
+ error = "illegal access: " + iae.getMessage();
+ }
+ catch (InstantiationException ie)
+ {
+ error = "instantiation exception: " + ie.getMessage();
+ }
+ catch (ExceptionInInitializerError eiie)
+ {
+ error = "exception in initializer: " + eiie.getMessage();
+ }
+ catch (SecurityException se)
+ {
+ error = "security exception: " + se.getMessage();
+ }
+
+ throw new NoSuchAlgorithmException(error);
+ }
+}
Index: libjava/java/security/Identity.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/security/Identity.java,v
retrieving revision 1.3
diff -u -r1.3 Identity.java
--- libjava/java/security/Identity.java 4 Oct 2002 20:15:07 -0000 1.3
+++ libjava/java/security/Identity.java 19 Apr 2003 20:19:46 -0000
@@ -1,7 +1,7 @@
/* Identity.java --- Identity Class
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2003, Free Software Foundation, Inc.
- This file is part of GNU Classpath.
+This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -36,31 +36,36 @@
exception statement from your version. */
package java.security;
+
import java.io.Serializable;
import java.util.Vector;
/**
- The Identity class is used to repsent people and companies that
- can be authenticated using public key encryption. The identities
- can also be abstract objects such as smart cards.
-
- Identity object store a name and public key for each identity.
- The names cannot be changed and the identities can be scoped.
- Each identity (name and public key) within a scope is unique
- to that scope.
-
- Each identity has a set of ceritificates which all specify the
- same public key but not necessarily the same name.
-
- The Identity class can be subclassed to allow additional
- information to be attached to it.
-
- @since JDK 1.1
-
- @deprecated Use java.security.KeyStore, the java.security.cert
- package, and java.security.Principal.
-
- @author Mark Benvenuto
+ * <p>This class represents identities: real-world objects such as people,
+ * companies or organizations whose identities can be authenticated using their
+ * public keys. Identities may also be more abstract (or concrete) constructs,
+ * such as daemon threads or smart cards.</p>
+ *
+ * <p>All Identity objects have a <i>name</i> and a <i>public key</i>. Names
+ * are immutable. <i>Identities</i> may also be <b>scoped</b>. That is, if an
+ * <i>Identity</i> is specified to have a particular <i>scope</i>, then the
+ * <i>name</i> and <i>public key</i> of the <i>Identity</i> are unique within
+ * that <i>scope</i>.</p>
+ *
+ * <p>An <i>Identity</i> also has a <i>set of certificates</i> (all certifying
+ * its own <i>public key</i>). The <i>Principal</i> names specified in these
+ * certificates need not be the same, only the key.</p>
+ *
+ * <p>An <i>Identity</i> can be subclassed, to include postal and email
+ * addresses, telephone numbers, images of faces and logos, and so on.</p>
+ *
+ * @author Mark Benvenuto
+ * @see IdentityScope
+ * @see Signer
+ * @see Principal
+ * @deprecated This class is no longer used. Its functionality has been replaced
+ * by <code>java.security.KeyStore</code>, the <code>java.security.cert</code>
+ * package, and <code>java.security.Principal</code>.
*/
public abstract class Identity implements Principal, Serializable
{
@@ -72,22 +77,18 @@
private String info;
private Vector certificates;
- /**
- Creates a new instance of Identity from Serialized Data
- */
+ /** Constructor for serialization only. */
protected Identity()
{
}
/**
- Creates a new instance of Identity with the specified name
- and IdentityScope.
-
- @param name the name to use
- @param scope the scope to use
-
- @throws KeyManagementException if the identity is already
- present
+ * Constructs an identity with the specified name and scope.
+ *
+ * @param name the identity name.
+ * @param scope the scope of the identity.
+ * @throws KeyManagementException if there is already an identity with the
+ * same name in the scope.
*/
public Identity(String name, IdentityScope scope)
throws KeyManagementException
@@ -97,10 +98,9 @@
}
/**
- Creates a new instance of Identity with the specified name
- and no scope.
-
- @param name the name to use
+ * Constructs an identity with the specified name and no scope.
+ *
+ * @param name the identity name.
*/
public Identity(String name)
{
@@ -109,9 +109,9 @@
}
/**
- Gets the name for this Identity.
-
- @return the name
+ * Returns this identity's name.
+ *
+ * @return the name of this identity.
*/
public final String getName()
{
@@ -119,9 +119,9 @@
}
/**
- Gets the scope for this Identity.
-
- @return the scope
+ * Returns this identity's scope.
+ *
+ * @return the scope of this identity.
*/
public final IdentityScope getScope()
{
@@ -129,9 +129,10 @@
}
/**
- Gets the public key for this identity.
-
- @return the public key
+ * Returns this identity's public key.
+ *
+ * @return the public key for this identity.
+ * @see #setPublicKey(java.security.PublicKey)
*/
public PublicKey getPublicKey()
{
@@ -139,18 +140,21 @@
}
/**
- Sets the public key for this identity.
- The old key and all certificates are removed.
-
- This class checks the security manager with the call
- checkSecurityAccess with "setIdentityPublicKey".
-
- @param key the public key to use
-
- @throws KeyManagementException if this public key is used by
- another identity in the current scope.
- @throws SecurityException - if the security manager denies
- access to "setIdentityPublicKey"
+ * <p>Sets this identity's public key. The old key and all of this identity's
+ * certificates are removed by this operation.</p>
+ *
+ * <p>First, if there is a security manager, its <code>checkSecurityAccess()
+ * </code> method is called with <code>"setIdentityPublicKey"</code> as its
+ * argument to see if it's ok to set the public key.</p>
+ *
+ * @param key the public key for this identity.
+ * @throws KeyManagementException if another identity in the identity's scope
+ * has the same public key, or if another exception occurs.
+ * @throws SecurityException if a security manager exists and its
+ * <code>checkSecurityAccess()<code> method doesn't allow setting the public
+ * key.
+ * @see #getPublicKey()
+ * @see SecurityManager#checkSecurityAccess(String)
*/
public void setPublicKey(PublicKey key) throws KeyManagementException
{
@@ -162,15 +166,18 @@
}
/**
- Sets the general information string.
-
- This class checks the security manager with the call
- checkSecurityAccess with "setIdentityInfo".
-
- @param info the general information string.
-
- @throws SecurityException - if the security manager denies
- access to "setIdentityInfo"
+ * <p>Specifies a general information string for this identity.</p>
+ *
+ * <p>First, if there is a security manager, its <code>checkSecurityAccess()
+ * </code> method is called with <code>"setIdentityInfo"</code> as its
+ * argument to see if it's ok to specify the information string.</p>
+ *
+ * @param info the information string.
+ * @throws SecurityException if a security manager exists and its
+ * <code>checkSecurityAccess()</code> method doesn't allow setting the
+ * information string.
+ * @see #getInfo()
+ * @see SecurityManager#checkSecurityAccess(String)
*/
public void setInfo(String info)
{
@@ -182,9 +189,10 @@
}
/**
- Gets the general information string.
-
- @return the string
+ * Returns general information previously specified for this identity.
+ *
+ * @return general information about this identity.
+ * @see #setInfo(String)
*/
public String getInfo()
{
@@ -192,50 +200,54 @@
}
/**
- Adds a certificate to the list of ceritificates for this
- identity. The public key in this certificate must match the
- existing public key if it exists.
-
- This class checks the security manager with the call
- checkSecurityAccess with "addIdentityCertificate".
-
- @param certificate the certificate to add
-
- @throws KeyManagementException if the certificate is invalid
- or the public key conflicts
- @throws SecurityException - if the security manager denies
- access to "addIdentityCertificate"
+ * <p>Adds a certificate for this identity. If the identity has a public key,
+ * the public key in the certificate must be the same, and if the identity
+ * does not have a public key, the identity's public key is set to be that
+ * specified in the certificate.</p>
+ *
+ * <p>First, if there is a security manager, its <code>checkSecurityAccess()
+ * </code> method is called with <code>"addIdentityCertificate"</code> as its
+ * argument to see if it's ok to add a certificate.</p>
+ *
+ * @param certificate the certificate to be added.
+ * @throws KeyManagementException if the certificate is not valid, if the
+ * public key in the certificate being added conflicts with this identity's
+ * public key, or if another exception occurs.
+ * @throws SecurityException if a security manager exists and its
+ * <code>checkSecurityAccess()</code> method doesn't allow adding a
+ * certificate.
+ * @see SecurityManager#checkSecurityAccess(String)
*/
- public void addCertificate(java.security.Certificate certificate)
+ public void addCertificate(Certificate certificate)
throws KeyManagementException
{
SecurityManager sm = System.getSecurityManager();
if (sm != null)
sm.checkSecurityAccess("addIdentityCertificate");
- //Check public key of this certificate against the first one
- //in the vector
+ // Check public key of this certificate against the first one in the vector
if (certificates.size() > 0)
{
- if (((Certificate) certificates.firstElement()).getPublicKey() !=
- publicKey)
+ if (((Certificate) certificates.firstElement()).getPublicKey() != publicKey)
throw new KeyManagementException("Public key does not match");
}
certificates.addElement(certificate);
}
/**
- Removes a certificate from the list of ceritificates for this
- identity.
-
- This class checks the security manager with the call
- checkSecurityAccess with "removeIdentityCertificate".
-
- @param certificate the certificate to add
-
- @throws KeyManagementException if the certificate is invalid
- @throws SecurityException - if the security manager denies
- access to "removeIdentityCertificate"
+ * <p>Removes a certificate from this identity.</p>
+ *
+ * <p>First, if there is a security manager, its <code>checkSecurityAccess()
+ * </code> method is called with <code>"removeIdentityCertificate"</code> as
+ * its argument to see if it's ok to remove a certificate.</p>
+ *
+ * @param certificate the certificate to be removed.
+ * @throws KeyManagementException if the certificate is missing, or if
+ * another exception occurs.
+ * @throws SecurityException if a security manager exists and its
+ * <code>checkSecurityAccess()</code> method doesn't allow removing a
+ * certificate.
+ * @see SecurityManager#checkSecurityAccess(String)
*/
public void removeCertificate(Certificate certificate)
throws KeyManagementException
@@ -251,9 +263,9 @@
}
/**
- Returns an array of certificates for this identity.
-
- @returns array of certificates
+ * Returns a copy of all the certificates for this identity.
+ *
+ * @return a copy of all the certificates for this identity.
*/
public Certificate[] certificates()
{
@@ -261,16 +273,22 @@
int max = certificates.size();
for (int i = 0; i < max; i++)
certs[i] = (Certificate) certificates.elementAt(i);
+
return certs;
}
/**
- Checks for equality between this Identity and the specified
- object. If first checks if they are the same object, then
- if the name and scope matches and returns true if successful.
- If these tests fail, identityEquals is called.
-
- @return true if they are equal, false otherwise
+ * Tests for equality between the specified object and this identity. This
+ * first tests to see if the entities actually refer to the same object, in
+ * which case it returns <code>true</code>. Next, it checks to see if the
+ * entities have the same <i>name</i> and the same <i>scope</i>. If they do,
+ * the method returns <code>true</code>. Otherwise, it calls
+ * <code>identityEquals()</code>, which subclasses should override.
+ *
+ * @param identity the object to test for equality with this identity.
+ * @return <code>true</code> if the objects are considered equal, <code>false
+ * </code>otherwise.
+ * @see #identityEquals(Identity)
*/
public final boolean equals(Object identity)
{
@@ -289,11 +307,15 @@
}
/**
- Checks for equality between this Identity and the specified
- object. A subclass should override this method. The default
- behavior is to return true if the public key and names match.
-
- @return true if they are equal, false otherwise
+ * Tests for equality between the specified <code>identity</code> and this
+ * <i>identity</i>. This method should be overriden by subclasses to test for
+ * equality. The default behavior is to return <code>true</code> if the names
+ * and public keys are equal.
+ *
+ * @param identity the identity to test for equality with this identity.
+ * @return <code>true</code> if the identities are considered equal,
+ * <code>false</code> otherwise.
+ * @see #equals(Object)
*/
protected boolean identityEquals(Identity identity)
{
@@ -302,15 +324,19 @@
}
/**
- Returns a string representing this Identity.
-
- This class checks the security manager with the call
- checkSecurityAccess with "printIdentity".
-
- @returns a string representing this Identity.
-
- @throws SecurityException - if the security manager denies
- access to "printIdentity"
+ * <p>Returns a short string describing this identity, telling its name and
+ * its scope (if any).</p>
+ *
+ * <p>First, if there is a security manager, its <code>checkSecurityAccess()
+ * </code> method is called with <code>"printIdentity"</code> as its argument
+ * to see if it's ok to return the string.</p>
+ *
+ * @return information about this identity, such as its name and the name of
+ * its scope (if any).
+ * @throws SecurityException if a security manager exists and its
+ * <code>checkSecurityAccess()</code> method doesn't allow returning a string
+ * describing this identity.
+ * @see SecurityManager#checkSecurityAccess(String)
*/
public String toString()
{
@@ -323,18 +349,23 @@
}
/**
- Returns a detailed string representing this Identity.
-
- This class checks the security manager with the call
- checkSecurityAccess with "printIdentity".
-
- @param detailed indicates whether or not to provide detailed
- information
-
- @returns a string representing this Identity.
-
- @throws SecurityException - if the security manager denies
- access to "printIdentity"
+ * <p>Returns a string representation of this identity, with optionally more
+ * details than that provided by the <code>toString()</code> method without
+ * any arguments.</p>
+ *
+ * <p>First, if there is a security manager, its <code>checkSecurityAccess()
+ * </code> method is called with <code>"printIdentity"</code> as its argument
+ * to see if it's ok to return the string.</p>
+ *
+ * @param detailed whether or not to provide detailed information.
+ * @return information about this identity. If detailed is <code>true</code>,
+ * then this method returns more information than that provided by the
+ * <code>toString()</code> method without any arguments.
+ * @throws SecurityException if a security manager exists and its
+ * <code>checkSecurityAccess()</code> method doesn't allow returning a string
+ * describing this identity.
+ * @see #toString()
+ * @see SecurityManager#checkSecurityAccess(String)
*/
public String toString(boolean detailed)
{
@@ -355,9 +386,9 @@
}
/**
- Gets the hashcode for this Identity.
-
- @returns the hashcode
+ * Returns a hashcode for this identity.
+ *
+ * @return a hashcode for this identity.
*/
public int hashCode()
{
Index: libjava/java/security/IdentityScope.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/security/IdentityScope.java,v
retrieving revision 1.2
diff -u -r1.2 IdentityScope.java
--- libjava/java/security/IdentityScope.java 22 Jan 2002 22:40:30 -0000 1.2
+++ libjava/java/security/IdentityScope.java 19 Apr 2003 20:19:46 -0000
@@ -1,7 +1,7 @@
/* IdentityScope.java --- IdentityScope Class
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2003, Free Software Foundation, Inc.
- This file is part of GNU Classpath.
+This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -36,33 +36,46 @@
exception statement from your version. */
package java.security;
+
import java.util.Enumeration;
/**
- IdentityScope represents a scope of an identity. IdentityScope
- is also an Identity and can have a name and scope along with
- the other qualitites identities posses.
-
- An IdentityScope contains other Identity objects. All Identity
- objects are manipulated in the scope the same way. The scope
- is suppose to apply different scope to different type of
- Identities.
-
- No identity within the same scope can have the same public key.
-
- @since JDK 1.1
-
- @deprecated Use java.security.KeyStore, the java.security.cert
- package, and java.security.Principal.
-
- @author Mark Benvenuto
+ * <p>This class represents a scope for identities. It is an Identity itself,
+ * and therefore has a name and can have a scope. It can also optionally have a
+ * public key and associated certificates.</p>
+ *
+ * <p>An <code>IdentityScope</code> can contain { at link Identity} objects of all
+ * kinds, including { at link Signer}s. All types of <code>Identity</code> objects
+ * can be retrieved, added, and removed using the same methods. Note that it is
+ * possible, and in fact expected, that different types of identity scopes will
+ * apply different policies for their various operations on the various types of
+ * Identities.</p>
+ *
+ * <p>There is a one-to-one mapping between keys and identities, and there can
+ * only be one copy of one key per scope. For example, suppose Acme Software,
+ * Inc is a software publisher known to a user. Suppose it is an <i>Identity</i>,
+ * that is, it has a public key, and a set of associated certificates. It is
+ * named in the scope using the name "Acme Software". No other named <i>Identity
+ * </i> in the scope has the same public key. Of course, none has the same name
+ * as well.</p>
+ *
+ * @author Mark Benvenuto
+ * @see Identity
+ * @see Signer
+ * @see Principal
+ * @see Key
+ * @deprecated This class is no longer used. Its functionality has been replaced
+ * by <code>java.security.KeyStore</code>, the <code>java.security.cert</code>
+ * package, and <code>java.security.Principal</code>.
*/
public abstract class IdentityScope extends Identity
{
+ static final long serialVersionUID = -2337346281189773310L;
private static IdentityScope systemScope = null;
/**
- Creates a new instance of IdentityScope from Serialized Data
+ * This constructor is used for serialization only and should not be used by
+ * subclasses.
*/
protected IdentityScope()
{
@@ -70,10 +83,9 @@
}
/**
- Creates a new instance of IdentityScope with the specified name
- and no scope.
-
- @param name the name to use
+ * Constructs a new identity scope with the specified name.
+ *
+ * @param name the scope name.
*/
public IdentityScope(String name)
{
@@ -81,14 +93,12 @@
}
/**
- Creates a new instance of IdentityScope with the specified name
- and IdentityScope.
-
- @param name the name to use
- @param scope the scope to use
-
- @throws KeyManagementException if the identity scope is already
- present
+ * Constructs a new identity scope with the specified name and scope.
+ *
+ * @param name the scope name.
+ * @param scope the scope for the new identity scope.
+ * @throws KeyManagementException if there is already an identity with the
+ * same name in the scope.
*/
public IdentityScope(String name, IdentityScope scope)
throws KeyManagementException
@@ -97,7 +107,10 @@
}
/**
- Gets the system's Scope.
+ * Returns the system's identity scope.
+ *
+ * @return the system's identity scope.
+ * @see #setSystemScope(IdentityScope)
*/
public static IdentityScope getSystemScope()
{
@@ -110,15 +123,18 @@
}
/**
- Sets the scope of the system.
-
- This class checks the security manager with the call
- checkSecurityAccess with "setSystemScope".
-
- @param scope the new sustem scope
-
- @throws SecurityException - if the security manager denies
- access to "setSystemScope"
+ * <p>Sets the system's identity scope.</p>
+ *
+ * <p>First, if there is a security manager, its <code>checkSecurityAccess()
+ * </code> method is called with <code>"setSystemScope"</code> as its argument
+ * to see if it's ok to set the identity scope.</p>
+ *
+ * @param scope the scope to set.
+ * @throws SecurityException if a security manager exists and its
+ * <code>checkSecurityAccess()<code> method doesn't allow setting the
+ * identity scope.
+ * @see #getSystemScope()
+ * @see SecurityManager#checkSecurityAccess(String)
*/
protected static void setSystemScope(IdentityScope scope)
{
@@ -130,31 +146,29 @@
}
/**
- Gets the number of entries within this IdentityScope.
-
- @returns the number of entries
+ * Returns the number of identities within this identity scope.
+ *
+ * @return the number of identities within this identity scope.
*/
public abstract int size();
/**
- Gets the specified Identity within this scope
- by specified name.
-
- @param name name of Identity to get
-
- @returns an identity representing the name or null if it
- cannot be found
+ * Returns the identity in this scope with the specified name (if any).
+ *
+ * @param name the name of the identity to be retrieved.
+ * @return the identity named name, or <code>null</code> if there are no
+ * identities named name in this scope.
*/
public abstract Identity getIdentity(String name);
/**
- Gets the specified Identity within this scope
- by the specified Principal.
-
- @param principal The Principal of the Identity to get
-
- @returns an identity representing the principal or null if it
- cannot be found
+ * Retrieves the identity whose name is the same as that of the specified
+ * principal. (Note: <code>Identity</code> implements <code>Principal</code>.)
+ *
+ * @param principal the principal corresponding to the identity to be
+ * retrieved.
+ * @return the identity whose name is the same as that of the principal, or
+ * <code>null</code> if there are no identities of the same name in this scope.
*/
public Identity getIdentity(Principal principal)
{
@@ -162,55 +176,51 @@
}
/**
- Gets the specified Identity within this scope
- by the specified public key.
-
- @param key the PublicKey of the Identity to get
-
- @returns an identity representing the public key or null if it
- cannot be found
+ * Retrieves the identity with the specified public key.
+ *
+ * @param key the public key for the identity to be returned.
+ * @return the identity with the given key, or <code>null</code> if there are
+ * no identities in this scope with that key.
*/
public abstract Identity getIdentity(PublicKey key);
/**
- Adds an identity to his scope.
-
- @param identity the identity to add
-
- @throws KeyManagementException if it is an invalid identity,
- an identity with the same key exists, or another error
- occurs.
+ * Adds an identity to this identity scope.
+ *
+ * @param identity the identity to be added.
+ * @throws KeyManagementException if the identity is not valid, a name
+ * conflict occurs, another identity has the same public key as the identity
+ * being added, or another exception occurs.
*/
public abstract void addIdentity(Identity identity)
throws KeyManagementException;
/**
- Removes an identity to his scope.
-
- @param identity the identity to remove
-
- @throws KeyManagementException if it is a missing identity,
- or another error occurs.
+ * Removes an identity from this identity scope.
+ *
+ * @param identity the identity to be removed.
+ * @throws KeyManagementException if the identity is missing, or another
+ * exception occurs.
*/
public abstract void removeIdentity(Identity identity)
throws KeyManagementException;
/**
- Returns an Enumeration of identities.
-
- @returns an enumeration of the identities.
+ * Returns an enumeration of all identities in this identity scope.
+ *
+ * @return an enumeration of all identities in this identity scope.
*/
public abstract Enumeration identities();
/**
- Returns a string representing this IdentityScope.
- It includes the name, the scope name, and number of identities.
-
- @returns a string representing this IdentityScope.
+ * Returns a string representation of this identity scope, including its name,
+ * its scope name, and the number of identities in this identity scope.
+ *
+ * @return a string representation of this identity scope.
+ * @see SecurityManager#checkSecurityAccess(String)
*/
public String toString()
{
- return (super.getName() + " " + super.getScope().getName()
- + " " + size());
+ return (super.getName() + " " + super.getScope().getName() + " " + size());
}
}
Index: libjava/java/security/KeyFactory.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/security/KeyFactory.java,v
retrieving revision 1.2
diff -u -r1.2 KeyFactory.java
--- libjava/java/security/KeyFactory.java 22 Jan 2002 22:40:30 -0000 1.2
+++ libjava/java/security/KeyFactory.java 19 Apr 2003 20:19:46 -0000
@@ -1,5 +1,5 @@
/* KeyFactory.java --- Key Factory Class
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -36,37 +36,67 @@
exception statement from your version. */
package java.security;
+
import java.security.spec.KeySpec;
import java.security.spec.InvalidKeySpecException;
+import java.security.NoSuchAlgorithmException;
/**
- Key factories are used to convert keys (opaque cryptographic
- keys of type Key) into key specifications (transparent
- representations of the underlying key material).
-
- Key factories are bi-directional. They allow a key class
- to be converted into a key specification (key material) and
- back again.
-
- For example DSA public keys can be specified as
- DSAPublicKeySpec or X509EncodedKeySpec. The key factory
- translate these key specifications.
-
- @since JDK 1.2
+ * <p>Key factories are used to convert keys (opaque cryptographic keys of type
+ * { at link Key}) into key specifications (transparent representations of the
+ * underlying key material), and vice versa.</p>
+ *
+ * <p>Key factories are bi-directional. That is, they allow you to build an
+ * opaque key object from a given key specification (key material), or to
+ * retrieve the underlying key material of a key object in a suitable format.</p>
+ *
+ * <p>Multiple compatible key specifications may exist for the same key. For
+ * example, a <i>DSA</i> public key may be specified using { at link
+ * java.security.spec.DSAPublicKeySpec} or { at link
+ * java.security.spec.X509EncodedKeySpec}. A key factory can be used to
+ * translate between compatible key specifications.</p>
+ *
+ * <p>The following is an example of how to use a key factory in order to
+ * instantiate a <i>DSA</i> public key from its encoding. Assume Alice has
+ * received a digital signature from Bob. Bob also sent her his public key (in
+ * encoded format) to verify his signature. Alice then performs the following
+ * actions:
+ *
+ * <pre>
+ * X509EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec(bobEncodedPubKey);
+ * KeyFactory keyFactory = KeyFactory.getInstance("DSA");
+ * PublicKey bobPubKey = keyFactory.generatePublic(bobPubKeySpec);
+ * Signature sig = Signature.getInstance("DSA");
+ * sig.initVerify(bobPubKey);
+ * sig.update(data);
+ * sig.verify(signature);
+ * </pre>
+ *
+ * @since 1.2
+ * @see Key
+ * @see PublicKey
+ * @see PrivateKey
+ * @see KeySpec
+ * @see java.security.spec.DSAPublicKeySpec
+ * @see java.security.spec.X509EncodedKeySpec
@author Mark Benvenuto
*/
public class KeyFactory
{
+ /** The service name for key factories. */
+ private static final String KEY_FACTORY = "KeyFactory";
+
private KeyFactorySpi keyFacSpi;
private Provider provider;
private String algorithm;
/**
- Constructs a new keyFactory with the specified parameters.
-
- @param keyFacSpi Key Factory SPI to use
- @param provider the provider of the Key Factory SPI
- @param algorithm the name of the key algorithm for this key factory
+ * Creates a <code>KeyFactory</code> object.
+ *
+ * @param keyFacSpi the delegate.
+ * @param provider the provider.
+ * @param algorithm the name of the algorithm to associate with this
+ * <code>KeyFactory</code>.
*/
protected KeyFactory(KeyFactorySpi keyFacSpi, Provider provider,
String algorithm)
@@ -76,85 +106,102 @@
this.algorithm = algorithm;
}
- /**
- Gets an instance of the KeyFactory class representing
- the specified key factory. If the algorithm is not
- found then, it throws NoSuchAlgorithmException.
-
- @param algorithm the name of algorithm to choose
- @return a KeyFactory repesenting the desired algorithm
-
- @throws NoSuchAlgorithmException if the algorithm is not implemented by providers
+ /**
+ * Generates a <code>KeyFactory</code> object that implements the specified
+ * algorithm. If the default provider package provides an implementation of
+ * the requested algorithm, an instance of <code>KeyFactory</code> containing
+ * that implementation is returned. If the algorithm is not available in the
+ * default package, other packages are searched.
+ *
+ * @param algorithm the name of the requested key algorithm. See Appendix A
+ * in the Java Cryptography Architecture API Specification & Reference
+ * for information about standard algorithm names.
+ * @return a <code>KeyFactory</code> object for the specified algorithm.
+ * @throws NoSuchAlgorithmException if the requested algorithm is not
+ * available in the default provider package or any of the other provider
+ * packages that were searched.
*/
public static KeyFactory getInstance(String algorithm)
throws NoSuchAlgorithmException
{
Provider[] p = Security.getProviders();
-
for (int i = 0; i < p.length; i++)
- {
- String classname = p[i].getProperty("KeyFactory." + algorithm);
- if (classname != null)
- return getInstance(classname, algorithm, p[i]);
- }
+ try
+ {
+ return getInstance(algorithm, p[i]);
+ }
+ catch (NoSuchAlgorithmException ignored) {}
throw new NoSuchAlgorithmException(algorithm);
}
- /**
- Gets an instance of the KeyFactory class representing
- the specified key factory from the specified provider.
- If the algorithm is not found then, it throws
- NoSuchAlgorithmException. If the provider is not found, then
- it throws NoSuchProviderException.
-
- @param algorithm the name of algorithm to choose
- @param provider the name of the provider to find the algorithm in
- @return a KeyFactory repesenting the desired algorithm
-
- @throws NoSuchAlgorithmException if the algorithm is not implemented by the provider
- @throws NoSuchProviderException if the provider is not found
+ /**
+ * Generates a <code>KeyFactory</code> object for the specified algorithm
+ * from the specified provider.
+ *
+ * @param algorithm the name of the requested key algorithm. See Appendix A
+ * in the Java Cryptography Architecture API Specification & Reference
+ * for information about standard algorithm names.
+ * @param provider the name of the provider.
+ * @return a <code>KeyFactory</code> object for the specified algorithm.
+ * @throws NoSuchAlgorithmException if the algorithm is not available from
+ * the specified provider.
+ * @throws NoSuchProviderException if the provider has not been configured.
+ * @throws IllegalArgumentException if the provider name is null or empty.
+ * @see Provider
*/
public static KeyFactory getInstance(String algorithm, String provider)
throws NoSuchAlgorithmException, NoSuchProviderException
{
+ if (provider == null || provider.length() == 0)
+ throw new IllegalArgumentException("Illegal provider");
+
Provider p = Security.getProvider(provider);
if (p == null)
throw new NoSuchProviderException();
- return getInstance(p.getProperty("KeyFactory." + algorithm),
- algorithm, p);
+ return getInstance(algorithm, p);
}
- private static KeyFactory getInstance(String classname,
- String algorithm,
- Provider provider)
+ /**
+ * Generates a <code>KeyFactory</code> object for the specified algorithm from
+ * the specified provider. Note: the <code>provider</code> doesn't have to be
+ * registered.
+ *
+ * @param algorithm the name of the requested key algorithm. See Appendix A
+ * in the Java Cryptography Architecture API Specification & Reference for
+ * information about standard algorithm names.
+ * @param provider the provider.
+ * @return a <code>KeyFactory</code> object for the specified algorithm.
+ * @throws NoSuchAlgorithmException if the algorithm is not available from
+ * the specified provider.
+ * @throws IllegalArgumentException if the <code>provider</code> is
+ * <code>null</code>.
+ * @since 1.4
+ * @see Provider
+ */
+ public static KeyFactory getInstance(String algorithm, Provider provider)
throws NoSuchAlgorithmException
{
+ if (provider == null)
+ throw new IllegalArgumentException("Illegal provider");
try
{
- return new KeyFactory((KeyFactorySpi) Class.forName(classname).
- newInstance(), provider, algorithm);
- }
- catch (ClassNotFoundException cnfe)
- {
- throw new NoSuchAlgorithmException("Class not found");
+ return new KeyFactory((KeyFactorySpi)
+ Engine.getInstance(KEY_FACTORY, algorithm, provider),
+ provider, algorithm);
}
- catch (InstantiationException ie)
+ catch (ClassCastException cce)
{
- throw new NoSuchAlgorithmException("Class instantiation failed");
- }
- catch (IllegalAccessException iae)
- {
- throw new NoSuchAlgorithmException("Illegal Access");
- }
+ throw new NoSuchAlgorithmException(algorithm);
+ }
}
/**
- Gets the provider that the class is from.
-
- @return the provider of this class
+ * Returns the provider of this key factory object.
+ *
+ * @return the provider of this key factory object.
*/
public final Provider getProvider()
{
@@ -162,9 +209,10 @@
}
/**
- Returns the name of the algorithm used
-
- @return A string with the name of the algorithm
+ * Gets the name of the algorithm associated with this <code>KeyFactory</code>.
+ *
+ * @return the name of the algorithm associated with this
+ * <code>KeyFactory</code>.
*/
public final String getAlgorithm()
{
@@ -172,52 +220,51 @@
}
/**
- Generates a public key from the provided key specification.
-
- @param keySpec key specification
-
- @return the public key
-
- @throws InvalidKeySpecException invalid key specification for
- this key factory to produce a public key
+ * Generates a public key object from the provided key specification (key
+ * material).
+ *
+ * @param keySpec the specification (key material) of the public key.
+ * @return the public key.
+ * @throws InvalidKeySpecException if the given key specification is
+ * inappropriate for this key factory to produce a public key.
*/
- public final PublicKey generatePublic(KeySpec keySpec) throws
- InvalidKeySpecException
+ public final PublicKey generatePublic(KeySpec keySpec)
+ throws InvalidKeySpecException
{
return keyFacSpi.engineGeneratePublic(keySpec);
}
/**
- Generates a private key from the provided key specification.
-
- @param keySpec key specification
-
- @return the private key
-
- @throws InvalidKeySpecException invalid key specification for
- this key factory to produce a private key
+ * Generates a private key object from the provided key specification (key
+ * material).
+ *
+ * @param keySpec the specification (key material) of the private key.
+ * @return the private key.
+ * @throws InvalidKeySpecException if the given key specification is
+ * inappropriate for this key factory to produce a private key.
*/
- public final PrivateKey generatePrivate(KeySpec keySpec) throws
- InvalidKeySpecException
+ public final PrivateKey generatePrivate(KeySpec keySpec)
+ throws InvalidKeySpecException
{
return keyFacSpi.engineGeneratePrivate(keySpec);
}
/**
- Returns a key specification for the given key. keySpec
- identifies the specification class to return the key
- material in.
-
- @param key the key
- @param keySpec the specification class to return the
- key material in.
-
- @return the key specification in an instance of the requested
- specification class
-
- @throws InvalidKeySpecException the requested key specification
- is inappropriate for this key or the key is
- unrecognized.
+ * Returns a specification (key material) of the given key object.
+ * <code>keySpec</code> identifies the specification class in which the key
+ * material should be returned. It could, for example, be
+ * <code>DSAPublicKeySpec.class</code>, to indicate that the key material
+ * should be returned in an instance of the { at link
+ * java.security.spec.DSAPublicKeySpec} class.
+ *
+ * @param key the key.
+ * @param keySpec the specification class in which the key material should be
+ * returned.
+ * @return the underlying key specification (key material) in an instance of
+ * the requested specification class.
+ * @throws InvalidKeySpecException if the requested key specification is
+ * inappropriate for the given key, or the given key cannot be processed
+ * (e.g., the given key has an unrecognized algorithm or format).
*/
public final KeySpec getKeySpec(Key key, Class keySpec)
throws InvalidKeySpecException
@@ -226,15 +273,13 @@
}
/**
- Translates the key from an unknown or untrusted provider
- into a key for this key factory.
-
- @param the key from an unknown or untrusted provider
-
- @return the translated key
-
- @throws InvalidKeySpecException if the key cannot be
- processed by this key factory
+ * Translates a key object, whose provider may be unknown or potentially
+ * untrusted, into a corresponding key object of this key factory.
+ *
+ * @param key the key whose provider is unknown or untrusted.
+ * @return the translated key.
+ * @throws InvalidKeyException if the given key cannot be processed by this
+ * key factory.
*/
public final Key translateKey(Key key) throws InvalidKeyException
{
Index: libjava/java/security/KeyPairGenerator.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/security/KeyPairGenerator.java,v
retrieving revision 1.4
diff -u -r1.4 KeyPairGenerator.java
--- libjava/java/security/KeyPairGenerator.java 17 Nov 2002 00:10:24 -0000 1.4
+++ libjava/java/security/KeyPairGenerator.java 19 Apr 2003 20:19:46 -0000
@@ -1,5 +1,5 @@
/* KeyPairGenerator.java --- Key Pair Generator Class
- Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -40,25 +40,94 @@
import java.security.spec.AlgorithmParameterSpec;
/**
- KeyPairGenerator is the class used to generate key pairs
- for a security algorithm.
-
- The KeyPairGenerator is created with the getInstance()
- methods. The class is used to generate public and private
- keys for an algorithm and associate it with
- algorithm parameters.
-
- @author Mark Benvenuto
+ * <p>The <code>KeyPairGenerator</code> class is used to generate pairs of
+ * public and private keys. Key pair generators are constructed using the
+ * <code>getInstance()</code> factory methods (static methods that return
+ * instances of a given class).</p>
+ *
+ * <p>A Key pair generator for a particular algorithm creates a public/private
+ * key pair that can be used with this algorithm. It also associates
+ * algorithm-specific parameters with each of the generated keys.</p>
+ *
+ * <p>There are two ways to generate a key pair: in an algorithm-independent
+ * manner, and in an algorithm-specific manner. The only difference between the
+ * two is the initialization of the object:</p>
+ *
+ * <ul>
+ * <li><b>Algorithm-Independent Initialization</b><br/>
+ * All key pair generators share the concepts of a <i>keysize</i> and a
+ * <i>source of randomness</i>. The <i>keysize</i> is interpreted differently
+ * for different algorithms (e.g., in the case of the <i>DSA</i> algorithm,
+ * the <i>keysize</i> corresponds to the length of the modulus). There is an
+ * <code>initialize()</code> method in this <code>KeyPairGenerator</code>
+ * class that takes these two universally shared types of arguments. There
+ * is also one that takes just a <i>keysize</i> argument, and uses the
+ * { at link SecureRandom} implementation of the highest-priority installed
+ * provider as the <i>source of randomness</i>. (If none of the installed
+ * providers supply an implementation of { at link SecureRandom}, a
+ * system-provided source of randomness is used.)<br/><br/>
+ *
+ * Since no other parameters are specified when you call the above
+ * algorithm-independent initialize methods, it is up to the provider what
+ * to do about the algorithm-specific parameters (if any) to be associated
+ * with each of the keys.<br/><br/>
+ *
+ * If the algorithm is the <i>DSA</i> algorithm, and the <i>keysize</i>
+ * (modulus size) is <code>512</code>, <code>768</code>, or <code>1024</code>,
+ * then the <b>GNU</b> provider uses a set of precomputed values for the
+ * <code>p</code>, <code>q</code>, and <code>g</code> parameters. If the
+ * <i>modulus size</i> is not one of the above values, the <b>GNU</b>
+ * provider creates a new set of parameters. Other providers might have
+ * precomputed parameter sets for more than just the three modulus sizes
+ * mentioned above. Still others might not have a list of precomputed
+ * parameters at all and instead always create new parameter sets.<br/></li>
+ *
+ * <li><b>Algorithm-Specific Initialization</b><br/>
+ * For situations where a set of algorithm-specific parameters already
+ * exists (e.g., so-called <i>community parameters</i> in <i>DSA</i>), there
+ * are two initialize methods that have an { at link AlgorithmParameterSpec}
+ * argument. One also has a { at link SecureRandom} argument, while the the
+ * other uses the { at link SecureRandom} implementation of the highest-priority
+ * installed provider as the source of randomness. (If none of the installed
+ * providers supply an implementation of { at link SecureRandom}, a
+ * system-provided source of randomness is used.)</li>
+ * </ul>
+ *
+ * <p>In case the client does not explicitly initialize the
+ * <code>KeyPairGenerator</code> (via a call to an initialize method), each
+ * provider must supply (and document) a default initialization. For example,
+ * the <b>GNU</b> provider uses a default modulus size (keysize) of
+ * <code>1024</code> bits.</p>
+ *
+ * <p>Note that this class is abstract and extends from { at link
+ * KeyPairGeneratorSpi} for historical reasons. Application developers should
+ * only take notice of the methods defined in this <code>KeyPairGenerator</code>
+ * class; all the methods in the superclass are intended for cryptographic
+ * service providers who wish to supply their own implementations of key pair
+ * generators.</p>
+ *
+ * @see Signature
+ * @see KeyPair
+ * @see AlgorithmParameterSpec
+ * @author Mark Benvenuto
+ * @author Casey Marshall
*/
public abstract class KeyPairGenerator extends KeyPairGeneratorSpi
{
+ /** The service name for key pair generators. */
+ private static final String KEY_PAIR_GENERATOR = "KeyPairGenerator";
+
Provider provider;
private String algorithm;
/**
- Constructs a new KeyPairGenerator
-
- @param algorithm the algorithm to use
+ * Creates a <code>KeyPairGenerator</code> object for the specified
+ * algorithm.
+ *
+ * @param algorithm the standard string name of the algorithm.
+ * See Appendix A in the Java Cryptography Architecture API
+ * Specification & Reference for information about standard
+ * algorithm names.
*/
protected KeyPairGenerator(String algorithm)
{
@@ -67,55 +136,65 @@
}
/**
- Returns the name of the algorithm used
-
- @return A string with the name of the algorithm
+ * Returns the standard name of the algorithm for this key pair generator.
+ * See Appendix A in the Java Cryptography Architecture API Specification
+ * & Reference for information about standard algorithm names.
+ *
+ * @return the standard string name of the algorithm.
*/
public String getAlgorithm()
{
return algorithm;
}
- /**
- Gets an instance of the KeyPairGenerator class
- which generates key pairs for the specified algorithm.
- If the algorithm is not found then, it throws NoSuchAlgorithmException.
-
- @param algorithm the name of algorithm to choose
- @return a AlgorithmParameterGenerator repesenting the desired algorithm
-
- @throws NoSuchAlgorithmException if the algorithm is not implemented by
- providers
+ /**
+ * Generates a <code>KeyPairGenerator</code> object that implements the
+ * specified digest algorithm. If the default provider package provides an
+ * implementation of the requested digest algorithm, an instance of
+ * <code>KeyPairGenerator</code> containing that implementation is returned.
+ * If the algorithm is not available in the default package, other packages
+ * are searched.
+ *
+ * @param algorithm the standard string name of the algorithm. See Appendix A
+ * in the Java Cryptography Architecture API Specification & Reference for
+ * information about standard algorithm names.
+ * @return the new <code>KeyPairGenerator</code> object.
+ * @throws NoSuchAlgorithmException if the algorithm is not available in the
+ * environment.
*/
- public static KeyPairGenerator getInstance(String algorithm) throws
- NoSuchAlgorithmException
+ public static KeyPairGenerator getInstance(String algorithm)
+ throws NoSuchAlgorithmException
{
Provider[] p = Security.getProviders();
-
for (int i = 0; i < p.length; i++)
{
- try
- {
- return getInstance(algorithm, p[i]);
+ try
+ {
+ return getInstance(algorithm, p[i]);
}
- catch (NoSuchAlgorithmException ignored) {}
+ catch (NoSuchAlgorithmException ignored) {}
}
throw new NoSuchAlgorithmException(algorithm);
}
- /**
- Gets an instance of the KeyPairGenerator class
- which generates key pairs for the specified algorithm.
- If the algorithm is not found then, it throws NoSuchAlgorithmException.
-
- @param algorithm the name of algorithm to choose
- @param provider the name of the provider to find the algorithm in
- @return a AlgorithmParameterGenerator repesenting the desired algorithm
-
- @throws NoSuchAlgorithmException if the algorithm is not implemented by
- the provider
- @throws NoSuchProviderException if the provider is not found
+ /**
+ * Generates a <code>KeyPairGenerator</code> object implementing the
+ * specified algorithm, as supplied from the specified provider, if
+ * such an algorithm is available from the provider.
+ *
+ * @param algorithm the standard string name of the algorithm. See
+ * Appendix A in the Java Cryptography Architecture API Specification
+ * & Reference for information about standard algorithm names.
+ * @param provider the string name of the provider.
+ * @return the new <code>KeyPairGenerator</code> object.
+ * @throws NoSuchAlgorithmException if the algorithm is not available
+ * from the provider.
+ * @throws NoSuchProviderException if the provider is not available in the
+ * environment.
+ * @throws IllegalArgumentException if the provider name is <code>null</code>
+ * or empty.
+ * @see Provider
*/
public static KeyPairGenerator getInstance(String algorithm, String provider)
throws NoSuchAlgorithmException, NoSuchProviderException
@@ -127,69 +206,50 @@
return getInstance(algorithm, p);
}
- private static KeyPairGenerator getInstance(String algorithm, Provider p)
- throws NoSuchAlgorithmException
- {
- // try the name as is
- String className = p.getProperty("KeyPairGenerator." + algorithm);
- if (className == null) { // try all uppercase
- String upper = algorithm.toUpperCase();
- className = p.getProperty("KeyPairGenerator." + upper);
- if (className == null) { // try if it's an alias
- String alias = p.getProperty("Alg.Alias.KeyPairGenerator." + algorithm);
- if (alias == null) { // try all-uppercase alias name
- alias = p.getProperty("Alg.Alias.KeyPairGenerator." + upper);
- if (alias == null) { // spit the dummy
- throw new NoSuchAlgorithmException(algorithm);
- }
- }
- className = p.getProperty("KeyPairGenerator." + alias);
- if (className == null) {
- throw new NoSuchAlgorithmException(algorithm);
- }
- }
- }
- return getInstance(className, algorithm, p);
- }
-
- private static KeyPairGenerator getInstance(String classname,
- String algorithm,
- Provider provider)
+ /**
+ * Generates a <code>KeyPairGenerator</code> object implementing the specified
+ * algorithm, as supplied from the specified provider, if such an algorithm is
+ * available from the provider. Note: the provider doesn't have to be
+ * registered.
+ *
+ * @param algorithm the standard string name of the algorithm. See Appendix A
+ * in the Java Cryptography Architecture API Specification & Reference for
+ * information about standard algorithm names.
+ * @param provider the provider.
+ * @return the new <code>KeyPairGenerator</code> object.
+ * @throws NoSuchAlgorithmException if the <code>algorithm</code> is not
+ * available from the <code>provider</code>.
+ * @throws IllegalArgumentException if the <code>provider</code> is
+ * <code>null</code>.
+ * @since 1.4
+ * @see Provider
+ */
+ public static KeyPairGenerator getInstance(String algorithm,
+ Provider provider)
throws NoSuchAlgorithmException
{
- try
- {
- Object o = Class.forName(classname).newInstance();
- KeyPairGenerator kpg;
- if (o instanceof KeyPairGeneratorSpi)
- kpg = new DummyKeyPairGenerator((KeyPairGeneratorSpi) o, algorithm);
- else
- {
- kpg = (KeyPairGenerator) o;
- kpg.algorithm = algorithm;
- }
+ if (provider == null)
+ throw new IllegalArgumentException("Illegal provider");
- kpg.provider = provider;
- return kpg;
- }
- catch (ClassNotFoundException cnfe)
+ Object o = Engine.getInstance(KEY_PAIR_GENERATOR, algorithm, provider);
+ KeyPairGenerator result = null;
+ if (o instanceof KeyPairGeneratorSpi)
{
- throw new NoSuchAlgorithmException("Class not found");
+ result = new DummyKeyPairGenerator((KeyPairGeneratorSpi) o, algorithm);
}
- catch (InstantiationException ie)
+ else if (o instanceof KeyPairGenerator)
{
- throw new NoSuchAlgorithmException("Class instantiation failed");
- }
- catch (IllegalAccessException iae)
- {
- throw new NoSuchAlgorithmException("Illegal Access");
+ result = (KeyPairGenerator) o;
+ result.algorithm = algorithm;
}
+ result.provider = provider;
+ return result;
}
/**
- Gets the provider that the class is from.
-
- @return the provider of this class
+ * Returns the provider of this key pair generator object.
+ *
+ * @return the provider of this key pair generator object.
*/
public final Provider getProvider()
{
@@ -197,11 +257,16 @@
}
/**
- Initializes the KeyPairGenerator for the specified key size.
- (Since no source of randomness is specified, a default one is
- provided.)
-
- @param keysize Size of key to generate
+ * Initializes the key pair generator for a certain keysize using a default
+ * parameter set and the { at link SecureRandom} implementation of the
+ * highest-priority installed provider as the source of randomness. (If none
+ * of the installed providers supply an implementation of { at link SecureRandom},
+ * a system-provided source of randomness is used.)
+ *
+ * @param keysize the keysize. This is an algorithm-specific metric, such as
+ * modulus length, specified in number of bits.
+ * @throws InvalidParameterException if the keysize is not supported by this
+ * <code>KeyPairGenerator</code> object.
*/
public void initialize(int keysize)
{
@@ -209,13 +274,15 @@
}
/**
- Initializes the KeyPairGenerator for the specified key size
- and specified SecureRandom.
-
- @param keysize Size of key to generate
- @param random SecureRandom to use
-
- @since JDK 1.2
+ * Initializes the key pair generator for a certain keysize with the given
+ * source of randomness (and a default parameter set).
+ *
+ * @param keysize the keysize. This is an algorithm-specific metric, such as
+ * modulus length, specified in number of bits.
+ * @param random the source of randomness.
+ * @throws InvalidParameterException if the <code>keysize</code> is not
+ * supported by this <code>KeyPairGenerator</code> object.
+ * @since 1.2
*/
public void initialize(int keysize, SecureRandom random)
{
@@ -223,14 +290,25 @@
}
/**
- Initializes the KeyPairGenerator with the specified
- AlgorithmParameterSpec class.
- (Since no source of randomness is specified, a default one is
- provided.)
-
- @param params AlgorithmParameterSpec to initialize with
-
- @since JDK 1.2
+ * <p>Initializes the key pair generator using the specified parameter set and
+ * the { at link SecureRandom} implementation of the highest-priority installed
+ * provider as the source of randomness. (If none of the installed providers
+ * supply an implementation of { at link SecureRandom}, a system-provided source
+ * of randomness is used.)</p>
+ *
+ * <p>This concrete method has been added to this previously-defined abstract
+ * class. This method calls the
+ * { at link KeyPairGeneratorSpi#initialize(AlgorithmParameterSpec, SecureRandom)}
+ * initialize method, passing it <code>params</code> and a source of
+ * randomness (obtained from the highest-priority installed provider or
+ * system-provided if none of the installed providers supply one). That
+ * initialize method always throws an { at link UnsupportedOperationException}
+ * if it is not overridden by the provider.</p>
+ *
+ * @param params the parameter set used to generate the keys.
+ * @throws InvalidAlgorithmParameterException if the given parameters are
+ * inappropriate for this key pair generator.
+ * @since 1.2
*/
public void initialize(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException
@@ -239,13 +317,21 @@
}
/**
- Initializes the KeyPairGenerator with the specified
- AlgorithmParameterSpec class and specified SecureRandom.
-
- @param params AlgorithmParameterSpec to initialize with
- @param random SecureRandom to use
-
- @since JDK 1.2
+ * <p>Initializes the key pair generator with the given parameter set and
+ * source of randomness.</p>
+ *
+ * <p>This concrete method has been added to this previously-defined abstract
+ * class. This method calls the
+ * { at link KeyPairGeneratorSpi#initialize(AlgorithmParameterSpec, SecureRandom)}
+ * initialize method, passing it <code>params</code> and <code>random</code>.
+ * That initialize method always throws an { at link UnsupportedOperationException}
+ * if it is not overridden by the provider.</p>
+ *
+ * @param params the parameter set used to generate the keys.
+ * @param random the source of randomness.
+ * @throws InvalidAlgorithmParameterException if the given parameters are
+ * inappropriate for this key pair generator.
+ * @since 1.2
*/
public void initialize(AlgorithmParameterSpec params, SecureRandom random)
throws InvalidAlgorithmParameterException
@@ -254,36 +340,45 @@
}
/**
- Generates a KeyPair according the rules for the algorithm.
- Unless intialized, algorithm defaults will be used. It
- creates a unique key pair each time.
-
- Same as generateKeyPair();
-
- @return a key pair
+ * <p>Generates a key pair.</p>
+ *
+ * <p>If this <code>KeyPairGenerator</code> has not been initialized
+ * explicitly, provider-specific defaults will be used for the size and other
+ * (algorithm-specific) values of the generated keys.</p>
+ *
+ * <p>This will generate a new key pair every time it is called.</p>
+ *
+ * <p>This method is functionally equivalent to { at link #generateKeyPair()}.</p>
+ *
+ * @return the generated key pair.
+ * @since 1.2
*/
public final KeyPair genKeyPair()
{
try
{
- return getInstance("DSA", "GNU").generateKeyPair();
+ return getInstance("DSA", "GNU").generateKeyPair();
}
catch (Exception e)
{
- System.err.println("genKeyPair failed: " + e);
- e.printStackTrace();
- return null;
+ System.err.println("genKeyPair failed: " + e);
+ e.printStackTrace();
+ return null;
}
}
/**
- Generates a KeyPair according the rules for the algorithm.
- Unless intialized, algorithm defaults will be used. It
- creates a unique key pair each time.
-
- Same as genKeyPair();
-
- @return a key pair
+ * <p>Generates a key pair.</p>
+ *
+ * <p>If this <code>KeyPairGenerator</code> has not been initialized
+ * explicitly, provider-specific defaults will be used for the size and other
+ * (algorithm-specific) values of the generated keys.</p>
+ *
+ * <p>This will generate a new key pair every time it is called.</p>
+ *
+ * <p>This method is functionally equivalent to { at link #genKeyPair()}.</p>
+ *
+ * @return the generated key pair.
*/
public KeyPair generateKeyPair()
{
Index: libjava/java/security/KeyStore.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/security/KeyStore.java,v
retrieving revision 1.3
diff -u -r1.3 KeyStore.java
--- libjava/java/security/KeyStore.java 18 Nov 2002 18:09:35 -0000 1.3
+++ libjava/java/security/KeyStore.java 19 Apr 2003 20:19:46 -0000
@@ -1,5 +1,5 @@
/* KeyStore.java --- Key Store Class
- Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -44,37 +44,52 @@
import java.util.Enumeration;
/**
- Keystore represents an in-memory collection of keys and
- certificates. There are two types of entries:
-
- * Key Entry
-
- This type of keystore entry store sensitive crytographic key
- information in a protected format.Typically this is a secret
- key or a private key with a certificate chain.
-
-
- * Trusted Ceritificate Entry
-
- This type of keystore entry contains a single public key
- certificate belonging to annother entity. It is called trusted
- because the keystore owner trusts that the certificates
- belongs to the subject (owner) of the certificate.
-
- The keystore contains an "alias" string for each entry.
-
- The structure and persistentence of the key store is not
- specified. Any method could be used to protect sensitive
- (private or secret) keys. Smart cards or integrated
- cryptographic engines could be used or the keystore could
- be simply stored in a file.
+ * Keystore represents an in-memory collection of keys and
+ * certificates. There are two types of entries:
+ *
+ * <dl>
+ * <dt>Key Entry</dt>
+ *
+ * <dd><p>This type of keystore entry store sensitive crytographic key
+ * information in a protected format.Typically this is a secret
+ * key or a private key with a certificate chain.</p></dd>
+ *
+ * <dt>Trusted Ceritificate Entry</dt>
+ *
+ * <dd><p>This type of keystore entry contains a single public key
+ * certificate belonging to annother entity. It is called trusted
+ * because the keystore owner trusts that the certificates
+ * belongs to the subject (owner) of the certificate.</p></dd>
+ * </dl>
+ *
+ * <p>Entries in a key store are referred to by their "alias": a simple
+ * unique string.
+ *
+ * <p>The structure and persistentence of the key store is not
+ * specified. Any method could be used to protect sensitive
+ * (private or secret) keys. Smart cards or integrated
+ * cryptographic engines could be used or the keystore could
+ * be simply stored in a file.</p>
+ *
+ * @see java.security.cert.Certificate
+ * @see Key
*/
public class KeyStore
{
+
+ // Constants and fields.
+ // ------------------------------------------------------------------------
+
+ /** Service name for key stores. */
+ private static final String KEY_STORE = "KeyStore";
+
private KeyStoreSpi keyStoreSpi;
private Provider provider;
private String type;
+ // Constructors.
+ // ------------------------------------------------------------------------
+
/**
Creates an instance of KeyStore
@@ -89,16 +104,18 @@
this.type = type;
}
- /**
- Gets an instance of the KeyStore class representing
- the specified keystore. If the type is not
- found then, it throws KeyStoreException.
-
- @param type the type of keystore to choose
-
- @return a KeyStore repesenting the desired type
+ // Class methods.
+ // ------------------------------------------------------------------------
- @throws KeyStoreException if the type of keystore is not implemented by providers
+ /**
+ * Gets an instance of the KeyStore class representing
+ * the specified keystore. If the type is not
+ * found then, it throws KeyStoreException.
+ *
+ * @param type the type of keystore to choose
+ * @return a KeyStore repesenting the desired type
+ * @throws KeyStoreException if the type of keystore is not implemented
+ * by providers or the implementation cannot be instantiated.
*/
public static KeyStore getInstance(String type) throws KeyStoreException
{
@@ -106,95 +123,102 @@
for (int i = 0; i < p.length; i++)
{
- String classname = p[i].getProperty("KeyStore." + type);
- if (classname != null)
- return getInstance(classname, type, p[i]);
+ try
+ {
+ return getInstance(type, p[i]);
+ }
+ catch (KeyStoreException ignore)
+ {
+ }
}
throw new KeyStoreException(type);
}
/**
- Gets an instance of the KeyStore class representing
- the specified key store from the specified provider.
- If the type is not found then, it throws KeyStoreException.
- If the provider is not found, then it throws
- NoSuchProviderException.
-
- @param type the type of keystore to choose
- @param provider the provider name
-
- @return a KeyStore repesenting the desired type
-
- @throws KeyStoreException if the type of keystore is not
- implemented by the given provider
- @throws NoSuchProviderException if the provider is not found
- @throws IllegalArgumentException if the provider string is
- null or empty
+ * Gets an instance of the KeyStore class representing
+ * the specified key store from the specified provider.
+ * If the type is not found then, it throws KeyStoreException.
+ * If the provider is not found, then it throws
+ * NoSuchProviderException.
+ *
+ * @param type the type of keystore to choose
+ * @param provider the provider name
+ * @return a KeyStore repesenting the desired type
+ * @throws KeyStoreException if the type of keystore is not
+ * implemented by the given provider
+ * @throws NoSuchProviderException if the provider is not found
+ * @throws IllegalArgumentException if the provider string is
+ * null or empty
*/
public static KeyStore getInstance(String type, String provider)
throws KeyStoreException, NoSuchProviderException
{
if (provider == null || provider.length() == 0)
throw new IllegalArgumentException("Illegal provider");
+
Provider p = Security.getProvider(provider);
if (p == null)
throw new NoSuchProviderException();
- return getInstance(p.getProperty("KeyStore." + type), type, p);
+ return getInstance(type, p);
}
/**
- Gets an instance of the KeyStore class representing
- the specified key store from the specified provider.
- If the type is not found then, it throws KeyStoreException.
- If the provider is not found, then it throws
- NoSuchProviderException.
-
- @param type the type of keystore to choose
- @param provider the keystore provider
-
- @return a KeyStore repesenting the desired type
-
- @throws KeyStoreException if the type of keystore is not
- implemented by the given provider
- @throws IllegalArgumentException if the provider object is null
- @since 1.4
+ * Gets an instance of the KeyStore class representing
+ * the specified key store from the specified provider.
+ * If the type is not found then, it throws KeyStoreException.
+ * If the provider is not found, then it throws
+ * NoSuchProviderException.
+ *
+ * @param type the type of keystore to choose
+ * @param provider the keystore provider
+ * @return a KeyStore repesenting the desired type
+ * @throws KeyStoreException if the type of keystore is not
+ * implemented by the given provider
+ * @throws IllegalArgumentException if the provider object is null
+ * @since 1.4
*/
public static KeyStore getInstance(String type, Provider provider)
throws KeyStoreException
{
if (provider == null)
throw new IllegalArgumentException("Illegal provider");
-
- return getInstance(provider.getProperty("KeyStore." + type),
- type, provider);
- }
-
- private static KeyStore getInstance(String classname,
- String type,
- Provider provider)
- throws KeyStoreException
- {
try
{
- return new KeyStore((KeyStoreSpi) Class.forName(classname).
- newInstance(), provider, type);
- }
- catch (ClassNotFoundException cnfe)
- {
- throw new KeyStoreException("Class not found");
+ return new KeyStore(
+ (KeyStoreSpi) Engine.getInstance(KEY_STORE, type, provider),
+ provider, type);
}
- catch (InstantiationException ie)
+ catch (NoSuchAlgorithmException nsae)
{
- throw new KeyStoreException("Class instantiation failed");
+ throw new KeyStoreException(type);
}
- catch (IllegalAccessException iae)
+ catch (ClassCastException cce)
{
- throw new KeyStoreException("Illegal Access");
+ throw new KeyStoreException(type);
}
}
+ /**
+ * Returns the default KeyStore type. This method looks up the
+ * type in <JAVA_HOME>/lib/security/java.security with the
+ * property "keystore.type" or if that fails then "jks" .
+ */
+ public static final String getDefaultType()
+ {
+ // Security reads every property in java.security so it
+ // will return this property if it exists.
+ String tmp = Security.getProperty("keystore.type");
+
+ if (tmp == null)
+ tmp = "jks";
+
+ return tmp;
+ }
+
+ // Instance methods.
+ // ------------------------------------------------------------------------
/**
Gets the provider that the class is from.
@@ -471,21 +495,4 @@
keyStoreSpi.engineLoad(stream, password);
}
- /**
- Returns the default KeyStore type. This method looks up the
- type in <JAVA_HOME>/lib/security/java.security with the
- property "keystore.type" or if that fails then "jks" .
- */
- public static final String getDefaultType()
- {
- String tmp;
- //Security reads every property in java.security so it
- //will return this property if it exists.
- tmp = Security.getProperty("keystore.type");
-
- if (tmp == null)
- tmp = "jks";
-
- return tmp;
- }
}
Index: libjava/java/security/MessageDigest.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/security/MessageDigest.java,v
retrieving revision 1.8
diff -u -r1.8 MessageDigest.java
--- libjava/java/security/MessageDigest.java 17 Nov 2002 00:10:24 -0000 1.8
+++ libjava/java/security/MessageDigest.java 19 Apr 2003 20:19:46 -0000
@@ -1,6 +1,5 @@
-
/* MessageDigest.java --- The message digest interface.
- Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,17 +37,73 @@
package java.security;
+/**
+ * <p>This <code>MessageDigest</code> class provides applications the
+ * functionality of a message digest algorithm, such as <i>MD5</i> or <i>SHA</i>.
+ * Message digests are secure one-way hash functions that take arbitrary-sized
+ * data and output a fixed-length hash value.</p>
+ *
+ * <p>A <code>MessageDigest</code> object starts out initialized. The data is
+ * processed through it using the <code>update()</code> methods. At any point
+ * <code>reset()</code> can be called to reset the digest. Once all the data to
+ * be updated has been updated, one of the <code>digest()</code> methods should
+ * be called to complete the hash computation.</p>
+ *
+ * <p>The <code>digest()</code> method can be called <b>once</b> for a given
+ * number of updates. After <code>digest()</code> has been called, the
+ * <code>MessageDigest</code> object is <b>reset</b> to its initialized state.
+ * </p>
+ *
+ * <p>Implementations are free to implement the { at link Cloneable} interface.
+ * Client applications can test cloneability by attempting cloning and catching
+ * the { at link CloneNotSupportedException}:
+ *
+ * <pre>
+ * MessageDigest md = MessageDigest.getInstance("SHA");
+ * try
+ * {
+ * md.update(toChapter1);
+ * MessageDigest tc1 = md.clone();
+ * byte[] toChapter1Digest = tc1.digest();
+ * md.update(toChapter2);
+ * // ...
+ * }
+ * catch (CloneNotSupportedException x)
+ * {
+ * throw new DigestException("couldn't make digest of partial content");
+ * }
+ * </pre>
+ *
+ * <p>Note that if a given implementation is not cloneable, it is still possible
+ * to compute intermediate digests by instantiating several instances, if the
+ * number of digests is known in advance.</p>
+ *
+ * <p>Note that this class is abstract and extends from { at link MessageDigestSpi}
+ * for historical reasons. Application developers should only take notice of the
+ * methods defined in this <code>MessageDigest</code> class; all the methods in
+ * the superclass are intended for cryptographic service providers who wish to
+ * supply their own implementations of message digest algorithms.</p>
+ *
+ * @see MessageDigestSpi
+ * @see Provider
+ * @since JDK 1.1
+ */
public abstract class MessageDigest extends MessageDigestSpi
{
+ /** The service name for message digests. */
+ private static final String MESSAGE_DIGEST = "MessageDigest";
+
private String algorithm;
Provider provider;
private byte[] lastDigest;
/**
- Creates a MessageDigest representing the specified
- algorithm.
-
- @param algorithm the name of digest algorithm to choose
+ * Creates a message digest with the specified algorithm name.
+ *
+ * @param algorithm the standard name of the digest algorithm.
+ * See Appendix A in the Java Cryptography Architecture API
+ * Specification & Reference for information about standard
+ * algorithm names.
*/
protected MessageDigest(String algorithm)
{
@@ -56,16 +111,20 @@
provider = null;
}
- /**
- Gets an instance of the MessageDigest class representing
- the specified digest. If the algorithm is not found then,
- it throws NoSuchAlgorithmException.
-
- @param algorithm the name of digest algorithm to choose
- @return a MessageDigest representing the desired algorithm
-
- @exception NoSuchAlgorithmException if the algorithm is not implemented by
- providers
+ /**
+ * Generates a <code>MessageDigest</code> object that implements the specified
+ * digest algorithm. If the default provider package provides an
+ * implementation of the requested digest algorithm, an instance of
+ * <code>MessageDigest</code> containing that implementation is returned. If
+ * the algorithm is not available in the default package, other packages are
+ * searched.
+ *
+ * @param algorithm the name of the algorithm requested. See Appendix A in the
+ * Java Cryptography Architecture API Specification & Reference for
+ * information about standard algorithm names.
+ * @return a Message Digest object implementing the specified algorithm.
+ * @throws NoSuchAlgorithmException if the algorithm is not available in the
+ * caller's environment.
*/
public static MessageDigest getInstance(String algorithm)
throws NoSuchAlgorithmException
@@ -83,103 +142,84 @@
throw new NoSuchAlgorithmException(algorithm);
}
- /**
- Gets an instance of the MessageDigest class representing
- the specified digest from the specified provider. If the
- algorithm is not found then, it throws NoSuchAlgorithmException.
- If the provider is not found, then it throws
- NoSuchProviderException.
-
- @param algorithm the name of digest algorithm to choose
- @param provider the name of the provider to find the algorithm in
- @return a MessageDigest representing the desired algorithm
-
- @exception NoSuchAlgorithmException if the algorithm is not implemented by
- the provider
- @exception NoSuchProviderException if the provider is not found
+ /**
+ * Generates a <code>MessageDigest</code> object implementing the specified
+ * algorithm, as supplied from the specified provider, if such an algorithm is
+ * available from the provider.
+ *
+ * @param algorithm the name of the algorithm requested. See Appendix A in the
+ * Java Cryptography Architecture API Specification & Reference for
+ * information about standard algorithm names.
+ * @param provider the name of the provider.
+ * @return a Message Digest object implementing the specified algorithm.
+ * @throws NoSuchAlgorithmException if the algorithm is not available in the
+ * package supplied by the requested provider.
+ * @throws NoSuchProviderException if the provider is not available in the
+ * environment.
+ * @throws IllegalArgumentException if the provider name is null or empty.
+ * @see Provider
*/
-
public static MessageDigest getInstance(String algorithm, String provider)
throws NoSuchAlgorithmException, NoSuchProviderException
{
- Provider p = Security.getProvider(provider);
+ if (provider == null || provider.length() == 0)
+ throw new IllegalArgumentException("Illegal provider");
+ Provider p = Security.getProvider(provider);
if (p == null)
throw new NoSuchProviderException(provider);
return getInstance(algorithm, p);
}
- private static MessageDigest getInstance(String algorithm, Provider p)
- throws NoSuchAlgorithmException
- {
- // try the name as is
- String className = p.getProperty("MessageDigest." + algorithm);
- if (className == null) { // try all uppercase
- String upper = algorithm.toUpperCase();
- className = p.getProperty("MessageDigest." + upper);
- if (className == null) { // try if it's an alias
- String alias = p.getProperty("Alg.Alias.MessageDigest." +algorithm);
- if (alias == null) { // try all-uppercase alias name
- alias = p.getProperty("Alg.Alias.MessageDigest." +upper);
- if (alias == null) { // spit the dummy
- throw new NoSuchAlgorithmException(algorithm);
- }
- }
- className = p.getProperty("MessageDigest." + alias);
- if (className == null) {
- throw new NoSuchAlgorithmException(algorithm);
- }
- }
- }
- return getInstance(className, algorithm, p);
- }
-
- private static MessageDigest getInstance(String classname,
- String algorithm,
- Provider provider)
+ /**
+ * Generates a <code>MessageDigest</code> object implementing the specified
+ * algorithm, as supplied from the specified provider, if such an algorithm
+ * is available from the provider. Note: the provider doesn't have to be
+ * registered.
+ *
+ * @param algorithm the name of the algorithm requested. See Appendix A in
+ * the Java Cryptography Architecture API Specification & Reference for
+ * information about standard algorithm names.
+ * @param provider the provider.
+ * @return a Message Digest object implementing the specified algorithm.
+ * @throws NoSuchAlgorithmException if the <code>algorithm</code> is not
+ * available in the package supplied by the requested <code>provider</code>.
+ * @throws IllegalArgumentException if the <code>provider</code> is
+ * <code>null</code>.
+ * @since 1.4
+ * @see Provider
+ */
+ public static MessageDigest getInstance(String algorithm, Provider provider)
throws NoSuchAlgorithmException
{
- if (classname == null)
- throw new NoSuchAlgorithmException(algorithm);
+ if (provider == null)
+ throw new IllegalArgumentException("Illegal provider");
MessageDigest result = null;
- try
+ Object o = Engine.getInstance(MESSAGE_DIGEST, algorithm, provider);
+
+ if (o instanceof MessageDigestSpi)
{
- Object obj = Class.forName(classname).newInstance();
- if (obj instanceof MessageDigest) {
- result = (MessageDigest) obj;
- result.algorithm = algorithm;
- } else if (obj instanceof MessageDigestSpi) {
- result = new DummyMessageDigest((MessageDigestSpi) obj, algorithm);
- } else {
- throw new ClassCastException("Class "+classname+" from Provider "
- +provider.getName()
- +" does not extend java.security.MessageDigestSpi");
- }
- result.provider = provider;
- return result;
+ result = new DummyMessageDigest((MessageDigestSpi) o, algorithm);
}
- catch (ClassNotFoundException cnfe)
+ else if (o instanceof MessageDigest)
{
- throw new NoSuchAlgorithmException(algorithm + ": Class not found.");
+ result = (MessageDigest) o;
+ result.algorithm = algorithm;
}
- catch (InstantiationException ie)
- {
- throw new NoSuchAlgorithmException(algorithm
- + ": Class instantiation failed.");
- }
- catch (IllegalAccessException iae)
+ else
{
- throw new NoSuchAlgorithmException(algorithm + ": Illegal Access");
+ throw new NoSuchAlgorithmException(algorithm);
}
+ result.provider = provider;
+ return result;
}
-
/**
- Gets the provider that the MessageDigest is from.
-
- @return the provider the this MessageDigest
+ * Returns the provider of this message digest object.
+ *
+ * @return the provider of this message digest object.
*/
public final Provider getProvider()
{
@@ -187,9 +227,9 @@
}
/**
- Updates the digest with the byte.
-
- @param input byte to update the digest with
+ * Updates the digest using the specified byte.
+ *
+ * @param input the byte with which to update the digest.
*/
public void update(byte input)
{
@@ -197,32 +237,33 @@
}
/**
- Updates the digest with the bytes from the array from the
- specified offset to the specified length.
-
- @param input bytes to update the digest with
- @param offset the offset to start at
- @param len length of the data to update with
+ * Updates the digest using the specified array of bytes, starting at the
+ * specified offset.
+ *
+ * @param input the array of bytes.
+ * @param offset the offset to start from in the array of bytes.
+ * @param len the number of bytes to use, starting at offset.
*/
- public void update(byte[]input, int offset, int len)
+ public void update(byte[] input, int offset, int len)
{
engineUpdate(input, offset, len);
}
/**
- Updates the digest with the bytes from the array.
-
- @param input bytes to update the digest with
+ * Updates the digest using the specified array of bytes.
+ *
+ * @param input the array of bytes.
*/
- public void update(byte[]input)
+ public void update(byte[] input)
{
engineUpdate(input, 0, input.length);
}
/**
- Computes the digest of the stored data.
-
- @return a byte array representing the message digest
+ * Completes the hash computation by performing final operations such as
+ * padding. The digest is reset after this call is made.
+ *
+ * @return the array of bytes for the resulting hash value.
*/
public byte[] digest()
{
@@ -230,52 +271,54 @@
}
/**
- Computes the final digest of the stored bytes and returns
- them.
-
- @param buf An array of bytes to store the digest
- @param offset An offset to start storing the digest at
- @param len The length of the buffer
- @return Returns the length of the buffer
+ * Completes the hash computation by performing final operations such as
+ * padding. The digest is reset after this call is made.
+ *
+ * @param buf An output buffer for the computed digest.
+ * @param offset The offset into the output buffer to begin storing the digest.
+ * @param len The number of bytes within buf allotted for the digest.
+ * @return The number of bytes placed into buf.
+ * @throws DigestException if an error occurs.
*/
- public int digest(byte[]buf, int offset, int len) throws DigestException
+ public int digest(byte[] buf, int offset, int len) throws DigestException
{
return engineDigest(buf, offset, len);
}
/**
- Computes a final update using the input array of bytes,
- then computes a final digest and returns it. It calls
- update(input) and then digest();
-
- @param input An array of bytes to perform final update with
- @return a byte array representing the message digest
+ * Performs a final update on the digest using the specified array of bytes,
+ * then completes the digest computation. That is, this method first calls
+ * <code>update(input)</code>, passing the input array to the <code>update()
+ * </code> method, then calls <code>digest()</code>.
+ *
+ * @param input the input to be updated before the digest is completed.
+ * @return the array of bytes for the resulting hash value.
*/
- public byte[] digest(byte[]input)
+ public byte[] digest(byte[] input)
{
update(input);
return digest();
}
/**
- Returns a representation of the MessageDigest as a String.
-
- @return a string representing the message digest
+ * Returns a string representation of this message digest object.
+ *
+ * @return a string representation of the object.
*/
public String toString()
{
- return (getClass()).getName()
- + " Message Digest <" + digestToString() + ">";
+ return (getClass()).getName() + " Message Digest <" + digestToString() + ">";
}
/**
- Does a simple byte comparison of the two digests.
-
- @param digesta first digest to compare
- @param digestb second digest to compare
- @return true if they are equal, false otherwise
+ * Compares two digests for equality. Does a simple byte compare.
+ *
+ * @param digesta one of the digests to compare.
+ * @param digestb the other digest to compare.
+ * @return <code>true</code> if the digests are equal, <code>false</code>
+ * otherwise.
*/
- public static boolean isEqual(byte[]digesta, byte[]digestb)
+ public static boolean isEqual(byte[] digesta, byte[] digestb)
{
if (digesta.length != digestb.length)
return false;
@@ -287,20 +330,20 @@
return true;
}
-
- /**
- Resets the message digest.
- */
+ /** Resets the digest for further use. */
public void reset()
{
engineReset();
}
- /**
- Gets the name of the algorithm currently used.
- The names of algorithms are usually SHA-1 or MD5.
-
- @return name of algorithm.
+ /**
+ * Returns a string that identifies the algorithm, independent of
+ * implementation details. The name should be a standard Java Security name
+ * (such as <code>"SHA"</code>, <code>"MD5"</code>, and so on). See Appendix
+ * A in the Java Cryptography Architecture API Specification & Reference
+ * for information about standard algorithm names.
+ *
+ * @return the name of the algorithm.
*/
public final String getAlgorithm()
{
@@ -308,11 +351,13 @@
}
/**
- Gets the length of the message digest.
- The default is zero which means that this message digest
- does not implement this function.
-
- @return length of the message digest
+ * Returns the length of the digest in bytes, or <code>0</code> if this
+ * operation is not supported by the provider and the implementation is not
+ * cloneable.
+ *
+ * @return the digest length in bytes, or <code>0</code> if this operation is
+ * not supported by the provider and the implementation is not cloneable.
+ * @since 1.2
*/
public final int getDigestLength()
{
@@ -320,15 +365,11 @@
}
/**
- Returns a clone of this class if supported.
- If it does not then it throws CloneNotSupportedException.
- The cloning of this class depends on whether the subclass
- MessageDigestSpi implements Cloneable which contains the
- actual implementation of the appropriate algorithm.
-
- @return clone of this class
-
- @exception CloneNotSupportedException this class does not support cloning
+ * Returns a clone if the implementation is cloneable.
+ *
+ * @return a clone if the implementation is cloneable.
+ * @throws CloneNotSupportedException if this is called on an implementation
+ * that does not support { at link Cloneable}.
*/
public Object clone() throws CloneNotSupportedException
{
@@ -359,5 +400,4 @@
return buf.toString();
}
-
}
Index: libjava/java/security/Policy.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/security/Policy.java,v
retrieving revision 1.3
diff -u -r1.3 Policy.java
--- libjava/java/security/Policy.java 24 May 2002 11:57:20 -0000 1.3
+++ libjava/java/security/Policy.java 19 Apr 2003 20:19:46 -0000
@@ -1,5 +1,5 @@
/* Policy.java --- Policy Manager Class
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2003, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,90 +37,87 @@
package java.security;
-/**
- Policy is an abstract class for managing the system security
- policy for the Java application environment. It specifies
- which permissions are available for code from various
- sources. The security policy is represented through a
- subclass of Policy.
-
- Only one Policy is in effect at any time. ProtectionDomain
- initializes itself with information from this class on the
- set of permssions to grant.
-
- The location for the actual Policy could be anywhere in any
- form because it depends on the Policy implementation. The
- default system is in a flat ASCII file or it could be in a
- database.
-
- The current installed Policy can be accessed with getPolicy
- and changed with setPolicy if the code has the correct
- permissions.
-
- The refresh method causes the Policy class to refresh/reload
- its configuration. The method used to refresh depends on the
- Policy implementation.
-
- When a protection domain initializes its permissions it uses
- code like:
- <code>
- policy = Policy.getPolicy();
- permissionCollection perms = policy.getPermissions(MyCodeSource)
- </code>
- The protection domain passes the Policy handler a CodeSource
- object which contains the codebase URL and public key. The
- Policy implementation then returns the proper set of
- permissions for the CodeSource.
-
- The default Policy implementation can be changed by setting
- the "policy.provider" security provider in java.security
- to the correct Policy implementation class.
-
- @author Mark Benvenuto
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.LinkedHashMap;
+import java.util.Map;
- @since JDK 1.2
+/**
+ * <p>This is an abstract class for representing the system security policy for
+ * a Java application environment (specifying which permissions are available
+ * for code from various sources). That is, the security policy is represented
+ * by a <code>Policy</code> subclass providing an implementation of the abstract
+ * methods in this <code>Policy</code> class.</p>
+ *
+ * <p>There is only one <code>Policy</code> object in effect at any given time.
+ * </p>
+ *
+ * <p>The source location for the policy information utilized by the
+ * <code>Policy</code> object is up to the <code>Policy</code> implementation.
+ * The policy configuration may be stored, for example, as a flat ASCII file, as
+ * a serialized binary file of the <code>Policy</code> class, or as a database.
+ * </p>
+ *
+ * <p>The currently-installed <code>Policy</code> object can be obtained by
+ * calling the <code>getPolicy()</code> method, and it can be changed by a call
+ * to the <code>setPolicy()</code> method (by code with permission to reset the
+ * <code>Policy</code>).</p>
+ *
+ * <p>The <code>refresh()</code> method causes the policy object to refresh /
+ * reload its current configuration.</p>
+ *
+ * <p>This is implementation-dependent. For example, if the policy object stores
+ * its policy in configuration files, calling <code>refresh()</code> will cause
+ * it to re-read the configuration policy files. The refreshed policy may not
+ * have an effect on classes in a particular { at link ProtectionDomain}. This is
+ * dependent on the <code>Policy</code> provider's implementation of the
+ * <code>implies()</code> method and the { at link PermissionCollection} caching
+ * strategy.</p>
+ *
+ * <p>The default <code>Policy</code> implementation can be changed by setting
+ * the value of the <code>"policy.provider"</code> security property (in the
+ * Java security properties file) to the fully qualified name of the desired
+ * <code>Policy</code> implementation class. The Java security properties file
+ * is located in the file named <code><JAVA_HOME>/lib/security/java.security
+ * </code>, where <code><JAVA_HOME></code> refers to the directory where the
+ * SDK was installed.</p>
+ *
+ * <p><b>IMPLEMENTATION NOTE:</b> This implementation attempts to read the
+ * System property named <code>policy.provider</code> to find the concrete
+ * implementation of the <code>Policy</code>. If/when this fails, it falls back
+ * to a default implementation, which <b>allows everything</b>.
+ *
+ * @author Mark Benvenuto
+ * @see CodeSource
+ * @see PermissionCollection
+ * @see SecureClassLoader
+ * @since 1.2
*/
public abstract class Policy
{
- // FIXME: The class name of the Policy provider should really be sourced
- // from the "java.security" configuration file. For now, just hard-code
- // a stub implementation.
static private Policy currentPolicy = null;
- static
- {
- String pp = System.getProperty ("policy.provider");
- if (pp != null)
- try
- {
- currentPolicy = (Policy)Class.forName(pp).newInstance();
- }
- catch (Exception _)
- {
- currentPolicy = null;
- }
- if (currentPolicy == null)
- currentPolicy = new gnu.java.security.provider.DefaultPolicy();
- }
-
- /**
- Constructs a new Policy class.
- */
+
+ /** Map of ProtectionDomains to PermissionCollections for this instance. */
+ private Map pd2pc = null;
+
+ /** Constructs a new <code>Policy</code> object. */
public Policy()
{
}
/**
- Gets the currently installed Policy handler. The value should
- not be cached as it can be changed by setPolicy. This
- function first calls <code>SecurityManager.checkPermission</code>
- with <code>SecurityPermission("getPolicy")</code> to check
- if the caller has Permission to get the current Policy.
-
- @return the current Policy
-
- @throws SecurityException if the security manager exists
- the caller does not have permission to
- <code>getPolicy</code>.
+ * Returns the installed <code>Policy</code> object. This value should not be
+ * cached, as it may be changed by a call to <code>setPolicy()</code>. This
+ * method first calls { at link SecurityManager#checkPermission(Permission)} with
+ * a <code>SecurityPermission("getPolicy")</code> permission to ensure it's ok
+ * to get the <code>Policy</code> object.
+ *
+ * @return the installed <code>Policy</code>.
+ * @throws SecurityException if a security manager exists and its
+ * <code>checkPermission()</code> method doesn't allow getting the
+ * <code>Policy</code> object.
+ * @see SecurityManager#checkPermission(Permission)
+ * @see #setPolicy(Policy)
*/
public static Policy getPolicy()
{
@@ -128,20 +125,21 @@
if (sm != null)
sm.checkPermission(new SecurityPermission("getPolicy"));
- return currentPolicy;
+ return getCurrentPolicy();
}
/**
- Sets the currently installed Policy handler. This
- function first calls <code>SecurityManager.checkPermission</code>
- with <code>SecurityPermission("setPolicy")</code> to check
- if the caller has Permission to get the current Policy.
-
- @param policy the new Policy to use
-
- @throws SecurityException if the security manager exists
- the caller does not have permission to
- <code>getPolicy</code>.
+ * Sets the system-wide <code>Policy</code> object. This method first calls
+ * { at link SecurityManager#checkPermission(Permission)} with a
+ * <code>SecurityPermission("setPolicy")</code> permission to ensure it's ok
+ * to set the <code>Policy</code>.
+ *
+ * @param policy the new system <code>Policy</code> object.
+ * @throws SecurityException if a security manager exists and its
+ * <code>checkPermission()</code> method doesn't allow setting the
+ * <code>Policy</code>.
+ * @see SecurityManager#checkPermission(Permission)
+ * @see #getPolicy()
*/
public static void setPolicy(Policy policy)
{
@@ -149,27 +147,161 @@
if (sm != null)
sm.checkPermission(new SecurityPermission("setPolicy"));
+ setup(policy);
currentPolicy = policy;
}
+ private static void setup(final Policy policy)
+ {
+ if (policy.pd2pc == null)
+ policy.pd2pc = Collections.synchronizedMap(new LinkedHashMap());
- /**
- Evalutes the global policy and returns a set of Permissions
- allowed for the specified CodeSource.
+ ProtectionDomain pd = policy.getClass().getProtectionDomain();
+ if (pd.getCodeSource() != null)
+ {
+ PermissionCollection pc = null;
+ if (currentPolicy != null)
+ pc = currentPolicy.getPermissions(pd);
+
+ if (pc == null) // assume it has all
+ {
+ pc = new Permissions();
+ pc.add(new AllPermission());
+ }
- @param codesource The CodeSource to get Permission for
+ policy.pd2pc.put(pd, pc); // add the mapping pd -> pc
+ }
+ }
- @return a set of permissions for codesource specified by
- the current policy
+ /**
+ * Ensures/forces loading of the configured policy provider, while bypassing
+ * the { at link SecurityManager} checks for <code>"getPolicy"</code> security
+ * permission. Needed by { at link ProtectionDomain}.
+ */
+ static Policy getCurrentPolicy()
+ {
+ // FIXME: The class name of the Policy provider should really be sourced
+ // from the "java.security" configuration file. For now, just hard-code
+ // a stub implementation.
+ if (currentPolicy == null)
+ {
+ String pp = System.getProperty ("policy.provider");
+ if (pp != null)
+ try
+ {
+ currentPolicy = (Policy) Class.forName(pp).newInstance();
+ }
+ catch (Exception ignored) {}
+
+ if (currentPolicy == null)
+ currentPolicy = new gnu.java.security.provider.DefaultPolicy();
+ }
+ return currentPolicy;
+ }
- @throws SecurityException if the current thread does not
- have permission to call <code>getPermissions</code>
+ /**
+ * Tests if <code>currentPolicy</code> is not <code>null</code>,
+ * thus allowing clients to not force loading of any policy
+ * provider; needed by { at link ProtectionDomain}.
+ */
+ static boolean isLoaded()
+ {
+ return currentPolicy != null;
+ }
+
+ /**
+ * Evaluates the global policy and returns a { at link PermissionCollection}
+ * object specifying the set of permissions allowed for code from the
+ * specified code source.
+ *
+ * @param codesource the { at link 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 allowed for code from codesource according
+ * to the policy. The returned set of permissions must be a new mutable
+ * instance and it must support heterogeneous { at link Permission} types.
*/
public abstract PermissionCollection getPermissions(CodeSource codesource);
/**
- Refreshes and/or reloads the current Policy. The actual
- behavior of this method depends on the implementation.
+ * Evaluates the global policy and returns a { at link PermissionCollection}
+ * object specifying the set of permissions allowed given the characteristics
+ * of the protection domain.
+ *
+ * @param domain the { at link ProtectionDomain} associated with the caller.
+ * @return the set of permissions allowed for the domain according to the
+ * policy. The returned set of permissions must be a new mutable instance and
+ * it must support heterogeneous { at link Permission} types.
+ * @since 1.4
+ * @see ProtectionDomain
+ * @see SecureClassLoader
+ */
+ public PermissionCollection getPermissions(ProtectionDomain domain)
+ {
+ if (domain == null)
+ return new Permissions();
+
+ if (pd2pc == null)
+ setup(this);
+
+ PermissionCollection result = (PermissionCollection) pd2pc.get(domain);
+ if (result != null)
+ {
+ Permissions realResult = new Permissions();
+ for (Enumeration e = result.elements(); e.hasMoreElements(); )
+ realResult.add((Permission) e.nextElement());
+
+ return realResult;
+ }
+
+ result = getPermissions(domain.getCodeSource());
+ if (result == null)
+ result = new Permissions();
+
+ PermissionCollection pc = domain.getPermissions();
+ if (pc != null)
+ for (Enumeration e = pc.elements(); e.hasMoreElements(); )
+ result.add((Permission) e.nextElement());
+
+ return result;
+ }
+
+ /**
+ * Evaluates the global policy for the permissions granted to the { at link
+ * ProtectionDomain} and tests whether the <code>permission</code> is granted.
+ *
+ * @param domain the { at link ProtectionDomain} to test.
+ * @param permission the { at link Permission} object to be tested for
+ * implication.
+ * @return <code>true</code> if <code>permission</code> is a proper subset of
+ * a permission granted to this { at link ProtectionDomain}.
+ * @since 1.4
+ * @see ProtectionDomain
+ */
+ public boolean implies(ProtectionDomain domain, Permission permission)
+ {
+ if (pd2pc == null)
+ setup(this);
+
+ PermissionCollection pc = (PermissionCollection) pd2pc.get(domain);
+ if (pc != null)
+ return pc.implies(permission);
+
+ boolean result = false;
+ pc = getPermissions(domain);
+ if (pc != null)
+ {
+ result = pc.implies(permission);
+ pd2pc.put(domain, pc);
+ }
+
+ return result;
+ }
+
+ /**
+ * Refreshes/reloads the policy configuration. The behavior of this method
+ * depends on the implementation. For example, calling refresh on a file-based
+ * policy will cause the file to be re-read.
*/
public abstract void refresh();
}
Index: libjava/java/security/ProtectionDomain.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/security/ProtectionDomain.java,v
retrieving revision 1.4
diff -u -r1.4 ProtectionDomain.java
--- libjava/java/security/ProtectionDomain.java 4 Oct 2002 20:15:07 -0000 1.4
+++ libjava/java/security/ProtectionDomain.java 19 Apr 2003 20:19:46 -0000
@@ -1,5 +1,5 @@
/* ProtectionDomain.java -- A security domain
- Copyright (C) 1998 Free Software Foundation, Inc.
+ Copyright (C) 1998, 2003, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,55 +38,109 @@
package java.security;
/**
- * This class represents a group of classes, along with the permissions
- * they are granted. The classes are identified by a <code>CodeSource</code>.
- * Thus, any class loaded from the specified <code>CodeSource</code> is
- * treated as part of this domain. The set of permissions is represented
- * by a <code>PermissionCollection</code>.
- * <p>
- * Every class in the system will belong to one and only one
- * <code>ProtectionDomain</code>.
+ * <p>This <code>ProtectionDomain</code> class encapsulates the characteristics
+ * of a domain, which encloses a set of classes whose instances are granted a
+ * set of permissions when being executed on behalf of a given set of
+ * <i>Principals</i>.
*
- * @version 0.0
+ * <p>A static set of permissions can be bound to a <code>ProtectionDomain</code>
+ * when it is constructed; such permissions are granted to the domain regardless
+ * of the { at link Policy} in force. However, to support dynamic security
+ * policies, a <code>ProtectionDomain</code> can also be constructed such that
+ * it is dynamically mapped to a set of permissions by the current { at link
+ * Policy} whenever a permission is checked.</p>
*
* @author Aaron M. Renn (arenn at urbanophile dot com)
+ * @version 0.0
*/
public class ProtectionDomain
{
- /**
- * This is the <code>CodeSource</code> for this protection domain
- */
+ /** This is the <code>CodeSource</code> for this protection domain. */
private CodeSource code_source;
+ /** This is the set of permissions granted to this domain. */
+ private PermissionCollection perms;
+
+ /** The { at link ClassLoader} associated with this domain. */
+ private ClassLoader classloader;
+
+ /** The array of Principals associated with this domain.. */
+ private Principal[] principals;
+
+ /** Post 1.4 the policy may be refreshed! use false for pre 1.4. */
+ private boolean staticBinding;
+
/**
- * This is the set of permissions granted to this domain
+ * Creates a new <code>ProtectionDomain</code> with the given { at link
+ * CodeSource} and { at link Permissions}. If the permissions object is not
+ * <code>null</code>, then <code>setReadOnly()</code> will be called on the
+ * passed in { at link Permissions} object. The only permissions granted to this
+ * domain are the ones specified; the current { at link Policy} will not be
+ * consulted.
+ *
+ * @param codesource the codesource associated with this domain.
+ * @param permissions the permissions granted to this domain
*/
- private PermissionCollection perms;
+ public ProtectionDomain(CodeSource codesource, PermissionCollection permissions)
+ {
+ this(codesource, permissions, null, null, false);
+ }
/**
- * This method initializes a new instance of <code>ProtectionDomain</code>
- * representing the specified <code>CodeSource</code> and permission set.
- * No permissions may be added to the <code>PermissionCollection</code>
- * and this contructor will call the <code>setReadOnly</code> method on
- * the specified permission set.
+ * <p>Creates a new ProtectionDomain qualified by the given CodeSource,
+ * Permissions, ClassLoader and array of Principals. If the permissions
+ * object is not null, then <code>setReadOnly()</code> will be called on the
+ * passed in Permissions object. The permissions granted to this domain are
+ * dynamic; they include both the static permissions passed to this
+ * constructor, and any permissions granted to this domain by the current
+ * Policy at the time a permission is checked.</p>
*
- * @param code_source The <code>CodeSource</code> for this domain
- * @param perms The permission set for this domain
+ * <p>This constructor is typically used by { at link ClassLoader}s and { at link
+ * DomainCombiner}s which delegate to <code>Policy</code> to actively
+ * associate the permissions granted to this domain. This constructor affords
+ * the Policy provider the opportunity to augment the supplied
+ * PermissionCollection to reflect policy changes.</p>
*
- * @see java.security.PermissionCollection#setReadOnly()
- */
- public ProtectionDomain(CodeSource code_source, PermissionCollection perms)
+ * @param codesource the CodeSource associated with this domain.
+ * @param permissions the permissions granted to this domain.
+ * @param classloader the ClassLoader associated with this domain.
+ * @param principals the array of Principals associated with this domain.
+ * @since 1.4
+ * @see Policy#refresh()
+ * @see Policy#getPermissions(ProtectionDomain)
+ */
+ public ProtectionDomain(CodeSource codesource,
+ PermissionCollection permissions,
+ ClassLoader classloader, Principal[] principals)
+ {
+ this(codesource, permissions, classloader, principals, false);
+ }
+
+ private ProtectionDomain(CodeSource codesource,
+ PermissionCollection permissions,
+ ClassLoader classloader, Principal[] principals,
+ boolean staticBinding)
{
- this.code_source = code_source;
- this.perms = perms;
- if (perms != null)
- perms.setReadOnly();
+ super();
+
+ code_source = codesource;
+ if (permissions != null)
+ {
+ perms = permissions;
+ perms.setReadOnly();
+ }
+
+ this.classloader = classloader;
+ this.principals =
+ (principals != null ? (Principal[]) principals.clone() : new Principal[0]);
+ this.staticBinding = staticBinding;
}
/**
- * This method returns the <code>CodeSource</code> for this domain.
- *
- * @return This domain's <code>CodeSource</code>.
+ * Returns the { at link CodeSource} of this domain.
+ *
+ * @return the { at link CodeSource} of this domain which may be <code>null</code>.
+ * @since 1.2
*/
public final CodeSource getCodeSource()
{
@@ -94,9 +148,36 @@
}
/**
- * This method returns the set of permissions granted to this domain.
+ * Returns the { at link ClassLoader} of this domain.
+ *
+ * @return the { at link ClassLoader} of this domain which may be
+ * <code>null</code>.
+ * @since 1.4
+ */
+ public final ClassLoader getClassLoader()
+ {
+ return this.classloader;
+ }
+
+ /**
+ * Returns an array of principals for this domain.
*
- * @return The permission set for this domain
+ * @return returns a non-null array of principals for this domain. Changes to
+ * this array will have no impact on the <code>ProtectionDomain</code>.
+ * @since 1.4
+ */
+ public final Principal[] getPrincipals()
+ {
+ return (Principal[]) principals.clone();
+ }
+
+ /**
+ * Returns the static permissions granted to this domain.
+ *
+ * @return the static set of permissions for this domain which may be
+ * <code>null</code>.
+ * @see Policy#refresh()
+ * @see Policy#getPermissions(ProtectionDomain)
*/
public final PermissionCollection getPermissions()
{
@@ -104,41 +185,85 @@
}
/**
- * This method tests whether or not the specified <code>Permission</code> is
- * implied by the set of permissions granted to this domain.
+ * <p>Check and see if this <code>ProtectionDomain</code> implies the
+ * permissions expressed in the <code>Permission</code> object.</p>
+ *
+ * <p>The set of permissions evaluated is a function of whether the
+ * <code>ProtectionDomain</code> was constructed with a static set of
+ * permissions or it was bound to a dynamically mapped set of permissions.</p>
*
- * @param perm The <code>Permission</code> to test.
+ * <p>If the <code>ProtectionDomain</code> was constructed to a statically
+ * bound { at link PermissionCollection} then the permission will only be checked
+ * against the { at link PermissionCollection} supplied at construction.</p>
*
- * @return <code>true</code> if the specified <code>Permission</code> is implied for this domain, <code>false</code> otherwise.
+ * <p>However, if the <code>ProtectionDomain</code> was constructed with the
+ * constructor variant which supports dynamically binding permissions, then
+ * the permission will be checked against the combination of the
+ * { at link PermissionCollection} supplied at construction and the current
+ * { at link Policy} binding.
+ *
+ * @param permission the { at link Permission} object to check.
+ * @return <code>true</code> if <code>permission</code> is implicit to this
+ * <code>ProtectionDomain</code>.
*/
- public boolean implies(Permission perm)
+ public boolean implies(Permission permission)
{
- PermissionCollection pc = getPermissions();
- if (pc == null)
- return (false);
-
- return (pc.implies(perm));
+ if (staticBinding)
+ return (perms == null ? false : perms.implies(permission));
+ // Else dynamically bound. Do we have it?
+ // NOTE: this will force loading of Policy.currentPolicy
+ return Policy.getCurrentPolicy().implies(this, permission);
}
/**
- * This method returns a <code>String</code> representation of this
- * object. It will print the <code>CodeSource</code> and
- * permission set associated with this domain.
+ * Convert a <code>ProtectionDomain</code> to a String.
*
- * @return A <code>String</code> representation of this object.
+ * @return a string representation of the object.
*/
public String toString()
{
String linesep = System.getProperty("line.separator");
- StringBuffer sb = new StringBuffer("");
- sb.append("ProtectionDomain (" + linesep);
+ StringBuffer sb = new StringBuffer("ProtectionDomain (").append(linesep);
+
if (code_source == null)
- sb.append("CodeSource:null" + linesep);
+ sb.append("CodeSource:null");
+ else
+ sb.append(code_source);
+
+ sb.append(linesep);
+ if (classloader == null)
+ sb.append("ClassLoader:null");
else
- sb.append(code_source + linesep);
- sb.append(perms);
- sb.append(linesep + ")" + linesep);
-
- return sb.toString();
+ sb.append(classloader);
+
+ sb.append(linesep);
+ sb.append("Principals:");
+ if (principals != null && principals.length > 0)
+ {
+ sb.append("[");
+ Principal pal;
+ for (int i = 0; i < principals.length; i++)
+ {
+ pal = principals[i];
+ sb.append("'").append(pal.getName())
+ .append("' of type ").append(pal.getClass().getName());
+ if (i < principals.length-1)
+ sb.append(", ");
+ }
+ sb.append("]");
+ }
+ else
+ sb.append("none");
+
+ sb.append(linesep);
+ if (!staticBinding) // include all but dont force loading Policy.currentPolicy
+ if (Policy.isLoaded())
+ sb.append(Policy.getCurrentPolicy().getPermissions(this));
+ else // fallback on this one's permissions
+ sb.append(perms);
+ else
+ sb.append(perms);
+
+ return sb.append(linesep).append(")").append(linesep).toString();
}
}
Index: libjava/java/security/SecureRandom.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/security/SecureRandom.java,v
retrieving revision 1.8
diff -u -r1.8 SecureRandom.java
--- libjava/java/security/SecureRandom.java 13 Feb 2003 17:00:22 -0000 1.8
+++ libjava/java/security/SecureRandom.java 19 Apr 2003 20:19:46 -0000
@@ -42,14 +42,24 @@
import java.util.Enumeration;
/**
- SecureRandom is the class interface for using SecureRandom
- providers. It provides an interface to the SecureRandomSpi
- engine so that programmers can generate pseudo-random numbers.
-
- @author Mark Benvenuto <ivymccough at worldnet dot att dot net>
+ * An interface to a cryptographically secure pseudo-random number
+ * generator (PRNG). Random (or at least unguessable) numbers are used
+ * in all areas of security and cryptography, from the generation of
+ * keys and initialization vectors to the generation of random padding
+ * bytes.
+ *
+ * @author Mark Benvenuto <ivymccough at worldnet dot att dot net>
+ * @author Casey Marshall
*/
public class SecureRandom extends Random
{
+
+ // Constants and fields.
+ // ------------------------------------------------------------------------
+
+ /** Service name for PRNGs. */
+ private static final String SECURE_RANDOM = "SecureRandom";
+
static final long serialVersionUID = 4940670005562187L;
//Serialized Field
@@ -60,6 +70,9 @@
SecureRandomSpi secureRandomSpi = null;
byte[] state = null;
+ // Constructors.
+ // ------------------------------------------------------------------------
+
/**
Default constructor for SecureRandom. It constructs a
new SecureRandom by instantating the first SecureRandom
@@ -69,7 +82,7 @@
on the first call to getnextBytes it will force a seed.
It is maintained for backwards compatibility and programs
- should use getInstance.
+ should use { at link #getInstance(java.lang.String)}.
*/
public SecureRandom()
{
@@ -88,20 +101,20 @@
{
key = (String) e.nextElement();
if (key.startsWith("SECURERANDOM."))
- {
- if ((classname = p[i].getProperty(key)) != null)
- {
- try
- {
- secureRandomSpi = (SecureRandomSpi) Class.
- forName(classname).newInstance();
- provider = p[i];
- return;
- }
- catch (Throwable ignore) { }
- }
- }
- }
+ {
+ if ((classname = p[i].getProperty(key)) != null)
+ {
+ try
+ {
+ secureRandomSpi = (SecureRandomSpi) Class.
+ forName(classname).newInstance();
+ provider = p[i];
+ return;
+ }
+ catch (Throwable ignore) { }
+ }
+ }
+ }
}
// Nothing found. Fall back to SHA1PRNG
@@ -141,15 +154,17 @@
this.provider = provider;
}
- /**
- Returns an instance of a SecureRandom. It creates the class
- for the specified algorithm if it exists from a provider.
-
- @param algorithm A SecureRandom algorithm to use
+ // Class methods.
+ // ------------------------------------------------------------------------
- @return Returns a new SecureRandom implmenting the chosen algorithm
-
- @throws NoSuchAlgorithmException if the algorithm cannot be found
+ /**
+ * Returns an instance of a SecureRandom. It creates the class from
+ * the first provider that implements it.
+ *
+ * @param algorithm The algorithm name.
+ * @return A new SecureRandom implmenting the given algorithm.
+ * @throws NoSuchAlgorithmException If no installed provider implements
+ * the given algorithm.
*/
public static SecureRandom getInstance(String algorithm) throws
NoSuchAlgorithmException
@@ -157,11 +172,13 @@
Provider p[] = Security.getProviders();
for (int i = 0; i < p.length; i++)
{
- try
- {
- return getInstance(algorithm, p[i]);
- }
- catch (NoSuchAlgorithmException ignored) { }
+ try
+ {
+ return getInstance(algorithm, p[i]);
+ }
+ catch (NoSuchAlgorithmException ignored)
+ {
+ }
}
// None found.
@@ -169,21 +186,26 @@
}
/**
- Returns an instance of a SecureRandom. It creates the class
- for the specified algorithm from the specified provider.
-
- @param algorithm A SecureRandom algorithm to use
- @param provider A security provider to use
-
- @return Returns a new SecureRandom implmenting the chosen algorithm
-
- @throws NoSuchAlgorithmException if the algorithm cannot be found
- @throws NoSuchProviderException if the provider cannot be found
+ * Returns an instance of a SecureRandom. It creates the class
+ * for the specified algorithm from the named provider.
+ *
+ * @param algorithm The algorithm name.
+ * @param provider The provider name.
+ * @return A new SecureRandom implmenting the chosen algorithm.
+ * @throws NoSuchAlgorithmException If the named provider does not implement
+ * the algorithm, or if the implementation cannot be
+ * instantiated.
+ * @throws NoSuchProviderException If no provider named
+ * <code>provider</code> is currently installed.
+ * @throws IllegalArgumentException If <code>provider</code> is null
+ * or is empty.
*/
- public static SecureRandom getInstance(String algorithm,
- String provider) throws
- NoSuchAlgorithmException, NoSuchProviderException
+ public static SecureRandom getInstance(String algorithm, String provider)
+ throws NoSuchAlgorithmException, NoSuchProviderException
{
+ if (provider == null || provider.length() == 0)
+ throw new IllegalArgumentException("Illegal provider");
+
Provider p = Security.getProvider(provider);
if (p == null)
throw new NoSuchProviderException();
@@ -192,88 +214,35 @@
}
/**
- Returns an instance of a SecureRandom. It creates the class for
- the specified algorithm from the given provider.
-
- @param algorithm The SecureRandom algorithm to create.
- @param provider The provider to get the instance from.
-
- @throws NoSuchAlgorithmException If the algorithm cannot be found, or
- if the class cannot be instantiated.
- */
- public static SecureRandom getInstance(String algorithm,
- Provider provider) throws
- NoSuchAlgorithmException
- {
- return getInstance(algorithm, provider, true);
- }
-
- /**
- Creates the instance of SecureRandom, recursing to resolve aliases.
-
- @param algorithm The SecureRandom algorithm to create.
- @param provider The provider to get the implementation from.
- @param recurse Whether or not to recurse to resolve aliases.
-
- @throws NoSuchAlgorithmException If the algorithm cannot be found,
- if there are too many aliases, or if the class cannot be
- instantiated.
- */
- private static SecureRandom getInstance(String algorithm,
- Provider provider,
- boolean recurse)
- throws NoSuchAlgorithmException
- {
- String msg = algorithm;
- for (Enumeration e = provider.propertyNames(); e.hasMoreElements(); )
+ * Returns an instance of a SecureRandom. It creates the class for
+ * the specified algorithm from the given provider.
+ *
+ * @param algorithm The SecureRandom algorithm to create.
+ * @param provider The provider to get the instance from.
+ * @throws NoSuchAlgorithmException If the algorithm cannot be found, or
+ * if the class cannot be instantiated.
+ * @throws IllegalArgumentException If <code>provider</code> is null.
+ */
+ public static SecureRandom getInstance(String algorithm, Provider provider)
+ throws NoSuchAlgorithmException
+ {
+ if (provider == null)
+ throw new IllegalArgumentException("Illegal provider");
+ try
{
- // We could replace the boolean with an integer, incrementing it
- // every
- String key = (String) e.nextElement();
- if (key.startsWith("SECURERANDOM.")
- && key.substring(13).equalsIgnoreCase(algorithm))
- {
- try
- {
- Class c = Class.forName(provider.getProperty(key));
- return new SecureRandom((SecureRandomSpi) c.newInstance(),
- provider);
- }
- catch (Throwable ignored) { }
- }
- else if (key.startsWith("ALG.ALIAS.SECURERANDOM.")
- && key.substring(23).equalsIgnoreCase(algorithm) && recurse)
- {
- try
- {
- // First see if this alias refers to a class in this
- // provider.
- return getInstance(provider.getProperty(key), provider, false);
- }
- catch (NoSuchAlgorithmException nsae)
- {
- Provider[] provs = Security.getProviders();
- for (int i = 0; i < provs.length; i++)
- {
- if (provs[i] == provider)
- continue;
- // Now try other providers for the implementation
- try
- {
- return getInstance(provider.getProperty(key),
- provs[i], false);
- }
- catch (NoSuchAlgorithmException nsae2)
- {
- msg = nsae2.getMessage();
- }
- }
- }
- }
+ return new SecureRandom((SecureRandomSpi)
+ Engine.getInstance(SECURE_RANDOM, algorithm, provider),
+ provider);
+ }
+ catch (ClassCastException cce)
+ {
+ throw new NoSuchAlgorithmException(algorithm);
}
- throw new NoSuchAlgorithmException(algorithm);
}
+ // Instance methods.
+ // ------------------------------------------------------------------------
+
/**
Returns the provider being used by the current SecureRandom class.
@@ -318,8 +287,8 @@
(byte) (0xff & (seed >> 16)),
(byte) (0xff & (seed >> 8)),
(byte) (0xff & seed)
- };
- secureRandomSpi.engineSetSeed(tmp);
+ };
+ secureRandomSpi.engineSetSeed(tmp);
}
}
Index: libjava/java/security/Security.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/security/Security.java,v
retrieving revision 1.11
diff -u -r1.11 Security.java
--- libjava/java/security/Security.java 31 Dec 2002 22:50:10 -0000 1.11
+++ libjava/java/security/Security.java 19 Apr 2003 20:19:46 -0000
@@ -1,5 +1,5 @@
/* Security.java --- Java base security class implmentation
- Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2001, 2002, 2003, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -36,28 +36,35 @@
exception statement from your version. */
package java.security;
-import java.io.File;
+
+import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.IOException;
-import java.io.FileNotFoundException;
import java.net.URL;
import java.security.Provider;
-import java.util.Vector;
+import java.util.Collections;
import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Map;
import java.util.Properties;
+import java.util.Set;
+import java.util.Vector;
/**
- Security class that loads the Providers and provides an
- interface to security properties.
-
- @author Mark Benvenuto <ivymccough at worldnet dot att dot net>
+ * This class centralizes all security properties and common security methods.
+ * One of its primary uses is to manage providers.
+ *
+ * @author Mark Benvenuto <ivymccough at worldnet dot att dot net>
*/
-
public final class Security extends Object
{
+ private static final String ALG_ALIAS = "Alg.Alias.";
+
private static Vector providers = new Vector();
private static Properties secprops;
-
static
{
String base = System.getProperty("gnu.classpath.home.url");
@@ -76,7 +83,6 @@
return;
String secfilestr = baseUrl + "/security/" + vendor + ".security";
-
try
{
InputStream fin = new URL(secfilestr).openStream();
@@ -85,12 +91,9 @@
int i = 1;
String name;
-
- while ((name = secprops.getProperty("security.provider." + i)) !=
- null)
+ while ((name = secprops.getProperty("security.provider." + i)) != null)
{
Exception exception = null;
-
try
{
providers.addElement(Class.forName(name).newInstance());
@@ -107,15 +110,16 @@
{
exception = x;
}
+
if (exception != null)
- System.err.println ("Error loading security provider " + name
- + ": " + exception);
+ System.err.println (
+ "Error loading security provider " + name + ": " + exception);
i++;
}
}
catch (FileNotFoundException ignored)
{
- // Actually we probibly shouldn't ignore these, once the security
+ // Actually we probably shouldn't ignore these, once the security
// properties file is actually installed somewhere.
}
catch (IOException ignored)
@@ -124,57 +128,78 @@
}
/**
- Gets a specific property for an algorithm. This is used to produce
- specialized algorithm parsers.
-
- @deprecated it used to a return the value of a propietary property
- for the "SUN" Cryptographic Service Provider to obtain
- algorithm-specific parameters. Used AlogorithmParameters and
- KeyFactory instead.
-
- @param algName name of algorithm to get property of
- @param propName name of property to check
-
- @return a string containing the value of the property
+ * Gets a specified property for an algorithm. The algorithm name should be a
+ * standard name. See Appendix A in the Java Cryptography Architecture API
+ * Specification & Reference for information about standard algorithm
+ * names. One possible use is by specialized algorithm parsers, which may map
+ * classes to algorithms which they understand (much like { at link Key} parsers
+ * do).
+ *
+ * @param algName the algorithm name.
+ * @param propName the name of the property to get.
+ * @return the value of the specified property.
+ * @deprecated This method used to return the value of a proprietary property
+ * in the master file of the "SUN" Cryptographic Service Provider in order to
+ * determine how to parse algorithm-specific parameters. Use the new
+ * provider-based and algorithm-independent { at link AlgorithmParameters} and
+ * { at link KeyFactory} engine classes (introduced in the Java 2 platform)
+ * instead.
*/
public static String getAlgorithmProperty(String algName, String propName)
{
- /* TODO: Figure out what this actually does */
+ if (algName == null || propName == null)
+ return null;
+
+ String property = String.valueOf(propName) + "." + String.valueOf(algName);
+ Provider p;
+ for (Iterator i = providers.iterator(); i.hasNext(); )
+ {
+ p = (Provider) i.next();
+ for (Iterator j = p.keySet().iterator(); j.hasNext(); )
+ {
+ String key = (String) j.next();
+ if (key.equalsIgnoreCase(property))
+ return p.getProperty(key);
+ }
+ }
return null;
}
/**
- Adds a new provider, at a specified position. The position is the
- preference order in which providers are searched for requested algorithms.
- Note that it is not guaranteed that this preference will be respected. The
- position is 1-based, that is, 1 is most preferred, followed by 2, and so
- on.
- <p>
- If the given provider is installed at the requested position, the
- provider that used to be at that position, and all providers with a
- position greater than position, are shifted up one position (towards the
- end of the list of installed providers).
- <p>
- A provider cannot be added if it is already installed.
- <p>
- <b>NOT IMPLEMENTED YET:</b>[
- First, if there is a security manager, its <code>checkSecurityAccess</code>
- method is called with the string
- <code>"insertProvider."+provider.getName()</code>
- to see if it's ok to add a new provider. If the default implementation of
- <code>checkSecurityAccess</code> is used (i.e., that method is not
- overriden), then this will result in a call to the security manager's
- <code>checkPermission</code> method with a <code>SecurityPermission(
- "insertProvider."+provider.getName())</code> permission.]
-
- @param provider the provider to be added.
- @param position the preference position that the caller would like for
- this provider.
- @return the actual preference position (1-based) in which the provider was
- added, or -1 if the provider was not added because it is already installed.
- @throws SecurityException if a security manager exists and its <code>
- SecurityManager.checkSecurityAccess(java.lang.String)</code> method denies
- access to add a new provider.
+ * <p>Adds a new provider, at a specified position. The position is the
+ * preference order in which providers are searched for requested algorithms.
+ * Note that it is not guaranteed that this preference will be respected. The
+ * position is 1-based, that is, <code>1</code> is most preferred, followed by
+ * <code>2</code>, and so on.</p>
+ *
+ * <p>If the given provider is installed at the requested position, the
+ * provider that used to be at that position, and all providers with a
+ * position greater than position, are shifted up one position (towards the
+ * end of the list of installed providers).</p>
+ *
+ * <p>A provider cannot be added if it is already installed.</p>
+ *
+ * <p>First, if there is a security manager, its <code>checkSecurityAccess()
+ * </code> method is called with the string <code>"insertProvider."+provider.
+ * getName()</code> to see if it's ok to add a new provider. If the default
+ * implementation of <code>checkSecurityAccess()</code> is used (i.e., that
+ * method is not overriden), then this will result in a call to the security
+ * manager's <code>checkPermission()</code> method with a
+ * <code>SecurityPermission("insertProvider."+provider.getName())</code>
+ * permission.</p>
+ *
+ * @param provider the provider to be added.
+ * @param position the preference position that the caller would like for
+ * this provider.
+ * @return the actual preference position in which the provider was added, or
+ * <code>-1</code> if the provider was not added because it is already
+ * installed.
+ * @throws SecurityException if a security manager exists and its
+ * { at link SecurityManager#checkSecurityAccess(String)} method denies access
+ * to add a new provider.
+ * @see #getProvider(String)
+ * @see #removeProvider(String)
+ * @see SecurityPermission
*/
public static int insertProviderAt(Provider provider, int position)
{
@@ -186,8 +211,7 @@
int max = providers.size ();
for (int i = 0; i < max; i++)
{
- if (((Provider) providers.elementAt(i)).getName() ==
- provider.getName())
+ if (((Provider) providers.elementAt(i)).getName() == provider.getName())
return -1;
}
@@ -201,26 +225,28 @@
return position + 1;
}
-
/**
- Adds a provider to the next position available.
- <p>
- <b>NOT IMPLEMENTED YET:</b> [
- First, if there is a security manager, its <code>checkSecurityAccess</code>
- method is called with the string
- <code>"insertProvider."+provider.getName()</code>
- to see if it's ok to add a new provider. If the default implementation of
- <code>checkSecurityAccess</code> is used (i.e., that method is not
- overriden), then this will result in a call to the security manager's
- <code>checkPermission</code> method with a <code>SecurityPermission(
- "insertProvider."+provider.getName())</code> permission.]
-
- @param provider the provider to be added.
- @return the preference position in which the provider was added, or <code>
- -1</code> if the provider was not added because it is already installed.
- @throws SecurityException if a security manager exists and its <code>
- SecurityManager.checkSecurityAccess(java.lang.String)</code> method denies
- access to add a new provider.
+ * <p>Adds a provider to the next position available.</p>
+ *
+ * <p>First, if there is a security manager, its <code>checkSecurityAccess()
+ * </code> method is called with the string <code>"insertProvider."+provider.
+ * getName()</code> to see if it's ok to add a new provider. If the default
+ * implementation of <code>checkSecurityAccess()</code> is used (i.e., that
+ * method is not overriden), then this will result in a call to the security
+ * manager's <code>checkPermission()</code> method with a
+ * <code>SecurityPermission("insertProvider."+provider.getName())</code>
+ * permission.</p>
+ *
+ * @param provider the provider to be added.
+ * @return the preference position in which the provider was added, or
+ * <code>-1</code> if the provider was not added because it is already
+ * installed.
+ * @throws SecurityException if a security manager exists and its
+ * { at link SecurityManager#checkSecurityAccess(String)} method denies access
+ * to add a new provider.
+ * @see #getProvider(String)
+ * @see #removeProvider(String)
+ * @see SecurityPermission
*/
public static int addProvider(Provider provider)
{
@@ -228,18 +254,28 @@
}
/**
- Removes a provider. This allows dynamic unloading
- of providers. It will automatically shift up providers to a higher
- ranking. If the provider is not installed, it fails silently.
-
- This method checks the security manager with the call checkSecurityAccess
- with "removeProvider."+provider.getName() to see if the user can remove
- this provider.
-
- @param name name of the provider to add
-
- @throws SecurityException - if the security manager denies access to
- remove a new provider
+ * <p>Removes the provider with the specified name.</p>
+ *
+ * <p>When the specified provider is removed, all providers located at a
+ * position greater than where the specified provider was are shifted down
+ * one position (towards the head of the list of installed providers).</p>
+ *
+ * <p>This method returns silently if the provider is not installed.</p>
+ *
+ * <p>First, if there is a security manager, its <code>checkSecurityAccess()
+ * </code> method is called with the string <code>"removeProvider."+name</code>
+ * to see if it's ok to remove the provider. If the default implementation of
+ * <code>checkSecurityAccess()</code> is used (i.e., that method is not
+ * overriden), then this will result in a call to the security manager's
+ * <code>checkPermission()</code> method with a <code>SecurityPermission(
+ * "removeProvider."+name)</code> permission.</p>
+ *
+ * @param name the name of the provider to remove.
+ * @throws SecurityException if a security manager exists and its
+ * { at link SecurityManager#checkSecurityAccess(String)} method denies access
+ * to remove the provider.
+ * @see #getProvider(String)
+ * @see #addProvider(Provider)
*/
public static void removeProvider(String name)
{
@@ -247,7 +283,6 @@
if (sm != null)
sm.checkSecurityAccess("removeProvider." + name);
- Provider p = null;
int max = providers.size ();
for (int i = 0; i < max; i++)
{
@@ -260,10 +295,10 @@
}
/**
- Returns array containing all the providers. It is in the preference order
- of the providers.
-
- @return an array of installed providers
+ * Returns an array containing all the installed providers. The order of the
+ * providers in the array is their preference order.
+ *
+ * @return an array of all the installed providers.
*/
public static Provider[] getProviders()
{
@@ -273,12 +308,13 @@
}
/**
- Returns the provider with the specified name. It will return null
- if the provider cannot be found.
-
- @param name name of the requested provider
-
- @return requested provider
+ * Returns the provider installed with the specified name, if any. Returns
+ * <code>null</code> if no provider with the specified name is installed.
+ *
+ * @param name the name of the provider to get.
+ * @return the provider of the specified name.
+ * @see #removeProvider(String)
+ * @see #addProvider(Provider)
*/
public static Provider getProvider(String name)
{
@@ -294,17 +330,20 @@
}
/**
- Gets the value of a security property.
-
- This method checks the security manager with the call checkSecurityAccess
- with "getProperty."+key to see if the user can get this property.
-
- @param key property to get
-
- @return value of the property
-
- @throws SecurityException - if the security manager denies access to
- getting a property
+ * <p>Gets a security property value.</p>
+ *
+ * <p>First, if there is a security manager, its <code>checkPermission()</code>
+ * method is called with a <code>SecurityPermission("getProperty."+key)</code>
+ * permission to see if it's ok to retrieve the specified security property
+ * value.</p>
+ *
+ * @param key the key of the property being retrieved.
+ * @return the value of the security property corresponding to key.
+ * @throws SecurityException if a security manager exists and its
+ * { at link SecurityManager#checkPermission(Permission)} method denies access
+ * to retrieve the specified security property value.
+ * @see #setProperty(String, String)
+ * @see SecurityPermission
*/
public static String getProperty(String key)
{
@@ -315,18 +354,21 @@
return secprops.getProperty(key);
}
-
/**
- Sets the value of a security property.
-
- This method checks the security manager with the call checkSecurityAccess
- with "setProperty."+key to see if the user can get this property.
-
- @param key property to set
- @param datnum new value of property
-
- @throws SecurityException - if the security manager denies access to
- setting a property
+ * <p>Sets a security property value.</p>
+ *
+ * <p>First, if there is a security manager, its <code>checkPermission()</code>
+ * method is called with a <code>SecurityPermission("setProperty."+key)</code>
+ * permission to see if it's ok to set the specified security property value.
+ * </p>
+ *
+ * @param key the name of the property to be set.
+ * @param datnum the value of the property to be set.
+ * @throws SecurityException if a security manager exists and its
+ * { at link SecurityManager#checkPermission(Permission)} method denies access
+ * to set the specified security property value.
+ * @see #getProperty(String)
+ * @see SecurityPermission
*/
public static void setProperty(String key, String datnum)
{
@@ -335,5 +377,328 @@
sm.checkSecurityAccess("setProperty." + key);
secprops.put(key, datnum);
+ }
+
+ /**
+ * Returns a Set of Strings containing the names of all available algorithms
+ * or types for the specified Java cryptographic service (e.g., Signature,
+ * MessageDigest, Cipher, Mac, KeyStore). Returns an empty Set if there is no
+ * provider that supports the specified service. For a complete list of Java
+ * cryptographic services, please see the Java Cryptography Architecture API
+ * Specification & Reference. Note: the returned set is immutable.
+ *
+ * @param serviceName the name of the Java cryptographic service (e.g.,
+ * Signature, MessageDigest, Cipher, Mac, KeyStore). Note: this parameter is
+ * case-insensitive.
+ * @return a Set of Strings containing the names of all available algorithms
+ * or types for the specified Java cryptographic service or an empty set if
+ * no provider supports the specified service.
+ * @since 1.4
+ */
+ public static Set getAlgorithms(String serviceName)
+ {
+ HashSet result = new HashSet();
+ if (serviceName == null || serviceName.length() == 0)
+ return result;
+
+ serviceName = serviceName.trim();
+ if (serviceName.length() == 0)
+ return result;
+
+ serviceName = serviceName.toUpperCase()+".";
+ Provider[] providers = getProviders();
+ int ndx;
+ for (int i = 0; i < providers.length; i++)
+ for (Enumeration e = providers[i].propertyNames(); e.hasMoreElements(); )
+ {
+ String service = ((String) e.nextElement()).trim();
+ if (service.toUpperCase().startsWith(serviceName))
+ {
+ service = service.substring(serviceName.length()).trim();
+ ndx = service.indexOf(' '); // get rid of attributes
+ if (ndx != -1)
+ service = service.substring(0, ndx);
+ result.add(service);
+ }
+ }
+ return Collections.unmodifiableSet(result);
+ }
+
+ /**
+ * <p>Returns an array containing all installed providers that satisfy the
+ * specified selection criterion, or <code>null</code> if no such providers
+ * have been installed. The returned providers are ordered according to their
+ * preference order.</p>
+ *
+ * <p>A cryptographic service is always associated with a particular
+ * algorithm or type. For example, a digital signature service is always
+ * associated with a particular algorithm (e.g., <i>DSA</i>), and a
+ * CertificateFactory service is always associated with a particular
+ * certificate type (e.g., <i>X.509</i>).</p>
+ *
+ * <p>The selection criterion must be specified in one of the following two
+ * formats:</p>
+ *
+ * <ul>
+ * <li><p><crypto_service>.<algorithm_or_type></p>
+ * <p>The cryptographic service name must not contain any dots.</p>
+ * <p>A provider satisfies the specified selection criterion iff the
+ * provider implements the specified algorithm or type for the specified
+ * cryptographic service.</p>
+ * <p>For example, "CertificateFactory.X.509" would be satisfied by any
+ * provider that supplied a CertificateFactory implementation for X.509
+ * certificates.</p></li>
+ *
+ * <li><p><crypto_service>.<algorithm_or_type> <attribute_name>:<attribute_value></p>
+ * <p>The cryptographic service name must not contain any dots. There must
+ * be one or more space charaters between the the <algorithm_or_type>
+ * and the <attribute_name>.</p>
+ * <p>A provider satisfies this selection criterion iff the provider
+ * implements the specified algorithm or type for the specified
+ * cryptographic service and its implementation meets the constraint
+ * expressed by the specified attribute name/value pair.</p>
+ * <p>For example, "Signature.SHA1withDSA KeySize:1024" would be satisfied
+ * by any provider that implemented the SHA1withDSA signature algorithm
+ * with a keysize of 1024 (or larger).</p></li>
+ * </ul>
+ *
+ * <p>See Appendix A in the Java Cryptogaphy Architecture API Specification
+ * & Reference for information about standard cryptographic service names,
+ * standard algorithm names and standard attribute names.</p>
+ *
+ * @param filter the criterion for selecting providers. The filter is case-
+ * insensitive.
+ * @return all the installed providers that satisfy the selection criterion,
+ * or null if no such providers have been installed.
+ * @throws InvalidParameterException if the filter is not in the required
+ * format.
+ * @see #getProviders(Map)
+ */
+ public static Provider[] getProviders(String filter)
+ {
+ if (providers == null || providers.isEmpty())
+ return null;
+
+ if (filter == null || filter.length() == 0)
+ return getProviders();
+
+ HashMap map = new HashMap(1);
+ int i = filter.indexOf(':');
+ if (i == -1) // <service>.<algorithm>
+ map.put(filter, "");
+ else // <service>.<algorithm> <attribute>:<value>
+ map.put(filter.substring(0, i), filter.substring(i+1));
+
+ return getProviders(map);
+ }
+
+ /**
+ * <p>Returns an array containing all installed providers that satisfy the
+ * specified selection criteria, or <code>null</code> if no such providers
+ * have been installed. The returned providers are ordered according to their
+ * preference order.</p>
+ *
+ * <p>The selection criteria are represented by a map. Each map entry
+ * represents a selection criterion. A provider is selected iff it satisfies
+ * all selection criteria. The key for any entry in such a map must be in one
+ * of the following two formats:</p>
+ *
+ * <ul>
+ * <li><p><crypto_service>.<algorithm_or_type></p>
+ * <p>The cryptographic service name must not contain any dots.</p>
+ * <p>The value associated with the key must be an empty string.</p>
+ * <p>A provider satisfies this selection criterion iff the provider
+ * implements the specified algorithm or type for the specified
+ * cryptographic service.</p></li>
+ *
+ * <li><p><crypto_service>.<algorithm_or_type> <attribute_name></p>
+ * <p>The cryptographic service name must not contain any dots. There must
+ * be one or more space charaters between the <algorithm_or_type> and
+ * the <attribute_name>.</p>
+ * <p>The value associated with the key must be a non-empty string. A
+ * provider satisfies this selection criterion iff the provider implements
+ * the specified algorithm or type for the specified cryptographic service
+ * and its implementation meets the constraint expressed by the specified
+ * attribute name/value pair.</p></li>
+ * </ul>
+ *
+ * <p>See Appendix A in the Java Cryptogaphy Architecture API Specification
+ * & Reference for information about standard cryptographic service names,
+ * standard algorithm names and standard attribute names.</p>
+ *
+ * @param filter the criteria for selecting providers. The filter is case-
+ * insensitive.
+ * @return all the installed providers that satisfy the selection criteria,
+ * or <code>null</code> if no such providers have been installed.
+ * @throws InvalidParameterException if the filter is not in the required
+ * format.
+ * @see #getProviders(String)
+ */
+ public static Provider[] getProviders(Map filter)
+ {
+ if (providers == null || providers.isEmpty())
+ return null;
+
+ if (filter == null)
+ return getProviders();
+
+ Set querries = filter.keySet();
+ if (querries == null || querries.isEmpty())
+ return getProviders();
+
+ LinkedHashSet result = new LinkedHashSet(providers); // assume all
+ int dot, ws;
+ String querry, service, algorithm, attribute, value;
+ LinkedHashSet serviceProviders = new LinkedHashSet(); // preserve insertion order
+ for (Iterator i = querries.iterator(); i.hasNext(); )
+ {
+ querry = (String) i.next();
+ if (querry == null) // all providers
+ continue;
+
+ querry = querry.trim();
+ if (querry.length() == 0) // all providers
+ continue;
+
+ dot = querry.indexOf('.');
+ if (dot == -1) // syntax error
+ throw new InvalidParameterException(
+ "missing dot in '" + String.valueOf(querry)+"'");
+
+ value = (String) filter.get(querry);
+ // deconstruct querry into [service, algorithm, attribute]
+ if (value == null || value.trim().length() == 0) // <service>.<algorithm>
+ {
+ value = null;
+ attribute = null;
+ service = querry.substring(0, dot).trim();
+ algorithm = querry.substring(dot+1).trim();
+ }
+ else // <service>.<algorithm> <attribute>
+ {
+ ws = querry.indexOf(' ');
+ if (ws == -1)
+ throw new InvalidParameterException(
+ "value (" + String.valueOf(value) +
+ ") is not empty, but querry (" + String.valueOf(querry) +
+ ") is missing at least one space character");
+ value = value.trim();
+ attribute = querry.substring(ws+1).trim();
+ // was the dot in the attribute?
+ if (attribute.indexOf('.') != -1)
+ throw new InvalidParameterException(
+ "attribute_name (" + String.valueOf(attribute) +
+ ") in querry (" + String.valueOf(querry) + ") contains a dot");
+
+ querry = querry.substring(0, ws).trim();
+ service = querry.substring(0, dot).trim();
+ algorithm = querry.substring(dot+1).trim();
+ }
+
+ // service and algorithm must not be empty
+ if (service.length() == 0)
+ throw new InvalidParameterException(
+ "<crypto_service> in querry (" + String.valueOf(querry) +
+ ") is empty");
+
+ if (algorithm.length() == 0)
+ throw new InvalidParameterException(
+ "<algorithm_or_type> in querry (" + String.valueOf(querry) +
+ ") is empty");
+
+ selectProviders(service, algorithm, attribute, value, result, serviceProviders);
+ result.retainAll(serviceProviders); // eval next retaining found providers
+ if (result.isEmpty()) // no point continuing
+ break;
+ }
+
+ if (result.isEmpty())
+ return null;
+
+ return (Provider[]) result.toArray(new Provider[0]);
+ }
+
+ private static void selectProviders(String svc, String algo, String attr,
+ String val, LinkedHashSet providerSet,
+ LinkedHashSet result)
+ {
+ result.clear(); // ensure we start with an empty result set
+ for (Iterator i = providerSet.iterator(); i.hasNext(); )
+ {
+ Provider p = (Provider) i.next();
+ if (provides(p, svc, algo, attr, val))
+ result.add(p);
+ }
+ }
+
+ private static boolean provides(Provider p, String svc, String algo,
+ String attr, String val)
+ {
+ Iterator it;
+ String serviceDotAlgorithm = null;
+ String key = null;
+ String realVal;
+ boolean found = false;
+ // if <svc>.<algo> <attr> is in the set then so is <svc>.<algo>
+ // but it may be stored under an alias <algo>. resolve
+ outer: for (int r = 0; r < 3; r++) // guard against circularity
+ {
+ serviceDotAlgorithm = (svc+"."+String.valueOf(algo)).trim();
+ inner: for (it = p.keySet().iterator(); it.hasNext(); )
+ {
+ key = (String) it.next();
+ if (key.equalsIgnoreCase(serviceDotAlgorithm)) // eureka
+ {
+ found = true;
+ break outer;
+ }
+ // it may be there but as an alias
+ if (key.equalsIgnoreCase(ALG_ALIAS + serviceDotAlgorithm))
+ {
+ algo = p.getProperty(key);
+ continue outer;
+ }
+ // else continue inner
+ }
+ }
+
+ if (!found)
+ return false;
+
+ // found a candidate for the querry. do we have an attr to match?
+ if (val == null) // <service>.<algorithm> querry
+ return true;
+
+ // <service>.<algorithm> <attribute>; find the key entry that match
+ String realAttr;
+ int limit = serviceDotAlgorithm.length() + 1;
+ for (it = p.keySet().iterator(); it.hasNext(); )
+ {
+ key = (String) it.next();
+ if (key.length() <= limit)
+ continue;
+
+ if (key.substring(0, limit).equalsIgnoreCase(serviceDotAlgorithm+" "))
+ {
+ realAttr = key.substring(limit).trim();
+ if (! realAttr.equalsIgnoreCase(attr))
+ continue;
+
+ // eveything matches so far. do the value
+ realVal = p.getProperty(key);
+ if (realVal == null)
+ return false;
+
+ realVal = realVal.trim();
+ // is it a string value?
+ if (val.equalsIgnoreCase(realVal))
+ return true;
+
+ // assume value is a number. cehck for greater-than-or-equal
+ return (new Integer(val).intValue() >= new Integer(realVal).intValue());
+ }
+ }
+
+ return false;
}
}
Index: libjava/java/security/Signature.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/security/Signature.java,v
retrieving revision 1.4
diff -u -r1.4 Signature.java
--- libjava/java/security/Signature.java 17 Nov 2002 00:10:24 -0000 1.4
+++ libjava/java/security/Signature.java 19 Apr 2003 20:19:47 -0000
@@ -1,5 +1,5 @@
/* Signature.java --- Signature Class
- Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -36,73 +36,113 @@
exception statement from your version. */
package java.security;
+
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
import java.security.spec.AlgorithmParameterSpec;
/**
- Signature is used to provide an interface to digital signature
- algorithms. Digital signatures provide authentication and data
- integrity of digital data.
-
- The GNU provider provides the NIST standard DSA which uses DSA
- and SHA-1. It can be specified by SHA/DSA, SHA-1/DSA or its
- OID. If the RSA signature algorithm is provided then
- it could be MD2/RSA. MD5/RSA, or SHA-1/RSA. The algorithm must
- be specified because there is no default.
-
- Signature provides implementation-independent algorithms which
- are requested by the user through getInstance. It can be
- requested by specifying just the algorithm name or by
- specifying both the algorithm name and provider name.
-
- The three phases of using Signature are:
-
- 1. Initialing
-
- * It must be initialized with a private key for signing.
- * It must be initialized with a public key for verifying.
-
- 2. Updating
-
- Update the bytes for signing or verifying with calls to update.
-
- 3. Signing or Verify the signature on the currently stored
- bytes by calling sign or verify.
-
- @author Mark Benvenuto <ivymccough at worldnet dot att dot net>
- @since JDK 1.1
+ * <p>This <code>Signature</code> class is used to provide applications the
+ * functionality of a digital signature algorithm. Digital signatures are used
+ * for authentication and integrity assurance of digital data.</p>
+ *
+ * <p>The signature algorithm can be, among others, the NIST standard <i>DSS</i>,
+ * using <i>DSA</i> and <i>SHA-1</i>. The <i>DSA</i> algorithm using the
+ * <i>SHA-1</i> message digest algorithm can be specified as <code>SHA1withDSA
+ * </code>. In the case of <i>RSA</i>, there are multiple choices for the
+ * message digest algorithm, so the signing algorithm could be specified as, for
+ * example, <code>MD2withRSA</code>, <code>MD5withRSA</code>, or
+ * <code>SHA1withRSA</code>. The algorithm name must be specified, as there is
+ * no default.</p>
+ *
+ * <p>Like other algorithm-based classes in Java Security, <code>Signature</code>
+ * provides implementation-independent algorithms, whereby a caller (application
+ * code) requests a particular signature algorithm and is handed back a properly
+ * initialized <code>Signature</code> object. It is also possible, if desired,
+ * to request a particular algorithm from a particular provider. See the
+ * <code>getInstance()</code> methods.</p>
+ *
+ * <p>Thus, there are two ways to request a <code>Signature</code> algorithm
+ * object: by specifying either just an algorithm name, or both an algorithm
+ * name and a package provider.</p>
+ *
+ * <p>If just an algorithm name is specified, the system will determine if there
+ * is an implementation of the algorithm requested available in the environment,
+ * and if there is more than one, if there is a preferred one.</p>
+ *
+ * <p>If both an algorithm name and a package provider are specified, the system
+ * will determine if there is an implementation of the algorithm in the package
+ * requested, and throw an exception if there is not.</p>
+ *
+ * <p>A <code>Signature</code> object can be used to generate and verify digital
+ * signatures.</p>
+ *
+ * <p>There are three phases to the use of a <code>Signature</code> object for
+ * either signing data or verifying a signature:</p>
+ *
+ * <ol>
+ * <li>Initialization, with either
+ * <ul>
+ * <li>a public key, which initializes the signature for verification
+ * (see <code>initVerify()</code>), or</li>
+ * <li>a private key (and optionally a Secure Random Number Generator),
+ * which initializes the signature for signing (see
+ * { at link #initSign(PrivateKey)} and { at link #initSign(PrivateKey, SecureRandom)}
+ * ).</li>
+ * </ul></li>
+ * <li>Updating<br/>
+ * Depending on the type of initialization, this will update the bytes to
+ * be signed or verified. See the update methods.<br/></li>
+ * <li>Signing or Verifying a signature on all updated bytes. See the
+ * <code>sign()</code> methods and the <code>verify()</code> method.</li>
+ * </ol>
+ *
+ * <p>Note that this class is abstract and extends from { at link SignatureSpi} for
+ * historical reasons. Application developers should only take notice of the
+ * methods defined in this <code>Signature</code> class; all the methods in the
+ * superclass are intended for cryptographic service providers who wish to
+ * supply their own implementations of digital signature algorithms.
+ *
+ * @author Mark Benvenuto <ivymccough at worldnet dot att dot net>
*/
public abstract class Signature extends SignatureSpi
{
+ /** Service name for signatures. */
+ private static final String SIGNATURE = "Signature";
+
/**
- Possible state variable which signifies if it has not been
- initialized.
+ * Possible <code>state</code> value, signifying that this signature object
+ * has not yet been initialized.
*/
- protected static final int UNINITIALIZED = 1;
+ protected static final int UNINITIALIZED = 0;
+
+ // Constructor.
+ // ------------------------------------------------------------------------
/**
- Possible state variable which signifies if it has been
- initialized for signing.
+ * Possible <code>state</code> value, signifying that this signature object
+ * has been initialized for signing.
*/
protected static final int SIGN = 2;
/**
- Possible state variable which signifies if it has been
- initialized for verifying.
+ * Possible <code>state</code> value, signifying that this signature object
+ * has been initialized for verification.
*/
protected static final int VERIFY = 3;
- /**
- State of this Signature class.
- */
+ /** Current state of this signature object. */
protected int state = UNINITIALIZED;
private String algorithm;
Provider provider;
/**
- Creates a new signature for this algorithm.
-
- @param algorithm the algorithm to use
+ * Creates a <code>Signature</code> object for the specified algorithm.
+ *
+ * @param algorithm the standard string name of the algorithm. See Appendix A
+ * in the Java Cryptography Architecture API Specification & Reference for
+ * information about standard algorithm names.
*/
protected Signature(String algorithm)
{
@@ -111,21 +151,24 @@
}
/**
- Gets an instance of the Signature class representing
- the specified signature. If the algorithm is not found then,
- it throws NoSuchAlgorithmException.
-
- @param algorithm the name of signature algorithm to choose
- @return a Signature repesenting the desired algorithm
-
- @throws NoSuchAlgorithmException if the algorithm is not implemented by
- providers
+ * Generates a <code>Signature</code> object that implements the specified
+ * digest algorithm. If the default provider package provides an
+ * implementation of the requested digest algorithm, an instance of
+ * <code>Signature</code> containing that implementation is returned. If the
+ * algorithm is not available in the default package, other packages are
+ * searched.
+ *
+ * @param algorithm the standard name of the algorithm requested. See Appendix
+ * A in the Java Cryptography Architecture API Specification & Reference
+ * for information about standard algorithm names.
+ * @return the new Signature object.
+ * @throws NoSuchAlgorithmException if the algorithm is not available in the
+ * environment.
*/
public static Signature getInstance(String algorithm)
throws NoSuchAlgorithmException
{
Provider[] p = Security.getProviders();
-
for (int i = 0; i < p.length; i++)
{
try
@@ -138,24 +181,30 @@
throw new NoSuchAlgorithmException(algorithm);
}
- /**
- Gets an instance of the Signature class representing
- the specified signature from the specified provider. If the
- algorithm is not found then, it throws NoSuchAlgorithmException.
- If the provider is not found, then it throws
- NoSuchProviderException.
-
- @param algorithm the name of signature algorithm to choose
- @param provider the name of the provider to find the algorithm in
- @return a Signature repesenting the desired algorithm
-
- @throws NoSuchAlgorithmException if the algorithm is not implemented by
- the provider
- @throws NoSuchProviderException if the provider is not found
+ /**
+ * Generates a <code>Signature</code> object implementing the specified
+ * algorithm, as supplied from the specified provider, if such an algorithm
+ * is available from the provider.
+ *
+ * @param algorithm the name of the algorithm requested. See Appendix A in
+ * the Java Cryptography Architecture API Specification & Reference for
+ * information about standard algorithm names.
+ * @param provider the name of the provider.
+ * @return the new <code>Signature</code> object.
+ * @throws NoSuchAlgorithmException if the algorithm is not available in the
+ * package supplied by the requested provider.
+ * @throws NoSuchProviderException if the provider is not available in the
+ * environment.
+ * @throws IllegalArgumentException if the provider name is <code>null</code>
+ * or empty.
+ * @see Provider
*/
public static Signature getInstance(String algorithm, String provider)
throws NoSuchAlgorithmException, NoSuchProviderException
{
+ if (provider == null || provider.length() == 0)
+ throw new IllegalArgumentException("Illegal provider");
+
Provider p = Security.getProvider(provider);
if (p == null)
throw new NoSuchProviderException(provider);
@@ -163,69 +212,54 @@
return getInstance(algorithm, p);
}
- private static Signature getInstance(String algorithm, Provider p)
+ /**
+ * Generates a <code>Signature</code> object implementing the specified
+ * algorithm, as supplied from the specified provider, if such an algorithm
+ * is available from the provider. Note: the provider doesn't have to be
+ * registered.
+ *
+ * @param algorithm the name of the algorithm requested. See Appendix A in
+ * the Java Cryptography Architecture API Specification & Reference for
+ * information about standard algorithm names.
+ * @param provider the provider.
+ * @return the new <code>Signature</code> object.
+ * @throws NoSuchAlgorithmException if the <code>algorithm</code> is not
+ * available in the package supplied by the requested <code>provider</code>.
+ * @throws IllegalArgumentException if the <code>provider</code> is
+ * <code>null</code>.
+ * @since 1.4
+ * @see Provider
+ */
+ public static Signature getInstance(String algorithm, Provider provider)
throws NoSuchAlgorithmException
{
- // try the name as is
- String className = p.getProperty("Signature." + algorithm);
- if (className == null) { // try all uppercase
- String upper = algorithm.toUpperCase();
- className = p.getProperty("Signature." + upper);
- if (className == null) { // try if it's an alias
- String alias = p.getProperty("Alg.Alias.Signature." + algorithm);
- if (alias == null) {
- alias = p.getProperty("Alg.Alias.Signature." + upper);
- if (alias == null) { // spit the dummy
- throw new NoSuchAlgorithmException(algorithm);
- }
- }
- className = p.getProperty("Signature." + alias);
- if (className == null) {
- throw new NoSuchAlgorithmException(algorithm);
- }
- }
- }
- return getInstance(className, algorithm, p);
- }
+ if (provider == null)
+ throw new IllegalArgumentException("Illegal provider");
- private static Signature getInstance(String classname,
- String algorithm,
- Provider provider)
- throws NoSuchAlgorithmException
- {
- try
- {
- Object o = Class.forName(classname).newInstance();
- Signature sig;
- if (o instanceof SignatureSpi)
- sig = new DummySignature((SignatureSpi) o, algorithm);
- else
- {
- sig = (Signature) o;
- sig.algorithm = algorithm;
- }
+ Signature result = null;
+ Object o = Engine.getInstance(SIGNATURE, algorithm, provider);
- sig.provider = provider;
- return sig;
- }
- catch (ClassNotFoundException cnfe)
+ if (o instanceof SignatureSpi)
{
- throw new NoSuchAlgorithmException("Class not found");
+ result = new DummySignature((SignatureSpi) o, algorithm);
}
- catch (InstantiationException ie)
+ else if (o instanceof Signature)
{
- throw new NoSuchAlgorithmException("Class instantiation failed");
+ result = (Signature) o;
+ result.algorithm = algorithm;
}
- catch (IllegalAccessException iae)
+ else
{
- throw new NoSuchAlgorithmException("Illegal Access");
+ throw new NoSuchAlgorithmException(algorithm);
}
+ result.provider = provider;
+ return result;
}
/**
- Gets the provider that the Signature is from.
-
- @return the provider of this Signature
+ * Returns the provider of this signature object.
+ *
+ * @return the provider of this signature object.
*/
public final Provider getProvider()
{
@@ -233,12 +267,12 @@
}
/**
- Initializes this class with the public key for
- verification purposes.
-
- @param publicKey the public key to verify with
-
- @throws InvalidKeyException invalid key
+ * Initializes this object for verification. If this method is called again
+ * with a different argument, it negates the effect of this call.
+ *
+ * @param publicKey the public key of the identity whose signature is going
+ * to be verified.
+ * @throws InvalidKeyException if the key is invalid.
*/
public final void initVerify(PublicKey publicKey) throws InvalidKeyException
{
@@ -247,39 +281,43 @@
}
/**
- Verify Signature with a certificate. This is a FIPS 140-1 compatible method
- since it verifies a signature with a certificate.
-
- If the certificate is an X.509 certificate, has a KeyUsage parameter and
- the parameter indicates this key is not to be used for signing then an
- error is returned.
-
- @param certificate a certificate containing a public key to verify with
+ * <p>Initializes this object for verification, using the public key from the
+ * given certificate.</p>
+ *
+ * <p>If the certificate is of type <i>X.509</i> and has a <i>key usage</i>
+ * extension field marked as <i>critical</i>, and the value of the <i>key
+ * usage</i> extension field implies that the public key in the certificate
+ * and its corresponding private key are not supposed to be used for digital
+ * signatures, an { at link InvalidKeyException} is thrown.</p>
+ *
+ * @param certificate the certificate of the identity whose signature is
+ * going to be verified.
+ * @throws InvalidKeyException if the public key in the certificate is not
+ * encoded properly or does not include required parameter information or
+ * cannot be used for digital signature purposes.
*/
- public final void initVerify(java.security.cert.Certificate certificate)
+ public final void initVerify(Certificate certificate)
throws InvalidKeyException
{
state = VERIFY;
if (certificate.getType().equals("X509"))
{
- java.security.cert.X509Certificate cert =
- (java.security.cert.X509Certificate) certificate;
-
+ X509Certificate cert = (X509Certificate) certificate;
boolean[]array = cert.getKeyUsage();
if (array != null && array[0] == false)
- throw new InvalidKeyException
- ("KeyUsage of this Certificate indicates it cannot be used for digital signing");
+ throw new InvalidKeyException(
+ "KeyUsage of this Certificate indicates it cannot be used for digital signing");
}
this.initVerify(certificate.getPublicKey());
}
/**
- Initializes this class with the private key for
- signing purposes.
-
- @param privateKey the private key to sign with
-
- @throws InvalidKeyException invalid key
+ * Initialize this object for signing. If this method is called again with a
+ * different argument, it negates the effect of this call.
+ *
+ * @param privateKey the private key of the identity whose signature is going
+ * to be generated.
+ * @throws InvalidKeyException if the key is invalid.
*/
public final void initSign(PrivateKey privateKey) throws InvalidKeyException
{
@@ -288,15 +326,13 @@
}
/**
- Initializes this class with the private key and source
- of randomness for signing purposes.
-
- @param privateKey the private key to sign with
- @param random Source of randomness
-
- @throws InvalidKeyException invalid key
-
- @since JDK 1.2
+ * Initialize this object for signing. If this method is called again with a
+ * different argument, it negates the effect of this call.
+ *
+ * @param privateKey the private key of the identity whose signature is going
+ * to be generated.
+ * @param random the source of randomness for this signature.
+ * @throws InvalidKeyException if the key is invalid.
*/
public final void initSign(PrivateKey privateKey, SecureRandom random)
throws InvalidKeyException
@@ -305,91 +341,137 @@
engineInitSign(privateKey, random);
}
-
/**
- Returns the signature bytes of all the data fed to this class.
- The format of the output depends on the underlying signature
- algorithm.
-
- @return the signature
-
- @throws SignatureException engine not properly initialized
+ * <p>Returns the signature bytes of all the data updated. The format of the
+ * signature depends on the underlying signature scheme.</p>
+ *
+ * <p>A call to this method resets this signature object to the state it was
+ * in when previously initialized for signing via a call to
+ * <code>initSign(PrivateKey)</code>. That is, the object is reset and
+ * available to generate another signature from the same signer, if desired,
+ * via new calls to <code>update()</code> and <code>sign()</code>.</p>
+ *
+ * @return the signature bytes of the signing operation's result.
+ * @throws SignatureException if this signature object is not initialized
+ * properly.
*/
public final byte[] sign() throws SignatureException
{
if (state == SIGN)
{
- state = UNINITIALIZED;
- return engineSign();
+ state = UNINITIALIZED;
+ return engineSign();
}
else
throw new SignatureException();
}
/**
- Generates signature bytes of all the data fed to this class
- and outputs it to the passed array. The format of the
- output depends on the underlying signature algorithm.
-
- After calling this method, the signature is reset to its
- initial state and can be used to generate additional
- signatures.
-
- @param outbuf array of bytes
- @param offset the offset to start at in the array
- @param len the length of the bytes to put into the array.
- Neither this method or the GNU provider will
- return partial digests. If len is less than the
- signature length, this method will throw
- SignatureException. If it is greater than or equal
- then it is ignored.
-
- @return number of bytes in outbuf
-
- @throws SignatureException engine not properly initialized
-
- @since JDK 1.2
+ * <p>Finishes the signature operation and stores the resulting signature
+ * bytes in the provided buffer <code>outbuf</code>, starting at <code>offset
+ * </code>. The format of the signature depends on the underlying signature
+ * scheme.</p>
+ *
+ * <p>This signature object is reset to its initial state (the state it was
+ * in after a call to one of the <code>initSign()</code> methods) and can be
+ * reused to generate further signatures with the same private key.</p>
+ *
+ * @param outbuf buffer for the signature result.
+ * @param offset offset into outbuf where the signature is stored.
+ * @param len number of bytes within outbuf allotted for the signature.
+ * @return the number of bytes placed into outbuf.
+ * @throws SignatureException if an error occurs or len is less than the
+ * actual signature length.
+ * @since 1.2
*/
public final int sign(byte[] outbuf, int offset, int len)
throws SignatureException
{
if (state == SIGN)
{
- state = UNINITIALIZED;
- return engineSign(outbuf, offset, len);
+ state = UNINITIALIZED;
+ return engineSign(outbuf, offset, len);
}
else
throw new SignatureException();
}
/**
- Verifies the passed signature.
-
- @param signature the signature bytes to verify
-
- @return true if verified, false otherwise
-
- @throws SignatureException engine not properly initialized
- or wrong signature
+ * <p>Verifies the passed-in signature.</p>
+ *
+ * <p>A call to this method resets this signature object to the state it was
+ * in when previously initialized for verification via a call to
+ * <code>initVerify(PublicKey)</code>. That is, the object is reset and
+ * available to verify another signature from the identity whose public key
+ * was specified in the call to <code>initVerify()</code>.</p>
+ *
+ * @param signature the signature bytes to be verified.
+ * @return <code>true</code> if the signature was verified, <code>false</code>
+ * if not.
+ * @throws SignatureException if this signature object is not initialized
+ * properly, or the passed-in signature is improperly encoded or of the wrong
+ * type, etc.
*/
public final boolean verify(byte[]signature) throws SignatureException
{
if (state == VERIFY)
{
- state = UNINITIALIZED;
- return engineVerify(signature);
+ state = UNINITIALIZED;
+ return engineVerify(signature);
}
else
throw new SignatureException();
}
/**
- Updates the data to be signed or verified with the specified
- byte.
+ * <p>Verifies the passed-in <code>signature</code> in the specified array of
+ * bytes, starting at the specified <code>offset</code>.</p>
+ *
+ * <p>A call to this method resets this signature object to the state it was
+ * in when previously initialized for verification via a call to
+ * <code>initVerify(PublicKey)</code>. That is, the object is reset and
+ * available to verify another signature from the identity whose public key
+ * was specified in the call to <code>initVerify()</code>.</p>
+ *
+ * @param signature the signature bytes to be verified.
+ * @param offset the offset to start from in the array of bytes.
+ * @param length the number of bytes to use, starting at offset.
+ * @return <code>true</code> if the signature was verified, <code>false</code>
+ * if not.
+ * @throws SignatureException if this signature object is not initialized
+ * properly, or the passed-in <code>signature</code> is improperly encoded or
+ * of the wrong type, etc.
+ * @throws IllegalArgumentException if the <code>signature</code> byte array
+ * is <code>null</code>, or the <code>offset</code> or <code>length</code> is
+ * less than <code>0</code>, or the sum of the <code>offset</code> and
+ * <code>length</code> is greater than the length of the <code>signature</code>
+ * byte array.
+ */
+ public final boolean verify(byte[] signature, int offset, int length)
+ throws SignatureException
+ {
+ if (state != VERIFY)
+ throw new SignatureException("illegal state");
- @param b byte to update with
+ if (signature == null)
+ throw new IllegalArgumentException("signaure is null");
+ if (offset < 0)
+ throw new IllegalArgumentException("offset is less than 0");
+ if (length < 0)
+ throw new IllegalArgumentException("length is less than 0");
+ if (offset + length < signature.length)
+ throw new IllegalArgumentException("range is out of bounds");
- @throws SignatureException Engine not properly initialized
+ state = UNINITIALIZED;
+ return engineVerify(signature, offset, length);
+ }
+
+ /**
+ * Updates the data to be signed or verified by a byte.
+ *
+ * @param b the byte to use for the update.
+ * @throws SignatureException if this signature object is not initialized
+ * properly.
*/
public final void update(byte b) throws SignatureException
{
@@ -400,12 +482,12 @@
}
/**
- Updates the data to be signed or verified with the specified
- bytes.
-
- @param data array of bytes
-
- @throws SignatureException engine not properly initialized
+ * Updates the data to be signed or verified, using the specified array of
+ * bytes.
+ *
+ * @param data the byte array to use for the update.
+ * @throws SignatureException if this signature object is not initialized
+ * properly.
*/
public final void update(byte[]data) throws SignatureException
{
@@ -416,14 +498,14 @@
}
/**
- Updates the data to be signed or verified with the specified
- bytes.
-
- @param data array of bytes
- @param off the offset to start at in the array
- @param len the length of the bytes to use in the array
-
- @throws SignatureException engine not properly initialized
+ * Updates the data to be signed or verified, using the specified array of
+ * bytes, starting at the specified offset.
+ *
+ * @param data the array of bytes.
+ * @param off the offset to start from in the array of bytes.
+ * @param len the number of bytes to use, starting at offset.
+ * @throws SignatureException if this signature object is not initialized
+ * properly.
*/
public final void update(byte[]data, int off, int len)
throws SignatureException
@@ -434,11 +516,10 @@
throw new SignatureException();
}
- /**
- Gets the name of the algorithm currently used.
- The names of algorithms are usually SHA/DSA or SHA/RSA.
-
- @return name of algorithm.
+ /**
+ * Returns the name of the algorithm for this signature object.
+ *
+ * @return the name of the algorithm for this signature object.
*/
public final String getAlgorithm()
{
@@ -446,9 +527,11 @@
}
/**
- Returns a representation of the Signature as a String
-
- @return a string representing the signature
+ * Returns a string representation of this signature object, providing
+ * information that includes the state of the object and the name of the
+ * algorithm used.
+ *
+ * @return a string representation of this signature object.
*/
public String toString()
{
@@ -456,16 +539,22 @@
}
/**
- Sets the specified algorithm parameter to the specified value.
-
- @param param parameter name
- @param value parameter value
-
- @throws InvalidParameterException invalid parameter, parameter
- already set and cannot set again, a security exception,
- etc.
-
- @deprecated use the other setParameter
+ * Sets the specified algorithm parameter to the specified value. This method
+ * supplies a general-purpose mechanism through which it is possible to set
+ * the various parameters of this object. A parameter may be any settable
+ * parameter for the algorithm, such as a parameter size, or a source of
+ * random bits for signature generation (if appropriate), or an indication of
+ * whether or not to perform a specific but optional computation. A uniform
+ * algorithm-specific naming scheme for each parameter is desirable but left
+ * unspecified at this time.
+ *
+ * @param param the string identifier of the parameter.
+ * @param value the parameter value.
+ * @throws InvalidParameterException if param is an invalid parameter for this
+ * signature algorithm engine, the parameter is already set and cannot be set
+ * again, a security exception occurs, and so on.
+ * @see #getParameter(String)
+ * @deprecated Use setParameter(AlgorithmParameterSpec).
*/
public final void setParameter(String param, Object value)
throws InvalidParameterException
@@ -474,17 +563,12 @@
}
/**
- Sets the signature engine with the specified
- AlgorithmParameterSpec;
-
- By default this always throws UnsupportedOperationException
- if not overridden;
-
- @param params the parameters
-
- @throws InvalidParameterException invalid parameter, parameter
- already set and cannot set again, a security exception,
- etc.
+ * Initializes this signature engine with the specified parameter set.
+ *
+ * @param params the parameters.
+ * @throws InvalidAlgorithmParameterException if the given parameters are
+ * inappropriate for this signature engine.
+ * @see #getParameters()
*/
public final void setParameter(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException
@@ -493,15 +577,40 @@
}
/**
- Gets the value for the specified algorithm parameter.
-
- @param param parameter name
-
- @return parameter value
-
- @throws InvalidParameterException invalid parameter
+ * <p>Returns the parameters used with this signature object.</p>
+ *
+ * <p>The returned parameters may be the same that were used to initialize
+ * this signature, or may contain a combination of default and randomly
+ * generated parameter values used by the underlying signature implementation
+ * if this signature requires algorithm parameters but was not initialized
+ * with any.
+ *
+ * @return the parameters used with this signature, or <code>null</code> if
+ * this signature does not use any parameters.
+ * @see #setParameter(AlgorithmParameterSpec)
+ */
+ public final AlgorithmParameters getParameters()
+ {
+ return engineGetParameters();
+ }
- @deprecated use the other getParameter
+ /**
+ * Gets the value of the specified algorithm parameter. This method supplies
+ * a general-purpose mechanism through which it is possible to get the various
+ * parameters of this object. A parameter may be any settable parameter for
+ * the algorithm, such as a parameter size, or a source of random bits for
+ * signature generation (if appropriate), or an indication of whether or not
+ * to perform a specific but optional computation. A uniform
+ * algorithm-specific naming scheme for each parameter is desirable but left
+ * unspecified at this time.
+ *
+ * @param param the string name of the parameter.
+ * @return the object that represents the parameter value, or null if there
+ * is none.
+ * @throws InvalidParameterException if param is an invalid parameter for this
+ * engine, or another exception occurs while trying to get this parameter.
+ * @see #setParameter(String, Object)
+ * @deprecated
*/
public final Object getParameter(String param)
throws InvalidParameterException
@@ -510,12 +619,11 @@
}
/**
- Returns a clone if cloneable.
-
- @return a clone if cloneable.
-
- @throws CloneNotSupportedException if the implementation does
- not support cloning
+ * Returns a clone if the implementation is cloneable.
+ *
+ * @return a clone if the implementation is cloneable.
+ * @throws CloneNotSupportedException if this is called on an implementation
+ * that does not support { at link Cloneable}.
*/
public Object clone() throws CloneNotSupportedException
{
Index: libjava/java/security/SignatureSpi.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/security/SignatureSpi.java,v
retrieving revision 1.2
diff -u -r1.2 SignatureSpi.java
--- libjava/java/security/SignatureSpi.java 22 Jan 2002 22:40:30 -0000 1.2
+++ libjava/java/security/SignatureSpi.java 19 Apr 2003 20:19:47 -0000
@@ -1,5 +1,5 @@
/* SignatureSpi.java --- Signature Service Provider Interface
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2003, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -36,67 +36,70 @@
exception statement from your version. */
package java.security;
+
import java.security.spec.AlgorithmParameterSpec;
/**
- SignatureSpi defines the Service Provider Interface (SPI)
- for the Signature class. The signature class provides an
- interface to a digital signature algorithm. Digital signatures
- are used for authentication and integrity of data.
-
- @author Mark Benvenuto <ivymccough at worldnet dot att dot net>
-
- @since JDK 1.2
+ * <p>This class defines the <i>Service Provider Interface (SPI)</i> for the
+ * { at link Signature} class, which is used to provide the functionality of a
+ * digital signature algorithm. Digital signatures are used for authentication
+ * and integrity assurance of digital data.</p>
+ *
+ * <p>All the abstract methods in this class must be implemented by each
+ * cryptographic service provider who wishes to supply the implementation of a
+ * particular signature algorithm.
+ *
+ * @author Mark Benvenuto <ivymccough at worldnet dot att dot net>
+ * @since 1.2
+ * @see Signature
*/
public abstract class SignatureSpi
{
- /**
- Source of randomness
- */
+ /** Application-specified source of randomness. */
protected SecureRandom appRandom;
- /**
- Creates a new instance of SignatureSpi.
- */
public SignatureSpi()
{
appRandom = null;
}
/**
- Initializes this class with the public key for
- verification purposes.
-
- @param publicKey the public key to verify with
-
- @throws InvalidKeyException invalid key
+ * Initializes this signature object with the specified public key for
+ * verification operations.
+ *
+ * @param publicKey the public key of the identity whose signature is going
+ * to be verified.
+ * @throws InvalidKeyException if the key is improperly encoded, parameters
+ * are missing, and so on.
*/
protected abstract void engineInitVerify(PublicKey publicKey)
throws InvalidKeyException;
/**
- Initializes this class with the private key for
- signing purposes.
-
- @param privateKey the private key to sign with
-
- @throws InvalidKeyException invalid key
+ * Initializes this signature object with the specified private key for
+ * signing operations.
+ *
+ * @param privateKey the private key of the identity whose signature will be
+ * generated.
+ * @throws InvalidKeyException if the key is improperly encoded, parameters
+ * are missing, and so on.
*/
protected abstract void engineInitSign(PrivateKey privateKey)
throws InvalidKeyException;
/**
- Initializes this class with the private key and source
- of randomness for signing purposes.
-
- This cannot be abstract backward compatibility reasons
-
- @param privateKey the private key to sign with
- @param random Source of randomness
-
- @throws InvalidKeyException invalid key
-
- @since JDK 1.2
+ * <p>Initializes this signature object with the specified private key and
+ * source of randomness for signing operations.</p>
+ *
+ * <p>This concrete method has been added to this previously-defined abstract
+ * class. (For backwards compatibility, it cannot be abstract.)</p>
+ *
+ * @param privateKey the private key of the identity whose signature will be
+ * generated.
+ * @param random the source of randomness.
+ * @throws InvalidKeyException if the key is improperly encoded, parameters
+ * are missing, and so on.
+ * @since 1.2
*/
protected void engineInitSign(PrivateKey privateKey, SecureRandom random)
throws InvalidKeyException
@@ -106,118 +109,135 @@
}
/**
- Updates the data to be signed or verified with the specified
- byte.
-
- @param b byte to update with
-
- @throws SignatureException Engine not properly initialized
+ * Updates the data to be signed or verified using the specified byte.
+ *
+ * @param b the byte to use for the update.
+ * @throws SignatureException if the engine is not initialized properly.
*/
protected abstract void engineUpdate(byte b) throws SignatureException;
/**
- Updates the data to be signed or verified with the specified
- bytes.
-
- @param b array of bytes
- @param off the offset to start at in the array
- @param len the length of the bytes to use in the array
-
- @throws SignatureException engine not properly initialized
+ * Updates the data to be signed or verified, using the specified array of
+ * bytes, starting at the specified offset.
+ *
+ * @param b the array of bytes.
+ * @param off the offset to start from in the array of bytes.
+ * @param len the number of bytes to use, starting at offset.
+ * @throws SignatureException if the engine is not initialized properly.
*/
protected abstract void engineUpdate(byte[] b, int off, int len)
throws SignatureException;
/**
- Returns the signature bytes of all the data fed to this class.
- The format of the output depends on the underlying signature
- algorithm.
-
- @return the signature
-
- @throws SignatureException engine not properly initialized
+ * Returns the signature bytes of all the data updated so far. The format of
+ * the signature depends on the underlying signature scheme.
+ *
+ * @return the signature bytes of the signing operation's result.
+ * @throws SignatureException if the engine is not initialized properly.
*/
protected abstract byte[] engineSign() throws SignatureException;
/**
- Generates signature bytes of all the data fed to this class
- and outputs it to the passed array. The format of the
- output depends on the underlying signature algorithm.
-
- This cannot be abstract backward compatibility reasons.
- After calling this method, the signature is reset to its
- initial state and can be used to generate additional
- signatures.
-
- @param outbuff array of bytes
- @param offset the offset to start at in the array
- @param len the length of the bytes to put into the array.
- Neither this method or the GNU provider will
- return partial digests. If len is less than the
- signature length, this method will throw
- SignatureException. If it is greater than or equal
- then it is ignored.
-
- @return number of bytes in outbuf
-
- @throws SignatureException engine not properly initialized
-
- @since JDK 1.2
+ * <p>Finishes this signature operation and stores the resulting signature
+ * bytes in the provided buffer <code>outbuf</code>, starting at <code>offset
+ * </code>. The format of the signature depends on the underlying signature
+ * scheme.</p>
+ *
+ * <p>The signature implementation is reset to its initial state (the state it
+ * was in after a call to one of the <code>engineInitSign()</code> methods)
+ * and can be reused to generate further signatures with the same private key.
+ * This method should be abstract, but we leave it concrete for binary
+ * compatibility. Knowledgeable providers should override this method.</p>
+ *
+ * @param outbuf buffer for the signature result.
+ * @param offset offset into outbuf where the signature is stored.
+ * @param len number of bytes within outbuf allotted for the signature. Both
+ * this default implementation and the <b>GNU</b> provider do not return
+ * partial digests. If the value of this parameter is less than the actual
+ * signature length, this method will throw a { at link SignatureException}. This
+ * parameter is ignored if its value is greater than or equal to the actual
+ * signature length.
+ * @return the number of bytes placed into <code>outbuf</code>.
+ * @throws SignatureException if an error occurs or len is less than the
+ * actual signature length.
+ * @since 1.2
*/
protected int engineSign(byte[] outbuf, int offset, int len)
throws SignatureException
{
byte tmp[] = engineSign();
-
if (tmp.length > len)
throw new SignatureException("Invalid Length");
System.arraycopy(outbuf, offset, tmp, 0, tmp.length);
-
return tmp.length;
}
/**
- Verifies the passed signature.
-
- @param sigBytes the signature bytes to verify
-
- @return true if verified, false otherwise
-
- @throws SignatureException engine not properly initialized
- or wrong signature
+ * Verifies the passed-in signature.
+ *
+ * @param sigBytes the signature bytes to be verified.
+ * @return <code>true</code> if the signature was verified, <code>false</code>
+ * if not.
+ * @throws SignatureException if the engine is not initialized properly, or
+ * the passed-in signature is improperly encoded or of the wrong type, etc.
*/
protected abstract boolean engineVerify(byte[] sigBytes)
throws SignatureException;
/**
- Sets the specified algorithm parameter to the specified value.
-
- @param param parameter name
- @param value parameter value
-
- @throws InvalidParameterException invalid parameter, parameter
- already set and cannot set again, a security exception,
- etc.
+ * <p>Verifies the passed-in <code>signature</code> in the specified array of
+ * bytes, starting at the specified <code>offset</code>.</p>
+ *
+ * <p>Note: Subclasses should overwrite the default implementation.</p>
+ *
+ * @param sigBytes the signature bytes to be verified.
+ * @param offset the offset to start from in the array of bytes.
+ * @param length the number of bytes to use, starting at offset.
+ * @return <code>true</code> if the signature was verified, <code>false</code>
+ * if not.
+ * @throws SignatureException if the engine is not initialized properly, or
+ * the passed-in <code>signature</code> is improperly encoded or of the wrong
+ * type, etc.
+ */
+ protected boolean engineVerify(byte[] sigBytes, int offset, int length)
+ throws SignatureException
+ {
+ byte[] tmp = new byte[length];
+ System.arraycopy(sigBytes, offset, tmp, 0, length);
+ return engineVerify(tmp);
+ }
- @deprecated use the other setParameter
+ /**
+ * Sets the specified algorithm parameter to the specified value. This method
+ * supplies a general-purpose mechanism through which it is possible to set
+ * the various parameters of this object. A parameter may be any settable
+ * parameter for the algorithm, such as a parameter size, or a source of
+ * random bits for signature generation (if appropriate), or an indication of
+ * whether or not to perform a specific but optional computation. A uniform
+ * algorithm-specific naming scheme for each parameter is desirable but left
+ * unspecified at this time.
+ *
+ * @param param the string identifier of the parameter.
+ * @param value the parameter value.
+ * @throws InvalidParameterException if <code>param</code> is an invalid
+ * parameter for this signature algorithm engine, the parameter is already set
+ * and cannot be set again, a security exception occurs, and so on.
+ * @deprecated Replaced by engineSetParameter(AlgorithmParameterSpec).
*/
protected abstract void engineSetParameter(String param, Object value)
throws InvalidParameterException;
/**
- Sets the signature engine with the specified
- AlgorithmParameterSpec;
-
- This cannot be abstract backward compatibility reasons
- By default this always throws UnsupportedOperationException
- if not overridden;
-
- @param params the parameters
-
- @throws InvalidParameterException invalid parameter, parameter
- already set and cannot set again, a security exception,
- etc.
+ * This method is overridden by providers to initialize this signature engine
+ * with the specified parameter set.
+ *
+ * @param params the parameters.
+ * @throws UnsupportedOperationException if this method is not overridden by
+ * a provider.
+ * @throws InvalidAlgorithmParameterException if this method is overridden by
+ * a provider and the the given parameters are inappropriate for this
+ * signature engine.
*/
protected void engineSetParameter(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException
@@ -226,26 +246,54 @@
}
/**
- Gets the value for the specified algorithm parameter.
-
- @param param parameter name
-
- @return parameter value
-
- @throws InvalidParameterException invalid parameter
+ * <p>This method is overridden by providers to return the parameters used
+ * with this signature engine, or <code>null</code> if this signature engine
+ * does not use any parameters.</p>
+ *
+ * <p>The returned parameters may be the same that were used to initialize
+ * this signature engine, or may contain a combination of default and randomly
+ * generated parameter values used by the underlying signature implementation
+ * if this signature engine requires algorithm parameters but was not
+ * initialized with any.</p>
+ *
+ * @return the parameters used with this signature engine, or <code>null</code>
+ * if this signature engine does not use any parameters.
+ * @throws UnsupportedOperationException if this method is not overridden by
+ * a provider.
+ */
+ protected AlgorithmParameters engineGetParameters()
+ {
+ throw new UnsupportedOperationException();
+ }
- @deprecated use the other getParameter
+ /**
+ * Gets the value of the specified algorithm parameter. This method supplies
+ * a general-purpose mechanism through which it is possible to get the various
+ * parameters of this object. A parameter may be any settable parameter for
+ * the algorithm, such as a parameter size, or a source of random bits for
+ * signature generation (if appropriate), or an indication of whether or not
+ * to perform a specific but optional computation. A uniform algorithm-specific
+ * naming scheme for each parameter is desirable but left unspecified at this
+ * time.
+ *
+ * @param param the string name of the parameter.
+ * @return the object that represents the parameter value, or <code>null</code>
+ * if there is none.
+ * @throws InvalidParameterException if <code>param<?code> is an invalid
+ * parameter for this engine, or another exception occurs while trying to get
+ * this parameter.
+ * @deprecated
*/
protected abstract Object engineGetParameter(String param)
throws InvalidParameterException;
/**
- Returns a clone if cloneable.
-
- @return a clone if cloneable.
-
- @throws CloneNotSupportedException if the implementation does
- not support cloning
+ * Returns a clone if the implementation is cloneable.
+ *
+ * @return a clone if the implementation is cloneable.
+ * @throws CloneNotSupportedException if this is called on an implementation
+ * that does not support { at link Cloneable}.
+ * @see Cloneable
*/
public Object clone() throws CloneNotSupportedException
{
Index: libjava/java/security/SignedObject.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/security/SignedObject.java,v
retrieving revision 1.4
diff -u -r1.4 SignedObject.java
--- libjava/java/security/SignedObject.java 4 Oct 2002 20:15:07 -0000 1.4
+++ libjava/java/security/SignedObject.java 19 Apr 2003 20:19:47 -0000
@@ -1,5 +1,5 @@
/* SignedObject.java --- Signed Object Class
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2003, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -36,70 +36,123 @@
exception statement from your version. */
package java.security;
+
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
/**
- SignedObject is used for storing rutime objects whose integrity
- cannot be compromised without being detected.
-
- SignedObject contains a Serializable object which is yet to be
- signed and its signature.
-
- The signed copy is a "deep copy" (in serialized form) of the
- original object. Any changes to the original will not affect
- the original.
-
- Several things to note are that, first there is no need to
- initialize the signature engine as this class will handle that
- automatically. Second, verification will only succeed if the
- public key corresponds to the private key used to generate
- the SignedObject.
-
- For fexibility, the signature engine can be specified in the
- constructor or the verify method. The programmer who writes
- code that verifies the SignedObject has not changed should be
- aware of the Signature engine they use. A malicious Signature
- may choose to always return true on verification and
- bypass the secrity check.
-
- The GNU provider provides the NIST standard DSA which uses DSA
- and SHA-1. It can be specified by SHA/DSA, SHA-1/DSA or its
- OID. If the RSA signature algorithm is provided then
- it could be MD2/RSA. MD5/RSA, or SHA-1/RSA. The algorithm must
- be specified because there is no default.
-
- @author Mark Benvenuto <ivymccough at worldnet dot att dot net>
-
- @since JDK 1.2
+ * <p><code>SignedObject</code> is a class for the purpose of creating authentic
+ * runtime objects whose integrity cannot be compromised without being detected.
+ * </p>
+ *
+ * <p>More specifically, a <code>SignedObject</code> contains another
+ * { at link Serializable} object, the (to-be-)signed object and its signature.</p>
+ *
+ * <p>The signed object is a <i>"deep copy"</i> (in serialized form) of an
+ * original object. Once the copy is made, further manipulation of the original
+ * object has no side effect on the copy.</p>
+ *
+ * <p>The underlying signing algorithm is designated by the { at link Signature}
+ * object passed to the constructor and the <code>verify()</code> method. A
+ * typical usage for signing is the following:</p>
+ *
+ * <pre>
+ * Signature signingEngine = Signature.getInstance(algorithm, provider);
+ * SignedObject so = new SignedObject(myobject, signingKey, signingEngine);
+ * </pre>
+ *
+ * <p>A typical usage for verification is the following (having received
+ * <code>SignedObject</code> so):</p>
+ *
+ * <pre>
+ * Signature verificationEngine = Signature.getInstance(algorithm, provider);
+ * if (so.verify(publickey, verificationEngine))
+ * try
+ * {
+ * Object myobj = so.getObject();
+ * }
+ * catch (ClassNotFoundException ignored) {};
+ * </pre>
+ *
+ * <p>Several points are worth noting. First, there is no need to initialize the
+ * signing or verification engine, as it will be re-initialized inside the
+ * constructor and the <code>verify()</code> method. Secondly, for verification
+ * to succeed, the specified public key must be the public key corresponding to
+ * the private key used to generate the <code>SignedObject</code>.</p>
+ *
+ * <p>More importantly, for flexibility reasons, the <code>constructor</code>
+ * and <code>verify()</code> method allow for customized signature engines,
+ * which can implement signature algorithms that are not installed formally as
+ * part of a crypto provider. However, it is crucial that the programmer writing
+ * the verifier code be aware what { at link Signature} engine is being used, as
+ * its own implementation of the <code>verify()</code> method is invoked to
+ * verify a signature. In other words, a malicious { at link Signature} may choose
+ * to always return <code>true</code> on verification in an attempt to bypass a
+ * security check.</p>
+ *
+ * <p>The signature algorithm can be, among others, the NIST standard <i>DSS</i>,
+ * using <i>DSA</i> and <i>SHA-1</i>. The algorithm is specified using the same
+ * convention as that for signatures. The <i>DSA</i> algorithm using the
+ * </i>SHA-1</i> message digest algorithm can be specified, for example, as
+ * <code>"SHA/DSA"</code> or <code>"SHA-1/DSA"</code> (they are equivalent). In
+ * the case of <i>RSA</i>, there are multiple choices for the message digest
+ * algorithm, so the signing algorithm could be specified as, for example,
+ * <code>"MD2/RSA"</code>, <code>"MD5/RSA"</code> or <code>"SHA-1/RSA"</code>.
+ * The algorithm name must be specified, as there is no default.</p>
+ *
+ * <p>The name of the Cryptography Package Provider is designated also by the
+ * { at link Signature} parameter to the <code>constructor</code> and the <code>
+ * verify()</code> method. If the provider is not specified, the default
+ * provider is used. Each installation can be configured to use a particular
+ * provider as default.</p>
+ *
+ * <p>Potential applications of <code>SignedObject</code> include:</p>
+ *
+ * <ul>
+ * <li>It can be used internally to any Java runtime as an unforgeable
+ * authorization token -- one that can be passed around without the fear that
+ * the token can be maliciously modified without being detected.</li>
+ * <li>It can be used to sign and serialize data/object for storage outside the
+ * Java runtime (e.g., storing critical access control data on disk).</li>
+ * <li>Nested <i>SignedObjects</i> can be used to construct a logical sequence
+ * of signatures, resembling a chain of authorization and delegation.</li>
+ * </ul>
+ *
+ * @author Mark Benvenuto <ivymccough at worldnet dot att dot net>
+ * @since 1.2
+ * @see Signature
*/
public final class SignedObject implements Serializable
{
static final long serialVersionUID = 720502720485447167L;
+ /** @serial */
private byte[] content;
+ /** @serial */
private byte[] signature;
+ /** @serial */
private String thealgorithm;
/**
- Constructs a new SignedObject from a Serializeable object. The
- object is signed with private key and signature engine
-
- @param object the object to sign
- @param signingKey the key to sign with
- @param signingEngine the signature engine to use
-
- @throws IOException serialization error occurred
- @throws InvalidKeyException invalid key
- @throws SignatureException signing error
+ * Constructs a <code>SignedObject</code> from any { at link Serializable}
+ * object. The given object is signed with the given signing key, using the
+ * designated signature engine.
+ *
+ * @param object the object to be signed.
+ * @param signingKey the private key for signing.
+ * @param signingEngine the signature signing engine.
+ * @throws IOException if an error occurs during serialization.
+ * @throws InvalidKeyException if the key is invalid.
+ * @throws SignatureException if signing fails.
*/
public SignedObject(Serializable object, PrivateKey signingKey,
- Signature signingEngine) throws IOException,
- InvalidKeyException, SignatureException
+ Signature signingEngine)
+ throws IOException, InvalidKeyException, SignatureException
{
thealgorithm = signingEngine.getAlgorithm();
@@ -107,6 +160,7 @@
ObjectOutputStream p = new ObjectOutputStream(ostream);
p.writeObject(object);
p.flush();
+ p.close();
content = ostream.toByteArray();
@@ -116,35 +170,39 @@
}
/**
- Returns the encapsulated object. The object is
- de-serialized before being returned.
-
- @return the encapsulated object
-
- @throws IOException de-serialization error occurred
- @throws ClassNotFoundException de-serialization error occurred
+ * Retrieves the encapsulated object. The encapsulated object is de-serialized
+ * before it is returned.
+ *
+ * @return the encapsulated object.
+ * @throws IOException if an error occurs during de-serialization.
+ * @throws ClassNotFoundException if an error occurs during de-serialization.
*/
public Object getObject() throws IOException, ClassNotFoundException
{
- ByteArrayInputStream istream = new ByteArrayInputStream(content);
+ ByteArrayInputStream bais = new ByteArrayInputStream(content);
+ ObjectInput oi = new ObjectInputStream(bais);
+ Object obj = oi.readObject();
+ oi.close();
+ bais.close();
- return new ObjectInputStream(istream).readObject();
+ return obj;
}
/**
- Returns the signature of the encapsulated object.
-
- @return a byte array containing the signature
+ * Retrieves the signature on the signed object, in the form of a byte array.
+ *
+ * @return a copy of the signature.
*/
public byte[] getSignature()
{
- return signature;
+ return (byte[]) signature.clone();
+
}
/**
- Returns the name of the signature algorithm.
-
- @return the name of the signature algorithm.
+ * Retrieves the name of the signature algorithm.
+ *
+ * @return the signature algorithm name.
*/
public String getAlgorithm()
{
@@ -152,28 +210,31 @@
}
/**
- Verifies the SignedObject by checking that the signature that
- this class contains for the encapsulated object.
-
- @param verificationKey the public key to use
- @param verificationEngine the signature engine to use
-
- @return true if signature is correct, false otherwise
-
- @throws InvalidKeyException invalid key
- @throws SignatureException signature verification failed
+ * Verifies that the signature in this <code>SignedObject</code> is the valid
+ * signature for the object stored inside, with the given verification key,
+ * using the designated verification engine.
+ *
+ * @param verificationKey the public key for verification.
+ * @param verificationEngine the signature verification engine.
+ * @return <code>true</code> if the signature is valid, <code>false</code>
+ * otherwise.
+ * @throws SignatureException if signature verification failed.
+ * @throws InvalidKeyException if the verification key is invalid.
*/
- public boolean verify(PublicKey verificationKey,
- Signature verificationEngine) throws
- InvalidKeyException, SignatureException
+ public boolean verify(PublicKey verificationKey, Signature verificationEngine)
+ throws InvalidKeyException, SignatureException
{
verificationEngine.initVerify(verificationKey);
verificationEngine.update(content);
return verificationEngine.verify(signature);
}
- // readObject is called to restore the state of the SignedObject from a
- // stream.
- //private void readObject(ObjectInputStream s)
- // throws IOException, ClassNotFoundException
+ /** Called to restore the state of the SignedObject from a stream. */
+ private void readObject(ObjectInputStream s)
+ throws IOException, ClassNotFoundException
+ {
+ s.defaultReadObject();
+ content = (byte[]) content.clone();
+ signature = (byte[]) signature.clone();
+ }
}
Index: libjava/java/security/Signer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/security/Signer.java,v
retrieving revision 1.2
diff -u -r1.2 Signer.java
--- libjava/java/security/Signer.java 22 Jan 2002 22:40:30 -0000 1.2
+++ libjava/java/security/Signer.java 19 Apr 2003 20:19:47 -0000
@@ -1,5 +1,5 @@
/* Signer.java --- Signer Class
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2003, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,28 +38,35 @@
package java.security;
/**
- Signer is a subclass used to store a digital signature key with
- an Identity.
-
- @author Mark Benvenuto <ivymccough at worldnet dot att dot net>
-
- @since JDK 1.1
+ * <p>This class is used to represent an { at link Identity} that can also
+ * digitally sign data.</p>
+ *
+ * <p>The management of a signer's private keys is an important and sensitive
+ * issue that should be handled by subclasses as appropriate to their intended
+ * use.</p>
+ *
+ * @author Mark Benvenuto <ivymccough at worldnet dot att dot net>
+ * @deprecated This class is no longer used. Its functionality has been replaced
+ * by <code>java.security.KeyStore</code>, the <code>java.security.cert</code>
+ * package, and <code>java.security.Principal</code>.
*/
public abstract class Signer extends Identity
{
+ static final long serialVersionUID = -1763464102261361480L;
private PrivateKey privateKey = null;
/**
- Constructs a new Signer.
+ * Creates a <code>Signer</code>. This constructor should only be used for
+ * serialization.
*/
protected Signer()
{
}
/**
- Constructs a new Signer with the specified name.
-
- @param name the name of the identity.
+ * Creates a <code>Signer</code> with the specified identity name.
+ *
+ * @param name the identity name.
*/
public Signer(String name)
{
@@ -67,31 +74,31 @@
}
/**
- Constructs a new Signer with the specifid name and
- IdentityScope.
-
- @param name the name of the identity.
- @scope the IdentityScope to use
-
- @throws KeyManagementException if duplicate identity name
- within scope
+ * Creates a <code>Signer</code> with the specified identity name and scope.
+ *
+ * @param name the identity name.
+ * @param scope the scope of the identity.
+ * @throws KeyManagementException if there is already an identity with the
+ * same name in the scope.
*/
- public Signer(String name, IdentityScope scope)
- throws KeyManagementException
+ public Signer(String name, IdentityScope scope) throws KeyManagementException
{
super(name, scope);
}
/**
- Returns the private key for this signer.
-
- This class checks the security manager with the call
- checkSecurityAccess with "getSignerPrivateKey".
-
- @returns the private key for the signer
-
- @throws SecurityException - if the security manager denies
- access to "getSignerPrivateKey"
+ * <p>Returns this signer's private key.</p>
+ *
+ * <p>First, if there is a security manager, its <code>checkSecurityAccess()
+ * </code> method is called with <code>"getSignerPrivateKey"</code> as its
+ * argument to see if it's ok to return the private key.</p>
+ *
+ * @return this signer's private key, or <code>null</code> if the private key
+ * has not yet been set.
+ * @throws SecurityException if a security manager exists and its
+ * <code>checkSecurityAccess()</code> method doesn't allow returning the
+ * private key.
+ * @see SecurityManager#checkSecurityAccess(String)
*/
public PrivateKey getPrivateKey()
{
@@ -103,17 +110,20 @@
}
/**
- Specifies the KeyPair associated with this Signer.
-
- This class checks the security manager with the call
- checkSecurityAccess with "setSignerKeyPair".
-
- @param pair the keyPair
-
- @throws InvalidParameterException invalidly intialized key pair
- @throws KeyException another key error
- @throws SecurityException - if the security manager denies
- access to "getSignerPrivateKey"
+ * <p>Sets the key pair (public key and private key) for this signer.</p>
+ *
+ * <p>First, if there is a security manager, its <code>checkSecurityAccess()
+ * </code> method is called with <code>"setSignerKeyPair"</code> as its
+ * argument to see if it's ok to set the key pair.</p>
+ *
+ * @param pair an initialized key pair.
+ * @throws InvalidParameterException if the key pair is not properly
+ * initialized.
+ * @throws KeyException if the key pair cannot be set for any other reason.
+ * @throws SecurityException if a security manager exists and its
+ * <code>checkSecurityAccess()</code> method doesn't allow setting the key
+ * pair.
+ * @see SecurityManager#checkSecurityAccess(String)
*/
public final void setKeyPair(KeyPair pair)
throws InvalidParameterException, KeyException
@@ -124,15 +134,15 @@
try
{
- if (pair.getPublic() != null)
- setPublicKey(pair.getPublic());
- else
- throw new InvalidParameterException();
+ if (pair.getPublic() != null)
+ setPublicKey(pair.getPublic());
+ else
+ throw new InvalidParameterException();
}
catch (KeyManagementException kme)
{
- throw new KeyException();
+ throw new KeyException();
}
if (pair.getPrivate() != null)
@@ -142,9 +152,10 @@
}
/**
- Returns a string representing this Signer.
-
- @returns a string representing this Signer.
+ * Returns a string of information about the signer.
+ *
+ * @return a string of information about the signer.
+ * @see SecurityManager#checkSecurityAccess(String)
*/
public String toString()
{
Index: libjava/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java
===================================================================
RCS file: libjava/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java
diff -N libjava/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ libjava/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java 19 Apr 2003 20:19:47 -0000
@@ -0,0 +1,110 @@
+/* RSAMultiPrimePrivateCrtKey.java --
+ Copyright (C) 2003, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.security.interfaces;
+
+import java.math.BigInteger;
+import java.security.spec.RSAOtherPrimeInfo;
+
+/**
+ * The interface to an RSA multi-prime private key, as defined in the PKCS#1
+ * v2.1, using the <i>Chinese Remainder Theorem</i> (CRT) information values.
+ *
+ * @since 1.4
+ * @see java.security.spec.RSAPrivateKeySpec
+ * @see java.security.spec.RSAMultiPrimePrivateCrtKeySpec
+ * @see RSAPrivateKey
+ * @see RSAPrivateCrtKey
+ */
+public interface RSAMultiPrimePrivateCrtKey extends RSAPrivateKey
+{
+ // Constants
+ // --------------------------------------------------------------------------
+
+ // Methods
+ // --------------------------------------------------------------------------
+
+ /**
+ * Returns the public exponent.
+ *
+ * @return the public exponent.
+ */
+ BigInteger getPublicExponent();
+
+ /**
+ * Returns the primeP.
+ *
+ * @return the primeP.
+ */
+ BigInteger getPrimeP();
+
+ /**
+ * Returns the primeQ.
+ *
+ * @return the primeQ.
+ */
+ BigInteger getPrimeQ();
+
+ /**
+ * Returns the primeExponentP.
+ *
+ * @return the primeExponentP.
+ */
+ BigInteger getPrimeExponentP();
+
+ /**
+ * Returns the primeExponentQ.
+ *
+ * @return the primeExponentQ.
+ */
+ BigInteger getPrimeExponentQ();
+
+ /**
+ * Returns the crtCoefficient.
+ *
+ * @return the crtCoefficient.
+ */
+ BigInteger getCrtCoefficient();
+
+ /**
+ * Returns the otherPrimeInfo or <code>null</code> if there are only two
+ * prime factors (p and q).
+ *
+ * @return the otherPrimeInfo.
+ */
+ RSAOtherPrimeInfo[] getOtherPrimeInfo();
+}
Index: libjava/java/security/spec/PSSParameterSpec.java
===================================================================
RCS file: libjava/java/security/spec/PSSParameterSpec.java
diff -N libjava/java/security/spec/PSSParameterSpec.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ libjava/java/security/spec/PSSParameterSpec.java 19 Apr 2003 20:19:47 -0000
@@ -0,0 +1,90 @@
+/* PSSParameterSpec.java --
+ Copyright (C) 2003, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.security.spec;
+
+/**
+ * This class specifies a parameter spec for RSA PSS encoding scheme, as
+ * defined in the PKCS#1 v2.1.
+ *
+ * @since 1.4
+ * @see AlgorithmParameterSpec
+ * @see java.security.Signature
+ */
+public class PSSParameterSpec implements AlgorithmParameterSpec
+{
+ // Constants and fields
+ // --------------------------------------------------------------------------
+
+ private int saltLen;
+
+ // Constructor(s)
+ // --------------------------------------------------------------------------
+
+ /**
+ * Creates a new <code>PSSParameterSpec</code> given the salt length as
+ * defined in PKCS#1.
+ *
+ * @param saltLen the length of salt in bits to be used in PKCS#1 PSS encoding.
+ * @throws IllegalArgumentException if <code>saltLen</code> is less than
+ * <code>0</code>.
+ */
+ public PSSParameterSpec(int saltLen)
+ {
+ super();
+
+ if (saltLen < 0)
+ throw new IllegalArgumentException();
+ this.saltLen = saltLen;
+ }
+
+ // Class methods
+ // --------------------------------------------------------------------------
+
+ // Instance methods
+ // --------------------------------------------------------------------------
+
+ /**
+ * Returns the salt length in bits.
+ *
+ * @return the salt length.
+ */
+ public int getSaltLength()
+ {
+ return this.saltLen;
+ }
+}
Index: libjava/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java
===================================================================
RCS file: libjava/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java
diff -N libjava/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ libjava/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java 19 Apr 2003 20:19:47 -0000
@@ -0,0 +1,218 @@
+/* PSSParameterSpec.java --
+ Copyright (C) 2003, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.security.spec;
+
+import java.math.BigInteger;
+import java.security.spec.RSAOtherPrimeInfo;
+
+/**
+ * This class specifies an RSA multi-prime private key, as defined in the
+ * PKCS#1 v2.1, using the <i>Chinese Remainder Theorem</i> (CRT) information
+ * values for efficiency.
+ *
+ * @since 1.4
+ * @see java.security.Key
+ * @see java.security.KeyFactory
+ * @see KeySpec
+ * @see PKCS8EncodedKeySpec
+ * @see RSAPrivateKeySpec
+ * @see RSAPublicKeySpec
+ * @see RSAOtherPrimeInfo
+ */
+public class RSAMultiPrimePrivateCrtKeySpec extends RSAPrivateKeySpec
+{
+ // Constants and fields
+ // --------------------------------------------------------------------------
+
+ private BigInteger publicExponent;
+ private BigInteger primeP;
+ private BigInteger primeQ;
+ private BigInteger primeExponentP;
+ private BigInteger primeExponentQ;
+ private BigInteger crtCoefficient;
+ private RSAOtherPrimeInfo[] otherPrimeInfo;
+
+ // Constructor(s)
+ // --------------------------------------------------------------------------
+
+ /**
+ * <p>Creates a new <code>RSAMultiPrimePrivateCrtKeySpec</code> given the
+ * modulus, publicExponent, privateExponent, primeP, primeQ, primeExponentP,
+ * primeExponentQ, crtCoefficient, and otherPrimeInfo as defined in PKCS#1
+ * v2.1.</p>
+ *
+ * <p>Note that <code>otherPrimeInfo</code> is cloned when constructing this
+ * object.</p>
+ *
+ * @param modulus the modulus n.
+ * @param publicExponent the public exponent e.
+ * @param privateExponent the private exponent d.
+ * @param primeP the prime factor p of n.
+ * @param primeQ the prime factor q of n.
+ * @param primeExponentP this is d mod (p-1).
+ * @param primeExponentQ this is d mod (q-1).
+ * @param crtCoefficient the Chinese Remainder Theorem coefficient q-1 mod p.
+ * @param otherPrimeInfo triplets of the rest of primes, <code>null</code>
+ * can be specified if there are only two prime factors (p and q).
+ * @throws NullPointerException if any of the parameters, i.e. modulus,
+ * publicExponent, privateExponent, primeP, primeQ, primeExponentP,
+ * primeExponentQ, crtCoefficient, is <code>null</code>.
+ * @throws IllegalArgumentException if an empty, i.e. 0-length,
+ * otherPrimeInfo is specified.
+ */
+ public RSAMultiPrimePrivateCrtKeySpec(BigInteger modulus,
+ BigInteger publicExponent,
+ BigInteger privateExponent,
+ BigInteger primeP,
+ BigInteger primeQ,
+ BigInteger primeExponentP,
+ BigInteger primeExponentQ,
+ BigInteger crtCoefficient,
+ RSAOtherPrimeInfo[] otherPrimeInfo)
+ {
+ super(modulus, privateExponent);
+
+ if (modulus == null)
+ throw new NullPointerException("modulus");
+ if (publicExponent == null)
+ throw new NullPointerException("publicExponent");
+ if (privateExponent == null)
+ throw new NullPointerException("privateExponent");
+ if (primeP == null)
+ throw new NullPointerException("primeP");
+ if (primeQ == null)
+ throw new NullPointerException("primeQ");
+ if (primeExponentP == null)
+ throw new NullPointerException("primeExponentP");
+ if (primeExponentQ == null)
+ throw new NullPointerException("primeExponentQ");
+ if (crtCoefficient == null)
+ throw new NullPointerException("crtCoefficient");
+ if (otherPrimeInfo != null)
+ if (otherPrimeInfo.length == 0)
+ throw new IllegalArgumentException();
+ else
+ this.otherPrimeInfo = (RSAOtherPrimeInfo[]) otherPrimeInfo.clone();
+
+ this.publicExponent = publicExponent;
+ this.primeP = primeP;
+ this.primeQ = primeQ;
+ this.primeExponentP = primeExponentP;
+ this.primeExponentQ = primeExponentQ;
+ this.crtCoefficient = crtCoefficient;
+ }
+
+ // Class methods
+ // --------------------------------------------------------------------------
+
+ // Instance methods
+ // --------------------------------------------------------------------------
+
+ /**
+ * Returns the public exponent.
+ *
+ * @return the public exponent.
+ */
+ public BigInteger getPublicExponent()
+ {
+ return this.publicExponent;
+ }
+
+ /**
+ * Returns the primeP.
+ *
+ * @return the primeP.
+ */
+ public BigInteger getPrimeP()
+ {
+ return this.primeP;
+ }
+
+ /**
+ * Returns the primeQ.
+ *
+ * @return the primeQ.
+ */
+ public BigInteger getPrimeQ()
+ {
+ return this.primeQ;
+ }
+
+ /**
+ * Returns the primeExponentP.
+ *
+ * @return the primeExponentP.
+ */
+ public BigInteger getPrimeExponentP()
+ {
+ return this.primeExponentP;
+ }
+
+ /**
+ * Returns the primeExponentQ.
+ *
+ * @return the primeExponentQ.
+ */
+ public BigInteger getPrimeExponentQ()
+ {
+ return this.primeExponentQ;
+ }
+
+ /**
+ * Returns the crtCoefficient.
+ *
+ * @return the crtCoefficient.
+ */
+ public BigInteger getCrtCoefficient()
+ {
+ return this.crtCoefficient;
+ }
+
+ /**
+ * Returns a copy of the otherPrimeInfo or <code>null</code> if there are
+ * only two prime factors (p and q).
+ *
+ * @return the otherPrimeInfo.
+ */
+ public RSAOtherPrimeInfo[] getOtherPrimeInfo()
+ {
+ return this.otherPrimeInfo == null
+ ? null
+ : (RSAOtherPrimeInfo[]) this.otherPrimeInfo.clone();
+ }
+}
Index: libjava/java/security/spec/RSAOtherPrimeInfo.java
===================================================================
RCS file: libjava/java/security/spec/RSAOtherPrimeInfo.java
diff -N libjava/java/security/spec/RSAOtherPrimeInfo.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ libjava/java/security/spec/RSAOtherPrimeInfo.java 19 Apr 2003 20:19:47 -0000
@@ -0,0 +1,133 @@
+/* RSAOtherPrimeInfo.java --
+ Copyright (C) 2003, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.security.spec;
+
+import java.math.BigInteger;
+
+/**
+ * This class represents the triplet (prime, exponent, and coefficient) inside
+ * RSA's OtherPrimeInfo structure, as defined in the PKCS#1 v2.1. The ASN.1
+ * syntax of RSA's OtherPrimeInfo is as follows:
+ *
+ * <pre>
+ * OtherPrimeInfo ::= SEQUENCE {
+ * prime INTEGER,
+ * exponent INTEGER,
+ * coefficient INTEGER
+ * }
+ * </pre>
+ *
+ * @since 1.4
+ * @see RSAPrivateCrtKeySpec
+ * @see java.security.interfaces.RSAMultiPrimePrivateCrtKey
+ */
+public class RSAOtherPrimeInfo
+{
+ // Constants and fields
+ // --------------------------------------------------------------------------
+
+ private BigInteger prime;
+ private BigInteger primeExponent;
+ private BigInteger crtCoefficient;
+
+ // Constructor(s)
+ // --------------------------------------------------------------------------
+
+ /**
+ * Creates a new <code>RSAOtherPrimeInfo</code> given the prime,
+ * primeExponent, and crtCoefficient as defined in PKCS#1.
+ *
+ * @param prime the prime factor of n.
+ * @param primeExponent the exponent.
+ * @param crtCoefficient the Chinese Remainder Theorem coefficient.
+ * @throws NullPointerException if any of the parameters, i.e. prime,
+ * primeExponent, crtCoefficient, is <code>null</code>.
+ */
+ public RSAOtherPrimeInfo(BigInteger prime, BigInteger primeExponent,
+ BigInteger crtCoefficient)
+ {
+ super();
+
+ if (prime == null)
+ throw new NullPointerException("prime");
+ if (primeExponent == null)
+ throw new NullPointerException("primeExponent");
+ if (crtCoefficient == null)
+ throw new NullPointerException("crtCoefficient");
+
+ this.prime = prime;
+ this.primeExponent = primeExponent;
+ this.crtCoefficient = crtCoefficient;
+ }
+
+ // Class methods
+ // --------------------------------------------------------------------------
+
+ // Instance methods
+ // --------------------------------------------------------------------------
+
+ /**
+ * Returns the prime.
+ *
+ * @return the prime.
+ */
+ public final BigInteger getPrime()
+ {
+ return this.prime;
+ }
+
+ /**
+ * Returns the prime's exponent.
+ *
+ * @return the primeExponent.
+ */
+ public final BigInteger getExponent()
+ {
+ return this.primeExponent;
+ }
+
+ /**
+ * Returns the prime's crtCoefficient.
+ *
+ * @return the crtCoefficient.
+ */
+ public final BigInteger getCrtCoefficient()
+ {
+ return this.crtCoefficient;
+ }
+}