OSDN Git Service

* Makefile.in: Rebuilt.
authortromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 19 Apr 2003 20:54:55 +0000 (20:54 +0000)
committertromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 19 Apr 2003 20:54:55 +0000 (20:54 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@65829 138bc75d-0d04-0410-961f-82ee72b054a4

24 files changed:
libjava/ChangeLog
libjava/Makefile.am
libjava/Makefile.in
libjava/java/security/AlgorithmParameterGenerator.java
libjava/java/security/AlgorithmParameters.java
libjava/java/security/Engine.java [new file with mode: 0644]
libjava/java/security/Identity.java
libjava/java/security/IdentityScope.java
libjava/java/security/KeyFactory.java
libjava/java/security/KeyPairGenerator.java
libjava/java/security/KeyStore.java
libjava/java/security/MessageDigest.java
libjava/java/security/Policy.java
libjava/java/security/ProtectionDomain.java
libjava/java/security/SecureRandom.java
libjava/java/security/Security.java
libjava/java/security/Signature.java
libjava/java/security/SignatureSpi.java
libjava/java/security/SignedObject.java
libjava/java/security/Signer.java
libjava/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java [new file with mode: 0644]
libjava/java/security/spec/PSSParameterSpec.java [new file with mode: 0644]
libjava/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java [new file with mode: 0644]
libjava/java/security/spec/RSAOtherPrimeInfo.java [new file with mode: 0644]

index f585134..c68224c 100644 (file)
@@ -1,3 +1,23 @@
+2003-04-19  Tom Tromey  <tromey@redhat.com>
+
+       * Makefile.in: Rebuilt.
+       * Makefile.am (ordinary_java_source_files): Added new files.
+       * java/security/AlgorithmParameterGenerator.java,
+       java/security/AlgorithmParameters.java, java/security/Engine.java,
+       java/security/Identity.java, java/security/IdentityScope.java,
+       java/security/KeyFactory.java,
+       java/security/KeyPairGenerator.java, java/security/KeyStore.java,
+       java/security/MessageDigest.java, java/security/Policy.java,
+       java/security/ProtectionDomain.java,
+       java/security/SecureRandom.java, java/security/Security.java,
+       java/security/Signature.java, java/security/SignatureSpi.java,
+       java/security/SignedObject.java, java/security/Signer.java,
+       java/security/interfaces/RSAMultiPrimePrivateCrtKey.java,
+       java/security/spec/PSSParameterSpec.java,
+       java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java,
+       java/security/spec/RSAOtherPrimeInfo.java: New versions from
+       Classpath.
+
 2003-04-19  Scott Gilbertson  <scottg@mantatest.com>
 
        * gnu/awt/xlib/XGraphics.java (XGraphics): Use new GC.create.
index 38435cb..35a2099 100644 (file)
@@ -2294,6 +2294,7 @@ java/security/DummySignature.java \
 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/DSAParams.java \
 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/InvalidKeySpecException.java \
 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 15279a5..2b94176 100644 (file)
@@ -2056,6 +2056,7 @@ java/security/DummySignature.java \
 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 \
@@ -2136,6 +2137,7 @@ java/security/interfaces/DSAParams.java \
 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 \
@@ -2148,7 +2150,10 @@ java/security/spec/InvalidKeySpecException.java \
 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 \
@@ -3571,7 +3576,7 @@ DEP_FILES =  .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
 .deps/java/security/DomainCombiner.P \
 .deps/java/security/DummyKeyPairGenerator.P \
 .deps/java/security/DummyMessageDigest.P \
-.deps/java/security/DummySignature.P \
+.deps/java/security/DummySignature.P .deps/java/security/Engine.P \
 .deps/java/security/GeneralSecurityException.P \
 .deps/java/security/Guard.P .deps/java/security/GuardedObject.P \
 .deps/java/security/Identity.P .deps/java/security/IdentityScope.P \
@@ -3636,6 +3641,7 @@ DEP_FILES =  .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
 .deps/java/security/interfaces/DSAPrivateKey.P \
 .deps/java/security/interfaces/DSAPublicKey.P \
 .deps/java/security/interfaces/RSAKey.P \
+.deps/java/security/interfaces/RSAMultiPrimePrivateCrtKey.P \
 .deps/java/security/interfaces/RSAPrivateCrtKey.P \
 .deps/java/security/interfaces/RSAPrivateKey.P \
 .deps/java/security/interfaces/RSAPublicKey.P \
@@ -3648,7 +3654,10 @@ DEP_FILES =  .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
 .deps/java/security/spec/InvalidParameterSpecException.P \
 .deps/java/security/spec/KeySpec.P \
 .deps/java/security/spec/PKCS8EncodedKeySpec.P \
+.deps/java/security/spec/PSSParameterSpec.P \
 .deps/java/security/spec/RSAKeyGenParameterSpec.P \
+.deps/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.P \
+.deps/java/security/spec/RSAOtherPrimeInfo.P \
 .deps/java/security/spec/RSAPrivateCrtKeySpec.P \
 .deps/java/security/spec/RSAPrivateKeySpec.P \
 .deps/java/security/spec/RSAPublicKeySpec.P \
index 9543657..b8ad8e2 100644 (file)
@@ -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 @@ 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.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 @@ public class AlgorithmParameterGenerator
   }
 
   /**
-     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 @@ public class AlgorithmParameterGenerator
   }
 
   /**
-     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 {@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
+   * {@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 @@ public class AlgorithmParameterGenerator
   }
 
   /**
-     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 @@ public class AlgorithmParameterGenerator
   }
 
   /**
-     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 {@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 {@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 {@link AlgorithmParameters} object.
    */
   public final AlgorithmParameters generateParameters()
   {
index afc457e..a721277 100644 (file)
@@ -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 @@ 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;
+
 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 @@ public class AlgorithmParameters
   }
 
   /**
-     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
+  /**
+   * <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
+  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 @@ public class AlgorithmParameters
   }
 
   /**
-     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 @@ public class AlgorithmParameters
   }
 
   /**
-     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 @@ public class AlgorithmParameters
   }
 
   /**
-     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 {@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 @@ public class AlgorithmParameters
   }
 
   /**
-     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 @@ public class AlgorithmParameters
   }
 
   /**
-     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()
   {
diff --git a/libjava/java/security/Engine.java b/libjava/java/security/Engine.java
new file mode 100644 (file)
index 0000000..88ff536
--- /dev/null
@@ -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 ({@link java.security.Signature} for example) can be
+ * thought of as the "chrome, upholstery, and steering wheel", and the SPI
+ * (service provider interface, e.g. {@link java.security.SignatureSpi})
+ * classes can be thought of as the "engine" -- providing the actual
+ * functionality of whatever cryptographic algorithm the instance
+ * represents.
+ *
+ * @see Provider
+ * @author Casey Marshall 
+ */
+final class Engine
+{
+
+  // Constants.
+  // ------------------------------------------------------------------------
+
+  /** Prefix for aliases. */
+  private static final String ALG_ALIAS = "Alg.Alias.";
+
+  /** Maximum number of aliases to try. */
+  private static final int MAX_ALIASES = 5;
+
+  // Constructor.
+  // ------------------------------------------------------------------------
+
+  /** This class cannot be instantiated. */
+  private Engine() { }
+
+  // Class method.
+  // ------------------------------------------------------------------------
+
+  /**
+   * Get the implementation for <i>algorithm</i> for service
+   * <i>service</i> from <i>provider</i>. The service is e.g.
+   * "Signature", and the algorithm "DSA".
+   *
+   * @param service   The service name.
+   * @param algorithm The name of the algorithm to get.
+   * @param provider  The provider to get the implementation from.
+   * @return The engine class for the specified algorithm; the object
+   *         returned is typically a subclass of the SPI class for that
+   *         service, but callers should check that this is so.
+   * @throws NoSuchAlgorithmException If the implementation cannot be
+   *         found or cannot be instantiated.
+   * @throws IllegalArgumentException If any of the three arguments are null.
+   */
+  static Object
+  getInstance(String service, String algorithm, Provider provider)
+  throws NoSuchAlgorithmException
+  {
+    if (service == null || algorithm == null || provider == null)
+      throw new IllegalArgumentException();
+
+    // If there is no property "service.algorithm"
+    if (provider.getProperty(service + "." + algorithm) == null)
+      {
+        // Iterate through aliases, until we find the class name or resolve
+        // too many aliases.
+        String alias = null;
+        int count = 0;
+        while ((alias = provider.getProperty(
+                ALG_ALIAS + service + "." + algorithm)) != null)
+          {
+            if (algorithm.equals(alias))  // Refers to itself!
+              break;
+            algorithm = alias;
+            if (count++ > MAX_ALIASES)
+              throw new NoSuchAlgorithmException("too many aliases");
+          }
+        if (provider.getProperty(service + "." + algorithm) == null)
+          throw new NoSuchAlgorithmException(algorithm);
+      }
+
+    // Find and instantiate the implementation.
+    Class clazz = null;
+    ClassLoader loader = provider.getClass().getClassLoader();
+    String error = algorithm;
+    try
+      {
+        if (loader != null)
+          clazz = loader.loadClass(provider.getProperty(service+"."+algorithm));
+        else
+          clazz = Class.forName(provider.getProperty(service+"."+algorithm));
+        return clazz.newInstance();
+      }
+    catch (ClassNotFoundException cnfe)
+      {
+        error = "class not found: " + algorithm;
+      }
+    catch (IllegalAccessException iae)
+      {
+        error = "illegal access: " + iae.getMessage();
+      }
+    catch (InstantiationException ie)
+      {
+        error = "instantiation exception: " + ie.getMessage();
+      }
+    catch (ExceptionInInitializerError eiie)
+      {
+        error = "exception in initializer: " + eiie.getMessage();
+      }
+    catch (SecurityException se)
+      {
+        error = "security exception: " + se.getMessage();
+      }
+
+    throw new NoSuchAlgorithmException(error);
+  }
+}
index a1af112..d44e96c 100644 (file)
@@ -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 @@ obligated to do so.  If you do not wish to do so, delete this
 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 @@ public abstract class Identity implements Principal, Serializable
   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 @@ public abstract class Identity implements Principal, Serializable
   }
 
   /**
-     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 @@ public abstract class Identity implements Principal, Serializable
   }
 
   /**
-     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 @@ public abstract class Identity implements Principal, Serializable
   }
 
   /**
-     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 @@ public abstract class Identity implements Principal, Serializable
   }
 
   /**
-     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 @@ public abstract class Identity implements Principal, Serializable
   }
 
   /**
-     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 @@ public abstract class Identity implements Principal, Serializable
   }
 
   /**
-     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 @@ public abstract class Identity implements Principal, Serializable
   }
 
   /**
-     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 @@ public abstract class Identity implements Principal, Serializable
   }
 
   /**
-     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 @@ public abstract class Identity implements Principal, Serializable
   }
 
   /**
-     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 @@ public abstract class Identity implements Principal, Serializable
     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 @@ public abstract class Identity implements Principal, Serializable
   }
 
   /**
-     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 @@ public abstract class Identity implements Principal, Serializable
   }
 
   /**
-     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 @@ public abstract class Identity implements Principal, Serializable
   }
 
   /**
-     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 @@ public abstract class Identity implements Principal, Serializable
   }
 
   /**
-     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 8df5b93..200b3c6 100644 (file)
@@ -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 @@ obligated to do so.  If you do not wish to do so, delete this
 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 {@link Identity} objects of all
+ * kinds, including {@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 @@ public abstract class IdentityScope extends Identity
   }
 
   /**
-     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 @@ public abstract class IdentityScope extends Identity
   }
 
   /**
-     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 @@ public abstract class IdentityScope extends Identity
   }
 
   /**
-     Gets the system's Scope.
+   * Returns the system's identity scope.
+   *
+   * @return the system's identity scope.
+   * @see #setSystemScope(IdentityScope)
    */
   public static IdentityScope getSystemScope()
   {
@@ -110,15 +123,18 @@ public abstract class IdentityScope extends Identity
   }
 
   /**
-     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 @@ public abstract class IdentityScope extends Identity
   }
 
   /**
-     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 @@ public abstract class IdentityScope extends Identity
   }
 
   /**
-     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 667c2fb..918bf3d 100644 (file)
@@ -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 @@ 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.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
+ * {@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 {@link
+ * java.security.spec.DSAPublicKeySpec} or {@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 @@ public class KeyFactory
     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 @@ public class KeyFactory
   }
 
   /**
-     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 @@ public class KeyFactory
   }
 
   /**
-     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 {@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 @@ public class KeyFactory
   }
 
   /**
-     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 9ca1aa8..8bc8296 100644 (file)
@@ -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 @@ package java.security;
 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
+ *    {@link SecureRandom} implementation of the highest-priority installed
+ *    provider as the <i>source of randomness</i>. (If none of the installed
+ *    providers supply an implementation of {@link SecureRandom}, a
+ *    system-provided source of randomness is used.)<br/><br/>
+ *
+ *    Since no other parameters are specified when you call the above
+ *    algorithm-independent initialize methods, it is up to the provider what
+ *    to do about the algorithm-specific parameters (if any) to be associated
+ *    with each of the keys.<br/><br/>
+ *
+ *    If the algorithm is the <i>DSA</i> algorithm, and the <i>keysize</i>
+ *    (modulus size) is <code>512</code>, <code>768</code>, or <code>1024</code>,
+ *    then the <b>GNU</b> provider uses a set of precomputed values for the
+ *    <code>p</code>, <code>q</code>, and <code>g</code> parameters. If the
+ *    <i>modulus size</i> is not one of the above values, the <b>GNU</b>
+ *    provider creates a new set of parameters. Other providers might have
+ *    precomputed parameter sets for more than just the three modulus sizes
+ *    mentioned above. Still others might not have a list of precomputed
+ *    parameters at all and instead always create new parameter sets.<br/></li>
+ *
+ *    <li><b>Algorithm-Specific Initialization</b><br/>
+ *    For situations where a set of algorithm-specific parameters already
+ *    exists (e.g., so-called <i>community parameters</i> in <i>DSA</i>), there
+ *    are two initialize methods that have an {@link AlgorithmParameterSpec}
+ *    argument. One also has a {@link SecureRandom} argument, while the the
+ *    other uses the {@link SecureRandom} implementation of the highest-priority
+ *    installed provider as the source of randomness. (If none of the installed
+ *    providers supply an implementation of {@link SecureRandom}, a
+ *    system-provided source of randomness is used.)</li>
+ * </ul>
+ *
+ * <p>In case the client does not explicitly initialize the
+ * <code>KeyPairGenerator</code> (via a call to an initialize method), each
+ * provider must supply (and document) a default initialization. For example,
+ * the <b>GNU</b> provider uses a default modulus size (keysize) of
+ * <code>1024</code> bits.</p>
+ *
+ * <p>Note that this class is abstract and extends from {@link
+ * KeyPairGeneratorSpi} for historical reasons. Application developers should
+ * only take notice of the methods defined in this <code>KeyPairGenerator</code>
+ * class; all the methods in the superclass are intended for cryptographic
+ * service providers who wish to supply their own implementations of key pair
+ * generators.</p>
+ *
+ * @see Signature
+ * @see KeyPair
+ * @see AlgorithmParameterSpec
+ * @author Mark Benvenuto
+ * @author Casey Marshall
  */
 public abstract class KeyPairGenerator extends KeyPairGeneratorSpi
 {
+  /** 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 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi
   }
 
   /**
-     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 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi
     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 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi
   }
 
   /**
-     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 {@link SecureRandom} implementation of the
+   * highest-priority installed provider as the source of randomness. (If none
+   * of the installed providers supply an implementation of {@link SecureRandom},
+   * a system-provided source of randomness is used.)
+   *
+   * @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 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi
   }
 
   /**
-     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 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi
   }
 
   /**
-     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 {@link SecureRandom} implementation of the highest-priority installed
+   * provider as the source of randomness. (If none of the installed providers
+   * supply an implementation of {@link SecureRandom}, a system-provided source
+   * of randomness is used.)</p>
+   *
+   * <p>This concrete method has been added to this previously-defined abstract
+   * class. This method calls the
+   * {@link KeyPairGeneratorSpi#initialize(AlgorithmParameterSpec, SecureRandom)}
+   * initialize method, passing it <code>params</code> and a source of
+   * randomness (obtained from the highest-priority installed provider or
+   * system-provided if none of the installed providers supply one). That
+   * initialize method always throws an {@link UnsupportedOperationException}
+   * if it is not overridden by the provider.</p>
+   *
+   * @param params the parameter set used to generate the keys.
+   * @throws InvalidAlgorithmParameterException if the given parameters are
+   * inappropriate for this key pair generator.
+   * @since 1.2
    */
   public void initialize(AlgorithmParameterSpec params)
     throws InvalidAlgorithmParameterException
@@ -239,13 +317,21 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi
   }
 
   /**
-     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
+   * {@link KeyPairGeneratorSpi#initialize(AlgorithmParameterSpec, SecureRandom)}
+   * initialize method, passing it <code>params</code> and <code>random</code>.
+   * That initialize method always throws an {@link UnsupportedOperationException}
+   * if it is not overridden by the provider.</p>
+   *
+   * @param params the parameter set used to generate the keys.
+   * @param random the source of randomness.
+   * @throws InvalidAlgorithmParameterException if the given parameters are
+   * inappropriate for this key pair generator.
+   * @since 1.2
    */
   public void initialize(AlgorithmParameterSpec params, SecureRandom random)
     throws InvalidAlgorithmParameterException
@@ -254,36 +340,45 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi
   }
 
   /**
-     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 {@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 {@link #genKeyPair()}.</p>
+   *
+   * @return the generated key pair.
    */
   public KeyPair generateKeyPair()
   {
index 1627bc5..cd3c268 100644 (file)
@@ -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.Date;
 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 @@ public class KeyStore
     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 @@ public class KeyStore
 
     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);
+        return new KeyStore(
+          (KeyStoreSpi) Engine.getInstance(KEY_STORE, type, provider),
+          provider, type);
       }
-    catch (ClassNotFoundException cnfe)
+    catch (NoSuchAlgorithmException nsae)
       {
-       throw new KeyStoreException("Class not found");
+        throw new KeyStoreException(type);
       }
-    catch (InstantiationException ie)
+    catch (ClassCastException cce)
       {
-       throw new KeyStoreException("Class instantiation failed");
-      }
-    catch (IllegalAccessException iae)
-      {
-       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 @@ public class KeyStore
     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 10032f2..cbf0e07 100644 (file)
@@ -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 @@ exception statement from your version. */
 
 package java.security;
 
+/**
+ * <p>This <code>MessageDigest</code> class provides applications the
+ * functionality of a message digest algorithm, such as <i>MD5</i> or <i>SHA</i>.
+ * Message digests are secure one-way hash functions that take arbitrary-sized
+ * data and output a fixed-length hash value.</p>
+ *
+ * <p>A <code>MessageDigest</code> object starts out initialized. The data is
+ * processed through it using the <code>update()</code> methods. At any point
+ * <code>reset()</code> can be called to reset the digest. Once all the data to
+ * be updated has been updated, one of the <code>digest()</code> methods should
+ * be called to complete the hash computation.</p>
+ *
+ * <p>The <code>digest()</code> method can be called <b>once</b> for a given
+ * number of updates. After <code>digest()</code> has been called, the
+ * <code>MessageDigest</code> object is <b>reset</b> to its initialized state.
+ * </p>
+ *
+ * <p>Implementations are free to implement the {@link Cloneable} interface.
+ * Client applications can test cloneability by attempting cloning and catching
+ * the {@link CloneNotSupportedException}:
+ *
+ * <pre>
+ *    MessageDigest md = MessageDigest.getInstance("SHA");
+ *    try
+ *      {
+ *        md.update(toChapter1);
+ *        MessageDigest tc1 = md.clone();
+ *        byte[] toChapter1Digest = tc1.digest();
+ *        md.update(toChapter2);
+ *        // ...
+ *      }
+ *    catch (CloneNotSupportedException x)
+ *      {
+ *        throw new DigestException("couldn't make digest of partial content");
+ *      }
+ * </pre>
+ *
+ * <p>Note that if a given implementation is not cloneable, it is still possible
+ * to compute intermediate digests by instantiating several instances, if the
+ * number of digests is known in advance.</p>
+ *
+ * <p>Note that this class is abstract and extends from {@link MessageDigestSpi}
+ * for historical reasons. Application developers should only take notice of the
+ * methods defined in this <code>MessageDigest</code> class; all the methods in
+ * the superclass are intended for cryptographic service providers who wish to
+ * supply their own implementations of message digest algorithms.</p>
+ *
+ * @see MessageDigestSpi
+ * @see Provider
+ * @since JDK 1.1
+ */
 public abstract class MessageDigest extends MessageDigestSpi
 {
+  /** 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 @@ public abstract class MessageDigest extends MessageDigestSpi
     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 @@ public abstract class MessageDigest extends MessageDigestSpi
     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 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;
-      }
-    catch (ClassNotFoundException cnfe)
+    Object o = Engine.getInstance(MESSAGE_DIGEST, algorithm, provider);
+     
+    if (o instanceof MessageDigestSpi)
       {
-       throw new NoSuchAlgorithmException(algorithm + ": Class not found.");
+       result = new DummyMessageDigest((MessageDigestSpi) o, algorithm);
       }
-    catch (InstantiationException ie)
+    else if (o instanceof MessageDigest)
       {
-       throw new NoSuchAlgorithmException(algorithm
-                                          + ": Class instantiation failed.");
+       result = (MessageDigest) o;
+       result.algorithm = algorithm;
       }
-    catch (IllegalAccessException iae)
+    else
       {
-       throw new NoSuchAlgorithmException(algorithm + ": Illegal Access");
+        throw new NoSuchAlgorithmException(algorithm);
       }
+    result.provider = provider;
+    return result;
   }
 
-
   /**
-     Gets the provider that the MessageDigest is from.
-
-     @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 @@ public abstract class MessageDigest extends MessageDigestSpi
   }
 
   /**
-     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 @@ public abstract class MessageDigest extends MessageDigestSpi
   }
 
   /**
-     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 @@ public abstract class MessageDigest extends MessageDigestSpi
   }
 
   /**
-     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 @@ public abstract class MessageDigest extends MessageDigestSpi
     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 @@ public abstract class MessageDigest extends MessageDigestSpi
   }
 
   /**
-     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 @@ public abstract class MessageDigest extends MessageDigestSpi
   }
 
   /**
-     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 {@link Cloneable}.
    */
   public Object clone() throws CloneNotSupportedException
   {
@@ -359,5 +400,4 @@ public abstract class MessageDigest extends MessageDigestSpi
 
     return buf.toString();
   }
-
 }
index 126c084..47171cf 100644 (file)
@@ -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 @@ exception statement from your version. */
 
 package java.security;
 
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
 /**
-   Policy is an abstract class for managing the system security
-   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
-
-   @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 {@link ProtectionDomain}. This is
+ * dependent on the <code>Policy</code> provider's implementation of the
+ * <code>implies()</code> method and the {@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 {@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 @@ public abstract class Policy
     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
+   * {@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 @@ public abstract class Policy
     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());
+
+    ProtectionDomain pd = policy.getClass().getProtectionDomain();
+    if (pd.getCodeSource() != null)
+      {
+        PermissionCollection pc = null;
+        if (currentPolicy != null)
+          pc = currentPolicy.getPermissions(pd);
+
+        if (pc == null) // assume it has all
+          {
+            pc = new Permissions();
+            pc.add(new AllPermission());
+          }
+
+        policy.pd2pc.put(pd, pc); // add the mapping pd -> pc
+      }
+  }
 
   /**
-     Evalutes the global policy and returns a set of Permissions 
-     allowed for the specified CodeSource.
+   * Ensures/forces loading of the configured policy provider, while bypassing
+   * the {@link SecurityManager} checks for <code>"getPolicy"</code> security
+   * permission.  Needed by {@link ProtectionDomain}.
+   */
+  static Policy getCurrentPolicy()
+  {
+    // FIXME: The class name of the Policy provider should really be sourced
+    // from the "java.security" configuration file. For now, just hard-code
+    // a stub implementation.
+    if (currentPolicy == null)
+      {
+        String pp = System.getProperty ("policy.provider");
+        if (pp != null)
+          try
+            {
+              currentPolicy = (Policy) Class.forName(pp).newInstance();
+            }
+          catch (Exception ignored) {}
 
-     @param codesource The CodeSource to get Permission for
+        if (currentPolicy == null)
+          currentPolicy = new gnu.java.security.provider.DefaultPolicy();
+      }
+    return currentPolicy;
+  }
 
-     @return a set of permissions for codesource specified by 
-     the current policy
+  /**
+   * Tests if <code>currentPolicy</code> is not <code>null</code>,
+   * thus allowing clients to not force loading of any policy
+   * provider; needed by {@link ProtectionDomain}.
+   */
+  static boolean isLoaded()
+  {
+    return currentPolicy != null;
+  }
 
-     @throws SecurityException if the current thread does not
-     have permission to call <code>getPermissions</code>
+  /**
+   * Evaluates the global policy and returns a {@link PermissionCollection}
+   * object specifying the set of permissions allowed for code from the
+   * specified code source.
+   *
+   * @param codesource the {@link CodeSource} associated with the caller. This
+   * encapsulates the original location of the code (where the code came from)
+   * and the public key(s) of its signer.
+   * @return the set of permissions allowed for code from codesource according
+   * to the policy. The returned set of permissions must be a new mutable
+   * instance and it must support heterogeneous {@link Permission} types.
    */
   public abstract PermissionCollection getPermissions(CodeSource codesource);
 
   /**
-     Refreshes and/or reloads the current Policy. The actual
-     behavior of this method depends on the implementation. 
+   * Evaluates the global policy and returns a {@link PermissionCollection}
+   * object specifying the set of permissions allowed given the characteristics
+   * of the protection domain.
+   *
+   * @param domain the {@link ProtectionDomain} associated with the caller.
+   * @return the set of permissions allowed for the domain according to the
+   * policy. The returned set of permissions must be a new mutable instance and
+   * it must support heterogeneous {@link Permission} types.
+   * @since 1.4
+   * @see ProtectionDomain
+   * @see SecureClassLoader
+   */
+  public PermissionCollection getPermissions(ProtectionDomain domain)
+  {
+    if (domain == null)
+      return new Permissions();
+
+    if (pd2pc == null)
+      setup(this);
+
+    PermissionCollection result = (PermissionCollection) pd2pc.get(domain);
+    if (result != null)
+      {
+        Permissions realResult = new Permissions();
+        for (Enumeration e = result.elements(); e.hasMoreElements(); )
+          realResult.add((Permission) e.nextElement());
+
+        return realResult;
+      }
+
+    result = getPermissions(domain.getCodeSource());
+    if (result == null)
+      result = new Permissions();
+
+    PermissionCollection pc = domain.getPermissions();
+    if (pc != null)
+      for (Enumeration e = pc.elements(); e.hasMoreElements(); )
+        result.add((Permission) e.nextElement());
+
+    return result;
+  }
+
+  /**
+   * Evaluates the global policy for the permissions granted to the {@link
+   * ProtectionDomain} and tests whether the <code>permission</code> is granted.
+   *
+   * @param domain the {@link ProtectionDomain} to test.
+   * @param permission the {@link Permission} object to be tested for
+   * implication.
+   * @return <code>true</code> if <code>permission</code> is a proper subset of
+   * a permission granted to this {@link ProtectionDomain}.
+   * @since 1.4
+   * @see ProtectionDomain
+   */
+  public boolean implies(ProtectionDomain domain, Permission permission)
+  {
+    if (pd2pc == null)
+      setup(this);
+
+    PermissionCollection pc = (PermissionCollection) pd2pc.get(domain);
+    if (pc != null)
+      return pc.implies(permission);
+
+    boolean result = false;
+    pc = getPermissions(domain);
+    if (pc != null)
+      {
+        result = pc.implies(permission);
+        pd2pc.put(domain, pc);
+      }
+
+    return result;
+  }
+
+  /**
+   * Refreshes/reloads the policy configuration. The behavior of this method
+   * depends on the implementation. For example, calling refresh on a file-based
+   * policy will cause the file to be re-read.
    */
   public abstract void refresh();
 }
index e8ead46..21d9b6d 100644 (file)
@@ -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 @@ exception statement from your version. */
 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 {@link Policy} in force. However, to support dynamic security
+ * policies, a <code>ProtectionDomain</code> can also be constructed such that
+ * it is dynamically mapped to a set of permissions by the current {@link
+ * Policy} whenever a permission is checked.</p>
  *
  * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @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 {@link ClassLoader} associated with this domain. */
+  private ClassLoader classloader;
+
+  /** The array of Principals associated with this domain.. */
+  private Principal[] principals;
+
+  /** Post 1.4 the policy may be refreshed! use false for pre 1.4. */
+  private boolean staticBinding;
+
   /**
-   * This is the set of permissions granted to this domain
+   * Creates a new <code>ProtectionDomain</code> with the given {@link
+   * CodeSource} and {@link Permissions}. If the permissions object is not
+   * <code>null</code>, then <code>setReadOnly()</code> will be called on the
+   * passed in {@link Permissions} object. The only permissions granted to this
+   * domain are the ones specified; the current {@link Policy} will not be
+   * consulted.
+   *
+   * @param codesource the codesource associated with this domain.
+   * @param permissions the permissions granted to this domain
    */
-  private PermissionCollection perms;
+  public ProtectionDomain(CodeSource codesource, PermissionCollection permissions)
+  {
+    this(codesource, permissions, null, null, false);
+  }
 
   /**
-   * This method initializes a new instance of <code>ProtectionDomain</code>
-   * 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 {@link ClassLoader}s and {@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.code_source = code_source;
-    this.perms = perms;
-    if (perms != null)
-      perms.setReadOnly();
+    this(codesource, permissions, classloader, principals, false);
+  }
+
+  private ProtectionDomain(CodeSource codesource,
+                           PermissionCollection permissions,
+                           ClassLoader classloader, Principal[] principals,
+                           boolean staticBinding)
+  {
+    super();
+
+    code_source = codesource;
+    if (permissions != null)
+      {
+        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 {@link CodeSource} of this domain.
+   *
+   * @return the {@link CodeSource} of this domain which may be <code>null</code>.
+   * @since 1.2
    */
   public final CodeSource getCodeSource()
   {
@@ -94,9 +148,36 @@ public class ProtectionDomain
   }
 
   /**
-   * This method returns the set of permissions granted to this domain.
+   * Returns the {@link ClassLoader} of this domain.
    *
-   * @return The permission set for this domain
+   * @return the {@link ClassLoader} of this domain which may be
+   * <code>null</code>.
+   * @since 1.4
+   */
+  public final ClassLoader getClassLoader()
+  {
+    return this.classloader;
+  }
+
+  /**
+   * Returns an array of principals for this domain.
+   *
+   * @return returns a non-null array of principals for this domain. Changes to
+   * this array will have no impact on the <code>ProtectionDomain</code>.
+   * @since 1.4
+   */
+  public final Principal[] getPrincipals()
+  {
+    return (Principal[]) principals.clone();
+  }
+
+  /**
+   * Returns the static permissions granted to this domain.
+   *
+   * @return the static set of permissions for this domain which may be
+   * <code>null</code>.
+   * @see Policy#refresh()
+   * @see Policy#getPermissions(ProtectionDomain)
    */
   public final PermissionCollection getPermissions()
   {
@@ -104,41 +185,85 @@ public class ProtectionDomain
   }
 
   /**
-   * 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 {@link PermissionCollection} then the permission will only be checked
+   * against the {@link PermissionCollection} supplied at construction.</p>
    *
-   * @return <code>true</code> if the specified <code>Permission</code> is implied for this domain, <code>false</code> otherwise.
+   * <p>However, if the <code>ProtectionDomain</code> was constructed with the
+   * constructor variant which supports dynamically binding permissions, then
+   * the permission will be checked against the combination of the
+   * {@link PermissionCollection} supplied at construction and the current
+   * {@link Policy} binding.
+   *
+   * @param permission the {@link Permission} object to check.
+   * @return <code>true</code> if <code>permission</code> is implicit to this
+   * <code>ProtectionDomain</code>.
    */
-  public boolean implies(Permission perm)
+  public boolean implies(Permission permission)
   {
-    PermissionCollection pc = getPermissions();
-    if (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 d9ac153..5cd3cae 100644 (file)
@@ -42,14 +42,24 @@ import java.util.Random;
 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@worldnet.att.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@worldnet.att.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 @@ public class SecureRandom extends Random
   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 @@ public class SecureRandom extends Random
      on the first call to getnextBytes it will force a seed.
 
      It is maintained for backwards compatibility and programs
-     should use getInstance.
+     should use {@link #getInstance(java.lang.String)}.
    */
   public SecureRandom()
   {
@@ -88,20 +101,20 @@ public class SecureRandom extends Random
           {
             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 @@ public class SecureRandom extends Random
     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 @@ public class SecureRandom extends Random
     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 @@ public class SecureRandom extends Random
   }
 
   /**
-     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 @@ public class SecureRandom extends Random
   }
 
   /**
-     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.
+   * 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
+  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(); )
+    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 @@ public class SecureRandom extends Random
                       (byte) (0xff & (seed >> 16)),
                       (byte) (0xff & (seed >> 8)),
                       (byte) (0xff & seed)
-       };
-       secureRandomSpi.engineSetSeed(tmp);
+        };
+        secureRandomSpi.engineSetSeed(tmp);
       }
   }
 
index 39d75ee..2b2ac39 100644 (file)
@@ -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 @@ obligated to do so.  If you do not wish to do so, delete this
 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@worldnet.att.net>
+ * This class centralizes all security properties and common security methods.
* One of its primary uses is to manage providers.
+ *
* @author Mark Benvenuto <ivymccough@worldnet.att.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 @@ public final class Security extends Object
       return;
 
     String secfilestr = baseUrl + "/security/" + vendor + ".security";
-
     try
       {
        InputStream fin = new URL(secfilestr).openStream();
@@ -85,12 +91,9 @@ public final class Security extends Object
 
        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 @@ public final class Security extends Object
              {
                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 @@ public final class Security extends Object
   }
 
   /**
-     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 {@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 {@link AlgorithmParameters} and
+   * {@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
+   * {@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 @@ public final class Security extends Object
     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 @@ public final class Security extends Object
     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
+   * {@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 @@ public final class Security extends Object
   }
 
   /**
-     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
+   * {@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 @@ public final class Security extends Object
     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 @@ public final class Security extends Object
   }
 
   /**
-     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 @@ public final class Security extends Object
   }
 
   /**
-     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 @@ public final class Security extends Object
   }
 
   /**
-     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
+   * {@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 @@ public final class Security extends Object
     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
+   * {@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)
   {
@@ -336,4 +378,327 @@ public final class Security extends Object
 
     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 209a7df..dff2e2d 100644 (file)
@@ -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 @@ 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.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@worldnet.att.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
+ *        {@link #initSign(PrivateKey)} and {@link #initSign(PrivateKey, SecureRandom)}
+ *        ).</li>
+ *      </ul></li>
+ *    <li>Updating<br/>
+ *      Depending on the type of initialization, this will update the bytes to
+ *      be signed or verified. See the update methods.<br/></li>
+ *    <li>Signing or Verifying a signature on all updated bytes. See the
+ *    <code>sign()</code> methods and the <code>verify()</code> method.</li>
+ *  </ol>
+ *
+ * <p>Note that this class is abstract and extends from {@link SignatureSpi} for
+ * historical reasons. Application developers should only take notice of the
+ * methods defined in this <code>Signature</code> class; all the methods in the
+ * superclass are intended for cryptographic service providers who wish to
+ * supply their own implementations of digital signature algorithms.
+ *
+ * @author Mark Benvenuto <ivymccough@worldnet.att.net>
  */
 public abstract class Signature extends SignatureSpi
 {
+  /** 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 @@ public abstract class Signature extends SignatureSpi
   }
 
   /**
-     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 @@ public abstract class Signature extends SignatureSpi
     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 @@ public abstract class Signature extends SignatureSpi
     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;
-         }
-
-       sig.provider = provider;
-       return sig;
-      }
-    catch (ClassNotFoundException cnfe)
+    Signature result = null;
+    Object o = Engine.getInstance(SIGNATURE, algorithm, provider);
+
+    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 @@ public abstract class Signature extends SignatureSpi
   }
 
   /**
-     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 @@ public abstract class Signature extends SignatureSpi
   }
 
   /**
-     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 {@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 @@ public abstract class Signature extends SignatureSpi
   }
 
   /**
-     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 @@ public abstract class Signature extends SignatureSpi
     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");
+
+    if (signature == null)
+      throw new IllegalArgumentException("signaure is null");
+    if (offset < 0)
+      throw new IllegalArgumentException("offset is less than 0");
+    if (length < 0)
+      throw new IllegalArgumentException("length is less than 0");
+    if (offset + length < signature.length)
+      throw new IllegalArgumentException("range is out of bounds");
 
-     @param b byte to update with
+    state = UNINITIALIZED;
+    return engineVerify(signature, offset, length);
+  }
 
-     @throws SignatureException Engine not properly initialized
+  /**
+   * Updates the data to be signed or verified by a byte.
+   *
+   * @param b the byte to use for the update.
+   * @throws SignatureException if this signature object is not initialized
+   * properly.
    */
   public final void update(byte b) throws SignatureException
   {
@@ -400,12 +482,12 @@ public abstract class Signature extends SignatureSpi
   }
 
   /**
-     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 @@ public abstract class Signature extends SignatureSpi
   }
 
   /**
-     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 @@ public abstract class Signature extends SignatureSpi
       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 @@ public abstract class Signature extends SignatureSpi
   }
 
   /**
-     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 @@ public abstract class Signature extends SignatureSpi
   }
 
   /**
-     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 @@ public abstract class Signature extends SignatureSpi
   }
 
   /**
-     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 @@ public abstract class Signature extends SignatureSpi
   }
 
   /**
-     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 @@ public abstract class Signature extends SignatureSpi
   }
 
   /**
-     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 {@link Cloneable}.
    */
   public Object clone() throws CloneNotSupportedException
   {
index 01a7280..7deafd6 100644 (file)
@@ -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 @@ 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.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@worldnet.att.net>
-
-   @since JDK 1.2
+ * <p>This class defines the <i>Service Provider Interface (SPI)</i> for the
+ * {@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@worldnet.att.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 @@ public abstract class SignatureSpi
   }
 
   /**
-     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 {@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 @@ public abstract class SignatureSpi
   }
 
   /**
-     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 {@link Cloneable}.
+   * @see Cloneable
    */
   public Object clone() throws CloneNotSupportedException
   {
index 78684e5..6a8d612 100644 (file)
@@ -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 @@ obligated to do so.  If you do not wish to do so, delete this
 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@worldnet.att.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
+ * {@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 {@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 {@link Signature} engine is being used, as
+ * its own implementation of the <code>verify()</code> method is invoked to
+ * verify a signature. In other words, a malicious {@link Signature} may choose
+ * to always return <code>true</code> on verification in an attempt to bypass a
+ * security check.</p>
+ *
+ * <p>The signature algorithm can be, among others, the NIST standard <i>DSS</i>,
+ * using <i>DSA</i> and <i>SHA-1</i>. The algorithm is specified using the same
+ * convention as that for signatures. The <i>DSA</i> algorithm using the
+ * </i>SHA-1</i> message digest algorithm can be specified, for example, as
+ * <code>"SHA/DSA"</code> or <code>"SHA-1/DSA"</code> (they are equivalent). In
+ * the case of <i>RSA</i>, there are multiple choices for the message digest
+ * algorithm, so the signing algorithm could be specified as, for example,
+ * <code>"MD2/RSA"</code>, <code>"MD5/RSA"</code> or <code>"SHA-1/RSA"</code>.
+ * The algorithm name must be specified, as there is no default.</p>
+ *
+ * <p>The name of the Cryptography Package Provider is designated also by the
+ * {@link Signature} parameter to the <code>constructor</code> and the <code>
+ * verify()</code> method. If the provider is not specified, the default
+ * provider is used. Each installation can be configured to use a particular
+ * provider as default.</p>
+ *
+ * <p>Potential applications of <code>SignedObject</code> include:</p>
+ *
+ * <ul>
+ *  <li>It can be used internally to any Java runtime as an unforgeable
+ *  authorization token -- one that can be passed around without the fear that
+ *  the token can be maliciously modified without being detected.</li>
+ *  <li>It can be used to sign and serialize data/object for storage outside the
+ *  Java runtime (e.g., storing critical access control data on disk).</li>
+ *  <li>Nested <i>SignedObjects</i> can be used to construct a logical sequence
+ *  of signatures, resembling a chain of authorization and delegation.</li>
+ * </ul>
+ *
+ * @author Mark Benvenuto <ivymccough@worldnet.att.net>
+ * @since 1.2
+ * @see Signature
  */
 public final class SignedObject implements Serializable
 {
   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 {@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 @@ public final class SignedObject implements Serializable
     ObjectOutputStream p = new ObjectOutputStream(ostream);
     p.writeObject(object);
     p.flush();
+    p.close();
 
     content = ostream.toByteArray();
 
@@ -116,35 +170,39 @@ public final class SignedObject implements Serializable
   }
 
   /**
-     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 @@ public final class SignedObject implements Serializable
   }
 
   /**
-     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 2622437..b5b3aaf 100644 (file)
@@ -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 @@ exception statement from your version. */
 package java.security;
 
 /**
-   Signer is a subclass used to store a digital signature key with 
-   an Identity.
-
-   @author Mark Benvenuto <ivymccough@worldnet.att.net>
-
-   @since JDK 1.1
+ * <p>This class is used to represent an {@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@worldnet.att.net>
+ * @deprecated This class is no longer used. Its functionality has been replaced
+ * by <code>java.security.KeyStore</code>, the <code>java.security.cert</code>
+ * package, and <code>java.security.Principal</code>.
  */
 public abstract class Signer extends Identity
 {
+  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 @@ public abstract class Signer extends Identity
   }
 
   /**
-     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 @@ public abstract class Signer extends Identity
   }
 
   /**
-     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 @@ public abstract class Signer extends Identity
 
     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 @@ public abstract class Signer extends Identity
   }
 
   /**
-     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()
   {
diff --git a/libjava/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java b/libjava/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java
new file mode 100644 (file)
index 0000000..7e115fa
--- /dev/null
@@ -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();
+}
diff --git a/libjava/java/security/spec/PSSParameterSpec.java b/libjava/java/security/spec/PSSParameterSpec.java
new file mode 100644 (file)
index 0000000..c8aa913
--- /dev/null
@@ -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;
+  }
+}
diff --git a/libjava/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java b/libjava/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java
new file mode 100644 (file)
index 0000000..f2cb88b
--- /dev/null
@@ -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();
+  }
+}
diff --git a/libjava/java/security/spec/RSAOtherPrimeInfo.java b/libjava/java/security/spec/RSAOtherPrimeInfo.java
new file mode 100644 (file)
index 0000000..082101e
--- /dev/null
@@ -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;
+  }
+}