blob: fd79680c13866dfac204470f713f565db2d006fd [file] [log] [blame]
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001/*
Narayan Kamath2c87ad32015-12-21 13:53:32 +00002 * Copyright (C) 2014 The Android Open Source Project
Adam Vartanian96635862017-05-25 14:39:26 +01003 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00004 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation. Oracle designates this
9 * particular file as subject to the "Classpath" exception as provided
10 * by Oracle in the LICENSE file that accompanied this code.
11 *
12 * This code is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * version 2 for more details (a copy is included in the LICENSE file that
16 * accompanied this code).
17 *
18 * You should have received a copy of the GNU General Public License version
19 * 2 along with this work; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23 * or visit www.oracle.com if you need additional information or have any
24 * questions.
25 */
26
27package javax.crypto;
28
29import java.util.*;
30
31import java.security.*;
32import java.security.Provider.Service;
33import java.security.spec.*;
34
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +000035import sun.security.jca.*;
36import sun.security.jca.GetInstance.Instance;
37
38/**
39 * This class provides the functionality of a key agreement (or key
40 * exchange) protocol.
41 * <p>
42 * The keys involved in establishing a shared secret are created by one of the
43 * key generators (<code>KeyPairGenerator</code> or
44 * <code>KeyGenerator</code>), a <code>KeyFactory</code>, or as a result from
45 * an intermediate phase of the key agreement protocol.
46 *
47 * <p> For each of the correspondents in the key exchange, <code>doPhase</code>
48 * needs to be called. For example, if this key exchange is with one other
49 * party, <code>doPhase</code> needs to be called once, with the
50 * <code>lastPhase</code> flag set to <code>true</code>.
51 * If this key exchange is
52 * with two other parties, <code>doPhase</code> needs to be called twice,
53 * the first time setting the <code>lastPhase</code> flag to
54 * <code>false</code>, and the second time setting it to <code>true</code>.
55 * There may be any number of parties involved in a key exchange.
56 *
Przemyslaw Szczepaniak444325b2016-05-18 13:09:39 +010057 * <p> Android provides the following <code>KeyAgreement</code> algorithms:
58 * <table>
Adam Vartaniana52aa9f2017-03-20 11:32:38 +000059 * <thead>
60 * <tr>
61 * <th>Algorithm</th>
62 * <th>Supported API Levels</th>
63 * </tr>
64 * </thead>
65 * <tbody>
66 * <tr>
67 * <td>DH</td>
68 * <td>1+</td>
69 * </tr>
70 * <tr>
71 * <td>ECDH</td>
72 * <td>11+</td>
73 * </tr>
74 * </tbody>
Przemyslaw Szczepaniak444325b2016-05-18 13:09:39 +010075 * </table>
76 *
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +000077 * This algorithm is described in the <a href=
Tobias Thierer6bd07db2019-04-03 18:06:18 +010078 * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyAgreement">
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +000079 * KeyAgreement section</a> of the
80 * Java Cryptography Architecture Standard Algorithm Name Documentation.
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +000081 *
82 * @author Jan Luehe
83 *
84 * @see KeyGenerator
85 * @see SecretKey
86 * @since 1.4
87 */
88
89public class KeyAgreement {
90
Tobias Thierer9eca2692017-04-12 18:16:06 +010091 // Android-removed: this debugging mechanism is not used in Android.
92 /*
Adam Vartanian96635862017-05-25 14:39:26 +010093 private static final Debug debug =
94 Debug.getInstance("jca", "KeyAgreement");
95
Sergio Giro17982542016-08-03 19:21:52 +010096 private static final Debug pdebug =
97 Debug.getInstance("provider", "Provider");
98 private static final boolean skipDebug =
99 Debug.isOn("engine=") && !Debug.isOn("keyagreement");
100 */
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000101
102 // The provider
103 private Provider provider;
104
105 // The provider implementation (delegate)
106 private KeyAgreementSpi spi;
107
108 // The name of the key agreement algorithm.
109 private final String algorithm;
110
Adam Vartanian96635862017-05-25 14:39:26 +0100111 // BEGIN Android-removed: Redo the provider selection logic to allow reselecting provider.
112 // When only the algorithm is specified, we want to allow the KeyAgreement provider for that
113 // algorithm to change if multiple providers exist and they support different subsets of
114 // keys. To that end, we don't hold an iterator and exhaust it when we need to choose
115 // a provider like the upstream implementation, we reestablish the list of providers
116 // each time.
117 /*
118 // next service to try in provider selection
119 // null once provider is selected
120 private Service firstService;
121
122 // remaining services to try in provider selection
123 // null once provider is selected
124 private Iterator<Service> serviceIterator;
125 */
126 // END Android-removed: Redo the provider selection logic to allow reselecting provider.
127
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000128 private final Object lock;
129
130 /**
131 * Creates a KeyAgreement object.
132 *
133 * @param keyAgreeSpi the delegate
134 * @param provider the provider
135 * @param algorithm the algorithm
136 */
137 protected KeyAgreement(KeyAgreementSpi keyAgreeSpi, Provider provider,
138 String algorithm) {
139 this.spi = keyAgreeSpi;
140 this.provider = provider;
141 this.algorithm = algorithm;
142 lock = null;
143 }
144
Adam Vartanian96635862017-05-25 14:39:26 +0100145 // Android-changed: Remove Service and Iterator from constructor args.
Piotr Jastrzebski875528b2015-04-10 12:23:00 +0100146 private KeyAgreement(String algorithm) {
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000147 this.algorithm = algorithm;
148 lock = new Object();
149 }
150
151 /**
152 * Returns the algorithm name of this <code>KeyAgreement</code> object.
153 *
154 * <p>This is the same name that was specified in one of the
155 * <code>getInstance</code> calls that created this
156 * <code>KeyAgreement</code> object.
157 *
158 * @return the algorithm name of this <code>KeyAgreement</code> object.
159 */
160 public final String getAlgorithm() {
161 return this.algorithm;
162 }
163
164 /**
165 * Returns a <code>KeyAgreement</code> object that implements the
166 * specified key agreement algorithm.
167 *
168 * <p> This method traverses the list of registered security Providers,
169 * starting with the most preferred Provider.
170 * A new KeyAgreement object encapsulating the
171 * KeyAgreementSpi implementation from the first
172 * Provider that supports the specified algorithm is returned.
173 *
174 * <p> Note that the list of registered providers may be retrieved via
175 * the {@link Security#getProviders() Security.getProviders()} method.
176 *
177 * @param algorithm the standard name of the requested key agreement
178 * algorithm.
179 * See the KeyAgreement section in the <a href=
Tobias Thierer6bd07db2019-04-03 18:06:18 +0100180 * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyAgreement">
Sergio Giro17982542016-08-03 19:21:52 +0100181 * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000182 * for information about standard algorithm names.
183 *
184 * @return the new <code>KeyAgreement</code> object.
185 *
186 * @exception NullPointerException if the specified algorithm
187 * is null.
188 *
189 * @exception NoSuchAlgorithmException if no Provider supports a
190 * KeyAgreementSpi implementation for the
191 * specified algorithm.
192 *
193 * @see java.security.Provider
194 */
195 public static final KeyAgreement getInstance(String algorithm)
196 throws NoSuchAlgorithmException {
Sergio Giro17982542016-08-03 19:21:52 +0100197 List<Service> services =
198 GetInstance.getServices("KeyAgreement", algorithm);
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000199 // make sure there is at least one service from a signed provider
Sergio Giro17982542016-08-03 19:21:52 +0100200 Iterator<Service> t = services.iterator();
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000201 while (t.hasNext()) {
Sergio Giro17982542016-08-03 19:21:52 +0100202 Service s = t.next();
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000203 if (JceSecurity.canUseProvider(s.getProvider()) == false) {
204 continue;
205 }
Adam Vartanian96635862017-05-25 14:39:26 +0100206 // Android-changed: Remove Service and Iterator from constructor args.
207 // return new KeyAgreement(s, t, algorithm);
Piotr Jastrzebski875528b2015-04-10 12:23:00 +0100208 return new KeyAgreement(algorithm);
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000209 }
210 throw new NoSuchAlgorithmException
211 ("Algorithm " + algorithm + " not available");
212 }
213
214 /**
215 * Returns a <code>KeyAgreement</code> object that implements the
216 * specified key agreement algorithm.
217 *
218 * <p> A new KeyAgreement object encapsulating the
219 * KeyAgreementSpi implementation from the specified provider
220 * is returned. The specified provider must be registered
221 * in the security provider list.
222 *
223 * <p> Note that the list of registered providers may be retrieved via
224 * the {@link Security#getProviders() Security.getProviders()} method.
225 *
226 * @param algorithm the standard name of the requested key agreement
227 * algorithm.
228 * See the KeyAgreement section in the <a href=
Tobias Thierer6bd07db2019-04-03 18:06:18 +0100229 * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyAgreement">
Sergio Giro17982542016-08-03 19:21:52 +0100230 * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000231 * for information about standard algorithm names.
232 *
233 * @param provider the name of the provider.
234 *
235 * @return the new <code>KeyAgreement</code> object.
236 *
237 * @exception NullPointerException if the specified algorithm
238 * is null.
239 *
240 * @exception NoSuchAlgorithmException if a KeyAgreementSpi
241 * implementation for the specified algorithm is not
242 * available from the specified provider.
243 *
244 * @exception NoSuchProviderException if the specified provider is not
245 * registered in the security provider list.
246 *
247 * @exception IllegalArgumentException if the <code>provider</code>
248 * is null or empty.
249 *
250 * @see java.security.Provider
251 */
252 public static final KeyAgreement getInstance(String algorithm,
253 String provider) throws NoSuchAlgorithmException,
254 NoSuchProviderException {
Adam Vartanian491d8882017-10-10 11:43:32 +0100255 // Android-added: Check for Bouncy Castle deprecation
256 Providers.checkBouncyCastleDeprecation(provider, "KeyAgreement", algorithm);
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000257 Instance instance = JceSecurity.getInstance
258 ("KeyAgreement", KeyAgreementSpi.class, algorithm, provider);
259 return new KeyAgreement((KeyAgreementSpi)instance.impl,
260 instance.provider, algorithm);
261 }
262
263 /**
264 * Returns a <code>KeyAgreement</code> object that implements the
265 * specified key agreement algorithm.
266 *
267 * <p> A new KeyAgreement object encapsulating the
268 * KeyAgreementSpi implementation from the specified Provider
269 * object is returned. Note that the specified Provider object
270 * does not have to be registered in the provider list.
271 *
272 * @param algorithm the standard name of the requested key agreement
273 * algorithm.
274 * See the KeyAgreement section in the <a href=
Tobias Thierer6bd07db2019-04-03 18:06:18 +0100275 * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyAgreement">
Sergio Giro17982542016-08-03 19:21:52 +0100276 * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000277 * for information about standard algorithm names.
278 *
279 * @param provider the provider.
280 *
281 * @return the new <code>KeyAgreement</code> object.
282 *
283 * @exception NullPointerException if the specified algorithm
284 * is null.
285 *
286 * @exception NoSuchAlgorithmException if a KeyAgreementSpi
287 * implementation for the specified algorithm is not available
288 * from the specified Provider object.
289 *
290 * @exception IllegalArgumentException if the <code>provider</code>
291 * is null.
292 *
293 * @see java.security.Provider
294 */
295 public static final KeyAgreement getInstance(String algorithm,
296 Provider provider) throws NoSuchAlgorithmException {
Adam Vartanian491d8882017-10-10 11:43:32 +0100297 // Android-added: Check for Bouncy Castle deprecation
298 Providers.checkBouncyCastleDeprecation(provider, "KeyAgreement", algorithm);
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000299 Instance instance = JceSecurity.getInstance
300 ("KeyAgreement", KeyAgreementSpi.class, algorithm, provider);
301 return new KeyAgreement((KeyAgreementSpi)instance.impl,
302 instance.provider, algorithm);
303 }
304
305 // max number of debug warnings to print from chooseFirstProvider()
306 private static int warnCount = 10;
307
308 /**
309 * Choose the Spi from the first provider available. Used if
310 * delayed provider selection is not possible because init()
311 * is not the first method called.
312 */
313 void chooseFirstProvider() {
314 if (spi != null) {
315 return;
316 }
317 synchronized (lock) {
318 if (spi != null) {
319 return;
320 }
Tobias Thierer9eca2692017-04-12 18:16:06 +0100321 // Android-removed: this debugging mechanism is not used in Android.
322 /*
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000323 if (debug != null) {
324 int w = --warnCount;
325 if (w >= 0) {
326 debug.println("KeyAgreement.init() not first method "
327 + "called, disabling delayed provider selection");
328 if (w == 0) {
329 debug.println("Further warnings of this type will "
330 + "be suppressed");
331 }
332 new Exception("Call trace").printStackTrace();
333 }
334 }
Sergio Giro17982542016-08-03 19:21:52 +0100335 */
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000336 Exception lastException = null;
Adam Vartanian96635862017-05-25 14:39:26 +0100337 // Android-changed: Provider selection; loop over a new list each time.
Piotr Jastrzebski875528b2015-04-10 12:23:00 +0100338 for (Service s : GetInstance.getServices("KeyAgreement", algorithm)) {
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000339 if (JceSecurity.canUseProvider(s.getProvider()) == false) {
340 continue;
341 }
342 try {
343 Object obj = s.newInstance(null);
344 if (obj instanceof KeyAgreementSpi == false) {
345 continue;
346 }
347 spi = (KeyAgreementSpi)obj;
348 provider = s.getProvider();
Adam Vartanian96635862017-05-25 14:39:26 +0100349 // Android-removed: Provider selection; loop over a new list each time.
350 /*
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000351 // not needed any more
Adam Vartanian96635862017-05-25 14:39:26 +0100352 firstService = null;
353 serviceIterator = null;
354 */
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000355 return;
356 } catch (Exception e) {
357 lastException = e;
358 }
359 }
360 ProviderException e = new ProviderException
361 ("Could not construct KeyAgreementSpi instance");
362 if (lastException != null) {
363 e.initCause(lastException);
364 }
365 throw e;
366 }
367 }
368
369 private final static int I_NO_PARAMS = 1;
370 private final static int I_PARAMS = 2;
371
372 private void implInit(KeyAgreementSpi spi, int type, Key key,
373 AlgorithmParameterSpec params, SecureRandom random)
374 throws InvalidKeyException, InvalidAlgorithmParameterException {
375 if (type == I_NO_PARAMS) {
376 spi.engineInit(key, random);
377 } else { // I_PARAMS
378 spi.engineInit(key, params, random);
379 }
380 }
381
382 private void chooseProvider(int initType, Key key,
383 AlgorithmParameterSpec params, SecureRandom random)
384 throws InvalidKeyException, InvalidAlgorithmParameterException {
385 synchronized (lock) {
Adam Vartanian96635862017-05-25 14:39:26 +0100386 // Android-changed: Use the currently-selected provider only if no key was provided.
387 // if (spi != null) {
Piotr Jastrzebski875528b2015-04-10 12:23:00 +0100388 if (spi != null && key == null) {
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000389 implInit(spi, initType, key, params, random);
390 return;
391 }
392 Exception lastException = null;
Adam Vartanian96635862017-05-25 14:39:26 +0100393 // Android-changed: Provider selection; loop over a new list each time.
Piotr Jastrzebski875528b2015-04-10 12:23:00 +0100394 for (Service s : GetInstance.getServices("KeyAgreement", algorithm)) {
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000395 // if provider says it does not support this key, ignore it
396 if (s.supportsParameter(key) == false) {
397 continue;
398 }
399 if (JceSecurity.canUseProvider(s.getProvider()) == false) {
400 continue;
401 }
402 try {
403 KeyAgreementSpi spi = (KeyAgreementSpi)s.newInstance(null);
404 implInit(spi, initType, key, params, random);
405 provider = s.getProvider();
406 this.spi = spi;
Adam Vartanian96635862017-05-25 14:39:26 +0100407 // Android-removed: Provider selection; loop over a new list each time.
408 /*
409 firstService = null;
410 serviceIterator = null;
411 */
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000412 return;
413 } catch (Exception e) {
414 // NoSuchAlgorithmException from newInstance()
415 // InvalidKeyException from init()
416 // RuntimeException (ProviderException) from init()
417 if (lastException == null) {
418 lastException = e;
419 }
420 }
421 }
422 // no working provider found, fail
423 if (lastException instanceof InvalidKeyException) {
424 throw (InvalidKeyException)lastException;
425 }
426 if (lastException instanceof InvalidAlgorithmParameterException) {
427 throw (InvalidAlgorithmParameterException)lastException;
428 }
429 if (lastException instanceof RuntimeException) {
430 throw (RuntimeException)lastException;
431 }
432 String kName = (key != null) ? key.getClass().getName() : "(null)";
433 throw new InvalidKeyException
434 ("No installed provider supports this key: "
435 + kName, lastException);
436 }
437 }
438
439 /**
440 * Returns the provider of this <code>KeyAgreement</code> object.
441 *
442 * @return the provider of this <code>KeyAgreement</code> object
443 */
444 public final Provider getProvider() {
445 chooseFirstProvider();
446 return this.provider;
447 }
448
449 /**
450 * Initializes this key agreement with the given key, which is required to
451 * contain all the algorithm parameters required for this key agreement.
452 *
453 * <p> If this key agreement requires any random bytes, it will get
454 * them using the
Sergio Giro17982542016-08-03 19:21:52 +0100455 * {@link java.security.SecureRandom}
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000456 * implementation of the highest-priority
457 * installed provider as the source of randomness.
458 * (If none of the installed providers supply an implementation of
459 * SecureRandom, a system-provided source of randomness will be used.)
460 *
461 * @param key the party's private information. For example, in the case
462 * of the Diffie-Hellman key agreement, this would be the party's own
463 * Diffie-Hellman private key.
464 *
465 * @exception InvalidKeyException if the given key is
466 * inappropriate for this key agreement, e.g., is of the wrong type or
467 * has an incompatible algorithm type.
468 */
469 public final void init(Key key) throws InvalidKeyException {
470 init(key, JceSecurity.RANDOM);
471 }
472
473 /**
474 * Initializes this key agreement with the given key and source of
475 * randomness. The given key is required to contain all the algorithm
476 * parameters required for this key agreement.
477 *
478 * <p> If the key agreement algorithm requires random bytes, it gets them
479 * from the given source of randomness, <code>random</code>.
480 * However, if the underlying
481 * algorithm implementation does not require any random bytes,
482 * <code>random</code> is ignored.
483 *
484 * @param key the party's private information. For example, in the case
485 * of the Diffie-Hellman key agreement, this would be the party's own
486 * Diffie-Hellman private key.
487 * @param random the source of randomness
488 *
489 * @exception InvalidKeyException if the given key is
490 * inappropriate for this key agreement, e.g., is of the wrong type or
491 * has an incompatible algorithm type.
492 */
493 public final void init(Key key, SecureRandom random)
494 throws InvalidKeyException {
Adam Vartanian96635862017-05-25 14:39:26 +0100495 // Android-changed: Use the currently-selected provider only if no key was provided.
496 // if (spi != null) {
Piotr Jastrzebski875528b2015-04-10 12:23:00 +0100497 if (spi != null && (key == null || lock == null)) {
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000498 spi.engineInit(key, random);
499 } else {
500 try {
501 chooseProvider(I_NO_PARAMS, key, null, random);
502 } catch (InvalidAlgorithmParameterException e) {
503 // should never occur
504 throw new InvalidKeyException(e);
505 }
506 }
Sergio Giro17982542016-08-03 19:21:52 +0100507
Tobias Thierer9eca2692017-04-12 18:16:06 +0100508 // Android-removed: this debugging mechanism is not used in Android.
509 /*
Sergio Giro17982542016-08-03 19:21:52 +0100510 if (!skipDebug && pdebug != null) {
511 pdebug.println("KeyAgreement." + algorithm + " algorithm from: " +
512 this.provider.getName());
513 }
514 */
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000515 }
516
517 /**
518 * Initializes this key agreement with the given key and set of
519 * algorithm parameters.
520 *
521 * <p> If this key agreement requires any random bytes, it will get
522 * them using the
Sergio Giro17982542016-08-03 19:21:52 +0100523 * {@link java.security.SecureRandom}
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000524 * implementation of the highest-priority
525 * installed provider as the source of randomness.
526 * (If none of the installed providers supply an implementation of
527 * SecureRandom, a system-provided source of randomness will be used.)
528 *
529 * @param key the party's private information. For example, in the case
530 * of the Diffie-Hellman key agreement, this would be the party's own
531 * Diffie-Hellman private key.
532 * @param params the key agreement parameters
533 *
534 * @exception InvalidKeyException if the given key is
535 * inappropriate for this key agreement, e.g., is of the wrong type or
536 * has an incompatible algorithm type.
537 * @exception InvalidAlgorithmParameterException if the given parameters
538 * are inappropriate for this key agreement.
539 */
540 public final void init(Key key, AlgorithmParameterSpec params)
541 throws InvalidKeyException, InvalidAlgorithmParameterException
542 {
543 init(key, params, JceSecurity.RANDOM);
544 }
545
546 /**
547 * Initializes this key agreement with the given key, set of
548 * algorithm parameters, and source of randomness.
549 *
550 * @param key the party's private information. For example, in the case
551 * of the Diffie-Hellman key agreement, this would be the party's own
552 * Diffie-Hellman private key.
553 * @param params the key agreement parameters
554 * @param random the source of randomness
555 *
556 * @exception InvalidKeyException if the given key is
557 * inappropriate for this key agreement, e.g., is of the wrong type or
558 * has an incompatible algorithm type.
559 * @exception InvalidAlgorithmParameterException if the given parameters
560 * are inappropriate for this key agreement.
561 */
562 public final void init(Key key, AlgorithmParameterSpec params,
563 SecureRandom random)
564 throws InvalidKeyException, InvalidAlgorithmParameterException
565 {
566 if (spi != null) {
567 spi.engineInit(key, params, random);
568 } else {
569 chooseProvider(I_PARAMS, key, params, random);
570 }
Sergio Giro17982542016-08-03 19:21:52 +0100571
Tobias Thierer9eca2692017-04-12 18:16:06 +0100572 // Android-removed: this debugging mechanism is not used in Android.
573 /*
Sergio Giro17982542016-08-03 19:21:52 +0100574 if (!skipDebug && pdebug != null) {
575 pdebug.println("KeyAgreement." + algorithm + " algorithm from: " +
576 this.provider.getName());
577 }
578 */
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000579 }
580
581 /**
582 * Executes the next phase of this key agreement with the given
583 * key that was received from one of the other parties involved in this key
584 * agreement.
585 *
586 * @param key the key for this phase. For example, in the case of
587 * Diffie-Hellman between 2 parties, this would be the other party's
588 * Diffie-Hellman public key.
589 * @param lastPhase flag which indicates whether or not this is the last
590 * phase of this key agreement.
591 *
592 * @return the (intermediate) key resulting from this phase, or null
593 * if this phase does not yield a key
594 *
595 * @exception InvalidKeyException if the given key is inappropriate for
596 * this phase.
597 * @exception IllegalStateException if this key agreement has not been
598 * initialized.
599 */
600 public final Key doPhase(Key key, boolean lastPhase)
601 throws InvalidKeyException, IllegalStateException
602 {
603 chooseFirstProvider();
604 return spi.engineDoPhase(key, lastPhase);
605 }
606
607 /**
608 * Generates the shared secret and returns it in a new buffer.
609 *
610 * <p>This method resets this <code>KeyAgreement</code> object, so that it
611 * can be reused for further key agreements. Unless this key agreement is
612 * reinitialized with one of the <code>init</code> methods, the same
613 * private information and algorithm parameters will be used for
614 * subsequent key agreements.
615 *
616 * @return the new buffer with the shared secret
617 *
618 * @exception IllegalStateException if this key agreement has not been
619 * completed yet
620 */
621 public final byte[] generateSecret() throws IllegalStateException {
622 chooseFirstProvider();
623 return spi.engineGenerateSecret();
624 }
625
626 /**
627 * Generates the shared secret, and places it into the buffer
628 * <code>sharedSecret</code>, beginning at <code>offset</code> inclusive.
629 *
630 * <p>If the <code>sharedSecret</code> buffer is too small to hold the
631 * result, a <code>ShortBufferException</code> is thrown.
632 * In this case, this call should be repeated with a larger output buffer.
633 *
634 * <p>This method resets this <code>KeyAgreement</code> object, so that it
635 * can be reused for further key agreements. Unless this key agreement is
636 * reinitialized with one of the <code>init</code> methods, the same
637 * private information and algorithm parameters will be used for
638 * subsequent key agreements.
639 *
640 * @param sharedSecret the buffer for the shared secret
641 * @param offset the offset in <code>sharedSecret</code> where the
642 * shared secret will be stored
643 *
644 * @return the number of bytes placed into <code>sharedSecret</code>
645 *
646 * @exception IllegalStateException if this key agreement has not been
647 * completed yet
648 * @exception ShortBufferException if the given output buffer is too small
649 * to hold the secret
650 */
651 public final int generateSecret(byte[] sharedSecret, int offset)
652 throws IllegalStateException, ShortBufferException
653 {
654 chooseFirstProvider();
655 return spi.engineGenerateSecret(sharedSecret, offset);
656 }
657
658 /**
659 * Creates the shared secret and returns it as a <code>SecretKey</code>
660 * object of the specified algorithm.
661 *
662 * <p>This method resets this <code>KeyAgreement</code> object, so that it
663 * can be reused for further key agreements. Unless this key agreement is
664 * reinitialized with one of the <code>init</code> methods, the same
665 * private information and algorithm parameters will be used for
666 * subsequent key agreements.
667 *
668 * @param algorithm the requested secret-key algorithm
669 *
670 * @return the shared secret key
671 *
672 * @exception IllegalStateException if this key agreement has not been
673 * completed yet
674 * @exception NoSuchAlgorithmException if the specified secret-key
675 * algorithm is not available
676 * @exception InvalidKeyException if the shared secret-key material cannot
677 * be used to generate a secret key of the specified algorithm (e.g.,
678 * the key material is too short)
679 */
680 public final SecretKey generateSecret(String algorithm)
681 throws IllegalStateException, NoSuchAlgorithmException,
682 InvalidKeyException
683 {
684 chooseFirstProvider();
685 return spi.engineGenerateSecret(algorithm);
686 }
687}