1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package java.security;
19
20import java.security.spec.AlgorithmParameterSpec;
21
22import org.apache.harmony.security.fortress.Engine;
23import org.apache.harmony.security.internal.nls.Messages;
24
25/**
26 * {@code AlgorithmParameterGenerator} is an engine class which is capable of
27 * generating parameters for the algorithm it was initialized with.
28 */
29public class AlgorithmParameterGenerator {
30
31    // Store spi service name
32    private static final String SERVICE = "AlgorithmParameterGenerator"; //$NON-NLS-1$
33
34    // Used to access common engine functionality
35    private static Engine engine = new Engine(SERVICE);
36
37    // Store SecureRandom
38    private static SecureRandom randm = new SecureRandom();
39
40    // Store used provider
41    private final Provider provider;
42
43    // Store used AlgorithmParameterGeneratorSpi implementation
44    private final AlgorithmParameterGeneratorSpi spiImpl;
45
46    //Store used algorithm
47    private final String algorithm;
48
49    /**
50     * Constructs a new instance of {@code AlgorithmParameterGenerator} with the
51     * given arguments.
52     *
53     * @param paramGenSpi
54     *            a concrete implementation, this engine instance delegates to.
55     * @param provider
56     *            the provider.
57     * @param algorithm
58     *            the name of the algorithm.
59     */
60    protected AlgorithmParameterGenerator(
61            AlgorithmParameterGeneratorSpi paramGenSpi, Provider provider,
62            String algorithm) {
63        this.provider = provider;
64        this.algorithm = algorithm;
65        this.spiImpl = paramGenSpi;
66    }
67
68    /**
69     * Returns the name of the algorithm.
70     *
71     * @return the name of the algorithm.
72     */
73    public final String getAlgorithm() {
74        return algorithm;
75    }
76
77    /**
78     * Returns a new instance of {@code AlgorithmParameterGenerator} for the
79     * specified algorithm.
80     *
81     * @param algorithm
82     *            the name of the algorithm to use.
83     * @return a new instance of {@code AlgorithmParameterGenerator} for the
84     *         specified algorithm.
85     * @throws NoSuchAlgorithmException
86     *             if the specified algorithm is not available.
87     * @throws NullPointerException
88     *             if {@code algorithm} is {@code null}.
89     */
90    public static AlgorithmParameterGenerator getInstance(String algorithm)
91            throws NoSuchAlgorithmException {
92        if (algorithm == null) {
93            throw new NullPointerException(Messages.getString("security.01")); //$NON-NLS-1$
94        }
95        synchronized (engine) {
96            engine.getInstance(algorithm, null);
97            return new AlgorithmParameterGenerator(
98                    (AlgorithmParameterGeneratorSpi) engine.spi, engine.provider,
99                    algorithm);
100        }
101    }
102
103    /**
104     * Returns a new instance of {@code AlgorithmParameterGenerator} from the
105     * specified provider for the specified algorithm.
106     *
107     * @param algorithm
108     *            the name of the algorithm to use.
109     * @param provider
110     *            name of the provider of the {@code
111     *            AlgorithmParameterGenerator}.
112     * @return a new instance of {@code AlgorithmParameterGenerator} for the
113     *         specified algorithm.
114     * @throws NoSuchAlgorithmException
115     *             if the specified algorithm is not available.
116     * @throws NoSuchProviderException
117     *             if the specified provider is not available.
118     * @throws NullPointerException
119     *             if {@code algorithm} is {@code null}.
120     */
121    public static AlgorithmParameterGenerator getInstance(String algorithm,
122            String provider) throws NoSuchAlgorithmException,
123            NoSuchProviderException {
124        if ((provider == null) || (provider.length() == 0)) {
125            throw new IllegalArgumentException(
126                    Messages.getString("security.02")); //$NON-NLS-1$
127        }
128        Provider impProvider = Security.getProvider(provider);
129        if (impProvider == null) {
130            throw new NoSuchProviderException(provider);
131        }
132        return getInstance(algorithm, impProvider);
133    }
134
135    /**
136     * Returns a new instance of {@code AlgorithmParameterGenerator} from the
137     * specified provider for the specified algorithm.
138     *
139     * @param algorithm
140     *            the name of the algorithm to use.
141     * @param provider
142     *            the provider of the {@code AlgorithmParameterGenerator}.
143     * @return a new instance of {@code AlgorithmParameterGenerator} for the
144     *         specified algorithm.
145     * @throws NoSuchAlgorithmException
146     *             if the specified algorithm is not available.
147     * @throws NullPointerException
148     *             if {@code algorithm} is {@code null}.
149     */
150    public static AlgorithmParameterGenerator getInstance(String algorithm,
151            Provider provider) throws NoSuchAlgorithmException {
152        if (provider == null) {
153            throw new IllegalArgumentException(Messages.getString("security.04")); //$NON-NLS-1$
154        }
155        if (algorithm == null) {
156            throw new NullPointerException(Messages.getString("security.01")); //$NON-NLS-1$
157        }
158        synchronized (engine) {
159            engine.getInstance(algorithm, provider, null);
160            return new AlgorithmParameterGenerator(
161                    (AlgorithmParameterGeneratorSpi) engine.spi, provider,
162                    algorithm);
163        }
164    }
165
166    /**
167     * Returns the provider associated with this {@code
168     * AlgorithmParameterGenerator}.
169     *
170     * @return the provider associated with this {@code
171     *         AlgorithmParameterGenerator}.
172     */
173    public final Provider getProvider() {
174        return provider;
175    }
176
177    /**
178     * Initializes this {@code AlgorithmParameterGenerator} with the given size.
179     * The default parameter set and a default {@code SecureRandom} instance
180     * will be used.
181     *
182     * @param size
183     *            the size (in number of bits).
184     */
185    public final void init(int size) {
186        spiImpl.engineInit(size, randm);
187    }
188
189    /**
190     * Initializes this {@code AlgorithmParameterGenerator} with the given size
191     * and the given {@code SecureRandom}. The default parameter set will be
192     * used.
193     *
194     * @param size
195     *            the size (in number of bits).
196     * @param random
197     *            the source of randomness.
198     */
199    public final void init(int size, SecureRandom random) {
200        spiImpl.engineInit(size, random);
201    }
202
203    /**
204     * Initializes this {@code AlgorithmParameterGenerator} with the given {@code
205     * AlgorithmParameterSpec}. A default {@code SecureRandom} instance will be
206     * used.
207     *
208     * @param genParamSpec
209     *            the parameters to use.
210     * @throws InvalidAlgorithmParameterException
211     *             if the specified parameters are not supported.
212     */
213    public final void init(AlgorithmParameterSpec genParamSpec)
214            throws InvalidAlgorithmParameterException {
215        spiImpl.engineInit(genParamSpec, randm);
216    }
217
218    /**
219     * Initializes this {@code AlgorithmParameterGenerator} with the given
220     * {@code AlgorithmParameterSpec} and the given {@code SecureRandom}.
221     *
222     * @param genParamSpec
223     *            the parameters to use.
224     * @param random
225     *            the source of randomness.
226     * @throws InvalidAlgorithmParameterException
227     *             if the specified parameters are not supported.
228     */
229    public final void init(AlgorithmParameterSpec genParamSpec,
230            SecureRandom random) throws InvalidAlgorithmParameterException {
231        spiImpl.engineInit(genParamSpec, random);
232    }
233
234    /**
235     * Computes and returns {@code AlgorithmParameters} for this generator's
236     * algorithm.
237     *
238     * @return {@code AlgorithmParameters} for this generator's algorithm.
239     */
240    public final AlgorithmParameters generateParameters() {
241        return spiImpl.engineGenerateParameters();
242    }
243}
244