AndroidKeyStoreTest.java revision 802768dd86c4e8a933dbfbac2e9f1a1daa5f93fa
1/*
2 * Copyright (C) 2012 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 android.security;
18
19import com.android.org.bouncycastle.x509.X509V3CertificateGenerator;
20
21import org.apache.harmony.xnet.provider.jsse.OpenSSLEngine;
22
23import android.test.AndroidTestCase;
24
25import java.io.ByteArrayInputStream;
26import java.io.ByteArrayOutputStream;
27import java.io.OutputStream;
28import java.math.BigInteger;
29import java.security.InvalidKeyException;
30import java.security.Key;
31import java.security.KeyFactory;
32import java.security.KeyStore.Entry;
33import java.security.KeyStore.PrivateKeyEntry;
34import java.security.KeyStore.TrustedCertificateEntry;
35import java.security.KeyStoreException;
36import java.security.NoSuchAlgorithmException;
37import java.security.PrivateKey;
38import java.security.PublicKey;
39import java.security.cert.Certificate;
40import java.security.cert.CertificateFactory;
41import java.security.cert.X509Certificate;
42import java.security.interfaces.RSAPrivateKey;
43import java.security.spec.InvalidKeySpecException;
44import java.security.spec.PKCS8EncodedKeySpec;
45import java.security.spec.X509EncodedKeySpec;
46import java.util.Arrays;
47import java.util.Collection;
48import java.util.Date;
49import java.util.Enumeration;
50import java.util.HashSet;
51import java.util.Iterator;
52import java.util.Set;
53
54import javax.security.auth.x500.X500Principal;
55
56public class AndroidKeyStoreTest extends AndroidTestCase {
57    private android.security.KeyStore mAndroidKeyStore;
58
59    private java.security.KeyStore mKeyStore;
60
61    private static final String TEST_ALIAS_1 = "test1";
62
63    private static final String TEST_ALIAS_2 = "test2";
64
65    private static final String TEST_ALIAS_3 = "test3";
66
67    private static final X500Principal TEST_DN_1 = new X500Principal("CN=test1");
68
69    private static final X500Principal TEST_DN_2 = new X500Principal("CN=test2");
70
71    private static final BigInteger TEST_SERIAL_1 = BigInteger.ONE;
72
73    private static final BigInteger TEST_SERIAL_2 = BigInteger.valueOf(2L);
74
75    private static final long NOW_MILLIS = System.currentTimeMillis();
76
77    /* We have to round this off because X509v3 doesn't store milliseconds. */
78    private static final Date NOW = new Date(NOW_MILLIS - (NOW_MILLIS % 1000L));
79
80    @SuppressWarnings("deprecation")
81    private static final Date NOW_PLUS_10_YEARS = new Date(NOW.getYear() + 10, 0, 1);
82
83    /*
84     * The keys and certificates below are generated with:
85     *
86     * openssl req -new -x509 -days 3650 -extensions v3_ca -keyout cakey.pem -out cacert.pem
87     * openssl req -newkey rsa:1024 -keyout userkey.pem -nodes -days 3650 -out userkey.req
88     * mkdir -p demoCA/newcerts
89     * touch demoCA/index.txt
90     * echo "01" > demoCA/serial
91     * openssl ca -out usercert.pem -in userkey.req -cert cacert.pem -keyfile cakey.pem -days 3650
92     */
93
94    /**
95     * Generated from above and converted with:
96     *
97     * openssl x509 -outform d -in cacert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
98     */
99    private static final byte[] FAKE_CA_1 = {
100            (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0xce, (byte) 0x30, (byte) 0x82,
101            (byte) 0x02, (byte) 0x37, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
102            (byte) 0x02, (byte) 0x02, (byte) 0x09, (byte) 0x00, (byte) 0xe1, (byte) 0x6a,
103            (byte) 0xa2, (byte) 0xf4, (byte) 0x2e, (byte) 0x55, (byte) 0x48, (byte) 0x0a,
104            (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
105            (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
106            (byte) 0x05, (byte) 0x05, (byte) 0x00, (byte) 0x30, (byte) 0x4f, (byte) 0x31,
107            (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55,
108            (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53,
109            (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03,
110            (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x13, (byte) 0x02, (byte) 0x43,
111            (byte) 0x41, (byte) 0x31, (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06,
112            (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x07, (byte) 0x13, (byte) 0x0d,
113            (byte) 0x4d, (byte) 0x6f, (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x61,
114            (byte) 0x69, (byte) 0x6e, (byte) 0x20, (byte) 0x56, (byte) 0x69, (byte) 0x65,
115            (byte) 0x77, (byte) 0x31, (byte) 0x1b, (byte) 0x30, (byte) 0x19, (byte) 0x06,
116            (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x13, (byte) 0x12,
117            (byte) 0x41, (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69,
118            (byte) 0x64, (byte) 0x20, (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74,
119            (byte) 0x20, (byte) 0x43, (byte) 0x61, (byte) 0x73, (byte) 0x65, (byte) 0x73,
120            (byte) 0x30, (byte) 0x1e, (byte) 0x17, (byte) 0x0d, (byte) 0x31, (byte) 0x32,
121            (byte) 0x30, (byte) 0x38, (byte) 0x31, (byte) 0x34, (byte) 0x31, (byte) 0x36,
122            (byte) 0x35, (byte) 0x35, (byte) 0x34, (byte) 0x34, (byte) 0x5a, (byte) 0x17,
123            (byte) 0x0d, (byte) 0x32, (byte) 0x32, (byte) 0x30, (byte) 0x38, (byte) 0x31,
124            (byte) 0x32, (byte) 0x31, (byte) 0x36, (byte) 0x35, (byte) 0x35, (byte) 0x34,
125            (byte) 0x34, (byte) 0x5a, (byte) 0x30, (byte) 0x4f, (byte) 0x31, (byte) 0x0b,
126            (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
127            (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31,
128            (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55,
129            (byte) 0x04, (byte) 0x08, (byte) 0x13, (byte) 0x02, (byte) 0x43, (byte) 0x41,
130            (byte) 0x31, (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06, (byte) 0x03,
131            (byte) 0x55, (byte) 0x04, (byte) 0x07, (byte) 0x13, (byte) 0x0d, (byte) 0x4d,
132            (byte) 0x6f, (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x61, (byte) 0x69,
133            (byte) 0x6e, (byte) 0x20, (byte) 0x56, (byte) 0x69, (byte) 0x65, (byte) 0x77,
134            (byte) 0x31, (byte) 0x1b, (byte) 0x30, (byte) 0x19, (byte) 0x06, (byte) 0x03,
135            (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x13, (byte) 0x12, (byte) 0x41,
136            (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64,
137            (byte) 0x20, (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x20,
138            (byte) 0x43, (byte) 0x61, (byte) 0x73, (byte) 0x65, (byte) 0x73, (byte) 0x30,
139            (byte) 0x81, (byte) 0x9f, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09,
140            (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d,
141            (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x03,
142            (byte) 0x81, (byte) 0x8d, (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0x89,
143            (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xa3, (byte) 0x72,
144            (byte) 0xab, (byte) 0xd0, (byte) 0xe4, (byte) 0xad, (byte) 0x2f, (byte) 0xe7,
145            (byte) 0xe2, (byte) 0x79, (byte) 0x07, (byte) 0x36, (byte) 0x3d, (byte) 0x0c,
146            (byte) 0x8d, (byte) 0x42, (byte) 0x9a, (byte) 0x0a, (byte) 0x33, (byte) 0x64,
147            (byte) 0xb3, (byte) 0xcd, (byte) 0xb2, (byte) 0xd7, (byte) 0x3a, (byte) 0x42,
148            (byte) 0x06, (byte) 0x77, (byte) 0x45, (byte) 0x29, (byte) 0xe9, (byte) 0xcb,
149            (byte) 0xb7, (byte) 0x4a, (byte) 0xd6, (byte) 0xee, (byte) 0xad, (byte) 0x01,
150            (byte) 0x91, (byte) 0x9b, (byte) 0x0c, (byte) 0x59, (byte) 0xa1, (byte) 0x03,
151            (byte) 0xfa, (byte) 0xf0, (byte) 0x5a, (byte) 0x7c, (byte) 0x4f, (byte) 0xf7,
152            (byte) 0x8d, (byte) 0x36, (byte) 0x0f, (byte) 0x1f, (byte) 0x45, (byte) 0x7d,
153            (byte) 0x1b, (byte) 0x31, (byte) 0xa1, (byte) 0x35, (byte) 0x0b, (byte) 0x00,
154            (byte) 0xed, (byte) 0x7a, (byte) 0xb6, (byte) 0xc8, (byte) 0x4e, (byte) 0xa9,
155            (byte) 0x86, (byte) 0x4c, (byte) 0x7b, (byte) 0x99, (byte) 0x57, (byte) 0x41,
156            (byte) 0x12, (byte) 0xef, (byte) 0x6b, (byte) 0xbc, (byte) 0x3d, (byte) 0x60,
157            (byte) 0xf2, (byte) 0x99, (byte) 0x1a, (byte) 0xcd, (byte) 0xed, (byte) 0x56,
158            (byte) 0xa4, (byte) 0xe5, (byte) 0x36, (byte) 0x9f, (byte) 0x24, (byte) 0x1f,
159            (byte) 0xdc, (byte) 0x89, (byte) 0x40, (byte) 0xc8, (byte) 0x99, (byte) 0x92,
160            (byte) 0xab, (byte) 0x4a, (byte) 0xb5, (byte) 0x61, (byte) 0x45, (byte) 0x62,
161            (byte) 0xff, (byte) 0xa3, (byte) 0x45, (byte) 0x65, (byte) 0xaf, (byte) 0xf6,
162            (byte) 0x27, (byte) 0x30, (byte) 0x51, (byte) 0x0e, (byte) 0x0e, (byte) 0xeb,
163            (byte) 0x79, (byte) 0x0c, (byte) 0xbe, (byte) 0xb3, (byte) 0x0a, (byte) 0x6f,
164            (byte) 0x29, (byte) 0x06, (byte) 0xdc, (byte) 0x2f, (byte) 0x6b, (byte) 0x51,
165            (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0xa3,
166            (byte) 0x81, (byte) 0xb1, (byte) 0x30, (byte) 0x81, (byte) 0xae, (byte) 0x30,
167            (byte) 0x1d, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x0e,
168            (byte) 0x04, (byte) 0x16, (byte) 0x04, (byte) 0x14, (byte) 0x33, (byte) 0x05,
169            (byte) 0xee, (byte) 0xfe, (byte) 0x6f, (byte) 0x60, (byte) 0xc7, (byte) 0xf9,
170            (byte) 0xa9, (byte) 0xd2, (byte) 0x73, (byte) 0x5c, (byte) 0x8f, (byte) 0x6d,
171            (byte) 0xa2, (byte) 0x2f, (byte) 0x97, (byte) 0x8e, (byte) 0x5d, (byte) 0x51,
172            (byte) 0x30, (byte) 0x7f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d,
173            (byte) 0x23, (byte) 0x04, (byte) 0x78, (byte) 0x30, (byte) 0x76, (byte) 0x80,
174            (byte) 0x14, (byte) 0x33, (byte) 0x05, (byte) 0xee, (byte) 0xfe, (byte) 0x6f,
175            (byte) 0x60, (byte) 0xc7, (byte) 0xf9, (byte) 0xa9, (byte) 0xd2, (byte) 0x73,
176            (byte) 0x5c, (byte) 0x8f, (byte) 0x6d, (byte) 0xa2, (byte) 0x2f, (byte) 0x97,
177            (byte) 0x8e, (byte) 0x5d, (byte) 0x51, (byte) 0xa1, (byte) 0x53, (byte) 0xa4,
178            (byte) 0x51, (byte) 0x30, (byte) 0x4f, (byte) 0x31, (byte) 0x0b, (byte) 0x30,
179            (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06,
180            (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x0b,
181            (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
182            (byte) 0x08, (byte) 0x13, (byte) 0x02, (byte) 0x43, (byte) 0x41, (byte) 0x31,
183            (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06, (byte) 0x03, (byte) 0x55,
184            (byte) 0x04, (byte) 0x07, (byte) 0x13, (byte) 0x0d, (byte) 0x4d, (byte) 0x6f,
185            (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x61, (byte) 0x69, (byte) 0x6e,
186            (byte) 0x20, (byte) 0x56, (byte) 0x69, (byte) 0x65, (byte) 0x77, (byte) 0x31,
187            (byte) 0x1b, (byte) 0x30, (byte) 0x19, (byte) 0x06, (byte) 0x03, (byte) 0x55,
188            (byte) 0x04, (byte) 0x0a, (byte) 0x13, (byte) 0x12, (byte) 0x41, (byte) 0x6e,
189            (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x20,
190            (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x20, (byte) 0x43,
191            (byte) 0x61, (byte) 0x73, (byte) 0x65, (byte) 0x73, (byte) 0x82, (byte) 0x09,
192            (byte) 0x00, (byte) 0xe1, (byte) 0x6a, (byte) 0xa2, (byte) 0xf4, (byte) 0x2e,
193            (byte) 0x55, (byte) 0x48, (byte) 0x0a, (byte) 0x30, (byte) 0x0c, (byte) 0x06,
194            (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x13, (byte) 0x04, (byte) 0x05,
195            (byte) 0x30, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0xff, (byte) 0x30,
196            (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48,
197            (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x05,
198            (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x81, (byte) 0x81, (byte) 0x00,
199            (byte) 0x8c, (byte) 0x30, (byte) 0x42, (byte) 0xfa, (byte) 0xeb, (byte) 0x1a,
200            (byte) 0x26, (byte) 0xeb, (byte) 0xda, (byte) 0x56, (byte) 0x32, (byte) 0xf2,
201            (byte) 0x9d, (byte) 0xa5, (byte) 0x24, (byte) 0xd8, (byte) 0x3a, (byte) 0xda,
202            (byte) 0x30, (byte) 0xa6, (byte) 0x8b, (byte) 0x46, (byte) 0xfe, (byte) 0xfe,
203            (byte) 0xdb, (byte) 0xf1, (byte) 0xe6, (byte) 0xe1, (byte) 0x7c, (byte) 0x1b,
204            (byte) 0xe7, (byte) 0x77, (byte) 0x00, (byte) 0xa1, (byte) 0x1c, (byte) 0x19,
205            (byte) 0x17, (byte) 0x73, (byte) 0xb0, (byte) 0xf0, (byte) 0x9d, (byte) 0xf3,
206            (byte) 0x4f, (byte) 0xb6, (byte) 0xbc, (byte) 0xc7, (byte) 0x47, (byte) 0x85,
207            (byte) 0x2a, (byte) 0x4a, (byte) 0xa1, (byte) 0xa5, (byte) 0x58, (byte) 0xf5,
208            (byte) 0xc5, (byte) 0x1a, (byte) 0x51, (byte) 0xb1, (byte) 0x04, (byte) 0x80,
209            (byte) 0xee, (byte) 0x3a, (byte) 0xec, (byte) 0x2f, (byte) 0xe1, (byte) 0xfd,
210            (byte) 0x58, (byte) 0xeb, (byte) 0xed, (byte) 0x82, (byte) 0x9e, (byte) 0x38,
211            (byte) 0xa3, (byte) 0x24, (byte) 0x75, (byte) 0xf7, (byte) 0x3e, (byte) 0xc2,
212            (byte) 0xc5, (byte) 0x27, (byte) 0xeb, (byte) 0x6f, (byte) 0x7b, (byte) 0x50,
213            (byte) 0xda, (byte) 0x43, (byte) 0xdc, (byte) 0x3b, (byte) 0x0b, (byte) 0x6f,
214            (byte) 0x78, (byte) 0x8f, (byte) 0xb0, (byte) 0x66, (byte) 0xe1, (byte) 0x12,
215            (byte) 0x87, (byte) 0x5f, (byte) 0x97, (byte) 0x7b, (byte) 0xca, (byte) 0x14,
216            (byte) 0x79, (byte) 0xf7, (byte) 0xe8, (byte) 0x6c, (byte) 0x72, (byte) 0xdb,
217            (byte) 0x91, (byte) 0x65, (byte) 0x17, (byte) 0x54, (byte) 0xe0, (byte) 0x74,
218            (byte) 0x1d, (byte) 0xac, (byte) 0x47, (byte) 0x04, (byte) 0x12, (byte) 0xe0,
219            (byte) 0xc3, (byte) 0x66, (byte) 0x19, (byte) 0x05, (byte) 0x2e, (byte) 0x7e,
220            (byte) 0xf1, (byte) 0x61
221    };
222
223    /**
224     * Generated from above and converted with:
225     *
226     * openssl pkcs8 -topk8 -outform d -in userkey.pem -nocrypt | xxd -i | sed 's/0x/(byte) 0x/g'
227     */
228    private static final byte[] FAKE_KEY_1 = new byte[] {
229            (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x78, (byte) 0x02, (byte) 0x01,
230            (byte) 0x00, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a,
231            (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01,
232            (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x04, (byte) 0x82,
233            (byte) 0x02, (byte) 0x62, (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x5e,
234            (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x81, (byte) 0x81,
235            (byte) 0x00, (byte) 0xce, (byte) 0x29, (byte) 0xeb, (byte) 0xf6, (byte) 0x5b,
236            (byte) 0x25, (byte) 0xdc, (byte) 0xa1, (byte) 0xa6, (byte) 0x2c, (byte) 0x66,
237            (byte) 0xcb, (byte) 0x20, (byte) 0x90, (byte) 0x27, (byte) 0x86, (byte) 0x8a,
238            (byte) 0x44, (byte) 0x71, (byte) 0x50, (byte) 0xda, (byte) 0xd3, (byte) 0x02,
239            (byte) 0x77, (byte) 0x55, (byte) 0xe9, (byte) 0xe8, (byte) 0x08, (byte) 0xf3,
240            (byte) 0x36, (byte) 0x9a, (byte) 0xae, (byte) 0xab, (byte) 0x04, (byte) 0x6d,
241            (byte) 0x00, (byte) 0x99, (byte) 0xbf, (byte) 0x7d, (byte) 0x0f, (byte) 0x67,
242            (byte) 0x8b, (byte) 0x1d, (byte) 0xd4, (byte) 0x2b, (byte) 0x7c, (byte) 0xcb,
243            (byte) 0xcd, (byte) 0x33, (byte) 0xc7, (byte) 0x84, (byte) 0x30, (byte) 0xe2,
244            (byte) 0x45, (byte) 0x21, (byte) 0xb3, (byte) 0x75, (byte) 0xf5, (byte) 0x79,
245            (byte) 0x02, (byte) 0xda, (byte) 0x50, (byte) 0xa3, (byte) 0x8b, (byte) 0xce,
246            (byte) 0xc3, (byte) 0x8e, (byte) 0x0f, (byte) 0x25, (byte) 0xeb, (byte) 0x08,
247            (byte) 0x2c, (byte) 0xdd, (byte) 0x1c, (byte) 0xcf, (byte) 0xff, (byte) 0x3b,
248            (byte) 0xde, (byte) 0xb6, (byte) 0xaa, (byte) 0x2a, (byte) 0xa9, (byte) 0xc4,
249            (byte) 0x8a, (byte) 0x24, (byte) 0x24, (byte) 0xe6, (byte) 0x29, (byte) 0x0d,
250            (byte) 0x98, (byte) 0x4c, (byte) 0x32, (byte) 0xa1, (byte) 0x7b, (byte) 0x23,
251            (byte) 0x2b, (byte) 0x42, (byte) 0x30, (byte) 0xee, (byte) 0x78, (byte) 0x08,
252            (byte) 0x47, (byte) 0xad, (byte) 0xf2, (byte) 0x96, (byte) 0xd5, (byte) 0xf1,
253            (byte) 0x62, (byte) 0x42, (byte) 0x2d, (byte) 0x35, (byte) 0x19, (byte) 0xb4,
254            (byte) 0x3c, (byte) 0xc9, (byte) 0xc3, (byte) 0x5f, (byte) 0x03, (byte) 0x16,
255            (byte) 0x3a, (byte) 0x23, (byte) 0xac, (byte) 0xcb, (byte) 0xce, (byte) 0x9e,
256            (byte) 0x51, (byte) 0x2e, (byte) 0x6d, (byte) 0x02, (byte) 0x03, (byte) 0x01,
257            (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x81, (byte) 0x80, (byte) 0x16,
258            (byte) 0x59, (byte) 0xc3, (byte) 0x24, (byte) 0x1d, (byte) 0x33, (byte) 0x98,
259            (byte) 0x9c, (byte) 0xc9, (byte) 0xc8, (byte) 0x2c, (byte) 0x88, (byte) 0xbf,
260            (byte) 0x0a, (byte) 0x01, (byte) 0xce, (byte) 0xfb, (byte) 0x34, (byte) 0x7a,
261            (byte) 0x58, (byte) 0x7a, (byte) 0xb0, (byte) 0xbf, (byte) 0xa6, (byte) 0xb2,
262            (byte) 0x60, (byte) 0xbe, (byte) 0x70, (byte) 0x21, (byte) 0xf5, (byte) 0xfc,
263            (byte) 0x85, (byte) 0x0d, (byte) 0x33, (byte) 0x58, (byte) 0xa1, (byte) 0xe5,
264            (byte) 0x09, (byte) 0x36, (byte) 0x84, (byte) 0xb2, (byte) 0x04, (byte) 0x0a,
265            (byte) 0x02, (byte) 0xd3, (byte) 0x88, (byte) 0x1f, (byte) 0x0c, (byte) 0x2b,
266            (byte) 0x1d, (byte) 0xe9, (byte) 0x3d, (byte) 0xe7, (byte) 0x79, (byte) 0xf9,
267            (byte) 0x32, (byte) 0x5c, (byte) 0x8a, (byte) 0x75, (byte) 0x49, (byte) 0x12,
268            (byte) 0xe4, (byte) 0x05, (byte) 0x26, (byte) 0xd4, (byte) 0x2e, (byte) 0x9e,
269            (byte) 0x1f, (byte) 0xcc, (byte) 0x54, (byte) 0xad, (byte) 0x33, (byte) 0x8d,
270            (byte) 0x99, (byte) 0x00, (byte) 0xdc, (byte) 0xf5, (byte) 0xb4, (byte) 0xa2,
271            (byte) 0x2f, (byte) 0xba, (byte) 0xe5, (byte) 0x62, (byte) 0x30, (byte) 0x6d,
272            (byte) 0xe6, (byte) 0x3d, (byte) 0xeb, (byte) 0x24, (byte) 0xc2, (byte) 0xdc,
273            (byte) 0x5f, (byte) 0xb7, (byte) 0x16, (byte) 0x35, (byte) 0xa3, (byte) 0x98,
274            (byte) 0x98, (byte) 0xa8, (byte) 0xef, (byte) 0xe8, (byte) 0xc4, (byte) 0x96,
275            (byte) 0x6d, (byte) 0x38, (byte) 0xab, (byte) 0x26, (byte) 0x6d, (byte) 0x30,
276            (byte) 0xc2, (byte) 0xa0, (byte) 0x44, (byte) 0xe4, (byte) 0xff, (byte) 0x7e,
277            (byte) 0xbe, (byte) 0x7c, (byte) 0x33, (byte) 0xa5, (byte) 0x10, (byte) 0xad,
278            (byte) 0xd7, (byte) 0x1e, (byte) 0x13, (byte) 0x20, (byte) 0xb3, (byte) 0x1f,
279            (byte) 0x41, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xf1, (byte) 0x89,
280            (byte) 0x07, (byte) 0x0f, (byte) 0xe8, (byte) 0xcf, (byte) 0xab, (byte) 0x13,
281            (byte) 0x2a, (byte) 0x8f, (byte) 0x88, (byte) 0x80, (byte) 0x11, (byte) 0x9a,
282            (byte) 0x79, (byte) 0xb6, (byte) 0x59, (byte) 0x3a, (byte) 0x50, (byte) 0x6e,
283            (byte) 0x57, (byte) 0x37, (byte) 0xab, (byte) 0x2a, (byte) 0xd2, (byte) 0xaa,
284            (byte) 0xd9, (byte) 0x72, (byte) 0x73, (byte) 0xff, (byte) 0x8b, (byte) 0x47,
285            (byte) 0x76, (byte) 0xdd, (byte) 0xdc, (byte) 0xf5, (byte) 0x97, (byte) 0x44,
286            (byte) 0x3a, (byte) 0x78, (byte) 0xbe, (byte) 0x17, (byte) 0xb4, (byte) 0x22,
287            (byte) 0x6f, (byte) 0xe5, (byte) 0x23, (byte) 0x70, (byte) 0x1d, (byte) 0x10,
288            (byte) 0x5d, (byte) 0xba, (byte) 0x16, (byte) 0x81, (byte) 0xf1, (byte) 0x45,
289            (byte) 0xce, (byte) 0x30, (byte) 0xb4, (byte) 0xab, (byte) 0x80, (byte) 0xe4,
290            (byte) 0x98, (byte) 0x31, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xda,
291            (byte) 0x82, (byte) 0x9d, (byte) 0x3f, (byte) 0xca, (byte) 0x2f, (byte) 0xe1,
292            (byte) 0xd4, (byte) 0x86, (byte) 0x77, (byte) 0x48, (byte) 0xa6, (byte) 0xab,
293            (byte) 0xab, (byte) 0x1c, (byte) 0x42, (byte) 0x5c, (byte) 0xd5, (byte) 0xc7,
294            (byte) 0x46, (byte) 0x59, (byte) 0x91, (byte) 0x3f, (byte) 0xfc, (byte) 0xcc,
295            (byte) 0xec, (byte) 0xc2, (byte) 0x40, (byte) 0x12, (byte) 0x2c, (byte) 0x8d,
296            (byte) 0x1f, (byte) 0xa2, (byte) 0x18, (byte) 0x88, (byte) 0xee, (byte) 0x82,
297            (byte) 0x4a, (byte) 0x5a, (byte) 0x5e, (byte) 0x88, (byte) 0x20, (byte) 0xe3,
298            (byte) 0x7b, (byte) 0xe0, (byte) 0xd8, (byte) 0x3a, (byte) 0x52, (byte) 0x9a,
299            (byte) 0x26, (byte) 0x6a, (byte) 0x04, (byte) 0xec, (byte) 0xe8, (byte) 0xb9,
300            (byte) 0x48, (byte) 0x40, (byte) 0xe1, (byte) 0xe1, (byte) 0x83, (byte) 0xa6,
301            (byte) 0x67, (byte) 0xa6, (byte) 0xfd, (byte) 0x02, (byte) 0x41, (byte) 0x00,
302            (byte) 0x89, (byte) 0x72, (byte) 0x3e, (byte) 0xb0, (byte) 0x90, (byte) 0xfd,
303            (byte) 0x4c, (byte) 0x0e, (byte) 0xd6, (byte) 0x13, (byte) 0x63, (byte) 0xcb,
304            (byte) 0xed, (byte) 0x38, (byte) 0x88, (byte) 0xb6, (byte) 0x79, (byte) 0xc4,
305            (byte) 0x33, (byte) 0x6c, (byte) 0xf6, (byte) 0xf8, (byte) 0xd8, (byte) 0xd0,
306            (byte) 0xbf, (byte) 0x9d, (byte) 0x35, (byte) 0xac, (byte) 0x69, (byte) 0xd2,
307            (byte) 0x2b, (byte) 0xc1, (byte) 0xf9, (byte) 0x24, (byte) 0x7b, (byte) 0xce,
308            (byte) 0xcd, (byte) 0xcb, (byte) 0xa7, (byte) 0xb2, (byte) 0x7a, (byte) 0x0a,
309            (byte) 0x27, (byte) 0x19, (byte) 0xc9, (byte) 0xaf, (byte) 0x0d, (byte) 0x21,
310            (byte) 0x89, (byte) 0x88, (byte) 0x7c, (byte) 0xad, (byte) 0x9e, (byte) 0x8d,
311            (byte) 0x47, (byte) 0x6d, (byte) 0x3f, (byte) 0xce, (byte) 0x7b, (byte) 0xa1,
312            (byte) 0x74, (byte) 0xf1, (byte) 0xa0, (byte) 0xa1, (byte) 0x02, (byte) 0x41,
313            (byte) 0x00, (byte) 0xd9, (byte) 0xa8, (byte) 0xf5, (byte) 0xfe, (byte) 0xce,
314            (byte) 0xe6, (byte) 0x77, (byte) 0x6b, (byte) 0xfe, (byte) 0x2d, (byte) 0xe0,
315            (byte) 0x1e, (byte) 0xb6, (byte) 0x2e, (byte) 0x12, (byte) 0x4e, (byte) 0x40,
316            (byte) 0xaf, (byte) 0x6a, (byte) 0x7b, (byte) 0x37, (byte) 0x49, (byte) 0x2a,
317            (byte) 0x96, (byte) 0x25, (byte) 0x83, (byte) 0x49, (byte) 0xd4, (byte) 0x0c,
318            (byte) 0xc6, (byte) 0x78, (byte) 0x25, (byte) 0x24, (byte) 0x90, (byte) 0x90,
319            (byte) 0x06, (byte) 0x15, (byte) 0x9e, (byte) 0xfe, (byte) 0xf9, (byte) 0xdf,
320            (byte) 0x5b, (byte) 0xf3, (byte) 0x7e, (byte) 0x38, (byte) 0x70, (byte) 0xeb,
321            (byte) 0x57, (byte) 0xd0, (byte) 0xd9, (byte) 0xa7, (byte) 0x0e, (byte) 0x14,
322            (byte) 0xf7, (byte) 0x95, (byte) 0x68, (byte) 0xd5, (byte) 0xc8, (byte) 0xab,
323            (byte) 0x9d, (byte) 0x3a, (byte) 0x2b, (byte) 0x51, (byte) 0xf9, (byte) 0x02,
324            (byte) 0x41, (byte) 0x00, (byte) 0x96, (byte) 0xdf, (byte) 0xe9, (byte) 0x67,
325            (byte) 0x6c, (byte) 0xdc, (byte) 0x90, (byte) 0x14, (byte) 0xb4, (byte) 0x1d,
326            (byte) 0x22, (byte) 0x33, (byte) 0x4a, (byte) 0x31, (byte) 0xc1, (byte) 0x9d,
327            (byte) 0x2e, (byte) 0xff, (byte) 0x9a, (byte) 0x2a, (byte) 0x95, (byte) 0x4b,
328            (byte) 0x27, (byte) 0x74, (byte) 0xcb, (byte) 0x21, (byte) 0xc3, (byte) 0xd2,
329            (byte) 0x0b, (byte) 0xb2, (byte) 0x46, (byte) 0x87, (byte) 0xf8, (byte) 0x28,
330            (byte) 0x01, (byte) 0x8b, (byte) 0xd8, (byte) 0xb9, (byte) 0x4b, (byte) 0xcd,
331            (byte) 0x9a, (byte) 0x96, (byte) 0x41, (byte) 0x0e, (byte) 0x36, (byte) 0x6d,
332            (byte) 0x40, (byte) 0x42, (byte) 0xbc, (byte) 0xd9, (byte) 0xd3, (byte) 0x7b,
333            (byte) 0xbc, (byte) 0xa7, (byte) 0x92, (byte) 0x90, (byte) 0xdd, (byte) 0xa1,
334            (byte) 0x9c, (byte) 0xce, (byte) 0xa1, (byte) 0x87, (byte) 0x11, (byte) 0x51
335    };
336
337    /**
338     * Generated from above and converted with:
339     *
340     * openssl x509 -outform d -in usercert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
341     */
342    private static final byte[] FAKE_USER_1 = new byte[] {
343            (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x95, (byte) 0x30, (byte) 0x82,
344            (byte) 0x01, (byte) 0xfe, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
345            (byte) 0x02, (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x30, (byte) 0x0d,
346            (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86,
347            (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x05,
348            (byte) 0x00, (byte) 0x30, (byte) 0x4f, (byte) 0x31, (byte) 0x0b, (byte) 0x30,
349            (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06,
350            (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x0b,
351            (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
352            (byte) 0x08, (byte) 0x13, (byte) 0x02, (byte) 0x43, (byte) 0x41, (byte) 0x31,
353            (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06, (byte) 0x03, (byte) 0x55,
354            (byte) 0x04, (byte) 0x07, (byte) 0x13, (byte) 0x0d, (byte) 0x4d, (byte) 0x6f,
355            (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x61, (byte) 0x69, (byte) 0x6e,
356            (byte) 0x20, (byte) 0x56, (byte) 0x69, (byte) 0x65, (byte) 0x77, (byte) 0x31,
357            (byte) 0x1b, (byte) 0x30, (byte) 0x19, (byte) 0x06, (byte) 0x03, (byte) 0x55,
358            (byte) 0x04, (byte) 0x0a, (byte) 0x13, (byte) 0x12, (byte) 0x41, (byte) 0x6e,
359            (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x20,
360            (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x20, (byte) 0x43,
361            (byte) 0x61, (byte) 0x73, (byte) 0x65, (byte) 0x73, (byte) 0x30, (byte) 0x1e,
362            (byte) 0x17, (byte) 0x0d, (byte) 0x31, (byte) 0x32, (byte) 0x30, (byte) 0x38,
363            (byte) 0x31, (byte) 0x34, (byte) 0x32, (byte) 0x33, (byte) 0x32, (byte) 0x35,
364            (byte) 0x34, (byte) 0x38, (byte) 0x5a, (byte) 0x17, (byte) 0x0d, (byte) 0x32,
365            (byte) 0x32, (byte) 0x30, (byte) 0x38, (byte) 0x31, (byte) 0x32, (byte) 0x32,
366            (byte) 0x33, (byte) 0x32, (byte) 0x35, (byte) 0x34, (byte) 0x38, (byte) 0x5a,
367            (byte) 0x30, (byte) 0x55, (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09,
368            (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13,
369            (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x0b, (byte) 0x30,
370            (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08,
371            (byte) 0x13, (byte) 0x02, (byte) 0x43, (byte) 0x41, (byte) 0x31, (byte) 0x1b,
372            (byte) 0x30, (byte) 0x19, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
373            (byte) 0x0a, (byte) 0x13, (byte) 0x12, (byte) 0x41, (byte) 0x6e, (byte) 0x64,
374            (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x20, (byte) 0x54,
375            (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x20, (byte) 0x43, (byte) 0x61,
376            (byte) 0x73, (byte) 0x65, (byte) 0x73, (byte) 0x31, (byte) 0x1c, (byte) 0x30,
377            (byte) 0x1a, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x03,
378            (byte) 0x13, (byte) 0x13, (byte) 0x73, (byte) 0x65, (byte) 0x72, (byte) 0x76,
379            (byte) 0x65, (byte) 0x72, (byte) 0x31, (byte) 0x2e, (byte) 0x65, (byte) 0x78,
380            (byte) 0x61, (byte) 0x6d, (byte) 0x70, (byte) 0x6c, (byte) 0x65, (byte) 0x2e,
381            (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30, (byte) 0x81, (byte) 0x9f,
382            (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
383            (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
384            (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x81, (byte) 0x8d,
385            (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0x89, (byte) 0x02, (byte) 0x81,
386            (byte) 0x81, (byte) 0x00, (byte) 0xce, (byte) 0x29, (byte) 0xeb, (byte) 0xf6,
387            (byte) 0x5b, (byte) 0x25, (byte) 0xdc, (byte) 0xa1, (byte) 0xa6, (byte) 0x2c,
388            (byte) 0x66, (byte) 0xcb, (byte) 0x20, (byte) 0x90, (byte) 0x27, (byte) 0x86,
389            (byte) 0x8a, (byte) 0x44, (byte) 0x71, (byte) 0x50, (byte) 0xda, (byte) 0xd3,
390            (byte) 0x02, (byte) 0x77, (byte) 0x55, (byte) 0xe9, (byte) 0xe8, (byte) 0x08,
391            (byte) 0xf3, (byte) 0x36, (byte) 0x9a, (byte) 0xae, (byte) 0xab, (byte) 0x04,
392            (byte) 0x6d, (byte) 0x00, (byte) 0x99, (byte) 0xbf, (byte) 0x7d, (byte) 0x0f,
393            (byte) 0x67, (byte) 0x8b, (byte) 0x1d, (byte) 0xd4, (byte) 0x2b, (byte) 0x7c,
394            (byte) 0xcb, (byte) 0xcd, (byte) 0x33, (byte) 0xc7, (byte) 0x84, (byte) 0x30,
395            (byte) 0xe2, (byte) 0x45, (byte) 0x21, (byte) 0xb3, (byte) 0x75, (byte) 0xf5,
396            (byte) 0x79, (byte) 0x02, (byte) 0xda, (byte) 0x50, (byte) 0xa3, (byte) 0x8b,
397            (byte) 0xce, (byte) 0xc3, (byte) 0x8e, (byte) 0x0f, (byte) 0x25, (byte) 0xeb,
398            (byte) 0x08, (byte) 0x2c, (byte) 0xdd, (byte) 0x1c, (byte) 0xcf, (byte) 0xff,
399            (byte) 0x3b, (byte) 0xde, (byte) 0xb6, (byte) 0xaa, (byte) 0x2a, (byte) 0xa9,
400            (byte) 0xc4, (byte) 0x8a, (byte) 0x24, (byte) 0x24, (byte) 0xe6, (byte) 0x29,
401            (byte) 0x0d, (byte) 0x98, (byte) 0x4c, (byte) 0x32, (byte) 0xa1, (byte) 0x7b,
402            (byte) 0x23, (byte) 0x2b, (byte) 0x42, (byte) 0x30, (byte) 0xee, (byte) 0x78,
403            (byte) 0x08, (byte) 0x47, (byte) 0xad, (byte) 0xf2, (byte) 0x96, (byte) 0xd5,
404            (byte) 0xf1, (byte) 0x62, (byte) 0x42, (byte) 0x2d, (byte) 0x35, (byte) 0x19,
405            (byte) 0xb4, (byte) 0x3c, (byte) 0xc9, (byte) 0xc3, (byte) 0x5f, (byte) 0x03,
406            (byte) 0x16, (byte) 0x3a, (byte) 0x23, (byte) 0xac, (byte) 0xcb, (byte) 0xce,
407            (byte) 0x9e, (byte) 0x51, (byte) 0x2e, (byte) 0x6d, (byte) 0x02, (byte) 0x03,
408            (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0xa3, (byte) 0x7b, (byte) 0x30,
409            (byte) 0x79, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55,
410            (byte) 0x1d, (byte) 0x13, (byte) 0x04, (byte) 0x02, (byte) 0x30, (byte) 0x00,
411            (byte) 0x30, (byte) 0x2c, (byte) 0x06, (byte) 0x09, (byte) 0x60, (byte) 0x86,
412            (byte) 0x48, (byte) 0x01, (byte) 0x86, (byte) 0xf8, (byte) 0x42, (byte) 0x01,
413            (byte) 0x0d, (byte) 0x04, (byte) 0x1f, (byte) 0x16, (byte) 0x1d, (byte) 0x4f,
414            (byte) 0x70, (byte) 0x65, (byte) 0x6e, (byte) 0x53, (byte) 0x53, (byte) 0x4c,
415            (byte) 0x20, (byte) 0x47, (byte) 0x65, (byte) 0x6e, (byte) 0x65, (byte) 0x72,
416            (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x64, (byte) 0x20, (byte) 0x43,
417            (byte) 0x65, (byte) 0x72, (byte) 0x74, (byte) 0x69, (byte) 0x66, (byte) 0x69,
418            (byte) 0x63, (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x30, (byte) 0x1d,
419            (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x0e, (byte) 0x04,
420            (byte) 0x16, (byte) 0x04, (byte) 0x14, (byte) 0x32, (byte) 0xa1, (byte) 0x1e,
421            (byte) 0x6b, (byte) 0x69, (byte) 0x04, (byte) 0xfe, (byte) 0xb3, (byte) 0xcd,
422            (byte) 0xf8, (byte) 0xbb, (byte) 0x14, (byte) 0xcd, (byte) 0xff, (byte) 0xd4,
423            (byte) 0x16, (byte) 0xc3, (byte) 0xab, (byte) 0x44, (byte) 0x2f, (byte) 0x30,
424            (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x23,
425            (byte) 0x04, (byte) 0x18, (byte) 0x30, (byte) 0x16, (byte) 0x80, (byte) 0x14,
426            (byte) 0x33, (byte) 0x05, (byte) 0xee, (byte) 0xfe, (byte) 0x6f, (byte) 0x60,
427            (byte) 0xc7, (byte) 0xf9, (byte) 0xa9, (byte) 0xd2, (byte) 0x73, (byte) 0x5c,
428            (byte) 0x8f, (byte) 0x6d, (byte) 0xa2, (byte) 0x2f, (byte) 0x97, (byte) 0x8e,
429            (byte) 0x5d, (byte) 0x51, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09,
430            (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d,
431            (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x05, (byte) 0x00, (byte) 0x03,
432            (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0x46, (byte) 0x42, (byte) 0xef,
433            (byte) 0x56, (byte) 0x89, (byte) 0x78, (byte) 0x90, (byte) 0x38, (byte) 0x24,
434            (byte) 0x9f, (byte) 0x8c, (byte) 0x7a, (byte) 0xce, (byte) 0x7a, (byte) 0xa5,
435            (byte) 0xb5, (byte) 0x1e, (byte) 0x74, (byte) 0x96, (byte) 0x34, (byte) 0x49,
436            (byte) 0x8b, (byte) 0xed, (byte) 0x44, (byte) 0xb3, (byte) 0xc9, (byte) 0x05,
437            (byte) 0xd7, (byte) 0x48, (byte) 0x55, (byte) 0x52, (byte) 0x59, (byte) 0x15,
438            (byte) 0x0b, (byte) 0xaa, (byte) 0x16, (byte) 0x86, (byte) 0xd2, (byte) 0x8e,
439            (byte) 0x16, (byte) 0x99, (byte) 0xe8, (byte) 0x5f, (byte) 0x11, (byte) 0x71,
440            (byte) 0x42, (byte) 0x55, (byte) 0xd1, (byte) 0xc4, (byte) 0x6f, (byte) 0x2e,
441            (byte) 0xa9, (byte) 0x64, (byte) 0x6f, (byte) 0xd8, (byte) 0xfd, (byte) 0x43,
442            (byte) 0x13, (byte) 0x24, (byte) 0xaa, (byte) 0x67, (byte) 0xe6, (byte) 0xf5,
443            (byte) 0xca, (byte) 0x80, (byte) 0x5e, (byte) 0x3a, (byte) 0x3e, (byte) 0xcc,
444            (byte) 0x4f, (byte) 0xba, (byte) 0x87, (byte) 0xe6, (byte) 0xae, (byte) 0xbf,
445            (byte) 0x8f, (byte) 0xd5, (byte) 0x28, (byte) 0x38, (byte) 0x58, (byte) 0x30,
446            (byte) 0x24, (byte) 0xf6, (byte) 0x53, (byte) 0x5b, (byte) 0x41, (byte) 0x53,
447            (byte) 0xe6, (byte) 0x45, (byte) 0xbc, (byte) 0xbe, (byte) 0xe6, (byte) 0xbb,
448            (byte) 0x5d, (byte) 0xd8, (byte) 0xa7, (byte) 0xf9, (byte) 0x64, (byte) 0x99,
449            (byte) 0x04, (byte) 0x43, (byte) 0x75, (byte) 0xd7, (byte) 0x2d, (byte) 0x32,
450            (byte) 0x0a, (byte) 0x94, (byte) 0xaf, (byte) 0x06, (byte) 0x34, (byte) 0xae,
451            (byte) 0x46, (byte) 0xbd, (byte) 0xda, (byte) 0x00, (byte) 0x0e, (byte) 0x25,
452            (byte) 0xc2, (byte) 0xf7, (byte) 0xc9, (byte) 0xc3, (byte) 0x65, (byte) 0xd2,
453            (byte) 0x08, (byte) 0x41, (byte) 0x0a, (byte) 0xf3, (byte) 0x72
454    };
455
456    /**
457     * The amount of time to allow before and after expected time for variance
458     * in timing tests.
459     */
460    private static final long SLOP_TIME_MILLIS = 15000L;
461
462    @Override
463    protected void setUp() throws Exception {
464        mAndroidKeyStore = android.security.KeyStore.getInstance();
465
466        assertTrue(mAndroidKeyStore.reset());
467
468        assertEquals(android.security.KeyStore.State.UNINITIALIZED, mAndroidKeyStore.state());
469
470        assertTrue(mAndroidKeyStore.password("1111"));
471
472        assertEquals(android.security.KeyStore.State.UNLOCKED, mAndroidKeyStore.state());
473
474        assertEquals(0, mAndroidKeyStore.saw("").length);
475
476        mKeyStore = java.security.KeyStore.getInstance(AndroidKeyStore.NAME);
477    }
478
479    private void assertAliases(final String[] expectedAliases) throws KeyStoreException {
480        final Enumeration<String> aliases = mKeyStore.aliases();
481        int count = 0;
482
483        final Set<String> expectedSet = new HashSet<String>();
484        expectedSet.addAll(Arrays.asList(expectedAliases));
485
486        while (aliases.hasMoreElements()) {
487            count++;
488            final String alias = aliases.nextElement();
489            assertTrue("The alias should be in the expected set", expectedSet.contains(alias));
490            expectedSet.remove(alias);
491        }
492        assertTrue("The expected set and actual set should be exactly equal", expectedSet.isEmpty());
493        assertEquals("There should be the correct number of keystore entries",
494                expectedAliases.length, count);
495    }
496
497    public void testKeyStore_Aliases_Success() throws Exception {
498        mKeyStore.load(null, null);
499
500        assertAliases(new String[] {});
501
502        assertTrue(mAndroidKeyStore.generate(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1));
503
504        assertAliases(new String[] { TEST_ALIAS_1 });
505
506        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_CA_1));
507
508        assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2 });
509    }
510
511    public void testKeyStore_Aliases_NotInitialized_Failure() throws Exception {
512        try {
513            mKeyStore.aliases();
514            fail("KeyStore should throw exception when not initialized");
515        } catch (KeyStoreException success) {
516        }
517    }
518
519    public void testKeyStore_ContainsAliases_PrivateAndCA_Success() throws Exception {
520        mKeyStore.load(null, null);
521
522        assertAliases(new String[] {});
523
524        assertTrue(mAndroidKeyStore.generate(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1));
525
526        assertTrue("Should contain generated private key", mKeyStore.containsAlias(TEST_ALIAS_1));
527
528        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_CA_1));
529
530        assertTrue("Should contain added CA certificate", mKeyStore.containsAlias(TEST_ALIAS_2));
531
532        assertFalse("Should not contain unadded certificate alias",
533                mKeyStore.containsAlias(TEST_ALIAS_3));
534    }
535
536    public void testKeyStore_ContainsAliases_CAOnly_Success() throws Exception {
537        mKeyStore.load(null, null);
538
539        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_CA_1));
540
541        assertTrue("Should contain added CA certificate", mKeyStore.containsAlias(TEST_ALIAS_2));
542    }
543
544    public void testKeyStore_ContainsAliases_NonExistent_Failure() throws Exception {
545        mKeyStore.load(null, null);
546
547        assertFalse("Should contain added CA certificate", mKeyStore.containsAlias(TEST_ALIAS_1));
548    }
549
550    public void testKeyStore_DeleteEntry_Success() throws Exception {
551        mKeyStore.load(null, null);
552
553        // TEST_ALIAS_1
554        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
555                FAKE_KEY_1));
556        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
557        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
558
559        // TEST_ALIAS_2
560        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_CA_1));
561
562        // TEST_ALIAS_3
563        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_3, FAKE_CA_1));
564
565        assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2, TEST_ALIAS_3 });
566
567        mKeyStore.deleteEntry(TEST_ALIAS_1);
568
569        assertAliases(new String[] { TEST_ALIAS_2, TEST_ALIAS_3 });
570
571        mKeyStore.deleteEntry(TEST_ALIAS_3);
572
573        assertAliases(new String[] { TEST_ALIAS_2 });
574
575        mKeyStore.deleteEntry(TEST_ALIAS_2);
576
577        assertAliases(new String[] { });
578    }
579
580    public void testKeyStore_DeleteEntry_EmptyStore_Failure() throws Exception {
581        mKeyStore.load(null, null);
582
583        try {
584            mKeyStore.deleteEntry(TEST_ALIAS_1);
585            fail("Should throw KeyStoreException with non-existent alias");
586        } catch (KeyStoreException success) {
587        }
588    }
589
590    public void testKeyStore_DeleteEntry_NonExistent_Failure() throws Exception {
591        mKeyStore.load(null, null);
592
593        // TEST_ALIAS_1
594        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
595                FAKE_KEY_1));
596        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
597        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
598
599        try {
600            mKeyStore.deleteEntry(TEST_ALIAS_2);
601            fail("Should throw KeyStoreException with non-existent alias");
602        } catch (KeyStoreException success) {
603        }
604    }
605
606    public void testKeyStore_GetCertificate_Single_Success() throws Exception {
607        mKeyStore.load(null, null);
608
609        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
610
611        assertAliases(new String[] { TEST_ALIAS_1 });
612
613        assertNull("Certificate should not exist in keystore",
614                mKeyStore.getCertificate(TEST_ALIAS_2));
615
616        Certificate retrieved = mKeyStore.getCertificate(TEST_ALIAS_1);
617
618        assertNotNull("Retrieved certificate should not be null", retrieved);
619
620        CertificateFactory f = CertificateFactory.getInstance("X.509");
621        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
622
623        assertEquals("Actual and retrieved certificates should be the same", actual, retrieved);
624    }
625
626    public void testKeyStore_GetCertificate_NonExist_Failure() throws Exception {
627        mKeyStore.load(null, null);
628
629        assertNull("Certificate should not exist in keystore",
630                mKeyStore.getCertificate(TEST_ALIAS_1));
631    }
632
633    public void testKeyStore_GetCertificateAlias_CAEntry_Success() throws Exception {
634        mKeyStore.load(null, null);
635
636        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
637
638        CertificateFactory f = CertificateFactory.getInstance("X.509");
639        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
640
641        assertEquals("Stored certificate alias should be found", TEST_ALIAS_1,
642                mKeyStore.getCertificateAlias(actual));
643    }
644
645    public void testKeyStore_GetCertificateAlias_PrivateKeyEntry_Success() throws Exception {
646        mKeyStore.load(null, null);
647
648        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
649                FAKE_KEY_1));
650        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
651        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
652
653        CertificateFactory f = CertificateFactory.getInstance("X.509");
654        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
655
656        assertEquals("Stored certificate alias should be found", TEST_ALIAS_1,
657                mKeyStore.getCertificateAlias(actual));
658    }
659
660    public void testKeyStore_GetCertificateAlias_CAEntry_WithPrivateKeyUsingCA_Success()
661            throws Exception {
662        mKeyStore.load(null, null);
663
664        // Insert TrustedCertificateEntry with CA name
665        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_CA_1));
666
667        // Insert PrivateKeyEntry that uses the same CA
668        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
669                FAKE_KEY_1));
670        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
671        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
672
673        CertificateFactory f = CertificateFactory.getInstance("X.509");
674        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
675
676        assertEquals("Stored certificate alias should be found", TEST_ALIAS_2,
677                mKeyStore.getCertificateAlias(actual));
678    }
679
680    public void testKeyStore_GetCertificateAlias_NonExist_Empty_Failure() throws Exception {
681        mKeyStore.load(null, null);
682
683        CertificateFactory f = CertificateFactory.getInstance("X.509");
684        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
685
686        assertNull("Stored certificate alias should not be found",
687                mKeyStore.getCertificateAlias(actual));
688    }
689
690    public void testKeyStore_GetCertificateAlias_NonExist_Failure() throws Exception {
691        mKeyStore.load(null, null);
692
693        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
694
695        CertificateFactory f = CertificateFactory.getInstance("X.509");
696        Certificate userCert = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
697
698        assertNull("Stored certificate alias should be found",
699                mKeyStore.getCertificateAlias(userCert));
700    }
701
702    public void testKeyStore_GetCertificateChain_SingleLength_Success() throws Exception {
703        mKeyStore.load(null, null);
704
705        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
706                FAKE_KEY_1));
707        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
708        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
709
710        CertificateFactory cf = CertificateFactory.getInstance("X.509");
711        Certificate[] expected = new Certificate[2];
712        expected[0] = cf.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
713        expected[1] = cf.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
714
715        Certificate[] actual = mKeyStore.getCertificateChain(TEST_ALIAS_1);
716
717        assertNotNull("Returned certificate chain should not be null", actual);
718        assertEquals("Returned certificate chain should be correct size", expected.length,
719                actual.length);
720        assertEquals("First certificate should be user certificate", expected[0], actual[0]);
721        assertEquals("Second certificate should be CA certificate", expected[1], actual[1]);
722
723        // Negative test when keystore is populated.
724        assertNull("Stored certificate alias should not be found",
725                mKeyStore.getCertificateChain(TEST_ALIAS_2));
726    }
727
728    public void testKeyStore_GetCertificateChain_NonExist_Failure() throws Exception {
729        mKeyStore.load(null, null);
730
731        assertNull("Stored certificate alias should not be found",
732                mKeyStore.getCertificateChain(TEST_ALIAS_1));
733    }
734
735    public void testKeyStore_GetCreationDate_PrivateKeyEntry_Success() throws Exception {
736        mKeyStore.load(null, null);
737
738        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
739                FAKE_KEY_1));
740        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
741        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
742
743        Date now = new Date();
744        Date actual = mKeyStore.getCreationDate(TEST_ALIAS_1);
745
746        Date expectedAfter = new Date(now.getTime() - SLOP_TIME_MILLIS);
747        Date expectedBefore = new Date(now.getTime() + SLOP_TIME_MILLIS);
748
749        assertTrue("Time should be close to current time", actual.before(expectedBefore));
750        assertTrue("Time should be close to current time", actual.after(expectedAfter));
751    }
752
753    public void testKeyStore_GetCreationDate_CAEntry_Success() throws Exception {
754        mKeyStore.load(null, null);
755
756        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
757
758        Date now = new Date();
759        Date actual = mKeyStore.getCreationDate(TEST_ALIAS_1);
760        assertNotNull("Certificate should be found", actual);
761
762        Date expectedAfter = new Date(now.getTime() - SLOP_TIME_MILLIS);
763        Date expectedBefore = new Date(now.getTime() + SLOP_TIME_MILLIS);
764
765        assertTrue("Time should be close to current time", actual.before(expectedBefore));
766        assertTrue("Time should be close to current time", actual.after(expectedAfter));
767    }
768
769    public void testKeyStore_GetEntry_NullParams_Success() throws Exception {
770        mKeyStore.load(null, null);
771
772        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
773                FAKE_KEY_1));
774        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
775        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
776
777        Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
778        assertNotNull("Entry should exist", entry);
779
780        assertTrue("Should be a PrivateKeyEntry", entry instanceof PrivateKeyEntry);
781
782        PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;
783
784        assertPrivateKeyEntryEquals(keyEntry, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
785    }
786
787    @SuppressWarnings("unchecked")
788    private void assertPrivateKeyEntryEquals(PrivateKeyEntry keyEntry, byte[] key, byte[] cert,
789            byte[] ca) throws Exception {
790        KeyFactory keyFact = KeyFactory.getInstance("RSA");
791        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(key));
792
793        CertificateFactory certFact = CertificateFactory.getInstance("X.509");
794        Certificate expectedCert = certFact.generateCertificate(new ByteArrayInputStream(cert));
795
796        final Collection<Certificate> expectedChain;
797        if (ca != null) {
798            expectedChain = (Collection<Certificate>) certFact
799                    .generateCertificates(new ByteArrayInputStream(ca));
800        } else {
801            expectedChain = null;
802        }
803
804        assertPrivateKeyEntryEquals(keyEntry, expectedKey, expectedCert, expectedChain);
805    }
806
807    private void assertPrivateKeyEntryEquals(PrivateKeyEntry keyEntry, PrivateKey expectedKey,
808            Certificate expectedCert, Collection<Certificate> expectedChain) throws Exception {
809        assertEquals("Returned PrivateKey should be what we inserted", expectedKey,
810                keyEntry.getPrivateKey());
811
812        assertEquals("Returned Certificate should be what we inserted", expectedCert,
813                keyEntry.getCertificate());
814
815        Certificate[] actualChain = keyEntry.getCertificateChain();
816
817        assertEquals("First certificate in chain should be user cert", expectedCert, actualChain[0]);
818
819        if (expectedChain == null) {
820            assertEquals("Certificate chain should not include CAs", 1, actualChain.length);
821        } else {
822            int i = 1;
823            final Iterator<Certificate> it = expectedChain.iterator();
824            while (it.hasNext()) {
825                assertEquals("CA chain certificate should equal what we put in", it.next(),
826                        actualChain[i++]);
827            }
828        }
829    }
830
831    public void testKeyStore_GetEntry_Nonexistent_NullParams_Failure() throws Exception {
832        mKeyStore.load(null, null);
833
834        assertNull("A non-existent entry should return null",
835                mKeyStore.getEntry(TEST_ALIAS_1, null));
836    }
837
838    public void testKeyStore_GetKey_NoPassword_Success() throws Exception {
839        mKeyStore.load(null, null);
840
841        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
842                FAKE_KEY_1));
843        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
844        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
845
846        Key key = mKeyStore.getKey(TEST_ALIAS_1, null);
847        assertNotNull("Key should exist", key);
848
849        assertTrue("Should be a RSAPrivateKey", key instanceof RSAPrivateKey);
850
851        RSAPrivateKey actualKey = (RSAPrivateKey) key;
852
853        KeyFactory keyFact = KeyFactory.getInstance("RSA");
854        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
855
856        assertEquals("Inserted key should be same as retrieved key", actualKey, expectedKey);
857    }
858
859    public void testKeyStore_GetKey_Certificate_Failure() throws Exception {
860        mKeyStore.load(null, null);
861
862        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
863
864        assertNull("Certificate entries should return null", mKeyStore.getKey(TEST_ALIAS_1, null));
865    }
866
867    public void testKeyStore_GetKey_NonExistent_Failure() throws Exception {
868        mKeyStore.load(null, null);
869
870        assertNull("A non-existent entry should return null", mKeyStore.getKey(TEST_ALIAS_1, null));
871    }
872
873    public void testKeyStore_GetProvider_Success() throws Exception {
874        assertEquals(AndroidKeyStoreProvider.PROVIDER_NAME, mKeyStore.getProvider().getName());
875    }
876
877    public void testKeyStore_GetType_Success() throws Exception {
878        assertEquals(AndroidKeyStore.NAME, mKeyStore.getType());
879    }
880
881    public void testKeyStore_IsCertificateEntry_CA_Success() throws Exception {
882        mKeyStore.load(null, null);
883
884        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
885
886        assertTrue("Should return true for CA certificate",
887                mKeyStore.isCertificateEntry(TEST_ALIAS_1));
888    }
889
890    public void testKeyStore_IsCertificateEntry_PrivateKey_Failure() throws Exception {
891        mKeyStore.load(null, null);
892
893        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
894                FAKE_KEY_1));
895        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
896        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
897
898        assertFalse("Should return false for PrivateKeyEntry",
899                mKeyStore.isCertificateEntry(TEST_ALIAS_1));
900    }
901
902    public void testKeyStore_IsCertificateEntry_NonExist_Failure() throws Exception {
903        mKeyStore.load(null, null);
904
905        assertFalse("Should return false for non-existent entry",
906                mKeyStore.isCertificateEntry(TEST_ALIAS_1));
907    }
908
909    public void testKeyStore_IsKeyEntry_PrivateKey_Success() throws Exception {
910        mKeyStore.load(null, null);
911
912        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
913                FAKE_KEY_1));
914        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
915        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
916
917        assertTrue("Should return true for PrivateKeyEntry", mKeyStore.isKeyEntry(TEST_ALIAS_1));
918    }
919
920    public void testKeyStore_IsKeyEntry_CA_Failure() throws Exception {
921        mKeyStore.load(null, null);
922
923        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
924
925        assertFalse("Should return false for CA certificate", mKeyStore.isKeyEntry(TEST_ALIAS_1));
926    }
927
928    public void testKeyStore_IsKeyEntry_NonExist_Failure() throws Exception {
929        mKeyStore.load(null, null);
930
931        assertFalse("Should return false for non-existent entry",
932                mKeyStore.isKeyEntry(TEST_ALIAS_1));
933    }
934
935    public void testKeyStore_SetCertificate_CA_Success() throws Exception {
936        final CertificateFactory f = CertificateFactory.getInstance("X.509");
937        final Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
938
939        mKeyStore.load(null, null);
940
941        mKeyStore.setCertificateEntry(TEST_ALIAS_1, actual);
942        assertAliases(new String[] { TEST_ALIAS_1 });
943
944        Certificate retrieved = mKeyStore.getCertificate(TEST_ALIAS_1);
945
946        assertEquals("Retrieved certificate should be the same as the one inserted", actual,
947                retrieved);
948    }
949
950    public void testKeyStore_SetCertificate_CAExists_Overwrite_Success() throws Exception {
951        mKeyStore.load(null, null);
952
953        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
954
955        assertAliases(new String[] { TEST_ALIAS_1 });
956
957        final CertificateFactory f = CertificateFactory.getInstance("X.509");
958        final Certificate cert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
959
960        // TODO have separate FAKE_CA for second test
961        mKeyStore.setCertificateEntry(TEST_ALIAS_1, cert);
962
963        assertAliases(new String[] { TEST_ALIAS_1 });
964    }
965
966    public void testKeyStore_SetCertificate_PrivateKeyExists_Failure() throws Exception {
967        mKeyStore.load(null, null);
968
969        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
970                FAKE_KEY_1));
971        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
972        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
973
974        assertAliases(new String[] { TEST_ALIAS_1 });
975
976        final CertificateFactory f = CertificateFactory.getInstance("X.509");
977        final Certificate cert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
978
979        try {
980            mKeyStore.setCertificateEntry(TEST_ALIAS_1, cert);
981            fail("Should throw when trying to overwrite a PrivateKey entry with a Certificate");
982        } catch (KeyStoreException success) {
983        }
984    }
985
986    public void testKeyStore_SetEntry_PrivateKeyEntry_Success() throws Exception {
987        mKeyStore.load(null, null);
988
989        KeyFactory keyFact = KeyFactory.getInstance("RSA");
990        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
991
992        final CertificateFactory f = CertificateFactory.getInstance("X.509");
993
994        final Certificate[] expectedChain = new Certificate[2];
995        expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
996        expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
997
998        PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);
999
1000        mKeyStore.setEntry(TEST_ALIAS_1, expected, null);
1001
1002        Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1003        assertNotNull("Retrieved entry should exist", actualEntry);
1004
1005        assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1006                actualEntry instanceof PrivateKeyEntry);
1007
1008        PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
1009
1010        assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
1011    }
1012
1013    public void testKeyStore_SetEntry_PrivateKeyEntry_Overwrites_PrivateKeyEntry_Success()
1014            throws Exception {
1015        mKeyStore.load(null, null);
1016
1017        final KeyFactory keyFact = KeyFactory.getInstance("RSA");
1018        final CertificateFactory f = CertificateFactory.getInstance("X.509");
1019
1020        // Start with PrivateKeyEntry
1021        {
1022            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
1023
1024            final Certificate[] expectedChain = new Certificate[2];
1025            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1026            expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1027
1028            PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);
1029
1030            mKeyStore.setEntry(TEST_ALIAS_1, expected, null);
1031
1032            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1033            assertNotNull("Retrieved entry should exist", actualEntry);
1034
1035            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1036                    actualEntry instanceof PrivateKeyEntry);
1037
1038            PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
1039
1040            assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
1041        }
1042
1043        // TODO make entirely new test vector for the overwrite
1044        // Replace with PrivateKeyEntry
1045        {
1046            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
1047
1048            final Certificate[] expectedChain = new Certificate[2];
1049            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1050            expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1051
1052            PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);
1053
1054            mKeyStore.setEntry(TEST_ALIAS_1, expected, null);
1055
1056            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1057            assertNotNull("Retrieved entry should exist", actualEntry);
1058
1059            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1060                    actualEntry instanceof PrivateKeyEntry);
1061
1062            PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
1063
1064            assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
1065        }
1066    }
1067
1068    public void testKeyStore_SetEntry_CAEntry_Overwrites_PrivateKeyEntry_Success() throws Exception {
1069        mKeyStore.load(null, null);
1070
1071        final CertificateFactory f = CertificateFactory.getInstance("X.509");
1072
1073        // Start with TrustedCertificateEntry
1074        {
1075            final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1076
1077            TrustedCertificateEntry expectedCertEntry = new TrustedCertificateEntry(caCert);
1078            mKeyStore.setEntry(TEST_ALIAS_1, expectedCertEntry, null);
1079
1080            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1081            assertNotNull("Retrieved entry should exist", actualEntry);
1082            assertTrue("Retrieved entry should be of type TrustedCertificateEntry",
1083                    actualEntry instanceof TrustedCertificateEntry);
1084            TrustedCertificateEntry actualCertEntry = (TrustedCertificateEntry) actualEntry;
1085            assertEquals("Stored and retrieved certificates should be the same",
1086                    expectedCertEntry.getTrustedCertificate(),
1087                    actualCertEntry.getTrustedCertificate());
1088        }
1089
1090        // Replace with PrivateKeyEntry
1091        {
1092            KeyFactory keyFact = KeyFactory.getInstance("RSA");
1093            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
1094            final Certificate[] expectedChain = new Certificate[2];
1095            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1096            expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1097
1098            PrivateKeyEntry expectedPrivEntry = new PrivateKeyEntry(expectedKey, expectedChain);
1099
1100            mKeyStore.setEntry(TEST_ALIAS_1, expectedPrivEntry, null);
1101
1102            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1103            assertNotNull("Retrieved entry should exist", actualEntry);
1104            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1105                    actualEntry instanceof PrivateKeyEntry);
1106
1107            PrivateKeyEntry actualPrivEntry = (PrivateKeyEntry) actualEntry;
1108            assertPrivateKeyEntryEquals(actualPrivEntry, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
1109        }
1110    }
1111
1112    public void testKeyStore_SetEntry_PrivateKeyEntry_Overwrites_CAEntry_Success() throws Exception {
1113        mKeyStore.load(null, null);
1114
1115        final CertificateFactory f = CertificateFactory.getInstance("X.509");
1116
1117        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1118
1119        // Start with PrivateKeyEntry
1120        {
1121            KeyFactory keyFact = KeyFactory.getInstance("RSA");
1122            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
1123            final Certificate[] expectedChain = new Certificate[2];
1124            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1125            expectedChain[1] = caCert;
1126
1127            PrivateKeyEntry expectedPrivEntry = new PrivateKeyEntry(expectedKey, expectedChain);
1128
1129            mKeyStore.setEntry(TEST_ALIAS_1, expectedPrivEntry, null);
1130
1131            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1132            assertNotNull("Retrieved entry should exist", actualEntry);
1133            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1134                    actualEntry instanceof PrivateKeyEntry);
1135
1136            PrivateKeyEntry actualPrivEntry = (PrivateKeyEntry) actualEntry;
1137            assertPrivateKeyEntryEquals(actualPrivEntry, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
1138        }
1139
1140        // Replace with TrustedCertificateEntry
1141        {
1142            TrustedCertificateEntry expectedCertEntry = new TrustedCertificateEntry(caCert);
1143            mKeyStore.setEntry(TEST_ALIAS_1, expectedCertEntry, null);
1144
1145            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1146            assertNotNull("Retrieved entry should exist", actualEntry);
1147            assertTrue("Retrieved entry should be of type TrustedCertificateEntry",
1148                    actualEntry instanceof TrustedCertificateEntry);
1149            TrustedCertificateEntry actualCertEntry = (TrustedCertificateEntry) actualEntry;
1150            assertEquals("Stored and retrieved certificates should be the same",
1151                    expectedCertEntry.getTrustedCertificate(),
1152                    actualCertEntry.getTrustedCertificate());
1153        }
1154    }
1155
1156    public void testKeyStore_SetEntry_PrivateKeyEntry_Overwrites_ShortPrivateKeyEntry_Success()
1157            throws Exception {
1158        mKeyStore.load(null, null);
1159
1160        final CertificateFactory f = CertificateFactory.getInstance("X.509");
1161
1162        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1163
1164        // Start with PrivateKeyEntry
1165        {
1166            KeyFactory keyFact = KeyFactory.getInstance("RSA");
1167            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
1168            final Certificate[] expectedChain = new Certificate[2];
1169            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1170            expectedChain[1] = caCert;
1171
1172            PrivateKeyEntry expectedPrivEntry = new PrivateKeyEntry(expectedKey, expectedChain);
1173
1174            mKeyStore.setEntry(TEST_ALIAS_1, expectedPrivEntry, null);
1175
1176            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1177            assertNotNull("Retrieved entry should exist", actualEntry);
1178            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1179                    actualEntry instanceof PrivateKeyEntry);
1180
1181            PrivateKeyEntry actualPrivEntry = (PrivateKeyEntry) actualEntry;
1182            assertPrivateKeyEntryEquals(actualPrivEntry, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
1183        }
1184
1185        // Replace with PrivateKeyEntry that has no chain
1186        {
1187            KeyFactory keyFact = KeyFactory.getInstance("RSA");
1188            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
1189            final Certificate[] expectedChain = new Certificate[1];
1190            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1191
1192            PrivateKeyEntry expectedPrivEntry = new PrivateKeyEntry(expectedKey, expectedChain);
1193
1194            mKeyStore.setEntry(TEST_ALIAS_1, expectedPrivEntry, null);
1195
1196            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1197            assertNotNull("Retrieved entry should exist", actualEntry);
1198            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1199                    actualEntry instanceof PrivateKeyEntry);
1200
1201            PrivateKeyEntry actualPrivEntry = (PrivateKeyEntry) actualEntry;
1202            assertPrivateKeyEntryEquals(actualPrivEntry, FAKE_KEY_1, FAKE_USER_1, null);
1203        }
1204    }
1205
1206    public void testKeyStore_SetEntry_CAEntry_Overwrites_CAEntry_Success() throws Exception {
1207        mKeyStore.load(null, null);
1208
1209        final CertificateFactory f = CertificateFactory.getInstance("X.509");
1210
1211        // Insert TrustedCertificateEntry
1212        {
1213            final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1214
1215            TrustedCertificateEntry expectedCertEntry = new TrustedCertificateEntry(caCert);
1216            mKeyStore.setEntry(TEST_ALIAS_1, expectedCertEntry, null);
1217
1218            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1219            assertNotNull("Retrieved entry should exist", actualEntry);
1220            assertTrue("Retrieved entry should be of type TrustedCertificateEntry",
1221                    actualEntry instanceof TrustedCertificateEntry);
1222            TrustedCertificateEntry actualCertEntry = (TrustedCertificateEntry) actualEntry;
1223            assertEquals("Stored and retrieved certificates should be the same",
1224                    expectedCertEntry.getTrustedCertificate(),
1225                    actualCertEntry.getTrustedCertificate());
1226        }
1227
1228        // Replace with TrustedCertificateEntry of USER
1229        {
1230            final Certificate userCert = f
1231                    .generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1232
1233            TrustedCertificateEntry expectedUserEntry = new TrustedCertificateEntry(userCert);
1234            mKeyStore.setEntry(TEST_ALIAS_1, expectedUserEntry, null);
1235
1236            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1237            assertNotNull("Retrieved entry should exist", actualEntry);
1238            assertTrue("Retrieved entry should be of type TrustedCertificateEntry",
1239                    actualEntry instanceof TrustedCertificateEntry);
1240            TrustedCertificateEntry actualUserEntry = (TrustedCertificateEntry) actualEntry;
1241            assertEquals("Stored and retrieved certificates should be the same",
1242                    expectedUserEntry.getTrustedCertificate(),
1243                    actualUserEntry.getTrustedCertificate());
1244        }
1245    }
1246
1247    public void testKeyStore_SetKeyEntry_ProtectedKey_Failure() throws Exception {
1248        mKeyStore.load(null, null);
1249
1250        final CertificateFactory f = CertificateFactory.getInstance("X.509");
1251
1252        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1253
1254        KeyFactory keyFact = KeyFactory.getInstance("RSA");
1255        PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
1256        final Certificate[] chain = new Certificate[2];
1257        chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1258        chain[1] = caCert;
1259
1260        try {
1261            mKeyStore.setKeyEntry(TEST_ALIAS_1, privKey, "foo".toCharArray(), chain);
1262            fail("Should fail when a password is specified");
1263        } catch (KeyStoreException success) {
1264        }
1265    }
1266
1267    public void testKeyStore_SetKeyEntry_Success() throws Exception {
1268        mKeyStore.load(null, null);
1269
1270        final CertificateFactory f = CertificateFactory.getInstance("X.509");
1271
1272        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1273
1274        KeyFactory keyFact = KeyFactory.getInstance("RSA");
1275        PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
1276        final Certificate[] chain = new Certificate[2];
1277        chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1278        chain[1] = caCert;
1279
1280        mKeyStore.setKeyEntry(TEST_ALIAS_1, privKey, null, chain);
1281
1282        Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1283        assertNotNull("Retrieved entry should exist", actualEntry);
1284
1285        assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1286                actualEntry instanceof PrivateKeyEntry);
1287
1288        PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
1289
1290        assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
1291    }
1292
1293    public void testKeyStore_SetKeyEntry_Replaced_Success() throws Exception {
1294        mKeyStore.load(null, null);
1295
1296        final CertificateFactory f = CertificateFactory.getInstance("X.509");
1297
1298        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1299
1300        // Insert initial key
1301        {
1302            KeyFactory keyFact = KeyFactory.getInstance("RSA");
1303            PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
1304            final Certificate[] chain = new Certificate[2];
1305            chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1306            chain[1] = caCert;
1307
1308            mKeyStore.setKeyEntry(TEST_ALIAS_1, privKey, null, chain);
1309
1310            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1311            assertNotNull("Retrieved entry should exist", actualEntry);
1312
1313            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1314                    actualEntry instanceof PrivateKeyEntry);
1315
1316            PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
1317
1318            assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
1319        }
1320
1321        // TODO make a separate key
1322        // Replace key
1323        {
1324            KeyFactory keyFact = KeyFactory.getInstance("RSA");
1325            PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
1326            final Certificate[] chain = new Certificate[2];
1327            chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1328            chain[1] = caCert;
1329
1330            mKeyStore.setKeyEntry(TEST_ALIAS_1, privKey, null, chain);
1331
1332            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1333            assertNotNull("Retrieved entry should exist", actualEntry);
1334
1335            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1336                    actualEntry instanceof PrivateKeyEntry);
1337
1338            PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
1339
1340            assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
1341        }
1342    }
1343
1344    @SuppressWarnings("deprecation")
1345    private static X509Certificate generateCertificate(android.security.KeyStore keyStore,
1346            String alias, BigInteger serialNumber, X500Principal subjectDN, Date notBefore,
1347            Date notAfter) throws Exception {
1348        final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + alias;
1349
1350        final PrivateKey privKey;
1351        final OpenSSLEngine engine = OpenSSLEngine.getInstance("keystore");
1352        try {
1353            privKey = engine.getPrivateKeyById(privateKeyAlias);
1354        } catch (InvalidKeyException e) {
1355            throw new RuntimeException("Can't get key", e);
1356        }
1357
1358        final byte[] pubKeyBytes = keyStore.getPubkey(privateKeyAlias);
1359
1360        final PublicKey pubKey;
1361        try {
1362            final KeyFactory keyFact = KeyFactory.getInstance("RSA");
1363            pubKey = keyFact.generatePublic(new X509EncodedKeySpec(pubKeyBytes));
1364        } catch (NoSuchAlgorithmException e) {
1365            throw new IllegalStateException("Can't instantiate RSA key generator", e);
1366        } catch (InvalidKeySpecException e) {
1367            throw new IllegalStateException("keystore returned invalid key encoding", e);
1368        }
1369
1370        final X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
1371        certGen.setPublicKey(pubKey);
1372        certGen.setSerialNumber(serialNumber);
1373        certGen.setSubjectDN(subjectDN);
1374        certGen.setIssuerDN(subjectDN);
1375        certGen.setNotBefore(notBefore);
1376        certGen.setNotAfter(notAfter);
1377        certGen.setSignatureAlgorithm("sha1WithRSA");
1378
1379        final X509Certificate cert = certGen.generate(privKey);
1380
1381        return cert;
1382    }
1383
1384    public void testKeyStore_SetKeyEntry_ReplacedChain_Success() throws Exception {
1385        mKeyStore.load(null, null);
1386
1387        // Create key #1
1388        {
1389            final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1;
1390            assertTrue(mAndroidKeyStore.generate(privateKeyAlias));
1391
1392            Key key = mKeyStore.getKey(TEST_ALIAS_1, null);
1393
1394            assertTrue(key instanceof PrivateKey);
1395
1396            PrivateKey expectedKey = (PrivateKey) key;
1397
1398            X509Certificate expectedCert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_1,
1399                    TEST_SERIAL_1, TEST_DN_1, NOW, NOW_PLUS_10_YEARS);
1400
1401            assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1,
1402                    expectedCert.getEncoded()));
1403
1404            Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1405
1406            assertTrue(entry instanceof PrivateKeyEntry);
1407
1408            PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;
1409
1410            assertPrivateKeyEntryEquals(keyEntry, expectedKey, expectedCert, null);
1411        }
1412
1413        // Replace key #1 with new chain
1414        {
1415            Key key = mKeyStore.getKey(TEST_ALIAS_1, null);
1416
1417            assertTrue(key instanceof PrivateKey);
1418
1419            PrivateKey expectedKey = (PrivateKey) key;
1420
1421            X509Certificate expectedCert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_1,
1422                    TEST_SERIAL_2, TEST_DN_2, NOW, NOW_PLUS_10_YEARS);
1423
1424            mKeyStore.setKeyEntry(TEST_ALIAS_1, expectedKey, null,
1425                    new Certificate[] { expectedCert });
1426
1427            Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1428
1429            assertTrue(entry instanceof PrivateKeyEntry);
1430
1431            PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;
1432
1433            assertPrivateKeyEntryEquals(keyEntry, expectedKey, expectedCert, null);
1434        }
1435    }
1436
1437    public void testKeyStore_SetKeyEntry_ReplacedChain_DifferentPrivateKey_Failure()
1438            throws Exception {
1439        mKeyStore.load(null, null);
1440
1441        // Create key #1
1442        {
1443            final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1;
1444            assertTrue(mAndroidKeyStore.generate(privateKeyAlias));
1445
1446            X509Certificate cert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_1,
1447                    TEST_SERIAL_1, TEST_DN_1, NOW, NOW_PLUS_10_YEARS);
1448
1449            assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1,
1450                    cert.getEncoded()));
1451        }
1452
1453        // Create key #2
1454        {
1455            final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_2;
1456            assertTrue(mAndroidKeyStore.generate(privateKeyAlias));
1457
1458            X509Certificate cert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_2,
1459                    TEST_SERIAL_2, TEST_DN_2, NOW, NOW_PLUS_10_YEARS);
1460
1461            assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_2,
1462                    cert.getEncoded()));
1463        }
1464
1465        // Replace key #1 with key #2
1466        {
1467            Key key1 = mKeyStore.getKey(TEST_ALIAS_2, null);
1468
1469            X509Certificate cert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_2,
1470                    TEST_SERIAL_2, TEST_DN_2, NOW, NOW_PLUS_10_YEARS);
1471
1472            try {
1473                mKeyStore.setKeyEntry(TEST_ALIAS_1, key1, null, new Certificate[] { cert });
1474                fail("Should not allow setting of KeyEntry with wrong PrivaetKey");
1475            } catch (KeyStoreException success) {
1476            }
1477        }
1478    }
1479
1480    public void testKeyStore_Size_Success() throws Exception {
1481        mKeyStore.load(null, null);
1482
1483        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
1484
1485        assertEquals("The keystore size should match expected", 1, mKeyStore.size());
1486        assertAliases(new String[] { TEST_ALIAS_1 });
1487
1488        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_CA_1));
1489
1490        assertEquals("The keystore size should match expected", 2, mKeyStore.size());
1491        assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2 });
1492
1493        assertTrue(mAndroidKeyStore.generate(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_3));
1494
1495        assertEquals("The keystore size should match expected", 3, mKeyStore.size());
1496        assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2, TEST_ALIAS_3 });
1497
1498        assertTrue(mAndroidKeyStore.delete(Credentials.CA_CERTIFICATE + TEST_ALIAS_1));
1499
1500        assertEquals("The keystore size should match expected", 2, mKeyStore.size());
1501        assertAliases(new String[] { TEST_ALIAS_2, TEST_ALIAS_3 });
1502
1503        assertTrue(mAndroidKeyStore.delKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_3));
1504
1505        assertEquals("The keystore size should match expected", 1, mKeyStore.size());
1506        assertAliases(new String[] { TEST_ALIAS_2 });
1507    }
1508
1509    public void testKeyStore_Store_LoadStoreParam_Failure() throws Exception {
1510        mKeyStore.load(null, null);
1511
1512        try {
1513            mKeyStore.store(null);
1514            fail("Should throw UnsupportedOperationException when trying to store");
1515        } catch (UnsupportedOperationException success) {
1516        }
1517    }
1518
1519    public void testKeyStore_Load_InputStreamSupplied_Failure() throws Exception {
1520        byte[] buf = "FAKE KEYSTORE".getBytes();
1521        ByteArrayInputStream is = new ByteArrayInputStream(buf);
1522
1523        try {
1524            mKeyStore.load(is, null);
1525            fail("Should throw IllegalArgumentException when InputStream is supplied");
1526        } catch (IllegalArgumentException success) {
1527        }
1528    }
1529
1530    public void testKeyStore_Load_PasswordSupplied_Failure() throws Exception {
1531        try {
1532            mKeyStore.load(null, "password".toCharArray());
1533            fail("Should throw IllegalArgumentException when password is supplied");
1534        } catch (IllegalArgumentException success) {
1535        }
1536    }
1537
1538    public void testKeyStore_Store_OutputStream_Failure() throws Exception {
1539        mKeyStore.load(null, null);
1540
1541        OutputStream sink = new ByteArrayOutputStream();
1542        try {
1543            mKeyStore.store(sink, null);
1544            fail("Should throw UnsupportedOperationException when trying to store");
1545        } catch (UnsupportedOperationException success) {
1546        }
1547
1548        try {
1549            mKeyStore.store(sink, "blah".toCharArray());
1550            fail("Should throw UnsupportedOperationException when trying to store");
1551        } catch (UnsupportedOperationException success) {
1552        }
1553    }
1554}
1555