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