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