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.security.spec.AlgorithmParameterSpec;
29 
30 /**
31  * The {@code AlgorithmParameterGenerator} class is used to generate a
32  * set of
33  * parameters to be used with a certain algorithm. Parameter generators
34  * are constructed using the {@code getInstance} factory methods
35  * (static methods that return instances of a given class).
36  *
37  * <P>The object that will generate the parameters can be initialized
38  * in two different ways: in an algorithm-independent manner, or in an
39  * algorithm-specific manner:
40  *
41  * <ul>
42  * <li>The algorithm-independent approach uses the fact that all parameter
43  * generators share the concept of a "size" and a
44  * source of randomness. The measure of size is universally shared
45  * by all algorithm parameters, though it is interpreted differently
46  * for different algorithms. For example, in the case of parameters for
47  * the <i>DSA</i> algorithm, "size" corresponds to the size
48  * of the prime modulus (in bits).
49  * When using this approach, algorithm-specific parameter generation
50  * values - if any - default to some standard values, unless they can be
51  * derived from the specified size.
52  *
53  * <li>The other approach initializes a parameter generator object
54  * using algorithm-specific semantics, which are represented by a set of
55  * algorithm-specific parameter generation values. To generate
56  * Diffie-Hellman system parameters, for example, the parameter generation
57  * values usually
58  * consist of the size of the prime modulus and the size of the
59  * random exponent, both specified in number of bits.
60  * </ul>
61  *
62  * <P>In case the client does not explicitly initialize the
63  * AlgorithmParameterGenerator
64  * (via a call to an {@code init} method), each provider must supply (and
65  * document) a default initialization. For example, the Sun provider uses a
66  * default modulus prime size of 1024 bits for the generation of DSA
67  * parameters.
68  *
69  * <p> Android provides the following <code>AlgorithmParameterGenerator</code> algorithms:
70  * <table>
71  *   <thead>
72  *     <tr>
73  *       <th>Algorithm</th>
74  *       <th>Supported API Levels</th>
75  *     </tr>
76  *   </thead>
77  *   <tbody>
78  *     <tr class="deprecated">
79  *       <td>AES</td>
80  *       <td>1-8</td>
81  *     </tr>
82  *     <tr class="deprecated">
83  *       <td>DES</td>
84  *       <td>1-8</td>
85  *     </tr>
86  *     <tr class="deprecated">
87  *       <td>DESede</td>
88  *       <td>1-8</td>
89  *     </tr>
90  *     <tr>
91  *       <td>DH</td>
92  *       <td>1+</td>
93  *     </tr>
94  *     <tr>
95  *       <td>DSA</td>
96  *       <td>1+</td>
97  *     </tr>
98  *   </tbody>
99  * </table>
100  *
101  * These algorithms are described in the <a href=
102  * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#AlgorithmParameterGenerator">
103  * AlgorithmParameterGenerator section</a> of the
104  * Java Cryptography Architecture Standard Algorithm Name Documentation.
105  *
106  * @author Jan Luehe
107  *
108  *
109  * @see AlgorithmParameters
110  * @see java.security.spec.AlgorithmParameterSpec
111  *
112  * @since 1.2
113  */
114 
115 public class AlgorithmParameterGenerator {
116 
117     // The provider
118     private Provider provider;
119 
120     // The provider implementation (delegate)
121     private AlgorithmParameterGeneratorSpi paramGenSpi;
122 
123     // The algorithm
124     private String algorithm;
125 
126     /**
127      * Creates an AlgorithmParameterGenerator object.
128      *
129      * @param paramGenSpi the delegate
130      * @param provider the provider
131      * @param algorithm the algorithm
132      */
AlgorithmParameterGenerator(AlgorithmParameterGeneratorSpi paramGenSpi, Provider provider, String algorithm)133     protected AlgorithmParameterGenerator
134     (AlgorithmParameterGeneratorSpi paramGenSpi, Provider provider,
135      String algorithm) {
136         this.paramGenSpi = paramGenSpi;
137         this.provider = provider;
138         this.algorithm = algorithm;
139     }
140 
141     /**
142      * Returns the standard name of the algorithm this parameter
143      * generator is associated with.
144      *
145      * @return the string name of the algorithm.
146      */
getAlgorithm()147     public final String getAlgorithm() {
148         return this.algorithm;
149     }
150 
151     /**
152      * Returns an AlgorithmParameterGenerator object for generating
153      * a set of parameters to be used with the specified algorithm.
154      *
155      * <p> This method traverses the list of registered security Providers,
156      * starting with the most preferred Provider.
157      * A new AlgorithmParameterGenerator object encapsulating the
158      * AlgorithmParameterGeneratorSpi implementation from the first
159      * Provider that supports the specified algorithm is returned.
160      *
161      * <p> Note that the list of registered providers may be retrieved via
162      * the {@link Security#getProviders() Security.getProviders()} method.
163      *
164      * @param algorithm the name of the algorithm this
165      * parameter generator is associated with.
166      * See the AlgorithmParameterGenerator section in the <a href=
167      * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#AlgorithmParameterGenerator">
168      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
169      * for information about standard algorithm names.
170      *
171      * @return the new AlgorithmParameterGenerator object.
172      *
173      * @exception NoSuchAlgorithmException if no Provider supports an
174      *          AlgorithmParameterGeneratorSpi implementation for the
175      *          specified algorithm.
176      *
177      * @see Provider
178      */
getInstance(String algorithm)179     public static AlgorithmParameterGenerator getInstance(String algorithm)
180         throws NoSuchAlgorithmException {
181             try {
182                 Object[] objs = Security.getImpl(algorithm,
183                                                  "AlgorithmParameterGenerator",
184                                                  (String)null);
185                 return new AlgorithmParameterGenerator
186                     ((AlgorithmParameterGeneratorSpi)objs[0],
187                      (Provider)objs[1],
188                      algorithm);
189             } catch(NoSuchProviderException e) {
190                 throw new NoSuchAlgorithmException(algorithm + " not found");
191             }
192     }
193 
194     /**
195      * Returns an AlgorithmParameterGenerator object for generating
196      * a set of parameters to be used with the specified algorithm.
197      *
198      * <p> A new AlgorithmParameterGenerator object encapsulating the
199      * AlgorithmParameterGeneratorSpi implementation from the specified provider
200      * is returned.  The specified provider must be registered
201      * in the security provider list.
202      *
203      * <p> Note that the list of registered providers may be retrieved via
204      * the {@link Security#getProviders() Security.getProviders()} method.
205      *
206      * @param algorithm the name of the algorithm this
207      * parameter generator is associated with.
208      * See the AlgorithmParameterGenerator section in the <a href=
209      * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#AlgorithmParameterGenerator">
210      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
211      * for information about standard algorithm names.
212      *
213      * @param provider the string name of the Provider.
214      *
215      * @return the new AlgorithmParameterGenerator object.
216      *
217      * @exception NoSuchAlgorithmException if an AlgorithmParameterGeneratorSpi
218      *          implementation for the specified algorithm is not
219      *          available from the specified provider.
220      *
221      * @exception NoSuchProviderException if the specified provider is not
222      *          registered in the security provider list.
223      *
224      * @exception IllegalArgumentException if the provider name is null
225      *          or empty.
226      *
227      * @see Provider
228      */
getInstance(String algorithm, String provider)229     public static AlgorithmParameterGenerator getInstance(String algorithm,
230                                                           String provider)
231         throws NoSuchAlgorithmException, NoSuchProviderException
232     {
233         if (provider == null || provider.length() == 0)
234             throw new IllegalArgumentException("missing provider");
235         Object[] objs = Security.getImpl(algorithm,
236                                          "AlgorithmParameterGenerator",
237                                          provider);
238         return new AlgorithmParameterGenerator
239             ((AlgorithmParameterGeneratorSpi)objs[0], (Provider)objs[1],
240              algorithm);
241     }
242 
243     /**
244      * Returns an AlgorithmParameterGenerator object for generating
245      * a set of parameters to be used with the specified algorithm.
246      *
247      * <p> A new AlgorithmParameterGenerator object encapsulating the
248      * AlgorithmParameterGeneratorSpi implementation from the specified Provider
249      * object is returned.  Note that the specified Provider object
250      * does not have to be registered in the provider list.
251      *
252      * @param algorithm the string name of the algorithm this
253      * parameter generator is associated with.
254      * See the AlgorithmParameterGenerator section in the <a href=
255      * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#AlgorithmParameterGenerator">
256      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
257      * for information about standard algorithm names.
258      *
259      * @param provider the Provider object.
260      *
261      * @return the new AlgorithmParameterGenerator object.
262      *
263      * @exception NoSuchAlgorithmException if an AlgorithmParameterGeneratorSpi
264      *          implementation for the specified algorithm is not available
265      *          from the specified Provider object.
266      *
267      * @exception IllegalArgumentException if the specified provider is null.
268      *
269      * @see Provider
270      *
271      * @since 1.4
272      */
getInstance(String algorithm, Provider provider)273     public static AlgorithmParameterGenerator getInstance(String algorithm,
274                                                           Provider provider)
275         throws NoSuchAlgorithmException
276     {
277         if (provider == null)
278             throw new IllegalArgumentException("missing provider");
279         Object[] objs = Security.getImpl(algorithm,
280                                          "AlgorithmParameterGenerator",
281                                          provider);
282         return new AlgorithmParameterGenerator
283             ((AlgorithmParameterGeneratorSpi)objs[0], (Provider)objs[1],
284              algorithm);
285     }
286 
287     /**
288      * Returns the provider of this algorithm parameter generator object.
289      *
290      * @return the provider of this algorithm parameter generator object
291      */
getProvider()292     public final Provider getProvider() {
293         return this.provider;
294     }
295 
296     /**
297      * Initializes this parameter generator for a certain size.
298      * To create the parameters, the {@code SecureRandom}
299      * implementation of the highest-priority installed provider is used as
300      * the source of randomness.
301      * (If none of the installed providers supply an implementation of
302      * {@code SecureRandom}, a system-provided source of randomness is
303      * used.)
304      *
305      * @param size the size (number of bits).
306      */
init(int size)307     public final void init(int size) {
308         paramGenSpi.engineInit(size, new SecureRandom());
309     }
310 
311     /**
312      * Initializes this parameter generator for a certain size and source
313      * of randomness.
314      *
315      * @param size the size (number of bits).
316      * @param random the source of randomness.
317      */
init(int size, SecureRandom random)318     public final void init(int size, SecureRandom random) {
319         paramGenSpi.engineInit(size, random);
320     }
321 
322     /**
323      * Initializes this parameter generator with a set of algorithm-specific
324      * parameter generation values.
325      * To generate the parameters, the {@code SecureRandom}
326      * implementation of the highest-priority installed provider is used as
327      * the source of randomness.
328      * (If none of the installed providers supply an implementation of
329      * {@code SecureRandom}, a system-provided source of randomness is
330      * used.)
331      *
332      * @param genParamSpec the set of algorithm-specific parameter generation values.
333      *
334      * @exception InvalidAlgorithmParameterException if the given parameter
335      * generation values are inappropriate for this parameter generator.
336      */
init(AlgorithmParameterSpec genParamSpec)337     public final void init(AlgorithmParameterSpec genParamSpec)
338         throws InvalidAlgorithmParameterException {
339             paramGenSpi.engineInit(genParamSpec, new SecureRandom());
340     }
341 
342     /**
343      * Initializes this parameter generator with a set of algorithm-specific
344      * parameter generation values.
345      *
346      * @param genParamSpec the set of algorithm-specific parameter generation values.
347      * @param random the source of randomness.
348      *
349      * @exception InvalidAlgorithmParameterException if the given parameter
350      * generation values are inappropriate for this parameter generator.
351      */
init(AlgorithmParameterSpec genParamSpec, SecureRandom random)352     public final void init(AlgorithmParameterSpec genParamSpec,
353                            SecureRandom random)
354         throws InvalidAlgorithmParameterException {
355             paramGenSpi.engineInit(genParamSpec, random);
356     }
357 
358     /**
359      * Generates the parameters.
360      *
361      * @return the new AlgorithmParameters object.
362      */
generateParameters()363     public final AlgorithmParameters generateParameters() {
364         return paramGenSpi.engineGenerateParameters();
365     }
366 }
367