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