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