Home | History | Annotate | Download | only in crypto
      1 /*
      2  *  Licensed to the Apache Software Foundation (ASF) under one or more
      3  *  contributor license agreements.  See the NOTICE file distributed with
      4  *  this work for additional information regarding copyright ownership.
      5  *  The ASF licenses this file to You under the Apache License, Version 2.0
      6  *  (the "License"); you may not use this file except in compliance with
      7  *  the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  */
     17 
     18 package javax.crypto;
     19 
     20 import java.security.InvalidAlgorithmParameterException;
     21 import java.security.InvalidKeyException;
     22 import java.security.Key;
     23 import java.security.NoSuchAlgorithmException;
     24 import java.security.NoSuchProviderException;
     25 import java.security.Provider;
     26 import java.security.SecureRandom;
     27 import java.security.Security;
     28 import java.security.spec.AlgorithmParameterSpec;
     29 import org.apache.harmony.security.fortress.Engine;
     30 
     31 /**
     32  * This class provides the functionality for a key exchange protocol. This
     33  * enables two or more parties to agree on a secret key for symmetric
     34  * cryptography.
     35  */
     36 public class KeyAgreement {
     37 
     38     // Used to access common engine functionality
     39     private static final Engine engine = new Engine("KeyAgreement");
     40 
     41     // Store SecureRandom
     42     private static final SecureRandom rndm = new SecureRandom();
     43 
     44     // Store used provider
     45     private final Provider provider;
     46 
     47     // Store used spi implementation
     48     private final KeyAgreementSpi spiImpl;
     49 
     50     // Store used algorithm name
     51     private final String algorithm;
     52 
     53     /**
     54      * Creates a new {@code KeyAgreement} instance.
     55      *
     56      * @param keyAgreeSpi
     57      *            the <b>SPI</b> delegate.
     58      * @param provider
     59      *            the provider providing this KeyAgreement.
     60      * @param algorithm
     61      *            the name of the key agreement algorithm.
     62      */
     63     protected KeyAgreement(KeyAgreementSpi keyAgreeSpi, Provider provider,
     64             String algorithm) {
     65         this.provider = provider;
     66         this.algorithm = algorithm;
     67         this.spiImpl = keyAgreeSpi;
     68     }
     69 
     70     /**
     71      * Returns the name of the key agreement algorithm.
     72      *
     73      * @return the name of the key agreement algorithm.
     74      */
     75     public final String getAlgorithm() {
     76         return algorithm;
     77     }
     78 
     79     /**
     80      * Returns the provider for this {@code KeyAgreement} instance.
     81      *
     82      * @return the provider for this {@code KeyAgreement} instance.
     83      */
     84     public final Provider getProvider() {
     85         return provider;
     86     }
     87 
     88     /**
     89      * Creates a new {@code KeyAgreement} for the specified algorithm.
     90      *
     91      * @param algorithm
     92      *            the name of the key agreement algorithm to create.
     93      * @return a key agreement for the specified algorithm.
     94      * @throws NoSuchAlgorithmException
     95      *             if no installed provider can provide the requested algorithm.
     96      * @throws NullPointerException
     97      *             if the specified algorithm is {@code null}.
     98      */
     99     public static final KeyAgreement getInstance(String algorithm)
    100             throws NoSuchAlgorithmException {
    101         if (algorithm == null) {
    102             throw new NullPointerException();
    103         }
    104         synchronized (engine) {
    105             engine.getInstance(algorithm, null);
    106             return new KeyAgreement((KeyAgreementSpi) engine.spi, engine.provider,
    107                     algorithm);
    108         }
    109     }
    110 
    111     /**
    112      * Creates a new {@code KeyAgreement} for the specified algorithm from the
    113      * specified provider.
    114      *
    115      * @param algorithm
    116      *            the name of the key agreement algorithm to create.
    117      * @param provider
    118      *            the name of the provider that provides the requested
    119      *            algorithm.
    120      * @return a key agreement for the specified algorithm from the specified
    121      *         provider.
    122      * @throws NoSuchAlgorithmException
    123      *             if the specified provider cannot provide the requested
    124      *             algorithm.
    125      * @throws NoSuchProviderException
    126      *             if the specified provider does not exist.
    127      * @throws IllegalArgumentException
    128      *             if the specified provider name is {@code null} or empty.
    129      */
    130     public static final KeyAgreement getInstance(String algorithm,
    131             String provider) throws NoSuchAlgorithmException,
    132             NoSuchProviderException {
    133         if (provider == null || provider.isEmpty()) {
    134             throw new IllegalArgumentException("Provider is null or empty");
    135         }
    136         Provider impProvider = Security.getProvider(provider);
    137         if (impProvider == null) {
    138             throw new NoSuchProviderException(provider);
    139         }
    140         return getInstance(algorithm, impProvider);
    141     }
    142 
    143     /**
    144      * Create a new {@code KeyAgreement} for the specified algorithm from the
    145      * specified provider.
    146      *
    147      * @param algorithm
    148      *            the name of the key agreement algorithm to create.
    149      * @param provider
    150      *            the provider that provides the requested algorithm.
    151      * @return a key agreement for the specified algorithm from the specified
    152      *         provider.
    153      * @throws NoSuchAlgorithmException
    154      *             if the specified provider cannot provide the requested
    155      *             algorithm.
    156      * @throws IllegalArgumentException
    157      *             if the specified provider is {@code null}.
    158      * @throws NullPointerException
    159      *             if the specified algorithm name is {@code null}.
    160      */
    161     public static final KeyAgreement getInstance(String algorithm,
    162             Provider provider) throws NoSuchAlgorithmException {
    163         if (provider == null) {
    164             throw new IllegalArgumentException("provider == null");
    165         }
    166         if (algorithm == null) {
    167             throw new NullPointerException();
    168         }
    169         synchronized (engine) {
    170             engine.getInstance(algorithm, provider, null);
    171             return new KeyAgreement((KeyAgreementSpi) engine.spi, provider,
    172                     algorithm);
    173         }
    174     }
    175 
    176     /**
    177      * Initializes this {@code KeyAgreement} with the specified key.
    178      *
    179      * @param key
    180      *            the key to initialize this key agreement.
    181      * @throws InvalidKeyException
    182      *             if the specified key cannot be used to initialize this key
    183      *             agreement.
    184      */
    185     public final void init(Key key) throws InvalidKeyException {
    186         spiImpl.engineInit(key, rndm);//new SecureRandom());
    187     }
    188 
    189     /**
    190      * Initializes this {@code KeyAgreement} with the specified key and the
    191      * specified randomness source.
    192      *
    193      * @param key
    194      *            the key to initialize this key agreement.
    195      * @param random
    196      *            the source for any randomness needed.
    197      * @throws InvalidKeyException
    198      *             if the specified key cannot be used to initialize this key
    199      *             agreement.
    200      */
    201     public final void init(Key key, SecureRandom random)
    202             throws InvalidKeyException {
    203         spiImpl.engineInit(key, random);
    204     }
    205 
    206     /**
    207      * Initializes this {@code KeyAgreement} with the specified key and the
    208      * algorithm parameters.
    209      *
    210      * @param key
    211      *            the key to initialize this key agreement.
    212      * @param params
    213      *            the parameters for this key agreement algorithm.
    214      * @throws InvalidKeyException
    215      *             if the specified key cannot be used to initialize this key
    216      *             agreement.
    217      * @throws InvalidAlgorithmParameterException
    218      *             if the specified parameters are invalid for this key
    219      *             agreement algorithm.
    220      */
    221     public final void init(Key key, AlgorithmParameterSpec params)
    222             throws InvalidKeyException, InvalidAlgorithmParameterException {
    223         spiImpl.engineInit(key, params, rndm);//new SecureRandom());
    224     }
    225 
    226     /**
    227      * Initializes this {@code KeyAgreement} with the specified key, algorithm
    228      * parameters and randomness source.
    229      *
    230      * @param key
    231      *            the key to initialize this key agreement.
    232      * @param params
    233      *            the parameters for this key agreement algorithm.
    234      * @param random
    235      *            the source for any randomness needed.
    236      * @throws InvalidKeyException
    237      *             if the specified key cannot be used to initialize this key
    238      *             agreement.
    239      * @throws InvalidAlgorithmParameterException
    240      *             if the specified parameters are invalid for this key
    241      *             agreement algorithm.
    242      */
    243     public final void init(Key key, AlgorithmParameterSpec params,
    244             SecureRandom random) throws InvalidKeyException,
    245             InvalidAlgorithmParameterException {
    246         spiImpl.engineInit(key, params, random);
    247     }
    248 
    249     /**
    250      * Does the next (or the last) phase of the key agreement, using the
    251      * specified key.
    252      *
    253      * @param key
    254      *            the key received from the other party for this phase.
    255      * @param lastPhase
    256      *            set to {@code true} if this is the last phase of this key
    257      *            agreement.
    258      * @return the intermediate key from this phase or {@code null} if there is
    259      *         no intermediate key for this phase.
    260      * @throws InvalidKeyException
    261      *             if the specified key cannot be used in this key agreement or
    262      *             this phase,
    263      * @throws IllegalStateException
    264      *             if this instance has not been initialized.
    265      */
    266     public final Key doPhase(Key key, boolean lastPhase)
    267             throws InvalidKeyException, IllegalStateException {
    268         return spiImpl.engineDoPhase(key, lastPhase);
    269     }
    270 
    271     /**
    272      * Generates the shared secret.
    273      *
    274      * @return the generated shared secret.
    275      * @throws IllegalStateException
    276      *             if this key agreement is not complete.
    277      */
    278     public final byte[] generateSecret() throws IllegalStateException {
    279         return spiImpl.engineGenerateSecret();
    280     }
    281 
    282     /**
    283      * Generates the shared secret and stores it into the buffer {@code
    284      * sharedSecred} at {@code offset}.
    285      *
    286      * @param sharedSecret
    287      *            the buffer to store the shared secret.
    288      * @param offset
    289      *            the offset in the buffer.
    290      * @return the number of bytes stored in the buffer.
    291      * @throws IllegalStateException
    292      *             if this key agreement is not complete.
    293      * @throws ShortBufferException
    294      *             if the specified buffer is too small for the shared secret.
    295      */
    296     public final int generateSecret(byte[] sharedSecret, int offset)
    297             throws IllegalStateException, ShortBufferException {
    298         return spiImpl.engineGenerateSecret(sharedSecret, offset);
    299     }
    300 
    301     /**
    302      * Generates the shared secret.
    303      *
    304      * @param algorithm
    305      *            the algorithm to for the {@code SecretKey}
    306      * @return the shared secret as a {@code SecretKey} of the specified
    307      *         algorithm.
    308      * @throws IllegalStateException
    309      *             if this key agreement is not complete.
    310      * @throws NoSuchAlgorithmException
    311      *             if the specified algorithm for the secret key does not
    312      *             exists.
    313      * @throws InvalidKeyException
    314      *             if a {@code SecretKey} with the specified algorithm cannot be
    315      *             created using the generated shared secret.
    316      */
    317     public final SecretKey generateSecret(String algorithm)
    318             throws IllegalStateException, NoSuchAlgorithmException,
    319             InvalidKeyException {
    320         return spiImpl.engineGenerateSecret(algorithm);
    321     }
    322 
    323 }
    324