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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
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;
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
36 public class KeyAgreement {
38 // Used to access common engine functionality
39 private static final Engine engine = new Engine("KeyAgreement");
42 private static final SecureRandom rndm = new SecureRandom();
44 // Store used provider
45 private final Provider provider;
47 // Store used spi implementation
48 private final KeyAgreementSpi spiImpl;
50 // Store used algorithm name
51 private final String algorithm;
54 * Creates a new {@code KeyAgreement} instance.
57 * the <b>SPI</b> delegate.
59 * the provider providing this KeyAgreement.
61 * the name of the key agreement algorithm.
63 protected KeyAgreement(KeyAgreementSpi keyAgreeSpi, Provider provider,
65 this.provider = provider;
66 this.algorithm = algorithm;
67 this.spiImpl = keyAgreeSpi;
71 * Returns the name of the key agreement algorithm.
73 * @return the name of the key agreement algorithm.
75 public final String getAlgorithm() {
80 * Returns the provider for this {@code KeyAgreement} instance.
82 * @return the provider for this {@code KeyAgreement} instance.
84 public final Provider getProvider() {
89 * Creates a new {@code KeyAgreement} for the specified 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}.
99 public static final KeyAgreement getInstance(String algorithm)
100 throws NoSuchAlgorithmException {
101 if (algorithm == null) {
102 throw new NullPointerException();
104 synchronized (engine) {
105 engine.getInstance(algorithm, null);
106 return new KeyAgreement((KeyAgreementSpi) engine.spi, engine.provider,
112 * Creates a new {@code KeyAgreement} for the specified algorithm from the
113 * specified provider.
116 * the name of the key agreement algorithm to create.
118 * the name of the provider that provides the requested
120 * @return a key agreement for the specified algorithm from the specified
122 * @throws NoSuchAlgorithmException
123 * if the specified provider cannot provide the requested
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.
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");
136 Provider impProvider = Security.getProvider(provider);
137 if (impProvider == null) {
138 throw new NoSuchProviderException(provider);
140 return getInstance(algorithm, impProvider);
144 * Create a new {@code KeyAgreement} for the specified algorithm from the
145 * specified provider.
148 * the name of the key agreement algorithm to create.
150 * the provider that provides the requested algorithm.
151 * @return a key agreement for the specified algorithm from the specified
153 * @throws NoSuchAlgorithmException
154 * if the specified provider cannot provide the requested
156 * @throws IllegalArgumentException
157 * if the specified provider is {@code null}.
158 * @throws NullPointerException
159 * if the specified algorithm name is {@code null}.
161 public static final KeyAgreement getInstance(String algorithm,
162 Provider provider) throws NoSuchAlgorithmException {
163 if (provider == null) {
164 throw new IllegalArgumentException("provider == null");
166 if (algorithm == null) {
167 throw new NullPointerException();
169 synchronized (engine) {
170 engine.getInstance(algorithm, provider, null);
171 return new KeyAgreement((KeyAgreementSpi) engine.spi, provider,
177 * Initializes this {@code KeyAgreement} with the specified key.
180 * the key to initialize this key agreement.
181 * @throws InvalidKeyException
182 * if the specified key cannot be used to initialize this key
185 public final void init(Key key) throws InvalidKeyException {
186 spiImpl.engineInit(key, rndm);//new SecureRandom());
190 * Initializes this {@code KeyAgreement} with the specified key and the
191 * specified randomness source.
194 * the key to initialize this key agreement.
196 * the source for any randomness needed.
197 * @throws InvalidKeyException
198 * if the specified key cannot be used to initialize this key
201 public final void init(Key key, SecureRandom random)
202 throws InvalidKeyException {
203 spiImpl.engineInit(key, random);
207 * Initializes this {@code KeyAgreement} with the specified key and the
208 * algorithm parameters.
211 * the key to initialize this key agreement.
213 * the parameters for this key agreement algorithm.
214 * @throws InvalidKeyException
215 * if the specified key cannot be used to initialize this key
217 * @throws InvalidAlgorithmParameterException
218 * if the specified parameters are invalid for this key
219 * agreement algorithm.
221 public final void init(Key key, AlgorithmParameterSpec params)
222 throws InvalidKeyException, InvalidAlgorithmParameterException {
223 spiImpl.engineInit(key, params, rndm);//new SecureRandom());
227 * Initializes this {@code KeyAgreement} with the specified key, algorithm
228 * parameters and randomness source.
231 * the key to initialize this key agreement.
233 * the parameters for this key agreement algorithm.
235 * the source for any randomness needed.
236 * @throws InvalidKeyException
237 * if the specified key cannot be used to initialize this key
239 * @throws InvalidAlgorithmParameterException
240 * if the specified parameters are invalid for this key
241 * agreement algorithm.
243 public final void init(Key key, AlgorithmParameterSpec params,
244 SecureRandom random) throws InvalidKeyException,
245 InvalidAlgorithmParameterException {
246 spiImpl.engineInit(key, params, random);
250 * Does the next (or the last) phase of the key agreement, using the
254 * the key received from the other party for this phase.
256 * set to {@code true} if this is the last phase of this key
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
263 * @throws IllegalStateException
264 * if this instance has not been initialized.
266 public final Key doPhase(Key key, boolean lastPhase)
267 throws InvalidKeyException, IllegalStateException {
268 return spiImpl.engineDoPhase(key, lastPhase);
272 * Generates the shared secret.
274 * @return the generated shared secret.
275 * @throws IllegalStateException
276 * if this key agreement is not complete.
278 public final byte[] generateSecret() throws IllegalStateException {
279 return spiImpl.engineGenerateSecret();
283 * Generates the shared secret and stores it into the buffer {@code
284 * sharedSecred} at {@code offset}.
286 * @param sharedSecret
287 * the buffer to store the shared secret.
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.
296 public final int generateSecret(byte[] sharedSecret, int offset)
297 throws IllegalStateException, ShortBufferException {
298 return spiImpl.engineGenerateSecret(sharedSecret, offset);
302 * Generates the shared secret.
305 * the algorithm to for the {@code SecretKey}
306 * @return the shared secret as a {@code SecretKey} of the specified
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
313 * @throws InvalidKeyException
314 * if a {@code SecretKey} with the specified algorithm cannot be
315 * created using the generated shared secret.
317 public final SecretKey generateSecret(String algorithm)
318 throws IllegalStateException, NoSuchAlgorithmException,
319 InvalidKeyException {
320 return spiImpl.engineGenerateSecret(algorithm);