View Javadoc
1   /*
2    * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  
26  package java.security;
27  
28  import java.io.*;
29  import java.security.spec.AlgorithmParameterSpec;
30  import java.security.spec.InvalidParameterSpecException;
31  
32  /**
33   * This class is used as an opaque representation of cryptographic parameters.
34   *
35   * <p>An {@code AlgorithmParameters} object for managing the parameters
36   * for a particular algorithm can be obtained by
37   * calling one of the {@code getInstance} factory methods
38   * (static methods that return instances of a given class).
39   *
40   * <p>Once an {@code AlgorithmParameters} object is obtained, it must be
41   * initialized via a call to {@code init}, using an appropriate parameter
42   * specification or parameter encoding.
43   *
44   * <p>A transparent parameter specification is obtained from an
45   * {@code AlgorithmParameters} object via a call to
46   * {@code getParameterSpec}, and a byte encoding of the parameters is
47   * obtained via a call to {@code getEncoded}.
48   *
49   * <p> Every implementation of the Java platform is required to support the
50   * following standard {@code AlgorithmParameters} algorithms:
51   * <ul>
52   * <li>{@code AES}</li>
53   * <li>{@code DES}</li>
54   * <li>{@code DESede}</li>
55   * <li>{@code DiffieHellman}</li>
56   * <li>{@code DSA}</li>
57   * </ul>
58   * These algorithms are described in the <a href=
59   * "{@docRoot}/../technotes/guides/security/StandardNames.html#AlgorithmParameters">
60   * AlgorithmParameters section</a> of the
61   * Java Cryptography Architecture Standard Algorithm Name Documentation.
62   * Consult the release documentation for your implementation to see if any
63   * other algorithms are supported.
64   *
65   * @author Jan Luehe
66   *
67   *
68   * @see java.security.spec.AlgorithmParameterSpec
69   * @see java.security.spec.DSAParameterSpec
70   * @see KeyPairGenerator
71   *
72   * @since 1.2
73   */
74  
75  public class AlgorithmParameters {
76  
77      // The provider
78      private Provider provider;
79  
80      // The provider implementation (delegate)
81      private AlgorithmParametersSpi paramSpi;
82  
83      // The algorithm
84      private String algorithm;
85  
86      // Has this object been initialized?
87      private boolean initialized = false;
88  
89      /**
90       * Creates an AlgorithmParameters object.
91       *
92       * @param paramSpi the delegate
93       * @param provider the provider
94       * @param algorithm the algorithm
95       */
96      protected AlgorithmParameters(AlgorithmParametersSpi paramSpi,
97                                    Provider provider, String algorithm)
98      {
99          this.paramSpi = paramSpi;
100         this.provider = provider;
101         this.algorithm = algorithm;
102     }
103 
104     /**
105      * Returns the name of the algorithm associated with this parameter object.
106      *
107      * @return the algorithm name.
108      */
109     public final String getAlgorithm() {
110         return this.algorithm;
111     }
112 
113     /**
114      * Returns a parameter object for the specified algorithm.
115      *
116      * <p> This method traverses the list of registered security Providers,
117      * starting with the most preferred Provider.
118      * A new AlgorithmParameters object encapsulating the
119      * AlgorithmParametersSpi implementation from the first
120      * Provider that supports the specified algorithm is returned.
121      *
122      * <p> Note that the list of registered providers may be retrieved via
123      * the {@link Security#getProviders() Security.getProviders()} method.
124      *
125      * <p> The returned parameter object must be initialized via a call to
126      * {@code init}, using an appropriate parameter specification or
127      * parameter encoding.
128      *
129      * @param algorithm the name of the algorithm requested.
130      * See the AlgorithmParameters section in the <a href=
131      * "{@docRoot}/../technotes/guides/security/StandardNames.html#AlgorithmParameters">
132      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
133      * for information about standard algorithm names.
134      *
135      * @return the new parameter object.
136      *
137      * @exception NoSuchAlgorithmException if no Provider supports an
138      *          AlgorithmParametersSpi implementation for the
139      *          specified algorithm.
140      *
141      * @see Provider
142      */
143     public static AlgorithmParameters getInstance(String algorithm)
144     throws NoSuchAlgorithmException {
145         try {
146             Object[] objs = Security.getImpl(algorithm, "AlgorithmParameters",
147                                              (String)null);
148             return new AlgorithmParameters((AlgorithmParametersSpi)objs[0],
149                                            (Provider)objs[1],
150                                            algorithm);
151         } catch(NoSuchProviderException e) {
152             throw new NoSuchAlgorithmException(algorithm + " not found");
153         }
154     }
155 
156     /**
157      * Returns a parameter object for the specified algorithm.
158      *
159      * <p> A new AlgorithmParameters object encapsulating the
160      * AlgorithmParametersSpi implementation from the specified provider
161      * is returned.  The specified provider must be registered
162      * in the security provider list.
163      *
164      * <p> Note that the list of registered providers may be retrieved via
165      * the {@link Security#getProviders() Security.getProviders()} method.
166      *
167      * <p>The returned parameter object must be initialized via a call to
168      * {@code init}, using an appropriate parameter specification or
169      * parameter encoding.
170      *
171      * @param algorithm the name of the algorithm requested.
172      * See the AlgorithmParameters section in the <a href=
173      * "{@docRoot}/../technotes/guides/security/StandardNames.html#AlgorithmParameters">
174      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
175      * for information about standard algorithm names.
176      *
177      * @param provider the name of the provider.
178      *
179      * @return the new parameter object.
180      *
181      * @exception NoSuchAlgorithmException if an AlgorithmParametersSpi
182      *          implementation for the specified algorithm is not
183      *          available from the specified provider.
184      *
185      * @exception NoSuchProviderException if the specified provider is not
186      *          registered in the security provider list.
187      *
188      * @exception IllegalArgumentException if the provider name is null
189      *          or empty.
190      *
191      * @see Provider
192      */
193     public static AlgorithmParameters getInstance(String algorithm,
194                                                   String provider)
195         throws NoSuchAlgorithmException, NoSuchProviderException
196     {
197         if (provider == null || provider.length() == 0)
198             throw new IllegalArgumentException("missing provider");
199         Object[] objs = Security.getImpl(algorithm, "AlgorithmParameters",
200                                          provider);
201         return new AlgorithmParameters((AlgorithmParametersSpi)objs[0],
202                                        (Provider)objs[1],
203                                        algorithm);
204     }
205 
206     /**
207      * Returns a parameter object for the specified algorithm.
208      *
209      * <p> A new AlgorithmParameters object encapsulating the
210      * AlgorithmParametersSpi implementation from the specified Provider
211      * object is returned.  Note that the specified Provider object
212      * does not have to be registered in the provider list.
213      *
214      * <p>The returned parameter object must be initialized via a call to
215      * {@code init}, using an appropriate parameter specification or
216      * parameter encoding.
217      *
218      * @param algorithm the name of the algorithm requested.
219      * See the AlgorithmParameters section in the <a href=
220      * "{@docRoot}/../technotes/guides/security/StandardNames.html#AlgorithmParameters">
221      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
222      * for information about standard algorithm names.
223      *
224      * @param provider the name of the provider.
225      *
226      * @return the new parameter object.
227      *
228      * @exception NoSuchAlgorithmException if an AlgorithmParameterGeneratorSpi
229      *          implementation for the specified algorithm is not available
230      *          from the specified Provider object.
231      *
232      * @exception IllegalArgumentException if the provider is null.
233      *
234      * @see Provider
235      *
236      * @since 1.4
237      */
238     public static AlgorithmParameters getInstance(String algorithm,
239                                                   Provider provider)
240         throws NoSuchAlgorithmException
241     {
242         if (provider == null)
243             throw new IllegalArgumentException("missing provider");
244         Object[] objs = Security.getImpl(algorithm, "AlgorithmParameters",
245                                          provider);
246         return new AlgorithmParameters((AlgorithmParametersSpi)objs[0],
247                                        (Provider)objs[1],
248                                        algorithm);
249     }
250 
251     /**
252      * Returns the provider of this parameter object.
253      *
254      * @return the provider of this parameter object
255      */
256     public final Provider getProvider() {
257         return this.provider;
258     }
259 
260     /**
261      * Initializes this parameter object using the parameters
262      * specified in {@code paramSpec}.
263      *
264      * @param paramSpec the parameter specification.
265      *
266      * @exception InvalidParameterSpecException if the given parameter
267      * specification is inappropriate for the initialization of this parameter
268      * object, or if this parameter object has already been initialized.
269      */
270     public final void init(AlgorithmParameterSpec paramSpec)
271         throws InvalidParameterSpecException
272     {
273         if (this.initialized)
274             throw new InvalidParameterSpecException("already initialized");
275         paramSpi.engineInit(paramSpec);
276         this.initialized = true;
277     }
278 
279     /**
280      * Imports the specified parameters and decodes them according to the
281      * primary decoding format for parameters. The primary decoding
282      * format for parameters is ASN.1, if an ASN.1 specification for this type
283      * of parameters exists.
284      *
285      * @param params the encoded parameters.
286      *
287      * @exception IOException on decoding errors, or if this parameter object
288      * has already been initialized.
289      */
290     public final void init(byte[] params) throws IOException {
291         if (this.initialized)
292             throw new IOException("already initialized");
293         paramSpi.engineInit(params);
294         this.initialized = true;
295     }
296 
297     /**
298      * Imports the parameters from {@code params} and decodes them
299      * according to the specified decoding scheme.
300      * If {@code format} is null, the
301      * primary decoding format for parameters is used. The primary decoding
302      * format is ASN.1, if an ASN.1 specification for these parameters
303      * exists.
304      *
305      * @param params the encoded parameters.
306      *
307      * @param format the name of the decoding scheme.
308      *
309      * @exception IOException on decoding errors, or if this parameter object
310      * has already been initialized.
311      */
312     public final void init(byte[] params, String format) throws IOException {
313         if (this.initialized)
314             throw new IOException("already initialized");
315         paramSpi.engineInit(params, format);
316         this.initialized = true;
317     }
318 
319     /**
320      * Returns a (transparent) specification of this parameter object.
321      * {@code paramSpec} identifies the specification class in which
322      * the parameters should be returned. It could, for example, be
323      * {@code DSAParameterSpec.class}, to indicate that the
324      * parameters should be returned in an instance of the
325      * {@code DSAParameterSpec} class.
326      *
327      * @param <T> the type of the parameter specification to be returrned
328      * @param paramSpec the specification class in which
329      * the parameters should be returned.
330      *
331      * @return the parameter specification.
332      *
333      * @exception InvalidParameterSpecException if the requested parameter
334      * specification is inappropriate for this parameter object, or if this
335      * parameter object has not been initialized.
336      */
337     public final <T extends AlgorithmParameterSpec>
338         T getParameterSpec(Class<T> paramSpec)
339         throws InvalidParameterSpecException
340     {
341         if (this.initialized == false) {
342             throw new InvalidParameterSpecException("not initialized");
343         }
344         return paramSpi.engineGetParameterSpec(paramSpec);
345     }
346 
347     /**
348      * Returns the parameters in their primary encoding format.
349      * The primary encoding format for parameters is ASN.1, if an ASN.1
350      * specification for this type of parameters exists.
351      *
352      * @return the parameters encoded using their primary encoding format.
353      *
354      * @exception IOException on encoding errors, or if this parameter object
355      * has not been initialized.
356      */
357     public final byte[] getEncoded() throws IOException
358     {
359         if (this.initialized == false) {
360             throw new IOException("not initialized");
361         }
362         return paramSpi.engineGetEncoded();
363     }
364 
365     /**
366      * Returns the parameters encoded in the specified scheme.
367      * If {@code format} is null, the
368      * primary encoding format for parameters is used. The primary encoding
369      * format is ASN.1, if an ASN.1 specification for these parameters
370      * exists.
371      *
372      * @param format the name of the encoding format.
373      *
374      * @return the parameters encoded using the specified encoding scheme.
375      *
376      * @exception IOException on encoding errors, or if this parameter object
377      * has not been initialized.
378      */
379     public final byte[] getEncoded(String format) throws IOException
380     {
381         if (this.initialized == false) {
382             throw new IOException("not initialized");
383         }
384         return paramSpi.engineGetEncoded(format);
385     }
386 
387     /**
388      * Returns a formatted string describing the parameters.
389      *
390      * @return a formatted string describing the parameters, or null if this
391      * parameter object has not been initialized.
392      */
393     public final String toString() {
394         if (this.initialized == false) {
395             return null;
396         }
397         return paramSpi.engineToString();
398     }
399 }