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/**
19* @author Vera Y. Petrashkova
20* @version $Revision$
21*/
22
23package org.apache.harmony.crypto.tests.javax.crypto;
24
25import org.apache.harmony.security.tests.support.SpiEngUtils;
26import org.apache.harmony.security.tests.support.TestKeyPair;
27import java.math.BigInteger;
28import java.security.InvalidAlgorithmParameterException;
29import java.security.InvalidKeyException;
30import java.security.NoSuchAlgorithmException;
31import java.security.NoSuchProviderException;
32import java.security.PrivateKey;
33import java.security.Provider;
34import java.security.PublicKey;
35import java.security.SecureRandom;
36import java.security.Security;
37import java.security.spec.AlgorithmParameterSpec;
38import java.security.spec.DSAParameterSpec;
39import java.security.spec.RSAKeyGenParameterSpec;
40
41import javax.crypto.KeyAgreement;
42import javax.crypto.KeyAgreementSpi;
43import javax.crypto.ShortBufferException;
44import javax.crypto.interfaces.DHPrivateKey;
45import javax.crypto.spec.DHParameterSpec;
46import junit.framework.TestCase;
47import libcore.java.security.StandardNames;
48import libcore.javax.crypto.MockKey;
49import libcore.javax.crypto.MockKey2;
50
51
52/**
53 * Tests for KeyAgreement constructor and methods
54 *
55 */
56public class KeyAgreementTest extends TestCase {
57
58    public static final String srvKeyAgreement = "KeyAgreement";
59
60    private static String defaultAlgorithm = "DH";
61
62    private static String defaultProviderName = null;
63
64    private static Provider defaultProvider = null;
65
66    private static boolean DEFSupported = false;
67
68    private static final String NotSupportMsg = "There is no suitable provider for KeyAgreement";
69
70    private static final String[] invalidValues = SpiEngUtils.invalidValues;
71
72    private static String[] validValues = { "DH", "dH",
73            "Dh", "dh" };
74
75    private static PrivateKey privKey = null;
76
77    private static PublicKey publKey = null;
78
79    private static boolean initKeys = false;
80
81    static {
82        defaultProvider = SpiEngUtils.isSupport(defaultAlgorithm,
83                srvKeyAgreement);
84        DEFSupported = (defaultProvider != null);
85        defaultProviderName = (DEFSupported ? defaultProvider.getName() : null);
86    }
87
88    private void createKeys() throws Exception {
89        if (!initKeys) {
90            TestKeyPair tkp = new TestKeyPair(defaultAlgorithm);
91            privKey = tkp.getPrivate();
92            publKey = tkp.getPublic();
93            initKeys = true;
94        }
95
96    }
97
98    private KeyAgreement[] createKAs() throws Exception {
99        if (!DEFSupported) {
100            fail(NotSupportMsg);
101        }
102
103        KeyAgreement[] ka = new KeyAgreement[3];
104        ka[0] = KeyAgreement.getInstance(defaultAlgorithm);
105        ka[1] = KeyAgreement.getInstance(defaultAlgorithm, defaultProvider);
106        ka[2] = KeyAgreement.getInstance(defaultAlgorithm,
107                defaultProviderName);
108        return ka;
109    }
110
111    public static String getDefAlg() {
112        return defaultAlgorithm;
113    }
114
115    /**
116     * Test for <code> getInstance(String algorithm) </code> method Assertions:
117     * throws NullPointerException when algorithm is null throws
118     * NoSuchAlgorithmException when algorithm isnot available
119     */
120    public void testGetInstanceString01() throws NoSuchAlgorithmException {
121        try {
122            KeyAgreement.getInstance(null);
123            fail("NullPointerException or NoSuchAlgorithmException should be thrown if algorithm is null");
124        } catch (NullPointerException e) {
125        } catch (NoSuchAlgorithmException e) {
126        }
127        for (int i = 0; i < invalidValues.length; i++) {
128            try {
129                KeyAgreement.getInstance(invalidValues[i]);
130                fail("NoSuchAlgorithmException must be thrown");
131            } catch (NoSuchAlgorithmException e) {
132            }
133        }
134    }
135
136    /**
137     * Test for <code> getInstance(String algorithm) </code> method Assertions:
138     * returns KeyAgreement object
139     */
140    public void testGetInstanceString02() throws NoSuchAlgorithmException {
141        if (!DEFSupported) {
142            fail(NotSupportMsg);
143            return;
144        }
145        KeyAgreement keyA;
146        for (int i = 0; i < validValues.length; i++) {
147            keyA = KeyAgreement.getInstance(validValues[i]);
148            assertEquals("Incorrect algorithm", keyA.getAlgorithm(),
149                    validValues[i]);
150        }
151    }
152
153    /**
154     * Test for <code> getInstance(String algorithm, String provider)</code>
155     * method Assertions: throws NullPointerException when algorithm is null
156     * throws NoSuchAlgorithmException when algorithm is not available
157     */
158    public void testGetInstanceStringString01()
159            throws NoSuchAlgorithmException, IllegalArgumentException,
160            NoSuchProviderException {
161        if (!DEFSupported) {
162            fail(NotSupportMsg);
163            return;
164        }
165        try {
166            KeyAgreement.getInstance(null, defaultProviderName);
167            fail("NullPointerException or NoSuchAlgorithmException should be thrown if algorithm is null");
168        } catch (NullPointerException e) {
169        } catch (NoSuchAlgorithmException e) {
170        }
171        for (int i = 0; i < invalidValues.length; i++) {
172            try {
173                KeyAgreement.getInstance(invalidValues[i], defaultProviderName);
174                fail("NoSuchAlgorithmException must be thrown");
175            } catch (NoSuchAlgorithmException e) {
176            }
177        }
178    }
179
180    /**
181     * Test for <code> getInstance(String algorithm, String provider)</code>
182     * method Assertions: throws IllegalArgumentException when provider is null
183     * or empty throws NoSuchProviderException when provider has not be
184     * configured
185     */
186    public void testGetInstanceStringString02()
187            throws IllegalArgumentException, NoSuchAlgorithmException,
188            NoSuchProviderException {
189        if (!DEFSupported) {
190            fail(NotSupportMsg);
191            return;
192        }
193        String provider = null;
194        for (int i = 0; i < validValues.length; i++) {
195            try {
196                KeyAgreement.getInstance(validValues[i], provider);
197                fail("IllegalArgumentException must be thrown when provider is null");
198            } catch (IllegalArgumentException e) {
199            }
200            try {
201                KeyAgreement.getInstance(validValues[i], "");
202                fail("IllegalArgumentException must be thrown when provider is empty");
203            } catch (IllegalArgumentException e) {
204            }
205            for (int j = 1; j < invalidValues.length; j++) {
206                try {
207                    KeyAgreement.getInstance(validValues[i], invalidValues[j]);
208                    fail("NoSuchProviderException must be thrown (algorithm: "
209                            .concat(validValues[i]).concat(" provider: ")
210                            .concat(invalidValues[j]).concat(")"));
211                } catch (NoSuchProviderException e) {
212                }
213            }
214        }
215    }
216
217    /**
218     * Test for <code> getInstance(String algorithm, String provider)</code>
219     * method Assertions: returns KeyAgreement object
220     */
221    public void testGetInstanceStringString03()
222            throws IllegalArgumentException, NoSuchAlgorithmException,
223            NoSuchProviderException {
224        if (!DEFSupported) {
225            fail(NotSupportMsg);
226            return;
227        }
228        KeyAgreement keyA;
229        for (int i = 0; i < validValues.length; i++) {
230            keyA = KeyAgreement
231                    .getInstance(validValues[i], defaultProviderName);
232            assertEquals("Incorrect algorithm", keyA.getAlgorithm(),
233                    validValues[i]);
234            assertEquals("Incorrect provider", keyA.getProvider().getName(),
235                    defaultProviderName);
236        }
237    }
238
239    /**
240     * Test for <code> getInstance(String algorithm, Provider provider)</code>
241     * method Assertions: throws NullPointerException when algorithm is null
242     * throws NoSuchAlgorithmException when algorithm isnot available
243     */
244    public void testGetInstanceStringProvider01()
245            throws NoSuchAlgorithmException, IllegalArgumentException {
246        if (!DEFSupported) {
247            fail(NotSupportMsg);
248            return;
249        }
250        try {
251            KeyAgreement.getInstance(null, defaultProvider);
252            fail("NullPointerException or NoSuchAlgorithmException should be thrown if algorithm is null");
253        } catch (NullPointerException e) {
254        } catch (NoSuchAlgorithmException e) {
255        }
256        for (int i = 0; i < invalidValues.length; i++) {
257            try {
258                KeyAgreement.getInstance(invalidValues[i], defaultProvider);
259                fail("NoSuchAlgorithmException must be thrown");
260            } catch (NoSuchAlgorithmException e) {
261            }
262        }
263    }
264
265    /**
266     * Test for <code> getInstance(String algorithm, Provider provider)</code>
267     * method Assertions: throws IllegalArgumentException when provider is null
268     */
269    public void testGetInstanceStringProvider02()
270            throws NoSuchAlgorithmException, IllegalArgumentException {
271        if (!DEFSupported) {
272            fail(NotSupportMsg);
273            return;
274        }
275        Provider provider = null;
276        for (int i = 0; i < invalidValues.length; i++) {
277            try {
278                KeyAgreement.getInstance(invalidValues[i], provider);
279                fail("IllegalArgumentException must be thrown");
280            } catch (IllegalArgumentException e) {
281            }
282        }
283    }
284
285    /**
286     * Test for <code> getInstance(String algorithm, Provider provider)</code>
287     * method Assertions: returns KeyAgreement object
288     */
289    public void testGetInstanceStringProvider03()
290            throws IllegalArgumentException, NoSuchAlgorithmException {
291        if (!DEFSupported) {
292            fail(NotSupportMsg);
293            return;
294        }
295        KeyAgreement keyA;
296        for (int i = 0; i < validValues.length; i++) {
297            keyA = KeyAgreement.getInstance(validValues[i], defaultProvider);
298            assertEquals("Incorrect algorithm", keyA.getAlgorithm(),
299                    validValues[i]);
300            assertEquals("Incorrect provider", keyA.getProvider(),
301                    defaultProvider);
302        }
303    }
304
305    /**
306     * Test for the methods: <code>init(Key key)</code>
307     * <code>generateSecret()</code>
308     * <code>generateSecret(byte[] sharedsecret, int offset)</code>
309     * <code>generateSecret(String algorithm)</code>
310     * Assertions: initializes KeyAgreement; returns sharedSecret; puts
311     * sharedsecret in buffer and return numbers of bytes; returns SecretKey
312     * object
313     */
314    public void testGenerateSecret03() throws Exception {
315        if (!DEFSupported) {
316            fail(NotSupportMsg);
317            return;
318        }
319        createKeys();
320        KeyAgreement[] kAgs = createKAs();
321
322        byte[] bb;
323        byte[] bb1 = new byte[10];
324        for (int i = 0; i < kAgs.length; i++) {
325            kAgs[i].init(privKey);
326            kAgs[i].doPhase(publKey, true);
327            bb = kAgs[i].generateSecret();
328            kAgs[i].init(privKey);
329            kAgs[i].doPhase(publKey, true);
330            bb1 = new byte[bb.length + 10];
331            kAgs[i].generateSecret(bb1, 9);
332            kAgs[i].init(privKey);
333            kAgs[i].doPhase(publKey, true);
334            kAgs[i].generateSecret("DES");
335        }
336    }
337
338    /**
339     * Test for <code>doPhase(Key key, boolean lastPhase)</code> method
340     * Assertion: throws InvalidKeyException if key is not appropriate
341     */
342    public void testDoPhase() throws Exception {
343        if (!DEFSupported) {
344            fail(NotSupportMsg);
345            return;
346        }
347        createKeys();
348        KeyAgreement[] kAgs = createKAs();
349        DHParameterSpec dhPs = ((DHPrivateKey) privKey).getParams();
350        SecureRandom randomNull = null;
351        SecureRandom random = new SecureRandom();
352
353        for (int i = 0; i < kAgs.length; i++) {
354            try {
355                kAgs[i].doPhase(publKey, true);
356                fail("IllegalStateException expected");
357            } catch (IllegalStateException e) {
358                //expected
359            }
360
361            kAgs[i].init(privKey);
362
363            try {
364                kAgs[i].doPhase(privKey, false);
365                fail("InvalidKeyException must be throw");
366            } catch (InvalidKeyException e) {
367            }
368
369            try {
370                kAgs[i].doPhase(privKey, true);
371                fail("InvalidKeyException must be throw");
372            } catch (InvalidKeyException e) {
373            }
374
375            kAgs[i].init(privKey, dhPs);
376            kAgs[i].doPhase(publKey, true);
377            kAgs[i].init(privKey, dhPs, random);
378            kAgs[i].doPhase(publKey, true);
379        }
380    }
381
382    /**
383     * Test for the methods <code>init(Key key)</code>
384     * <code>init(Key key, SecureRandom random)</code>
385     * <code>init(Key key, AlgorithmParameterSpec params)</code>
386     * <code>init(Key key, AlgorithmParameterSpec params, SecureRandom random)</code>
387     * Assertion: throws InvalidKeyException when key is inappropriate
388     */
389    public void testInit01() throws Exception {
390        if (!DEFSupported) {
391            fail(NotSupportMsg);
392            return;
393        }
394        createKeys();
395        KeyAgreement[] kAgs = createKAs();
396
397        SecureRandom random = null;
398        AlgorithmParameterSpec aps = null;
399        DHParameterSpec dhPs = new DHParameterSpec(new BigInteger("56"),
400                new BigInteger("56"));
401        for (int i = 0; i < kAgs.length; i++) {
402            try {
403                kAgs[i].init(publKey);
404                fail("InvalidKeyException must be throw");
405            } catch (InvalidKeyException e) {
406            }
407            try {
408                kAgs[i].init(publKey, new SecureRandom());
409                fail("InvalidKeyException must be throw");
410            } catch (InvalidKeyException e) {
411            }
412            try {
413                kAgs[i].init(publKey, random);
414                fail("InvalidKeyException must be throw");
415            } catch (InvalidKeyException e) {
416            }
417            try {
418                kAgs[i].init(publKey, dhPs);
419                fail("InvalidKeyException must be throw");
420            } catch (InvalidKeyException e) {
421            }
422            try {
423                kAgs[i].init(publKey, aps);
424                fail("InvalidKeyException must be throw");
425            } catch (InvalidKeyException e) {
426            }
427            try {
428                kAgs[i].init(publKey, dhPs, new SecureRandom());
429                fail("InvalidKeyException must be throw");
430            } catch (InvalidKeyException e) {
431            }
432        }
433    }
434
435    /**
436     * Test for the methods
437     * <code>init(Key key, AlgorithmParameterSpec params)</code>
438     * <code>init(Key key, AlgorithmParameterSpec params, SecureRandom random)</code>
439     * Assertion: throws AlgorithmParameterException when params are
440     * inappropriate
441     */
442    public void testInit02() throws Exception {
443        if (!DEFSupported) {
444            fail(NotSupportMsg);
445            return;
446        }
447        createKeys();
448        KeyAgreement[] kAgs = createKAs();
449
450        SecureRandom random = null;
451        DSAParameterSpec dsa = new DSAParameterSpec(new BigInteger("56"),
452                new BigInteger("56"), new BigInteger("56"));
453        for (int i = 0; i < kAgs.length; i++) {
454            try {
455                kAgs[i].init(privKey, dsa);
456                fail("InvalidAlgorithmParameterException or InvalidKeyException must be throw");
457            } catch (InvalidAlgorithmParameterException e) {
458            } catch (InvalidKeyException e) {
459            }
460            try {
461                kAgs[i].init(privKey, dsa, new SecureRandom());
462                fail("InvalidAlgorithmParameterException or InvalidKeyException must be throw");
463            } catch (InvalidAlgorithmParameterException e) {
464            } catch (InvalidKeyException e) {
465            }
466            try {
467                kAgs[i].init(privKey, dsa, random);
468                fail("InvalidAlgorithmParameterException or InvalidKeyException must be throw");
469            } catch (InvalidAlgorithmParameterException e) {
470            } catch (InvalidKeyException e) {
471            }
472        }
473    }
474
475    /**
476     * Test for the methods: <code>init(Key key)</code>
477     * <code>init(Key key, SecureRandom random)</code>
478     * <code>generateSecret()</code>
479     * Assertions: initializes KeyAgreement and returns byte array
480     */
481    public void testInit03() throws Exception {
482        if (!DEFSupported) {
483            fail(NotSupportMsg);
484            return;
485        }
486        createKeys();
487        KeyAgreement[] kAgs = createKAs();
488
489        byte[] bbRes1;
490        byte[] bbRes2;
491        byte[] bbRes3;
492        SecureRandom randomNull = null;
493        SecureRandom random = new SecureRandom();
494        for (int i = 0; i < kAgs.length; i++) {
495            kAgs[i].init(privKey);
496            kAgs[i].doPhase(publKey, true);
497            bbRes1 = kAgs[i].generateSecret();
498            kAgs[i].init(privKey, random);
499            kAgs[i].doPhase(publKey, true);
500            bbRes2 = kAgs[i].generateSecret();
501            assertEquals("Incorrect byte array length", bbRes1.length,
502                    bbRes2.length);
503            for (int j = 0; j < bbRes1.length; j++) {
504                assertEquals("Incorrect byte (index: ".concat(
505                        Integer.toString(i)).concat(")"), bbRes1[j], bbRes2[j]);
506            }
507            kAgs[i].init(privKey, randomNull);
508            kAgs[i].doPhase(publKey, true);
509            bbRes3 = kAgs[i].generateSecret();
510            assertEquals("Incorrect byte array length", bbRes1.length,
511                    bbRes3.length);
512            for (int j = 0; j < bbRes1.length; j++) {
513                assertEquals("Incorrect byte (index: ".concat(
514                        Integer.toString(i)).concat(")"), bbRes1[j], bbRes3[j]);
515            }
516        }
517    }
518
519    /**
520     * Test for the methods:
521     * <code>init(Key key, AlgorithmParameterSpec params)</code>
522     * <code>init(Key key, AlgorithmParameterSpec params, SecureRandom random)</code>
523     * <code>generateSecret()</code>
524     * Assertions: initializes KeyAgreement and returns byte array
525     */
526    public void testInit04() throws Exception,
527            InvalidAlgorithmParameterException {
528        if (!DEFSupported) {
529            fail(NotSupportMsg);
530            return;
531        }
532        createKeys();
533        KeyAgreement[] kAgs = createKAs();
534
535        DHParameterSpec dhPs = ((DHPrivateKey) privKey).getParams();
536        AlgorithmParameterSpec aps = new RSAKeyGenParameterSpec(10, new BigInteger("10"));
537
538        byte[] bbRes1;
539        byte[] bbRes2;
540        byte[] bbRes3;
541        SecureRandom randomNull = null;
542        SecureRandom random = new SecureRandom();
543        for (int i = 0; i < kAgs.length; i++) {
544            kAgs[i].init(privKey, dhPs);
545            kAgs[i].doPhase(publKey, true);
546            bbRes1 = kAgs[i].generateSecret();
547            kAgs[i].init(privKey, dhPs, random);
548            kAgs[i].doPhase(publKey, true);
549            bbRes2 = kAgs[i].generateSecret();
550            assertEquals("Incorrect byte array length", bbRes1.length,
551                    bbRes2.length);
552            for (int j = 0; j < bbRes1.length; j++) {
553                assertEquals("Incorrect byte (index: ".concat(
554                        Integer.toString(i)).concat(")"), bbRes1[j], bbRes2[j]);
555            }
556            kAgs[i].init(privKey, dhPs, randomNull);
557            kAgs[i].doPhase(publKey, true);
558            bbRes3 = kAgs[i].generateSecret();
559            assertEquals("Incorrect byte array length", bbRes1.length,
560                    bbRes3.length);
561            for (int j = 0; j < bbRes1.length; j++) {
562                assertEquals("Incorrect byte (index: ".concat(
563                        Integer.toString(i)).concat(")"), bbRes1[j], bbRes3[j]);
564            }
565
566            try {
567                kAgs[i].init(publKey, dhPs, random);
568                fail("InvalidKeyException expected");
569            } catch (InvalidKeyException e) {
570                //expected
571            }
572            try {
573                kAgs[i].init(privKey, aps, random);
574                fail("InvalidAlgorithmParameterException expected");
575            } catch (InvalidAlgorithmParameterException e) {
576                //expected
577            }
578        }
579    }
580
581    class Mock_KeyAgreement extends KeyAgreement {
582        protected Mock_KeyAgreement(KeyAgreementSpi arg0, Provider arg1, String arg2) {
583            super(arg0, arg1, arg2);
584        }
585    }
586
587    public void test_constructor() {
588        assertNotNull(new Mock_KeyAgreement(null, null, null));
589    }
590
591    public void test_getAlgorithm() throws NoSuchAlgorithmException {
592        Mock_KeyAgreement mka = new Mock_KeyAgreement(null, null, null);
593        assertNull(mka.getAlgorithm());
594
595        KeyAgreement keyA;
596        for (int i = 0; i < validValues.length; i++) {
597            keyA = KeyAgreement.getInstance(validValues[i]);
598            assertEquals("Incorrect algorithm", keyA.getAlgorithm(),
599                    validValues[i]);
600        }
601    }
602
603    public void test_getProvider() throws NoSuchAlgorithmException {
604        KeyAgreement keyA;
605        for (int i = 0; i < validValues.length; i++) {
606            keyA = KeyAgreement.getInstance(validValues[i]);
607            assertNotNull(keyA.getProvider());
608        }
609    }
610
611    public void test_generateSecret$BI() throws Exception {
612        if (!DEFSupported) {
613            fail(NotSupportMsg);
614            return;
615        }
616        createKeys();
617        KeyAgreement[] kAgs = createKAs();
618        KeyAgreement ka = KeyAgreement.getInstance("DH");
619
620        byte[] bb1 = new byte[1];
621        try {
622            ka.generateSecret(bb1, 0);
623            fail("IllegalStateException expected");
624        } catch (IllegalStateException e) {
625            //expected
626        }
627        ka.init(privKey);
628        ka.doPhase(publKey, true);
629        try {
630            ka.generateSecret(bb1, 0);
631            fail("ShortBufferException expected");
632        } catch (ShortBufferException e) {
633            //expected
634        }
635    }
636
637    public void test_generateSecretLjava_lang_String() throws Exception {
638        if (!DEFSupported) {
639            fail(NotSupportMsg);
640            return;
641        }
642        createKeys();
643        KeyAgreement[] kAgs = createKAs();
644        KeyAgreement ka = KeyAgreement.getInstance("DH");
645
646        byte[] bb1 = new byte[1];
647        try {
648            ka.generateSecret("dh");
649            fail("IllegalStateException expected");
650        } catch (IllegalStateException e) {
651            //expected
652        }
653        ka.init(privKey);
654        ka.doPhase(publKey, true);
655        try {
656            ka.generateSecret("Wrong alg name");
657            fail("NoSuchAlgorithmException expected");
658        } catch (NoSuchAlgorithmException e) {
659            //expected
660        }
661    }
662
663    public void test_initLjava_security_KeyLjava_security_SecureRandom() throws Exception {
664        if (!DEFSupported) {
665            fail(NotSupportMsg);
666            return;
667        }
668        createKeys();
669        KeyAgreement[] kAgs = createKAs();
670        KeyAgreement ka = KeyAgreement.getInstance("DH");
671
672        ka.init(privKey, new SecureRandom());
673        try {
674            ka.init(publKey, new SecureRandom());
675            fail("InvalidKeyException expected");
676        } catch (InvalidKeyException e) {
677            //expected
678        }
679    }
680
681    private static abstract class MockProvider extends Provider {
682        public MockProvider(String name) {
683            super(name, 1.0, "Mock provider used for testing");
684            setup();
685        }
686
687        public abstract void setup();
688    }
689
690    public void testKeyAgreement_getInstance_SuppliedProviderNotRegistered_Success()
691            throws Exception {
692        Provider mockProvider = new MockProvider("MockProvider") {
693            public void setup() {
694                put("KeyAgreement.FOO", MockKeyAgreementSpi.AllKeyTypes.class.getName());
695            }
696        };
697
698        {
699            KeyAgreement s = KeyAgreement.getInstance("FOO", mockProvider);
700            s.init(new MockKey());
701            assertEquals(mockProvider, s.getProvider());
702        }
703    }
704
705    public void testKeyAgreement_getInstance_OnlyUsesSpecifiedProvider_SameNameAndClass_Success()
706            throws Exception {
707        Provider mockProvider = new MockProvider("MockProvider") {
708            public void setup() {
709                put("KeyAgreement.FOO", MockKeyAgreementSpi.AllKeyTypes.class.getName());
710            }
711        };
712
713        Security.addProvider(mockProvider);
714        try {
715            {
716                Provider mockProvider2 = new MockProvider("MockProvider") {
717                    public void setup() {
718                        put("KeyAgreement.FOO", MockKeyAgreementSpi.AllKeyTypes.class.getName());
719                    }
720                };
721                KeyAgreement s = KeyAgreement.getInstance("FOO", mockProvider2);
722                assertEquals(mockProvider2, s.getProvider());
723            }
724        } finally {
725            Security.removeProvider(mockProvider.getName());
726        }
727    }
728
729    public void testKeyAgreement_getInstance_DelayedInitialization_KeyType() throws Exception {
730        Provider mockProviderSpecific = new MockProvider("MockProviderSpecific") {
731            public void setup() {
732                put("KeyAgreement.FOO", MockKeyAgreementSpi.SpecificKeyTypes.class.getName());
733                put("KeyAgreement.FOO SupportedKeyClasses", MockKey.class.getName());
734            }
735        };
736        Provider mockProviderSpecific2 = new MockProvider("MockProviderSpecific2") {
737            public void setup() {
738                put("KeyAgreement.FOO", MockKeyAgreementSpi.SpecificKeyTypes2.class.getName());
739                put("KeyAgreement.FOO SupportedKeyClasses", MockKey2.class.getName());
740            }
741        };
742        Provider mockProviderAll = new MockProvider("MockProviderAll") {
743            public void setup() {
744                put("KeyAgreement.FOO", MockKeyAgreementSpi.AllKeyTypes.class.getName());
745            }
746        };
747
748        Security.addProvider(mockProviderSpecific);
749        Security.addProvider(mockProviderSpecific2);
750        Security.addProvider(mockProviderAll);
751
752        try {
753            {
754                KeyAgreement s = KeyAgreement.getInstance("FOO");
755                s.init(new MockKey());
756                assertEquals(mockProviderSpecific, s.getProvider());
757
758                try {
759                    s.init(new MockKey2());
760                    assertEquals(mockProviderSpecific2, s.getProvider());
761                    if (StandardNames.IS_RI) {
762                        fail("RI was broken before; fix tests now that it works!");
763                    }
764                } catch (InvalidKeyException e) {
765                    if (!StandardNames.IS_RI) {
766                        fail("Non-RI should select the right provider");
767                    }
768                }
769            }
770
771            {
772                KeyAgreement s = KeyAgreement.getInstance("FOO");
773                s.init(new PrivateKey() {
774                    @Override
775                    public String getAlgorithm() {
776                        throw new UnsupportedOperationException("not implemented");
777                    }
778
779                    @Override
780                    public String getFormat() {
781                        throw new UnsupportedOperationException("not implemented");
782                    }
783
784                    @Override
785                    public byte[] getEncoded() {
786                        throw new UnsupportedOperationException("not implemented");
787                    }
788                });
789                assertEquals(mockProviderAll, s.getProvider());
790            }
791
792            {
793                KeyAgreement s = KeyAgreement.getInstance("FOO");
794                assertEquals(mockProviderSpecific, s.getProvider());
795            }
796        } finally {
797            Security.removeProvider(mockProviderSpecific.getName());
798            Security.removeProvider(mockProviderSpecific2.getName());
799            Security.removeProvider(mockProviderAll.getName());
800        }
801    }
802
803}
804