1/*
2 * Copyright (C) 2009 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 */
16package tests.targets.security;
17
18import java.io.ByteArrayInputStream;
19import java.io.ByteArrayOutputStream;
20import java.io.IOException;
21import java.io.InputStream;
22import java.security.KeyPair;
23import java.security.KeyPairGenerator;
24import java.security.KeyStore;
25import java.security.KeyStore.Entry;
26import java.security.KeyStore.PasswordProtection;
27import java.security.KeyStore.PrivateKeyEntry;
28import java.security.KeyStore.ProtectionParameter;
29import java.security.KeyStoreException;
30import java.security.NoSuchAlgorithmException;
31import java.security.PrivateKey;
32import java.security.UnrecoverableEntryException;
33import java.security.cert.Certificate;
34import java.security.cert.CertificateException;
35import java.security.cert.CertificateFactory;
36import junit.framework.TestCase;
37
38public abstract class KeyStoreTest extends TestCase {
39
40    private final String algorithmName;
41    private final byte[] keyStoreData;
42    private final String keyStorePassword;
43
44    public KeyStoreTest(String algorithmName, byte[] keyStoreData,
45            String keyStorePassword) {
46        this.algorithmName = algorithmName;
47        this.keyStoreData = keyStoreData;
48        this.keyStorePassword = keyStorePassword;
49    }
50
51    public void testKeyStoreLoad() {
52        KeyStore keyStore = null;
53        try {
54            keyStore = KeyStore.getInstance(algorithmName);
55        } catch (KeyStoreException e) {
56            fail(e.getMessage());
57        }
58
59        try {
60            keyStore.load(new ByteArrayInputStream(keyStoreData),
61                    keyStorePassword.toCharArray());
62        } catch (NoSuchAlgorithmException e) {
63            fail(e.getMessage());
64        } catch (CertificateException e) {
65            fail(e.getMessage());
66        } catch (IOException e) {
67            fail(e.getMessage());
68        }
69
70        try {
71            assertTrue("keystore is empty", keyStore.aliases()
72                    .hasMoreElements());
73        } catch (KeyStoreException e) {
74            fail(e.getMessage());
75        }
76    }
77
78    public void testKeyStoreCreate() {
79        KeyStore keyStore = null;
80        try {
81            keyStore = KeyStore.getInstance(algorithmName);
82        } catch (KeyStoreException e) {
83            fail(e.getMessage());
84        }
85
86        try {
87            keyStore.load(null, "the secret password".toCharArray());
88        } catch (NoSuchAlgorithmException e) {
89            fail(e.getMessage());
90        } catch (CertificateException e) {
91            fail(e.getMessage());
92        } catch (IOException e) {
93            fail(e.getMessage());
94        }
95
96        CertificateFactory certificateFactory = null;
97        try {
98            certificateFactory = CertificateFactory.getInstance("X.509");
99        } catch (CertificateException e) {
100            fail(e.getMessage());
101        }
102
103        Certificate certificate = null;
104        try {
105            certificate = certificateFactory
106                    .generateCertificate(new ByteArrayInputStream(
107                            encodedCertificate.getBytes()));
108        } catch (CertificateException e) {
109            fail(e.getMessage());
110        }
111
112        KeyPairGenerator generator = null;
113        try {
114            generator = KeyPairGenerator.getInstance(certificate.getPublicKey()
115                    .getAlgorithm());
116        } catch (NoSuchAlgorithmException e) {
117            fail(e.getMessage());
118        }
119
120        KeyPair keyPair = generator.generateKeyPair();
121
122        PrivateKeyEntry privateKeyEntry = new PrivateKeyEntry(keyPair
123                .getPrivate(), new Certificate[] {certificate});
124
125        try {
126            keyStore.setEntry("aPrivateKey", privateKeyEntry,
127                    new PasswordProtection("the key password".toCharArray()));
128        } catch (KeyStoreException e) {
129            fail(e.getMessage());
130        }
131
132        try {
133            assertTrue(keyStore.containsAlias("aPrivateKey"));
134        } catch (KeyStoreException e) {
135            fail(e.getMessage());
136        }
137
138        try {
139            PrivateKeyEntry entry = (PrivateKeyEntry) keyStore.getEntry(
140                    "aPrivateKey", new PasswordProtection("the key password"
141                            .toCharArray()));
142            PrivateKey privateKey = entry.getPrivateKey();
143            assertEquals(keyPair.getPrivate(), privateKey);
144        } catch (NoSuchAlgorithmException e) {
145            fail(e.getMessage());
146        } catch (UnrecoverableEntryException e) {
147            fail(e.getMessage());
148        } catch (KeyStoreException e) {
149            fail(e.getMessage());
150        }
151
152        try {
153            ByteArrayOutputStream stream = new ByteArrayOutputStream();
154            keyStore.store(stream, "the keystore password".toCharArray());
155            assertTrue("keystore not written", stream.size() > 0);
156        } catch (KeyStoreException e) {
157            fail(e.getMessage());
158        } catch (NoSuchAlgorithmException e) {
159            fail(e.getMessage());
160        } catch (CertificateException e) {
161            fail(e.getMessage());
162        } catch (IOException e) {
163            fail(e.getMessage());
164        }
165    }
166
167    private String encodedCertificate = "-----BEGIN CERTIFICATE-----\n"
168            + "MIID0jCCAzugAwIBAgIBAjANBgkqhkiG9w0BAQQFADCBmjELMAkGA1UEBhMCVUsx\n"
169            + "EjAQBgNVBAgTCUhhbXBzaGlyZTETMBEGA1UEBxMKV2luY2hlc3RlcjETMBEGA1UE\n"
170            + "ChMKSUJNIFVLIEx0ZDEMMAoGA1UECxMDSlRDMRYwFAYDVQQDEw1QYXVsIEggQWJi\n"
171            + "b3R0MScwJQYJKoZIhvcNAQkBFhhQYXVsX0hfQWJib3R0QHVrLmlibS5jb20wHhcN\n"
172            + "MDQwNjIyMjA1MDU1WhcNMDUwNjIyMjA1MDU1WjCBmDELMAkGA1UEBhMCVUsxEjAQ\n"
173            + "BgNVBAgTCUhhbXBzaGlyZTETMBEGA1UEBxMKV2luY2hlc3RlcjETMBEGA1UEChMK\n"
174            + "SUJNIFVrIEx0ZDEMMAoGA1UECxMDSkVUMRQwEgYDVQQDEwtQYXVsIEFiYm90dDEn\n"
175            + "MCUGCSqGSIb3DQEJARYYUGF1bF9IX0FiYm90dEB1ay5pYm0uY29tMIGfMA0GCSqG\n"
176            + "SIb3DQEBAQUAA4GNADCBiQKBgQDitZBQ5d18ecNJpcnuKTraHYtqsAugoc95/L5Q\n"
177            + "28s3t1QAu2505qQR1MZaAkY7tDNyl1vPnZoym+Y06UswTrZoVYo/gPNeyWPMTsLA\n"
178            + "wzQvk5/6yhtE9ciH7B0SqYw6uSiDTbUY/zQ6qed+TsQhjlbn3PUHRjnI2P8A04cg\n"
179            + "LgYYGQIDAQABo4IBJjCCASIwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3Bl\n"
180            + "blNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFPplRPs65hUfxUBs\n"
181            + "6/Taq7nN8i1UMIHHBgNVHSMEgb8wgbyAFJOMtPAwlXdZLqE7DKU6xpL6FjFtoYGg\n"
182            + "pIGdMIGaMQswCQYDVQQGEwJVSzESMBAGA1UECBMJSGFtcHNoaXJlMRMwEQYDVQQH\n"
183            + "EwpXaW5jaGVzdGVyMRMwEQYDVQQKEwpJQk0gVUsgTHRkMQwwCgYDVQQLEwNKVEMx\n"
184            + "FjAUBgNVBAMTDVBhdWwgSCBBYmJvdHQxJzAlBgkqhkiG9w0BCQEWGFBhdWxfSF9B\n"
185            + "YmJvdHRAdWsuaWJtLmNvbYIBADANBgkqhkiG9w0BAQQFAAOBgQAnQ22Jw2HUrz7c\n"
186            + "VaOap31mTikuQ/CQxpwPYiSyTJ4s99eEzn+2yAk9tIDIJpqoay/fj+OLgPUQKIAo\n"
187            + "XpRVvmHlGE7UqMKebZtSZJQzs6VoeeKFhgHmqg8eVC2AsTc4ZswJmg4wCui5AH3a\n"
188            + "oqG7PIM3LxZqXYQlZiPSZ6kCpDOWVg==\n"
189            + "-----END CERTIFICATE-----\n";
190}
191