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