001/* AlgorithmParameters.java --- Algorithm Parameters Implementation Class
002   Copyright (C) 1999, 2003, 2004  Free Software Foundation, Inc.
003
004This file is part of GNU Classpath.
005
006GNU Classpath is free software; you can redistribute it and/or modify
007it under the terms of the GNU General Public License as published by
008the Free Software Foundation; either version 2, or (at your option)
009any later version.
010
011GNU Classpath is distributed in the hope that it will be useful, but
012WITHOUT ANY WARRANTY; without even the implied warranty of
013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014General Public License for more details.
015
016You should have received a copy of the GNU General Public License
017along with GNU Classpath; see the file COPYING.  If not, write to the
018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
01902110-1301 USA.
020
021Linking this library statically or dynamically with other modules is
022making a combined work based on this library.  Thus, the terms and
023conditions of the GNU General Public License cover the whole
024combination.
025
026As a special exception, the copyright holders of this library give you
027permission to link this library with independent modules to produce an
028executable, regardless of the license terms of these independent
029modules, and to copy and distribute the resulting executable under
030terms of your choice, provided that you also meet, for each linked
031independent module, the terms and conditions of the license of that
032module.  An independent module is a module which is not derived from
033or based on this library.  If you modify this library, you may extend
034this exception to your version of the library, but you are not
035obligated to do so.  If you do not wish to do so, delete this
036exception statement from your version. */
037
038
039package java.security;
040
041import gnu.java.lang.CPStringBuilder;
042
043import gnu.java.security.Engine;
044
045import java.io.IOException;
046import java.lang.reflect.InvocationTargetException;
047import java.security.spec.AlgorithmParameterSpec;
048import java.security.spec.InvalidParameterSpecException;
049
050/**
051 * <code>AlgorithmParameters</code> is an Algorithm Parameters class which
052 * provides an interface through which the user can manage the parameters of an
053 * Algorithm.
054 *
055 * @author Mark Benvenuto
056 * @since 1.2
057 * @see AlgorithmParameterSpec
058 * @see java.security.spec.DSAParameterSpec
059 * @see KeyPairGenerator
060 */
061public class AlgorithmParameters
062{
063  /** Service name for algorithm parameters. */
064  private static final String ALGORITHM_PARAMETERS = "AlgorithmParameters";
065
066  private AlgorithmParametersSpi paramSpi;
067  private Provider provider;
068  private String algorithm;
069
070  /**
071   * Constructs a new instance of <code>AlgorithmParameters</code>.
072   * 
073   * @param paramSpi
074   *          the engine to use.
075   * @param provider
076   *          the provider to use.
077   * @param algorithm
078   *          the algorithm to use.
079   */
080  protected AlgorithmParameters(AlgorithmParametersSpi paramSpi,
081                                Provider provider, String algorithm)
082  {
083    this.paramSpi = paramSpi;
084    this.provider = provider;
085    this.algorithm = algorithm;
086  }
087
088  /** @return A string with the name of the algorithm used. */
089  public final String getAlgorithm()
090  {
091    return algorithm;
092  }
093
094  /**
095   * Returns a new instance of <code>AlgorithmParameters</code> representing
096   * the specified algorithm parameters.
097   * <p>
098   * The returned <code>AlgorithmParameters</code> must still be initialized
099   * with an <code>init()</code> method.
100   * 
101   * @param algorithm the algorithm to use.
102   * @return the new instance repesenting the desired algorithm.
103   * @throws NoSuchAlgorithmException if the algorithm is not implemented by any
104   *           provider.
105   * @throws IllegalArgumentException if <code>algorithm</code> is
106   *           <code>null</code> or is an empty string.
107   */
108  public static AlgorithmParameters getInstance(String algorithm)
109      throws NoSuchAlgorithmException
110  {
111    Provider[] p = Security.getProviders();
112    NoSuchAlgorithmException lastException = null;
113    for (int i = 0; i < p.length; i++)
114      try
115        {
116          return getInstance(algorithm, p[i]);
117        }
118      catch (NoSuchAlgorithmException x)
119        {
120          lastException = x;
121        }
122    if (lastException != null)
123      throw lastException;
124    throw new NoSuchAlgorithmException(algorithm);
125  }
126
127  /**
128   * Returns a new instance of <code>AlgorithmParameters</code> representing
129   * the specified algorithm parameters from a named provider.
130   * <p>
131   * The returned <code>AlgorithmParameters</code> must still be intialized
132   * with an <code>init()</code> method.
133   * </p>
134   * 
135   * @param algorithm the algorithm to use.
136   * @param provider the name of the {@link Provider} to use.
137   * @return the new instance repesenting the desired algorithm.
138   * @throws NoSuchAlgorithmException if the algorithm is not implemented by the
139   *           named provider.
140   * @throws NoSuchProviderException if the named provider was not found.
141   * @throws IllegalArgumentException if either <code>algorithm</code> or
142   *           <code>provider</code> is <code>null</code> or empty.
143   */
144  public static AlgorithmParameters getInstance(String algorithm,
145                                                String provider)
146      throws NoSuchAlgorithmException, NoSuchProviderException
147  {
148    if (provider == null)
149      throw new IllegalArgumentException("provider MUST NOT be null");
150    provider = provider.trim();
151    if (provider.length() == 0)
152      throw new IllegalArgumentException("provider MUST NOT be empty");
153    Provider p = Security.getProvider(provider);
154    if (p == null)
155      throw new NoSuchProviderException(provider);
156    return getInstance(algorithm, p);
157  }
158
159  /**
160   * Returns a new instance of <code>AlgorithmParameters</code> representing
161   * the specified algorithm parameters from the specified {@link Provider}.
162   * <p>
163   * The returned <code>AlgorithmParameters</code> must still be intialized
164   * with an <code>init()</code> method.
165   * 
166   * @param algorithm the algorithm to use.
167   * @param provider the {@link Provider} to use.
168   * @return the new instance repesenting the desired algorithm.
169   * @throws NoSuchAlgorithmException if the algorithm is not implemented by the
170   *           {@link Provider}.
171   * @throws IllegalArgumentException if either <code>algorithm</code> or
172   *           <code>provider</code> is <code>null</code>, or if
173   *           <code>algorithm</code> is an empty string.
174   * @since 1.4
175   */
176  public static AlgorithmParameters getInstance(String algorithm,
177                                                Provider provider)
178      throws NoSuchAlgorithmException
179  {
180    CPStringBuilder sb = new CPStringBuilder("AlgorithmParameters for algorithm [")
181        .append(algorithm).append("] from provider[")
182        .append(provider).append("] could not be created");
183    Throwable cause;
184    try
185      {
186        Object spi = Engine.getInstance(ALGORITHM_PARAMETERS, algorithm, provider);
187        return new AlgorithmParameters((AlgorithmParametersSpi) spi,
188                                       provider,
189                                       algorithm);
190      }
191    catch (InvocationTargetException x)
192      {
193        cause = x.getCause();
194        if (cause instanceof NoSuchAlgorithmException)
195          throw (NoSuchAlgorithmException) cause;
196        if (cause == null)
197          cause = x;
198      }
199    catch (ClassCastException x)
200      {
201        cause = x;
202      }
203    NoSuchAlgorithmException x = new NoSuchAlgorithmException(sb.toString());
204    x.initCause(cause);
205    throw x;
206  }
207
208  /** @return the provider of this parameter object. */
209  public final Provider getProvider()
210  {
211    return provider;
212  }
213
214  /**
215   * Initializes the engine with the specified {@link AlgorithmParameterSpec}.
216   * 
217   * @param paramSpec
218   *          A {@link AlgorithmParameterSpec} to use.
219   * @throws InvalidParameterSpecException
220   *           if <code>paramSpec</code> is invalid.
221   */
222  public final void init(AlgorithmParameterSpec paramSpec)
223    throws InvalidParameterSpecException
224  {
225    paramSpi.engineInit(paramSpec);
226  }
227
228  /**
229   * Initializes the engine with the specified parameters stored in the byte
230   * array and decodes them according to the ASN.1 specification. If the ASN.1
231   * specification exists then it succeeds otherwise an {@link IOException} is
232   * thrown.
233   * 
234   * @param params
235   *          the parameters to use.
236   * @throws IOException
237   *           if a decoding error occurs.
238   */
239  public final void init(byte[]params) throws IOException
240  {
241    paramSpi.engineInit(params);
242  }
243
244  /**
245   * Initializes the engine with the specified parameters stored in the byte
246   * array and decodes them according to the specified decoding specification.
247   * If <code>format</code> is <code>null</code>, then this method decodes the
248   * byte array using the ASN.1 specification if it exists, otherwise it throws
249   * an {@link IOException}.
250   * 
251   * @param params
252   *          the parameters to use.
253   * @param format
254   *          the name of decoding format to use.
255   * @throws IOException
256   *           if a decoding error occurs.
257   */
258  public final void init(byte[]params, String format) throws IOException
259  {
260    paramSpi.engineInit(params, format);
261  }
262
263  /**
264   * Returns a new instance of <code>AlgorithmParameters</code> as a
265   * designated parameter specification {@link Class}.
266   * 
267   * @param paramSpec
268   *          the {@link Class} to use.
269   * @return the parameter specification.
270   * @throws InvalidParameterSpecException
271   *           if <code>paramSpec</code> is invalid.
272   */
273  public final <T extends AlgorithmParameterSpec>
274  T getParameterSpec(Class<T> paramSpec)
275    throws InvalidParameterSpecException
276  {
277    return paramSpi.engineGetParameterSpec(paramSpec);
278  }
279
280  /**
281   * Returns the parameters in the default encoding format. The primary encoding
282   * format is ASN.1 if it exists for the specified type.
283   * 
284   * @return byte array representing the parameters.
285   */
286  public final byte[] getEncoded() throws IOException
287  {
288    return paramSpi.engineGetEncoded();
289  }
290
291  /**
292   * Returns the parameters in the specified encoding format. If
293   * <code>format</code> is <code>null</code> then the ASN.1 encoding
294   * format is used if it exists for the specified type.
295   * 
296   * @param format
297   *          the name of the encoding format to use.
298   * @return the parameters encoded using the specified encoding scheme.
299   * @throws IOException
300   *           if an encoding exception occurs, or if this parameter object has
301   *           not been initialized.
302   */
303  public final byte[] getEncoded(String format) throws IOException
304  {
305    return paramSpi.engineGetEncoded(format);
306  }
307
308  /**
309   * Returns a string representation of the encoded form.
310   * 
311   * @return a string representation of the encoded form.
312   */
313  public final String toString()
314  {
315    return paramSpi.engineToString();
316  }
317}