| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package javax.crypto; |
| |
| import java.security.InvalidAlgorithmParameterException; |
| import java.security.InvalidKeyException; |
| import java.security.Key; |
| import java.security.NoSuchAlgorithmException; |
| import java.security.NoSuchProviderException; |
| import java.security.Provider; |
| import java.security.SecureRandom; |
| import java.security.Security; |
| import java.security.spec.AlgorithmParameterSpec; |
| import org.apache.harmony.security.fortress.Engine; |
| |
| /** |
| * This class provides the functionality for a key exchange protocol. This |
| * enables two or more parties to agree on a secret key for symmetric |
| * cryptography. |
| */ |
| public class KeyAgreement { |
| |
| // Used to access common engine functionality |
| private static final Engine engine = new Engine("KeyAgreement"); |
| |
| // Store SecureRandom |
| private static final SecureRandom rndm = new SecureRandom(); |
| |
| // Store used provider |
| private final Provider provider; |
| |
| // Store used spi implementation |
| private final KeyAgreementSpi spiImpl; |
| |
| // Store used algorithm name |
| private final String algorithm; |
| |
| /** |
| * Creates a new {@code KeyAgreement} instance. |
| * |
| * @param keyAgreeSpi |
| * the <b>SPI</b> delegate. |
| * @param provider |
| * the provider providing this KeyAgreement. |
| * @param algorithm |
| * the name of the key agreement algorithm. |
| */ |
| protected KeyAgreement(KeyAgreementSpi keyAgreeSpi, Provider provider, |
| String algorithm) { |
| this.provider = provider; |
| this.algorithm = algorithm; |
| this.spiImpl = keyAgreeSpi; |
| } |
| |
| /** |
| * Returns the name of the key agreement algorithm. |
| * |
| * @return the name of the key agreement algorithm. |
| */ |
| public final String getAlgorithm() { |
| return algorithm; |
| } |
| |
| /** |
| * Returns the provider for this {@code KeyAgreement} instance. |
| * |
| * @return the provider for this {@code KeyAgreement} instance. |
| */ |
| public final Provider getProvider() { |
| return provider; |
| } |
| |
| /** |
| * Creates a new {@code KeyAgreement} for the specified algorithm. |
| * |
| * @param algorithm |
| * the name of the key agreement algorithm to create. |
| * @return a key agreement for the specified algorithm. |
| * @throws NoSuchAlgorithmException |
| * if no installed provider can provide the requested algorithm. |
| * @throws NullPointerException |
| * if the specified algorithm is {@code null}. |
| */ |
| public static final KeyAgreement getInstance(String algorithm) |
| throws NoSuchAlgorithmException { |
| if (algorithm == null) { |
| throw new NullPointerException(); |
| } |
| synchronized (engine) { |
| engine.getInstance(algorithm, null); |
| return new KeyAgreement((KeyAgreementSpi) engine.spi, engine.provider, |
| algorithm); |
| } |
| } |
| |
| /** |
| * Creates a new {@code KeyAgreement} for the specified algorithm from the |
| * specified provider. |
| * |
| * @param algorithm |
| * the name of the key agreement algorithm to create. |
| * @param provider |
| * the name of the provider that provides the requested |
| * algorithm. |
| * @return a key agreement for the specified algorithm from the specified |
| * provider. |
| * @throws NoSuchAlgorithmException |
| * if the specified provider cannot provide the requested |
| * algorithm. |
| * @throws NoSuchProviderException |
| * if the specified provider does not exist. |
| * @throws IllegalArgumentException |
| * if the specified provider name is {@code null} or empty. |
| */ |
| public static final KeyAgreement getInstance(String algorithm, |
| String provider) throws NoSuchAlgorithmException, |
| NoSuchProviderException { |
| if (provider == null || provider.isEmpty()) { |
| throw new IllegalArgumentException("Provider is null or empty"); |
| } |
| Provider impProvider = Security.getProvider(provider); |
| if (impProvider == null) { |
| throw new NoSuchProviderException(provider); |
| } |
| return getInstance(algorithm, impProvider); |
| } |
| |
| /** |
| * Create a new {@code KeyAgreement} for the specified algorithm from the |
| * specified provider. |
| * |
| * @param algorithm |
| * the name of the key agreement algorithm to create. |
| * @param provider |
| * the provider that provides the requested algorithm. |
| * @return a key agreement for the specified algorithm from the specified |
| * provider. |
| * @throws NoSuchAlgorithmException |
| * if the specified provider cannot provide the requested |
| * algorithm. |
| * @throws IllegalArgumentException |
| * if the specified provider is {@code null}. |
| * @throws NullPointerException |
| * if the specified algorithm name is {@code null}. |
| */ |
| public static final KeyAgreement getInstance(String algorithm, |
| Provider provider) throws NoSuchAlgorithmException { |
| if (provider == null) { |
| throw new IllegalArgumentException("provider == null"); |
| } |
| if (algorithm == null) { |
| throw new NullPointerException(); |
| } |
| synchronized (engine) { |
| engine.getInstance(algorithm, provider, null); |
| return new KeyAgreement((KeyAgreementSpi) engine.spi, provider, |
| algorithm); |
| } |
| } |
| |
| /** |
| * Initializes this {@code KeyAgreement} with the specified key. |
| * |
| * @param key |
| * the key to initialize this key agreement. |
| * @throws InvalidKeyException |
| * if the specified key cannot be used to initialize this key |
| * agreement. |
| */ |
| public final void init(Key key) throws InvalidKeyException { |
| spiImpl.engineInit(key, rndm);//new SecureRandom()); |
| } |
| |
| /** |
| * Initializes this {@code KeyAgreement} with the specified key and the |
| * specified randomness source. |
| * |
| * @param key |
| * the key to initialize this key agreement. |
| * @param random |
| * the source for any randomness needed. |
| * @throws InvalidKeyException |
| * if the specified key cannot be used to initialize this key |
| * agreement. |
| */ |
| public final void init(Key key, SecureRandom random) |
| throws InvalidKeyException { |
| spiImpl.engineInit(key, random); |
| } |
| |
| /** |
| * Initializes this {@code KeyAgreement} with the specified key and the |
| * algorithm parameters. |
| * |
| * @param key |
| * the key to initialize this key agreement. |
| * @param params |
| * the parameters for this key agreement algorithm. |
| * @throws InvalidKeyException |
| * if the specified key cannot be used to initialize this key |
| * agreement. |
| * @throws InvalidAlgorithmParameterException |
| * if the specified parameters are invalid for this key |
| * agreement algorithm. |
| */ |
| public final void init(Key key, AlgorithmParameterSpec params) |
| throws InvalidKeyException, InvalidAlgorithmParameterException { |
| spiImpl.engineInit(key, params, rndm);//new SecureRandom()); |
| } |
| |
| /** |
| * Initializes this {@code KeyAgreement} with the specified key, algorithm |
| * parameters and randomness source. |
| * |
| * @param key |
| * the key to initialize this key agreement. |
| * @param params |
| * the parameters for this key agreement algorithm. |
| * @param random |
| * the source for any randomness needed. |
| * @throws InvalidKeyException |
| * if the specified key cannot be used to initialize this key |
| * agreement. |
| * @throws InvalidAlgorithmParameterException |
| * if the specified parameters are invalid for this key |
| * agreement algorithm. |
| */ |
| public final void init(Key key, AlgorithmParameterSpec params, |
| SecureRandom random) throws InvalidKeyException, |
| InvalidAlgorithmParameterException { |
| spiImpl.engineInit(key, params, random); |
| } |
| |
| /** |
| * Does the next (or the last) phase of the key agreement, using the |
| * specified key. |
| * |
| * @param key |
| * the key received from the other party for this phase. |
| * @param lastPhase |
| * set to {@code true} if this is the last phase of this key |
| * agreement. |
| * @return the intermediate key from this phase or {@code null} if there is |
| * no intermediate key for this phase. |
| * @throws InvalidKeyException |
| * if the specified key cannot be used in this key agreement or |
| * this phase, |
| * @throws IllegalStateException |
| * if this instance has not been initialized. |
| */ |
| public final Key doPhase(Key key, boolean lastPhase) |
| throws InvalidKeyException, IllegalStateException { |
| return spiImpl.engineDoPhase(key, lastPhase); |
| } |
| |
| /** |
| * Generates the shared secret. |
| * |
| * @return the generated shared secret. |
| * @throws IllegalStateException |
| * if this key agreement is not complete. |
| */ |
| public final byte[] generateSecret() throws IllegalStateException { |
| return spiImpl.engineGenerateSecret(); |
| } |
| |
| /** |
| * Generates the shared secret and stores it into the buffer {@code |
| * sharedSecred} at {@code offset}. |
| * |
| * @param sharedSecret |
| * the buffer to store the shared secret. |
| * @param offset |
| * the offset in the buffer. |
| * @return the number of bytes stored in the buffer. |
| * @throws IllegalStateException |
| * if this key agreement is not complete. |
| * @throws ShortBufferException |
| * if the specified buffer is too small for the shared secret. |
| */ |
| public final int generateSecret(byte[] sharedSecret, int offset) |
| throws IllegalStateException, ShortBufferException { |
| return spiImpl.engineGenerateSecret(sharedSecret, offset); |
| } |
| |
| /** |
| * Generates the shared secret. |
| * |
| * @param algorithm |
| * the algorithm to for the {@code SecretKey} |
| * @return the shared secret as a {@code SecretKey} of the specified |
| * algorithm. |
| * @throws IllegalStateException |
| * if this key agreement is not complete. |
| * @throws NoSuchAlgorithmException |
| * if the specified algorithm for the secret key does not |
| * exists. |
| * @throws InvalidKeyException |
| * if a {@code SecretKey} with the specified algorithm cannot be |
| * created using the generated shared secret. |
| */ |
| public final SecretKey generateSecret(String algorithm) |
| throws IllegalStateException, NoSuchAlgorithmException, |
| InvalidKeyException { |
| return spiImpl.engineGenerateSecret(algorithm); |
| } |
| |
| } |