Home | History | Annotate | Download | only in security
      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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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>
    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      */
    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      */
    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      */
    482     public final String toString() {
    483         if (this.initialized == false) {
    484             return null;
    485         }
    486         return paramSpi.engineToString();
    487     }
    488 }
    489