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.lang.CPStringBuilder;
042
043 import gnu.java.security.Engine;
044
045 import java.lang.reflect.InvocationTargetException;
046 import java.security.spec.AlgorithmParameterSpec;
047
048 /**
049 * <code>KeyPairGenerator</code> is a class used to generate key-pairs for a
050 * security algorithm.
051 *
052 * <p>The <code>KeyPairGenerator</code> is created with the
053 * <code>getInstance()</code> Factory methods. It is used to generate a pair of
054 * public and private keys for a specific algorithm and associate this key-pair
055 * with the algorithm parameters it was initialized with.</p>
056 *
057 * @see KeyPair
058 * @see AlgorithmParameterSpec
059 * @author Mark Benvenuto
060 * @author Casey Marshall
061 */
062 public abstract class KeyPairGenerator extends KeyPairGeneratorSpi
063 {
064 /** The service name for key pair generators. */
065 private static final String KEY_PAIR_GENERATOR = "KeyPairGenerator";
066
067 Provider provider;
068 private String algorithm;
069
070 /**
071 * Constructs a new instance of <code>KeyPairGenerator</code>.
072 *
073 * @param algorithm
074 * the algorithm to use.
075 */
076 protected KeyPairGenerator(String algorithm)
077 {
078 this.algorithm = algorithm;
079 this.provider = null;
080 }
081
082 /**
083 * Returns the name of the algorithm used.
084 *
085 * @return the name of the algorithm used.
086 */
087 public String getAlgorithm()
088 {
089 return algorithm;
090 }
091
092 /**
093 * Returns a new instance of <code>KeyPairGenerator</code> which generates
094 * key-pairs for the specified algorithm.
095 *
096 * @param algorithm the name of the algorithm to use.
097 * @return a new instance repesenting the desired algorithm.
098 * @throws NoSuchAlgorithmException if the algorithm is not implemented by any
099 * provider.
100 * @throws IllegalArgumentException if <code>algorithm</code> is
101 * <code>null</code> or is an empty string.
102 */
103 public static KeyPairGenerator getInstance(String algorithm)
104 throws NoSuchAlgorithmException
105 {
106 Provider[] p = Security.getProviders();
107 NoSuchAlgorithmException lastException = null;
108 for (int i = 0; i < p.length; i++)
109 try
110 {
111 return getInstance(algorithm, p[i]);
112 }
113 catch (NoSuchAlgorithmException x)
114 {
115 lastException = x;
116 }
117 if (lastException != null)
118 throw lastException;
119 throw new NoSuchAlgorithmException(algorithm);
120 }
121
122 /**
123 * Returns a new instance of <code>KeyPairGenerator</code> which generates
124 * key-pairs for the specified algorithm from a named provider.
125 *
126 * @param algorithm the name of the algorithm to use.
127 * @param provider the name of a {@link Provider} to use.
128 * @return a new instance repesenting the desired algorithm.
129 * @throws NoSuchAlgorithmException if the algorithm is not implemented by the
130 * named provider.
131 * @throws NoSuchProviderException if the named provider was not found.
132 * @throws IllegalArgumentException if either <code>algorithm</code> or
133 * <code>provider</code> is <code>null</code> or empty.
134 */
135 public static KeyPairGenerator getInstance(String algorithm, String provider)
136 throws NoSuchAlgorithmException, NoSuchProviderException
137 {
138 if (provider == null)
139 throw new IllegalArgumentException("provider MUST NOT be null");
140 provider = provider.trim();
141 if (provider.length() == 0)
142 throw new IllegalArgumentException("provider MUST NOT be empty");
143 Provider p = Security.getProvider(provider);
144 if (p == null)
145 throw new NoSuchProviderException(provider);
146 return getInstance(algorithm, p);
147 }
148
149 /**
150 * Returns a new instance of <code>KeyPairGenerator</code> which generates
151 * key-pairs for the specified algorithm from a designated {@link Provider}.
152 *
153 * @param algorithm
154 * the name of the algorithm to use.
155 * @param provider
156 * the {@link Provider} to use.
157 * @return a new insatnce repesenting the desired algorithm.
158 * @throws NoSuchAlgorithmException
159 * if the algorithm is not implemented by the {@link Provider}.
160 * @throws IllegalArgumentException if either <code>algorithm</code> or
161 * <code>provider</code> is <code>null</code>, or if
162 * <code>algorithm</code> is an empty string.
163 * @since 1.4
164 * @see Provider
165 */
166 public static KeyPairGenerator getInstance(String algorithm,
167 Provider provider)
168 throws NoSuchAlgorithmException
169 {
170 CPStringBuilder sb = new CPStringBuilder("KeyPairGenerator for algorithm [")
171 .append(algorithm).append("] from provider[")
172 .append(provider).append("] ");
173 Object o;
174 try
175 {
176 o = Engine.getInstance(KEY_PAIR_GENERATOR, algorithm, provider);
177 }
178 catch (InvocationTargetException x)
179 {
180 Throwable cause = x.getCause();
181 if (cause instanceof NoSuchAlgorithmException)
182 throw (NoSuchAlgorithmException) cause;
183 if (cause == null)
184 cause = x;
185 sb.append("could not be created");
186 NoSuchAlgorithmException y = new NoSuchAlgorithmException(sb.toString());
187 y.initCause(cause);
188 throw y;
189 }
190 KeyPairGenerator result;
191 if (o instanceof KeyPairGenerator)
192 {
193 result = (KeyPairGenerator) o;
194 result.algorithm = algorithm;
195 }
196 else if (o instanceof KeyPairGeneratorSpi)
197 result = new DummyKeyPairGenerator((KeyPairGeneratorSpi) o, algorithm);
198 else
199 {
200 sb.append("is of an unexpected Type: ").append(o.getClass().getName());
201 throw new NoSuchAlgorithmException(sb.toString());
202 }
203 result.provider = provider;
204 return result;
205 }
206
207 /**
208 * Returns the {@link Provider} of this instance.
209 *
210 * @return the {@link Provider} of this instance.
211 */
212 public final Provider getProvider()
213 {
214 return provider;
215 }
216
217 /**
218 * Initializes this instance for the specified key size. Since no source of
219 * randomness is specified, a default one will be used.
220 *
221 * @param keysize
222 * the size of keys to use.
223 */
224 public void initialize(int keysize)
225 {
226 initialize(keysize, new SecureRandom());
227 }
228
229 /**
230 * Initializes this instance for the specified key size and
231 * {@link SecureRandom}.
232 *
233 * @param keysize
234 * the size of keys to use.
235 * @param random
236 * the {@link SecureRandom} to use.
237 * @since 1.2
238 */
239 public void initialize(int keysize, SecureRandom random)
240 {
241 }
242
243 /**
244 * Initializes this instance with the specified
245 * {@link AlgorithmParameterSpec}. Since no source of randomness is specified,
246 * a default one will be used.
247 *
248 * @param params
249 * the {@link AlgorithmParameterSpec} to use.
250 * @throws InvalidAlgorithmParameterException
251 * if the designated specifications are invalid.
252 * @since 1.2
253 */
254 public void initialize(AlgorithmParameterSpec params)
255 throws InvalidAlgorithmParameterException
256 {
257 initialize(params, new SecureRandom());
258 }
259
260 /**
261 * Initializes this instance with the specified {@link AlgorithmParameterSpec}
262 * and {@link SecureRandom}.
263 *
264 * @param params
265 * the {@link AlgorithmParameterSpec} to use.
266 * @param random
267 * the {@link SecureRandom} to use.
268 * @throws InvalidAlgorithmParameterException
269 * if the designated specifications are invalid.
270 * @since 1.2
271 */
272 public void initialize(AlgorithmParameterSpec params, SecureRandom random)
273 throws InvalidAlgorithmParameterException
274 {
275 super.initialize(params, random);
276 }
277
278 /**
279 * Generates a new "DSA" {@link KeyPair} from the "GNU" security provider.
280 *
281 * <p>This method generates a unique key-pair each time it is called.</p>
282 *
283 * @return a new unique {@link KeyPair}.
284 * @see #generateKeyPair()
285 * @since 1.2
286 */
287 public final KeyPair genKeyPair()
288 {
289 try
290 {
291 return getInstance("DSA", "GNU").generateKeyPair();
292 }
293 catch (Exception e)
294 {
295 System.err.println("genKeyPair failed: " + e);
296 e.printStackTrace();
297 return null;
298 }
299 }
300
301 /**
302 * Generates a new "DSA" {@link KeyPair} from the "GNU" security provider.
303 *
304 * <p>This method generates a unique key pair each time it is called.</p>
305 *
306 * @return a new unique {@link KeyPair}.
307 * @see #genKeyPair()
308 */
309 public KeyPair generateKeyPair()
310 {
311 return genKeyPair();
312 }
313 }