1 /* 2 * Copyright (c) 1997, 2016, 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} 132 * {@link Security#getProperty(String) Security} property to determine 133 * the preferred provider order for the specified algorithm. This 134 * may be different than the order of providers returned by 135 * {@link Security#getProviders() Security.getProviders()}. 136 * 137 * @param algorithm the name of the algorithm requested. 138 * See the AlgorithmParameters section in the <a href= 139 * "{@docRoot}/../technotes/guides/security/StandardNames.html#AlgorithmParameters"> 140 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 141 * for information about standard algorithm names. 142 * 143 * @return the new parameter object. 144 * 145 * @exception NoSuchAlgorithmException if no Provider supports an 146 * AlgorithmParametersSpi implementation for the 147 * specified algorithm. 148 * 149 * @see Provider 150 */ 151 public static AlgorithmParameters getInstance(String algorithm) 152 throws NoSuchAlgorithmException { 153 try { 154 Object[] objs = Security.getImpl(algorithm, "AlgorithmParameters", 155 (String)null); 156 return new AlgorithmParameters((AlgorithmParametersSpi)objs[0], 157 (Provider)objs[1], 158 algorithm); 159 } catch(NoSuchProviderException e) { 160 throw new NoSuchAlgorithmException(algorithm + " not found"); 161 } 162 } 163 164 /** 165 * Returns a parameter object for the specified algorithm. 166 * 167 * <p> A new AlgorithmParameters object encapsulating the 168 * AlgorithmParametersSpi implementation from the specified provider 169 * is returned. The specified provider must be registered 170 * in the security provider list. 171 * 172 * <p> Note that the list of registered providers may be retrieved via 173 * the {@link Security#getProviders() Security.getProviders()} method. 174 * 175 * <p>The returned parameter object must be initialized via a call to 176 * {@code init}, using an appropriate parameter specification or 177 * parameter encoding. 178 * 179 * @param algorithm the name of the algorithm requested. 180 * See the AlgorithmParameters section in the <a href= 181 * "{@docRoot}/../technotes/guides/security/StandardNames.html#AlgorithmParameters"> 182 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 183 * for information about standard algorithm names. 184 * 185 * @param provider the name of the provider. 186 * 187 * @return the new parameter object. 188 * 189 * @exception NoSuchAlgorithmException if an AlgorithmParametersSpi 190 * implementation for the specified algorithm is not 191 * available from the specified provider. 192 * 193 * @exception NoSuchProviderException if the specified provider is not 194 * registered in the security provider list. 195 * 196 * @exception IllegalArgumentException if the provider name is null 197 * or empty. 198 * 199 * @see Provider 200 */ 201 public static AlgorithmParameters getInstance(String algorithm, 202 String provider) 203 throws NoSuchAlgorithmException, NoSuchProviderException 204 { 205 if (provider == null || provider.length() == 0) 206 throw new IllegalArgumentException("missing provider"); 207 Object[] objs = Security.getImpl(algorithm, "AlgorithmParameters", 208 provider); 209 return new AlgorithmParameters((AlgorithmParametersSpi)objs[0], 210 (Provider)objs[1], 211 algorithm); 212 } 213 214 /** 215 * Returns a parameter object for the specified algorithm. 216 * 217 * <p> A new AlgorithmParameters object encapsulating the 218 * AlgorithmParametersSpi implementation from the specified Provider 219 * object is returned. Note that the specified Provider object 220 * does not have to be registered in the provider list. 221 * 222 * <p>The returned parameter object must be initialized via a call to 223 * {@code init}, using an appropriate parameter specification or 224 * parameter encoding. 225 * 226 * @param algorithm the name of the algorithm requested. 227 * See the AlgorithmParameters section in the <a href= 228 * "{@docRoot}/../technotes/guides/security/StandardNames.html#AlgorithmParameters"> 229 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 230 * for information about standard algorithm names. 231 * 232 * @param provider the name of the provider. 233 * 234 * @return the new parameter object. 235 * 236 * @exception NoSuchAlgorithmException if an AlgorithmParameterGeneratorSpi 237 * implementation for the specified algorithm is not available 238 * from the specified Provider object. 239 * 240 * @exception IllegalArgumentException if the provider is null. 241 * 242 * @see Provider 243 * 244 * @since 1.4 245 */ 246 public static AlgorithmParameters getInstance(String algorithm, 247 Provider provider) 248 throws NoSuchAlgorithmException 249 { 250 if (provider == null) 251 throw new IllegalArgumentException("missing provider"); 252 Object[] objs = Security.getImpl(algorithm, "AlgorithmParameters", 253 provider); 254 return new AlgorithmParameters((AlgorithmParametersSpi)objs[0], 255 (Provider)objs[1], 256 algorithm); 257 } 258 259 /** 260 * Returns the provider of this parameter object. 261 * 262 * @return the provider of this parameter object 263 */ 264 public final Provider getProvider() { 265 return this.provider; 266 } 267 268 /** 269 * Initializes this parameter object using the parameters 270 * specified in {@code paramSpec}. 271 * 272 * @param paramSpec the parameter specification. 273 * 274 * @exception InvalidParameterSpecException if the given parameter 275 * specification is inappropriate for the initialization of this parameter 276 * object, or if this parameter object has already been initialized. 277 */ 278 public final void init(AlgorithmParameterSpec paramSpec) 279 throws InvalidParameterSpecException 280 { 281 if (this.initialized) 282 throw new InvalidParameterSpecException("already initialized"); 283 paramSpi.engineInit(paramSpec); 284 this.initialized = true; 285 } 286 287 /** 288 * Imports the specified parameters and decodes them according to the 289 * primary decoding format for parameters. The primary decoding 290 * format for parameters is ASN.1, if an ASN.1 specification for this type 291 * of parameters exists. 292 * 293 * @param params the encoded parameters. 294 * 295 * @exception IOException on decoding errors, or if this parameter object 296 * has already been initialized. 297 */ 298 public final void init(byte[] params) throws IOException { 299 if (this.initialized) 300 throw new IOException("already initialized"); 301 paramSpi.engineInit(params); 302 this.initialized = true; 303 } 304 305 /** 306 * Imports the parameters from {@code params} and decodes them 307 * according to the specified decoding scheme. 308 * If {@code format} is null, the 309 * primary decoding format for parameters is used. The primary decoding 310 * format is ASN.1, if an ASN.1 specification for these parameters 311 * exists. 312 * 313 * @param params the encoded parameters. 314 * 315 * @param format the name of the decoding scheme. 316 * 317 * @exception IOException on decoding errors, or if this parameter object 318 * has already been initialized. 319 */ 320 public final void init(byte[] params, String format) throws IOException { 321 if (this.initialized) 322 throw new IOException("already initialized"); 323 paramSpi.engineInit(params, format); 324 this.initialized = true; 325 } 326 327 /** 328 * Returns a (transparent) specification of this parameter object. 329 * {@code paramSpec} identifies the specification class in which 330 * the parameters should be returned. It could, for example, be 331 * {@code DSAParameterSpec.class}, to indicate that the 332 * parameters should be returned in an instance of the 333 * {@code DSAParameterSpec} class. 334 * 335 * @param <T> the type of the parameter specification to be returrned 336 * @param paramSpec the specification class in which 337 * the parameters should be returned. 338 * 339 * @return the parameter specification. 340 * 341 * @exception InvalidParameterSpecException if the requested parameter 342 * specification is inappropriate for this parameter object, or if this 343 * parameter object has not been initialized. 344 */ 345 public final <T extends AlgorithmParameterSpec> 346 T getParameterSpec(Class<T> paramSpec) 347 throws InvalidParameterSpecException 348 { 349 if (this.initialized == false) { 350 throw new InvalidParameterSpecException("not initialized"); 351 } 352 return paramSpi.engineGetParameterSpec(paramSpec); 353 } 354 355 /** 356 * Returns the parameters in their primary encoding format. 357 * The primary encoding format for parameters is ASN.1, if an ASN.1 358 * specification for this type of parameters exists. 359 * 360 * @return the parameters encoded using their primary encoding format. 361 * 362 * @exception IOException on encoding errors, or if this parameter object 363 * has not been initialized. 364 */ 365 public final byte[] getEncoded() throws IOException 366 { 367 if (this.initialized == false) { 368 throw new IOException("not initialized"); 369 } 370 return paramSpi.engineGetEncoded(); 371 } 372 373 /** 374 * Returns the parameters encoded in the specified scheme. 375 * If {@code format} is null, the 376 * primary encoding format for parameters is used. The primary encoding 377 * format is ASN.1, if an ASN.1 specification for these parameters 378 * exists. 379 * 380 * @param format the name of the encoding format. 381 * 382 * @return the parameters encoded using the specified encoding scheme. 383 * 384 * @exception IOException on encoding errors, or if this parameter object 385 * has not been initialized. 386 */ 387 public final byte[] getEncoded(String format) throws IOException 388 { 389 if (this.initialized == false) { 390 throw new IOException("not initialized"); 391 } 392 return paramSpi.engineGetEncoded(format); 393 } 394 395 /** 396 * Returns a formatted string describing the parameters. 397 * 398 * @return a formatted string describing the parameters, or null if this 399 * parameter object has not been initialized. 400 */ 401 public final String toString() { 402 if (this.initialized == false) { 403 return null; 404 } 405 return paramSpi.engineToString(); 406 } 407 }