• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 RANDOM = 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      */
KeyAgreement(KeyAgreementSpi keyAgreeSpi, Provider provider, String algorithm)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      */
getAlgorithm()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      */
getProvider()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      */
getInstance(String algorithm)99     public static final KeyAgreement getInstance(String algorithm)
100             throws NoSuchAlgorithmException {
101         if (algorithm == null) {
102             throw new NullPointerException("algorithm == null");
103         }
104         Engine.SpiAndProvider sap = ENGINE.getInstance(algorithm, null);
105         return new KeyAgreement((KeyAgreementSpi) sap.spi, sap.provider, algorithm);
106     }
107 
108     /**
109      * Creates a new {@code KeyAgreement} for the specified algorithm from the
110      * specified provider.
111      *
112      * @param algorithm
113      *            the name of the key agreement algorithm to create.
114      * @param provider
115      *            the name of the provider that provides the requested
116      *            algorithm.
117      * @return a key agreement for the specified algorithm from the specified
118      *         provider.
119      * @throws NoSuchAlgorithmException
120      *             if the specified provider cannot provide the requested
121      *             algorithm.
122      * @throws NoSuchProviderException
123      *             if the specified provider does not exist.
124      * @throws IllegalArgumentException
125      *             if the specified provider name is {@code null} or empty.
126      */
getInstance(String algorithm, String provider)127     public static final KeyAgreement getInstance(String algorithm,
128             String provider) throws NoSuchAlgorithmException,
129             NoSuchProviderException {
130         if (provider == null || provider.isEmpty()) {
131             throw new IllegalArgumentException("Provider is null or empty");
132         }
133         Provider impProvider = Security.getProvider(provider);
134         if (impProvider == null) {
135             throw new NoSuchProviderException(provider);
136         }
137         return getInstance(algorithm, impProvider);
138     }
139 
140     /**
141      * Create a new {@code KeyAgreement} for the specified algorithm from the
142      * specified provider.
143      *
144      * @param algorithm
145      *            the name of the key agreement algorithm to create.
146      * @param provider
147      *            the provider that provides the requested algorithm.
148      * @return a key agreement for the specified algorithm from the specified
149      *         provider.
150      * @throws NoSuchAlgorithmException
151      *             if the specified provider cannot provide the requested
152      *             algorithm.
153      * @throws IllegalArgumentException
154      *             if the specified provider is {@code null}.
155      * @throws NullPointerException
156      *             if the specified algorithm name is {@code null}.
157      */
getInstance(String algorithm, Provider provider)158     public static final KeyAgreement getInstance(String algorithm,
159             Provider provider) throws NoSuchAlgorithmException {
160         if (provider == null) {
161             throw new IllegalArgumentException("provider == null");
162         }
163         if (algorithm == null) {
164             throw new NullPointerException("algorithm == null");
165         }
166         Object spi = ENGINE.getInstance(algorithm, provider, null);
167         return new KeyAgreement((KeyAgreementSpi) spi, provider, algorithm);
168     }
169 
170     /**
171      * Initializes this {@code KeyAgreement} with the specified key.
172      *
173      * @param key
174      *            the key to initialize this key agreement.
175      * @throws InvalidKeyException
176      *             if the specified key cannot be used to initialize this key
177      *             agreement.
178      */
init(Key key)179     public final void init(Key key) throws InvalidKeyException {
180         spiImpl.engineInit(key, RANDOM);//new SecureRandom());
181     }
182 
183     /**
184      * Initializes this {@code KeyAgreement} with the specified key and the
185      * specified randomness source.
186      *
187      * @param key
188      *            the key to initialize this key agreement.
189      * @param random
190      *            the source for any randomness needed.
191      * @throws InvalidKeyException
192      *             if the specified key cannot be used to initialize this key
193      *             agreement.
194      */
init(Key key, SecureRandom random)195     public final void init(Key key, SecureRandom random)
196             throws InvalidKeyException {
197         spiImpl.engineInit(key, random);
198     }
199 
200     /**
201      * Initializes this {@code KeyAgreement} with the specified key and the
202      * algorithm parameters.
203      *
204      * @param key
205      *            the key to initialize this key agreement.
206      * @param params
207      *            the parameters for this key agreement algorithm.
208      * @throws InvalidKeyException
209      *             if the specified key cannot be used to initialize this key
210      *             agreement.
211      * @throws InvalidAlgorithmParameterException
212      *             if the specified parameters are invalid for this key
213      *             agreement algorithm.
214      */
init(Key key, AlgorithmParameterSpec params)215     public final void init(Key key, AlgorithmParameterSpec params)
216             throws InvalidKeyException, InvalidAlgorithmParameterException {
217         spiImpl.engineInit(key, params, RANDOM);//new SecureRandom());
218     }
219 
220     /**
221      * Initializes this {@code KeyAgreement} with the specified key, algorithm
222      * parameters and randomness source.
223      *
224      * @param key
225      *            the key to initialize this key agreement.
226      * @param params
227      *            the parameters for this key agreement algorithm.
228      * @param random
229      *            the source for any randomness needed.
230      * @throws InvalidKeyException
231      *             if the specified key cannot be used to initialize this key
232      *             agreement.
233      * @throws InvalidAlgorithmParameterException
234      *             if the specified parameters are invalid for this key
235      *             agreement algorithm.
236      */
init(Key key, AlgorithmParameterSpec params, SecureRandom random)237     public final void init(Key key, AlgorithmParameterSpec params,
238             SecureRandom random) throws InvalidKeyException,
239             InvalidAlgorithmParameterException {
240         spiImpl.engineInit(key, params, random);
241     }
242 
243     /**
244      * Does the next (or the last) phase of the key agreement, using the
245      * specified key.
246      *
247      * @param key
248      *            the key received from the other party for this phase.
249      * @param lastPhase
250      *            set to {@code true} if this is the last phase of this key
251      *            agreement.
252      * @return the intermediate key from this phase or {@code null} if there is
253      *         no intermediate key for this phase.
254      * @throws InvalidKeyException
255      *             if the specified key cannot be used in this key agreement or
256      *             this phase,
257      * @throws IllegalStateException
258      *             if this instance has not been initialized.
259      */
doPhase(Key key, boolean lastPhase)260     public final Key doPhase(Key key, boolean lastPhase)
261             throws InvalidKeyException, IllegalStateException {
262         return spiImpl.engineDoPhase(key, lastPhase);
263     }
264 
265     /**
266      * Generates the shared secret.
267      *
268      * @return the generated shared secret.
269      * @throws IllegalStateException
270      *             if this key agreement is not complete.
271      */
generateSecret()272     public final byte[] generateSecret() throws IllegalStateException {
273         return spiImpl.engineGenerateSecret();
274     }
275 
276     /**
277      * Generates the shared secret and stores it into the buffer {@code
278      * sharedSecred} at {@code offset}.
279      *
280      * @param sharedSecret
281      *            the buffer to store the shared secret.
282      * @param offset
283      *            the offset in the buffer.
284      * @return the number of bytes stored in the buffer.
285      * @throws IllegalStateException
286      *             if this key agreement is not complete.
287      * @throws ShortBufferException
288      *             if the specified buffer is too small for the shared secret.
289      */
generateSecret(byte[] sharedSecret, int offset)290     public final int generateSecret(byte[] sharedSecret, int offset)
291             throws IllegalStateException, ShortBufferException {
292         return spiImpl.engineGenerateSecret(sharedSecret, offset);
293     }
294 
295     /**
296      * Generates the shared secret.
297      *
298      * @param algorithm
299      *            the algorithm to for the {@code SecretKey}
300      * @return the shared secret as a {@code SecretKey} of the specified
301      *         algorithm.
302      * @throws IllegalStateException
303      *             if this key agreement is not complete.
304      * @throws NoSuchAlgorithmException
305      *             if the specified algorithm for the secret key does not
306      *             exists.
307      * @throws InvalidKeyException
308      *             if a {@code SecretKey} with the specified algorithm cannot be
309      *             created using the generated shared secret.
310      */
generateSecret(String algorithm)311     public final SecretKey generateSecret(String algorithm)
312             throws IllegalStateException, NoSuchAlgorithmException,
313             InvalidKeyException {
314         return spiImpl.engineGenerateSecret(algorithm);
315     }
316 
317 }
318