This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Patch: FYI: java.security update


I'm checking this in on the trunk.

This updates java.security with code from Classpath.

Tom

Index: libjava/ChangeLog
from  Tom Tromey  <tromey at redhat dot com>

	* Makefile.in: Rebuilt.
	* Makefile.am (ordinary_java_source_files): Added new files.
	* java/security/AlgorithmParameterGenerator.java,
	java/security/AlgorithmParameters.java, java/security/Engine.java,
	java/security/Identity.java, java/security/IdentityScope.java,
	java/security/KeyFactory.java,
	java/security/KeyPairGenerator.java, java/security/KeyStore.java,
	java/security/MessageDigest.java, java/security/Policy.java,
	java/security/ProtectionDomain.java,
	java/security/SecureRandom.java, java/security/Security.java,
	java/security/Signature.java, java/security/SignatureSpi.java,
	java/security/SignedObject.java, java/security/Signer.java,
	java/security/interfaces/RSAMultiPrimePrivateCrtKey.java,
	java/security/spec/PSSParameterSpec.java,
	java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java,
	java/security/spec/RSAOtherPrimeInfo.java: New versions from
	Classpath.

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]