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