1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package libcore.java.security;
18
19import java.io.ByteArrayInputStream;
20import java.io.ByteArrayOutputStream;
21import java.io.File;
22import java.io.FileInputStream;
23import java.io.FileOutputStream;
24import java.io.IOException;
25import java.io.InputStream;
26import java.io.OutputStream;
27import java.security.Key;
28import java.security.KeyStore;
29import java.security.KeyStore.Builder;
30import java.security.KeyStore.Entry;
31import java.security.KeyStore.LoadStoreParameter;
32import java.security.KeyStore.PasswordProtection;
33import java.security.KeyStore.PrivateKeyEntry;
34import java.security.KeyStore.ProtectionParameter;
35import java.security.KeyStore.SecretKeyEntry;
36import java.security.KeyStore.TrustedCertificateEntry;
37import java.security.KeyStoreException;
38import java.security.NoSuchAlgorithmException;
39import java.security.Provider;
40import java.security.Security;
41import java.security.UnrecoverableKeyException;
42import java.security.cert.Certificate;
43import java.security.cert.X509Certificate;
44import java.util.ArrayList;
45import java.util.Arrays;
46import java.util.Collections;
47import java.util.Date;
48import java.util.Enumeration;
49import java.util.HashMap;
50import java.util.HashSet;
51import java.util.List;
52import java.util.Set;
53import javax.crypto.KeyGenerator;
54import javax.crypto.SecretKey;
55import junit.framework.TestCase;
56
57public class KeyStoreTest extends TestCase {
58
59    private static final HashMap<String, PrivateKeyEntry> sPrivateKeys
60            = new HashMap<String, PrivateKeyEntry>();
61
62    private static TestKeyStore sTestKeyStore;
63
64    private static final String[] KEY_TYPES = new String[] { "DH", "DSA", "RSA", "EC" };
65
66    private static PrivateKeyEntry sPrivateKey2;
67
68    private static SecretKey sSecretKey;
69    private static SecretKey sSecretKey2;
70
71    private static final String ALIAS_PRIVATE = "private";
72    private static final String ALIAS_CERTIFICATE = "certificate";
73    private static final String ALIAS_SECRET = "secret";
74
75    private static final String ALIAS_ALT_CASE_PRIVATE = "pRiVaTe";
76    private static final String ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE = "PrIvAtE-no-password";
77    private static final String ALIAS_ALT_CASE_CERTIFICATE = "cErTiFiCaTe";
78    private static final String ALIAS_ALT_CASE_SECRET = "sEcRet";
79
80    private static final String ALIAS_UNICODE_PRIVATE = "\u6400\u7902\u3101\u8c02\u5002\u8702\udd01";
81    private static final String ALIAS_UNICODE_NO_PASSWORD_PRIVATE = "\u926c\u0967\uc65b\ubc78";
82    private static final String ALIAS_UNICODE_CERTIFICATE = "\u5402\udd01\u7902\u8702\u3101\u5f02\u3101\u5402\u5002\u8702\udd01";
83    private static final String ALIAS_UNICODE_SECRET = "\ue224\ud424\ud224\ue124\ud424\ue324";
84
85    private static final String ALIAS_NO_PASSWORD_PRIVATE = "private-no-password";
86    private static final String ALIAS_NO_PASSWORD_SECRET = "secret-no-password";
87
88    private static final char[] PASSWORD_STORE = "store password".toCharArray();
89    private static final char[] PASSWORD_KEY = "key password".toCharArray();
90    private static final char[] PASSWORD_BAD = "dummy".toCharArray();
91
92    private static final ProtectionParameter PARAM_STORE = new PasswordProtection(PASSWORD_STORE);
93    private static final ProtectionParameter PARAM_KEY = new PasswordProtection(PASSWORD_KEY);
94    private static final ProtectionParameter PARAM_BAD = new PasswordProtection(PASSWORD_BAD);
95
96    private static PrivateKeyEntry getPrivateKey() {
97        return getPrivateKey("RSA");
98    }
99
100    private static PrivateKeyEntry getPrivateKey(String keyType) {
101        // Avoiding initialization of TestKeyStore in the static initializer: it breaks CTS tests
102        // by causing a NetworkOnMainThreadException.
103        if (sTestKeyStore == null) {
104            sTestKeyStore = new TestKeyStore.Builder()
105                .keyAlgorithms("RSA", "DH_RSA", "DSA", "EC")
106                .aliasPrefix("rsa-dsa-ec-dh")
107                .build();
108        }
109
110        PrivateKeyEntry entry = sPrivateKeys.get(keyType);
111        if (entry == null) {
112            if ("RSA".equals(keyType)) {
113                entry = sTestKeyStore.getPrivateKey("RSA", "RSA");
114            } else if ("DH".equals(keyType)) {
115                entry = sTestKeyStore.getPrivateKey("DH", "RSA");
116            } else if ("DSA".equals(keyType)) {
117                entry = sTestKeyStore.getPrivateKey("DSA", "DSA");
118            } else if ("EC".equals(keyType)) {
119                entry = sTestKeyStore.getPrivateKey("EC", "EC");
120            } else {
121                throw new IllegalArgumentException("Unexpected key type " + keyType);
122            }
123            sPrivateKeys.put(keyType, entry);
124        }
125        return entry;
126    }
127
128    private static PrivateKeyEntry getPrivateKey2() {
129        if (sPrivateKey2 == null) {
130            sPrivateKey2 = TestKeyStore.getClientCertificate().getPrivateKey("RSA", "RSA");
131        }
132        return sPrivateKey2;
133    }
134
135    private static SecretKey getSecretKey() {
136        if (sSecretKey == null) {
137            sSecretKey = generateSecretKey();
138        }
139        return sSecretKey;
140    }
141
142    private static SecretKey getSecretKey2() {
143        if (sSecretKey2 == null) {
144            sSecretKey2 = generateSecretKey();
145        }
146        return sSecretKey2;
147    }
148
149    private static SecretKey generateSecretKey() {
150        try {
151            KeyGenerator kg = KeyGenerator.getInstance("DES");
152            return kg.generateKey();
153        } catch (NoSuchAlgorithmException e) {
154            throw new RuntimeException(e);
155        }
156    }
157
158    public static List<KeyStore> keyStores() throws Exception {
159        List<KeyStore> keyStores = new ArrayList<KeyStore>();
160        Provider[] providers = Security.getProviders();
161        for (Provider provider : providers) {
162            Set<Provider.Service> services = provider.getServices();
163            for (Provider.Service service : services) {
164                String type = service.getType();
165                if (!type.equals("KeyStore")) {
166                    continue;
167                }
168                String algorithm = service.getAlgorithm();
169                KeyStore ks = KeyStore.getInstance(algorithm, provider);
170                assertEquals(provider, ks.getProvider());
171                assertEquals(algorithm, ks.getType());
172                if (!isUnsupported(ks)) {
173                    keyStores.add(ks);
174                }
175            }
176        }
177        return keyStores;
178    }
179
180    private static boolean isSecretKeyEnabled(KeyStore ks) {
181        // JKS key stores cannot store secret keys, neither can the RI's PKCS12
182        return (!(ks.getType().equals("JKS")
183                  || ks.getType().equals("CaseExactJKS")
184                  || (ks.getType().equals("PKCS12"))
185                  || (ks.getType().equals("AndroidKeyStore"))));
186    }
187
188    private static boolean isCertificateEnabled(KeyStore ks) {
189        // RI can't handle certificate in PKCS12, but BC can
190        return (!(ks.getType().equals("PKCS12") && ks.getProvider().getName().equals("SunJSSE")));
191    }
192
193    private static boolean isCaseSensitive(KeyStore ks) {
194        return (ks.getType().equals("CaseExactJKS")
195                || ks.getType().equals("BKS")
196                || ks.getType().equals("BouncyCastle")
197                || ks.getType().equals("AndroidKeyStore"));
198
199    }
200
201    private static boolean isUnsupported(KeyStore ks) {
202        // Don't bother testing BC on RI
203        // TODO enable AndroidKeyStore when CTS can set up the keystore
204        return (StandardNames.IS_RI && ks.getProvider().getName().equals("BC"))
205                || "AndroidKeyStore".equalsIgnoreCase(ks.getType())
206                || "TimaKeyStore".equalsIgnoreCase(ks.getType());
207    }
208
209    private static boolean isNullPasswordAllowed(KeyStore ks) {
210        return (!(ks.getType().equals("JKS")
211                  || ks.getType().equals("CaseExactJKS")
212                  || ks.getType().equals("JCEKS")
213                  || ks.getType().equals("PKCS12")));
214    }
215    private static boolean isKeyPasswordSupported(KeyStore ks) {
216        return !ks.getType().equals("AndroidKeyStore");
217    }
218    private static boolean isKeyPasswordIgnored(KeyStore ks) {
219        // BouncyCastle's PKCS12 ignores the key password unlike the RI which requires it
220        return (ks.getType().equals("PKCS12") && ks.getProvider().getName().equals("BC"));
221    }
222
223    private static boolean isLoadStoreParameterSupported(KeyStore ks) {
224        // BouncyCastle's PKCS12 allows a JDKPKCS12StoreParameter
225        return (ks.getType().equals("PKCS12") && ks.getProvider().getName().equals("BC"));
226    }
227
228    private static boolean isPersistentStorage(KeyStore ks) {
229        return ks.getType().equalsIgnoreCase("AndroidKeyStore");
230    }
231
232    private static boolean isLoadStoreUnsupported(KeyStore ks) {
233        return ks.getType().equalsIgnoreCase("AndroidKeyStore");
234    }
235
236    private static boolean isSetKeyByteArrayUnimplemented(KeyStore ks) {
237        // All of BouncyCastle's
238        // KeyStore.setKeyEntry(String,byte[],char[]) implementations
239        // throw RuntimeException
240        return (ks.getProvider().getName().equals("BC"));
241    }
242
243    private static boolean hasDefaultContents(KeyStore ks) {
244        // AndroidCAStore exposes CA cert files via the KeyStore
245        // interface, so it does start out empty like other KeyStores
246        return (ks.getType().equals("AndroidCAStore"));
247    }
248
249    private static boolean isReadOnly(KeyStore ks) {
250        // AndroidCAStore is read only, throwing
251        // UnsupportedOperationException on write operations
252        return (ks.getType().equals("AndroidCAStore"));
253    }
254
255    public static void populate(KeyStore ks) throws Exception {
256        boolean readOnly = clearKeyStore(ks);
257        if (readOnly) {
258            return;
259        }
260        if (isKeyPasswordSupported(ks)) {
261            setPrivateKey(ks);
262        }
263        if (isNullPasswordAllowed(ks)) {
264            ks.setKeyEntry(ALIAS_NO_PASSWORD_PRIVATE,
265                           getPrivateKey().getPrivateKey(),
266                           null,
267                           getPrivateKey().getCertificateChain());
268        }
269        if (isCertificateEnabled(ks)) {
270            ks.setCertificateEntry(ALIAS_CERTIFICATE,
271                                   getPrivateKey().getCertificate());
272        }
273        if (isSecretKeyEnabled(ks)) {
274            setSecretKey(ks);
275            if (isNullPasswordAllowed(ks)) {
276                ks.setKeyEntry(ALIAS_NO_PASSWORD_SECRET,
277                               getSecretKey(),
278                               null,
279                               null);
280            }
281        }
282    }
283
284    private static boolean clearKeyStore(KeyStore ks) throws Exception {
285        ks.load(null, null);
286        if (isReadOnly(ks)) {
287            try {
288                setPrivateKey(ks);
289                fail(ks.toString());
290            } catch (UnsupportedOperationException e) {
291            }
292            return true;
293        }
294        if (isPersistentStorage(ks)) {
295            Enumeration<String> aliases = ks.aliases();
296            while (aliases.hasMoreElements()) {
297                String alias = aliases.nextElement();
298                ks.deleteEntry(alias);
299            }
300        }
301        return false;
302    }
303
304    public static void setPrivateKeyNoPassword(KeyStore ks, String alias, PrivateKeyEntry privateKey)
305            throws Exception {
306        ks.setKeyEntry(alias, privateKey.getPrivateKey(), null, privateKey.getCertificateChain());
307    }
308    public static void setPrivateKey(KeyStore ks) throws Exception {
309        setPrivateKey(ks, ALIAS_PRIVATE);
310    }
311    public static void setPrivateKey(KeyStore ks, String alias) throws Exception {
312        setPrivateKey(ks, alias, getPrivateKey());
313    }
314    public static void setPrivateKey(KeyStore ks,
315                                     String alias,
316                                     PrivateKeyEntry privateKey)
317            throws Exception {
318        ks.setKeyEntry(alias,
319                       privateKey.getPrivateKey(),
320                       PASSWORD_KEY,
321                       privateKey.getCertificateChain());
322    }
323
324    public static void setPrivateKeyBytes(KeyStore ks) throws Exception {
325        setPrivateKeyBytes(ks, ALIAS_PRIVATE);
326    }
327    public static void setPrivateKeyBytes(KeyStore ks, String alias) throws Exception {
328        setPrivateKeyBytes(ks, alias, getPrivateKey());
329    }
330    public static void setPrivateKeyBytes(KeyStore ks,
331                                     String alias,
332                                     PrivateKeyEntry privateKey)
333            throws Exception {
334        ks.setKeyEntry(alias,
335                       privateKey.getPrivateKey().getEncoded(),
336                       privateKey.getCertificateChain());
337    }
338
339    public static void setSecretKey(KeyStore ks) throws Exception {
340        setSecretKey(ks, ALIAS_SECRET);
341    }
342    public static void setSecretKey(KeyStore ks, String alias) throws Exception {
343        setSecretKey(ks, alias, getSecretKey());
344    }
345    public static void setSecretKey(KeyStore ks, String alias, SecretKey key) throws Exception {
346        ks.setKeyEntry(alias,
347                       key,
348                       PASSWORD_KEY,
349                       null);
350    }
351
352    public static void setSecretKeyBytes(KeyStore ks) throws Exception {
353        setSecretKeyBytes(ks, ALIAS_SECRET);
354    }
355    public static void setSecretKeyBytes(KeyStore ks, String alias) throws Exception {
356        setSecretKeyBytes(ks, alias, getSecretKey());
357    }
358    public static void setSecretKeyBytes(KeyStore ks, String alias, SecretKey key)
359            throws Exception {
360        ks.setKeyEntry(alias,
361                       key.getEncoded(),
362                       null);
363    }
364
365    public static void setCertificate(KeyStore ks) throws Exception {
366        setCertificate(ks, ALIAS_CERTIFICATE);
367    }
368    public static void setCertificate(KeyStore ks, String alias) throws Exception {
369        setCertificate(ks, alias, getPrivateKey().getCertificate());
370    }
371    public static void setCertificate(KeyStore ks, String alias, Certificate certificate)
372            throws Exception {
373        ks.setCertificateEntry(alias, certificate);
374    }
375
376
377    public static void assertPrivateKey(Key actual)
378            throws Exception {
379        assertEquals(getPrivateKey().getPrivateKey(), actual);
380    }
381    public static void assertPrivateKey(String keyType, Key actual)
382            throws Exception {
383        assertEquals(getPrivateKey(keyType).getPrivateKey(), actual);
384    }
385    public static void assertPrivateKey2(Key actual)
386            throws Exception {
387        assertEquals(getPrivateKey2().getPrivateKey(), actual);
388    }
389    public static void assertPrivateKey(Entry actual)
390            throws Exception {
391        assertNotNull(actual);
392        assertSame(PrivateKeyEntry.class, actual.getClass());
393        PrivateKeyEntry privateKey = (PrivateKeyEntry) actual;
394        assertEquals(getPrivateKey().getPrivateKey(), privateKey.getPrivateKey());
395        assertEquals(getPrivateKey().getCertificate(), privateKey.getCertificate());
396        assertEquals(Arrays.asList(getPrivateKey().getCertificateChain()),
397                     Arrays.asList(privateKey.getCertificateChain()));
398    }
399
400    public static void assertSecretKey(Key actual)
401            throws Exception {
402        assertEquals(getSecretKey(), actual);
403    }
404    public static void assertSecretKey2(Key actual)
405            throws Exception {
406        assertEquals(getSecretKey2(), actual);
407    }
408    public static void assertSecretKey(Entry actual)
409            throws Exception {
410        assertSame(SecretKeyEntry.class, actual.getClass());
411        assertEquals(getSecretKey(), ((SecretKeyEntry) actual).getSecretKey());
412    }
413
414    public static void assertCertificate(Certificate actual)
415            throws Exception {
416        assertEquals(getPrivateKey().getCertificate(), actual);
417    }
418    public static void assertCertificate2(Certificate actual)
419            throws Exception {
420        assertEquals(getPrivateKey2().getCertificate(), actual);
421    }
422    public static void assertCertificate(Entry actual)
423            throws Exception {
424        assertSame(TrustedCertificateEntry.class, actual.getClass());
425        assertEquals(getPrivateKey().getCertificate(),
426                     ((TrustedCertificateEntry) actual).getTrustedCertificate());
427    }
428
429    public static void assertCertificateChain(Certificate[] actual)
430            throws Exception {
431        assertEquals(Arrays.asList(getPrivateKey().getCertificateChain()),
432                     Arrays.asList(actual));
433    }
434
435    public void test_KeyStore_create() throws Exception {
436        Provider[] providers = Security.getProviders();
437        for (Provider provider : providers) {
438            Set<Provider.Service> services = provider.getServices();
439            for (Provider.Service service : services) {
440                String type = service.getType();
441                if (!type.equals("KeyStore")) {
442                    continue;
443                }
444                String algorithm = service.getAlgorithm();
445                KeyStore ks = KeyStore.getInstance(algorithm, provider);
446                assertEquals(provider, ks.getProvider());
447                assertEquals(algorithm, ks.getType());
448            }
449        }
450    }
451
452    public void test_KeyStore_getInstance() throws Exception {
453        String type = KeyStore.getDefaultType();
454        try {
455            KeyStore.getInstance(null);
456            fail(type);
457        } catch (NullPointerException expected) {
458        }
459
460        assertNotNull(KeyStore.getInstance(type));
461
462        String providerName = StandardNames.SECURITY_PROVIDER_NAME;
463        try {
464            KeyStore.getInstance(null, (String)null);
465            fail(type);
466        } catch (IllegalArgumentException expected) {
467        }
468        try {
469            KeyStore.getInstance(null, providerName);
470            fail(type);
471        } catch (Exception e) {
472            if (e.getClass() != NullPointerException.class
473                && e.getClass() != KeyStoreException.class) {
474                throw e;
475            }
476        }
477        try {
478            KeyStore.getInstance(type, (String)null);
479            fail(type);
480        } catch (IllegalArgumentException expected) {
481        }
482        assertNotNull(KeyStore.getInstance(type, providerName));
483
484        Provider provider = Security.getProvider(providerName);
485        try {
486            KeyStore.getInstance(null, (Provider)null);
487            fail(type);
488        } catch (IllegalArgumentException expected) {
489        }
490        try {
491            KeyStore.getInstance(null, provider);
492            fail(type);
493        } catch (NullPointerException expected) {
494        }
495        try {
496            KeyStore.getInstance(type, (Provider)null);
497            fail(type);
498        } catch (IllegalArgumentException expected) {
499        }
500        assertNotNull(KeyStore.getInstance(type, provider));
501    }
502
503    public void test_KeyStore_getDefaultType() throws Exception {
504        String type = KeyStore.getDefaultType();
505        assertNotNull(type);
506        KeyStore ks = KeyStore.getInstance(type);
507        assertNotNull(ks);
508        assertEquals(type, ks.getType());
509    }
510
511    public void test_KeyStore_getProvider() throws Exception {
512        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
513        assertNotNull(ks.getProvider());
514        assertNotNull(StandardNames.SECURITY_PROVIDER_NAME, ks.getProvider().getName());
515
516        for (KeyStore keyStore : keyStores()) {
517            assertNotNull(keyStore.getProvider());
518        }
519    }
520
521    public void test_KeyStore_getType() throws Exception {
522        String type = KeyStore.getDefaultType();
523        KeyStore ks = KeyStore.getInstance(type);
524        assertNotNull(ks.getType());
525        assertNotNull(type, ks.getType());
526
527        for (KeyStore keyStore : keyStores()) {
528            assertNotNull(keyStore.getType());
529        }
530    }
531
532    public void test_KeyStore_getKey() throws Exception {
533        for (KeyStore keyStore : keyStores()) {
534            try {
535                keyStore.getKey(null, null);
536                fail(keyStore.getType());
537            } catch (KeyStoreException expected) {
538            }
539        }
540
541        for (KeyStore keyStore : keyStores()) {
542            populate(keyStore);
543
544            // test odd inputs
545            try {
546                keyStore.getKey(null, null);
547                fail(keyStore.getType());
548            } catch (Exception e) {
549                if (e.getClass() != NullPointerException.class
550                    && e.getClass() != IllegalArgumentException.class) {
551                    throw e;
552                }
553            }
554            try {
555                keyStore.getKey(null, PASSWORD_KEY);
556                fail(keyStore.getType());
557            } catch (Exception e) {
558                if (e.getClass() != NullPointerException.class
559                    && e.getClass() != IllegalArgumentException.class
560                    && e.getClass() != KeyStoreException.class) {
561                    throw e;
562                }
563            }
564            assertNull(keyStore.getKey("", null));
565            assertNull(keyStore.getKey("", PASSWORD_KEY));
566
567            // test case sensitive
568            if (isReadOnly(keyStore)) {
569                assertNull(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
570            } else {
571                if (isKeyPasswordSupported(keyStore)) {
572                    assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
573                }
574                if (isNullPasswordAllowed(keyStore)) {
575                    assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
576                }
577                if (isSecretKeyEnabled(keyStore)) {
578                    assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
579                } else {
580                    assertNull(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
581                }
582            }
583
584            // test case insensitive
585            if (isCaseSensitive(keyStore) || isReadOnly(keyStore)) {
586                assertNull(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
587                assertNull(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, PASSWORD_KEY));
588                assertNull(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
589            } else {
590                if (isKeyPasswordSupported(keyStore)) {
591                    assertPrivateKey(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
592                }
593                if (isNullPasswordAllowed(keyStore)) {
594                    assertPrivateKey(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, null));
595                }
596                if (isSecretKeyEnabled(keyStore)) {
597                    assertSecretKey(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
598                }
599            }
600
601            // test with null passwords
602            if (isKeyPasswordSupported(keyStore) && isKeyPasswordIgnored(keyStore)) {
603                assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, null));
604            } else {
605                if (isReadOnly(keyStore)) {
606                    assertNull(keyStore.getKey(ALIAS_PRIVATE, null));
607                } else if (isKeyPasswordSupported(keyStore)) {
608                    try {
609                        keyStore.getKey(ALIAS_PRIVATE, null);
610                        fail(keyStore.getType());
611                    } catch (Exception e) {
612                        if (e.getClass() != UnrecoverableKeyException.class
613                            && e.getClass() != IllegalArgumentException.class) {
614                            throw e;
615                        }
616                    }
617                }
618            }
619            if (isReadOnly(keyStore)) {
620                assertNull(keyStore.getKey(ALIAS_SECRET, null));
621            } else if (isSecretKeyEnabled(keyStore)) {
622                try {
623                    keyStore.getKey(ALIAS_SECRET, null);
624                    fail(keyStore.getType());
625                } catch (Exception e) {
626                    if (e.getClass() != UnrecoverableKeyException.class
627                        && e.getClass() != IllegalArgumentException.class) {
628                        throw e;
629                    }
630                }
631            }
632
633            // test with bad passwords
634            if (isReadOnly(keyStore)) {
635                assertNull(keyStore.getKey(ALIAS_PRIVATE, null));
636            } else if (isKeyPasswordSupported(keyStore) && isKeyPasswordIgnored(keyStore)) {
637                assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, null));
638            } else if (isKeyPasswordSupported(keyStore)) {
639                try {
640                    keyStore.getKey(ALIAS_PRIVATE, PASSWORD_BAD);
641                    fail(keyStore.getType());
642                } catch (UnrecoverableKeyException expected) {
643                }
644            }
645            if (isReadOnly(keyStore)) {
646                assertNull(keyStore.getKey(ALIAS_SECRET, PASSWORD_BAD));
647            } else if (isSecretKeyEnabled(keyStore)) {
648                try {
649                    keyStore.getKey(ALIAS_SECRET, PASSWORD_BAD);
650                    fail(keyStore.getType());
651                } catch (UnrecoverableKeyException expected) {
652                }
653            }
654        }
655    }
656
657    public void test_KeyStore_getCertificateChain() throws Exception {
658        for (KeyStore keyStore : keyStores()) {
659            try {
660                keyStore.getCertificateChain(null);
661                fail(keyStore.getType());
662            } catch (KeyStoreException expected) {
663            }
664        }
665        for (KeyStore keyStore : keyStores()) {
666            populate(keyStore);
667
668            // test odd inputs
669            try {
670                keyStore.getCertificateChain(null);
671                fail(keyStore.getType());
672            } catch (Exception e) {
673                if (e.getClass() != NullPointerException.class
674                    && e.getClass() != IllegalArgumentException.class) {
675                    throw e;
676                }
677            }
678            assertNull(keyStore.getCertificateChain(""));
679
680            // test case sensitive
681            if (isReadOnly(keyStore)) {
682                assertNull(keyStore.getCertificateChain(ALIAS_PRIVATE));
683            } else if (isKeyPasswordSupported(keyStore)) {
684                assertCertificateChain(keyStore.getCertificateChain(ALIAS_PRIVATE));
685            } else if (isNullPasswordAllowed(keyStore)) {
686                assertCertificateChain(keyStore.getCertificateChain(ALIAS_NO_PASSWORD_PRIVATE));
687            }
688
689            // test case insensitive
690            if (isReadOnly(keyStore) || isCaseSensitive(keyStore)) {
691                assertNull(keyStore.getCertificateChain(ALIAS_ALT_CASE_PRIVATE));
692            } else {
693                assertCertificateChain(keyStore.getCertificateChain(ALIAS_ALT_CASE_PRIVATE));
694            }
695        }
696    }
697
698    public void test_KeyStore_getCertificate() throws Exception {
699        for (KeyStore keyStore : keyStores()) {
700            try {
701                keyStore.getCertificate(null);
702                fail(keyStore.getType());
703            } catch (KeyStoreException expected) {
704            }
705        }
706        for (KeyStore keyStore : keyStores()) {
707            populate(keyStore);
708
709            // test odd inputs
710            try {
711                keyStore.getCertificate(null);
712                fail(keyStore.getType());
713            } catch (Exception e) {
714                if (e.getClass() != NullPointerException.class
715                    && e.getClass() != IllegalArgumentException.class) {
716                    throw e;
717                }
718            }
719            assertNull(keyStore.getCertificate(""));
720
721            // test case sensitive
722            if (!isReadOnly(keyStore) && isCertificateEnabled(keyStore)) {
723                assertCertificate(keyStore.getCertificate(ALIAS_CERTIFICATE));
724            } else {
725                assertNull(keyStore.getCertificate(ALIAS_CERTIFICATE));
726            }
727
728            // test case insensitive
729            if (isReadOnly(keyStore) || isCaseSensitive(keyStore)) {
730                assertNull(keyStore.getCertificate(ALIAS_ALT_CASE_CERTIFICATE));
731            } else {
732                if (isCertificateEnabled(keyStore)) {
733                    assertCertificate(keyStore.getCertificate(ALIAS_ALT_CASE_CERTIFICATE));
734                }
735            }
736        }
737    }
738
739    public void test_KeyStore_getCreationDate() throws Exception {
740        for (KeyStore keyStore : keyStores()) {
741            try {
742                keyStore.getCreationDate(null);
743                fail(keyStore.getType());
744            } catch (KeyStoreException expected) {
745            }
746        }
747        long before = System.currentTimeMillis();
748        for (KeyStore keyStore : keyStores()) {
749            populate(keyStore);
750
751            // add 1000 since some key stores round of time to nearest second
752            long after = System.currentTimeMillis() + 1000;
753
754            // test odd inputs
755            try {
756                keyStore.getCreationDate(null);
757                fail(keyStore.getType());
758            } catch (NullPointerException expected) {
759            }
760            assertNull(keyStore.getCreationDate(""));
761
762            // test case sensitive
763            if (!isReadOnly(keyStore) && isCertificateEnabled(keyStore)) {
764                Date date = keyStore.getCreationDate(ALIAS_CERTIFICATE);
765                assertNotNull(date);
766                assertTrue("date should be after start time: " + date.getTime() + " >= " + before,
767                        before <= date.getTime());
768                assertTrue("date should be before expiry time: " + date.getTime() + " <= " + after,
769                        date.getTime() <= after);
770            } else {
771                assertNull(keyStore.getCreationDate(ALIAS_CERTIFICATE));
772            }
773
774            // test case insensitive
775            if (isReadOnly(keyStore) || isCaseSensitive(keyStore)) {
776                assertNull(keyStore.getCreationDate(ALIAS_ALT_CASE_CERTIFICATE));
777            } else {
778                if (isCertificateEnabled(keyStore)) {
779                    Date date = keyStore.getCreationDate(ALIAS_ALT_CASE_CERTIFICATE);
780                    assertTrue(before <= date.getTime());
781                    assertTrue(date.getTime() <= after);
782                }
783            }
784        }
785    }
786
787    public void test_KeyStore_setKeyEntry_Key() throws Exception {
788        for (KeyStore keyStore : keyStores()) {
789            try {
790                keyStore.setKeyEntry(null, null, null, null);
791                fail(keyStore.getType());
792            } catch (KeyStoreException expected) {
793            }
794        }
795
796        for (KeyStore keyStore : keyStores()) {
797            keyStore.load(null, null);
798            if (isReadOnly(keyStore)) {
799                try {
800                    keyStore.setKeyEntry(null, null, null, null);
801                    fail(keyStore.getType());
802                } catch (UnsupportedOperationException expected) {
803                }
804                continue;
805            }
806
807            // test odd inputs
808            try {
809                keyStore.setKeyEntry(null, null, null, null);
810                fail(keyStore.getType());
811            } catch (Exception e) {
812                if (e.getClass() != NullPointerException.class
813                    && e.getClass() != KeyStoreException.class) {
814                    throw e;
815                }
816            }
817            try {
818                keyStore.setKeyEntry(null, null, PASSWORD_KEY, null);
819                fail(keyStore.getType());
820            } catch (Exception e) {
821                if (e.getClass() != NullPointerException.class
822                    && e.getClass() != KeyStoreException.class) {
823                    throw e;
824                }
825            }
826            try {
827                keyStore.setKeyEntry(ALIAS_PRIVATE,
828                                     getPrivateKey().getPrivateKey(),
829                                     PASSWORD_KEY,
830                                     null);
831                fail(keyStore.getType());
832            } catch (Exception e) {
833                if (e.getClass() != IllegalArgumentException.class
834                        && e.getClass() != KeyStoreException.class) {
835                    throw e;
836                }
837            }
838        }
839
840        for (KeyStore keyStore : keyStores()) {
841            clearKeyStore(keyStore);
842
843            // test case sensitive
844            if (isKeyPasswordSupported(keyStore)) {
845                assertNull(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
846            }
847            if (isNullPasswordAllowed(keyStore)) {
848                assertNull(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
849            }
850            if (isReadOnly(keyStore)) {
851                try {
852                    keyStore.setKeyEntry(ALIAS_SECRET, getSecretKey(), PASSWORD_KEY, null);
853                    fail(keyStore.getType());
854                } catch (UnsupportedOperationException expected) {
855                }
856                continue;
857            }
858            if (isKeyPasswordSupported(keyStore)) {
859                setPrivateKey(keyStore);
860                assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
861                assertCertificateChain(keyStore.getCertificateChain(ALIAS_PRIVATE));
862            }
863            if (isNullPasswordAllowed(keyStore)) {
864                setPrivateKeyNoPassword(keyStore, ALIAS_NO_PASSWORD_PRIVATE, getPrivateKey());
865                assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
866                assertCertificateChain(keyStore.getCertificateChain(ALIAS_NO_PASSWORD_PRIVATE));
867            }
868            if (isSecretKeyEnabled(keyStore)) {
869                assertNull(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
870                setSecretKey(keyStore);
871                assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
872            } else {
873                try {
874                    keyStore.setKeyEntry(ALIAS_SECRET, getSecretKey(), PASSWORD_KEY, null);
875                    fail(keyStore.getType());
876                } catch (Exception e) {
877                    if (e.getClass() != KeyStoreException.class
878                        && e.getClass() != NullPointerException.class) {
879                        throw e;
880                    }
881                }
882            }
883        }
884
885        for (KeyStore keyStore : keyStores()) {
886            populate(keyStore);
887
888            if (isReadOnly(keyStore)) {
889                assertNull(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
890                assertNull(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
891                assertNull(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
892                assertNull(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
893            } else if (isCaseSensitive(keyStore)) {
894                if (isKeyPasswordSupported(keyStore)) {
895                    assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
896                    assertNull(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
897                    setPrivateKey(keyStore, ALIAS_ALT_CASE_PRIVATE, getPrivateKey2());
898                    assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
899                    assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
900                }
901
902                if (isNullPasswordAllowed(keyStore)) {
903                    assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
904                    assertNull(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, null));
905                    setPrivateKeyNoPassword(keyStore, ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE,
906                            getPrivateKey2());
907                    assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
908                    assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, null));
909                }
910
911                if (isSecretKeyEnabled(keyStore)) {
912                    assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
913                    assertNull(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
914                    setSecretKey(keyStore, ALIAS_ALT_CASE_SECRET, getSecretKey2());
915                    assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
916                    assertSecretKey2(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
917                }
918            } else {
919                if (isKeyPasswordSupported(keyStore)) {
920                    assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
921                    assertPrivateKey(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
922                    setPrivateKey(keyStore, ALIAS_ALT_CASE_PRIVATE, getPrivateKey2());
923                    assertPrivateKey2(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
924                    assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
925                }
926
927                if (isNullPasswordAllowed(keyStore)) {
928                    assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, null));
929                    assertPrivateKey(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, null));
930                    setPrivateKey(keyStore, ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, getPrivateKey2());
931                    assertPrivateKey2(keyStore.getKey(ALIAS_PRIVATE, null));
932                    assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, null));
933                }
934
935                if (isSecretKeyEnabled(keyStore)) {
936                    assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
937                    assertSecretKey(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
938                    setSecretKey(keyStore, ALIAS_ALT_CASE_PRIVATE, getSecretKey2());
939                    assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
940                    assertSecretKey(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
941                }
942            }
943        }
944
945        for (KeyStore keyStore : keyStores()) {
946            keyStore.load(null, null);
947            if (isReadOnly(keyStore)) {
948                try {
949                    keyStore.setKeyEntry(ALIAS_PRIVATE,
950                                         getPrivateKey().getPrivateKey(),
951                                         null,
952                                         getPrivateKey().getCertificateChain());
953                    fail(keyStore.getType());
954                } catch (UnsupportedOperationException expected) {
955                }
956                continue;
957            }
958
959            // test with null passwords
960            if (isNullPasswordAllowed(keyStore) || isKeyPasswordIgnored(keyStore)) {
961                keyStore.setKeyEntry(ALIAS_PRIVATE,
962                                     getPrivateKey().getPrivateKey(),
963                                     null,
964                                     getPrivateKey().getCertificateChain());
965                assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, null));
966            } else {
967                try {
968                    keyStore.setKeyEntry(ALIAS_PRIVATE,
969                                         getPrivateKey().getPrivateKey(),
970                                         null,
971                                         getPrivateKey().getCertificateChain());
972                    fail(keyStore.getType());
973                } catch (Exception e) {
974                    if (e.getClass() != UnrecoverableKeyException.class
975                        && e.getClass() != IllegalArgumentException.class
976                        && e.getClass() != KeyStoreException.class) {
977                        throw e;
978                    }
979                }
980            }
981            if (isSecretKeyEnabled(keyStore)) {
982                if (isNullPasswordAllowed(keyStore) || isKeyPasswordIgnored(keyStore)) {
983                    keyStore.setKeyEntry(ALIAS_SECRET, getSecretKey(), null, null);
984                    assertSecretKey(keyStore.getKey(ALIAS_SECRET, null));
985                } else {
986                    try {
987                        keyStore.setKeyEntry(ALIAS_SECRET, getSecretKey(), null, null);
988                        fail(keyStore.getType());
989                    } catch (Exception e) {
990                        if (e.getClass() != UnrecoverableKeyException.class
991                            && e.getClass() != IllegalArgumentException.class
992                            && e.getClass() != KeyStoreException.class) {
993                            throw e;
994                        }
995                    }
996                }
997            }
998        }
999    }
1000
1001    public void test_KeyStore_setKeyEntry_array() throws Exception {
1002        for (KeyStore keyStore : keyStores()) {
1003            try {
1004                keyStore.setKeyEntry(null, null, null);
1005                fail(keyStore.getType());
1006            } catch (KeyStoreException expected) {
1007            }
1008        }
1009
1010        for (KeyStore keyStore : keyStores()) {
1011            keyStore.load(null, null);
1012
1013            if (isReadOnly(keyStore)) {
1014                try {
1015                    keyStore.setKeyEntry(null, null, null);
1016                    fail(keyStore.getType());
1017                } catch (UnsupportedOperationException expected) {
1018                }
1019                continue;
1020            }
1021
1022            // test odd inputs
1023            try {
1024                keyStore.setKeyEntry(null, null, null);
1025                fail(keyStore.getType());
1026            } catch (Exception e) {
1027                if (e.getClass() != NullPointerException.class
1028                    && e.getClass() != IllegalArgumentException.class
1029                    && e.getClass() != KeyStoreException.class
1030                    && e.getClass() != RuntimeException.class) {
1031                    throw e;
1032                }
1033            }
1034        }
1035
1036        for (KeyStore keyStore : keyStores()) {
1037            if (!isNullPasswordAllowed(keyStore)) {
1038                // TODO Use EncryptedPrivateKeyInfo to protect keys if
1039                // password is required.
1040                continue;
1041            }
1042            if (isSetKeyByteArrayUnimplemented(keyStore)) {
1043                continue;
1044            }
1045
1046            clearKeyStore(keyStore);
1047
1048            // test case sensitive
1049            if (isKeyPasswordSupported(keyStore)) {
1050                assertNull(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
1051            }
1052            if (isNullPasswordAllowed(keyStore)) {
1053                assertNull(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
1054            }
1055            if (isReadOnly(keyStore)) {
1056                try {
1057                    setPrivateKeyBytes(keyStore);
1058                    fail(keyStore.getType());
1059                } catch (UnsupportedOperationException expected) {
1060                }
1061                continue;
1062            }
1063            if (isKeyPasswordSupported(keyStore)) {
1064                setPrivateKeyBytes(keyStore);
1065                assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
1066                assertCertificateChain(keyStore.getCertificateChain(ALIAS_PRIVATE));
1067            }
1068            if (isNullPasswordAllowed(keyStore)) {
1069                setPrivateKeyNoPassword(keyStore, ALIAS_NO_PASSWORD_PRIVATE, getPrivateKey());
1070                assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
1071                assertCertificateChain(keyStore.getCertificateChain(ALIAS_NO_PASSWORD_PRIVATE));
1072            }
1073            if (isSecretKeyEnabled(keyStore)) {
1074                assertNull(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
1075                setSecretKeyBytes(keyStore);
1076                assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
1077            } else {
1078                try {
1079                    keyStore.setKeyEntry(ALIAS_SECRET, getSecretKey().getEncoded(), null);
1080                    fail(keyStore.getType());
1081                } catch (KeyStoreException expected) {
1082                }
1083            }
1084        }
1085
1086        for (KeyStore keyStore : keyStores()) {
1087            if (!isNullPasswordAllowed(keyStore)) {
1088                // TODO Use EncryptedPrivateKeyInfo to protect keys if
1089                // password is required.
1090                continue;
1091            }
1092            if (isSetKeyByteArrayUnimplemented(keyStore)) {
1093                continue;
1094            }
1095
1096            populate(keyStore);
1097
1098            if (isReadOnly(keyStore)) {
1099                assertNull(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
1100                assertNull(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
1101                assertNull(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
1102                assertNull(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
1103            } else if (isCaseSensitive(keyStore)) {
1104                if (isKeyPasswordSupported(keyStore)) {
1105                    assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
1106                    assertNull(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
1107                    setPrivateKeyBytes(keyStore, ALIAS_ALT_CASE_PRIVATE, getPrivateKey2());
1108                    assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
1109                    assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
1110                }
1111                if (isNullPasswordAllowed(keyStore)) {
1112                    assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
1113                    assertNull(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, null));
1114                    setPrivateKeyNoPassword(keyStore, ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE,
1115                            getPrivateKey2());
1116                    assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
1117                    assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, null));
1118                }
1119
1120                if (isSecretKeyEnabled(keyStore)) {
1121                    assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
1122                    assertNull(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
1123                    setSecretKeyBytes(keyStore, ALIAS_ALT_CASE_PRIVATE, getSecretKey2());
1124                    assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
1125                    assertSecretKey2(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
1126                }
1127            } else {
1128                if (isKeyPasswordSupported(keyStore)) {
1129                    assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
1130                    assertPrivateKey(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
1131                    setPrivateKeyBytes(keyStore, ALIAS_ALT_CASE_PRIVATE, getPrivateKey2());
1132                    assertPrivateKey2(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
1133                    assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
1134                }
1135                if (isNullPasswordAllowed(keyStore)) {
1136                    assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
1137                    assertPrivateKey(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, null));
1138                    setPrivateKeyNoPassword(keyStore, ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE,
1139                            getPrivateKey2());
1140                    assertPrivateKey2(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
1141                    assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, null));
1142                }
1143
1144                if (isSecretKeyEnabled(keyStore)) {
1145                    assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
1146                    assertSecretKey(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
1147                    setSecretKeyBytes(keyStore, ALIAS_ALT_CASE_PRIVATE, getSecretKey2());
1148                    assertSecretKey2(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
1149                    assertSecretKey2(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
1150                }
1151            }
1152        }
1153    }
1154
1155    public void test_KeyStore_setCertificateEntry() throws Exception {
1156        for (KeyStore keyStore : keyStores()) {
1157            try {
1158                keyStore.setCertificateEntry(null, null);
1159                fail(keyStore.getType());
1160            } catch (KeyStoreException expected) {
1161            }
1162        }
1163
1164        for (KeyStore keyStore : keyStores()) {
1165            populate(keyStore);
1166
1167            // test odd inputs
1168            try {
1169                keyStore.setCertificateEntry(null, null);
1170                fail(keyStore.getType());
1171            } catch (Exception e) {
1172                if (e.getClass() != NullPointerException.class
1173                    && e.getClass() != KeyStoreException.class) {
1174                    throw e;
1175                }
1176            }
1177
1178            if (isReadOnly(keyStore)) {
1179                try {
1180                    assertNull(keyStore.getCertificate(ALIAS_CERTIFICATE));
1181                    keyStore.setCertificateEntry(ALIAS_CERTIFICATE, null);
1182                    fail(keyStore.getType());
1183                } catch (UnsupportedOperationException expected) {
1184                }
1185                continue;
1186            }
1187
1188            // Sort of delete by setting null.  Note that even though
1189            // certificate is null, size doesn't change,
1190            // isCertificateEntry returns true, and it is still listed in aliases.
1191            if (isCertificateEnabled(keyStore)) {
1192                assertCertificate(keyStore.getCertificate(ALIAS_CERTIFICATE));
1193                try {
1194                    int size = keyStore.size();
1195                    keyStore.setCertificateEntry(ALIAS_CERTIFICATE, null);
1196                    assertNull(keyStore.getType(), keyStore.getCertificate(ALIAS_CERTIFICATE));
1197                    assertEquals(keyStore.getType(), size, keyStore.size());
1198                    assertTrue(keyStore.getType(), keyStore.isCertificateEntry(ALIAS_CERTIFICATE));
1199                    assertTrue(keyStore.getType(),
1200                            Collections.list(keyStore.aliases()).contains(ALIAS_CERTIFICATE));
1201                } catch (NullPointerException expectedSometimes) {
1202                    if (!("PKCS12".equalsIgnoreCase(keyStore.getType()) &&
1203                                "BC".equalsIgnoreCase(keyStore.getProvider().getName()))
1204                            && !"AndroidKeyStore".equalsIgnoreCase(keyStore.getType())) {
1205                        throw expectedSometimes;
1206                    }
1207                }
1208            } else {
1209                try {
1210                    keyStore.setCertificateEntry(ALIAS_CERTIFICATE, null);
1211                    fail(keyStore.getType());
1212                } catch (KeyStoreException expected) {
1213                }
1214            }
1215        }
1216
1217        for (KeyStore keyStore : keyStores()) {
1218            if (!isCertificateEnabled(keyStore)) {
1219                continue;
1220            }
1221
1222            clearKeyStore(keyStore);
1223
1224            assertNull(keyStore.getCertificate(ALIAS_CERTIFICATE));
1225            if (isReadOnly(keyStore)) {
1226                try {
1227                    setCertificate(keyStore);
1228                    fail(keyStore.getType());
1229                } catch (UnsupportedOperationException expected) {
1230                }
1231                continue;
1232            }
1233            setCertificate(keyStore);
1234            assertCertificate(keyStore.getCertificate(ALIAS_CERTIFICATE));
1235        }
1236
1237        for (KeyStore keyStore : keyStores()) {
1238            if (!isCertificateEnabled(keyStore)) {
1239                continue;
1240            }
1241
1242            populate(keyStore);
1243
1244            if (isReadOnly(keyStore)) {
1245                assertNull(keyStore.getCertificate(ALIAS_CERTIFICATE));
1246                assertNull(keyStore.getCertificate(ALIAS_ALT_CASE_CERTIFICATE));
1247            } else if (isCaseSensitive(keyStore)) {
1248                assertCertificate(keyStore.getCertificate(ALIAS_CERTIFICATE));
1249                assertNull(keyStore.getCertificate(ALIAS_ALT_CASE_CERTIFICATE));
1250                setCertificate(keyStore,
1251                               ALIAS_ALT_CASE_CERTIFICATE,
1252                               getPrivateKey2().getCertificate());
1253                assertCertificate(keyStore.getCertificate(ALIAS_CERTIFICATE));
1254                assertCertificate2(keyStore.getCertificate(ALIAS_ALT_CASE_CERTIFICATE));
1255            } else {
1256                assertCertificate(keyStore.getCertificate(ALIAS_CERTIFICATE));
1257                assertCertificate(keyStore.getCertificate(ALIAS_ALT_CASE_CERTIFICATE));
1258                setCertificate(keyStore,
1259                               ALIAS_ALT_CASE_CERTIFICATE,
1260                               getPrivateKey2().getCertificate());
1261                assertCertificate2(keyStore.getCertificate(ALIAS_CERTIFICATE));
1262                assertCertificate2(keyStore.getCertificate(ALIAS_ALT_CASE_CERTIFICATE));
1263            }
1264        }
1265    }
1266    public void test_KeyStore_deleteEntry() throws Exception {
1267        for (KeyStore keyStore : keyStores()) {
1268            try {
1269                keyStore.deleteEntry(null);
1270                fail(keyStore.getType());
1271            } catch (KeyStoreException expected) {
1272            }
1273        }
1274
1275        for (KeyStore keyStore : keyStores()) {
1276            keyStore.load(null, null);
1277
1278            if (isReadOnly(keyStore)) {
1279                try {
1280                    keyStore.deleteEntry(null);
1281                    fail(keyStore.getType());
1282                } catch (UnsupportedOperationException expected) {
1283                }
1284                continue;
1285            }
1286
1287            // test odd inputs
1288            try {
1289                keyStore.deleteEntry(null);
1290                fail(keyStore.getType());
1291            } catch (Exception e) {
1292                if (e.getClass() != NullPointerException.class
1293                    && e.getClass() != KeyStoreException.class) {
1294                    throw e;
1295                }
1296            }
1297            keyStore.deleteEntry("");
1298        }
1299
1300        for (KeyStore keyStore : keyStores()) {
1301            populate(keyStore);
1302
1303            if (isReadOnly(keyStore)) {
1304                try {
1305                    keyStore.deleteEntry(ALIAS_PRIVATE);
1306                } catch (UnsupportedOperationException e) {
1307                }
1308                continue;
1309            }
1310
1311            // test case sensitive
1312            if (isKeyPasswordSupported(keyStore)) {
1313                assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
1314                assertCertificateChain(keyStore.getCertificateChain(ALIAS_PRIVATE));
1315                keyStore.deleteEntry(ALIAS_PRIVATE);
1316                assertNull(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
1317            }
1318            if (isNullPasswordAllowed(keyStore)) {
1319                assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
1320                assertCertificateChain(keyStore.getCertificateChain(ALIAS_NO_PASSWORD_PRIVATE));
1321                keyStore.deleteEntry(ALIAS_NO_PASSWORD_PRIVATE);
1322                assertNull(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
1323            }
1324
1325            if (isSecretKeyEnabled(keyStore)) {
1326                assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
1327                keyStore.deleteEntry(ALIAS_SECRET);
1328                assertNull(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
1329            } else {
1330                keyStore.deleteEntry(ALIAS_SECRET);
1331            }
1332
1333            if (isCertificateEnabled(keyStore)) {
1334                assertCertificate(keyStore.getCertificate(ALIAS_CERTIFICATE));
1335                keyStore.deleteEntry(ALIAS_CERTIFICATE);
1336                assertNull(keyStore.getCertificate(ALIAS_CERTIFICATE));
1337            } else {
1338                keyStore.deleteEntry(ALIAS_CERTIFICATE);
1339            }
1340        }
1341
1342        for (KeyStore keyStore : keyStores()) {
1343            populate(keyStore);
1344
1345            // test case insensitive
1346
1347            if (isCaseSensitive(keyStore)) {
1348                if (isKeyPasswordSupported(keyStore)) {
1349                    assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
1350                    keyStore.deleteEntry(ALIAS_ALT_CASE_PRIVATE);
1351                    assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
1352                }
1353                if (isNullPasswordAllowed(keyStore)) {
1354                    assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
1355                    keyStore.deleteEntry(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE);
1356                    assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
1357                }
1358
1359                if (isSecretKeyEnabled(keyStore)) {
1360                    assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
1361                    keyStore.deleteEntry(ALIAS_ALT_CASE_SECRET);
1362                    assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
1363                } else {
1364                    keyStore.deleteEntry(ALIAS_SECRET);
1365                }
1366
1367                if (isCertificateEnabled(keyStore)) {
1368                    assertCertificate(keyStore.getCertificate(ALIAS_CERTIFICATE));
1369                    keyStore.deleteEntry(ALIAS_ALT_CASE_CERTIFICATE);
1370                    assertCertificate(keyStore.getCertificate(ALIAS_CERTIFICATE));
1371                } else {
1372                    keyStore.deleteEntry(ALIAS_CERTIFICATE);
1373                }
1374            }
1375        }
1376    }
1377
1378    public void test_KeyStore_aliases() throws Exception {
1379        for (KeyStore keyStore : keyStores()) {
1380            try {
1381                keyStore.aliases();
1382                fail(keyStore.getType());
1383            } catch (KeyStoreException expected) {
1384            }
1385        }
1386
1387        for (KeyStore keyStore : keyStores()) {
1388            keyStore.load(null, null);
1389            if (isPersistentStorage(keyStore)) {
1390                assertNotNull("Should be able to query size: " + keyStore.getType(),
1391                        keyStore.aliases());
1392            } else if (hasDefaultContents(keyStore)) {
1393                assertTrue("Should have more than one alias already: " + keyStore.getType(),
1394                        keyStore.aliases().hasMoreElements());
1395            } else {
1396                assertEquals("Should have no aliases:" + keyStore.getType(), Collections.EMPTY_SET,
1397                        new HashSet(Collections.list(keyStore.aliases())));
1398            }
1399        }
1400
1401        for (KeyStore keyStore : keyStores()) {
1402            populate(keyStore);
1403
1404            Set<String> expected = new HashSet<String>();
1405            if (isKeyPasswordSupported(keyStore)) {
1406                expected.add(ALIAS_PRIVATE);
1407            }
1408            if (isNullPasswordAllowed(keyStore)) {
1409                expected.add(ALIAS_NO_PASSWORD_PRIVATE);
1410            }
1411            if (isSecretKeyEnabled(keyStore)) {
1412                expected.add(ALIAS_SECRET);
1413                if (isNullPasswordAllowed(keyStore)) {
1414                    expected.add(ALIAS_NO_PASSWORD_SECRET);
1415                }
1416            }
1417            if (isCertificateEnabled(keyStore)) {
1418                expected.add(ALIAS_CERTIFICATE);
1419            }
1420            if (isPersistentStorage(keyStore)) {
1421                assertNotNull("Should be able to query size: " + keyStore.getType(),
1422                        keyStore.aliases());
1423            } else if (hasDefaultContents(keyStore)) {
1424                assertTrue(keyStore.aliases().hasMoreElements());
1425            } else {
1426                assertEquals(expected, new HashSet<String>(Collections.list(keyStore.aliases())));
1427            }
1428        }
1429    }
1430
1431    public void test_KeyStore_containsAlias() throws Exception {
1432        for (KeyStore keyStore : keyStores()) {
1433            try {
1434                keyStore.containsAlias(null);
1435                fail(keyStore.getType());
1436            } catch (KeyStoreException expected) {
1437            }
1438        }
1439
1440        for (KeyStore keyStore : keyStores()) {
1441            keyStore.load(null, null);
1442
1443            try {
1444                keyStore.containsAlias(null);
1445                fail(keyStore.getType());
1446            } catch (NullPointerException expected) {
1447            }
1448
1449            assertFalse(keyStore.containsAlias(""));
1450        }
1451
1452        for (KeyStore keyStore : keyStores()) {
1453            populate(keyStore);
1454
1455            assertFalse(keyStore.containsAlias(""));
1456
1457            if (isReadOnly(keyStore)) {
1458                assertFalse(keyStore.containsAlias(ALIAS_PRIVATE));
1459                continue;
1460            }
1461            if (isKeyPasswordSupported(keyStore)) {
1462                assertTrue(keyStore.containsAlias(ALIAS_PRIVATE));
1463            } else if (isNullPasswordAllowed(keyStore)) {
1464                assertTrue(keyStore.containsAlias(ALIAS_NO_PASSWORD_PRIVATE));
1465            }
1466            assertEquals(isSecretKeyEnabled(keyStore), keyStore.containsAlias(ALIAS_SECRET));
1467            assertEquals(isCertificateEnabled(keyStore), keyStore.containsAlias(ALIAS_CERTIFICATE));
1468
1469            assertEquals(!isCaseSensitive(keyStore),
1470                         keyStore.containsAlias(ALIAS_ALT_CASE_PRIVATE));
1471            assertEquals(!isCaseSensitive(keyStore) && isSecretKeyEnabled(keyStore),
1472                         keyStore.containsAlias(ALIAS_ALT_CASE_SECRET));
1473            assertEquals(!isCaseSensitive(keyStore) && isCertificateEnabled(keyStore),
1474                         keyStore.containsAlias(ALIAS_ALT_CASE_CERTIFICATE));
1475        }
1476    }
1477
1478    public void test_KeyStore_size() throws Exception {
1479        for (KeyStore keyStore : keyStores()) {
1480            try {
1481                keyStore.aliases();
1482                fail(keyStore.getType());
1483            } catch (KeyStoreException expected) {
1484            }
1485        }
1486
1487        for (KeyStore keyStore : keyStores()) {
1488            keyStore.load(null, null);
1489            if (isPersistentStorage(keyStore)) {
1490                assertTrue("Should successfully query size: " + keyStore.getType(),
1491                        keyStore.size() >= 0);
1492            } else if (hasDefaultContents(keyStore)) {
1493                assertTrue("Should have non-empty store: " + keyStore.getType(),
1494                        keyStore.size() > 0);
1495            } else {
1496                assertEquals("Should have empty store: " + keyStore.getType(), 0, keyStore.size());
1497            }
1498        }
1499
1500        for (KeyStore keyStore : keyStores()) {
1501            populate(keyStore);
1502            if (hasDefaultContents(keyStore)) {
1503                assertTrue("Should have non-empty store: " + keyStore.getType(),
1504                        keyStore.size() > 0);
1505                continue;
1506            }
1507
1508            int expected = 0;
1509            if (isKeyPasswordSupported(keyStore)) {
1510                expected++;
1511            }
1512            if (isNullPasswordAllowed(keyStore)) {
1513                expected++;
1514            }
1515            if (isSecretKeyEnabled(keyStore)) {
1516                expected++;
1517                if (isNullPasswordAllowed(keyStore)) {
1518                    expected++;
1519                }
1520            }
1521            if (isCertificateEnabled(keyStore)) {
1522                expected++;
1523            }
1524            assertEquals(expected, keyStore.size());
1525        }
1526    }
1527
1528    public void test_KeyStore_isKeyEntry() throws Exception {
1529        for (KeyStore keyStore : keyStores()) {
1530            try {
1531                keyStore.isKeyEntry(null);
1532                fail(keyStore.getType());
1533            } catch (KeyStoreException expected) {
1534            }
1535        }
1536
1537        for (KeyStore keyStore : keyStores()) {
1538            keyStore.load(null, null);
1539
1540            try {
1541                keyStore.isKeyEntry(null);
1542                fail(keyStore.getType());
1543            } catch (NullPointerException expected) {
1544            }
1545
1546            assertFalse(keyStore.isKeyEntry(""));
1547        }
1548
1549        for (KeyStore keyStore : keyStores()) {
1550            populate(keyStore);
1551
1552            assertFalse(keyStore.isKeyEntry(""));
1553            if (isReadOnly(keyStore)) {
1554                assertFalse(keyStore.isKeyEntry(ALIAS_PRIVATE));
1555                continue;
1556            }
1557            if (isKeyPasswordSupported(keyStore)) {
1558                assertTrue(keyStore.isKeyEntry(ALIAS_PRIVATE));
1559            }
1560            if (isNullPasswordAllowed(keyStore)) {
1561                assertTrue(keyStore.isKeyEntry(ALIAS_NO_PASSWORD_PRIVATE));
1562            }
1563            assertEquals(isSecretKeyEnabled(keyStore), keyStore.isKeyEntry(ALIAS_SECRET));
1564            assertFalse(keyStore.isKeyEntry(ALIAS_CERTIFICATE));
1565
1566            assertEquals(!isCaseSensitive(keyStore),
1567                         keyStore.isKeyEntry(ALIAS_ALT_CASE_PRIVATE));
1568            assertEquals(!isCaseSensitive(keyStore) && isSecretKeyEnabled(keyStore),
1569                         keyStore.isKeyEntry(ALIAS_ALT_CASE_SECRET));
1570            assertFalse(keyStore.isKeyEntry(ALIAS_ALT_CASE_CERTIFICATE));
1571        }
1572    }
1573
1574    public void test_KeyStore_isCertificateEntry() throws Exception {
1575        for (KeyStore keyStore : keyStores()) {
1576            try {
1577                keyStore.isCertificateEntry(null);
1578                fail(keyStore.getType());
1579            } catch (KeyStoreException expected) {
1580            }
1581        }
1582
1583        for (KeyStore keyStore : keyStores()) {
1584            keyStore.load(null, null);
1585
1586            if (isCertificateEnabled(keyStore)) {
1587                try {
1588                    keyStore.isCertificateEntry(null);
1589                    fail(keyStore.getType());
1590                } catch (NullPointerException expected) {
1591                }
1592            } else {
1593                assertFalse(keyStore.isCertificateEntry(null));
1594            }
1595
1596            assertFalse(keyStore.isCertificateEntry(""));
1597        }
1598
1599        for (KeyStore keyStore : keyStores()) {
1600            populate(keyStore);
1601
1602            assertFalse(keyStore.isCertificateEntry(""));
1603
1604            if (isKeyPasswordSupported(keyStore)) {
1605                assertFalse(keyStore.isCertificateEntry(ALIAS_PRIVATE));
1606            }
1607            if (isNullPasswordAllowed(keyStore)) {
1608                assertFalse(keyStore.isCertificateEntry(ALIAS_NO_PASSWORD_PRIVATE));
1609            }
1610            assertFalse(keyStore.isCertificateEntry(ALIAS_SECRET));
1611            assertEquals(isCertificateEnabled(keyStore) && !isReadOnly(keyStore),
1612                    keyStore.isCertificateEntry(ALIAS_CERTIFICATE));
1613
1614            assertFalse(keyStore.isCertificateEntry(ALIAS_ALT_CASE_PRIVATE));
1615            assertFalse(keyStore.isCertificateEntry(ALIAS_ALT_CASE_SECRET));
1616            assertEquals(!isCaseSensitive(keyStore)
1617                    && isCertificateEnabled(keyStore)
1618                    && !isReadOnly(keyStore),
1619                    keyStore.isCertificateEntry(ALIAS_ALT_CASE_CERTIFICATE));
1620        }
1621    }
1622
1623    public void test_KeyStore_getCertificateAlias() throws Exception {
1624        for (KeyStore keyStore : keyStores()) {
1625            try {
1626                keyStore.getCertificateAlias(null);
1627                fail(keyStore.getType());
1628            } catch (KeyStoreException expected) {
1629            }
1630        }
1631
1632        for (KeyStore keyStore : keyStores()) {
1633            keyStore.load(null, null);
1634            assertNull(keyStore.getCertificateAlias(null));
1635        }
1636
1637        for (KeyStore keyStore : keyStores()) {
1638            populate(keyStore);
1639
1640            Set<String> expected = new HashSet<String>();
1641            if (isKeyPasswordSupported(keyStore)) {
1642                expected.add(ALIAS_PRIVATE);
1643            }
1644            if (isNullPasswordAllowed(keyStore)) {
1645                expected.add(ALIAS_NO_PASSWORD_PRIVATE);
1646            }
1647            if (isCertificateEnabled(keyStore)) {
1648                expected.add(ALIAS_CERTIFICATE);
1649            }
1650            String actual = keyStore.getCertificateAlias(getPrivateKey().getCertificate());
1651            assertEquals(!isReadOnly(keyStore), expected.contains(actual));
1652            assertNull(keyStore.getCertificateAlias(getPrivateKey2().getCertificate()));
1653        }
1654    }
1655
1656    public void assertEqualsKeyStores(File expected, char[] storePassword, KeyStore actual)
1657            throws Exception{
1658        KeyStore ks = KeyStore.getInstance(actual.getType(), actual.getProvider());
1659        InputStream is = new FileInputStream(expected);
1660        ks.load(is, storePassword);
1661        is.close();
1662        assertEqualsKeyStores(ks, actual);
1663    }
1664
1665    public void assertEqualsKeyStores(KeyStore expected,
1666                                      ByteArrayOutputStream actual, char[] storePassword)
1667            throws Exception{
1668        KeyStore ks = KeyStore.getInstance(expected.getType(), expected.getProvider());
1669        ks.load(new ByteArrayInputStream(actual.toByteArray()), storePassword);
1670        assertEqualsKeyStores(expected, ks);
1671    }
1672
1673    public void assertEqualsKeyStores(KeyStore expected, KeyStore actual)
1674            throws Exception{
1675        assertEquals(expected.size(), actual.size());
1676        for (String alias : Collections.list(actual.aliases())) {
1677            if (alias.equals(ALIAS_NO_PASSWORD_PRIVATE)
1678                    || alias.equals(ALIAS_NO_PASSWORD_SECRET)) {
1679                assertEquals(expected.getKey(alias, null),
1680                             actual.getKey(alias, null));
1681            } else {
1682                assertEquals(expected.getKey(alias, PASSWORD_KEY),
1683                             actual.getKey(alias, PASSWORD_KEY));
1684            }
1685            assertEquals(expected.getCertificate(alias), actual.getCertificate(alias));
1686        }
1687    }
1688
1689    public void test_KeyStore_store_OutputStream() throws Exception {
1690        for (KeyStore keyStore : keyStores()) {
1691            try {
1692                keyStore.store(null, null);
1693                fail(keyStore.getType());
1694            } catch (KeyStoreException expected) {
1695            }
1696        }
1697
1698        for (KeyStore keyStore : keyStores()) {
1699            keyStore.load(null, null);
1700            ByteArrayOutputStream out = new ByteArrayOutputStream();
1701            if (isLoadStoreUnsupported(keyStore) || isReadOnly(keyStore)) {
1702                try {
1703                    keyStore.store(out, null);
1704                    fail(keyStore.getType());
1705                } catch (UnsupportedOperationException expected) {
1706                }
1707                continue;
1708            }
1709
1710            if (isNullPasswordAllowed(keyStore)) {
1711                keyStore.store(out, null);
1712                assertEqualsKeyStores(keyStore, out, null);
1713                continue;
1714            }
1715
1716            try {
1717                keyStore.store(out, null);
1718                fail(keyStore.getType());
1719            } catch (Exception e) {
1720                if (e.getClass() != IllegalArgumentException.class
1721                    && e.getClass() != NullPointerException.class) {
1722                    throw e;
1723                }
1724            }
1725        }
1726
1727        for (KeyStore keyStore : keyStores()) {
1728            populate(keyStore);
1729
1730            ByteArrayOutputStream out = new ByteArrayOutputStream();
1731            if (isLoadStoreUnsupported(keyStore) || isReadOnly(keyStore)) {
1732                try {
1733                    keyStore.store(out, null);
1734                    fail(keyStore.getType());
1735                } catch (UnsupportedOperationException expected) {
1736                }
1737            } else if (isNullPasswordAllowed(keyStore)) {
1738                keyStore.store(out, null);
1739                assertEqualsKeyStores(keyStore, out, null);
1740            } else {
1741                try {
1742                    keyStore.store(out, null);
1743                    fail(keyStore.getType());
1744                } catch (Exception e) {
1745                    if (e.getClass() != IllegalArgumentException.class
1746                        && e.getClass() != NullPointerException.class) {
1747                        throw e;
1748                    }
1749                }
1750            }
1751        }
1752
1753        for (KeyStore keyStore : keyStores()) {
1754            keyStore.load(null, null);
1755            ByteArrayOutputStream out = new ByteArrayOutputStream();
1756            if (isLoadStoreUnsupported(keyStore) || isReadOnly(keyStore)) {
1757                try {
1758                    keyStore.store(out, PASSWORD_STORE);
1759                    fail(keyStore.getType());
1760                } catch (UnsupportedOperationException e) {
1761                }
1762                continue;
1763            }
1764            keyStore.store(out, PASSWORD_STORE);
1765            assertEqualsKeyStores(keyStore, out, PASSWORD_STORE);
1766        }
1767
1768        for (KeyStore keyStore : keyStores()) {
1769            populate(keyStore);
1770            ByteArrayOutputStream out = new ByteArrayOutputStream();
1771            if (isLoadStoreUnsupported(keyStore) || isReadOnly(keyStore)) {
1772                try {
1773                    keyStore.store(out, PASSWORD_STORE);
1774                    fail(keyStore.getType());
1775                } catch (UnsupportedOperationException e) {
1776                }
1777                continue;
1778            }
1779            keyStore.store(out, PASSWORD_STORE);
1780            assertEqualsKeyStores(keyStore, out, PASSWORD_STORE);
1781        }
1782    }
1783
1784    public void test_KeyStore_store_LoadStoreParameter() throws Exception {
1785        for (KeyStore keyStore : keyStores()) {
1786            try {
1787                keyStore.store(null);
1788                fail(keyStore.getType());
1789            } catch (KeyStoreException expected) {
1790            }
1791        }
1792
1793        for (KeyStore keyStore : keyStores()) {
1794            keyStore.load(null, null);
1795            try {
1796                keyStore.store(null);
1797                fail(keyStore.getType());
1798            } catch (UnsupportedOperationException expected) {
1799                assertFalse(isLoadStoreParameterSupported(keyStore));
1800            } catch (IllegalArgumentException expected) {
1801                // its supported, but null causes an exception
1802                assertTrue(isLoadStoreParameterSupported(keyStore));
1803            }
1804        }
1805    }
1806
1807    public void test_KeyStore_load_InputStream() throws Exception {
1808        for (KeyStore keyStore : keyStores()) {
1809            keyStore.load(null, null);
1810            if (isPersistentStorage(keyStore)) {
1811                assertTrue("Should be able to query size: " + keyStore.getType(),
1812                        keyStore.size() >= 0);
1813            } else if (hasDefaultContents(keyStore)) {
1814                assertTrue("Should have non-empty store: " + keyStore.getType(),
1815                        keyStore.size() > 0);
1816            } else {
1817                assertEquals("Should have empty store: " + keyStore.getType(), 0, keyStore.size());
1818            }
1819        }
1820
1821        for (KeyStore keyStore : keyStores()) {
1822            if (isLoadStoreUnsupported(keyStore)) {
1823                continue;
1824            }
1825            keyStore.load(null, PASSWORD_STORE);
1826            if (isPersistentStorage(keyStore)) {
1827                assertTrue("Should be able to query size: " + keyStore.getType(),
1828                        keyStore.size() >= 0);
1829            } else if (hasDefaultContents(keyStore)) {
1830                assertTrue("Should have non-empty store: " + keyStore.getType(),
1831                        keyStore.size() > 0);
1832            } else {
1833                assertEquals("Should have empty store: " + keyStore.getType(), 0, keyStore.size());
1834            }
1835        }
1836
1837        // test_KeyStore_store_OutputStream effectively tests load as well as store
1838    }
1839
1840    public void test_KeyStore_load_LoadStoreParameter() throws Exception {
1841        for (KeyStore keyStore : keyStores()) {
1842            keyStore.load(null);
1843            if (isPersistentStorage(keyStore)) {
1844                assertTrue("Should be able to query size: " + keyStore.getType(),
1845                        keyStore.size() >= 0);
1846            } else if (hasDefaultContents(keyStore)) {
1847                assertTrue("Should have non-empty store: " + keyStore.getType(),
1848                        keyStore.size() > 0);
1849            } else {
1850                assertEquals("Should have empty store: " + keyStore.getType(), 0, keyStore.size());
1851            }
1852        }
1853
1854        for (KeyStore keyStore : keyStores()) {
1855            try {
1856                keyStore.load(new LoadStoreParameter() {
1857                        public ProtectionParameter getProtectionParameter() {
1858                            return null;
1859                        }
1860                    });
1861                fail(keyStore.getType());
1862            } catch (UnsupportedOperationException expected) {
1863            }
1864        }
1865    }
1866
1867    public void test_KeyStore_getEntry() throws Exception {
1868        for (KeyStore keyStore : keyStores()) {
1869            try {
1870                keyStore.getEntry(null, null);
1871                fail(keyStore.getType());
1872            } catch (NullPointerException expected) {
1873            }
1874        }
1875
1876        for (KeyStore keyStore : keyStores()) {
1877            populate(keyStore);
1878
1879            // test odd inputs
1880            try {
1881                keyStore.getEntry(null, null);
1882                fail(keyStore.getType());
1883            } catch (NullPointerException expected) {
1884            }
1885            try {
1886                keyStore.getEntry(null, PARAM_KEY);
1887                fail(keyStore.getType());
1888            } catch (NullPointerException expected) {
1889            }
1890            assertNull(keyStore.getEntry("", null));
1891            assertNull(keyStore.getEntry("", PARAM_KEY));
1892
1893            // test case sensitive
1894            if (isReadOnly(keyStore)) {
1895                assertNull(keyStore.getEntry(ALIAS_PRIVATE, PARAM_KEY));
1896            } else {
1897                if (isKeyPasswordSupported(keyStore)) {
1898                    assertPrivateKey(keyStore.getEntry(ALIAS_PRIVATE, PARAM_KEY));
1899                } else if (isNullPasswordAllowed(keyStore)) {
1900                    assertPrivateKey(keyStore.getEntry(ALIAS_NO_PASSWORD_PRIVATE, null));
1901                }
1902                if (isSecretKeyEnabled(keyStore)) {
1903                    assertSecretKey(keyStore.getEntry(ALIAS_SECRET, PARAM_KEY));
1904                } else {
1905                    assertNull(keyStore.getEntry(ALIAS_SECRET, PARAM_KEY));
1906                }
1907                if (isCertificateEnabled(keyStore)) {
1908                    assertCertificate(keyStore.getEntry(ALIAS_CERTIFICATE, null));
1909                } else {
1910                    assertNull(keyStore.getEntry(ALIAS_CERTIFICATE, null));
1911                }
1912            }
1913
1914            // test case insensitive
1915            if (isCaseSensitive(keyStore) || isReadOnly(keyStore)) {
1916                assertNull(keyStore.getEntry(ALIAS_ALT_CASE_PRIVATE, PARAM_KEY));
1917                assertNull(keyStore.getEntry(ALIAS_ALT_CASE_SECRET, PARAM_KEY));
1918            } else {
1919                assertPrivateKey(keyStore.getEntry(ALIAS_ALT_CASE_PRIVATE, PARAM_KEY));
1920                if (isSecretKeyEnabled(keyStore)) {
1921                    assertSecretKey(keyStore.getEntry(ALIAS_ALT_CASE_SECRET, PARAM_KEY));
1922                }
1923            }
1924            if (isCaseSensitive(keyStore) || isReadOnly(keyStore)) {
1925                assertNull(keyStore.getEntry(ALIAS_ALT_CASE_CERTIFICATE, null));
1926            } else {
1927                if (isCertificateEnabled(keyStore)) {
1928                    assertCertificate(keyStore.getEntry(ALIAS_ALT_CASE_CERTIFICATE, null));
1929                }
1930            }
1931
1932            // test with null passwords
1933            if (isReadOnly(keyStore)) {
1934                assertNull(keyStore.getEntry(ALIAS_NO_PASSWORD_PRIVATE, null));
1935            } else if (isNullPasswordAllowed(keyStore)) {
1936                assertPrivateKey(keyStore.getEntry(ALIAS_NO_PASSWORD_PRIVATE, null));
1937            } else if (isKeyPasswordSupported(keyStore) && isKeyPasswordIgnored(keyStore)) {
1938                assertPrivateKey(keyStore.getEntry(ALIAS_PRIVATE, null));
1939            } else if (isKeyPasswordIgnored(keyStore)) {
1940                try {
1941                    keyStore.getEntry(ALIAS_PRIVATE, null);
1942                    fail(keyStore.getType());
1943                } catch (Exception e) {
1944                    if (e.getClass() != UnrecoverableKeyException.class
1945                        && e.getClass() != IllegalArgumentException.class) {
1946                        throw e;
1947                    }
1948                }
1949            }
1950            if (isReadOnly(keyStore)) {
1951                assertNull(keyStore.getEntry(ALIAS_SECRET, null));
1952            } else if (isSecretKeyEnabled(keyStore)) {
1953                try {
1954                    keyStore.getEntry(ALIAS_SECRET, null);
1955                    fail(keyStore.getType());
1956                } catch (Exception e) {
1957                    if (e.getClass() != UnrecoverableKeyException.class
1958                        && e.getClass() != IllegalArgumentException.class) {
1959                        throw e;
1960                    }
1961                }
1962            }
1963
1964            // test with bad passwords
1965            if (isReadOnly(keyStore)) {
1966                assertNull(keyStore.getEntry(ALIAS_PRIVATE, PARAM_BAD));
1967            } else if (isKeyPasswordSupported(keyStore) && isKeyPasswordIgnored(keyStore)) {
1968                assertPrivateKey(keyStore.getEntry(ALIAS_PRIVATE, PARAM_BAD));
1969            } else if (isKeyPasswordSupported(keyStore)) {
1970                try {
1971                    keyStore.getEntry(ALIAS_PRIVATE, PARAM_BAD);
1972                    fail(keyStore.getType());
1973                } catch (UnrecoverableKeyException expected) {
1974                }
1975            }
1976            if (isReadOnly(keyStore)) {
1977                assertNull(keyStore.getEntry(ALIAS_SECRET, PARAM_BAD));
1978            } else if (isSecretKeyEnabled(keyStore)) {
1979                try {
1980                    keyStore.getEntry(ALIAS_SECRET, PARAM_BAD);
1981                    fail(keyStore.getType());
1982                } catch (UnrecoverableKeyException expected) {
1983                }
1984            }
1985        }
1986    }
1987
1988    public static class FakeProtectionParameter implements ProtectionParameter {
1989    }
1990
1991    public void test_KeyStore_setEntry() throws Exception {
1992        for (KeyStore keyStore : keyStores()) {
1993            keyStore.load(null, null);
1994            try {
1995                keyStore.setEntry(null, null, null);
1996                fail(keyStore.getType());
1997            } catch (NullPointerException expected) {
1998            }
1999        }
2000
2001        for (KeyStore keyStore : keyStores()) {
2002            keyStore.load(null, null);
2003
2004            try {
2005                keyStore.setEntry(ALIAS_PRIVATE, getPrivateKey(), new FakeProtectionParameter());
2006                fail("Should not accept unknown ProtectionParameter: " + keyStore.getProvider());
2007            } catch (KeyStoreException expected) {
2008            }
2009        }
2010
2011        for (KeyStore keyStore : keyStores()) {
2012            keyStore.load(null, null);
2013
2014            // test odd inputs
2015            try {
2016                keyStore.setEntry(null, null, null);
2017                fail(keyStore.getType());
2018            } catch (Exception e) {
2019                if (e.getClass() != NullPointerException.class
2020                    && e.getClass() != KeyStoreException.class) {
2021                    throw e;
2022                }
2023            }
2024            try {
2025                keyStore.setEntry(null, null, PARAM_KEY);
2026                fail(keyStore.getType());
2027            } catch (Exception e) {
2028                if (e.getClass() != NullPointerException.class
2029                    && e.getClass() != KeyStoreException.class) {
2030                    throw e;
2031                }
2032            }
2033            try {
2034                keyStore.setEntry("", null, PARAM_KEY);
2035                fail(keyStore.getType());
2036            } catch (NullPointerException expected) {
2037            }
2038        }
2039
2040        for (KeyStore keyStore : keyStores()) {
2041            clearKeyStore(keyStore);
2042
2043            // test case sensitive
2044            assertNull(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
2045            if (isReadOnly(keyStore)) {
2046                try {
2047                    keyStore.setEntry(ALIAS_PRIVATE, getPrivateKey(), PARAM_KEY);
2048                    fail(keyStore.getType());
2049                } catch (UnsupportedOperationException expected) {
2050                }
2051                continue;
2052            }
2053            if (isKeyPasswordSupported(keyStore)) {
2054                keyStore.setEntry(ALIAS_PRIVATE, getPrivateKey(), PARAM_KEY);
2055                assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
2056                assertCertificateChain(keyStore.getCertificateChain(ALIAS_PRIVATE));
2057            }
2058            if (isNullPasswordAllowed(keyStore)) {
2059                keyStore.setEntry(ALIAS_NO_PASSWORD_PRIVATE, getPrivateKey(), null);
2060                assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
2061                assertCertificateChain(keyStore.getCertificateChain(ALIAS_NO_PASSWORD_PRIVATE));
2062            }
2063            if (isSecretKeyEnabled(keyStore)) {
2064                assertNull(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
2065                keyStore.setEntry(ALIAS_SECRET, new SecretKeyEntry(getSecretKey()), PARAM_KEY);
2066                assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
2067            } else {
2068                try {
2069                    keyStore.setKeyEntry(ALIAS_SECRET, getSecretKey(), PASSWORD_KEY, null);
2070                    fail(keyStore.getType());
2071                } catch (KeyStoreException expected) {
2072                }
2073            }
2074            if (isCertificateEnabled(keyStore)) {
2075                assertNull(keyStore.getCertificate(ALIAS_CERTIFICATE));
2076                keyStore.setEntry(ALIAS_CERTIFICATE,
2077                                  new TrustedCertificateEntry(getPrivateKey().getCertificate()),
2078                                  null);
2079                assertCertificate(keyStore.getCertificate(ALIAS_CERTIFICATE));
2080            } else {
2081                try {
2082                    keyStore.setEntry(ALIAS_CERTIFICATE,
2083                                      new TrustedCertificateEntry(getPrivateKey().getCertificate()),
2084                                      null);
2085                    fail(keyStore.getType());
2086                } catch (KeyStoreException expected) {
2087                }
2088            }
2089            if (isKeyPasswordSupported(keyStore)) {
2090                keyStore.setEntry(ALIAS_UNICODE_PRIVATE, getPrivateKey(), PARAM_KEY);
2091                assertPrivateKey(keyStore.getKey(ALIAS_UNICODE_PRIVATE, PASSWORD_KEY));
2092                assertCertificateChain(keyStore.getCertificateChain(ALIAS_UNICODE_PRIVATE));
2093            }
2094            if (isNullPasswordAllowed(keyStore)) {
2095                keyStore.setEntry(ALIAS_UNICODE_NO_PASSWORD_PRIVATE, getPrivateKey(), null);
2096                assertPrivateKey(keyStore.getKey(ALIAS_UNICODE_NO_PASSWORD_PRIVATE, null));
2097                assertCertificateChain(keyStore
2098                        .getCertificateChain(ALIAS_UNICODE_NO_PASSWORD_PRIVATE));
2099            }
2100            if (isSecretKeyEnabled(keyStore)) {
2101                assertNull(keyStore.getKey(ALIAS_UNICODE_SECRET, PASSWORD_KEY));
2102                keyStore.setEntry(ALIAS_UNICODE_SECRET, new SecretKeyEntry(getSecretKey()), PARAM_KEY);
2103                assertSecretKey(keyStore.getKey(ALIAS_UNICODE_SECRET, PASSWORD_KEY));
2104            } else {
2105                try {
2106                    keyStore.setKeyEntry(ALIAS_UNICODE_SECRET, getSecretKey(), PASSWORD_KEY, null);
2107                    fail(keyStore.getType());
2108                } catch (KeyStoreException expected) {
2109                }
2110            }
2111        }
2112
2113        for (KeyStore keyStore : keyStores()) {
2114            populate(keyStore);
2115
2116            if (isReadOnly(keyStore)) {
2117                assertNull(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
2118                assertNull(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
2119                assertNull(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
2120                assertNull(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
2121            } else if (isCaseSensitive(keyStore)) {
2122                if (isKeyPasswordSupported(keyStore)) {
2123                    assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
2124                    assertNull(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
2125                    keyStore.setEntry(ALIAS_ALT_CASE_PRIVATE, getPrivateKey2(), PARAM_KEY);
2126                    assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
2127                    assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
2128                }
2129
2130                if (isNullPasswordAllowed(keyStore)) {
2131                    assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
2132                    assertNull(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, null));
2133                    keyStore.setEntry(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, getPrivateKey2(), null);
2134                    assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
2135                    assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, null));
2136                }
2137
2138                if (isSecretKeyEnabled(keyStore)) {
2139                    assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
2140                    assertNull(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
2141                    keyStore.setEntry(ALIAS_ALT_CASE_SECRET,
2142                                      new SecretKeyEntry(getSecretKey2()),
2143                                      PARAM_KEY);
2144                    assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
2145                    assertSecretKey2(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
2146                }
2147
2148                if (isCertificateEnabled(keyStore)) {
2149                    assertCertificate(keyStore.getCertificate(ALIAS_CERTIFICATE));
2150                    assertNull(keyStore.getCertificate(ALIAS_ALT_CASE_CERTIFICATE));
2151                    keyStore.setEntry(ALIAS_ALT_CASE_CERTIFICATE,
2152                                      new TrustedCertificateEntry(
2153                                              getPrivateKey2().getCertificate()),
2154                                      null);
2155                    assertCertificate(keyStore.getCertificate(ALIAS_CERTIFICATE));
2156                    assertCertificate2(keyStore.getCertificate(ALIAS_ALT_CASE_CERTIFICATE));
2157                    keyStore.setEntry(ALIAS_UNICODE_CERTIFICATE,
2158                                      new TrustedCertificateEntry(
2159                                              getPrivateKey().getCertificate()),
2160                                      null);
2161                    assertCertificate(keyStore.getCertificate(ALIAS_UNICODE_CERTIFICATE));
2162                }
2163            } else {
2164                assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
2165                assertPrivateKey(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
2166                keyStore.setEntry(ALIAS_ALT_CASE_PRIVATE, getPrivateKey2(), PARAM_KEY);
2167                assertPrivateKey2(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
2168                assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
2169
2170                if (isSecretKeyEnabled(keyStore)) {
2171                    assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
2172                    assertSecretKey(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
2173                    keyStore.setEntry(ALIAS_ALT_CASE_SECRET,
2174                                      new SecretKeyEntry(getSecretKey2()),
2175                                      PARAM_KEY);
2176                    assertSecretKey2(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
2177                    assertSecretKey2(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
2178                }
2179
2180                if (isCertificateEnabled(keyStore)) {
2181                    assertCertificate(keyStore.getCertificate(ALIAS_CERTIFICATE));
2182                    assertCertificate(keyStore.getCertificate(ALIAS_ALT_CASE_CERTIFICATE));
2183                    keyStore.setEntry(ALIAS_ALT_CASE_CERTIFICATE,
2184                                      new TrustedCertificateEntry(
2185                                              getPrivateKey2().getCertificate()),
2186                                      null);
2187                    assertCertificate2(keyStore.getCertificate(ALIAS_CERTIFICATE));
2188                    assertCertificate2(keyStore.getCertificate(ALIAS_ALT_CASE_CERTIFICATE));
2189                    keyStore.setEntry(ALIAS_UNICODE_CERTIFICATE,
2190                                      new TrustedCertificateEntry(
2191                                              getPrivateKey().getCertificate()),
2192                                      null);
2193                    assertCertificate(keyStore.getCertificate(ALIAS_UNICODE_CERTIFICATE));
2194                }
2195            }
2196        }
2197
2198        for (KeyStore keyStore : keyStores()) {
2199            keyStore.load(null, null);
2200
2201            // test with null/non-null passwords
2202            if (isReadOnly(keyStore)) {
2203                try {
2204                    keyStore.setEntry(ALIAS_PRIVATE, getPrivateKey(), null);
2205                    fail(keyStore.getType());
2206                } catch (UnsupportedOperationException expected) {
2207                }
2208                try {
2209                    keyStore.setEntry(ALIAS_SECRET, new SecretKeyEntry(getSecretKey()), null);
2210                    fail(keyStore.getType());
2211                } catch (UnsupportedOperationException expected) {
2212                }
2213                try {
2214                    keyStore.setEntry(ALIAS_CERTIFICATE,
2215                                      new TrustedCertificateEntry(getPrivateKey().getCertificate()),
2216                                      null);
2217                    fail(keyStore.getType());
2218                } catch (UnsupportedOperationException expected) {
2219                }
2220                continue;
2221            }
2222            if (isNullPasswordAllowed(keyStore) || isKeyPasswordIgnored(keyStore)) {
2223                for (String keyType : KEY_TYPES) {
2224                    keyStore.setEntry(ALIAS_PRIVATE, getPrivateKey(keyType), null);
2225                    assertPrivateKey(keyType, keyStore.getKey(ALIAS_PRIVATE, null));
2226                }
2227            } else {
2228                try {
2229                    keyStore.setEntry(ALIAS_PRIVATE, getPrivateKey(), null);
2230                    fail(keyStore.getType());
2231                } catch (Exception e) {
2232                    if (e.getClass() != UnrecoverableKeyException.class
2233                        && e.getClass() != IllegalArgumentException.class
2234                        && e.getClass() != KeyStoreException.class) {
2235                        throw e;
2236                    }
2237                }
2238            }
2239            if (isSecretKeyEnabled(keyStore)) {
2240                if (isNullPasswordAllowed(keyStore) || isKeyPasswordIgnored(keyStore)) {
2241                    keyStore.setEntry(ALIAS_SECRET, new SecretKeyEntry(getSecretKey()), null);
2242                    assertSecretKey(keyStore.getKey(ALIAS_SECRET, null));
2243                } else {
2244                    try {
2245                        keyStore.setEntry(ALIAS_SECRET, new SecretKeyEntry(getSecretKey()), null);
2246                        fail(keyStore.getType());
2247                    } catch (Exception e) {
2248                        if (e.getClass() != UnrecoverableKeyException.class
2249                            && e.getClass() != IllegalArgumentException.class
2250                            && e.getClass() != KeyStoreException.class) {
2251                            throw e;
2252                        }
2253                    }
2254                }
2255            }
2256            if (isCertificateEnabled(keyStore)) {
2257                if (isNullPasswordAllowed(keyStore) || isKeyPasswordIgnored(keyStore)) {
2258                    keyStore.setEntry(ALIAS_CERTIFICATE,
2259                                      new TrustedCertificateEntry(getPrivateKey().getCertificate()),
2260                                      PARAM_KEY);
2261                    assertCertificate(keyStore.getCertificate(ALIAS_CERTIFICATE));
2262                } else {
2263                    try {
2264                        keyStore.setEntry(ALIAS_CERTIFICATE,
2265                                          new TrustedCertificateEntry(
2266                                                  getPrivateKey().getCertificate()),
2267                                          PARAM_KEY);
2268                        fail(keyStore.getType());
2269                    } catch (KeyStoreException expected) {
2270                    }
2271                }
2272            }
2273        }
2274    }
2275
2276    public void test_KeyStore_entryInstanceOf() throws Exception {
2277        for (KeyStore keyStore : keyStores()) {
2278            try {
2279                keyStore.entryInstanceOf(null, null);
2280                fail(keyStore.getType());
2281            } catch (NullPointerException expected) {
2282            }
2283        }
2284
2285        for (KeyStore keyStore : keyStores()) {
2286            keyStore.load(null, null);
2287
2288            try {
2289                keyStore.entryInstanceOf(null, null);
2290                fail(keyStore.getType());
2291            } catch (NullPointerException expected) {
2292            }
2293            try {
2294                keyStore.entryInstanceOf(null, Entry.class);
2295                fail(keyStore.getType());
2296            } catch (NullPointerException expected) {
2297            }
2298            try {
2299                keyStore.entryInstanceOf("", null);
2300                fail(keyStore.getType());
2301            } catch (NullPointerException expected) {
2302            }
2303
2304            assertFalse(keyStore.entryInstanceOf("", Entry.class));
2305        }
2306
2307        for (KeyStore keyStore : keyStores()) {
2308            populate(keyStore);
2309
2310            // test odd inputs
2311            assertFalse(keyStore.entryInstanceOf("", Entry.class));
2312            assertFalse(keyStore.entryInstanceOf("", PrivateKeyEntry.class));
2313            assertFalse(keyStore.entryInstanceOf("", SecretKeyEntry.class));
2314            assertFalse(keyStore.entryInstanceOf("", TrustedCertificateEntry.class));
2315
2316            if (isReadOnly(keyStore)) {
2317                assertFalse(keyStore.entryInstanceOf(ALIAS_PRIVATE, PrivateKeyEntry.class));
2318                assertFalse(keyStore.entryInstanceOf(ALIAS_PRIVATE, SecretKeyEntry.class));
2319                assertFalse(keyStore.entryInstanceOf(ALIAS_PRIVATE, TrustedCertificateEntry.class));
2320
2321                assertFalse(keyStore.entryInstanceOf(ALIAS_SECRET, SecretKeyEntry.class));
2322                assertFalse(keyStore.entryInstanceOf(ALIAS_SECRET, PrivateKeyEntry.class));
2323                assertFalse(keyStore.entryInstanceOf(ALIAS_SECRET, TrustedCertificateEntry.class));
2324
2325                assertFalse(keyStore.entryInstanceOf(ALIAS_CERTIFICATE,
2326                                                     TrustedCertificateEntry.class));
2327                assertFalse(keyStore.entryInstanceOf(ALIAS_CERTIFICATE, PrivateKeyEntry.class));
2328                assertFalse(keyStore.entryInstanceOf(ALIAS_CERTIFICATE, SecretKeyEntry.class));
2329                continue;
2330            }
2331
2332            // test case sensitive
2333            assertEquals(isKeyPasswordSupported(keyStore),
2334                    keyStore.entryInstanceOf(ALIAS_PRIVATE, PrivateKeyEntry.class));
2335            assertFalse(keyStore.entryInstanceOf(ALIAS_PRIVATE, SecretKeyEntry.class));
2336            assertFalse(keyStore.entryInstanceOf(ALIAS_PRIVATE, TrustedCertificateEntry.class));
2337
2338            assertEquals(isNullPasswordAllowed(keyStore),
2339                    keyStore.entryInstanceOf(ALIAS_NO_PASSWORD_PRIVATE, PrivateKeyEntry.class));
2340            assertFalse(keyStore.entryInstanceOf(ALIAS_NO_PASSWORD_PRIVATE, SecretKeyEntry.class));
2341            assertFalse(keyStore.entryInstanceOf(ALIAS_NO_PASSWORD_PRIVATE,
2342                    TrustedCertificateEntry.class));
2343
2344            assertEquals(isSecretKeyEnabled(keyStore),
2345                         keyStore.entryInstanceOf(ALIAS_SECRET, SecretKeyEntry.class));
2346            assertFalse(keyStore.entryInstanceOf(ALIAS_SECRET, PrivateKeyEntry.class));
2347            assertFalse(keyStore.entryInstanceOf(ALIAS_SECRET, TrustedCertificateEntry.class));
2348
2349            assertEquals(isCertificateEnabled(keyStore),
2350                         keyStore.entryInstanceOf(ALIAS_CERTIFICATE,
2351                                                  TrustedCertificateEntry.class));
2352            assertFalse(keyStore.entryInstanceOf(ALIAS_CERTIFICATE, PrivateKeyEntry.class));
2353            assertFalse(keyStore.entryInstanceOf(ALIAS_CERTIFICATE, SecretKeyEntry.class));
2354
2355            // test case insensitive
2356            assertEquals(!isCaseSensitive(keyStore),
2357                         keyStore.entryInstanceOf(ALIAS_ALT_CASE_PRIVATE, PrivateKeyEntry.class));
2358            assertFalse(keyStore.entryInstanceOf(ALIAS_ALT_CASE_PRIVATE, SecretKeyEntry.class));
2359            assertFalse(keyStore.entryInstanceOf(ALIAS_ALT_CASE_PRIVATE,
2360                                                 TrustedCertificateEntry.class));
2361
2362            assertEquals(!isCaseSensitive(keyStore) && isSecretKeyEnabled(keyStore),
2363                         keyStore.entryInstanceOf(ALIAS_ALT_CASE_SECRET, SecretKeyEntry.class));
2364            assertFalse(keyStore.entryInstanceOf(ALIAS_ALT_CASE_SECRET, PrivateKeyEntry.class));
2365            assertFalse(keyStore.entryInstanceOf(ALIAS_ALT_CASE_SECRET,
2366                                                 TrustedCertificateEntry.class));
2367
2368            assertEquals(!isCaseSensitive(keyStore) && isCertificateEnabled(keyStore),
2369                         keyStore.entryInstanceOf(ALIAS_ALT_CASE_CERTIFICATE,
2370                                                  TrustedCertificateEntry.class));
2371            assertFalse(keyStore.entryInstanceOf(ALIAS_ALT_CASE_CERTIFICATE,
2372                                                 PrivateKeyEntry.class));
2373            assertFalse(keyStore.entryInstanceOf(ALIAS_ALT_CASE_CERTIFICATE, SecretKeyEntry.class));
2374        }
2375    }
2376
2377    public void test_KeyStore_Builder() throws Exception {
2378        for (KeyStore keyStore : keyStores()) {
2379            keyStore.load(null, null);
2380            try {
2381                Builder.newInstance(keyStore, null);
2382                fail(keyStore.getType());
2383            } catch (NullPointerException expected) {
2384            }
2385        }
2386
2387        for (KeyStore keyStore : keyStores()) {
2388            try {
2389                Builder.newInstance(keyStore.getType(),
2390                                    keyStore.getProvider(),
2391                                    null);
2392                fail(keyStore.getType());
2393            } catch (NullPointerException expected) {
2394            }
2395        }
2396
2397        for (KeyStore keyStore : keyStores()) {
2398            try {
2399                Builder.newInstance(null,
2400                                    null,
2401                                    null,
2402                                    null);
2403                fail(keyStore.getType());
2404            } catch (NullPointerException expected) {
2405            }
2406            try {
2407                Builder.newInstance(keyStore.getType(),
2408                                    keyStore.getProvider(),
2409                                    null,
2410                                    null);
2411                fail(keyStore.getType());
2412            } catch (NullPointerException expected) {
2413            }
2414        }
2415
2416        for (KeyStore keyStore : keyStores()) {
2417            keyStore.load(null, null);
2418            Builder builder = Builder.newInstance(keyStore, PARAM_STORE);
2419            try {
2420                builder.getProtectionParameter(null);
2421                fail(keyStore.getType());
2422            } catch (NullPointerException expected) {
2423            }
2424            assertEquals(keyStore, builder.getKeyStore());
2425            try {
2426                builder.getProtectionParameter(null);
2427                fail(keyStore.getType());
2428            } catch (NullPointerException expected) {
2429            }
2430            assertEquals(PARAM_STORE, builder.getProtectionParameter(""));
2431        }
2432
2433        for (KeyStore keyStore : keyStores()) {
2434            populate(keyStore);
2435
2436            File file = File.createTempFile("keystore", keyStore.getProvider().getName());
2437            OutputStream os = null;
2438            try {
2439                os = new FileOutputStream(file);
2440                if (isLoadStoreUnsupported(keyStore) || isReadOnly(keyStore)) {
2441                    try {
2442                        keyStore.store(os, PASSWORD_STORE);
2443                        fail(keyStore.getType());
2444                    } catch (UnsupportedOperationException expected) {
2445                    }
2446                    continue;
2447                }
2448
2449                keyStore.store(os, PASSWORD_STORE);
2450                os.close();
2451                Builder builder = Builder.newInstance(keyStore.getType(),
2452                                                      keyStore.getProvider(),
2453                                                      file,
2454                                                      PARAM_STORE);
2455                assertEquals(keyStore.getType(), builder.getKeyStore().getType());
2456                assertEquals(keyStore.getProvider(), builder.getKeyStore().getProvider());
2457                assertEquals(PARAM_STORE, builder.getProtectionParameter(""));
2458                assertEqualsKeyStores(file, PASSWORD_STORE, keyStore);
2459            } finally {
2460                try {
2461                    if (os != null) {
2462                        os.close();
2463                    }
2464                } catch (IOException ignored) {
2465                }
2466                file.delete();
2467            }
2468        }
2469
2470        for (KeyStore keyStore : keyStores()) {
2471            if (isLoadStoreUnsupported(keyStore)) {
2472                continue;
2473            }
2474            Builder builder = Builder.newInstance(keyStore.getType(),
2475                                                  keyStore.getProvider(),
2476                                                  PARAM_STORE);
2477            assertEquals(keyStore.getType(), builder.getKeyStore().getType());
2478            assertEquals(keyStore.getProvider(), builder.getKeyStore().getProvider());
2479            assertEquals(PARAM_STORE, builder.getProtectionParameter(""));
2480        }
2481    }
2482
2483    public void test_KeyStore_cacerts() throws Exception {
2484        if (StandardNames.IS_RI) {
2485            return;
2486        }
2487        KeyStore ks = KeyStore.getInstance("AndroidCAStore");
2488        assertEquals("AndroidCAStore", ks.getType());
2489        assertEquals("HarmonyJSSE", ks.getProvider().getName());
2490
2491        ks.load(null, null);
2492        for (String alias : Collections.list(ks.aliases())) {
2493            Certificate c = null;
2494            try {
2495                c = ks.getCertificate(alias);
2496                assertNotNull(c);
2497                assertTrue(ks.isCertificateEntry(alias));
2498                assertTrue(ks.entryInstanceOf(alias, TrustedCertificateEntry.class));
2499                assertEquals(alias, ks.getCertificateAlias(c));
2500
2501                assertTrue(c instanceof X509Certificate);
2502                X509Certificate cert = (X509Certificate) c;
2503                assertEquals(cert.getSubjectUniqueID(), cert.getIssuerUniqueID());
2504                assertNotNull(cert.getPublicKey());
2505
2506                assertTrue(ks.containsAlias(alias));
2507                assertNotNull(ks.getCreationDate(alias));
2508                assertNotNull(ks.getEntry(alias, null));
2509
2510                assertFalse(ks.isKeyEntry(alias));
2511                assertNull(ks.getKey(alias, null));
2512                assertNull(ks.getCertificateChain(alias));
2513
2514            } catch (Throwable t) {
2515                throw new Exception("alias=" + alias + " cert=" + c, t);
2516            }
2517        }
2518    }
2519
2520    // http://b/857840: want JKS key store
2521    public void testDefaultKeystore() {
2522        String type = KeyStore.getDefaultType();
2523        assertEquals(StandardNames.KEY_STORE_ALGORITHM, type);
2524
2525        try {
2526            KeyStore store = KeyStore.getInstance(KeyStore.getDefaultType());
2527            assertNotNull("Keystore must not be null", store);
2528        } catch (Exception ex) {
2529            throw new RuntimeException(ex);
2530        }
2531
2532        try {
2533            KeyStore store = KeyStore.getInstance(StandardNames.KEY_STORE_ALGORITHM);
2534            assertNotNull("Keystore must not be null", store);
2535        } catch (Exception ex) {
2536            throw new RuntimeException(ex);
2537        }
2538    }
2539}
2540