1 /* 2 * Copyright (c) 1997, 2011, 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.io.*; 29 import java.security.spec.AlgorithmParameterSpec; 30 import java.security.spec.InvalidParameterSpecException; 31 32 /** 33 * This class is used as an opaque representation of cryptographic parameters. 34 * 35 * <p>An <code>AlgorithmParameters</code> object for managing the parameters 36 * for a particular algorithm can be obtained by 37 * calling one of the <code>getInstance</code> factory methods 38 * (static methods that return instances of a given class). 39 * 40 * <p>Once an <code>AlgorithmParameters</code> object is obtained, it must be 41 * initialized via a call to <code>init</code>, using an appropriate parameter 42 * specification or parameter encoding. 43 * 44 * <p>A transparent parameter specification is obtained from an 45 * <code>AlgorithmParameters</code> object via a call to 46 * <code>getParameterSpec</code>, and a byte encoding of the parameters is 47 * obtained via a call to <code>getEncoded</code>. 48 * 49 * <p> Android provides the following <code>AlgorithmParameters</code> algorithms: 50 * <table> 51 * <thead> 52 * <tr> 53 * <th>Name</th> 54 * <th>Supported (API Levels)</th> 55 * </tr> 56 * </thead> 57 * <tbody> 58 * <tr> 59 * <td>AES</td> 60 * <td>1+</td> 61 * </tr> 62 * <tr> 63 * <td>Blowfish</td> 64 * <td>10+</td> 65 * </tr> 66 * <tr> 67 * <td>DES</td> 68 * <td>1+</td> 69 * </tr> 70 * <tr> 71 * <td>DESede</td> 72 * <td>1+</td> 73 * </tr> 74 * <tr> 75 * <td>DH</td> 76 * <td>1+</td> 77 * </tr> 78 * <tr> 79 * <td>DSA</td> 80 * <td>1+</td> 81 * </tr> 82 * <tr> 83 * <td>GCM</td> 84 * <td>22+</td> 85 * </tr> 86 * <tr> 87 * <td>IES</td> 88 * <td>1–8</td> 89 * </tr> 90 * <tr> 91 * <td>OAEP</td> 92 * <td>1+</td> 93 * </tr> 94 * <tr> 95 * <td>PKCS12PBE</td> 96 * <td>1+</td> 97 * </tr> 98 * <tr> 99 * <td>PSS</td> 100 * <td>1–8, 24+</td> 101 * </tr> 102 * </tbody> 103 * </table> 104 * 105 * These algorithms are described in the <a href= 106 * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#AlgorithmParameters"> 107 * AlgorithmParameters section</a> of the 108 * Java Cryptography Architecture Standard Algorithm Name Documentation. 109 * 110 * @author Jan Luehe 111 * 112 * 113 * @see java.security.spec.AlgorithmParameterSpec 114 * @see java.security.spec.DSAParameterSpec 115 * @see KeyPairGenerator 116 * 117 * @since 1.2 118 */ 119 120 public class AlgorithmParameters { 121 122 // The provider 123 private Provider provider; 124 125 // The provider implementation (delegate) 126 private AlgorithmParametersSpi paramSpi; 127 128 // The algorithm 129 private String algorithm; 130 131 // Has this object been initialized? 132 private boolean initialized = false; 133 134 /** 135 * Creates an AlgorithmParameters object. 136 * 137 * @param paramSpi the delegate 138 * @param provider the provider 139 * @param algorithm the algorithm 140 */ AlgorithmParameters(AlgorithmParametersSpi paramSpi, Provider provider, String algorithm)141 protected AlgorithmParameters(AlgorithmParametersSpi paramSpi, 142 Provider provider, String algorithm) 143 { 144 this.paramSpi = paramSpi; 145 this.provider = provider; 146 this.algorithm = algorithm; 147 } 148 149 /** 150 * Returns the name of the algorithm associated with this parameter object. 151 * 152 * @return the algorithm name. 153 */ getAlgorithm()154 public final String getAlgorithm() { 155 return this.algorithm; 156 } 157 158 /** 159 * Returns a parameter object for the specified algorithm. 160 * 161 * <p> This method traverses the list of registered security Providers, 162 * starting with the most preferred Provider. 163 * A new AlgorithmParameters object encapsulating the 164 * AlgorithmParametersSpi implementation from the first 165 * Provider that supports the specified algorithm is returned. 166 * 167 * <p> Note that the list of registered providers may be retrieved via 168 * the {@link Security#getProviders() Security.getProviders()} method. 169 * 170 * <p> The returned parameter object must be initialized via a call to 171 * <code>init</code>, using an appropriate parameter specification or 172 * parameter encoding. 173 * 174 * @param algorithm the name of the algorithm requested. 175 * See the AlgorithmParameters section in the <a href= 176 * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#AlgorithmParameters"> 177 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 178 * for information about standard algorithm names. 179 * 180 * @return the new parameter object. 181 * 182 * @exception NoSuchAlgorithmException if no Provider supports an 183 * AlgorithmParametersSpi implementation for the 184 * specified algorithm. 185 * 186 * @see Provider 187 */ getInstance(String algorithm)188 public static AlgorithmParameters getInstance(String algorithm) 189 throws NoSuchAlgorithmException { 190 try { 191 Object[] objs = Security.getImpl(algorithm, "AlgorithmParameters", 192 (String)null); 193 return new AlgorithmParameters((AlgorithmParametersSpi)objs[0], 194 (Provider)objs[1], 195 algorithm); 196 } catch(NoSuchProviderException e) { 197 throw new NoSuchAlgorithmException(algorithm + " not found"); 198 } 199 } 200 201 /** 202 * Returns a parameter object for the specified algorithm. 203 * 204 * <p> A new AlgorithmParameters object encapsulating the 205 * AlgorithmParametersSpi implementation from the specified provider 206 * is returned. The specified provider must be registered 207 * in the security provider list. 208 * 209 * <p> Note that the list of registered providers may be retrieved via 210 * the {@link Security#getProviders() Security.getProviders()} method. 211 * 212 * <p>The returned parameter object must be initialized via a call to 213 * <code>init</code>, using an appropriate parameter specification or 214 * parameter encoding. 215 * 216 * @param algorithm the name of the algorithm requested. 217 * See the AlgorithmParameters section in the <a href= 218 * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#AlgorithmParameters"> 219 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 220 * for information about standard algorithm names. 221 * 222 * @param provider the name of the provider. 223 * 224 * @return the new parameter object. 225 * 226 * @exception NoSuchAlgorithmException if an AlgorithmParametersSpi 227 * implementation for the specified algorithm is not 228 * available from the specified provider. 229 * 230 * @exception NoSuchProviderException if the specified provider is not 231 * registered in the security provider list. 232 * 233 * @exception IllegalArgumentException if the provider name is null 234 * or empty. 235 * 236 * @see Provider 237 */ getInstance(String algorithm, String provider)238 public static AlgorithmParameters getInstance(String algorithm, 239 String provider) 240 throws NoSuchAlgorithmException, NoSuchProviderException 241 { 242 if (provider == null || provider.length() == 0) 243 throw new IllegalArgumentException("missing provider"); 244 Object[] objs = Security.getImpl(algorithm, "AlgorithmParameters", 245 provider); 246 return new AlgorithmParameters((AlgorithmParametersSpi)objs[0], 247 (Provider)objs[1], 248 algorithm); 249 } 250 251 /** 252 * Returns a parameter object for the specified algorithm. 253 * 254 * <p> A new AlgorithmParameters object encapsulating the 255 * AlgorithmParametersSpi implementation from the specified Provider 256 * object is returned. Note that the specified Provider object 257 * does not have to be registered in the provider list. 258 * 259 * <p>The returned parameter object must be initialized via a call to 260 * <code>init</code>, using an appropriate parameter specification or 261 * parameter encoding. 262 * 263 * @param algorithm the name of the algorithm requested. 264 * See the AlgorithmParameters section in the <a href= 265 * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#AlgorithmParameters"> 266 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 267 * for information about standard algorithm names. 268 * 269 * @param provider the name of the provider. 270 * 271 * @return the new parameter object. 272 * 273 * @exception NoSuchAlgorithmException if an AlgorithmParameterGeneratorSpi 274 * implementation for the specified algorithm is not available 275 * from the specified Provider object. 276 * 277 * @exception IllegalArgumentException if the provider is null. 278 * 279 * @see Provider 280 * 281 * @since 1.4 282 */ getInstance(String algorithm, Provider provider)283 public static AlgorithmParameters getInstance(String algorithm, 284 Provider provider) 285 throws NoSuchAlgorithmException 286 { 287 if (provider == null) 288 throw new IllegalArgumentException("missing provider"); 289 Object[] objs = Security.getImpl(algorithm, "AlgorithmParameters", 290 provider); 291 return new AlgorithmParameters((AlgorithmParametersSpi)objs[0], 292 (Provider)objs[1], 293 algorithm); 294 } 295 296 /** 297 * Returns the provider of this parameter object. 298 * 299 * @return the provider of this parameter object 300 */ getProvider()301 public final Provider getProvider() { 302 return this.provider; 303 } 304 305 /** 306 * Initializes this parameter object using the parameters 307 * specified in <code>paramSpec</code>. 308 * 309 * @param paramSpec the parameter specification. 310 * 311 * @exception InvalidParameterSpecException if the given parameter 312 * specification is inappropriate for the initialization of this parameter 313 * object, or if this parameter object has already been initialized. 314 */ init(AlgorithmParameterSpec paramSpec)315 public final void init(AlgorithmParameterSpec paramSpec) 316 throws InvalidParameterSpecException 317 { 318 if (this.initialized) 319 throw new InvalidParameterSpecException("already initialized"); 320 paramSpi.engineInit(paramSpec); 321 this.initialized = true; 322 } 323 324 /** 325 * Imports the specified parameters and decodes them according to the 326 * primary decoding format for parameters. The primary decoding 327 * format for parameters is ASN.1, if an ASN.1 specification for this type 328 * of parameters exists. 329 * 330 * @param params the encoded parameters. 331 * 332 * @exception IOException on decoding errors, or if this parameter object 333 * has already been initialized. 334 */ init(byte[] params)335 public final void init(byte[] params) throws IOException { 336 if (this.initialized) 337 throw new IOException("already initialized"); 338 paramSpi.engineInit(params); 339 this.initialized = true; 340 } 341 342 /** 343 * Imports the parameters from <code>params</code> and decodes them 344 * according to the specified decoding scheme. 345 * If <code>format</code> is null, the 346 * primary decoding format for parameters is used. The primary decoding 347 * format is ASN.1, if an ASN.1 specification for these parameters 348 * exists. 349 * 350 * @param params the encoded parameters. 351 * 352 * @param format the name of the decoding scheme. 353 * 354 * @exception IOException on decoding errors, or if this parameter object 355 * has already been initialized. 356 */ init(byte[] params, String format)357 public final void init(byte[] params, String format) throws IOException { 358 if (this.initialized) 359 throw new IOException("already initialized"); 360 paramSpi.engineInit(params, format); 361 this.initialized = true; 362 } 363 364 /** 365 * Returns a (transparent) specification of this parameter object. 366 * <code>paramSpec</code> identifies the specification class in which 367 * the parameters should be returned. It could, for example, be 368 * <code>DSAParameterSpec.class</code>, to indicate that the 369 * parameters should be returned in an instance of the 370 * <code>DSAParameterSpec</code> class. 371 * 372 * @param paramSpec the specification class in which 373 * the parameters should be returned. 374 * 375 * @return the parameter specification. 376 * 377 * @exception InvalidParameterSpecException if the requested parameter 378 * specification is inappropriate for this parameter object, or if this 379 * parameter object has not been initialized. 380 */ 381 public final <T extends AlgorithmParameterSpec> getParameterSpec(Class<T> paramSpec)382 T getParameterSpec(Class<T> paramSpec) 383 throws InvalidParameterSpecException 384 { 385 if (this.initialized == false) { 386 throw new InvalidParameterSpecException("not initialized"); 387 } 388 return paramSpi.engineGetParameterSpec(paramSpec); 389 } 390 391 /** 392 * Returns the parameters in their primary encoding format. 393 * The primary encoding format for parameters is ASN.1, if an ASN.1 394 * specification for this type of parameters exists. 395 * 396 * @return the parameters encoded using their primary encoding format. 397 * 398 * @exception IOException on encoding errors, or if this parameter object 399 * has not been initialized. 400 */ getEncoded()401 public final byte[] getEncoded() throws IOException 402 { 403 if (this.initialized == false) { 404 throw new IOException("not initialized"); 405 } 406 return paramSpi.engineGetEncoded(); 407 } 408 409 /** 410 * Returns the parameters encoded in the specified scheme. 411 * If <code>format</code> is null, the 412 * primary encoding format for parameters is used. The primary encoding 413 * format is ASN.1, if an ASN.1 specification for these parameters 414 * exists. 415 * 416 * @param format the name of the encoding format. 417 * 418 * @return the parameters encoded using the specified encoding scheme. 419 * 420 * @exception IOException on encoding errors, or if this parameter object 421 * has not been initialized. 422 */ getEncoded(String format)423 public final byte[] getEncoded(String format) throws IOException 424 { 425 if (this.initialized == false) { 426 throw new IOException("not initialized"); 427 } 428 return paramSpi.engineGetEncoded(format); 429 } 430 431 /** 432 * Returns a formatted string describing the parameters. 433 * 434 * @return a formatted string describing the parameters, or null if this 435 * parameter object has not been initialized. 436 */ toString()437 public final String toString() { 438 if (this.initialized == false) { 439 return null; 440 } 441 return paramSpi.engineToString(); 442 } 443 } 444