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 }