Commit 7451c155 by Tom Tromey Committed by Tom Tromey

Makefile.in: Rebuilt.

	* 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.

From-SVN: r65829
parent 9e9e2042
2003-04-19 Tom Tromey <tromey@redhat.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.
2003-04-19 Scott Gilbertson <scottg@mantatest.com> 2003-04-19 Scott Gilbertson <scottg@mantatest.com>
* gnu/awt/xlib/XGraphics.java (XGraphics): Use new GC.create. * gnu/awt/xlib/XGraphics.java (XGraphics): Use new GC.create.
......
...@@ -2294,6 +2294,7 @@ java/security/DummySignature.java \ ...@@ -2294,6 +2294,7 @@ java/security/DummySignature.java \
java/security/DigestInputStream.java \ java/security/DigestInputStream.java \
java/security/DomainCombiner.java \ java/security/DomainCombiner.java \
java/security/DummyMessageDigest.java \ java/security/DummyMessageDigest.java \
java/security/Engine.java \
java/security/GeneralSecurityException.java \ java/security/GeneralSecurityException.java \
java/security/Guard.java \ java/security/Guard.java \
java/security/GuardedObject.java \ java/security/GuardedObject.java \
...@@ -2374,6 +2375,7 @@ java/security/interfaces/DSAParams.java \ ...@@ -2374,6 +2375,7 @@ java/security/interfaces/DSAParams.java \
java/security/interfaces/DSAPrivateKey.java \ java/security/interfaces/DSAPrivateKey.java \
java/security/interfaces/DSAPublicKey.java \ java/security/interfaces/DSAPublicKey.java \
java/security/interfaces/RSAKey.java \ java/security/interfaces/RSAKey.java \
java/security/interfaces/RSAMultiPrimePrivateCrtKey.java \
java/security/interfaces/RSAPrivateCrtKey.java \ java/security/interfaces/RSAPrivateCrtKey.java \
java/security/interfaces/RSAPrivateKey.java \ java/security/interfaces/RSAPrivateKey.java \
java/security/interfaces/RSAPublicKey.java \ java/security/interfaces/RSAPublicKey.java \
...@@ -2386,7 +2388,10 @@ java/security/spec/InvalidKeySpecException.java \ ...@@ -2386,7 +2388,10 @@ java/security/spec/InvalidKeySpecException.java \
java/security/spec/InvalidParameterSpecException.java \ java/security/spec/InvalidParameterSpecException.java \
java/security/spec/KeySpec.java \ java/security/spec/KeySpec.java \
java/security/spec/PKCS8EncodedKeySpec.java \ java/security/spec/PKCS8EncodedKeySpec.java \
java/security/spec/PSSParameterSpec.java \
java/security/spec/RSAKeyGenParameterSpec.java \ java/security/spec/RSAKeyGenParameterSpec.java \
java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java\
java/security/spec/RSAOtherPrimeInfo.java \
java/security/spec/RSAPrivateCrtKeySpec.java \ java/security/spec/RSAPrivateCrtKeySpec.java \
java/security/spec/RSAPrivateKeySpec.java \ java/security/spec/RSAPrivateKeySpec.java \
java/security/spec/RSAPublicKeySpec.java \ java/security/spec/RSAPublicKeySpec.java \
......
...@@ -2056,6 +2056,7 @@ java/security/DummySignature.java \ ...@@ -2056,6 +2056,7 @@ java/security/DummySignature.java \
java/security/DigestInputStream.java \ java/security/DigestInputStream.java \
java/security/DomainCombiner.java \ java/security/DomainCombiner.java \
java/security/DummyMessageDigest.java \ java/security/DummyMessageDigest.java \
java/security/Engine.java \
java/security/GeneralSecurityException.java \ java/security/GeneralSecurityException.java \
java/security/Guard.java \ java/security/Guard.java \
java/security/GuardedObject.java \ java/security/GuardedObject.java \
...@@ -2136,6 +2137,7 @@ java/security/interfaces/DSAParams.java \ ...@@ -2136,6 +2137,7 @@ java/security/interfaces/DSAParams.java \
java/security/interfaces/DSAPrivateKey.java \ java/security/interfaces/DSAPrivateKey.java \
java/security/interfaces/DSAPublicKey.java \ java/security/interfaces/DSAPublicKey.java \
java/security/interfaces/RSAKey.java \ java/security/interfaces/RSAKey.java \
java/security/interfaces/RSAMultiPrimePrivateCrtKey.java \
java/security/interfaces/RSAPrivateCrtKey.java \ java/security/interfaces/RSAPrivateCrtKey.java \
java/security/interfaces/RSAPrivateKey.java \ java/security/interfaces/RSAPrivateKey.java \
java/security/interfaces/RSAPublicKey.java \ java/security/interfaces/RSAPublicKey.java \
...@@ -2148,7 +2150,10 @@ java/security/spec/InvalidKeySpecException.java \ ...@@ -2148,7 +2150,10 @@ java/security/spec/InvalidKeySpecException.java \
java/security/spec/InvalidParameterSpecException.java \ java/security/spec/InvalidParameterSpecException.java \
java/security/spec/KeySpec.java \ java/security/spec/KeySpec.java \
java/security/spec/PKCS8EncodedKeySpec.java \ java/security/spec/PKCS8EncodedKeySpec.java \
java/security/spec/PSSParameterSpec.java \
java/security/spec/RSAKeyGenParameterSpec.java \ java/security/spec/RSAKeyGenParameterSpec.java \
java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java\
java/security/spec/RSAOtherPrimeInfo.java \
java/security/spec/RSAPrivateCrtKeySpec.java \ java/security/spec/RSAPrivateCrtKeySpec.java \
java/security/spec/RSAPrivateKeySpec.java \ java/security/spec/RSAPrivateKeySpec.java \
java/security/spec/RSAPublicKeySpec.java \ java/security/spec/RSAPublicKeySpec.java \
...@@ -3571,7 +3576,7 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \ ...@@ -3571,7 +3576,7 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/java/security/DomainCombiner.P \ .deps/java/security/DomainCombiner.P \
.deps/java/security/DummyKeyPairGenerator.P \ .deps/java/security/DummyKeyPairGenerator.P \
.deps/java/security/DummyMessageDigest.P \ .deps/java/security/DummyMessageDigest.P \
.deps/java/security/DummySignature.P \ .deps/java/security/DummySignature.P .deps/java/security/Engine.P \
.deps/java/security/GeneralSecurityException.P \ .deps/java/security/GeneralSecurityException.P \
.deps/java/security/Guard.P .deps/java/security/GuardedObject.P \ .deps/java/security/Guard.P .deps/java/security/GuardedObject.P \
.deps/java/security/Identity.P .deps/java/security/IdentityScope.P \ .deps/java/security/Identity.P .deps/java/security/IdentityScope.P \
...@@ -3636,6 +3641,7 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \ ...@@ -3636,6 +3641,7 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/java/security/interfaces/DSAPrivateKey.P \ .deps/java/security/interfaces/DSAPrivateKey.P \
.deps/java/security/interfaces/DSAPublicKey.P \ .deps/java/security/interfaces/DSAPublicKey.P \
.deps/java/security/interfaces/RSAKey.P \ .deps/java/security/interfaces/RSAKey.P \
.deps/java/security/interfaces/RSAMultiPrimePrivateCrtKey.P \
.deps/java/security/interfaces/RSAPrivateCrtKey.P \ .deps/java/security/interfaces/RSAPrivateCrtKey.P \
.deps/java/security/interfaces/RSAPrivateKey.P \ .deps/java/security/interfaces/RSAPrivateKey.P \
.deps/java/security/interfaces/RSAPublicKey.P \ .deps/java/security/interfaces/RSAPublicKey.P \
...@@ -3648,7 +3654,10 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \ ...@@ -3648,7 +3654,10 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/java/security/spec/InvalidParameterSpecException.P \ .deps/java/security/spec/InvalidParameterSpecException.P \
.deps/java/security/spec/KeySpec.P \ .deps/java/security/spec/KeySpec.P \
.deps/java/security/spec/PKCS8EncodedKeySpec.P \ .deps/java/security/spec/PKCS8EncodedKeySpec.P \
.deps/java/security/spec/PSSParameterSpec.P \
.deps/java/security/spec/RSAKeyGenParameterSpec.P \ .deps/java/security/spec/RSAKeyGenParameterSpec.P \
.deps/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.P \
.deps/java/security/spec/RSAOtherPrimeInfo.P \
.deps/java/security/spec/RSAPrivateCrtKeySpec.P \ .deps/java/security/spec/RSAPrivateCrtKeySpec.P \
.deps/java/security/spec/RSAPrivateKeySpec.P \ .deps/java/security/spec/RSAPrivateKeySpec.P \
.deps/java/security/spec/RSAPublicKeySpec.P \ .deps/java/security/spec/RSAPublicKeySpec.P \
......
/* AlgorithmParameterGenerator.java --- Algorithm Parameter Generator /* 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. This file is part of GNU Classpath.
...@@ -36,29 +36,64 @@ obligated to do so. If you do not wish to do so, delete this ...@@ -36,29 +36,64 @@ obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */ exception statement from your version. */
package java.security; package java.security;
import java.security.spec.AlgorithmParameterSpec; import java.security.spec.AlgorithmParameterSpec;
/** /**
AlgorithmParameterGenerator is used to generate * <p>The <code>AlgorithmParameterGenerator</code> class is used to generate a
algorithm parameters for specified algorithms. * set of parameters to be used with a certain algorithm. Parameter generators
This class is used to generate the algorithm parameters * are constructed using the <code>getInstance()</code> factory methods (static
for a specific algorithm. * methods that return instances of a given class).</p>
*
@since JDK 1.2 * <p>The object that will generate the parameters can be initialized in two
@author Mark Benvenuto * 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 public class AlgorithmParameterGenerator
{ {
/** Service name for algorithm parameter generators. */
private static final String ALGORITHM_PARAMETER_GENERATOR =
"AlgorithmParameterGenerator";
private AlgorithmParameterGeneratorSpi paramGenSpi; private AlgorithmParameterGeneratorSpi paramGenSpi;
private Provider provider; private Provider provider;
private String algorithm; private String algorithm;
/** /**
Creates an instance of AlgorithmParameters * Creates an <code>AlgorithmParameterGenerator</code> object.
*
@param paramSpi A parameters engine to use * @param paramGenSpi the delegate.
@param provider A provider to use * @param provider the provider.
@param algorithm The algorithm * @param algorithm the algorithm.
*/ */
protected AlgorithmParameterGenerator(AlgorithmParameterGeneratorSpi protected AlgorithmParameterGenerator(AlgorithmParameterGeneratorSpi
paramGenSpi, Provider provider, paramGenSpi, Provider provider,
...@@ -70,9 +105,10 @@ public class AlgorithmParameterGenerator ...@@ -70,9 +105,10 @@ public class AlgorithmParameterGenerator
} }
/** /**
Returns the name of the algorithm used * Returns the standard name of the algorithm this parameter generator is
* associated with.
@return A string with the name of the algorithm *
* @return the string name of the algorithm.
*/ */
public final String getAlgorithm() public final String getAlgorithm()
{ {
...@@ -80,87 +116,102 @@ public class AlgorithmParameterGenerator ...@@ -80,87 +116,102 @@ public class AlgorithmParameterGenerator
} }
/** /**
Gets an instance of the AlgorithmParameterGenerator class * Generates an <code>AlgorithmParameterGenerator</code> object that
which generates algorithm parameters for the specified algorithm. * implements the specified digest algorithm. If the default provider package
If the algorithm is not found then, it throws NoSuchAlgorithmException. * provides an implementation of the requested digest algorithm, an instance
* of <code>AlgorithmParameterGenerator</code> containing that implementation
@param algorithm the name of algorithm to choose * is returned. If the algorithm is not available in the default package,
@return a AlgorithmParameterGenerator repesenting the desired algorithm * other packages are searched.
*
@throws NoSuchAlgorithmException if the algorithm is not implemented by providers * @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) public static AlgorithmParameterGenerator getInstance(String algorithm)
throws NoSuchAlgorithmException throws NoSuchAlgorithmException
{ {
Provider[] p = Security.getProviders(); Provider[] p = Security.getProviders();
for (int i = 0; i < p.length; i++) for (int i = 0; i < p.length; i++)
try
{ {
String classname = return getInstance(algorithm, p[i]);
p[i].getProperty("AlgorithmParameterGenerator." + algorithm);
if (classname != null)
return getInstance(classname, algorithm, p[i]);
} }
catch (NoSuchAlgorithmException ignored) {}
throw new NoSuchAlgorithmException(algorithm); throw new NoSuchAlgorithmException(algorithm);
} }
/** /**
Gets an instance of the AlgorithmParameterGenerator class * Generates an <code>AlgorithmParameterGenerator</code> object for the
which generates algorithm parameters for the specified algorithm. * requested algorithm, as supplied from the specified provider, if such a
If the algorithm is not found then, it throws NoSuchAlgorithmException. * parameter generator is available from the provider.
*
@param algorithm the name of algorithm to choose * @param algorithm the string name of the algorithm.
@param provider the name of the provider to find the algorithm in * @param provider the string name of the provider.
@return a AlgorithmParameterGenerator repesenting the desired algorithm * @return the new <code>AlgorithmParameterGenerator</code> object.
* @throws NoSuchAlgorithmException if the <code>algorithm</code> is not
@throws NoSuchAlgorithmException if the algorithm is not implemented by the provider * available from the <code>provider</code>.
@throws NoSuchProviderException if the provider is not found * @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, public static AlgorithmParameterGenerator getInstance(String algorithm,
String provider) String provider)
throws NoSuchAlgorithmException, NoSuchProviderException throws NoSuchAlgorithmException, NoSuchProviderException
{ {
if (provider == null || provider.length() == 0)
throw new IllegalArgumentException("Illegal provider");
Provider p = Security.getProvider(provider); Provider p = Security.getProvider(provider);
if (p == null) if (p == null)
throw new NoSuchProviderException(); throw new NoSuchProviderException();
return getInstance(p. return getInstance(algorithm, p);
getProperty("AlgorithmParameterGenerator." +
algorithm), algorithm, p);
} }
private static AlgorithmParameterGenerator getInstance(String classname, /**
String algorithm, * 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) Provider provider)
throws NoSuchAlgorithmException throws NoSuchAlgorithmException
{ {
if (provider == null)
throw new IllegalArgumentException("Illegal provider");
try try
{ {
return new return new AlgorithmParameterGenerator(
AlgorithmParameterGenerator((AlgorithmParameterGeneratorSpi) Class. (AlgorithmParameterGeneratorSpi) Engine.getInstance(
forName(classname).newInstance(), ALGORITHM_PARAMETER_GENERATOR, algorithm, provider),
provider, algorithm); provider, algorithm);
} }
catch (ClassNotFoundException cnfe) catch (ClassCastException cce)
{
throw new NoSuchAlgorithmException("Class not found");
}
catch (InstantiationException ie)
{ {
throw new NoSuchAlgorithmException("Class instantiation failed"); throw new NoSuchAlgorithmException(algorithm);
}
catch (IllegalAccessException iae)
{
throw new NoSuchAlgorithmException("Illegal Access");
} }
} }
/** /**
Gets the provider that the class is from. * Returns the provider of this algorithm parameter generator object.
*
@return the provider of this class * @return the provider of this algorithm parameter generator object.
*/ */
public final Provider getProvider() public final Provider getProvider()
{ {
...@@ -168,11 +219,13 @@ public class AlgorithmParameterGenerator ...@@ -168,11 +219,13 @@ public class AlgorithmParameterGenerator
} }
/** /**
Initializes the Algorithm Parameter Generator with the specified * Initializes this parameter generator for a certain <i>size</i>. To create
size. (Since no source of randomness is supplied, a default * the parameters, the {@link SecureRandom} implementation of the
one is supplied). * highest-priority installed provider is used as the source of randomness.
* (If none of the installed providers supply an implementation of
@param size size (in bits) to use * {@link SecureRandom}, a system-provided source of randomness is used.)
*
* @param size the size (number of bits).
*/ */
public final void init(int size) public final void init(int size)
{ {
...@@ -180,11 +233,11 @@ public class AlgorithmParameterGenerator ...@@ -180,11 +233,11 @@ public class AlgorithmParameterGenerator
} }
/** /**
Initializes the Algorithm Parameter Generator with the specified * Initializes this parameter generator for a certain size and source of
size and source of randomness. * randomness.
*
@param size size (in bits) to use * @param size the size (number of bits).
@param random source of randomness to use * @param random the source of randomness.
*/ */
public final void init(int size, SecureRandom random) public final void init(int size, SecureRandom random)
{ {
...@@ -192,36 +245,45 @@ public class AlgorithmParameterGenerator ...@@ -192,36 +245,45 @@ public class AlgorithmParameterGenerator
} }
/** /**
Initializes the Algorithm Parameter Generator with the specified * Initializes this parameter generator with a set of algorithm-specific
AlgorithmParameterSpec. (Since no source of randomness is supplied, * parameter generation values. To generate the parameters, the {@link
a default one is supplied). * SecureRandom} implementation of the highest-priority installed provider is
* used as the source of randomness. (If none of the installed providers
@param genParamSpec the AlgorithmParameterSpec class to use * supply an implementation of {@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 public final void init(AlgorithmParameterSpec genParamSpec)
InvalidAlgorithmParameterException throws InvalidAlgorithmParameterException
{ {
init(genParamSpec, new SecureRandom()); init(genParamSpec, new SecureRandom());
} }
/** /**
Initializes the Algorithm Parameter Generator with the specified * Initializes this parameter generator with a set of algorithm-specific
AlgorithmParameterSpec and source of randomness. * parameter generation values.
*
@param genParamSpec the AlgorithmParameterSpec class to use * @param genParamSpec the set of algorithm-specific parameter generation
@param random source of randomness to use * 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, public final void init(AlgorithmParameterSpec genParamSpec,
SecureRandom random) throws SecureRandom random)
InvalidAlgorithmParameterException throws InvalidAlgorithmParameterException
{ {
paramGenSpi.engineInit(genParamSpec, random); paramGenSpi.engineInit(genParamSpec, random);
} }
/** /**
Generate a new set of AlgorithmParameters. * Generates the parameters.
*
@returns a new set of algorithm parameters * @return the new {@link AlgorithmParameters} object.
*/ */
public final AlgorithmParameters generateParameters() public final AlgorithmParameters generateParameters()
{ {
......
/* AlgorithmParameters.java --- Algorithm Parameters Implementation Class /* 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. This file is part of GNU Classpath.
...@@ -35,32 +35,65 @@ this exception to your version of the library, but you are not ...@@ -35,32 +35,65 @@ 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 obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */ exception statement from your version. */
package java.security; package java.security;
import java.security.spec.InvalidParameterSpecException; import java.security.spec.InvalidParameterSpecException;
import java.security.spec.AlgorithmParameterSpec; import java.security.spec.AlgorithmParameterSpec;
import java.io.IOException; import java.io.IOException;
/** /**
AlgorithmParameters is the Algorithm Parameters class which * <p>This class is used as an opaque representation of cryptographic
provides an interface through which to modify parameters for * parameters.</p>
classes. This class is used to manage the algorithm parameters. *
* <p>An <code>AlgorithmParameters</code> object for managing the parameters
@since JDK 1.2 * for a particular algorithm can be obtained by calling one of the
@author Mark Benvenuto * <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 public class AlgorithmParameters
{ {
/** Service name for algorithm parameters. */
private static final String ALGORITHM_PARAMETERS = "AlgorithmParameters";
private AlgorithmParametersSpi paramSpi; private AlgorithmParametersSpi paramSpi;
private Provider provider; private Provider provider;
private String algorithm; private String algorithm;
/** /**
Creates an instance of AlgorithmParameters * Creates an <code>AlgorithmParameters</code> object.
*
@param paramSpi A parameters engine to use * @param paramSpi the delegate.
@param provider A provider to use * @param provider the provider.
@param algorithm The algorithm * @param algorithm the algorithm.
*/ */
protected AlgorithmParameters(AlgorithmParametersSpi paramSpi, protected AlgorithmParameters(AlgorithmParametersSpi paramSpi,
Provider provider, String algorithm) Provider provider, String algorithm)
...@@ -71,9 +104,9 @@ public class AlgorithmParameters ...@@ -71,9 +104,9 @@ public class AlgorithmParameters
} }
/** /**
Returns the name of the algorithm used * Returns the name of the algorithm associated with this parameter object.
*
@return A string with the name of the algorithm * @return the algorithm name.
*/ */
public final String getAlgorithm() public final String getAlgorithm()
{ {
...@@ -81,93 +114,106 @@ public class AlgorithmParameters ...@@ -81,93 +114,106 @@ public class AlgorithmParameters
} }
/** /**
Gets an instance of the AlgorithmParameters class representing * <p>Generates a parameter object for the specified algorithm.</p>
the specified algorithm parameters. If the algorithm is not *
found then, it throws NoSuchAlgorithmException. * <p>If the default provider package provides an implementation of the
* requested algorithm, an instance of <code>AlgorithmParameters</code>
The returned AlgorithmParameters must still be intialized with * containing that implementation is returned. If the algorithm is not
init(). * available in the default package, other packages are searched.</p>
*
@param algorithm the name of algorithm to choose * <p>The returned parameter object must be initialized via a call to
@return a AlgorithmParameters repesenting the desired algorithm * <code>init()</code>, using an appropriate parameter specification or
* parameter encoding.</p>
@throws NoSuchAlgorithmException if the algorithm is not implemented by providers *
* @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 public static AlgorithmParameters getInstance(String algorithm)
NoSuchAlgorithmException throws NoSuchAlgorithmException
{ {
Provider[] p = Security.getProviders(); Provider[] p = Security.getProviders();
for (int i = 0; i < p.length; i++) for (int i = 0; i < p.length; i++)
try
{ {
String classname = return getInstance(algorithm, p[i]);
p[i].getProperty("AlgorithmParameters." + algorithm);
if (classname != null)
return getInstance(classname, algorithm, p[i]);
} }
catch (NoSuchAlgorithmException ignored) {}
throw new NoSuchAlgorithmException(algorithm); throw new NoSuchAlgorithmException(algorithm);
} }
/** /**
Gets an instance of the AlgorithmParameters class representing * <p>Generates a parameter object for the specified algorithm, as supplied
the specified algorithm parameters from the specified provider. * by the specified provider, if such an algorithm is available from the
If the algorithm is not found then, it throws * provider.</p>
NoSuchAlgorithmException. If the provider is not found, then *
it throws NoSuchProviderException. * <p>The returned parameter object must be initialized via a call to
* <code>init()</code>, using an appropriate parameter specification or
The returned AlgorithmParameters must still be intialized with * parameter encoding.</p>
init(). *
* @param algorithm the name of the algorithm requested.
@param algorithm the name of algorithm to choose * @param provider the name of the provider.
@param provider the name of the provider to find the algorithm in * @return the new parameter object.
@return a AlgorithmParameters repesenting the desired algorithm * @throws NoSuchAlgorithmException if the algorithm is not available in the
* package supplied by the requested provider.
@throws NoSuchAlgorithmException if the algorithm is not implemented by the provider * @throws NoSuchProviderException if the provider is not available in the
@throws NoSuchProviderException if the provider is not found * environment.
* @throws IllegalArgumentException if the provider name is null or empty.
* @see Provider
*/ */
public static AlgorithmParameters getInstance(String algorithm, public static AlgorithmParameters getInstance(String algorithm, String provider)
String provider) throws throws NoSuchAlgorithmException, NoSuchProviderException
NoSuchAlgorithmException, NoSuchProviderException
{ {
if (provider == null || provider.length() == 0)
throw new IllegalArgumentException("Illegal provider");
Provider p = Security.getProvider(provider); Provider p = Security.getProvider(provider);
if (p == null) if (p == null)
throw new NoSuchProviderException(); throw new NoSuchProviderException();
return getInstance(p.getProperty("AlgorithmParameters." + algorithm), return getInstance(algorithm, p);
algorithm, p);
} }
private static AlgorithmParameters getInstance(String classname, /**
String algorithm, * 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) Provider provider)
throws NoSuchAlgorithmException throws NoSuchAlgorithmException
{ {
if (provider == null)
throw new IllegalArgumentException("Illegal provider");
try try
{ {
return new AlgorithmParameters((AlgorithmParametersSpi) Class. return new AlgorithmParameters((AlgorithmParametersSpi)
forName(classname).newInstance(), Engine.getInstance(ALGORITHM_PARAMETERS, algorithm, provider),
provider, algorithm); provider, algorithm);
} }
catch (ClassNotFoundException cnfe) catch (ClassCastException cce)
{
throw new NoSuchAlgorithmException("Class not found");
}
catch (InstantiationException ie)
{
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. * Returns the provider of this parameter object.
*
@return the provider of this class * @return the provider of this parameter object.
*/ */
public final Provider getProvider() public final Provider getProvider()
{ {
...@@ -175,29 +221,28 @@ public class AlgorithmParameters ...@@ -175,29 +221,28 @@ public class AlgorithmParameters
} }
/** /**
Initializes the engine with the specified * Initializes this parameter object using the parameters specified in
AlgorithmParameterSpec class. * <code>paramSpec</code>.
*
@param paramSpec A AlgorithmParameterSpec to initialize with * @param paramSpec the parameter specification.
* @throws InvalidParameterSpecException if the given parameter specification
@throws InvalidParameterSpecException For an inapporiate ParameterSpec class * 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 public final void init(AlgorithmParameterSpec paramSpec)
InvalidParameterSpecException throws InvalidParameterSpecException
{ {
paramSpi.engineInit(paramSpec); paramSpi.engineInit(paramSpec);
} }
/** /**
Initializes the engine with the specified * Imports the specified parameters and decodes them according to the primary
parameters stored in the byte array and decodes them * decoding format for parameters. The primary decoding format for parameters
according to the ASN.1 specification. If the ASN.1 * is ASN.1, if an ASN.1 specification for this type of parameters exists.
specification exists then it succeeds or else it throws *
IOException. * @param params the encoded parameters.
* @throws IOException on decoding errors, or if this parameter object has
@param params Parameters to initialize with * already been initialized.
@throws IOException Decoding Error
*/ */
public final void init(byte[]params) throws IOException public final void init(byte[]params) throws IOException
{ {
...@@ -205,17 +250,15 @@ public class AlgorithmParameters ...@@ -205,17 +250,15 @@ public class AlgorithmParameters
} }
/** /**
Initializes the engine with the specified * Imports the parameters from params and decodes them according to the
parameters stored in the byte array and decodes them * specified decoding scheme. If <code>format</code> is <code>null</code>,
according to the specified decoding specification. * the primary decoding format for parameters is used. The primary decoding
If format is null, then it is decoded using the ASN.1 * format is ASN.1, if an ASN.1 specification for these parameters exists.
specification if it exists or else it throws *
IOException. * @param params the encoded parameters.
* @param format the name of the decoding scheme.
@param params Parameters to initialize with * @throws IOException on decoding errors, or if this parameter object has
@param format Name of decoding format to use * already been initialized.
@throws IOException Decoding Error
*/ */
public final void init(byte[]params, String format) throws IOException public final void init(byte[]params, String format) throws IOException
{ {
...@@ -223,28 +266,34 @@ public class AlgorithmParameters ...@@ -223,28 +266,34 @@ public class AlgorithmParameters
} }
/** /**
Returns a specification of this AlgorithmParameters object. * Returns a (transparent) specification of this parameter object.
paramSpec identifies the class to return the AlgortihmParameters * <code>paramSpec</code> identifies the specification class in which the
in. * parameters should be returned. It could, for example, be
* <code>DSAParameterSpec.class</code>, to indicate that the parameters should
@param paramSpec Class to return AlgorithmParameters in * be returned in an instance of the {@link java.security.spec.DSAParameterSpec}
* class.
@return the parameter specification *
* @param paramSpec the specification class in which the parameters should be
@throws InvalidParameterSpecException if the paramSpec is an invalid parameter class * 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 public final AlgorithmParameterSpec getParameterSpec(Class paramSpec)
InvalidParameterSpecException throws InvalidParameterSpecException
{ {
return paramSpi.engineGetParameterSpec(paramSpec); return paramSpi.engineGetParameterSpec(paramSpec);
} }
/** /**
Returns the parameters in the default encoding format. * Returns the parameters in their primary encoding format. The primary
The primary encoding format is ASN.1 format if it exists * encoding format for parameters is ASN.1, if an ASN.1 specification for
for the specified type. * this type of parameters exists.
*
@return byte array representing the parameters * @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 public final byte[] getEncoded() throws IOException
{ {
...@@ -252,12 +301,15 @@ public class AlgorithmParameters ...@@ -252,12 +301,15 @@ public class AlgorithmParameters
} }
/** /**
Returns the parameters in the specified encoding format. * Returns the parameters encoded in the specified scheme. If format is
If <code>format</code> is <code>null</code> then the * <code>null</code>, the primary encoding format for parameters is used. The
primary encoding format is used, the ASN.1 format, * primary encoding format is ASN.1, if an ASN.1 specification for these
if it exists for the specified type. * parameters exists.
*
@return byte array representing the parameters * @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 public final byte[] getEncoded(String format) throws IOException
{ {
...@@ -265,9 +317,10 @@ public class AlgorithmParameters ...@@ -265,9 +317,10 @@ public class AlgorithmParameters
} }
/** /**
Returns a string representation of the encoding format * Returns a formatted string describing the parameters.
*
@return a string containing the string representation * @return a formatted string describing the parameters, or <code>null</code>
* if this parameter object has not been initialized.
*/ */
public final String toString() public final String toString()
{ {
......
/* 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 ({@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. {@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);
}
}
/* Identity.java --- Identity Class /* 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 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 it under the terms of the GNU General Public License as published by
...@@ -36,31 +36,36 @@ obligated to do so. If you do not wish to do so, delete this ...@@ -36,31 +36,36 @@ obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */ exception statement from your version. */
package java.security; package java.security;
import java.io.Serializable; import java.io.Serializable;
import java.util.Vector; import java.util.Vector;
/** /**
The Identity class is used to repsent people and companies that * <p>This class represents identities: real-world objects such as people,
can be authenticated using public key encryption. The identities * companies or organizations whose identities can be authenticated using their
can also be abstract objects such as smart cards. * public keys. Identities may also be more abstract (or concrete) constructs,
* such as daemon threads or smart cards.</p>
Identity object store a name and public key for each identity. *
The names cannot be changed and the identities can be scoped. * <p>All Identity objects have a <i>name</i> and a <i>public key</i>. Names
Each identity (name and public key) within a scope is unique * are immutable. <i>Identities</i> may also be <b>scoped</b>. That is, if an
to that scope. * <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
Each identity has a set of ceritificates which all specify the * that <i>scope</i>.</p>
same public key but not necessarily the same name. *
* <p>An <i>Identity</i> also has a <i>set of certificates</i> (all certifying
The Identity class can be subclassed to allow additional * its own <i>public key</i>). The <i>Principal</i> names specified in these
information to be attached to it. * certificates need not be the same, only the key.</p>
*
@since JDK 1.1 * <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>
@deprecated Use java.security.KeyStore, the java.security.cert *
package, and java.security.Principal. * @author Mark Benvenuto
* @see IdentityScope
@author Mark Benvenuto * @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 public abstract class Identity implements Principal, Serializable
{ {
...@@ -72,22 +77,18 @@ public abstract class Identity implements Principal, Serializable ...@@ -72,22 +77,18 @@ public abstract class Identity implements Principal, Serializable
private String info; private String info;
private Vector certificates; private Vector certificates;
/** /** Constructor for serialization only. */
Creates a new instance of Identity from Serialized Data
*/
protected Identity() protected Identity()
{ {
} }
/** /**
Creates a new instance of Identity with the specified name * Constructs an identity with the specified name and scope.
and IdentityScope. *
* @param name the identity name.
@param name the name to use * @param scope the scope of the identity.
@param scope the scope to use * @throws KeyManagementException if there is already an identity with the
* same name in the scope.
@throws KeyManagementException if the identity is already
present
*/ */
public Identity(String name, IdentityScope scope) public Identity(String name, IdentityScope scope)
throws KeyManagementException throws KeyManagementException
...@@ -97,10 +98,9 @@ public abstract class Identity implements Principal, Serializable ...@@ -97,10 +98,9 @@ public abstract class Identity implements Principal, Serializable
} }
/** /**
Creates a new instance of Identity with the specified name * Constructs an identity with the specified name and no scope.
and no scope. *
* @param name the identity name.
@param name the name to use
*/ */
public Identity(String name) public Identity(String name)
{ {
...@@ -109,9 +109,9 @@ public abstract class Identity implements Principal, Serializable ...@@ -109,9 +109,9 @@ public abstract class Identity implements Principal, Serializable
} }
/** /**
Gets the name for this Identity. * Returns this identity's name.
*
@return the name * @return the name of this identity.
*/ */
public final String getName() public final String getName()
{ {
...@@ -119,9 +119,9 @@ public abstract class Identity implements Principal, Serializable ...@@ -119,9 +119,9 @@ public abstract class Identity implements Principal, Serializable
} }
/** /**
Gets the scope for this Identity. * Returns this identity's scope.
*
@return the scope * @return the scope of this identity.
*/ */
public final IdentityScope getScope() public final IdentityScope getScope()
{ {
...@@ -129,9 +129,10 @@ public abstract class Identity implements Principal, Serializable ...@@ -129,9 +129,10 @@ public abstract class Identity implements Principal, Serializable
} }
/** /**
Gets the public key for this identity. * Returns this identity's public key.
*
@return the public key * @return the public key for this identity.
* @see #setPublicKey(java.security.PublicKey)
*/ */
public PublicKey getPublicKey() public PublicKey getPublicKey()
{ {
...@@ -139,18 +140,21 @@ public abstract class Identity implements Principal, Serializable ...@@ -139,18 +140,21 @@ public abstract class Identity implements Principal, Serializable
} }
/** /**
Sets the public key for this identity. * <p>Sets this identity's public key. The old key and all of this identity's
The old key and all certificates are removed. * certificates are removed by this operation.</p>
*
This class checks the security manager with the call * <p>First, if there is a security manager, its <code>checkSecurityAccess()
checkSecurityAccess with "setIdentityPublicKey". * </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 to use *
* @param key the public key for this identity.
@throws KeyManagementException if this public key is used by * @throws KeyManagementException if another identity in the identity's scope
another identity in the current scope. * has the same public key, or if another exception occurs.
@throws SecurityException - if the security manager denies * @throws SecurityException if a security manager exists and its
access to "setIdentityPublicKey" * <code>checkSecurityAccess()<code> method doesn't allow setting the public
* key.
* @see #getPublicKey()
* @see SecurityManager#checkSecurityAccess(String)
*/ */
public void setPublicKey(PublicKey key) throws KeyManagementException public void setPublicKey(PublicKey key) throws KeyManagementException
{ {
...@@ -162,15 +166,18 @@ public abstract class Identity implements Principal, Serializable ...@@ -162,15 +166,18 @@ public abstract class Identity implements Principal, Serializable
} }
/** /**
Sets the general information string. * <p>Specifies a general information string for this identity.</p>
*
This class checks the security manager with the call * <p>First, if there is a security manager, its <code>checkSecurityAccess()
checkSecurityAccess with "setIdentityInfo". * </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 general information string. *
* @param info the information string.
@throws SecurityException - if the security manager denies * @throws SecurityException if a security manager exists and its
access to "setIdentityInfo" * <code>checkSecurityAccess()</code> method doesn't allow setting the
* information string.
* @see #getInfo()
* @see SecurityManager#checkSecurityAccess(String)
*/ */
public void setInfo(String info) public void setInfo(String info)
{ {
...@@ -182,9 +189,10 @@ public abstract class Identity implements Principal, Serializable ...@@ -182,9 +189,10 @@ public abstract class Identity implements Principal, Serializable
} }
/** /**
Gets the general information string. * Returns general information previously specified for this identity.
*
@return the string * @return general information about this identity.
* @see #setInfo(String)
*/ */
public String getInfo() public String getInfo()
{ {
...@@ -192,50 +200,54 @@ public abstract class Identity implements Principal, Serializable ...@@ -192,50 +200,54 @@ public abstract class Identity implements Principal, Serializable
} }
/** /**
Adds a certificate to the list of ceritificates for this * <p>Adds a certificate for this identity. If the identity has a public key,
identity. The public key in this certificate must match the * the public key in the certificate must be the same, and if the identity
existing public key if it exists. * does not have a public key, the identity's public key is set to be that
* specified in the certificate.</p>
This class checks the security manager with the call *
checkSecurityAccess with "addIdentityCertificate". * <p>First, if there is a security manager, its <code>checkSecurityAccess()
* </code> method is called with <code>"addIdentityCertificate"</code> as its
@param certificate the certificate to add * argument to see if it's ok to add a certificate.</p>
*
@throws KeyManagementException if the certificate is invalid * @param certificate the certificate to be added.
or the public key conflicts * @throws KeyManagementException if the certificate is not valid, if the
@throws SecurityException - if the security manager denies * public key in the certificate being added conflicts with this identity's
access to "addIdentityCertificate" * 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 throws KeyManagementException
{ {
SecurityManager sm = System.getSecurityManager(); SecurityManager sm = System.getSecurityManager();
if (sm != null) if (sm != null)
sm.checkSecurityAccess("addIdentityCertificate"); sm.checkSecurityAccess("addIdentityCertificate");
//Check public key of this certificate against the first one // Check public key of this certificate against the first one in the vector
//in the vector
if (certificates.size() > 0) if (certificates.size() > 0)
{ {
if (((Certificate) certificates.firstElement()).getPublicKey() != if (((Certificate) certificates.firstElement()).getPublicKey() != publicKey)
publicKey)
throw new KeyManagementException("Public key does not match"); throw new KeyManagementException("Public key does not match");
} }
certificates.addElement(certificate); certificates.addElement(certificate);
} }
/** /**
Removes a certificate from the list of ceritificates for this * <p>Removes a certificate from this identity.</p>
identity. *
* <p>First, if there is a security manager, its <code>checkSecurityAccess()
This class checks the security manager with the call * </code> method is called with <code>"removeIdentityCertificate"</code> as
checkSecurityAccess with "removeIdentityCertificate". * its argument to see if it's ok to remove a certificate.</p>
*
@param certificate the certificate to add * @param certificate the certificate to be removed.
* @throws KeyManagementException if the certificate is missing, or if
@throws KeyManagementException if the certificate is invalid * another exception occurs.
@throws SecurityException - if the security manager denies * @throws SecurityException if a security manager exists and its
access to "removeIdentityCertificate" * <code>checkSecurityAccess()</code> method doesn't allow removing a
* certificate.
* @see SecurityManager#checkSecurityAccess(String)
*/ */
public void removeCertificate(Certificate certificate) public void removeCertificate(Certificate certificate)
throws KeyManagementException throws KeyManagementException
...@@ -251,9 +263,9 @@ public abstract class Identity implements Principal, Serializable ...@@ -251,9 +263,9 @@ public abstract class Identity implements Principal, Serializable
} }
/** /**
Returns an array of certificates for this identity. * Returns a copy of all the certificates for this identity.
*
@returns array of certificates * @return a copy of all the certificates for this identity.
*/ */
public Certificate[] certificates() public Certificate[] certificates()
{ {
...@@ -261,16 +273,22 @@ public abstract class Identity implements Principal, Serializable ...@@ -261,16 +273,22 @@ public abstract class Identity implements Principal, Serializable
int max = certificates.size(); int max = certificates.size();
for (int i = 0; i < max; i++) for (int i = 0; i < max; i++)
certs[i] = (Certificate) certificates.elementAt(i); certs[i] = (Certificate) certificates.elementAt(i);
return certs; return certs;
} }
/** /**
Checks for equality between this Identity and the specified * Tests for equality between the specified object and this identity. This
object. If first checks if they are the same object, then * first tests to see if the entities actually refer to the same object, in
if the name and scope matches and returns true if successful. * which case it returns <code>true</code>. Next, it checks to see if the
If these tests fail, identityEquals is called. * 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
@return true if they are equal, false otherwise * <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) public final boolean equals(Object identity)
{ {
...@@ -289,11 +307,15 @@ public abstract class Identity implements Principal, Serializable ...@@ -289,11 +307,15 @@ public abstract class Identity implements Principal, Serializable
} }
/** /**
Checks for equality between this Identity and the specified * Tests for equality between the specified <code>identity</code> and this
object. A subclass should override this method. The default * <i>identity</i>. This method should be overriden by subclasses to test for
behavior is to return true if the public key and names match. * equality. The default behavior is to return <code>true</code> if the names
* and public keys are equal.
@return true if they are equal, false otherwise *
* @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) protected boolean identityEquals(Identity identity)
{ {
...@@ -302,15 +324,19 @@ public abstract class Identity implements Principal, Serializable ...@@ -302,15 +324,19 @@ public abstract class Identity implements Principal, Serializable
} }
/** /**
Returns a string representing this Identity. * <p>Returns a short string describing this identity, telling its name and
* its scope (if any).</p>
This class checks the security manager with the call *
checkSecurityAccess with "printIdentity". * <p>First, if there is a security manager, its <code>checkSecurityAccess()
* </code> method is called with <code>"printIdentity"</code> as its argument
@returns a string representing this Identity. * to see if it's ok to return the string.</p>
*
@throws SecurityException - if the security manager denies * @return information about this identity, such as its name and the name of
access to "printIdentity" * 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() public String toString()
{ {
...@@ -323,18 +349,23 @@ public abstract class Identity implements Principal, Serializable ...@@ -323,18 +349,23 @@ public abstract class Identity implements Principal, Serializable
} }
/** /**
Returns a detailed string representing this Identity. * <p>Returns a string representation of this identity, with optionally more
* details than that provided by the <code>toString()</code> method without
This class checks the security manager with the call * any arguments.</p>
checkSecurityAccess with "printIdentity". *
* <p>First, if there is a security manager, its <code>checkSecurityAccess()
@param detailed indicates whether or not to provide detailed * </code> method is called with <code>"printIdentity"</code> as its argument
information * to see if it's ok to return the string.</p>
*
@returns a string representing this Identity. * @param detailed whether or not to provide detailed information.
* @return information about this identity. If detailed is <code>true</code>,
@throws SecurityException - if the security manager denies * then this method returns more information than that provided by the
access to "printIdentity" * <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) public String toString(boolean detailed)
{ {
...@@ -355,9 +386,9 @@ public abstract class Identity implements Principal, Serializable ...@@ -355,9 +386,9 @@ public abstract class Identity implements Principal, Serializable
} }
/** /**
Gets the hashcode for this Identity. * Returns a hashcode for this identity.
*
@returns the hashcode * @return a hashcode for this identity.
*/ */
public int hashCode() public int hashCode()
{ {
......
/* IdentityScope.java --- IdentityScope Class /* 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 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 it under the terms of the GNU General Public License as published by
...@@ -36,33 +36,46 @@ obligated to do so. If you do not wish to do so, delete this ...@@ -36,33 +36,46 @@ obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */ exception statement from your version. */
package java.security; package java.security;
import java.util.Enumeration; import java.util.Enumeration;
/** /**
IdentityScope represents a scope of an identity. IdentityScope * <p>This class represents a scope for identities. It is an Identity itself,
is also an Identity and can have a name and scope along with * and therefore has a name and can have a scope. It can also optionally have a
the other qualitites identities posses. * public key and associated certificates.</p>
*
An IdentityScope contains other Identity objects. All Identity * <p>An <code>IdentityScope</code> can contain {@link Identity} objects of all
objects are manipulated in the scope the same way. The scope * kinds, including {@link Signer}s. All types of <code>Identity</code> objects
is suppose to apply different scope to different type of * can be retrieved, added, and removed using the same methods. Note that it is
Identities. * possible, and in fact expected, that different types of identity scopes will
* apply different policies for their various operations on the various types of
No identity within the same scope can have the same public key. * Identities.</p>
*
@since JDK 1.1 * <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,
@deprecated Use java.security.KeyStore, the java.security.cert * Inc is a software publisher known to a user. Suppose it is an <i>Identity</i>,
package, and java.security.Principal. * 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
@author Mark Benvenuto * </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 public abstract class IdentityScope extends Identity
{ {
static final long serialVersionUID = -2337346281189773310L;
private static IdentityScope systemScope = null; 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() protected IdentityScope()
{ {
...@@ -70,10 +83,9 @@ public abstract class IdentityScope extends Identity ...@@ -70,10 +83,9 @@ public abstract class IdentityScope extends Identity
} }
/** /**
Creates a new instance of IdentityScope with the specified name * Constructs a new identity scope with the specified name.
and no scope. *
* @param name the scope name.
@param name the name to use
*/ */
public IdentityScope(String name) public IdentityScope(String name)
{ {
...@@ -81,14 +93,12 @@ public abstract class IdentityScope extends Identity ...@@ -81,14 +93,12 @@ public abstract class IdentityScope extends Identity
} }
/** /**
Creates a new instance of IdentityScope with the specified name * Constructs a new identity scope with the specified name and scope.
and IdentityScope. *
* @param name the scope name.
@param name the name to use * @param scope the scope for the new identity scope.
@param scope the scope to use * @throws KeyManagementException if there is already an identity with the
* same name in the scope.
@throws KeyManagementException if the identity scope is already
present
*/ */
public IdentityScope(String name, IdentityScope scope) public IdentityScope(String name, IdentityScope scope)
throws KeyManagementException throws KeyManagementException
...@@ -97,7 +107,10 @@ public abstract class IdentityScope extends Identity ...@@ -97,7 +107,10 @@ public abstract class IdentityScope extends Identity
} }
/** /**
Gets the system's Scope. * Returns the system's identity scope.
*
* @return the system's identity scope.
* @see #setSystemScope(IdentityScope)
*/ */
public static IdentityScope getSystemScope() public static IdentityScope getSystemScope()
{ {
...@@ -110,15 +123,18 @@ public abstract class IdentityScope extends Identity ...@@ -110,15 +123,18 @@ public abstract class IdentityScope extends Identity
} }
/** /**
Sets the scope of the system. * <p>Sets the system's identity scope.</p>
*
This class checks the security manager with the call * <p>First, if there is a security manager, its <code>checkSecurityAccess()
checkSecurityAccess with "setSystemScope". * </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 new sustem scope *
* @param scope the scope to set.
@throws SecurityException - if the security manager denies * @throws SecurityException if a security manager exists and its
access to "setSystemScope" * <code>checkSecurityAccess()<code> method doesn't allow setting the
* identity scope.
* @see #getSystemScope()
* @see SecurityManager#checkSecurityAccess(String)
*/ */
protected static void setSystemScope(IdentityScope scope) protected static void setSystemScope(IdentityScope scope)
{ {
...@@ -130,31 +146,29 @@ public abstract class IdentityScope extends Identity ...@@ -130,31 +146,29 @@ public abstract class IdentityScope extends Identity
} }
/** /**
Gets the number of entries within this IdentityScope. * Returns the number of identities within this identity scope.
*
@returns the number of entries * @return the number of identities within this identity scope.
*/ */
public abstract int size(); public abstract int size();
/** /**
Gets the specified Identity within this scope * Returns the identity in this scope with the specified name (if any).
by specified name. *
* @param name the name of the identity to be retrieved.
@param name name of Identity to get * @return the identity named name, or <code>null</code> if there are no
* identities named name in this scope.
@returns an identity representing the name or null if it
cannot be found
*/ */
public abstract Identity getIdentity(String name); public abstract Identity getIdentity(String name);
/** /**
Gets the specified Identity within this scope * Retrieves the identity whose name is the same as that of the specified
by the specified Principal. * principal. (Note: <code>Identity</code> implements <code>Principal</code>.)
*
@param principal The Principal of the Identity to get * @param principal the principal corresponding to the identity to be
* retrieved.
@returns an identity representing the principal or null if it * @return the identity whose name is the same as that of the principal, or
cannot be found * <code>null</code> if there are no identities of the same name in this scope.
*/ */
public Identity getIdentity(Principal principal) public Identity getIdentity(Principal principal)
{ {
...@@ -162,55 +176,51 @@ public abstract class IdentityScope extends Identity ...@@ -162,55 +176,51 @@ public abstract class IdentityScope extends Identity
} }
/** /**
Gets the specified Identity within this scope * Retrieves the identity with the specified public key.
by the specified public key. *
* @param key the public key for the identity to be returned.
@param key the PublicKey of the Identity to get * @return the identity with the given key, or <code>null</code> if there are
* no identities in this scope with that key.
@returns an identity representing the public key or null if it
cannot be found
*/ */
public abstract Identity getIdentity(PublicKey key); public abstract Identity getIdentity(PublicKey key);
/** /**
Adds an identity to his scope. * Adds an identity to this identity scope.
*
@param identity the identity to add * @param identity the identity to be added.
* @throws KeyManagementException if the identity is not valid, a name
@throws KeyManagementException if it is an invalid identity, * conflict occurs, another identity has the same public key as the identity
an identity with the same key exists, or another error * being added, or another exception occurs.
occurs.
*/ */
public abstract void addIdentity(Identity identity) public abstract void addIdentity(Identity identity)
throws KeyManagementException; throws KeyManagementException;
/** /**
Removes an identity to his scope. * Removes an identity from this identity scope.
*
@param identity the identity to remove * @param identity the identity to be removed.
* @throws KeyManagementException if the identity is missing, or another
@throws KeyManagementException if it is a missing identity, * exception occurs.
or another error occurs.
*/ */
public abstract void removeIdentity(Identity identity) public abstract void removeIdentity(Identity identity)
throws KeyManagementException; throws KeyManagementException;
/** /**
Returns an Enumeration of identities. * Returns an enumeration of all identities in this identity scope.
*
@returns an enumeration of the identities. * @return an enumeration of all identities in this identity scope.
*/ */
public abstract Enumeration identities(); public abstract Enumeration identities();
/** /**
Returns a string representing this IdentityScope. * Returns a string representation of this identity scope, including its name,
It includes the name, the scope name, and number of identities. * its scope name, and the number of identities in this identity scope.
*
@returns a string representing this IdentityScope. * @return a string representation of this identity scope.
* @see SecurityManager#checkSecurityAccess(String)
*/ */
public String toString() public String toString()
{ {
return (super.getName() + " " + super.getScope().getName() return (super.getName() + " " + super.getScope().getName() + " " + size());
+ " " + size());
} }
} }
/* KeyFactory.java --- Key Factory Class /* 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. This file is part of GNU Classpath.
...@@ -36,37 +36,67 @@ obligated to do so. If you do not wish to do so, delete this ...@@ -36,37 +36,67 @@ obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */ exception statement from your version. */
package java.security; package java.security;
import java.security.spec.KeySpec; import java.security.spec.KeySpec;
import java.security.spec.InvalidKeySpecException; import java.security.spec.InvalidKeySpecException;
import java.security.NoSuchAlgorithmException;
/** /**
Key factories are used to convert keys (opaque cryptographic * <p>Key factories are used to convert keys (opaque cryptographic keys of type
keys of type Key) into key specifications (transparent * {@link Key}) into key specifications (transparent representations of the
representations of the underlying key material). * underlying key material), and vice versa.</p>
*
Key factories are bi-directional. They allow a key class * <p>Key factories are bi-directional. That is, they allow you to build an
to be converted into a key specification (key material) and * opaque key object from a given key specification (key material), or to
back again. * retrieve the underlying key material of a key object in a suitable format.</p>
*
For example DSA public keys can be specified as * <p>Multiple compatible key specifications may exist for the same key. For
DSAPublicKeySpec or X509EncodedKeySpec. The key factory * example, a <i>DSA</i> public key may be specified using {@link
translate these key specifications. * java.security.spec.DSAPublicKeySpec} or {@link
* java.security.spec.X509EncodedKeySpec}. A key factory can be used to
@since JDK 1.2 * 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 @author Mark Benvenuto
*/ */
public class KeyFactory public class KeyFactory
{ {
/** The service name for key factories. */
private static final String KEY_FACTORY = "KeyFactory";
private KeyFactorySpi keyFacSpi; private KeyFactorySpi keyFacSpi;
private Provider provider; private Provider provider;
private String algorithm; private String algorithm;
/** /**
Constructs a new keyFactory with the specified parameters. * Creates a <code>KeyFactory</code> object.
*
@param keyFacSpi Key Factory SPI to use * @param keyFacSpi the delegate.
@param provider the provider of the Key Factory SPI * @param provider the provider.
@param algorithm the name of the key algorithm for this key factory * @param algorithm the name of the algorithm to associate with this
* <code>KeyFactory</code>.
*/ */
protected KeyFactory(KeyFactorySpi keyFacSpi, Provider provider, protected KeyFactory(KeyFactorySpi keyFacSpi, Provider provider,
String algorithm) String algorithm)
...@@ -77,84 +107,101 @@ public class KeyFactory ...@@ -77,84 +107,101 @@ public class KeyFactory
} }
/** /**
Gets an instance of the KeyFactory class representing * Generates a <code>KeyFactory</code> object that implements the specified
the specified key factory. If the algorithm is not * algorithm. If the default provider package provides an implementation of
found then, it throws NoSuchAlgorithmException. * the requested algorithm, an instance of <code>KeyFactory</code> containing
* that implementation is returned. If the algorithm is not available in the
@param algorithm the name of algorithm to choose * default package, other packages are searched.
@return a KeyFactory repesenting the desired algorithm *
* @param algorithm the name of the requested key algorithm. See Appendix A
@throws NoSuchAlgorithmException if the algorithm is not implemented by providers * in the Java Cryptography Architecture API Specification &amp; 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) public static KeyFactory getInstance(String algorithm)
throws NoSuchAlgorithmException throws NoSuchAlgorithmException
{ {
Provider[] p = Security.getProviders(); Provider[] p = Security.getProviders();
for (int i = 0; i < p.length; i++) for (int i = 0; i < p.length; i++)
try
{ {
String classname = p[i].getProperty("KeyFactory." + algorithm); return getInstance(algorithm, p[i]);
if (classname != null)
return getInstance(classname, algorithm, p[i]);
} }
catch (NoSuchAlgorithmException ignored) {}
throw new NoSuchAlgorithmException(algorithm); throw new NoSuchAlgorithmException(algorithm);
} }
/** /**
Gets an instance of the KeyFactory class representing * Generates a <code>KeyFactory</code> object for the specified algorithm
the specified key factory from the specified provider. * from the specified provider.
If the algorithm is not found then, it throws *
NoSuchAlgorithmException. If the provider is not found, then * @param algorithm the name of the requested key algorithm. See Appendix A
it throws NoSuchProviderException. * in the Java Cryptography Architecture API Specification &amp; Reference
* for information about standard algorithm names.
@param algorithm the name of algorithm to choose * @param provider the name of the provider.
@param provider the name of the provider to find the algorithm in * @return a <code>KeyFactory</code> object for the specified algorithm.
@return a KeyFactory repesenting the desired algorithm * @throws NoSuchAlgorithmException if the algorithm is not available from
* the specified provider.
@throws NoSuchAlgorithmException if the algorithm is not implemented by the provider * @throws NoSuchProviderException if the provider has not been configured.
@throws NoSuchProviderException if the provider is not found * @throws IllegalArgumentException if the provider name is null or empty.
* @see Provider
*/ */
public static KeyFactory getInstance(String algorithm, String provider) public static KeyFactory getInstance(String algorithm, String provider)
throws NoSuchAlgorithmException, NoSuchProviderException throws NoSuchAlgorithmException, NoSuchProviderException
{ {
if (provider == null || provider.length() == 0)
throw new IllegalArgumentException("Illegal provider");
Provider p = Security.getProvider(provider); Provider p = Security.getProvider(provider);
if (p == null) if (p == null)
throw new NoSuchProviderException(); throw new NoSuchProviderException();
return getInstance(p.getProperty("KeyFactory." + algorithm), return getInstance(algorithm, p);
algorithm, p);
} }
private static KeyFactory getInstance(String classname, /**
String algorithm, * Generates a <code>KeyFactory</code> object for the specified algorithm from
Provider provider) * 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 &amp; 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 throws NoSuchAlgorithmException
{ {
if (provider == null)
throw new IllegalArgumentException("Illegal provider");
try try
{ {
return new KeyFactory((KeyFactorySpi) Class.forName(classname). return new KeyFactory((KeyFactorySpi)
newInstance(), provider, algorithm); Engine.getInstance(KEY_FACTORY, algorithm, provider),
} provider, algorithm);
catch (ClassNotFoundException cnfe)
{
throw new NoSuchAlgorithmException("Class not found");
}
catch (InstantiationException ie)
{
throw new NoSuchAlgorithmException("Class instantiation failed");
} }
catch (IllegalAccessException iae) catch (ClassCastException cce)
{ {
throw new NoSuchAlgorithmException("Illegal Access"); throw new NoSuchAlgorithmException(algorithm);
} }
} }
/** /**
Gets the provider that the class is from. * Returns the provider of this key factory object.
*
@return the provider of this class * @return the provider of this key factory object.
*/ */
public final Provider getProvider() public final Provider getProvider()
{ {
...@@ -162,9 +209,10 @@ public class KeyFactory ...@@ -162,9 +209,10 @@ public class KeyFactory
} }
/** /**
Returns the name of the algorithm used * Gets the name of the algorithm associated with this <code>KeyFactory</code>.
*
@return A string with the name of the algorithm * @return the name of the algorithm associated with this
* <code>KeyFactory</code>.
*/ */
public final String getAlgorithm() public final String getAlgorithm()
{ {
...@@ -172,52 +220,51 @@ public class KeyFactory ...@@ -172,52 +220,51 @@ public class KeyFactory
} }
/** /**
Generates a public key from the provided key specification. * Generates a public key object from the provided key specification (key
* material).
@param keySpec key specification *
* @param keySpec the specification (key material) of the public key.
@return the public key * @return the public key.
* @throws InvalidKeySpecException if the given key specification is
@throws InvalidKeySpecException invalid key specification for * inappropriate for this key factory to produce a public key.
this key factory to produce a public key
*/ */
public final PublicKey generatePublic(KeySpec keySpec) throws public final PublicKey generatePublic(KeySpec keySpec)
InvalidKeySpecException throws InvalidKeySpecException
{ {
return keyFacSpi.engineGeneratePublic(keySpec); return keyFacSpi.engineGeneratePublic(keySpec);
} }
/** /**
Generates a private key from the provided key specification. * Generates a private key object from the provided key specification (key
* material).
@param keySpec key specification *
* @param keySpec the specification (key material) of the private key.
@return the private key * @return the private key.
* @throws InvalidKeySpecException if the given key specification is
@throws InvalidKeySpecException invalid key specification for * inappropriate for this key factory to produce a private key.
this key factory to produce a private key
*/ */
public final PrivateKey generatePrivate(KeySpec keySpec) throws public final PrivateKey generatePrivate(KeySpec keySpec)
InvalidKeySpecException throws InvalidKeySpecException
{ {
return keyFacSpi.engineGeneratePrivate(keySpec); return keyFacSpi.engineGeneratePrivate(keySpec);
} }
/** /**
Returns a key specification for the given key. keySpec * Returns a specification (key material) of the given key object.
identifies the specification class to return the key * <code>keySpec</code> identifies the specification class in which the key
material in. * material should be returned. It could, for example, be
* <code>DSAPublicKeySpec.class</code>, to indicate that the key material
@param key the key * should be returned in an instance of the {@link
@param keySpec the specification class to return the * java.security.spec.DSAPublicKeySpec} class.
key material in. *
* @param key the key.
@return the key specification in an instance of the requested * @param keySpec the specification class in which the key material should be
specification class * returned.
* @return the underlying key specification (key material) in an instance of
@throws InvalidKeySpecException the requested key specification * the requested specification class.
is inappropriate for this key or the key is * @throws InvalidKeySpecException if the requested key specification is
unrecognized. * 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) public final KeySpec getKeySpec(Key key, Class keySpec)
throws InvalidKeySpecException throws InvalidKeySpecException
...@@ -226,15 +273,13 @@ public class KeyFactory ...@@ -226,15 +273,13 @@ public class KeyFactory
} }
/** /**
Translates the key from an unknown or untrusted provider * Translates a key object, whose provider may be unknown or potentially
into a key for this key factory. * untrusted, into a corresponding key object of this key factory.
*
@param the key from an unknown or untrusted provider * @param key the key whose provider is unknown or untrusted.
* @return the translated key.
@return the translated key * @throws InvalidKeyException if the given key cannot be processed by this
* key factory.
@throws InvalidKeySpecException if the key cannot be
processed by this key factory
*/ */
public final Key translateKey(Key key) throws InvalidKeyException public final Key translateKey(Key key) throws InvalidKeyException
{ {
......
/* KeyPairGenerator.java --- Key Pair Generator Class /* 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. This file is part of GNU Classpath.
...@@ -40,25 +40,94 @@ package java.security; ...@@ -40,25 +40,94 @@ package java.security;
import java.security.spec.AlgorithmParameterSpec; import java.security.spec.AlgorithmParameterSpec;
/** /**
KeyPairGenerator is the class used to generate key pairs * <p>The <code>KeyPairGenerator</code> class is used to generate pairs of
for a security algorithm. * public and private keys. Key pair generators are constructed using the
* <code>getInstance()</code> factory methods (static methods that return
The KeyPairGenerator is created with the getInstance() * instances of a given class).</p>
methods. The class is used to generate public and private *
keys for an algorithm and associate it with * <p>A Key pair generator for a particular algorithm creates a public/private
algorithm parameters. * key pair that can be used with this algorithm. It also associates
* algorithm-specific parameters with each of the generated keys.</p>
@author Mark Benvenuto *
* <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
* {@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 {@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 {@link AlgorithmParameterSpec}
* argument. One also has a {@link SecureRandom} argument, while the the
* other uses the {@link SecureRandom} implementation of the highest-priority
* installed provider as the source of randomness. (If none of the installed
* providers supply an implementation of {@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 {@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 public abstract class KeyPairGenerator extends KeyPairGeneratorSpi
{ {
/** The service name for key pair generators. */
private static final String KEY_PAIR_GENERATOR = "KeyPairGenerator";
Provider provider; Provider provider;
private String algorithm; private String algorithm;
/** /**
Constructs a new KeyPairGenerator * Creates a <code>KeyPairGenerator</code> object for the specified
* algorithm.
@param algorithm the algorithm to use *
* @param algorithm the standard string name of the algorithm.
* See Appendix A in the Java Cryptography Architecture API
* Specification &amp; Reference for information about standard
* algorithm names.
*/ */
protected KeyPairGenerator(String algorithm) protected KeyPairGenerator(String algorithm)
{ {
...@@ -67,9 +136,11 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi ...@@ -67,9 +136,11 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi
} }
/** /**
Returns the name of the algorithm used * Returns the standard name of the algorithm for this key pair generator.
* See Appendix A in the Java Cryptography Architecture API Specification
@return A string with the name of the algorithm * &amp; Reference for information about standard algorithm names.
*
* @return the standard string name of the algorithm.
*/ */
public String getAlgorithm() public String getAlgorithm()
{ {
...@@ -77,21 +148,24 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi ...@@ -77,21 +148,24 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi
} }
/** /**
Gets an instance of the KeyPairGenerator class * Generates a <code>KeyPairGenerator</code> object that implements the
which generates key pairs for the specified algorithm. * specified digest algorithm. If the default provider package provides an
If the algorithm is not found then, it throws NoSuchAlgorithmException. * implementation of the requested digest algorithm, an instance of
* <code>KeyPairGenerator</code> containing that implementation is returned.
@param algorithm the name of algorithm to choose * If the algorithm is not available in the default package, other packages
@return a AlgorithmParameterGenerator repesenting the desired algorithm * are searched.
*
@throws NoSuchAlgorithmException if the algorithm is not implemented by * @param algorithm the standard string name of the algorithm. See Appendix A
providers * in the Java Cryptography Architecture API Specification &amp; 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 public static KeyPairGenerator getInstance(String algorithm)
NoSuchAlgorithmException throws NoSuchAlgorithmException
{ {
Provider[] p = Security.getProviders(); Provider[] p = Security.getProviders();
for (int i = 0; i < p.length; i++) for (int i = 0; i < p.length; i++)
{ {
try try
...@@ -105,17 +179,22 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi ...@@ -105,17 +179,22 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi
} }
/** /**
Gets an instance of the KeyPairGenerator class * Generates a <code>KeyPairGenerator</code> object implementing the
which generates key pairs for the specified algorithm. * specified algorithm, as supplied from the specified provider, if
If the algorithm is not found then, it throws NoSuchAlgorithmException. * such an algorithm is available from the provider.
*
@param algorithm the name of algorithm to choose * @param algorithm the standard string name of the algorithm. See
@param provider the name of the provider to find the algorithm in * Appendix A in the Java Cryptography Architecture API Specification
@return a AlgorithmParameterGenerator repesenting the desired algorithm * &amp; Reference for information about standard algorithm names.
* @param provider the string name of the provider.
@throws NoSuchAlgorithmException if the algorithm is not implemented by * @return the new <code>KeyPairGenerator</code> object.
the provider * @throws NoSuchAlgorithmException if the algorithm is not available
@throws NoSuchProviderException if the provider is not found * 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) public static KeyPairGenerator getInstance(String algorithm, String provider)
throws NoSuchAlgorithmException, NoSuchProviderException throws NoSuchAlgorithmException, NoSuchProviderException
...@@ -127,69 +206,50 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi ...@@ -127,69 +206,50 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi
return getInstance(algorithm, p); return getInstance(algorithm, p);
} }
private static KeyPairGenerator getInstance(String algorithm, Provider p) /**
throws NoSuchAlgorithmException * Generates a <code>KeyPairGenerator</code> object implementing the specified
{ * algorithm, as supplied from the specified provider, if such an algorithm is
// try the name as is * available from the provider. Note: the provider doesn't have to be
String className = p.getProperty("KeyPairGenerator." + algorithm); * registered.
if (className == null) { // try all uppercase *
String upper = algorithm.toUpperCase(); * @param algorithm the standard string name of the algorithm. See Appendix A
className = p.getProperty("KeyPairGenerator." + upper); * in the Java Cryptography Architecture API Specification &amp; Reference for
if (className == null) { // try if it's an alias * information about standard algorithm names.
String alias = p.getProperty("Alg.Alias.KeyPairGenerator." + algorithm); * @param provider the provider.
if (alias == null) { // try all-uppercase alias name * @return the new <code>KeyPairGenerator</code> object.
alias = p.getProperty("Alg.Alias.KeyPairGenerator." + upper); * @throws NoSuchAlgorithmException if the <code>algorithm</code> is not
if (alias == null) { // spit the dummy * available from the <code>provider</code>.
throw new NoSuchAlgorithmException(algorithm); * @throws IllegalArgumentException if the <code>provider</code> is
} * <code>null</code>.
} * @since 1.4
className = p.getProperty("KeyPairGenerator." + alias); * @see Provider
if (className == null) { */
throw new NoSuchAlgorithmException(algorithm); public static KeyPairGenerator getInstance(String algorithm,
}
}
}
return getInstance(className, algorithm, p);
}
private static KeyPairGenerator getInstance(String classname,
String algorithm,
Provider provider) Provider provider)
throws NoSuchAlgorithmException throws NoSuchAlgorithmException
{ {
try if (provider == null)
{ throw new IllegalArgumentException("Illegal provider");
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;
}
kpg.provider = provider; Object o = Engine.getInstance(KEY_PAIR_GENERATOR, algorithm, provider);
return kpg; KeyPairGenerator result = null;
} if (o instanceof KeyPairGeneratorSpi)
catch (ClassNotFoundException cnfe)
{
throw new NoSuchAlgorithmException("Class not found");
}
catch (InstantiationException ie)
{ {
throw new NoSuchAlgorithmException("Class instantiation failed"); result = new DummyKeyPairGenerator((KeyPairGeneratorSpi) o, algorithm);
} }
catch (IllegalAccessException iae) else if (o instanceof KeyPairGenerator)
{ {
throw new NoSuchAlgorithmException("Illegal Access"); result = (KeyPairGenerator) o;
result.algorithm = algorithm;
} }
result.provider = provider;
return result;
} }
/** /**
Gets the provider that the class is from. * Returns the provider of this key pair generator object.
*
@return the provider of this class * @return the provider of this key pair generator object.
*/ */
public final Provider getProvider() public final Provider getProvider()
{ {
...@@ -197,11 +257,16 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi ...@@ -197,11 +257,16 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi
} }
/** /**
Initializes the KeyPairGenerator for the specified key size. * Initializes the key pair generator for a certain keysize using a default
(Since no source of randomness is specified, a default one is * parameter set and the {@link SecureRandom} implementation of the
provided.) * highest-priority installed provider as the source of randomness. (If none
* of the installed providers supply an implementation of {@link SecureRandom},
@param keysize Size of key to generate * 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) public void initialize(int keysize)
{ {
...@@ -209,13 +274,15 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi ...@@ -209,13 +274,15 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi
} }
/** /**
Initializes the KeyPairGenerator for the specified key size * Initializes the key pair generator for a certain keysize with the given
and specified SecureRandom. * source of randomness (and a default parameter set).
*
@param keysize Size of key to generate * @param keysize the keysize. This is an algorithm-specific metric, such as
@param random SecureRandom to use * modulus length, specified in number of bits.
* @param random the source of randomness.
@since JDK 1.2 * @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) public void initialize(int keysize, SecureRandom random)
{ {
...@@ -223,14 +290,25 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi ...@@ -223,14 +290,25 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi
} }
/** /**
Initializes the KeyPairGenerator with the specified * <p>Initializes the key pair generator using the specified parameter set and
AlgorithmParameterSpec class. * the {@link SecureRandom} implementation of the highest-priority installed
(Since no source of randomness is specified, a default one is * provider as the source of randomness. (If none of the installed providers
provided.) * supply an implementation of {@link SecureRandom}, a system-provided source
* of randomness is used.)</p>
@param params AlgorithmParameterSpec to initialize with *
* <p>This concrete method has been added to this previously-defined abstract
@since JDK 1.2 * class. This method calls the
* {@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 {@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) public void initialize(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException throws InvalidAlgorithmParameterException
...@@ -239,13 +317,21 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi ...@@ -239,13 +317,21 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi
} }
/** /**
Initializes the KeyPairGenerator with the specified * <p>Initializes the key pair generator with the given parameter set and
AlgorithmParameterSpec class and specified SecureRandom. * source of randomness.</p>
*
@param params AlgorithmParameterSpec to initialize with * <p>This concrete method has been added to this previously-defined abstract
@param random SecureRandom to use * class. This method calls the
* {@link KeyPairGeneratorSpi#initialize(AlgorithmParameterSpec, SecureRandom)}
@since JDK 1.2 * initialize method, passing it <code>params</code> and <code>random</code>.
* That initialize method always throws an {@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) public void initialize(AlgorithmParameterSpec params, SecureRandom random)
throws InvalidAlgorithmParameterException throws InvalidAlgorithmParameterException
...@@ -254,13 +340,18 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi ...@@ -254,13 +340,18 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi
} }
/** /**
Generates a KeyPair according the rules for the algorithm. * <p>Generates a key pair.</p>
Unless intialized, algorithm defaults will be used. It *
creates a unique key pair each time. * <p>If this <code>KeyPairGenerator</code> has not been initialized
* explicitly, provider-specific defaults will be used for the size and other
Same as generateKeyPair(); * (algorithm-specific) values of the generated keys.</p>
*
@return a key pair * <p>This will generate a new key pair every time it is called.</p>
*
* <p>This method is functionally equivalent to {@link #generateKeyPair()}.</p>
*
* @return the generated key pair.
* @since 1.2
*/ */
public final KeyPair genKeyPair() public final KeyPair genKeyPair()
{ {
...@@ -277,13 +368,17 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi ...@@ -277,13 +368,17 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi
} }
/** /**
Generates a KeyPair according the rules for the algorithm. * <p>Generates a key pair.</p>
Unless intialized, algorithm defaults will be used. It *
creates a unique key pair each time. * <p>If this <code>KeyPairGenerator</code> has not been initialized
* explicitly, provider-specific defaults will be used for the size and other
Same as genKeyPair(); * (algorithm-specific) values of the generated keys.</p>
*
@return a key pair * <p>This will generate a new key pair every time it is called.</p>
*
* <p>This method is functionally equivalent to {@link #genKeyPair()}.</p>
*
* @return the generated key pair.
*/ */
public KeyPair generateKeyPair() public KeyPair generateKeyPair()
{ {
......
/* KeyStore.java --- Key Store Class /* 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. This file is part of GNU Classpath.
...@@ -44,37 +44,52 @@ import java.util.Date; ...@@ -44,37 +44,52 @@ import java.util.Date;
import java.util.Enumeration; import java.util.Enumeration;
/** /**
Keystore represents an in-memory collection of keys and * Keystore represents an in-memory collection of keys and
certificates. There are two types of entries: * certificates. There are two types of entries:
*
* Key Entry * <dl>
* <dt>Key Entry</dt>
This type of keystore entry store sensitive crytographic key *
information in a protected format.Typically this is a secret * <dd><p>This type of keystore entry store sensitive crytographic key
key or a private key with a certificate chain. * information in a protected format.Typically this is a secret
* key or a private key with a certificate chain.</p></dd>
*
* Trusted Ceritificate Entry * <dt>Trusted Ceritificate Entry</dt>
*
This type of keystore entry contains a single public key * <dd><p>This type of keystore entry contains a single public key
certificate belonging to annother entity. It is called trusted * certificate belonging to annother entity. It is called trusted
because the keystore owner trusts that the certificates * because the keystore owner trusts that the certificates
belongs to the subject (owner) of the certificate. * belongs to the subject (owner) of the certificate.</p></dd>
* </dl>
The keystore contains an "alias" string for each entry. *
* <p>Entries in a key store are referred to by their "alias": a simple
The structure and persistentence of the key store is not * unique string.
specified. Any method could be used to protect sensitive *
(private or secret) keys. Smart cards or integrated * <p>The structure and persistentence of the key store is not
cryptographic engines could be used or the keystore could * specified. Any method could be used to protect sensitive
be simply stored in a file. * (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 public class KeyStore
{ {
// Constants and fields.
// ------------------------------------------------------------------------
/** Service name for key stores. */
private static final String KEY_STORE = "KeyStore";
private KeyStoreSpi keyStoreSpi; private KeyStoreSpi keyStoreSpi;
private Provider provider; private Provider provider;
private String type; private String type;
// Constructors.
// ------------------------------------------------------------------------
/** /**
Creates an instance of KeyStore Creates an instance of KeyStore
...@@ -89,16 +104,18 @@ public class KeyStore ...@@ -89,16 +104,18 @@ public class KeyStore
this.type = type; this.type = type;
} }
/** // Class methods.
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 /**
* Gets an instance of the KeyStore class representing
@throws KeyStoreException if the type of keystore is not implemented by providers * 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 public static KeyStore getInstance(String type) throws KeyStoreException
{ {
...@@ -106,95 +123,102 @@ public class KeyStore ...@@ -106,95 +123,102 @@ public class KeyStore
for (int i = 0; i < p.length; i++) for (int i = 0; i < p.length; i++)
{ {
String classname = p[i].getProperty("KeyStore." + type); try
if (classname != null) {
return getInstance(classname, type, p[i]); return getInstance(type, p[i]);
}
catch (KeyStoreException ignore)
{
}
} }
throw new KeyStoreException(type); throw new KeyStoreException(type);
} }
/** /**
Gets an instance of the KeyStore class representing * Gets an instance of the KeyStore class representing
the specified key store from the specified provider. * the specified key store from the specified provider.
If the type is not found then, it throws KeyStoreException. * If the type is not found then, it throws KeyStoreException.
If the provider is not found, then it throws * If the provider is not found, then it throws
NoSuchProviderException. * NoSuchProviderException.
*
@param type the type of keystore to choose * @param type the type of keystore to choose
@param provider the provider name * @param provider the provider name
* @return a KeyStore repesenting the desired type
@return a KeyStore repesenting the desired type * @throws KeyStoreException if the type of keystore is not
* implemented by the given provider
@throws KeyStoreException if the type of keystore is not * @throws NoSuchProviderException if the provider is not found
implemented by the given provider * @throws IllegalArgumentException if the provider string is
@throws NoSuchProviderException if the provider is not found * null or empty
@throws IllegalArgumentException if the provider string is
null or empty
*/ */
public static KeyStore getInstance(String type, String provider) public static KeyStore getInstance(String type, String provider)
throws KeyStoreException, NoSuchProviderException throws KeyStoreException, NoSuchProviderException
{ {
if (provider == null || provider.length() == 0) if (provider == null || provider.length() == 0)
throw new IllegalArgumentException("Illegal provider"); throw new IllegalArgumentException("Illegal provider");
Provider p = Security.getProvider(provider); Provider p = Security.getProvider(provider);
if (p == null) if (p == null)
throw new NoSuchProviderException(); throw new NoSuchProviderException();
return getInstance(p.getProperty("KeyStore." + type), type, p); return getInstance(type, p);
} }
/** /**
Gets an instance of the KeyStore class representing * Gets an instance of the KeyStore class representing
the specified key store from the specified provider. * the specified key store from the specified provider.
If the type is not found then, it throws KeyStoreException. * If the type is not found then, it throws KeyStoreException.
If the provider is not found, then it throws * If the provider is not found, then it throws
NoSuchProviderException. * NoSuchProviderException.
*
@param type the type of keystore to choose * @param type the type of keystore to choose
@param provider the keystore provider * @param provider the keystore provider
* @return a KeyStore repesenting the desired type
@return a KeyStore repesenting the desired type * @throws KeyStoreException if the type of keystore is not
* implemented by the given provider
@throws KeyStoreException if the type of keystore is not * @throws IllegalArgumentException if the provider object is null
implemented by the given provider * @since 1.4
@throws IllegalArgumentException if the provider object is null
@since 1.4
*/ */
public static KeyStore getInstance(String type, Provider provider) public static KeyStore getInstance(String type, Provider provider)
throws KeyStoreException throws KeyStoreException
{ {
if (provider == null) if (provider == null)
throw new IllegalArgumentException("Illegal provider"); 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 try
{ {
return new KeyStore((KeyStoreSpi) Class.forName(classname). return new KeyStore(
newInstance(), provider, type); (KeyStoreSpi) Engine.getInstance(KEY_STORE, type, provider),
provider, type);
} }
catch (ClassNotFoundException cnfe) catch (NoSuchAlgorithmException nsae)
{ {
throw new KeyStoreException("Class not found"); throw new KeyStoreException(type);
} }
catch (InstantiationException ie) catch (ClassCastException cce)
{ {
throw new KeyStoreException("Class instantiation failed"); throw new KeyStoreException(type);
} }
catch (IllegalAccessException iae)
{
throw new KeyStoreException("Illegal Access");
} }
/**
* 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. Gets the provider that the class is from.
...@@ -471,21 +495,4 @@ public class KeyStore ...@@ -471,21 +495,4 @@ public class KeyStore
keyStoreSpi.engineLoad(stream, password); 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;
}
} }
/* MessageDigest.java --- The message digest interface. /* 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. This file is part of GNU Classpath.
...@@ -38,17 +37,73 @@ exception statement from your version. */ ...@@ -38,17 +37,73 @@ exception statement from your version. */
package java.security; 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 {@link Cloneable} interface.
* Client applications can test cloneability by attempting cloning and catching
* the {@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 {@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 public abstract class MessageDigest extends MessageDigestSpi
{ {
/** The service name for message digests. */
private static final String MESSAGE_DIGEST = "MessageDigest";
private String algorithm; private String algorithm;
Provider provider; Provider provider;
private byte[] lastDigest; private byte[] lastDigest;
/** /**
Creates a MessageDigest representing the specified * Creates a message digest with the specified algorithm name.
algorithm. *
* @param algorithm the standard name of the digest algorithm.
@param algorithm the name of digest algorithm to choose * See Appendix A in the Java Cryptography Architecture API
* Specification &amp; Reference for information about standard
* algorithm names.
*/ */
protected MessageDigest(String algorithm) protected MessageDigest(String algorithm)
{ {
...@@ -57,15 +112,19 @@ public abstract class MessageDigest extends MessageDigestSpi ...@@ -57,15 +112,19 @@ public abstract class MessageDigest extends MessageDigestSpi
} }
/** /**
Gets an instance of the MessageDigest class representing * Generates a <code>MessageDigest</code> object that implements the specified
the specified digest. If the algorithm is not found then, * digest algorithm. If the default provider package provides an
it throws NoSuchAlgorithmException. * implementation of the requested digest algorithm, an instance of
* <code>MessageDigest</code> containing that implementation is returned. If
@param algorithm the name of digest algorithm to choose * the algorithm is not available in the default package, other packages are
@return a MessageDigest representing the desired algorithm * searched.
*
@exception NoSuchAlgorithmException if the algorithm is not implemented by * @param algorithm the name of the algorithm requested. See Appendix A in the
providers * Java Cryptography Architecture API Specification &amp; 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) public static MessageDigest getInstance(String algorithm)
throws NoSuchAlgorithmException throws NoSuchAlgorithmException
...@@ -84,102 +143,83 @@ public abstract class MessageDigest extends MessageDigestSpi ...@@ -84,102 +143,83 @@ public abstract class MessageDigest extends MessageDigestSpi
} }
/** /**
Gets an instance of the MessageDigest class representing * Generates a <code>MessageDigest</code> object implementing the specified
the specified digest from the specified provider. If the * algorithm, as supplied from the specified provider, if such an algorithm is
algorithm is not found then, it throws NoSuchAlgorithmException. * available from the provider.
If the provider is not found, then it throws *
NoSuchProviderException. * @param algorithm the name of the algorithm requested. See Appendix A in the
* Java Cryptography Architecture API Specification &amp; Reference for
@param algorithm the name of digest algorithm to choose * information about standard algorithm names.
@param provider the name of the provider to find the algorithm in * @param provider the name of the provider.
@return a MessageDigest representing the desired algorithm * @return a Message Digest object implementing the specified algorithm.
* @throws NoSuchAlgorithmException if the algorithm is not available in the
@exception NoSuchAlgorithmException if the algorithm is not implemented by * package supplied by the requested provider.
the provider * @throws NoSuchProviderException if the provider is not available in the
@exception NoSuchProviderException if the provider is not found * environment.
* @throws IllegalArgumentException if the provider name is null or empty.
* @see Provider
*/ */
public static MessageDigest getInstance(String algorithm, String provider) public static MessageDigest getInstance(String algorithm, String provider)
throws NoSuchAlgorithmException, NoSuchProviderException 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) if (p == null)
throw new NoSuchProviderException(provider); throw new NoSuchProviderException(provider);
return getInstance(algorithm, p); return getInstance(algorithm, p);
} }
private static MessageDigest getInstance(String algorithm, Provider p) /**
throws NoSuchAlgorithmException * Generates a <code>MessageDigest</code> object implementing the specified
{ * algorithm, as supplied from the specified provider, if such an algorithm
// try the name as is * is available from the provider. Note: the provider doesn't have to be
String className = p.getProperty("MessageDigest." + algorithm); * registered.
if (className == null) { // try all uppercase *
String upper = algorithm.toUpperCase(); * @param algorithm the name of the algorithm requested. See Appendix A in
className = p.getProperty("MessageDigest." + upper); * the Java Cryptography Architecture API Specification &amp; Reference for
if (className == null) { // try if it's an alias * information about standard algorithm names.
String alias = p.getProperty("Alg.Alias.MessageDigest." +algorithm); * @param provider the provider.
if (alias == null) { // try all-uppercase alias name * @return a Message Digest object implementing the specified algorithm.
alias = p.getProperty("Alg.Alias.MessageDigest." +upper); * @throws NoSuchAlgorithmException if the <code>algorithm</code> is not
if (alias == null) { // spit the dummy * available in the package supplied by the requested <code>provider</code>.
throw new NoSuchAlgorithmException(algorithm); * @throws IllegalArgumentException if the <code>provider</code> is
} * <code>null</code>.
} * @since 1.4
className = p.getProperty("MessageDigest." + alias); * @see Provider
if (className == null) { */
throw new NoSuchAlgorithmException(algorithm); public static MessageDigest getInstance(String algorithm, Provider provider)
}
}
}
return getInstance(className, algorithm, p);
}
private static MessageDigest getInstance(String classname,
String algorithm,
Provider provider)
throws NoSuchAlgorithmException throws NoSuchAlgorithmException
{ {
if (classname == null) if (provider == null)
throw new NoSuchAlgorithmException(algorithm); throw new IllegalArgumentException("Illegal provider");
MessageDigest result = null; MessageDigest result = null;
try Object o = Engine.getInstance(MESSAGE_DIGEST, algorithm, provider);
{
Object obj = Class.forName(classname).newInstance(); if (o instanceof MessageDigestSpi)
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;
}
catch (ClassNotFoundException cnfe)
{ {
throw new NoSuchAlgorithmException(algorithm + ": Class not found."); result = new DummyMessageDigest((MessageDigestSpi) o, algorithm);
} }
catch (InstantiationException ie) else if (o instanceof MessageDigest)
{ {
throw new NoSuchAlgorithmException(algorithm result = (MessageDigest) o;
+ ": Class instantiation failed."); result.algorithm = algorithm;
} }
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. * Returns the provider of this message digest object.
*
@return the provider the this MessageDigest * @return the provider of this message digest object.
*/ */
public final Provider getProvider() public final Provider getProvider()
{ {
...@@ -187,9 +227,9 @@ public abstract class MessageDigest extends MessageDigestSpi ...@@ -187,9 +227,9 @@ public abstract class MessageDigest extends MessageDigestSpi
} }
/** /**
Updates the digest with the byte. * Updates the digest using the specified byte.
*
@param input byte to update the digest with * @param input the byte with which to update the digest.
*/ */
public void update(byte input) public void update(byte input)
{ {
...@@ -197,32 +237,33 @@ public abstract class MessageDigest extends MessageDigestSpi ...@@ -197,32 +237,33 @@ public abstract class MessageDigest extends MessageDigestSpi
} }
/** /**
Updates the digest with the bytes from the array from the * Updates the digest using the specified array of bytes, starting at the
specified offset to the specified length. * specified offset.
*
@param input bytes to update the digest with * @param input the array of bytes.
@param offset the offset to start at * @param offset the offset to start from in the array of bytes.
@param len length of the data to update with * @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); engineUpdate(input, offset, len);
} }
/** /**
Updates the digest with the bytes from the array. * Updates the digest using the specified array of bytes.
*
@param input bytes to update the digest with * @param input the array of bytes.
*/ */
public void update(byte[]input) public void update(byte[] input)
{ {
engineUpdate(input, 0, input.length); engineUpdate(input, 0, input.length);
} }
/** /**
Computes the digest of the stored data. * Completes the hash computation by performing final operations such as
* padding. The digest is reset after this call is made.
@return a byte array representing the message digest *
* @return the array of bytes for the resulting hash value.
*/ */
public byte[] digest() public byte[] digest()
{ {
...@@ -230,52 +271,54 @@ public abstract class MessageDigest extends MessageDigestSpi ...@@ -230,52 +271,54 @@ public abstract class MessageDigest extends MessageDigestSpi
} }
/** /**
Computes the final digest of the stored bytes and returns * Completes the hash computation by performing final operations such as
them. * padding. The digest is reset after this call is made.
*
@param buf An array of bytes to store the digest * @param buf An output buffer for the computed digest.
@param offset An offset to start storing the digest at * @param offset The offset into the output buffer to begin storing the digest.
@param len The length of the buffer * @param len The number of bytes within buf allotted for the digest.
@return Returns the length of the buffer * @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); return engineDigest(buf, offset, len);
} }
/** /**
Computes a final update using the input array of bytes, * Performs a final update on the digest using the specified array of bytes,
then computes a final digest and returns it. It calls * then completes the digest computation. That is, this method first calls
update(input) and then digest(); * <code>update(input)</code>, passing the input array to the <code>update()
* </code> method, then calls <code>digest()</code>.
@param input An array of bytes to perform final update with *
@return a byte array representing the message digest * @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); update(input);
return digest(); return digest();
} }
/** /**
Returns a representation of the MessageDigest as a String. * Returns a string representation of this message digest object.
*
@return a string representing the message digest * @return a string representation of the object.
*/ */
public String toString() public String toString()
{ {
return (getClass()).getName() return (getClass()).getName() + " Message Digest <" + digestToString() + ">";
+ " Message Digest <" + digestToString() + ">";
} }
/** /**
Does a simple byte comparison of the two digests. * Compares two digests for equality. Does a simple byte compare.
*
@param digesta first digest to compare * @param digesta one of the digests to compare.
@param digestb second digest to compare * @param digestb the other digest to compare.
@return true if they are equal, false otherwise * @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) if (digesta.length != digestb.length)
return false; return false;
...@@ -287,20 +330,20 @@ public abstract class MessageDigest extends MessageDigestSpi ...@@ -287,20 +330,20 @@ public abstract class MessageDigest extends MessageDigestSpi
return true; return true;
} }
/** Resets the digest for further use. */
/**
Resets the message digest.
*/
public void reset() public void reset()
{ {
engineReset(); engineReset();
} }
/** /**
Gets the name of the algorithm currently used. * Returns a string that identifies the algorithm, independent of
The names of algorithms are usually SHA-1 or MD5. * implementation details. The name should be a standard Java Security name
* (such as <code>"SHA"</code>, <code>"MD5"</code>, and so on). See Appendix
@return name of algorithm. * A in the Java Cryptography Architecture API Specification &amp; Reference
* for information about standard algorithm names.
*
* @return the name of the algorithm.
*/ */
public final String getAlgorithm() public final String getAlgorithm()
{ {
...@@ -308,11 +351,13 @@ public abstract class MessageDigest extends MessageDigestSpi ...@@ -308,11 +351,13 @@ public abstract class MessageDigest extends MessageDigestSpi
} }
/** /**
Gets the length of the message digest. * Returns the length of the digest in bytes, or <code>0</code> if this
The default is zero which means that this message digest * operation is not supported by the provider and the implementation is not
does not implement this function. * cloneable.
*
@return length of the message digest * @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() public final int getDigestLength()
{ {
...@@ -320,15 +365,11 @@ public abstract class MessageDigest extends MessageDigestSpi ...@@ -320,15 +365,11 @@ public abstract class MessageDigest extends MessageDigestSpi
} }
/** /**
Returns a clone of this class if supported. * Returns a clone if the implementation is cloneable.
If it does not then it throws CloneNotSupportedException. *
The cloning of this class depends on whether the subclass * @return a clone if the implementation is cloneable.
MessageDigestSpi implements Cloneable which contains the * @throws CloneNotSupportedException if this is called on an implementation
actual implementation of the appropriate algorithm. * that does not support {@link Cloneable}.
@return clone of this class
@exception CloneNotSupportedException this class does not support cloning
*/ */
public Object clone() throws CloneNotSupportedException public Object clone() throws CloneNotSupportedException
{ {
...@@ -359,5 +400,4 @@ public abstract class MessageDigest extends MessageDigestSpi ...@@ -359,5 +400,4 @@ public abstract class MessageDigest extends MessageDigestSpi
return buf.toString(); return buf.toString();
} }
} }
/* Policy.java --- Policy Manager Class /* 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. This file is part of GNU Classpath.
...@@ -37,90 +37,87 @@ exception statement from your version. */ ...@@ -37,90 +37,87 @@ exception statement from your version. */
package java.security; package java.security;
import java.util.Collections;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.Map;
/** /**
Policy is an abstract class for managing the system security * <p>This is an abstract class for representing the system security policy for
policy for the Java application environment. It specifies * a Java application environment (specifying which permissions are available
which permissions are available for code from various * for code from various sources). That is, the security policy is represented
sources. The security policy is represented through a * by a <code>Policy</code> subclass providing an implementation of the abstract
subclass of Policy. * methods in this <code>Policy</code> class.</p>
*
Only one Policy is in effect at any time. ProtectionDomain * <p>There is only one <code>Policy</code> object in effect at any given time.
initializes itself with information from this class on the * </p>
set of permssions to grant. *
* <p>The source location for the policy information utilized by the
The location for the actual Policy could be anywhere in any * <code>Policy</code> object is up to the <code>Policy</code> implementation.
form because it depends on the Policy implementation. The * The policy configuration may be stored, for example, as a flat ASCII file, as
default system is in a flat ASCII file or it could be in a * a serialized binary file of the <code>Policy</code> class, or as a database.
database. * </p>
*
The current installed Policy can be accessed with getPolicy * <p>The currently-installed <code>Policy</code> object can be obtained by
and changed with setPolicy if the code has the correct * calling the <code>getPolicy()</code> method, and it can be changed by a call
permissions. * to the <code>setPolicy()</code> method (by code with permission to reset the
* <code>Policy</code>).</p>
The refresh method causes the Policy class to refresh/reload *
its configuration. The method used to refresh depends on the * <p>The <code>refresh()</code> method causes the policy object to refresh /
Policy implementation. * reload its current configuration.</p>
*
When a protection domain initializes its permissions it uses * <p>This is implementation-dependent. For example, if the policy object stores
code like: * its policy in configuration files, calling <code>refresh()</code> will cause
<code> * it to re-read the configuration policy files. The refreshed policy may not
policy = Policy.getPolicy(); * have an effect on classes in a particular {@link ProtectionDomain}. This is
permissionCollection perms = policy.getPermissions(MyCodeSource) * dependent on the <code>Policy</code> provider's implementation of the
</code> * <code>implies()</code> method and the {@link PermissionCollection} caching
The protection domain passes the Policy handler a CodeSource * strategy.</p>
object which contains the codebase URL and public key. The *
Policy implementation then returns the proper set of * <p>The default <code>Policy</code> implementation can be changed by setting
permissions for the CodeSource. * the value of the <code>"policy.provider"</code> security property (in the
* Java security properties file) to the fully qualified name of the desired
The default Policy implementation can be changed by setting * <code>Policy</code> implementation class. The Java security properties file
the "policy.provider" security provider in java.security * is located in the file named <code>&lt;JAVA_HOME>/lib/security/java.security
to the correct Policy implementation class. * </code>, where <code>&lt;JAVA_HOME></code> refers to the directory where the
* SDK was installed.</p>
@author Mark Benvenuto *
* <p><b>IMPLEMENTATION NOTE:</b> This implementation attempts to read the
@since JDK 1.2 * 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 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 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();
}
/** /** Map of ProtectionDomains to PermissionCollections for this instance. */
Constructs a new Policy class. private Map pd2pc = null;
*/
/** Constructs a new <code>Policy</code> object. */
public Policy() public Policy()
{ {
} }
/** /**
Gets the currently installed Policy handler. The value should * Returns the installed <code>Policy</code> object. This value should not be
not be cached as it can be changed by setPolicy. This * cached, as it may be changed by a call to <code>setPolicy()</code>. This
function first calls <code>SecurityManager.checkPermission</code> * method first calls {@link SecurityManager#checkPermission(Permission)} with
with <code>SecurityPermission("getPolicy")</code> to check * a <code>SecurityPermission("getPolicy")</code> permission to ensure it's ok
if the caller has Permission to get the current Policy. * to get the <code>Policy</code> object.
*
@return the current Policy * @return the installed <code>Policy</code>.
* @throws SecurityException if a security manager exists and its
@throws SecurityException if the security manager exists * <code>checkPermission()</code> method doesn't allow getting the
the caller does not have permission to * <code>Policy</code> object.
<code>getPolicy</code>. * @see SecurityManager#checkPermission(Permission)
* @see #setPolicy(Policy)
*/ */
public static Policy getPolicy() public static Policy getPolicy()
{ {
...@@ -128,20 +125,21 @@ public abstract class Policy ...@@ -128,20 +125,21 @@ public abstract class Policy
if (sm != null) if (sm != null)
sm.checkPermission(new SecurityPermission("getPolicy")); sm.checkPermission(new SecurityPermission("getPolicy"));
return currentPolicy; return getCurrentPolicy();
} }
/** /**
Sets the currently installed Policy handler. This * Sets the system-wide <code>Policy</code> object. This method first calls
function first calls <code>SecurityManager.checkPermission</code> * {@link SecurityManager#checkPermission(Permission)} with a
with <code>SecurityPermission("setPolicy")</code> to check * <code>SecurityPermission("setPolicy")</code> permission to ensure it's ok
if the caller has Permission to get the current Policy. * to set the <code>Policy</code>.
*
@param policy the new Policy to use * @param policy the new system <code>Policy</code> object.
* @throws SecurityException if a security manager exists and its
@throws SecurityException if the security manager exists * <code>checkPermission()</code> method doesn't allow setting the
the caller does not have permission to * <code>Policy</code>.
<code>getPolicy</code>. * @see SecurityManager#checkPermission(Permission)
* @see #getPolicy()
*/ */
public static void setPolicy(Policy policy) public static void setPolicy(Policy policy)
{ {
...@@ -149,27 +147,161 @@ public abstract class Policy ...@@ -149,27 +147,161 @@ public abstract class Policy
if (sm != null) if (sm != null)
sm.checkPermission(new SecurityPermission("setPolicy")); sm.checkPermission(new SecurityPermission("setPolicy"));
setup(policy);
currentPolicy = policy; currentPolicy = policy;
} }
private static void setup(final Policy policy)
{
if (policy.pd2pc == null)
policy.pd2pc = Collections.synchronizedMap(new LinkedHashMap());
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());
}
policy.pd2pc.put(pd, pc); // add the mapping pd -> pc
}
}
/** /**
Evalutes the global policy and returns a set of Permissions * Ensures/forces loading of the configured policy provider, while bypassing
allowed for the specified CodeSource. * the {@link SecurityManager} checks for <code>"getPolicy"</code> security
* permission. Needed by {@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) {}
@param codesource The CodeSource to get Permission for if (currentPolicy == null)
currentPolicy = new gnu.java.security.provider.DefaultPolicy();
}
return currentPolicy;
}
@return a set of permissions for codesource specified by /**
the current policy * Tests if <code>currentPolicy</code> is not <code>null</code>,
* thus allowing clients to not force loading of any policy
* provider; needed by {@link ProtectionDomain}.
*/
static boolean isLoaded()
{
return currentPolicy != null;
}
@throws SecurityException if the current thread does not /**
have permission to call <code>getPermissions</code> * Evaluates the global policy and returns a {@link PermissionCollection}
* object specifying the set of permissions allowed for code from the
* specified code source.
*
* @param codesource the {@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 {@link Permission} types.
*/ */
public abstract PermissionCollection getPermissions(CodeSource codesource); public abstract PermissionCollection getPermissions(CodeSource codesource);
/** /**
Refreshes and/or reloads the current Policy. The actual * Evaluates the global policy and returns a {@link PermissionCollection}
behavior of this method depends on the implementation. * object specifying the set of permissions allowed given the characteristics
* of the protection domain.
*
* @param domain the {@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 {@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 {@link
* ProtectionDomain} and tests whether the <code>permission</code> is granted.
*
* @param domain the {@link ProtectionDomain} to test.
* @param permission the {@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 {@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(); public abstract void refresh();
} }
/* ProtectionDomain.java -- A security domain /* 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. This file is part of GNU Classpath.
...@@ -38,55 +38,109 @@ exception statement from your version. */ ...@@ -38,55 +38,109 @@ exception statement from your version. */
package java.security; package java.security;
/** /**
* This class represents a group of classes, along with the permissions * <p>This <code>ProtectionDomain</code> class encapsulates the characteristics
* they are granted. The classes are identified by a <code>CodeSource</code>. * of a domain, which encloses a set of classes whose instances are granted a
* Thus, any class loaded from the specified <code>CodeSource</code> is * set of permissions when being executed on behalf of a given set of
* treated as part of this domain. The set of permissions is represented * <i>Principals</i>.
* by a <code>PermissionCollection</code>.
* <p>
* Every class in the system will belong to one and only one
* <code>ProtectionDomain</code>.
* *
* @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 {@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 {@link
* Policy} whenever a permission is checked.</p>
* *
* @author Aaron M. Renn (arenn@urbanophile.com) * @author Aaron M. Renn (arenn@urbanophile.com)
* @version 0.0
*/ */
public class ProtectionDomain 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; private CodeSource code_source;
/** This is the set of permissions granted to this domain. */
private PermissionCollection perms;
/** The {@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 {@link
* CodeSource} and {@link Permissions}. If the permissions object is not
* <code>null</code>, then <code>setReadOnly()</code> will be called on the
* passed in {@link Permissions} object. The only permissions granted to this
* domain are the ones specified; the current {@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> * <p>Creates a new ProtectionDomain qualified by the given CodeSource,
* representing the specified <code>CodeSource</code> and permission set. * Permissions, ClassLoader and array of Principals. If the permissions
* No permissions may be added to the <code>PermissionCollection</code> * object is not null, then <code>setReadOnly()</code> will be called on the
* and this contructor will call the <code>setReadOnly</code> method on * passed in Permissions object. The permissions granted to this domain are
* the specified permission set. * 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 * <p>This constructor is typically used by {@link ClassLoader}s and {@link
* @param perms The permission set for this domain * 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() * @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 code_source, PermissionCollection perms) 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)
{
super();
code_source = codesource;
if (permissions != null)
{ {
this.code_source = code_source; perms = permissions;
this.perms = perms;
if (perms != null)
perms.setReadOnly(); 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. * Returns the {@link CodeSource} of this domain.
* *
* @return This domain's <code>CodeSource</code>. * @return the {@link CodeSource} of this domain which may be <code>null</code>.
* @since 1.2
*/ */
public final CodeSource getCodeSource() public final CodeSource getCodeSource()
{ {
...@@ -94,9 +148,36 @@ public class ProtectionDomain ...@@ -94,9 +148,36 @@ public class ProtectionDomain
} }
/** /**
* This method returns the set of permissions granted to this domain. * Returns the {@link ClassLoader} of this domain.
* *
* @return The permission set for this domain * @return the {@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 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() public final PermissionCollection getPermissions()
{ {
...@@ -104,41 +185,85 @@ public class ProtectionDomain ...@@ -104,41 +185,85 @@ public class ProtectionDomain
} }
/** /**
* This method tests whether or not the specified <code>Permission</code> is * <p>Check and see if this <code>ProtectionDomain</code> implies the
* implied by the set of permissions granted to this domain. * 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 {@link PermissionCollection} then the permission will only be checked
* against the {@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
* {@link PermissionCollection} supplied at construction and the current
* {@link Policy} binding.
*
* @param permission the {@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 (staticBinding)
if (pc == null) return (perms == null ? false : perms.implies(permission));
return (false); // Else dynamically bound. Do we have it?
// NOTE: this will force loading of Policy.currentPolicy
return (pc.implies(perm)); return Policy.getCurrentPolicy().implies(this, permission);
} }
/** /**
* This method returns a <code>String</code> representation of this * Convert a <code>ProtectionDomain</code> to a String.
* object. It will print the <code>CodeSource</code> and
* permission set associated with this domain.
* *
* @return A <code>String</code> representation of this object. * @return a string representation of the object.
*/ */
public String toString() public String toString()
{ {
String linesep = System.getProperty("line.separator"); String linesep = System.getProperty("line.separator");
StringBuffer sb = new StringBuffer(""); StringBuffer sb = new StringBuffer("ProtectionDomain (").append(linesep);
sb.append("ProtectionDomain (" + linesep);
if (code_source == null) 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(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 else
sb.append(code_source + linesep);
sb.append(perms); sb.append(perms);
sb.append(linesep + ")" + linesep);
return sb.toString(); return sb.append(linesep).append(")").append(linesep).toString();
} }
} }
...@@ -42,14 +42,24 @@ import java.util.Random; ...@@ -42,14 +42,24 @@ import java.util.Random;
import java.util.Enumeration; import java.util.Enumeration;
/** /**
SecureRandom is the class interface for using SecureRandom * An interface to a cryptographically secure pseudo-random number
providers. It provides an interface to the SecureRandomSpi * generator (PRNG). Random (or at least unguessable) numbers are used
engine so that programmers can generate pseudo-random numbers. * in all areas of security and cryptography, from the generation of
* keys and initialization vectors to the generation of random padding
@author Mark Benvenuto <ivymccough@worldnet.att.net> * bytes.
*
* @author Mark Benvenuto <ivymccough@worldnet.att.net>
* @author Casey Marshall
*/ */
public class SecureRandom extends Random public class SecureRandom extends Random
{ {
// Constants and fields.
// ------------------------------------------------------------------------
/** Service name for PRNGs. */
private static final String SECURE_RANDOM = "SecureRandom";
static final long serialVersionUID = 4940670005562187L; static final long serialVersionUID = 4940670005562187L;
//Serialized Field //Serialized Field
...@@ -60,6 +70,9 @@ public class SecureRandom extends Random ...@@ -60,6 +70,9 @@ public class SecureRandom extends Random
SecureRandomSpi secureRandomSpi = null; SecureRandomSpi secureRandomSpi = null;
byte[] state = null; byte[] state = null;
// Constructors.
// ------------------------------------------------------------------------
/** /**
Default constructor for SecureRandom. It constructs a Default constructor for SecureRandom. It constructs a
new SecureRandom by instantating the first SecureRandom new SecureRandom by instantating the first SecureRandom
...@@ -69,7 +82,7 @@ public class SecureRandom extends Random ...@@ -69,7 +82,7 @@ public class SecureRandom extends Random
on the first call to getnextBytes it will force a seed. on the first call to getnextBytes it will force a seed.
It is maintained for backwards compatibility and programs It is maintained for backwards compatibility and programs
should use getInstance. should use {@link #getInstance(java.lang.String)}.
*/ */
public SecureRandom() public SecureRandom()
{ {
...@@ -141,15 +154,17 @@ public class SecureRandom extends Random ...@@ -141,15 +154,17 @@ public class SecureRandom extends Random
this.provider = provider; this.provider = provider;
} }
/** // Class methods.
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
@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 public static SecureRandom getInstance(String algorithm) throws
NoSuchAlgorithmException NoSuchAlgorithmException
...@@ -161,7 +176,9 @@ public class SecureRandom extends Random ...@@ -161,7 +176,9 @@ public class SecureRandom extends Random
{ {
return getInstance(algorithm, p[i]); return getInstance(algorithm, p[i]);
} }
catch (NoSuchAlgorithmException ignored) { } catch (NoSuchAlgorithmException ignored)
{
}
} }
// None found. // None found.
...@@ -169,21 +186,26 @@ public class SecureRandom extends Random ...@@ -169,21 +186,26 @@ public class SecureRandom extends Random
} }
/** /**
Returns an instance of a SecureRandom. It creates the class * Returns an instance of a SecureRandom. It creates the class
for the specified algorithm from the specified provider. * for the specified algorithm from the named provider.
*
@param algorithm A SecureRandom algorithm to use * @param algorithm The algorithm name.
@param provider A security provider to use * @param provider The provider name.
* @return A new SecureRandom implmenting the chosen algorithm.
@return Returns a new SecureRandom implmenting the chosen algorithm * @throws NoSuchAlgorithmException If the named provider does not implement
* the algorithm, or if the implementation cannot be
@throws NoSuchAlgorithmException if the algorithm cannot be found * instantiated.
@throws NoSuchProviderException if the provider cannot be found * @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, public static SecureRandom getInstance(String algorithm, String provider)
String provider) throws throws NoSuchAlgorithmException, NoSuchProviderException
NoSuchAlgorithmException, NoSuchProviderException
{ {
if (provider == null || provider.length() == 0)
throw new IllegalArgumentException("Illegal provider");
Provider p = Security.getProvider(provider); Provider p = Security.getProvider(provider);
if (p == null) if (p == null)
throw new NoSuchProviderException(); throw new NoSuchProviderException();
...@@ -192,87 +214,34 @@ public class SecureRandom extends Random ...@@ -192,87 +214,34 @@ public class SecureRandom extends Random
} }
/** /**
Returns an instance of a SecureRandom. It creates the class for * Returns an instance of a SecureRandom. It creates the class for
the specified algorithm from the given provider. * the specified algorithm from the given provider.
*
@param algorithm The SecureRandom algorithm to create. * @param algorithm The SecureRandom algorithm to create.
@param provider The provider to get the instance from. * @param provider The provider to get the instance from.
* @throws NoSuchAlgorithmException If the algorithm cannot be found, or
@throws NoSuchAlgorithmException If the algorithm cannot be found, or * if the class cannot be instantiated.
if the class cannot be instantiated. * @throws IllegalArgumentException If <code>provider</code> is null.
*/ */
public static SecureRandom getInstance(String algorithm, public static SecureRandom getInstance(String algorithm, Provider provider)
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 throws NoSuchAlgorithmException
{ {
String msg = algorithm; if (provider == null)
for (Enumeration e = provider.propertyNames(); e.hasMoreElements(); ) throw new IllegalArgumentException("Illegal provider");
{
// 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 try
{ {
Class c = Class.forName(provider.getProperty(key)); return new SecureRandom((SecureRandomSpi)
return new SecureRandom((SecureRandomSpi) c.newInstance(), Engine.getInstance(SECURE_RANDOM, algorithm, provider),
provider); provider);
} }
catch (Throwable ignored) { } catch (ClassCastException cce)
}
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();
}
}
}
}
}
throw new NoSuchAlgorithmException(algorithm); throw new NoSuchAlgorithmException(algorithm);
} }
}
// Instance methods.
// ------------------------------------------------------------------------
/** /**
Returns the provider being used by the current SecureRandom class. Returns the provider being used by the current SecureRandom class.
......
/* Security.java --- Java base security class implmentation /* 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. This file is part of GNU Classpath.
...@@ -36,28 +36,35 @@ obligated to do so. If you do not wish to do so, delete this ...@@ -36,28 +36,35 @@ obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */ exception statement from your version. */
package java.security; package java.security;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream; import java.io.InputStream;
import java.io.IOException; import java.io.IOException;
import java.io.FileNotFoundException;
import java.net.URL; import java.net.URL;
import java.security.Provider; import java.security.Provider;
import java.util.Vector; import java.util.Collections;
import java.util.Enumeration; 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.Properties;
import java.util.Set;
import java.util.Vector;
/** /**
Security class that loads the Providers and provides an * This class centralizes all security properties and common security methods.
interface to security properties. * One of its primary uses is to manage providers.
*
@author Mark Benvenuto <ivymccough@worldnet.att.net> * @author Mark Benvenuto <ivymccough@worldnet.att.net>
*/ */
public final class Security extends Object public final class Security extends Object
{ {
private static final String ALG_ALIAS = "Alg.Alias.";
private static Vector providers = new Vector(); private static Vector providers = new Vector();
private static Properties secprops; private static Properties secprops;
static static
{ {
String base = System.getProperty("gnu.classpath.home.url"); String base = System.getProperty("gnu.classpath.home.url");
...@@ -76,7 +83,6 @@ public final class Security extends Object ...@@ -76,7 +83,6 @@ public final class Security extends Object
return; return;
String secfilestr = baseUrl + "/security/" + vendor + ".security"; String secfilestr = baseUrl + "/security/" + vendor + ".security";
try try
{ {
InputStream fin = new URL(secfilestr).openStream(); InputStream fin = new URL(secfilestr).openStream();
...@@ -85,12 +91,9 @@ public final class Security extends Object ...@@ -85,12 +91,9 @@ public final class Security extends Object
int i = 1; int i = 1;
String name; String name;
while ((name = secprops.getProperty("security.provider." + i)) != null)
while ((name = secprops.getProperty("security.provider." + i)) !=
null)
{ {
Exception exception = null; Exception exception = null;
try try
{ {
providers.addElement(Class.forName(name).newInstance()); providers.addElement(Class.forName(name).newInstance());
...@@ -107,15 +110,16 @@ public final class Security extends Object ...@@ -107,15 +110,16 @@ public final class Security extends Object
{ {
exception = x; exception = x;
} }
if (exception != null) if (exception != null)
System.err.println ("Error loading security provider " + name System.err.println (
+ ": " + exception); "Error loading security provider " + name + ": " + exception);
i++; i++;
} }
} }
catch (FileNotFoundException ignored) 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. // properties file is actually installed somewhere.
} }
catch (IOException ignored) catch (IOException ignored)
...@@ -124,57 +128,78 @@ public final class Security extends Object ...@@ -124,57 +128,78 @@ public final class Security extends Object
} }
/** /**
Gets a specific property for an algorithm. This is used to produce * Gets a specified property for an algorithm. The algorithm name should be a
specialized algorithm parsers. * standard name. See Appendix A in the Java Cryptography Architecture API
* Specification &amp; Reference for information about standard algorithm
@deprecated it used to a return the value of a propietary property * names. One possible use is by specialized algorithm parsers, which may map
for the "SUN" Cryptographic Service Provider to obtain * classes to algorithms which they understand (much like {@link Key} parsers
algorithm-specific parameters. Used AlogorithmParameters and * do).
KeyFactory instead. *
* @param algName the algorithm name.
@param algName name of algorithm to get property of * @param propName the name of the property to get.
@param propName name of property to check * @return the value of the specified property.
* @deprecated This method used to return the value of a proprietary property
@return a string containing the value of the 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 {@link AlgorithmParameters} and
* {@link KeyFactory} engine classes (introduced in the Java 2 platform)
* instead.
*/ */
public static String getAlgorithmProperty(String algName, String propName) 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; return null;
} }
/** /**
Adds a new provider, at a specified position. The position is the * <p>Adds a new provider, at a specified position. The position is the
preference order in which providers are searched for requested algorithms. * preference order in which providers are searched for requested algorithms.
Note that it is not guaranteed that this preference will be respected. The * 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 * position is 1-based, that is, <code>1</code> is most preferred, followed by
on. * <code>2</code>, and so on.</p>
<p> *
If the given provider is installed at the requested position, the * <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 * provider that used to be at that position, and all providers with a
position greater than position, are shifted up one position (towards the * position greater than position, are shifted up one position (towards the
end of the list of installed providers). * end of the list of installed providers).</p>
<p> *
A provider cannot be added if it is already installed. * <p>A provider cannot be added if it is already installed.</p>
<p> *
<b>NOT IMPLEMENTED YET:</b>[ * <p>First, if there is a security manager, its <code>checkSecurityAccess()
First, if there is a security manager, its <code>checkSecurityAccess</code> * </code> method is called with the string <code>"insertProvider."+provider.
method is called with the string * getName()</code> to see if it's ok to add a new provider. If the default
<code>"insertProvider."+provider.getName()</code> * implementation of <code>checkSecurityAccess()</code> is used (i.e., that
to see if it's ok to add a new provider. If the default implementation of * method is not overriden), then this will result in a call to the security
<code>checkSecurityAccess</code> is used (i.e., that method is not * manager's <code>checkPermission()</code> method with a
overriden), then this will result in a call to the security manager's * <code>SecurityPermission("insertProvider."+provider.getName())</code>
<code>checkPermission</code> method with a <code>SecurityPermission( * permission.</p>
"insertProvider."+provider.getName())</code> permission.] *
* @param provider the provider to be added.
@param provider the provider to be added. * @param position the preference position that the caller would like for
@param position the preference position that the caller would like for * this provider.
this provider. * @return the actual preference position in which the provider was added, or
@return the actual preference position (1-based) in which the provider was * <code>-1</code> if the provider was not added because it is already
added, or -1 if the provider was not added because it is already installed. * installed.
@throws SecurityException if a security manager exists and its <code> * @throws SecurityException if a security manager exists and its
SecurityManager.checkSecurityAccess(java.lang.String)</code> method denies * {@link SecurityManager#checkSecurityAccess(String)} method denies access
access to add a new provider. * to add a new provider.
* @see #getProvider(String)
* @see #removeProvider(String)
* @see SecurityPermission
*/ */
public static int insertProviderAt(Provider provider, int position) public static int insertProviderAt(Provider provider, int position)
{ {
...@@ -186,8 +211,7 @@ public final class Security extends Object ...@@ -186,8 +211,7 @@ public final class Security extends Object
int max = providers.size (); int max = providers.size ();
for (int i = 0; i < max; i++) for (int i = 0; i < max; i++)
{ {
if (((Provider) providers.elementAt(i)).getName() == if (((Provider) providers.elementAt(i)).getName() == provider.getName())
provider.getName())
return -1; return -1;
} }
...@@ -201,26 +225,28 @@ public final class Security extends Object ...@@ -201,26 +225,28 @@ public final class Security extends Object
return position + 1; return position + 1;
} }
/** /**
Adds a provider to the next position available. * <p>Adds a provider to the next position available.</p>
<p> *
<b>NOT IMPLEMENTED YET:</b> [ * <p>First, if there is a security manager, its <code>checkSecurityAccess()
First, if there is a security manager, its <code>checkSecurityAccess</code> * </code> method is called with the string <code>"insertProvider."+provider.
method is called with the string * getName()</code> to see if it's ok to add a new provider. If the default
<code>"insertProvider."+provider.getName()</code> * implementation of <code>checkSecurityAccess()</code> is used (i.e., that
to see if it's ok to add a new provider. If the default implementation of * method is not overriden), then this will result in a call to the security
<code>checkSecurityAccess</code> is used (i.e., that method is not * manager's <code>checkPermission()</code> method with a
overriden), then this will result in a call to the security manager's * <code>SecurityPermission("insertProvider."+provider.getName())</code>
<code>checkPermission</code> method with a <code>SecurityPermission( * permission.</p>
"insertProvider."+provider.getName())</code> permission.] *
* @param provider the provider to be added.
@param provider the provider to be added. * @return the preference position in which the provider was added, or
@return the preference position in which the provider was added, or <code> * <code>-1</code> if the provider was not added because it is already
-1</code> if the provider was not added because it is already installed. * installed.
@throws SecurityException if a security manager exists and its <code> * @throws SecurityException if a security manager exists and its
SecurityManager.checkSecurityAccess(java.lang.String)</code> method denies * {@link SecurityManager#checkSecurityAccess(String)} method denies access
access to add a new provider. * to add a new provider.
* @see #getProvider(String)
* @see #removeProvider(String)
* @see SecurityPermission
*/ */
public static int addProvider(Provider provider) public static int addProvider(Provider provider)
{ {
...@@ -228,18 +254,28 @@ public final class Security extends Object ...@@ -228,18 +254,28 @@ public final class Security extends Object
} }
/** /**
Removes a provider. This allows dynamic unloading * <p>Removes the provider with the specified name.</p>
of providers. It will automatically shift up providers to a higher *
ranking. If the provider is not installed, it fails silently. * <p>When the specified provider is removed, all providers located at a
* position greater than where the specified provider was are shifted down
This method checks the security manager with the call checkSecurityAccess * one position (towards the head of the list of installed providers).</p>
with "removeProvider."+provider.getName() to see if the user can remove *
this provider. * <p>This method returns silently if the provider is not installed.</p>
*
@param name name of the provider to add * <p>First, if there is a security manager, its <code>checkSecurityAccess()
* </code> method is called with the string <code>"removeProvider."+name</code>
@throws SecurityException - if the security manager denies access to * to see if it's ok to remove the provider. If the default implementation of
remove a new provider * <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
* {@link SecurityManager#checkSecurityAccess(String)} method denies access
* to remove the provider.
* @see #getProvider(String)
* @see #addProvider(Provider)
*/ */
public static void removeProvider(String name) public static void removeProvider(String name)
{ {
...@@ -247,7 +283,6 @@ public final class Security extends Object ...@@ -247,7 +283,6 @@ public final class Security extends Object
if (sm != null) if (sm != null)
sm.checkSecurityAccess("removeProvider." + name); sm.checkSecurityAccess("removeProvider." + name);
Provider p = null;
int max = providers.size (); int max = providers.size ();
for (int i = 0; i < max; i++) for (int i = 0; i < max; i++)
{ {
...@@ -260,10 +295,10 @@ public final class Security extends Object ...@@ -260,10 +295,10 @@ public final class Security extends Object
} }
/** /**
Returns array containing all the providers. It is in the preference order * Returns an array containing all the installed providers. The order of the
of the providers. * providers in the array is their preference order.
*
@return an array of installed providers * @return an array of all the installed providers.
*/ */
public static Provider[] getProviders() public static Provider[] getProviders()
{ {
...@@ -273,12 +308,13 @@ public final class Security extends Object ...@@ -273,12 +308,13 @@ public final class Security extends Object
} }
/** /**
Returns the provider with the specified name. It will return null * Returns the provider installed with the specified name, if any. Returns
if the provider cannot be found. * <code>null</code> if no provider with the specified name is installed.
*
@param name name of the requested provider * @param name the name of the provider to get.
* @return the provider of the specified name.
@return requested provider * @see #removeProvider(String)
* @see #addProvider(Provider)
*/ */
public static Provider getProvider(String name) public static Provider getProvider(String name)
{ {
...@@ -294,17 +330,20 @@ public final class Security extends Object ...@@ -294,17 +330,20 @@ public final class Security extends Object
} }
/** /**
Gets the value of a security property. * <p>Gets a security property value.</p>
*
This method checks the security manager with the call checkSecurityAccess * <p>First, if there is a security manager, its <code>checkPermission()</code>
with "getProperty."+key to see if the user can get this property. * method is called with a <code>SecurityPermission("getProperty."+key)</code>
* permission to see if it's ok to retrieve the specified security property
@param key property to get * value.</p>
*
@return value of the property * @param key the key of the property being retrieved.
* @return the value of the security property corresponding to key.
@throws SecurityException - if the security manager denies access to * @throws SecurityException if a security manager exists and its
getting a property * {@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) public static String getProperty(String key)
{ {
...@@ -315,18 +354,21 @@ public final class Security extends Object ...@@ -315,18 +354,21 @@ public final class Security extends Object
return secprops.getProperty(key); return secprops.getProperty(key);
} }
/** /**
Sets the value of a security property. * <p>Sets a security property value.</p>
*
This method checks the security manager with the call checkSecurityAccess * <p>First, if there is a security manager, its <code>checkPermission()</code>
with "setProperty."+key to see if the user can get this property. * method is called with a <code>SecurityPermission("setProperty."+key)</code>
* permission to see if it's ok to set the specified security property value.
@param key property to set * </p>
@param datnum new value of property *
* @param key the name of the property to be set.
@throws SecurityException - if the security manager denies access to * @param datnum the value of the property to be set.
setting a property * @throws SecurityException if a security manager exists and its
* {@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) public static void setProperty(String key, String datnum)
{ {
...@@ -336,4 +378,327 @@ public final class Security extends Object ...@@ -336,4 +378,327 @@ public final class Security extends Object
secprops.put(key, datnum); 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>&lt;crypto_service>.&lt;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>&lt;crypto_service>.&lt;algorithm_or_type>&nbsp;&lt;attribute_name>:&lt;attribute_value></p>
* <p>The cryptographic service name must not contain any dots. There must
* be one or more space charaters between the the &lt;algorithm_or_type>
* and the &lt;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
* &amp; 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>&lt;crypto_service>.&lt;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>&lt;crypto_service>.&lt;algorithm_or_type> &lt;attribute_name></p>
* <p>The cryptographic service name must not contain any dots. There must
* be one or more space charaters between the &lt;algorithm_or_type> and
* the &lt;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
* &amp; 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;
}
} }
/* Signature.java --- Signature Class /* 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. This file is part of GNU Classpath.
...@@ -36,73 +36,113 @@ obligated to do so. If you do not wish to do so, delete this ...@@ -36,73 +36,113 @@ obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */ exception statement from your version. */
package java.security; package java.security;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.security.spec.AlgorithmParameterSpec; import java.security.spec.AlgorithmParameterSpec;
/** /**
Signature is used to provide an interface to digital signature * <p>This <code>Signature</code> class is used to provide applications the
algorithms. Digital signatures provide authentication and data * functionality of a digital signature algorithm. Digital signatures are used
integrity of digital data. * for authentication and integrity assurance of digital data.</p>
*
The GNU provider provides the NIST standard DSA which uses DSA * <p>The signature algorithm can be, among others, the NIST standard <i>DSS</i>,
and SHA-1. It can be specified by SHA/DSA, SHA-1/DSA or its * using <i>DSA</i> and <i>SHA-1</i>. The <i>DSA</i> algorithm using the
OID. If the RSA signature algorithm is provided then * <i>SHA-1</i> message digest algorithm can be specified as <code>SHA1withDSA
it could be MD2/RSA. MD5/RSA, or SHA-1/RSA. The algorithm must * </code>. In the case of <i>RSA</i>, there are multiple choices for the
be specified because there is no default. * message digest algorithm, so the signing algorithm could be specified as, for
* example, <code>MD2withRSA</code>, <code>MD5withRSA</code>, or
Signature provides implementation-independent algorithms which * <code>SHA1withRSA</code>. The algorithm name must be specified, as there is
are requested by the user through getInstance. It can be * no default.</p>
requested by specifying just the algorithm name or by *
specifying both the algorithm name and provider name. * <p>Like other algorithm-based classes in Java Security, <code>Signature</code>
* provides implementation-independent algorithms, whereby a caller (application
The three phases of using Signature are: * code) requests a particular signature algorithm and is handed back a properly
* initialized <code>Signature</code> object. It is also possible, if desired,
1. Initialing * to request a particular algorithm from a particular provider. See the
* <code>getInstance()</code> methods.</p>
* It must be initialized with a private key for signing. *
* It must be initialized with a public key for verifying. * <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
2. Updating * name and a package provider.</p>
*
Update the bytes for signing or verifying with calls to update. * <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,
3. Signing or Verify the signature on the currently stored * and if there is more than one, if there is a preferred one.</p>
bytes by calling sign or verify. *
* <p>If both an algorithm name and a package provider are specified, the system
@author Mark Benvenuto <ivymccough@worldnet.att.net> * will determine if there is an implementation of the algorithm in the package
@since JDK 1.1 * 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
* {@link #initSign(PrivateKey)} and {@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 {@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@worldnet.att.net>
*/ */
public abstract class Signature extends SignatureSpi 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 * Possible <code>state</code> value, signifying that this signature object
initialized. * 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 * Possible <code>state</code> value, signifying that this signature object
initialized for signing. * has been initialized for signing.
*/ */
protected static final int SIGN = 2; protected static final int SIGN = 2;
/** /**
Possible state variable which signifies if it has been * Possible <code>state</code> value, signifying that this signature object
initialized for verifying. * has been initialized for verification.
*/ */
protected static final int VERIFY = 3; protected static final int VERIFY = 3;
/** /** Current state of this signature object. */
State of this Signature class.
*/
protected int state = UNINITIALIZED; protected int state = UNINITIALIZED;
private String algorithm; private String algorithm;
Provider provider; Provider provider;
/** /**
Creates a new signature for this algorithm. * Creates a <code>Signature</code> object for the specified algorithm.
*
@param algorithm the algorithm to use * @param algorithm the standard string name of the algorithm. See Appendix A
* in the Java Cryptography Architecture API Specification &amp; Reference for
* information about standard algorithm names.
*/ */
protected Signature(String algorithm) protected Signature(String algorithm)
{ {
...@@ -111,21 +151,24 @@ public abstract class Signature extends SignatureSpi ...@@ -111,21 +151,24 @@ public abstract class Signature extends SignatureSpi
} }
/** /**
Gets an instance of the Signature class representing * Generates a <code>Signature</code> object that implements the specified
the specified signature. If the algorithm is not found then, * digest algorithm. If the default provider package provides an
it throws NoSuchAlgorithmException. * implementation of the requested digest algorithm, an instance of
* <code>Signature</code> containing that implementation is returned. If the
@param algorithm the name of signature algorithm to choose * algorithm is not available in the default package, other packages are
@return a Signature repesenting the desired algorithm * searched.
*
@throws NoSuchAlgorithmException if the algorithm is not implemented by * @param algorithm the standard name of the algorithm requested. See Appendix
providers * A in the Java Cryptography Architecture API Specification &amp; 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) public static Signature getInstance(String algorithm)
throws NoSuchAlgorithmException throws NoSuchAlgorithmException
{ {
Provider[] p = Security.getProviders(); Provider[] p = Security.getProviders();
for (int i = 0; i < p.length; i++) for (int i = 0; i < p.length; i++)
{ {
try try
...@@ -139,23 +182,29 @@ public abstract class Signature extends SignatureSpi ...@@ -139,23 +182,29 @@ public abstract class Signature extends SignatureSpi
} }
/** /**
Gets an instance of the Signature class representing * Generates a <code>Signature</code> object implementing the specified
the specified signature from the specified provider. If the * algorithm, as supplied from the specified provider, if such an algorithm
algorithm is not found then, it throws NoSuchAlgorithmException. * is available from the provider.
If the provider is not found, then it throws *
NoSuchProviderException. * @param algorithm the name of the algorithm requested. See Appendix A in
* the Java Cryptography Architecture API Specification &amp; Reference for
@param algorithm the name of signature algorithm to choose * information about standard algorithm names.
@param provider the name of the provider to find the algorithm in * @param provider the name of the provider.
@return a Signature repesenting the desired algorithm * @return the new <code>Signature</code> object.
* @throws NoSuchAlgorithmException if the algorithm is not available in the
@throws NoSuchAlgorithmException if the algorithm is not implemented by * package supplied by the requested provider.
the provider * @throws NoSuchProviderException if the provider is not available in the
@throws NoSuchProviderException if the provider is not found * environment.
* @throws IllegalArgumentException if the provider name is <code>null</code>
* or empty.
* @see Provider
*/ */
public static Signature getInstance(String algorithm, String provider) public static Signature getInstance(String algorithm, String provider)
throws NoSuchAlgorithmException, NoSuchProviderException throws NoSuchAlgorithmException, NoSuchProviderException
{ {
if (provider == null || provider.length() == 0)
throw new IllegalArgumentException("Illegal provider");
Provider p = Security.getProvider(provider); Provider p = Security.getProvider(provider);
if (p == null) if (p == null)
throw new NoSuchProviderException(provider); throw new NoSuchProviderException(provider);
...@@ -163,69 +212,54 @@ public abstract class Signature extends SignatureSpi ...@@ -163,69 +212,54 @@ public abstract class Signature extends SignatureSpi
return getInstance(algorithm, p); 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 &amp; 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 throws NoSuchAlgorithmException
{ {
// try the name as is if (provider == null)
String className = p.getProperty("Signature." + algorithm); throw new IllegalArgumentException("Illegal provider");
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);
}
private static Signature getInstance(String classname, Signature result = null;
String algorithm, Object o = Engine.getInstance(SIGNATURE, algorithm, provider);
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;
}
sig.provider = provider; if (o instanceof SignatureSpi)
return sig;
}
catch (ClassNotFoundException cnfe)
{ {
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. * Returns the provider of this signature object.
*
@return the provider of this Signature * @return the provider of this signature object.
*/ */
public final Provider getProvider() public final Provider getProvider()
{ {
...@@ -233,12 +267,12 @@ public abstract class Signature extends SignatureSpi ...@@ -233,12 +267,12 @@ public abstract class Signature extends SignatureSpi
} }
/** /**
Initializes this class with the public key for * Initializes this object for verification. If this method is called again
verification purposes. * with a different argument, it negates the effect of this call.
*
@param publicKey the public key to verify with * @param publicKey the public key of the identity whose signature is going
* to be verified.
@throws InvalidKeyException invalid key * @throws InvalidKeyException if the key is invalid.
*/ */
public final void initVerify(PublicKey publicKey) throws InvalidKeyException public final void initVerify(PublicKey publicKey) throws InvalidKeyException
{ {
...@@ -247,39 +281,43 @@ public abstract class Signature extends SignatureSpi ...@@ -247,39 +281,43 @@ public abstract class Signature extends SignatureSpi
} }
/** /**
Verify Signature with a certificate. This is a FIPS 140-1 compatible method * <p>Initializes this object for verification, using the public key from the
since it verifies a signature with a certificate. * given certificate.</p>
*
If the certificate is an X.509 certificate, has a KeyUsage parameter and * <p>If the certificate is of type <i>X.509</i> and has a <i>key usage</i>
the parameter indicates this key is not to be used for signing then an * extension field marked as <i>critical</i>, and the value of the <i>key
error is returned. * 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
@param certificate a certificate containing a public key to verify with * signatures, an {@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 throws InvalidKeyException
{ {
state = VERIFY; state = VERIFY;
if (certificate.getType().equals("X509")) if (certificate.getType().equals("X509"))
{ {
java.security.cert.X509Certificate cert = X509Certificate cert = (X509Certificate) certificate;
(java.security.cert.X509Certificate) certificate;
boolean[]array = cert.getKeyUsage(); boolean[]array = cert.getKeyUsage();
if (array != null && array[0] == false) if (array != null && array[0] == false)
throw new InvalidKeyException throw new InvalidKeyException(
("KeyUsage of this Certificate indicates it cannot be used for digital signing"); "KeyUsage of this Certificate indicates it cannot be used for digital signing");
} }
this.initVerify(certificate.getPublicKey()); this.initVerify(certificate.getPublicKey());
} }
/** /**
Initializes this class with the private key for * Initialize this object for signing. If this method is called again with a
signing purposes. * different argument, it negates the effect of this call.
*
@param privateKey the private key to sign with * @param privateKey the private key of the identity whose signature is going
* to be generated.
@throws InvalidKeyException invalid key * @throws InvalidKeyException if the key is invalid.
*/ */
public final void initSign(PrivateKey privateKey) throws InvalidKeyException public final void initSign(PrivateKey privateKey) throws InvalidKeyException
{ {
...@@ -288,15 +326,13 @@ public abstract class Signature extends SignatureSpi ...@@ -288,15 +326,13 @@ public abstract class Signature extends SignatureSpi
} }
/** /**
Initializes this class with the private key and source * Initialize this object for signing. If this method is called again with a
of randomness for signing purposes. * different argument, it negates the effect of this call.
*
@param privateKey the private key to sign with * @param privateKey the private key of the identity whose signature is going
@param random Source of randomness * to be generated.
* @param random the source of randomness for this signature.
@throws InvalidKeyException invalid key * @throws InvalidKeyException if the key is invalid.
@since JDK 1.2
*/ */
public final void initSign(PrivateKey privateKey, SecureRandom random) public final void initSign(PrivateKey privateKey, SecureRandom random)
throws InvalidKeyException throws InvalidKeyException
...@@ -305,15 +341,19 @@ public abstract class Signature extends SignatureSpi ...@@ -305,15 +341,19 @@ public abstract class Signature extends SignatureSpi
engineInitSign(privateKey, random); engineInitSign(privateKey, random);
} }
/** /**
Returns the signature bytes of all the data fed to this class. * <p>Returns the signature bytes of all the data updated. The format of the
The format of the output depends on the underlying signature * signature depends on the underlying signature scheme.</p>
algorithm. *
* <p>A call to this method resets this signature object to the state it was
@return the signature * in when previously initialized for signing via a call to
* <code>initSign(PrivateKey)</code>. That is, the object is reset and
@throws SignatureException engine not properly initialized * 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 public final byte[] sign() throws SignatureException
{ {
...@@ -327,28 +367,22 @@ public abstract class Signature extends SignatureSpi ...@@ -327,28 +367,22 @@ public abstract class Signature extends SignatureSpi
} }
/** /**
Generates signature bytes of all the data fed to this class * <p>Finishes the signature operation and stores the resulting signature
and outputs it to the passed array. The format of the * bytes in the provided buffer <code>outbuf</code>, starting at <code>offset
output depends on the underlying signature algorithm. * </code>. The format of the signature depends on the underlying signature
* scheme.</p>
After calling this method, the signature is reset to its *
initial state and can be used to generate additional * <p>This signature object is reset to its initial state (the state it was
signatures. * 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 array of bytes *
@param offset the offset to start at in the array * @param outbuf buffer for the signature result.
@param len the length of the bytes to put into the array. * @param offset offset into outbuf where the signature is stored.
Neither this method or the GNU provider will * @param len number of bytes within outbuf allotted for the signature.
return partial digests. If len is less than the * @return the number of bytes placed into outbuf.
signature length, this method will throw * @throws SignatureException if an error occurs or len is less than the
SignatureException. If it is greater than or equal * actual signature length.
then it is ignored. * @since 1.2
@return number of bytes in outbuf
@throws SignatureException engine not properly initialized
@since JDK 1.2
*/ */
public final int sign(byte[] outbuf, int offset, int len) public final int sign(byte[] outbuf, int offset, int len)
throws SignatureException throws SignatureException
...@@ -363,14 +397,20 @@ public abstract class Signature extends SignatureSpi ...@@ -363,14 +397,20 @@ public abstract class Signature extends SignatureSpi
} }
/** /**
Verifies the passed signature. * <p>Verifies the passed-in signature.</p>
*
@param signature the signature bytes to verify * <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
@return true if verified, false otherwise * <code>initVerify(PublicKey)</code>. That is, the object is reset and
* available to verify another signature from the identity whose public key
@throws SignatureException engine not properly initialized * was specified in the call to <code>initVerify()</code>.</p>
or wrong signature *
* @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 public final boolean verify(byte[]signature) throws SignatureException
{ {
...@@ -384,12 +424,54 @@ public abstract class Signature extends SignatureSpi ...@@ -384,12 +424,54 @@ public abstract class Signature extends SignatureSpi
} }
/** /**
Updates the data to be signed or verified with the specified * <p>Verifies the passed-in <code>signature</code> in the specified array of
byte. * 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");
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");
@param b byte to update with state = UNINITIALIZED;
return engineVerify(signature, offset, length);
}
@throws SignatureException Engine not properly initialized /**
* 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 public final void update(byte b) throws SignatureException
{ {
...@@ -400,12 +482,12 @@ public abstract class Signature extends SignatureSpi ...@@ -400,12 +482,12 @@ public abstract class Signature extends SignatureSpi
} }
/** /**
Updates the data to be signed or verified with the specified * Updates the data to be signed or verified, using the specified array of
bytes. * bytes.
*
@param data array of bytes * @param data the byte array to use for the update.
* @throws SignatureException if this signature object is not initialized
@throws SignatureException engine not properly initialized * properly.
*/ */
public final void update(byte[]data) throws SignatureException public final void update(byte[]data) throws SignatureException
{ {
...@@ -416,14 +498,14 @@ public abstract class Signature extends SignatureSpi ...@@ -416,14 +498,14 @@ public abstract class Signature extends SignatureSpi
} }
/** /**
Updates the data to be signed or verified with the specified * Updates the data to be signed or verified, using the specified array of
bytes. * bytes, starting at the specified offset.
*
@param data array of bytes * @param data the array of bytes.
@param off the offset to start at in the array * @param off the offset to start from in the array of bytes.
@param len the length of the bytes to use in the array * @param len the number of bytes to use, starting at offset.
* @throws SignatureException if this signature object is not initialized
@throws SignatureException engine not properly initialized * properly.
*/ */
public final void update(byte[]data, int off, int len) public final void update(byte[]data, int off, int len)
throws SignatureException throws SignatureException
...@@ -435,10 +517,9 @@ public abstract class Signature extends SignatureSpi ...@@ -435,10 +517,9 @@ public abstract class Signature extends SignatureSpi
} }
/** /**
Gets the name of the algorithm currently used. * Returns the name of the algorithm for this signature object.
The names of algorithms are usually SHA/DSA or SHA/RSA. *
* @return the name of the algorithm for this signature object.
@return name of algorithm.
*/ */
public final String getAlgorithm() public final String getAlgorithm()
{ {
...@@ -446,9 +527,11 @@ public abstract class Signature extends SignatureSpi ...@@ -446,9 +527,11 @@ public abstract class Signature extends SignatureSpi
} }
/** /**
Returns a representation of the Signature as a String * Returns a string representation of this signature object, providing
* information that includes the state of the object and the name of the
@return a string representing the signature * algorithm used.
*
* @return a string representation of this signature object.
*/ */
public String toString() public String toString()
{ {
...@@ -456,16 +539,22 @@ public abstract class Signature extends SignatureSpi ...@@ -456,16 +539,22 @@ public abstract class Signature extends SignatureSpi
} }
/** /**
Sets the specified algorithm parameter to the specified value. * Sets the specified algorithm parameter to the specified value. This method
* supplies a general-purpose mechanism through which it is possible to set
@param param parameter name * the various parameters of this object. A parameter may be any settable
@param value parameter value * parameter for the algorithm, such as a parameter size, or a source of
* random bits for signature generation (if appropriate), or an indication of
@throws InvalidParameterException invalid parameter, parameter * whether or not to perform a specific but optional computation. A uniform
already set and cannot set again, a security exception, * algorithm-specific naming scheme for each parameter is desirable but left
etc. * unspecified at this time.
*
@deprecated use the other setParameter * @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) public final void setParameter(String param, Object value)
throws InvalidParameterException throws InvalidParameterException
...@@ -474,17 +563,12 @@ public abstract class Signature extends SignatureSpi ...@@ -474,17 +563,12 @@ public abstract class Signature extends SignatureSpi
} }
/** /**
Sets the signature engine with the specified * Initializes this signature engine with the specified parameter set.
AlgorithmParameterSpec; *
* @param params the parameters.
By default this always throws UnsupportedOperationException * @throws InvalidAlgorithmParameterException if the given parameters are
if not overridden; * inappropriate for this signature engine.
* @see #getParameters()
@param params the parameters
@throws InvalidParameterException invalid parameter, parameter
already set and cannot set again, a security exception,
etc.
*/ */
public final void setParameter(AlgorithmParameterSpec params) public final void setParameter(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException throws InvalidAlgorithmParameterException
...@@ -493,15 +577,40 @@ public abstract class Signature extends SignatureSpi ...@@ -493,15 +577,40 @@ public abstract class Signature extends SignatureSpi
} }
/** /**
Gets the value for the specified algorithm parameter. * <p>Returns the parameters used with this signature object.</p>
*
@param param parameter name * <p>The returned parameters may be the same that were used to initialize
* this signature, or may contain a combination of default and randomly
@return parameter value * generated parameter values used by the underlying signature implementation
* if this signature requires algorithm parameters but was not initialized
@throws InvalidParameterException invalid parameter * 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) public final Object getParameter(String param)
throws InvalidParameterException throws InvalidParameterException
...@@ -510,12 +619,11 @@ public abstract class Signature extends SignatureSpi ...@@ -510,12 +619,11 @@ public abstract class Signature extends SignatureSpi
} }
/** /**
Returns a clone if cloneable. * Returns a clone if the implementation is cloneable.
*
@return a clone if cloneable. * @return a clone if the implementation is cloneable.
* @throws CloneNotSupportedException if this is called on an implementation
@throws CloneNotSupportedException if the implementation does * that does not support {@link Cloneable}.
not support cloning
*/ */
public Object clone() throws CloneNotSupportedException public Object clone() throws CloneNotSupportedException
{ {
......
/* SignatureSpi.java --- Signature Service Provider Interface /* 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. This file is part of GNU Classpath.
...@@ -36,67 +36,70 @@ obligated to do so. If you do not wish to do so, delete this ...@@ -36,67 +36,70 @@ obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */ exception statement from your version. */
package java.security; package java.security;
import java.security.spec.AlgorithmParameterSpec; import java.security.spec.AlgorithmParameterSpec;
/** /**
SignatureSpi defines the Service Provider Interface (SPI) * <p>This class defines the <i>Service Provider Interface (SPI)</i> for the
for the Signature class. The signature class provides an * {@link Signature} class, which is used to provide the functionality of a
interface to a digital signature algorithm. Digital signatures * digital signature algorithm. Digital signatures are used for authentication
are used for authentication and integrity of data. * and integrity assurance of digital data.</p>
*
@author Mark Benvenuto <ivymccough@worldnet.att.net> * <p>All the abstract methods in this class must be implemented by each
* cryptographic service provider who wishes to supply the implementation of a
@since JDK 1.2 * particular signature algorithm.
*
* @author Mark Benvenuto <ivymccough@worldnet.att.net>
* @since 1.2
* @see Signature
*/ */
public abstract class SignatureSpi public abstract class SignatureSpi
{ {
/** /** Application-specified source of randomness. */
Source of randomness
*/
protected SecureRandom appRandom; protected SecureRandom appRandom;
/**
Creates a new instance of SignatureSpi.
*/
public SignatureSpi() public SignatureSpi()
{ {
appRandom = null; appRandom = null;
} }
/** /**
Initializes this class with the public key for * Initializes this signature object with the specified public key for
verification purposes. * verification operations.
*
@param publicKey the public key to verify with * @param publicKey the public key of the identity whose signature is going
* to be verified.
@throws InvalidKeyException invalid key * @throws InvalidKeyException if the key is improperly encoded, parameters
* are missing, and so on.
*/ */
protected abstract void engineInitVerify(PublicKey publicKey) protected abstract void engineInitVerify(PublicKey publicKey)
throws InvalidKeyException; throws InvalidKeyException;
/** /**
Initializes this class with the private key for * Initializes this signature object with the specified private key for
signing purposes. * signing operations.
*
@param privateKey the private key to sign with * @param privateKey the private key of the identity whose signature will be
* generated.
@throws InvalidKeyException invalid key * @throws InvalidKeyException if the key is improperly encoded, parameters
* are missing, and so on.
*/ */
protected abstract void engineInitSign(PrivateKey privateKey) protected abstract void engineInitSign(PrivateKey privateKey)
throws InvalidKeyException; throws InvalidKeyException;
/** /**
Initializes this class with the private key and source * <p>Initializes this signature object with the specified private key and
of randomness for signing purposes. * source of randomness for signing operations.</p>
*
This cannot be abstract backward compatibility reasons * <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 to sign with *
@param random Source of randomness * @param privateKey the private key of the identity whose signature will be
* generated.
@throws InvalidKeyException invalid key * @param random the source of randomness.
* @throws InvalidKeyException if the key is improperly encoded, parameters
@since JDK 1.2 * are missing, and so on.
* @since 1.2
*/ */
protected void engineInitSign(PrivateKey privateKey, SecureRandom random) protected void engineInitSign(PrivateKey privateKey, SecureRandom random)
throws InvalidKeyException throws InvalidKeyException
...@@ -106,118 +109,135 @@ public abstract class SignatureSpi ...@@ -106,118 +109,135 @@ public abstract class SignatureSpi
} }
/** /**
Updates the data to be signed or verified with the specified * Updates the data to be signed or verified using the specified byte.
byte. *
* @param b the byte to use for the update.
@param b byte to update with * @throws SignatureException if the engine is not initialized properly.
@throws SignatureException Engine not properly initialized
*/ */
protected abstract void engineUpdate(byte b) throws SignatureException; protected abstract void engineUpdate(byte b) throws SignatureException;
/** /**
Updates the data to be signed or verified with the specified * Updates the data to be signed or verified, using the specified array of
bytes. * bytes, starting at the specified offset.
*
@param b array of bytes * @param b the array of bytes.
@param off the offset to start at in the array * @param off the offset to start from in the array of bytes.
@param len the length of the bytes to use in the array * @param len the number of bytes to use, starting at offset.
* @throws SignatureException if the engine is not initialized properly.
@throws SignatureException engine not properly initialized
*/ */
protected abstract void engineUpdate(byte[] b, int off, int len) protected abstract void engineUpdate(byte[] b, int off, int len)
throws SignatureException; throws SignatureException;
/** /**
Returns the signature bytes of all the data fed to this class. * Returns the signature bytes of all the data updated so far. The format of
The format of the output depends on the underlying signature * the signature depends on the underlying signature scheme.
algorithm. *
* @return the signature bytes of the signing operation's result.
@return the signature * @throws SignatureException if the engine is not initialized properly.
@throws SignatureException engine not properly initialized
*/ */
protected abstract byte[] engineSign() throws SignatureException; protected abstract byte[] engineSign() throws SignatureException;
/** /**
Generates signature bytes of all the data fed to this class * <p>Finishes this signature operation and stores the resulting signature
and outputs it to the passed array. The format of the * bytes in the provided buffer <code>outbuf</code>, starting at <code>offset
output depends on the underlying signature algorithm. * </code>. The format of the signature depends on the underlying signature
* scheme.</p>
This cannot be abstract backward compatibility reasons. *
After calling this method, the signature is reset to its * <p>The signature implementation is reset to its initial state (the state it
initial state and can be used to generate additional * was in after a call to one of the <code>engineInitSign()</code> methods)
signatures. * 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
@param outbuff array of bytes * compatibility. Knowledgeable providers should override this method.</p>
@param offset the offset to start at in the array *
@param len the length of the bytes to put into the array. * @param outbuf buffer for the signature result.
Neither this method or the GNU provider will * @param offset offset into outbuf where the signature is stored.
return partial digests. If len is less than the * @param len number of bytes within outbuf allotted for the signature. Both
signature length, this method will throw * this default implementation and the <b>GNU</b> provider do not return
SignatureException. If it is greater than or equal * partial digests. If the value of this parameter is less than the actual
then it is ignored. * signature length, this method will throw a {@link SignatureException}. This
* parameter is ignored if its value is greater than or equal to the actual
@return number of bytes in outbuf * signature length.
* @return the number of bytes placed into <code>outbuf</code>.
@throws SignatureException engine not properly initialized * @throws SignatureException if an error occurs or len is less than the
* actual signature length.
@since JDK 1.2 * @since 1.2
*/ */
protected int engineSign(byte[] outbuf, int offset, int len) protected int engineSign(byte[] outbuf, int offset, int len)
throws SignatureException throws SignatureException
{ {
byte tmp[] = engineSign(); byte tmp[] = engineSign();
if (tmp.length > len) if (tmp.length > len)
throw new SignatureException("Invalid Length"); throw new SignatureException("Invalid Length");
System.arraycopy(outbuf, offset, tmp, 0, tmp.length); System.arraycopy(outbuf, offset, tmp, 0, tmp.length);
return tmp.length; return tmp.length;
} }
/** /**
Verifies the passed signature. * Verifies the passed-in signature.
*
@param sigBytes the signature bytes to verify * @param sigBytes the signature bytes to be verified.
* @return <code>true</code> if the signature was verified, <code>false</code>
@return true if verified, false otherwise * if not.
* @throws SignatureException if the engine is not initialized properly, or
@throws SignatureException engine not properly initialized * the passed-in signature is improperly encoded or of the wrong type, etc.
or wrong signature
*/ */
protected abstract boolean engineVerify(byte[] sigBytes) protected abstract boolean engineVerify(byte[] sigBytes)
throws SignatureException; throws SignatureException;
/** /**
Sets the specified algorithm parameter to the specified value. * <p>Verifies the passed-in <code>signature</code> in the specified array of
* bytes, starting at the specified <code>offset</code>.</p>
@param param parameter name *
@param value parameter value * <p>Note: Subclasses should overwrite the default implementation.</p>
*
@throws InvalidParameterException invalid parameter, parameter * @param sigBytes the signature bytes to be verified.
already set and cannot set again, a security exception, * @param offset the offset to start from in the array of bytes.
etc. * @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) protected abstract void engineSetParameter(String param, Object value)
throws InvalidParameterException; throws InvalidParameterException;
/** /**
Sets the signature engine with the specified * This method is overridden by providers to initialize this signature engine
AlgorithmParameterSpec; * with the specified parameter set.
*
This cannot be abstract backward compatibility reasons * @param params the parameters.
By default this always throws UnsupportedOperationException * @throws UnsupportedOperationException if this method is not overridden by
if not overridden; * a provider.
* @throws InvalidAlgorithmParameterException if this method is overridden by
@param params the parameters * a provider and the the given parameters are inappropriate for this
* signature engine.
@throws InvalidParameterException invalid parameter, parameter
already set and cannot set again, a security exception,
etc.
*/ */
protected void engineSetParameter(AlgorithmParameterSpec params) protected void engineSetParameter(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException throws InvalidAlgorithmParameterException
...@@ -226,26 +246,54 @@ public abstract class SignatureSpi ...@@ -226,26 +246,54 @@ public abstract class SignatureSpi
} }
/** /**
Gets the value for the specified algorithm 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
@param param parameter name * does not use any parameters.</p>
*
@return parameter value * <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
@throws InvalidParameterException invalid parameter * 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) protected abstract Object engineGetParameter(String param)
throws InvalidParameterException; throws InvalidParameterException;
/** /**
Returns a clone if cloneable. * Returns a clone if the implementation is cloneable.
*
@return a clone if cloneable. * @return a clone if the implementation is cloneable.
* @throws CloneNotSupportedException if this is called on an implementation
@throws CloneNotSupportedException if the implementation does * that does not support {@link Cloneable}.
not support cloning * @see Cloneable
*/ */
public Object clone() throws CloneNotSupportedException public Object clone() throws CloneNotSupportedException
{ {
......
/* SignedObject.java --- Signed Object Class /* 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. This file is part of GNU Classpath.
...@@ -36,70 +36,123 @@ obligated to do so. If you do not wish to do so, delete this ...@@ -36,70 +36,123 @@ obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */ exception statement from your version. */
package java.security; package java.security;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.io.Serializable; import java.io.Serializable;
/** /**
SignedObject is used for storing rutime objects whose integrity * <p><code>SignedObject</code> is a class for the purpose of creating authentic
cannot be compromised without being detected. * runtime objects whose integrity cannot be compromised without being detected.
* </p>
SignedObject contains a Serializable object which is yet to be *
signed and its signature. * <p>More specifically, a <code>SignedObject</code> contains another
* {@link Serializable} object, the (to-be-)signed object and its signature.</p>
The signed copy is a "deep copy" (in serialized form) of the *
original object. Any changes to the original will not affect * <p>The signed object is a <i>"deep copy"</i> (in serialized form) of an
the original. * original object. Once the copy is made, further manipulation of the original
* object has no side effect on the copy.</p>
Several things to note are that, first there is no need to *
initialize the signature engine as this class will handle that * <p>The underlying signing algorithm is designated by the {@link Signature}
automatically. Second, verification will only succeed if the * object passed to the constructor and the <code>verify()</code> method. A
public key corresponds to the private key used to generate * typical usage for signing is the following:</p>
the SignedObject. *
* <pre>
For fexibility, the signature engine can be specified in the * Signature signingEngine = Signature.getInstance(algorithm, provider);
constructor or the verify method. The programmer who writes * SignedObject so = new SignedObject(myobject, signingKey, signingEngine);
code that verifies the SignedObject has not changed should be * </pre>
aware of the Signature engine they use. A malicious Signature *
may choose to always return true on verification and * <p>A typical usage for verification is the following (having received
bypass the secrity check. * <code>SignedObject</code> so):</p>
*
The GNU provider provides the NIST standard DSA which uses DSA * <pre>
and SHA-1. It can be specified by SHA/DSA, SHA-1/DSA or its * Signature verificationEngine = Signature.getInstance(algorithm, provider);
OID. If the RSA signature algorithm is provided then * if (so.verify(publickey, verificationEngine))
it could be MD2/RSA. MD5/RSA, or SHA-1/RSA. The algorithm must * try
be specified because there is no default. * {
* Object myobj = so.getObject();
@author Mark Benvenuto <ivymccough@worldnet.att.net> * }
* catch (ClassNotFoundException ignored) {};
@since JDK 1.2 * </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 {@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 {@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
* {@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@worldnet.att.net>
* @since 1.2
* @see Signature
*/ */
public final class SignedObject implements Serializable public final class SignedObject implements Serializable
{ {
static final long serialVersionUID = 720502720485447167L; static final long serialVersionUID = 720502720485447167L;
/** @serial */
private byte[] content; private byte[] content;
/** @serial */
private byte[] signature; private byte[] signature;
/** @serial */
private String thealgorithm; private String thealgorithm;
/** /**
Constructs a new SignedObject from a Serializeable object. The * Constructs a <code>SignedObject</code> from any {@link Serializable}
object is signed with private key and signature engine * object. The given object is signed with the given signing key, using the
* designated signature engine.
@param object the object to sign *
@param signingKey the key to sign with * @param object the object to be signed.
@param signingEngine the signature engine to use * @param signingKey the private key for signing.
* @param signingEngine the signature signing engine.
@throws IOException serialization error occurred * @throws IOException if an error occurs during serialization.
@throws InvalidKeyException invalid key * @throws InvalidKeyException if the key is invalid.
@throws SignatureException signing error * @throws SignatureException if signing fails.
*/ */
public SignedObject(Serializable object, PrivateKey signingKey, public SignedObject(Serializable object, PrivateKey signingKey,
Signature signingEngine) throws IOException, Signature signingEngine)
InvalidKeyException, SignatureException throws IOException, InvalidKeyException, SignatureException
{ {
thealgorithm = signingEngine.getAlgorithm(); thealgorithm = signingEngine.getAlgorithm();
...@@ -107,6 +160,7 @@ public final class SignedObject implements Serializable ...@@ -107,6 +160,7 @@ public final class SignedObject implements Serializable
ObjectOutputStream p = new ObjectOutputStream(ostream); ObjectOutputStream p = new ObjectOutputStream(ostream);
p.writeObject(object); p.writeObject(object);
p.flush(); p.flush();
p.close();
content = ostream.toByteArray(); content = ostream.toByteArray();
...@@ -116,35 +170,39 @@ public final class SignedObject implements Serializable ...@@ -116,35 +170,39 @@ public final class SignedObject implements Serializable
} }
/** /**
Returns the encapsulated object. The object is * Retrieves the encapsulated object. The encapsulated object is de-serialized
de-serialized before being returned. * before it is returned.
*
@return the encapsulated object * @return the encapsulated object.
* @throws IOException if an error occurs during de-serialization.
@throws IOException de-serialization error occurred * @throws ClassNotFoundException if an error occurs during de-serialization.
@throws ClassNotFoundException de-serialization error occurred
*/ */
public Object getObject() throws IOException, ClassNotFoundException 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. * Retrieves the signature on the signed object, in the form of a byte array.
*
@return a byte array containing the signature * @return a copy of the signature.
*/ */
public byte[] getSignature() public byte[] getSignature()
{ {
return signature; return (byte[]) signature.clone();
} }
/** /**
Returns the name of the signature algorithm. * Retrieves the name of the signature algorithm.
*
@return the name of the signature algorithm. * @return the signature algorithm name.
*/ */
public String getAlgorithm() public String getAlgorithm()
{ {
...@@ -152,28 +210,31 @@ public final class SignedObject implements Serializable ...@@ -152,28 +210,31 @@ public final class SignedObject implements Serializable
} }
/** /**
Verifies the SignedObject by checking that the signature that * Verifies that the signature in this <code>SignedObject</code> is the valid
this class contains for the encapsulated object. * signature for the object stored inside, with the given verification key,
* using the designated verification engine.
@param verificationKey the public key to use *
@param verificationEngine the signature engine to use * @param verificationKey the public key for verification.
* @param verificationEngine the signature verification engine.
@return true if signature is correct, false otherwise * @return <code>true</code> if the signature is valid, <code>false</code>
* otherwise.
@throws InvalidKeyException invalid key * @throws SignatureException if signature verification failed.
@throws SignatureException signature verification failed * @throws InvalidKeyException if the verification key is invalid.
*/ */
public boolean verify(PublicKey verificationKey, public boolean verify(PublicKey verificationKey, Signature verificationEngine)
Signature verificationEngine) throws throws InvalidKeyException, SignatureException
InvalidKeyException, SignatureException
{ {
verificationEngine.initVerify(verificationKey); verificationEngine.initVerify(verificationKey);
verificationEngine.update(content); verificationEngine.update(content);
return verificationEngine.verify(signature); return verificationEngine.verify(signature);
} }
// readObject is called to restore the state of the SignedObject from a /** Called to restore the state of the SignedObject from a stream. */
// stream. private void readObject(ObjectInputStream s)
//private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException
// throws IOException, ClassNotFoundException {
s.defaultReadObject();
content = (byte[]) content.clone();
signature = (byte[]) signature.clone();
}
} }
/* Signer.java --- Signer Class /* 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. This file is part of GNU Classpath.
...@@ -38,28 +38,35 @@ exception statement from your version. */ ...@@ -38,28 +38,35 @@ exception statement from your version. */
package java.security; package java.security;
/** /**
Signer is a subclass used to store a digital signature key with * <p>This class is used to represent an {@link Identity} that can also
an Identity. * digitally sign data.</p>
*
@author Mark Benvenuto <ivymccough@worldnet.att.net> * <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
@since JDK 1.1 * use.</p>
*
* @author Mark Benvenuto <ivymccough@worldnet.att.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 public abstract class Signer extends Identity
{ {
static final long serialVersionUID = -1763464102261361480L;
private PrivateKey privateKey = null; private PrivateKey privateKey = null;
/** /**
Constructs a new Signer. * Creates a <code>Signer</code>. This constructor should only be used for
* serialization.
*/ */
protected Signer() protected Signer()
{ {
} }
/** /**
Constructs a new Signer with the specified name. * Creates a <code>Signer</code> with the specified identity name.
*
@param name the name of the identity. * @param name the identity name.
*/ */
public Signer(String name) public Signer(String name)
{ {
...@@ -67,31 +74,31 @@ public abstract class Signer extends Identity ...@@ -67,31 +74,31 @@ public abstract class Signer extends Identity
} }
/** /**
Constructs a new Signer with the specifid name and * Creates a <code>Signer</code> with the specified identity name and scope.
IdentityScope. *
* @param name the identity name.
@param name the name of the identity. * @param scope the scope of the identity.
@scope the IdentityScope to use * @throws KeyManagementException if there is already an identity with the
* same name in the scope.
@throws KeyManagementException if duplicate identity name
within scope
*/ */
public Signer(String name, IdentityScope scope) public Signer(String name, IdentityScope scope) throws KeyManagementException
throws KeyManagementException
{ {
super(name, scope); super(name, scope);
} }
/** /**
Returns the private key for this signer. * <p>Returns this signer's private key.</p>
*
This class checks the security manager with the call * <p>First, if there is a security manager, its <code>checkSecurityAccess()
checkSecurityAccess with "getSignerPrivateKey". * </code> method is called with <code>"getSignerPrivateKey"</code> as its
* argument to see if it's ok to return the private key.</p>
@returns the private key for the signer *
* @return this signer's private key, or <code>null</code> if the private key
@throws SecurityException - if the security manager denies * has not yet been set.
access to "getSignerPrivateKey" * @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() public PrivateKey getPrivateKey()
{ {
...@@ -103,17 +110,20 @@ public abstract class Signer extends Identity ...@@ -103,17 +110,20 @@ public abstract class Signer extends Identity
} }
/** /**
Specifies the KeyPair associated with this Signer. * <p>Sets the key pair (public key and private key) for this signer.</p>
*
This class checks the security manager with the call * <p>First, if there is a security manager, its <code>checkSecurityAccess()
checkSecurityAccess with "setSignerKeyPair". * </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 the keyPair *
* @param pair an initialized key pair.
@throws InvalidParameterException invalidly intialized key pair * @throws InvalidParameterException if the key pair is not properly
@throws KeyException another key error * initialized.
@throws SecurityException - if the security manager denies * @throws KeyException if the key pair cannot be set for any other reason.
access to "getSignerPrivateKey" * @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) public final void setKeyPair(KeyPair pair)
throws InvalidParameterException, KeyException throws InvalidParameterException, KeyException
...@@ -142,9 +152,10 @@ public abstract class Signer extends Identity ...@@ -142,9 +152,10 @@ public abstract class Signer extends Identity
} }
/** /**
Returns a string representing this Signer. * Returns a string of information about the signer.
*
@returns a string representing this Signer. * @return a string of information about the signer.
* @see SecurityManager#checkSecurityAccess(String)
*/ */
public String toString() public String toString()
{ {
......
/* 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();
}
/* 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;
}
}
/* 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();
}
}
/* 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;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment